Skip to content

Commit 703bb98

Browse files
authored
Rollup merge of #131669 - niacdoial:linting-ptrdyn-ffi, r=workingjubilee
lint: change help for pointers to dyn types in FFI ### Context while playing around, I encountered the warning for dyn types in `extern "C"` functions, but even after that I assumed that a (rust) raw pointer could be interpreted in C ('s ABI) as a `void *`... to be fair part of why I ignored the warning is because I wanted to poke at the generated assembly, not make useful code. ### Example ```rust extern "C" fn caller(callee: *const dyn Fn(i32)->i32){ // -- snip -- } ``` old warning: ``` warning: `extern` fn uses type `dyn Fn(i32) -> i32`, which is not FFI-safe --> file/name.rs:42:19 | 42 | fn caller(callee: *const dyn Fn(i32)->i32) { | ^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe | = note: trait objects have no C equivalent = note: `#[warn(improper_ctypes_definitions)]` on by default ``` new warning: ``` warning: `extern` fn uses type `dyn Fn(i32) -> i32`, which is not FFI-safe --> file/name.rs:42:19 | 42 | fn caller(callee: *const dyn Fn(i32)->i32) -> (){ | ^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe | = note: this pointer to an unsized type contains metadata, which makes it incompatible with a C pointer = note: `#[warn(improper_ctypes_definitions)]` on by default ```
2 parents f415c07 + 02072fd commit 703bb98

15 files changed

+490
-181
lines changed

Diff for: 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

Diff for: compiler/rustc_lint/src/lints.rs

+36-9
Original file line numberDiff line numberDiff line change
@@ -1851,13 +1851,44 @@ pub(crate) struct UnpredictableFunctionPointerComparisonsSuggestion<'a> {
18511851
pub right: Span,
18521852
}
18531853

1854+
pub(crate) struct ImproperCTypesLayer<'a> {
1855+
pub ty: Ty<'a>,
1856+
pub inner_ty: Option<Ty<'a>>,
1857+
pub note: DiagMessage,
1858+
pub span_note: Option<Span>,
1859+
pub help: Option<DiagMessage>,
1860+
}
1861+
1862+
impl<'a> Subdiagnostic for ImproperCTypesLayer<'a> {
1863+
fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
1864+
self,
1865+
diag: &mut Diag<'_, G>,
1866+
f: &F,
1867+
) {
1868+
diag.arg("ty", self.ty);
1869+
if let Some(ty) = self.inner_ty {
1870+
diag.arg("inner_ty", ty);
1871+
}
1872+
1873+
if let Some(help) = self.help {
1874+
let msg = f(diag, help.into());
1875+
diag.help(msg);
1876+
}
1877+
1878+
let msg = f(diag, self.note.into());
1879+
diag.note(msg);
1880+
if let Some(note) = self.span_note {
1881+
let msg = f(diag, fluent::lint_note.into());
1882+
diag.span_note(note, msg);
1883+
};
1884+
}
1885+
}
1886+
18541887
pub(crate) struct ImproperCTypes<'a> {
18551888
pub ty: Ty<'a>,
18561889
pub desc: &'a str,
18571890
pub label: Span,
1858-
pub help: Option<DiagMessage>,
1859-
pub note: DiagMessage,
1860-
pub span_note: Option<Span>,
1891+
pub reasons: Vec<ImproperCTypesLayer<'a>>,
18611892
}
18621893

18631894
// Used because of the complexity of Option<DiagMessage>, DiagMessage, and Option<Span>
@@ -1867,12 +1898,8 @@ impl<'a> LintDiagnostic<'a, ()> for ImproperCTypes<'_> {
18671898
diag.arg("ty", self.ty);
18681899
diag.arg("desc", self.desc);
18691900
diag.span_label(self.label, fluent::lint_label);
1870-
if let Some(help) = self.help {
1871-
diag.help(help);
1872-
}
1873-
diag.note(self.note);
1874-
if let Some(note) = self.span_note {
1875-
diag.span_note(note, fluent::lint_note);
1901+
for reason in self.reasons.into_iter() {
1902+
diag.subdiagnostic(reason);
18761903
}
18771904
}
18781905
}

0 commit comments

Comments
 (0)