Skip to content

Commit

Permalink
fix ClashingExternDeclarations lint ICE
Browse files Browse the repository at this point in the history
  • Loading branch information
DaniPopes committed Mar 19, 2023
1 parent 8826b68 commit 8ca0f61
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 26 deletions.
24 changes: 11 additions & 13 deletions compiler/rustc_lint/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2781,8 +2781,8 @@ 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;
// Also returns whether this type is a ZST.
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 +2792,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 +2813,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

0 comments on commit 8ca0f61

Please sign in to comment.