mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 08:13:41 +00:00
Rollup merge of #109370 - DaniPopes:issue-109334, r=Nilstrieb
fix ClashingExternDeclarations lint ICE Fixes #109334 First "real" contribution, please let me know if I did something wrong. As I understand it, it's OK if a `#[repr(transparent)]` type has no non-zero sized types (aka is a ZST itself) and the function should just return the type normally instead of panicking r? `@Nilstrieb`
This commit is contained in:
commit
eb1f8dc2cb
@ -2781,8 +2781,7 @@ impl ClashingExternDeclarations {
|
||||
|
||||
// Given a transparent newtype, reach through and grab the inner
|
||||
// type unless the newtype makes the type non-null.
|
||||
let non_transparent_ty = |ty: Ty<'tcx>| -> Ty<'tcx> {
|
||||
let mut ty = ty;
|
||||
let non_transparent_ty = |mut ty: Ty<'tcx>| -> Ty<'tcx> {
|
||||
loop {
|
||||
if let ty::Adt(def, substs) = *ty.kind() {
|
||||
let is_transparent = def.repr().transparent();
|
||||
@ -2792,14 +2791,14 @@ impl ClashingExternDeclarations {
|
||||
ty, is_transparent, is_non_null
|
||||
);
|
||||
if is_transparent && !is_non_null {
|
||||
debug_assert!(def.variants().len() == 1);
|
||||
debug_assert_eq!(def.variants().len(), 1);
|
||||
let v = &def.variant(VariantIdx::new(0));
|
||||
ty = transparent_newtype_field(tcx, v)
|
||||
.expect(
|
||||
"single-variant transparent structure with zero-sized field",
|
||||
)
|
||||
.ty(tcx, substs);
|
||||
continue;
|
||||
// continue with `ty`'s non-ZST field,
|
||||
// otherwise `ty` is a ZST and we can return
|
||||
if let Some(field) = transparent_newtype_field(tcx, v) {
|
||||
ty = field.ty(tcx, substs);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
debug!("non_transparent_ty -> {:?}", ty);
|
||||
@ -2813,10 +2812,8 @@ impl ClashingExternDeclarations {
|
||||
if !seen_types.insert((a, b)) {
|
||||
// We've encountered a cycle. There's no point going any further -- the types are
|
||||
// structurally the same.
|
||||
return true;
|
||||
}
|
||||
let tcx = cx.tcx;
|
||||
if a == b {
|
||||
true
|
||||
} else if a == b {
|
||||
// All nominally-same types are structurally same, too.
|
||||
true
|
||||
} else {
|
||||
|
@ -122,8 +122,8 @@ mod banana {
|
||||
weight: u32,
|
||||
length: u16,
|
||||
} // note: distinct type
|
||||
// This should not trigger the lint because two::Banana is structurally equivalent to
|
||||
// one::Banana.
|
||||
// This should not trigger the lint because two::Banana is structurally equivalent to
|
||||
// one::Banana.
|
||||
extern "C" {
|
||||
fn weigh_banana(count: *const Banana) -> u64;
|
||||
}
|
||||
@ -223,6 +223,27 @@ mod transparent {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(improper_ctypes)]
|
||||
mod zst {
|
||||
mod transparent {
|
||||
#[repr(transparent)]
|
||||
struct TransparentZst(());
|
||||
extern "C" {
|
||||
fn zst() -> ();
|
||||
fn transparent_zst() -> TransparentZst;
|
||||
}
|
||||
}
|
||||
|
||||
mod not_transparent {
|
||||
struct NotTransparentZst(());
|
||||
extern "C" {
|
||||
// These shouldn't warn since all return types are zero sized
|
||||
fn zst() -> NotTransparentZst;
|
||||
fn transparent_zst() -> NotTransparentZst;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod missing_return_type {
|
||||
mod a {
|
||||
extern "C" {
|
||||
@ -397,10 +418,14 @@ mod hidden_niche {
|
||||
use std::num::NonZeroUsize;
|
||||
|
||||
#[repr(transparent)]
|
||||
struct Transparent { x: NonZeroUsize }
|
||||
struct Transparent {
|
||||
x: NonZeroUsize,
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
struct TransparentNoNiche { y: UnsafeCell<NonZeroUsize> }
|
||||
struct TransparentNoNiche {
|
||||
y: UnsafeCell<NonZeroUsize>,
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
fn hidden_niche_transparent() -> Option<Transparent>;
|
||||
|
@ -130,7 +130,7 @@ LL | fn transparent_incorrect() -> isize;
|
||||
found `unsafe extern "C" fn() -> isize`
|
||||
|
||||
warning: `missing_return_type` redeclared with a different signature
|
||||
--> $DIR/clashing-extern-fn.rs:238:13
|
||||
--> $DIR/clashing-extern-fn.rs:259:13
|
||||
|
|
||||
LL | fn missing_return_type() -> usize;
|
||||
| ---------------------------------- `missing_return_type` previously declared here
|
||||
@ -142,7 +142,7 @@ LL | fn missing_return_type();
|
||||
found `unsafe extern "C" fn()`
|
||||
|
||||
warning: `non_zero_usize` redeclared with a different signature
|
||||
--> $DIR/clashing-extern-fn.rs:256:13
|
||||
--> $DIR/clashing-extern-fn.rs:277:13
|
||||
|
|
||||
LL | fn non_zero_usize() -> core::num::NonZeroUsize;
|
||||
| ----------------------------------------------- `non_zero_usize` previously declared here
|
||||
@ -154,7 +154,7 @@ LL | fn non_zero_usize() -> usize;
|
||||
found `unsafe extern "C" fn() -> usize`
|
||||
|
||||
warning: `non_null_ptr` redeclared with a different signature
|
||||
--> $DIR/clashing-extern-fn.rs:258:13
|
||||
--> $DIR/clashing-extern-fn.rs:279:13
|
||||
|
|
||||
LL | fn non_null_ptr() -> core::ptr::NonNull<usize>;
|
||||
| ----------------------------------------------- `non_null_ptr` previously declared here
|
||||
@ -166,7 +166,7 @@ LL | fn non_null_ptr() -> *const usize;
|
||||
found `unsafe extern "C" fn() -> *const usize`
|
||||
|
||||
warning: `option_non_zero_usize_incorrect` redeclared with a different signature
|
||||
--> $DIR/clashing-extern-fn.rs:356:13
|
||||
--> $DIR/clashing-extern-fn.rs:377:13
|
||||
|
|
||||
LL | fn option_non_zero_usize_incorrect() -> usize;
|
||||
| ---------------------------------------------- `option_non_zero_usize_incorrect` previously declared here
|
||||
@ -178,7 +178,7 @@ LL | fn option_non_zero_usize_incorrect() -> isize;
|
||||
found `unsafe extern "C" fn() -> isize`
|
||||
|
||||
warning: `option_non_null_ptr_incorrect` redeclared with a different signature
|
||||
--> $DIR/clashing-extern-fn.rs:358:13
|
||||
--> $DIR/clashing-extern-fn.rs:379:13
|
||||
|
|
||||
LL | fn option_non_null_ptr_incorrect() -> *const usize;
|
||||
| --------------------------------------------------- `option_non_null_ptr_incorrect` previously declared here
|
||||
@ -190,7 +190,7 @@ LL | fn option_non_null_ptr_incorrect() -> *const isize;
|
||||
found `unsafe extern "C" fn() -> *const isize`
|
||||
|
||||
warning: `hidden_niche_transparent_no_niche` redeclared with a different signature
|
||||
--> $DIR/clashing-extern-fn.rs:408:13
|
||||
--> $DIR/clashing-extern-fn.rs:433:13
|
||||
|
|
||||
LL | fn hidden_niche_transparent_no_niche() -> usize;
|
||||
| ------------------------------------------------ `hidden_niche_transparent_no_niche` previously declared here
|
||||
@ -202,7 +202,7 @@ LL | fn hidden_niche_transparent_no_niche() -> Option<TransparentNoN
|
||||
found `unsafe extern "C" fn() -> Option<TransparentNoNiche>`
|
||||
|
||||
warning: `hidden_niche_unsafe_cell` redeclared with a different signature
|
||||
--> $DIR/clashing-extern-fn.rs:412:13
|
||||
--> $DIR/clashing-extern-fn.rs:437:13
|
||||
|
|
||||
LL | fn hidden_niche_unsafe_cell() -> usize;
|
||||
| --------------------------------------- `hidden_niche_unsafe_cell` previously declared here
|
||||
@ -214,7 +214,7 @@ LL | fn hidden_niche_unsafe_cell() -> Option<UnsafeCell<NonZeroUsize
|
||||
found `unsafe extern "C" fn() -> Option<UnsafeCell<NonZeroUsize>>`
|
||||
|
||||
warning: `extern` block uses type `Option<TransparentNoNiche>`, which is not FFI-safe
|
||||
--> $DIR/clashing-extern-fn.rs:408:55
|
||||
--> $DIR/clashing-extern-fn.rs:433:55
|
||||
|
|
||||
LL | fn hidden_niche_transparent_no_niche() -> Option<TransparentNoNiche>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
@ -224,7 +224,7 @@ LL | fn hidden_niche_transparent_no_niche() -> Option<TransparentNoN
|
||||
= note: `#[warn(improper_ctypes)]` on by default
|
||||
|
||||
warning: `extern` block uses type `Option<UnsafeCell<NonZeroUsize>>`, which is not FFI-safe
|
||||
--> $DIR/clashing-extern-fn.rs:412:46
|
||||
--> $DIR/clashing-extern-fn.rs:437:46
|
||||
|
|
||||
LL | fn hidden_niche_unsafe_cell() -> Option<UnsafeCell<NonZeroUsize>>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||
|
Loading…
Reference in New Issue
Block a user