Skip to content

Commit fc3f654

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

15 files changed

+482
-175
lines changed

compiler/rustc_lint/messages.ftl

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,6 @@ lint_improper_ctypes = `extern` {$desc} uses type `{$ty}`, which is not FFI-safe
375375
lint_improper_ctypes_array_help = consider passing a pointer to the array
376376
377377
lint_improper_ctypes_array_reason = passing raw arrays by value is not FFI-safe
378-
lint_improper_ctypes_box = box cannot be represented as a single pointer
379378
380379
lint_improper_ctypes_char_help = consider using `u32` or `libc::wchar_t` instead
381380
@@ -393,15 +392,23 @@ lint_improper_ctypes_enum_repr_help =
393392
lint_improper_ctypes_enum_repr_reason = enum has no representation hint
394393
lint_improper_ctypes_fnptr_help = consider using an `extern fn(...) -> ...` function pointer instead
395394
395+
lint_improper_ctypes_fnptr_indirect_reason = the function pointer to `{$ty}` is FFI-unsafe due to `{$inner_ty}`
396396
lint_improper_ctypes_fnptr_reason = this function pointer has Rust-specific calling convention
397+
397398
lint_improper_ctypes_non_exhaustive = this enum is non-exhaustive
398399
lint_improper_ctypes_non_exhaustive_variant = this enum has non-exhaustive variants
399400
400401
lint_improper_ctypes_only_phantomdata = composed only of `PhantomData`
401402
402403
lint_improper_ctypes_opaque = opaque types have no C equivalent
403404
404-
lint_improper_ctypes_slice_help = consider using a raw pointer instead
405+
lint_improper_ctypes_pat_help = consider using the base type instead
406+
lint_improper_ctypes_pat_reason = pattern types have no C equivalent
407+
408+
lint_improper_ctypes_sized_ptr_to_unsafe_type =
409+
this reference (`{$ty}`) is ABI-compatible with a C pointer, but `{$inner_ty}` itself does not have a C layout
410+
411+
lint_improper_ctypes_slice_help = consider using a raw pointer to the slice's first element (and a length) instead
405412
406413
lint_improper_ctypes_slice_reason = slices have no C equivalent
407414
lint_improper_ctypes_str_help = consider using `*const u8` and a length instead
@@ -427,6 +434,10 @@ lint_improper_ctypes_union_layout_help = consider adding a `#[repr(C)]` or `#[re
427434
lint_improper_ctypes_union_layout_reason = this union has unspecified layout
428435
lint_improper_ctypes_union_non_exhaustive = this union is non-exhaustive
429436
437+
lint_improper_ctypes_unsized_box = this box for an unsized type contains metadata, which makes it incompatible with a C pointer
438+
lint_improper_ctypes_unsized_ptr = this pointer to an unsized type contains metadata, which makes it incompatible with a C pointer
439+
lint_improper_ctypes_unsized_ref = this reference to an unsized type contains metadata, which makes it incompatible with a C pointer
440+
430441
lint_incomplete_include =
431442
include macro expected single expression in source
432443

compiler/rustc_lint/src/lints.rs

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1976,29 +1976,50 @@ pub(crate) enum UnpredictableFunctionPointerComparisonsSuggestion<'a, 'tcx> {
19761976
},
19771977
}
19781978

1979+
pub(crate) struct ImproperCTypesLayer<'a> {
1980+
pub ty: Ty<'a>,
1981+
pub inner_ty: Option<Ty<'a>>,
1982+
pub note: DiagMessage,
1983+
pub span_note: Option<Span>,
1984+
pub help: Option<DiagMessage>,
1985+
}
1986+
1987+
impl<'a> Subdiagnostic for ImproperCTypesLayer<'a> {
1988+
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
1989+
diag.arg("ty", self.ty);
1990+
if let Some(ty) = self.inner_ty {
1991+
diag.arg("inner_ty", ty);
1992+
}
1993+
1994+
if let Some(help) = self.help {
1995+
diag.help(diag.eagerly_translate(help));
1996+
}
1997+
1998+
diag.note(diag.eagerly_translate(self.note));
1999+
if let Some(note) = self.span_note {
2000+
diag.span_note(note, fluent::lint_note);
2001+
};
2002+
}
2003+
}
2004+
19792005
pub(crate) struct ImproperCTypes<'a> {
19802006
pub ty: Ty<'a>,
19812007
pub desc: &'a str,
19822008
pub label: Span,
1983-
pub help: Option<DiagMessage>,
1984-
pub note: DiagMessage,
1985-
pub span_note: Option<Span>,
2009+
pub reasons: Vec<ImproperCTypesLayer<'a>>,
19862010
}
19872011

19882012
// Used because of the complexity of Option<DiagMessage>, DiagMessage, and Option<Span>
19892013
impl<'a> LintDiagnostic<'a, ()> for ImproperCTypes<'_> {
19902014
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
19912015
diag.primary_message(fluent::lint_improper_ctypes);
1992-
diag.arg("ty", self.ty);
1993-
diag.arg("desc", self.desc);
19942016
diag.span_label(self.label, fluent::lint_label);
1995-
if let Some(help) = self.help {
1996-
diag.help(help);
1997-
}
1998-
diag.note(self.note);
1999-
if let Some(note) = self.span_note {
2000-
diag.span_note(note, fluent::lint_note);
2017+
for reason in self.reasons.into_iter() {
2018+
diag.subdiagnostic(reason);
20012019
}
2020+
// declare the arguments at the end to avoid them being clobbered in the subdiagnostics
2021+
diag.arg("ty", self.ty);
2022+
diag.arg("desc", self.desc);
20022023
}
20032024
}
20042025

0 commit comments

Comments
 (0)