1
Fork 0

Correctly handle pattern types in FFI redeclaration lints

This commit is contained in:
Oli Scherer 2025-01-24 15:57:13 +00:00
parent 473352da31
commit 5bae8ca77c
4 changed files with 66 additions and 90 deletions

View file

@ -241,10 +241,7 @@ fn structurally_same_type_impl<'tcx>(
if let ty::Adt(def, args) = *ty.kind() { if let ty::Adt(def, args) = *ty.kind() {
let is_transparent = def.repr().transparent(); let is_transparent = def.repr().transparent();
let is_non_null = types::nonnull_optimization_guaranteed(tcx, def); let is_non_null = types::nonnull_optimization_guaranteed(tcx, def);
debug!( debug!(?ty, is_transparent, is_non_null);
"non_transparent_ty({:?}) -- type is transparent? {}, type is non-null? {}",
ty, is_transparent, is_non_null
);
if is_transparent && !is_non_null { if is_transparent && !is_non_null {
debug_assert_eq!(def.variants().len(), 1); debug_assert_eq!(def.variants().len(), 1);
let v = &def.variant(FIRST_VARIANT); let v = &def.variant(FIRST_VARIANT);
@ -378,14 +375,14 @@ fn structurally_same_type_impl<'tcx>(
// An Adt and a primitive or pointer type. This can be FFI-safe if non-null // An Adt and a primitive or pointer type. This can be FFI-safe if non-null
// enum layout optimisation is being applied. // enum layout optimisation is being applied.
(Adt(..), _) if is_primitive_or_pointer(b) => { (Adt(..) | 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, ckind) {
a_inner == b a_inner == b
} else { } else {
false false
} }
} }
(_, Adt(..)) if is_primitive_or_pointer(a) => { (_, Adt(..) | 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, ckind) {
b_inner == a b_inner == a
} else { } else {

View file

@ -907,9 +907,8 @@ fn get_nullable_type<'tcx>(
}; };
return get_nullable_type(tcx, typing_env, inner_field_ty); return get_nullable_type(tcx, typing_env, inner_field_ty);
} }
ty::Int(ty) => Ty::new_int(tcx, ty), ty::Pat(base, ..) => return get_nullable_type(tcx, typing_env, base),
ty::Uint(ty) => Ty::new_uint(tcx, ty), ty::Int(_) | ty::Uint(_) | ty::RawPtr(..) => ty,
ty::RawPtr(ty, mutbl) => Ty::new_ptr(tcx, ty, mutbl),
// As these types are always non-null, the nullable equivalent of // As these types are always non-null, the nullable equivalent of
// `Option<T>` of these types are their raw pointer counterparts. // `Option<T>` of these types are their raw pointer counterparts.
ty::Ref(_region, ty, mutbl) => Ty::new_ptr(tcx, ty, mutbl), ty::Ref(_region, ty, mutbl) => Ty::new_ptr(tcx, ty, mutbl),
@ -965,7 +964,8 @@ pub(crate) fn repr_nullable_ptr<'tcx>(
ckind: CItemKind, ckind: CItemKind,
) -> Option<Ty<'tcx>> { ) -> Option<Ty<'tcx>> {
debug!("is_repr_nullable_ptr(tcx, ty = {:?})", ty); debug!("is_repr_nullable_ptr(tcx, ty = {:?})", ty);
if let ty::Adt(ty_def, args) = ty.kind() { match ty.kind() {
ty::Adt(ty_def, args) => {
let field_ty = match &ty_def.variants().raw[..] { let field_ty = match &ty_def.variants().raw[..] {
[var_one, var_two] => match (&var_one.fields.raw[..], &var_two.fields.raw[..]) { [var_one, var_two] => match (&var_one.fields.raw[..], &var_two.fields.raw[..]) {
([], [field]) | ([field], []) => field.ty(tcx, args), ([], [field]) | ([field], []) => field.ty(tcx, args),
@ -1020,8 +1020,13 @@ pub(crate) fn repr_nullable_ptr<'tcx>(
} }
}; };
} }
}
None None
}
ty::Pat(base, pat) => match **pat {
ty::PatternKind::Range { .. } => get_nullable_type(tcx, typing_env, *base),
},
_ => None,
}
} }
impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {

View file

@ -514,13 +514,11 @@ mod pattern_types {
// invariant that the value is non-zero, or you're missing out on that invariant. Both // invariant that the value is non-zero, or you're missing out on that invariant. Both
// cases are warning for, from both a caller-convenience and optimisation perspective. // cases are warning for, from both a caller-convenience and optimisation perspective.
fn pt_non_zero_usize() -> usize; fn pt_non_zero_usize() -> usize;
//~^ WARN `pt_non_zero_usize` redeclared with a different signature
fn pt_non_zero_usize_opt() -> usize; fn pt_non_zero_usize_opt() -> usize;
//~^ WARN `pt_non_zero_usize_opt` redeclared with a different signature //~^ WARN `pt_non_zero_usize_opt` redeclared with a different signature
fn pt_non_null_ptr() -> *const (); fn pt_non_null_ptr() -> *const ();
//~^ WARN `pt_non_null_ptr` redeclared with a different signature //~^ WARN `pt_non_null_ptr` redeclared with a different signature
fn pt_non_zero_usize_wrapper() -> usize; fn pt_non_zero_usize_wrapper() -> usize;
//~^ WARN `pt_non_zero_usize_wrapper` redeclared with a different signature
fn pt_non_zero_usize_wrapper_opt() -> usize; fn pt_non_zero_usize_wrapper_opt() -> usize;
//~^ WARN `pt_non_zero_usize_wrapper_opt` redeclared with a different signature //~^ WARN `pt_non_zero_usize_wrapper_opt` redeclared with a different signature
} }

