Skip to content

Commit 57c7507

Browse files
committed
Changes to the ImproperCTypes lint, start of take 1 [does not pass tests]
This reverts commit 1fcbb1e.
1 parent ebcf860 commit 57c7507

15 files changed

+490
-181
lines changed

compiler/rustc_lint/messages.ftl

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,6 @@ lint_improper_ctypes_128bit = 128-bit integers don't currently have a known stab
364364
lint_improper_ctypes_array_help = consider passing a pointer to the array
365365
366366
lint_improper_ctypes_array_reason = passing raw arrays by value is not FFI-safe
367-
lint_improper_ctypes_box = box cannot be represented as a single pointer
368367
369368
lint_improper_ctypes_char_help = consider using `u32` or `libc::wchar_t` instead
370369
@@ -382,7 +381,9 @@ lint_improper_ctypes_enum_repr_help =
382381
lint_improper_ctypes_enum_repr_reason = enum has no representation hint
383382
lint_improper_ctypes_fnptr_help = consider using an `extern fn(...) -> ...` function pointer instead
384383
384+
lint_improper_ctypes_fnptr_indirect_reason = the function pointer to `{$ty}` is FFI-unsafe due to `{$inner_ty}`
385385
lint_improper_ctypes_fnptr_reason = this function pointer has Rust-specific calling convention
386+
386387
lint_improper_ctypes_non_exhaustive = this enum is non-exhaustive
387388
lint_improper_ctypes_non_exhaustive_variant = this enum has non-exhaustive variants
388389
@@ -393,7 +394,11 @@ lint_improper_ctypes_opaque = opaque types have no C equivalent
393394
lint_improper_ctypes_pat_help = consider using the base type instead
394395
395396
lint_improper_ctypes_pat_reason = pattern types have no C equivalent
396-
lint_improper_ctypes_slice_help = consider using a raw pointer instead
397+
398+
lint_improper_ctypes_sized_ptr_to_unsafe_type =
399+
this reference (`{$ty}`) is ABI-compatible with a C pointer, but `{$inner_ty}` itself does not have a C layout
400+
401+
lint_improper_ctypes_slice_help = consider using a raw pointer to the slice's first element (and a length) instead
397402
398403
lint_improper_ctypes_slice_reason = slices have no C equivalent
399404
lint_improper_ctypes_str_help = consider using `*const u8` and a length instead
@@ -419,6 +424,10 @@ lint_improper_ctypes_union_layout_help = consider adding a `#[repr(C)]` or `#[re
419424
lint_improper_ctypes_union_layout_reason = this union has unspecified layout
420425
lint_improper_ctypes_union_non_exhaustive = this union is non-exhaustive
421426
427+
lint_improper_ctypes_unsized_box = this box for an unsized type contains metadata, which makes it incompatible with a C pointer
428+
lint_improper_ctypes_unsized_ptr = this pointer to an unsized type contains metadata, which makes it incompatible with a C pointer
429+
lint_improper_ctypes_unsized_ref = this reference to an unsized type contains metadata, which makes it incompatible with a C pointer
430+
422431
lint_incomplete_include =
423432
include macro expected single expression in source
424433

compiler/rustc_lint/src/lints.rs

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1873,13 +1873,44 @@ pub(crate) enum UnpredictableFunctionPointerComparisonsSuggestion<'a, 'tcx> {
18731873
},
18741874
}
18751875

1876+
pub(crate) struct ImproperCTypesLayer<'a> {
1877+
pub ty: Ty<'a>,
1878+
pub inner_ty: Option<Ty<'a>>,
1879+
pub note: DiagMessage,
1880+
pub span_note: Option<Span>,
1881+
pub help: Option<DiagMessage>,
1882+
}
1883+
1884+
impl<'a> Subdiagnostic for ImproperCTypesLayer<'a> {
1885+
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
1886+
self,
1887+
diag: &mut Diag<'_, G>,
1888+
f: &F,
1889+
) {
1890+
diag.arg("ty", self.ty);
1891+
if let Some(ty) = self.inner_ty {
1892+
diag.arg("inner_ty", ty);
1893+
}
1894+
1895+
if let Some(help) = self.help {
1896+
let msg = f(diag, help.into());
1897+
diag.help(msg);
1898+
}
1899+
1900+
let msg = f(diag, self.note.into());
1901+
diag.note(msg);
1902+
if let Some(note) = self.span_note {
1903+
let msg = f(diag, fluent::lint_note.into());
1904+
diag.span_note(note, msg);
1905+
};
1906+
}
1907+
}
1908+
18761909
pub(crate) struct ImproperCTypes<'a> {
18771910
pub ty: Ty<'a>,
18781911
pub desc: &'a str,
18791912
pub label: Span,
1880-
pub help: Option<DiagMessage>,
1881-
pub note: DiagMessage,
1882-
pub span_note: Option<Span>,
1913+
pub reasons: Vec<ImproperCTypesLayer<'a>>,
18831914
}
18841915

18851916
// Used because of the complexity of Option<DiagMessage>, DiagMessage, and Option<Span>
@@ -1889,12 +1920,8 @@ impl<'a> LintDiagnostic<'a, ()> for ImproperCTypes<'_> {
18891920
diag.arg("ty", self.ty);
18901921
diag.arg("desc", self.desc);
18911922
diag.span_label(self.label, fluent::lint_label);
1892-
if let Some(help) = self.help {
1893-
diag.help(help);
1894-
}
1895-
diag.note(self.note);
1896-
if let Some(note) = self.span_note {
1897-
diag.span_note(note, fluent::lint_note);
1923+
for reason in self.reasons.into_iter() {
1924+
diag.subdiagnostic(reason);
18981925
}
18991926
}
19001927
}

0 commit comments

Comments
 (0)