mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-18 01:44:04 +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
|
// Given a transparent newtype, reach through and grab the inner
|
||||||
// type unless the newtype makes the type non-null.
|
// type unless the newtype makes the type non-null.
|
||||||
let non_transparent_ty = |ty: Ty<'tcx>| -> Ty<'tcx> {
|
let non_transparent_ty = |mut ty: Ty<'tcx>| -> Ty<'tcx> {
|
||||||
let mut ty = ty;
|
|
||||||
loop {
|
loop {
|
||||||
if let ty::Adt(def, substs) = *ty.kind() {
|
if let ty::Adt(def, substs) = *ty.kind() {
|
||||||
let is_transparent = def.repr().transparent();
|
let is_transparent = def.repr().transparent();
|
||||||
@ -2792,14 +2791,14 @@ impl ClashingExternDeclarations {
|
|||||||
ty, is_transparent, is_non_null
|
ty, is_transparent, is_non_null
|
||||||
);
|
);
|
||||||
if 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));
|
let v = &def.variant(VariantIdx::new(0));
|
||||||
ty = transparent_newtype_field(tcx, v)
|
// continue with `ty`'s non-ZST field,
|
||||||
.expect(
|
// otherwise `ty` is a ZST and we can return
|
||||||
"single-variant transparent structure with zero-sized field",
|
if let Some(field) = transparent_newtype_field(tcx, v) {
|
||||||
)
|
ty = field.ty(tcx, substs);
|
||||||
.ty(tcx, substs);
|
continue;
|
||||||
continue;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
debug!("non_transparent_ty -> {:?}", ty);
|
debug!("non_transparent_ty -> {:?}", ty);
|
||||||
@ -2813,10 +2812,8 @@ impl ClashingExternDeclarations {
|
|||||||
if !seen_types.insert((a, b)) {
|
if !seen_types.insert((a, b)) {
|
||||||
// We've encountered a cycle. There's no point going any further -- the types are
|
// We've encountered a cycle. There's no point going any further -- the types are
|
||||||
// structurally the same.
|
// structurally the same.
|
||||||
return true;
|
true
|
||||||
}
|
} else if a == b {
|
||||||
let tcx = cx.tcx;
|
|
||||||
if a == b {
|
|
||||||
// All nominally-same types are structurally same, too.
|
// All nominally-same types are structurally same, too.
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
|
@ -122,8 +122,8 @@ mod banana {
|
|||||||
weight: u32,
|
weight: u32,
|
||||||
length: u16,
|
length: u16,
|
||||||
} // note: distinct type
|
} // note: distinct type
|
||||||
// This should not trigger the lint because two::Banana is structurally equivalent to
|
// This should not trigger the lint because two::Banana is structurally equivalent to
|
||||||
// one::Banana.
|
// one::Banana.
|
||||||
extern "C" {
|
extern "C" {
|
||||||
fn weigh_banana(count: *const Banana) -> u64;
|
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 missing_return_type {
|
||||||
mod a {
|
mod a {
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -397,10 +418,14 @@ mod hidden_niche {
|
|||||||
use std::num::NonZeroUsize;
|
use std::num::NonZeroUsize;
|
||||||
|
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
struct Transparent { x: NonZeroUsize }
|
struct Transparent {
|
||||||
|
x: NonZeroUsize,
|
||||||
|
}
|
||||||
|
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
struct TransparentNoNiche { y: UnsafeCell<NonZeroUsize> }
|
struct TransparentNoNiche {
|
||||||
|
y: UnsafeCell<NonZeroUsize>,
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
fn hidden_niche_transparent() -> Option<Transparent>;
|
fn hidden_niche_transparent() -> Option<Transparent>;
|
||||||
|
@ -130,7 +130,7 @@ LL | fn transparent_incorrect() -> isize;
|
|||||||
found `unsafe extern "C" fn() -> isize`
|
found `unsafe extern "C" fn() -> isize`
|
||||||
|
|
||||||
warning: `missing_return_type` redeclared with a different signature
|
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;
|
LL | fn missing_return_type() -> usize;
|
||||||
| ---------------------------------- `missing_return_type` previously declared here
|
| ---------------------------------- `missing_return_type` previously declared here
|
||||||
@ -142,7 +142,7 @@ LL | fn missing_return_type();
|
|||||||
found `unsafe extern "C" fn()`
|
found `unsafe extern "C" fn()`
|
||||||
|
|
||||||
warning: `non_zero_usize` redeclared with a different signature
|
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;
|
LL | fn non_zero_usize() -> core::num::NonZeroUsize;
|
||||||
| ----------------------------------------------- `non_zero_usize` previously declared here
|
| ----------------------------------------------- `non_zero_usize` previously declared here
|
||||||
@ -154,7 +154,7 @@ LL | fn non_zero_usize() -> usize;
|
|||||||
found `unsafe extern "C" fn() -> usize`
|
found `unsafe extern "C" fn() -> usize`
|
||||||
|
|
||||||
warning: `non_null_ptr` redeclared with a different signature
|
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>;
|
LL | fn non_null_ptr() -> core::ptr::NonNull<usize>;
|
||||||
| ----------------------------------------------- `non_null_ptr` previously declared here
|
| ----------------------------------------------- `non_null_ptr` previously declared here
|
||||||
@ -166,7 +166,7 @@ LL | fn non_null_ptr() -> *const usize;
|
|||||||
found `unsafe extern "C" fn() -> *const usize`
|
found `unsafe extern "C" fn() -> *const usize`
|
||||||
|
|
||||||
warning: `option_non_zero_usize_incorrect` redeclared with a different signature
|
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;
|
LL | fn option_non_zero_usize_incorrect() -> usize;
|
||||||
| ---------------------------------------------- `option_non_zero_usize_incorrect` previously declared here
|
| ---------------------------------------------- `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`
|
found `unsafe extern "C" fn() -> isize`
|
||||||
|
|
||||||
warning: `option_non_null_ptr_incorrect` redeclared with a different signature
|
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;
|
LL | fn option_non_null_ptr_incorrect() -> *const usize;
|
||||||
| --------------------------------------------------- `option_non_null_ptr_incorrect` previously declared here
|
| --------------------------------------------------- `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`
|
found `unsafe extern "C" fn() -> *const isize`
|
||||||
|
|
||||||
warning: `hidden_niche_transparent_no_niche` redeclared with a different signature
|
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;
|
LL | fn hidden_niche_transparent_no_niche() -> usize;
|
||||||
| ------------------------------------------------ `hidden_niche_transparent_no_niche` previously declared here
|
| ------------------------------------------------ `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>`
|
found `unsafe extern "C" fn() -> Option<TransparentNoNiche>`
|
||||||
|
|
||||||
warning: `hidden_niche_unsafe_cell` redeclared with a different signature
|
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;
|
LL | fn hidden_niche_unsafe_cell() -> usize;
|
||||||
| --------------------------------------- `hidden_niche_unsafe_cell` previously declared here
|
| --------------------------------------- `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>>`
|
found `unsafe extern "C" fn() -> Option<UnsafeCell<NonZeroUsize>>`
|
||||||
|
|
||||||
warning: `extern` block uses type `Option<TransparentNoNiche>`, which is not FFI-safe
|
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>;
|
LL | fn hidden_niche_transparent_no_niche() -> Option<TransparentNoNiche>;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||||
@ -224,7 +224,7 @@ LL | fn hidden_niche_transparent_no_niche() -> Option<TransparentNoN
|
|||||||
= note: `#[warn(improper_ctypes)]` on by default
|
= note: `#[warn(improper_ctypes)]` on by default
|
||||||
|
|
||||||
warning: `extern` block uses type `Option<UnsafeCell<NonZeroUsize>>`, which is not FFI-safe
|
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>>;
|
LL | fn hidden_niche_unsafe_cell() -> Option<UnsafeCell<NonZeroUsize>>;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
|
||||||
|
Loading…
Reference in New Issue
Block a user