Skip to content

Commit 5c7e7cc

Browse files
committed
Changes to the ImproperCTypes lint, start of take 2 [does not pass tests]
This reverts commit 1fcbb1e.
1 parent 85c3989 commit 5c7e7cc

15 files changed

+490
-181
lines changed

compiler/rustc_lint/messages.ftl

+11-2
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,6 @@ lint_improper_ctypes_128bit = 128-bit integers don't currently have a known stab
359359
lint_improper_ctypes_array_help = consider passing a pointer to the array
360360
361361
lint_improper_ctypes_array_reason = passing raw arrays by value is not FFI-safe
362-
lint_improper_ctypes_box = box cannot be represented as a single pointer
363362
364363
lint_improper_ctypes_char_help = consider using `u32` or `libc::wchar_t` instead
365364
@@ -377,7 +376,9 @@ lint_improper_ctypes_enum_repr_help =
377376
lint_improper_ctypes_enum_repr_reason = enum has no representation hint
378377
lint_improper_ctypes_fnptr_help = consider using an `extern fn(...) -> ...` function pointer instead
379378
379+
lint_improper_ctypes_fnptr_indirect_reason = the function pointer to `{$ty}` is FFI-unsafe due to `{$inner_ty}`
380380
lint_improper_ctypes_fnptr_reason = this function pointer has Rust-specific calling convention
381+
381382
lint_improper_ctypes_non_exhaustive = this enum is non-exhaustive
382383
lint_improper_ctypes_non_exhaustive_variant = this enum has non-exhaustive variants
383384
@@ -388,7 +389,11 @@ lint_improper_ctypes_opaque = opaque types have no C equivalent
388389
lint_improper_ctypes_pat_help = consider using the base type instead
389390
390391
lint_improper_ctypes_pat_reason = pattern types have no C equivalent
391-
lint_improper_ctypes_slice_help = consider using a raw pointer instead
392+
393+
lint_improper_ctypes_sized_ptr_to_unsafe_type =
394+
this reference (`{$ty}`) is ABI-compatible with a C pointer, but `{$inner_ty}` itself does not have a C layout
395+
396+
lint_improper_ctypes_slice_help = consider using a raw pointer to the slice's first element (and a length) instead
392397
393398
lint_improper_ctypes_slice_reason = slices have no C equivalent
394399
lint_improper_ctypes_str_help = consider using `*const u8` and a length instead
@@ -414,6 +419,10 @@ lint_improper_ctypes_union_layout_help = consider adding a `#[repr(C)]` or `#[re
414419
lint_improper_ctypes_union_layout_reason = this union has unspecified layout
415420
lint_improper_ctypes_union_non_exhaustive = this union is non-exhaustive
416421
422+
lint_improper_ctypes_unsized_box = this box for an unsized type contains metadata, which makes it incompatible with a C pointer
423+
lint_improper_ctypes_unsized_ptr = this pointer to an unsized type contains metadata, which makes it incompatible with a C pointer
424+
lint_improper_ctypes_unsized_ref = this reference to an unsized type contains metadata, which makes it incompatible with a C pointer
425+
417426
lint_incomplete_include =
418427
include macro expected single expression in source
419428

compiler/rustc_lint/src/lints.rs

+36-9
Original file line numberDiff line numberDiff line change
@@ -1861,13 +1861,44 @@ pub(crate) enum UnpredictableFunctionPointerComparisonsSuggestion<'a, 'tcx> {
18611861
},
18621862
}
18631863

1864+
pub(crate) struct ImproperCTypesLayer<'a> {
1865+
pub ty: Ty<'a>,
1866+
pub inner_ty: Option<Ty<'a>>,
1867+
pub note: DiagMessage,
1868+
pub span_note: Option<Span>,
1869+
pub help: Option<DiagMessage>,
1870+
}
1871+
1872+
impl<'a> Subdiagnostic for ImproperCTypesLayer<'a> {
1873+
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
1874+
self,
1875+
diag: &mut Diag<'_, G>,
1876+
f: &F,
1877+
) {
1878+
diag.arg("ty", self.ty);
1879+
if let Some(ty) = self.inner_ty {
1880+
diag.arg("inner_ty", ty);
1881+
}
1882+
1883+
if let Some(help) = self.help {
1884+
let msg = f(diag, help.into());
1885+
diag.help(msg);
1886+
}
1887+
1888+
let msg = f(diag, self.note.into());
1889+
diag.note(msg);
1890+
if let Some(note) = self.span_note {
1891+
let msg = f(diag, fluent::lint_note.into());
1892+
diag.span_note(note, msg);
1893+
};
1894+
}
1895+
}
1896+
18641897
pub(crate) struct ImproperCTypes<'a> {
18651898
pub ty: Ty<'a>,
18661899
pub desc: &'a str,
18671900
pub label: Span,
1868-
pub help: Option<DiagMessage>,
1869-
pub note: DiagMessage,
1870-
pub span_note: Option<Span>,
1901+
pub reasons: Vec<ImproperCTypesLayer<'a>>,
18711902
}
18721903

18731904
// Used because of the complexity of Option<DiagMessage>, DiagMessage, and Option<Span>
@@ -1877,12 +1908,8 @@ impl<'a> LintDiagnostic<'a, ()> for ImproperCTypes<'_> {
18771908
diag.arg("ty", self.ty);
18781909
diag.arg("desc", self.desc);
18791910
diag.span_label(self.label, fluent::lint_label);
1880-
if let Some(help) = self.help {
1881-
diag.help(help);
1882-
}
1883-
diag.note(self.note);
1884-
if let Some(note) = self.span_note {
1885-
diag.span_note(note, fluent::lint_note);
1911+
for reason in self.reasons.into_iter() {
1912+
diag.subdiagnostic(reason);
18861913
}
18871914
}
18881915
}

0 commit comments

Comments
 (0)