View file

@ -285,20 +285,8 @@ LL | fn hidden_niche_unsafe_cell() -> Option<UnsafeCell<NonZero<usiz
= note: expected `unsafe extern "C" fn() -> usize` = note: expected `unsafe extern "C" fn() -> usize`
found `unsafe extern "C" fn() -> Option<UnsafeCell<NonZero<usize>>>` found `unsafe extern "C" fn() -> Option<UnsafeCell<NonZero<usize>>>`
warning: `pt_non_zero_usize` redeclared with a different signature
--> $DIR/clashing-extern-fn.rs:516:13
|
LL | fn pt_non_zero_usize() -> pattern_type!(usize is 1..);
| ------------------------------------------------------ `pt_non_zero_usize` previously declared here
...
LL | fn pt_non_zero_usize() -> usize;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
|
= note: expected `unsafe extern "C" fn() -> (usize) is 1..=`
found `unsafe extern "C" fn() -> usize`
warning: `pt_non_zero_usize_opt` redeclared with a different signature warning: `pt_non_zero_usize_opt` redeclared with a different signature
--> $DIR/clashing-extern-fn.rs:518:13 --> $DIR/clashing-extern-fn.rs:517:13
| |
LL | fn pt_non_zero_usize_opt() -> Option<pattern_type!(usize is 1..)>; LL | fn pt_non_zero_usize_opt() -> Option<pattern_type!(usize is 1..)>;
| ------------------------------------------------------------------ `pt_non_zero_usize_opt` previously declared here | ------------------------------------------------------------------ `pt_non_zero_usize_opt` previously declared here
@ -310,7 +298,7 @@ LL | fn pt_non_zero_usize_opt() -> usize;
found `unsafe extern "C" fn() -> usize` found `unsafe extern "C" fn() -> usize`
warning: `pt_non_null_ptr` redeclared with a different signature warning: `pt_non_null_ptr` redeclared with a different signature
--> $DIR/clashing-extern-fn.rs:520:13 --> $DIR/clashing-extern-fn.rs:519:13
| |
LL | fn pt_non_null_ptr() -> pattern_type!(usize is 1..); LL | fn pt_non_null_ptr() -> pattern_type!(usize is 1..);
| ---------------------------------------------------- `pt_non_null_ptr` previously declared here | ---------------------------------------------------- `pt_non_null_ptr` previously declared here
@ -321,20 +309,8 @@ LL | fn pt_non_null_ptr() -> *const ();
= note: expected `unsafe extern "C" fn() -> (usize) is 1..=` = note: expected `unsafe extern "C" fn() -> (usize) is 1..=`
found `unsafe extern "C" fn() -> *const ()` found `unsafe extern "C" fn() -> *const ()`
warning: `pt_non_zero_usize_wrapper` redeclared with a different signature
--> $DIR/clashing-extern-fn.rs:522:13
|
LL | fn pt_non_zero_usize_wrapper() -> NonZeroUsize;
| ----------------------------------------------- `pt_non_zero_usize_wrapper` previously declared here
...
LL | fn pt_non_zero_usize_wrapper() -> usize;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
|
= note: expected `unsafe extern "C" fn() -> NonZeroUsize`
found `unsafe extern "C" fn() -> usize`
warning: `pt_non_zero_usize_wrapper_opt` redeclared with a different signature warning: `pt_non_zero_usize_wrapper_opt` redeclared with a different signature
--> $DIR/clashing-extern-fn.rs:524:13 --> $DIR/clashing-extern-fn.rs:522:13
| |
LL | fn pt_non_zero_usize_wrapper_opt() -> Option<NonZeroUsize>; LL | fn pt_non_zero_usize_wrapper_opt() -> Option<NonZeroUsize>;
| ----------------------------------------------------------- `pt_non_zero_usize_wrapper_opt` previously declared here | ----------------------------------------------------------- `pt_non_zero_usize_wrapper_opt` previously declared here
@ -345,5 +321,5 @@ LL | fn pt_non_zero_usize_wrapper_opt() -> usize;
= note: expected `unsafe extern "C" fn() -> Option<NonZeroUsize>` = note: expected `unsafe extern "C" fn() -> Option<NonZeroUsize>`
found `unsafe extern "C" fn() -> usize` found `unsafe extern "C" fn() -> usize`
warning: 30 warnings emitted warning: 28 warnings emitted