Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix ClashingExternDeclarations lint ICE #109370

Merged
merged 2 commits into from
Mar 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 10 additions & 13 deletions compiler/rustc_lint/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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);
Expand All @@ -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 {
Expand Down
33 changes: 29 additions & 4 deletions tests/ui/lint/clashing-extern-fn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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" {
Expand Down Expand Up @@ -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>;
Expand Down
18 changes: 9 additions & 9 deletions tests/ui/lint/clashing-extern-fn.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down