diff options
| author | niacdoial <niac.notirl@gmail.com> | 2025-08-22 23:39:07 +0200 |
|---|---|---|
| committer | niacdoial <niac.notirl@gmail.com> | 2025-09-06 21:46:33 +0200 |
| commit | 33943d183207980a56387ca78dc7865b21b99c10 (patch) | |
| tree | fe3180ad32e5be90058a270ca9a5e5f20d22d7be | |
| parent | 0c0e764ff7d0708b90baa1386c6cbe75d70bce7d (diff) | |
| download | rust-33943d183207980a56387ca78dc7865b21b99c10.tar.gz rust-33943d183207980a56387ca78dc7865b21b99c10.zip | |
ImproperCTypes: more pre-emptive cleanup
Mainly, we realise that the non-null assumption on a Box<_> argument does not depend on what side of the FFI boundary the function is on. And anyway, this is not the way to deal with this assumption being maybe violated.
| -rw-r--r-- | compiler/rustc_lint/src/foreign_modules.rs | 27 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/types.rs | 14 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/types/improper_ctypes.rs | 4 | ||||
| -rw-r--r-- | tests/ui/lint/improper-ctypes/lint-ctypes.rs | 1 | ||||
| -rw-r--r-- | tests/ui/lint/improper-ctypes/lint-ctypes.stderr | 41 |
5 files changed, 31 insertions, 56 deletions
diff --git a/compiler/rustc_lint/src/foreign_modules.rs b/compiler/rustc_lint/src/foreign_modules.rs index 3267e70f1de..ad73e15e31f 100644 --- a/compiler/rustc_lint/src/foreign_modules.rs +++ b/compiler/rustc_lint/src/foreign_modules.rs @@ -136,7 +136,6 @@ impl ClashingExternDeclarations { ty::TypingEnv::non_body_analysis(tcx, this_fi.owner_id), existing_decl_ty, this_decl_ty, - types::CItemKind::Declaration, ) { let orig = name_of_extern_decl(tcx, existing_did); @@ -214,10 +213,9 @@ fn structurally_same_type<'tcx>( typing_env: ty::TypingEnv<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>, - ckind: types::CItemKind, ) -> bool { let mut seen_types = UnordSet::default(); - let result = structurally_same_type_impl(&mut seen_types, tcx, typing_env, a, b, ckind); + let result = structurally_same_type_impl(&mut seen_types, tcx, typing_env, a, b); if cfg!(debug_assertions) && result { // Sanity-check: must have same ABI, size and alignment. // `extern` blocks cannot be generic, so we'll always get a layout here. @@ -236,7 +234,6 @@ fn structurally_same_type_impl<'tcx>( typing_env: ty::TypingEnv<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>, - ckind: types::CItemKind, ) -> bool { debug!("structurally_same_type_impl(tcx, a = {:?}, b = {:?})", a, b); @@ -307,7 +304,6 @@ fn structurally_same_type_impl<'tcx>( typing_env, tcx.type_of(a_did).instantiate(tcx, a_gen_args), tcx.type_of(b_did).instantiate(tcx, b_gen_args), - ckind, ) }, ) @@ -315,25 +311,19 @@ fn structurally_same_type_impl<'tcx>( (ty::Array(a_ty, a_len), ty::Array(b_ty, b_len)) => { // For arrays, we also check the length. a_len == b_len - && structurally_same_type_impl( - seen_types, tcx, typing_env, *a_ty, *b_ty, ckind, - ) + && structurally_same_type_impl(seen_types, tcx, typing_env, *a_ty, *b_ty) } (ty::Slice(a_ty), ty::Slice(b_ty)) => { - structurally_same_type_impl(seen_types, tcx, typing_env, *a_ty, *b_ty, ckind) + structurally_same_type_impl(seen_types, tcx, typing_env, *a_ty, *b_ty) } (ty::RawPtr(a_ty, a_mutbl), ty::RawPtr(b_ty, b_mutbl)) => { a_mutbl == b_mutbl - && structurally_same_type_impl( - seen_types, tcx, typing_env, *a_ty, *b_ty, ckind, - ) + && structurally_same_type_impl(seen_types, tcx, typing_env, *a_ty, *b_ty) } (ty::Ref(_a_region, a_ty, a_mut), ty::Ref(_b_region, b_ty, b_mut)) => { // For structural sameness, we don't need the region to be same. a_mut == b_mut - && structurally_same_type_impl( - seen_types, tcx, typing_env, *a_ty, *b_ty, ckind, - ) + && structurally_same_type_impl(seen_types, tcx, typing_env, *a_ty, *b_ty) } (ty::FnDef(..), ty::FnDef(..)) => { let a_poly_sig = a.fn_sig(tcx); @@ -347,7 +337,7 @@ fn structurally_same_type_impl<'tcx>( (a_sig.abi, a_sig.safety, a_sig.c_variadic) == (b_sig.abi, b_sig.safety, b_sig.c_variadic) && a_sig.inputs().iter().eq_by(b_sig.inputs().iter(), |a, b| { - structurally_same_type_impl(seen_types, tcx, typing_env, *a, *b, ckind) + structurally_same_type_impl(seen_types, tcx, typing_env, *a, *b) }) && structurally_same_type_impl( seen_types, @@ -355,7 +345,6 @@ fn structurally_same_type_impl<'tcx>( typing_env, a_sig.output(), b_sig.output(), - ckind, ) } (ty::Tuple(..), ty::Tuple(..)) => { @@ -383,14 +372,14 @@ fn structurally_same_type_impl<'tcx>( // An Adt and a primitive or pointer type. This can be FFI-safe if non-null // enum layout optimisation is being applied. (ty::Adt(..) | ty::Pat(..), _) if is_primitive_or_pointer(b) => { - if let Some(a_inner) = types::repr_nullable_ptr(tcx, typing_env, a, ckind) { + if let Some(a_inner) = types::repr_nullable_ptr(tcx, typing_env, a) { a_inner == b } else { false } } (_, ty::Adt(..) | ty::Pat(..)) if is_primitive_or_pointer(a) => { - if let Some(b_inner) = types::repr_nullable_ptr(tcx, typing_env, b, ckind) { + if let Some(b_inner) = types::repr_nullable_ptr(tcx, typing_env, b) { b_inner == a } else { false diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 056ecb70af8..979a8631701 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -11,9 +11,7 @@ use tracing::debug; use {rustc_ast as ast, rustc_hir as hir}; mod improper_ctypes; // these filed do the implementation for ImproperCTypesDefinitions,ImproperCTypesDeclarations -pub(crate) use improper_ctypes::{ - CItemKind, ImproperCTypesDeclarations, ImproperCTypesDefinitions, -}; +pub(crate) use improper_ctypes::{ImproperCTypesDeclarations, ImproperCTypesDefinitions}; use crate::lints::{ AmbiguousWidePointerComparisons, AmbiguousWidePointerComparisonsAddrMetadataSuggestion, @@ -712,14 +710,13 @@ fn ty_is_known_nonnull<'tcx>( tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>, ty: Ty<'tcx>, - mode: CItemKind, ) -> bool { let ty = tcx.try_normalize_erasing_regions(typing_env, ty).unwrap_or(ty); match ty.kind() { ty::FnPtr(..) => true, ty::Ref(..) => true, - ty::Adt(def, _) if def.is_box() && matches!(mode, CItemKind::Definition) => true, + ty::Adt(def, _) if def.is_box() => true, ty::Adt(def, args) if def.repr().transparent() && !def.is_union() => { let marked_non_null = nonnull_optimization_guaranteed(tcx, *def); @@ -735,10 +732,10 @@ fn ty_is_known_nonnull<'tcx>( def.variants() .iter() .filter_map(|variant| transparent_newtype_field(tcx, variant)) - .any(|field| ty_is_known_nonnull(tcx, typing_env, field.ty(tcx, args), mode)) + .any(|field| ty_is_known_nonnull(tcx, typing_env, field.ty(tcx, args))) } ty::Pat(base, pat) => { - ty_is_known_nonnull(tcx, typing_env, *base, mode) + ty_is_known_nonnull(tcx, typing_env, *base) || pat_ty_is_known_nonnull(tcx, typing_env, *pat) } _ => false, @@ -849,7 +846,6 @@ pub(crate) fn repr_nullable_ptr<'tcx>( tcx: TyCtxt<'tcx>, typing_env: ty::TypingEnv<'tcx>, ty: Ty<'tcx>, - ckind: CItemKind, ) -> Option<Ty<'tcx>> { debug!("is_repr_nullable_ptr(tcx, ty = {:?})", ty); match ty.kind() { @@ -874,7 +870,7 @@ pub(crate) fn repr_nullable_ptr<'tcx>( _ => return None, }; - if !ty_is_known_nonnull(tcx, typing_env, field_ty, ckind) { + if !ty_is_known_nonnull(tcx, typing_env, field_ty) { return None; } diff --git a/compiler/rustc_lint/src/types/improper_ctypes.rs b/compiler/rustc_lint/src/types/improper_ctypes.rs index 6f732fc2a50..7d7d86f93fc 100644 --- a/compiler/rustc_lint/src/types/improper_ctypes.rs +++ b/compiler/rustc_lint/src/types/improper_ctypes.rs @@ -173,7 +173,7 @@ fn variant_has_complex_ctor(variant: &ty::VariantDef) -> bool { } #[derive(Clone, Copy)] -pub(crate) enum CItemKind { +enum CItemKind { Declaration, Definition, } @@ -385,7 +385,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { { // Special-case types like `Option<extern fn()>` and `Result<extern fn(), ()>` if let Some(ty) = - repr_nullable_ptr(self.cx.tcx, self.cx.typing_env(), ty, self.mode) + repr_nullable_ptr(self.cx.tcx, self.cx.typing_env(), ty) { return self.check_type_for_ffi(acc, ty); } diff --git a/tests/ui/lint/improper-ctypes/lint-ctypes.rs b/tests/ui/lint/improper-ctypes/lint-ctypes.rs index 47586c826ab..7dc06079fa3 100644 --- a/tests/ui/lint/improper-ctypes/lint-ctypes.rs +++ b/tests/ui/lint/improper-ctypes/lint-ctypes.rs @@ -52,7 +52,6 @@ extern "C" { pub fn str_type(p: &str); //~ ERROR: uses type `str` pub fn box_type(p: Box<u32>); //~ ERROR uses type `Box<u32>` pub fn opt_box_type(p: Option<Box<u32>>); - //~^ ERROR uses type `Option<Box<u32>>` pub fn char_type(p: char); //~ ERROR uses type `char` pub fn trait_type(p: &dyn Bar); //~ ERROR uses type `dyn Bar` pub fn tuple_type(p: (i32, i32)); //~ ERROR uses type `(i32, i32)` diff --git a/tests/ui/lint/improper-ctypes/lint-ctypes.stderr b/tests/ui/lint/improper-ctypes/lint-ctypes.stderr index 3fb36647d4f..6f8b951c53d 100644 --- a/tests/ui/lint/improper-ctypes/lint-ctypes.stderr +++ b/tests/ui/lint/improper-ctypes/lint-ctypes.stderr @@ -67,17 +67,8 @@ LL | pub fn box_type(p: Box<u32>); = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct = note: this struct has unspecified layout -error: `extern` block uses type `Option<Box<u32>>`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:54:28 - | -LL | pub fn opt_box_type(p: Option<Box<u32>>); - | ^^^^^^^^^^^^^^^^ not FFI-safe - | - = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum - = note: enum has no representation hint - error: `extern` block uses type `char`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:56:25 + --> $DIR/lint-ctypes.rs:55:25 | LL | pub fn char_type(p: char); | ^^^^ not FFI-safe @@ -86,7 +77,7 @@ LL | pub fn char_type(p: char); = note: the `char` type has no C equivalent error: `extern` block uses type `dyn Bar`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:57:26 + --> $DIR/lint-ctypes.rs:56:26 | LL | pub fn trait_type(p: &dyn Bar); | ^^^^^^^^ not FFI-safe @@ -94,7 +85,7 @@ LL | pub fn trait_type(p: &dyn Bar); = note: trait objects have no C equivalent error: `extern` block uses type `(i32, i32)`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:58:26 + --> $DIR/lint-ctypes.rs:57:26 | LL | pub fn tuple_type(p: (i32, i32)); | ^^^^^^^^^^ not FFI-safe @@ -103,7 +94,7 @@ LL | pub fn tuple_type(p: (i32, i32)); = note: tuples have unspecified layout error: `extern` block uses type `(i32, i32)`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:59:27 + --> $DIR/lint-ctypes.rs:58:27 | LL | pub fn tuple_type2(p: I32Pair); | ^^^^^^^ not FFI-safe @@ -112,7 +103,7 @@ LL | pub fn tuple_type2(p: I32Pair); = note: tuples have unspecified layout error: `extern` block uses type `ZeroSize`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:60:25 + --> $DIR/lint-ctypes.rs:59:25 | LL | pub fn zero_size(p: ZeroSize); | ^^^^^^^^ not FFI-safe @@ -126,7 +117,7 @@ LL | pub struct ZeroSize; | ^^^^^^^^^^^^^^^^^^^ error: `extern` block uses type `ZeroSizeWithPhantomData`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:61:33 + --> $DIR/lint-ctypes.rs:60:33 | LL | pub fn zero_size_phantom(p: ZeroSizeWithPhantomData); | ^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -139,7 +130,7 @@ LL | pub struct ZeroSizeWithPhantomData(::std::marker::PhantomData<i32>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `extern` block uses type `PhantomData<bool>`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:64:12 + --> $DIR/lint-ctypes.rs:63:12 | LL | -> ::std::marker::PhantomData<bool>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -147,7 +138,7 @@ LL | -> ::std::marker::PhantomData<bool>; = note: composed only of `PhantomData` error: `extern` block uses type `fn()`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:65:23 + --> $DIR/lint-ctypes.rs:64:23 | LL | pub fn fn_type(p: RustFn); | ^^^^^^ not FFI-safe @@ -156,7 +147,7 @@ LL | pub fn fn_type(p: RustFn); = note: this function pointer has Rust-specific calling convention error: `extern` block uses type `fn()`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:66:24 + --> $DIR/lint-ctypes.rs:65:24 | LL | pub fn fn_type2(p: fn()); | ^^^^ not FFI-safe @@ -165,7 +156,7 @@ LL | pub fn fn_type2(p: fn()); = note: this function pointer has Rust-specific calling convention error: `extern` block uses type `Box<u32>`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:67:28 + --> $DIR/lint-ctypes.rs:66:28 | LL | pub fn fn_contained(p: RustBadRet); | ^^^^^^^^^^ not FFI-safe @@ -174,7 +165,7 @@ LL | pub fn fn_contained(p: RustBadRet); = note: this struct has unspecified layout error: `extern` block uses type `str`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:68:31 + --> $DIR/lint-ctypes.rs:67:31 | LL | pub fn transparent_str(p: TransparentStr); | ^^^^^^^^^^^^^^ not FFI-safe @@ -183,7 +174,7 @@ LL | pub fn transparent_str(p: TransparentStr); = note: string slices have no C equivalent error: `extern` block uses type `Box<u32>`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:69:30 + --> $DIR/lint-ctypes.rs:68:30 | LL | pub fn transparent_fn(p: TransparentBadFn); | ^^^^^^^^^^^^^^^^ not FFI-safe @@ -192,7 +183,7 @@ LL | pub fn transparent_fn(p: TransparentBadFn); = note: this struct has unspecified layout error: `extern` block uses type `[u8; 8]`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:70:27 + --> $DIR/lint-ctypes.rs:69:27 | LL | pub fn raw_array(arr: [u8; 8]); | ^^^^^^^ not FFI-safe @@ -201,7 +192,7 @@ LL | pub fn raw_array(arr: [u8; 8]); = note: passing raw arrays by value is not FFI-safe error: `extern` block uses type `Option<UnsafeCell<extern "C" fn()>>`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:72:26 + --> $DIR/lint-ctypes.rs:71:26 | LL | pub fn no_niche_a(a: Option<UnsafeCell<extern "C" fn()>>); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -210,7 +201,7 @@ LL | pub fn no_niche_a(a: Option<UnsafeCell<extern "C" fn()>>); = note: enum has no representation hint error: `extern` block uses type `Option<UnsafeCell<&i32>>`, which is not FFI-safe - --> $DIR/lint-ctypes.rs:74:26 + --> $DIR/lint-ctypes.rs:73:26 | LL | pub fn no_niche_b(b: Option<UnsafeCell<&i32>>); | ^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe @@ -218,5 +209,5 @@ LL | pub fn no_niche_b(b: Option<UnsafeCell<&i32>>); = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum = note: enum has no representation hint -error: aborting due to 22 previous errors +error: aborting due to 21 previous errors |
