From 78fb000b62c3f2a3fe9b4fc37d81fa17355421ce Mon Sep 17 00:00:00 2001 From: niacdoial Date: Sun, 13 Oct 2024 23:30:40 +0200 Subject: [PATCH] [WIP COMMIT, EXPECT OVERWRITING] lint: change help for pointers to dyn types in FFI --- compiler/rustc_lint/messages.ftl | 6 ++- compiler/rustc_lint/src/types.rs | 37 ++++++++++++++----- tests/ui/lint/extern-C-fnptr-lints-slices.rs | 2 +- .../lint/extern-C-fnptr-lints-slices.stderr | 4 +- 4 files changed, 36 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index c4d709aa1f985..c025fcd0f4983 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -360,7 +360,6 @@ lint_improper_ctypes_128bit = 128-bit integers don't currently have a known stab lint_improper_ctypes_array_help = consider passing a pointer to the array lint_improper_ctypes_array_reason = passing raw arrays by value is not FFI-safe -lint_improper_ctypes_box = box cannot be represented as a single pointer lint_improper_ctypes_char_help = consider using `u32` or `libc::wchar_t` instead @@ -389,6 +388,7 @@ lint_improper_ctypes_opaque = opaque types have no C equivalent lint_improper_ctypes_pat_help = consider using the base type instead lint_improper_ctypes_pat_reason = pattern types have no C equivalent + lint_improper_ctypes_slice_help = consider using a raw pointer instead lint_improper_ctypes_slice_reason = slices have no C equivalent @@ -415,6 +415,10 @@ lint_improper_ctypes_union_layout_help = consider adding a `#[repr(C)]` or `#[re lint_improper_ctypes_union_layout_reason = this union has unspecified layout lint_improper_ctypes_union_non_exhaustive = this union is non-exhaustive +lint_improper_ctypes_unsized_box = this box for an unsized rust type contains metadata, which makes it incompatible with a C pointer +lint_improper_ctypes_unsized_ptr = this pointer to an unsized rust type contains metadata, which makes it incompatible with a C pointer +lint_improper_ctypes_unsized_ref = this reference to an unsized rust type contains metadata, which makes it incompatible with a C pointer + lint_incomplete_include = include macro expected single expression in source diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index db4413149a49f..ddab4e6e81d9e 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -901,15 +901,24 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { match *ty.kind() { ty::Adt(def, args) => { - if let Some(boxed) = ty.boxed_ty() + if let Some(inner_ty) = ty.boxed_ty() && matches!(self.mode, CItemKind::Definition) { - if boxed.is_sized(tcx, self.cx.param_env) { + if inner_ty.is_sized(tcx, self.cx.param_env) + || matches!(inner_ty.kind(), ty::Foreign(..)) + { + let _probe = self.check_type_for_ffi(acc, inner_ty); return FfiSafe; } else { + //let help = match inner_ty.kind() { + // ty::Dynamic(..) => Some(fluent::lint_improper_ctypes_unsized_help_dyn), + // ty::Closure(..) => Some(fluent::lint_improper_ctypes_unsized_help_closure), + // ty::Slice(..) => Some(fluent::lint_improper_ctypes_unsized_help_slice), + // _ => None, + //}; return FfiUnsafe { ty, - reason: fluent::lint_improper_ctypes_box, + reason: fluent::lint_improper_ctypes_unsized_box, help: None, }; } @@ -1057,6 +1066,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { help: Some(fluent::lint_improper_ctypes_slice_help), }, + ty::Dynamic(..) => { FfiUnsafe { ty, reason: fluent::lint_improper_ctypes_dyn, help: None } } @@ -1073,13 +1083,22 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { help: Some(fluent::lint_improper_ctypes_tuple_help), }, - ty::RawPtr(ty, _) | ty::Ref(_, ty, _) - if { - matches!(self.mode, CItemKind::Definition) - && ty.is_sized(self.cx.tcx, self.cx.param_env) - } => + ty::RawPtr(inner_ty, _) | ty::Ref(_, inner_ty, _) + if matches!(self.mode, CItemKind::Definition) => { - FfiSafe + if inner_ty.is_sized(tcx, self.cx.param_env) + || matches!(inner_ty.kind(), ty::Foreign(..)) + { + let _probe = self.check_type_for_ffi(acc, inner_ty); + FfiSafe + } else { + let reason = match ty.kind() { + ty::RawPtr(..) => fluent::lint_improper_ctypes_unsized_ptr, + ty::Ref(..) => fluent::lint_improper_ctypes_unsized_ref, + _ => unreachable!(), + }; + FfiUnsafe { ty, reason, help: None } + } } ty::RawPtr(ty, _) diff --git a/tests/ui/lint/extern-C-fnptr-lints-slices.rs b/tests/ui/lint/extern-C-fnptr-lints-slices.rs index 0c35eb37a4890..4e3832ab1b672 100644 --- a/tests/ui/lint/extern-C-fnptr-lints-slices.rs +++ b/tests/ui/lint/extern-C-fnptr-lints-slices.rs @@ -3,7 +3,7 @@ // It's an improper ctype (a slice) arg in an extern "C" fnptr. pub type F = extern "C" fn(&[u8]); -//~^ ERROR: `extern` fn uses type `[u8]`, which is not FFI-safe +//~^ ERROR: `extern` fn uses type `&[u8]`, which is not FFI-safe fn main() {} diff --git a/tests/ui/lint/extern-C-fnptr-lints-slices.stderr b/tests/ui/lint/extern-C-fnptr-lints-slices.stderr index d13f93ca96f22..f6f321492849c 100644 --- a/tests/ui/lint/extern-C-fnptr-lints-slices.stderr +++ b/tests/ui/lint/extern-C-fnptr-lints-slices.stderr @@ -1,11 +1,11 @@ -error: `extern` fn uses type `[u8]`, which is not FFI-safe +error: `extern` fn uses type `&[u8]`, which is not FFI-safe --> $DIR/extern-C-fnptr-lints-slices.rs:5:14 | LL | pub type F = extern "C" fn(&[u8]); | ^^^^^^^^^^^^^^^^^^^^ not FFI-safe | = help: consider using a raw pointer instead - = note: slices have no C equivalent + = note: this reference to an unsized rust type contains metadata, which makes it incompatible with a C pointer note: the lint level is defined here --> $DIR/extern-C-fnptr-lints-slices.rs:1:8 |