Skip to content

Commit eb1f8dc

Browse files
authored
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`
2 parents cd9fade + 7ab612a commit eb1f8dc

File tree

3 files changed

+48
-26
lines changed

3 files changed

+48
-26
lines changed

compiler/rustc_lint/src/builtin.rs

+10-13
Original file line numberDiff line numberDiff line change
@@ -2781,8 +2781,7 @@ impl ClashingExternDeclarations {
27812781

27822782
// Given a transparent newtype, reach through and grab the inner
27832783
// type unless the newtype makes the type non-null.
2784-
let non_transparent_ty = |ty: Ty<'tcx>| -> Ty<'tcx> {
2785-
let mut ty = ty;
2784+
let non_transparent_ty = |mut ty: Ty<'tcx>| -> Ty<'tcx> {
27862785
loop {
27872786
if let ty::Adt(def, substs) = *ty.kind() {
27882787
let is_transparent = def.repr().transparent();
@@ -2792,14 +2791,14 @@ impl ClashingExternDeclarations {
27922791
ty, is_transparent, is_non_null
27932792
);
27942793
if is_transparent && !is_non_null {
2795-
debug_assert!(def.variants().len() == 1);
2794+
debug_assert_eq!(def.variants().len(), 1);
27962795
let v = &def.variant(VariantIdx::new(0));
2797-
ty = transparent_newtype_field(tcx, v)
2798-
.expect(
2799-
"single-variant transparent structure with zero-sized field",
2800-
)
2801-
.ty(tcx, substs);
2802-
continue;
2796+
// continue with `ty`'s non-ZST field,
2797+
// otherwise `ty` is a ZST and we can return
2798+
if let Some(field) = transparent_newtype_field(tcx, v) {
2799+
ty = field.ty(tcx, substs);
2800+
continue;
2801+
}
28032802
}
28042803
}
28052804
debug!("non_transparent_ty -> {:?}", ty);
@@ -2813,10 +2812,8 @@ impl ClashingExternDeclarations {
28132812
if !seen_types.insert((a, b)) {
28142813
// We've encountered a cycle. There's no point going any further -- the types are
28152814
// structurally the same.
2816-
return true;
2817-
}
2818-
let tcx = cx.tcx;
2819-
if a == b {
2815+
true
2816+
} else if a == b {
28202817
// All nominally-same types are structurally same, too.
28212818
true
28222819
} else {

tests/ui/lint/clashing-extern-fn.rs

+29-4
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,8 @@ mod banana {
122122
weight: u32,
123123
length: u16,
124124
} // note: distinct type
125-
// This should not trigger the lint because two::Banana is structurally equivalent to
126-
// one::Banana.
125+
// This should not trigger the lint because two::Banana is structurally equivalent to
126+
// one::Banana.
127127
extern "C" {
128128
fn weigh_banana(count: *const Banana) -> u64;
129129
}
@@ -223,6 +223,27 @@ mod transparent {
223223
}
224224
}
225225

226+
#[allow(improper_ctypes)]
227+
mod zst {
228+
mod transparent {
229+
#[repr(transparent)]
230+
struct TransparentZst(());
231+
extern "C" {
232+
fn zst() -> ();
233+
fn transparent_zst() -> TransparentZst;
234+
}
235+
}
236+
237+
mod not_transparent {
238+
struct NotTransparentZst(());
239+
extern "C" {
240+
// These shouldn't warn since all return types are zero sized
241+
fn zst() -> NotTransparentZst;
242+
fn transparent_zst() -> NotTransparentZst;
243+
}
244+
}
245+
}
246+
226247
mod missing_return_type {
227248
mod a {
228249
extern "C" {
@@ -397,10 +418,14 @@ mod hidden_niche {
397418
use std::num::NonZeroUsize;
398419

399420
#[repr(transparent)]
400-
struct Transparent { x: NonZeroUsize }
421+
struct Transparent {
422+
x: NonZeroUsize,
423+
}
401424

402425
#[repr(transparent)]
403-
struct TransparentNoNiche { y: UnsafeCell<NonZeroUsize> }
426+
struct TransparentNoNiche {
427+
y: UnsafeCell<NonZeroUsize>,
428+
}
404429

405430
extern "C" {
406431
fn hidden_niche_transparent() -> Option<Transparent>;

tests/ui/lint/clashing-extern-fn.stderr

+9-9
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ LL | fn transparent_incorrect() -> isize;
130130
found `unsafe extern "C" fn() -> isize`
131131

132132
warning: `missing_return_type` redeclared with a different signature
133-
--> $DIR/clashing-extern-fn.rs:238:13
133+
--> $DIR/clashing-extern-fn.rs:259:13
134134
|
135135
LL | fn missing_return_type() -> usize;
136136
| ---------------------------------- `missing_return_type` previously declared here
@@ -142,7 +142,7 @@ LL | fn missing_return_type();
142142
found `unsafe extern "C" fn()`
143143

144144
warning: `non_zero_usize` redeclared with a different signature
145-
--> $DIR/clashing-extern-fn.rs:256:13
145+
--> $DIR/clashing-extern-fn.rs:277:13
146146
|
147147
LL | fn non_zero_usize() -> core::num::NonZeroUsize;
148148
| ----------------------------------------------- `non_zero_usize` previously declared here
@@ -154,7 +154,7 @@ LL | fn non_zero_usize() -> usize;
154154
found `unsafe extern "C" fn() -> usize`
155155

156156
warning: `non_null_ptr` redeclared with a different signature
157-
--> $DIR/clashing-extern-fn.rs:258:13
157+
--> $DIR/clashing-extern-fn.rs:279:13
158158
|
159159
LL | fn non_null_ptr() -> core::ptr::NonNull<usize>;
160160
| ----------------------------------------------- `non_null_ptr` previously declared here
@@ -166,7 +166,7 @@ LL | fn non_null_ptr() -> *const usize;
166166
found `unsafe extern "C" fn() -> *const usize`
167167

168168
warning: `option_non_zero_usize_incorrect` redeclared with a different signature
169-
--> $DIR/clashing-extern-fn.rs:356:13
169+
--> $DIR/clashing-extern-fn.rs:377:13
170170
|
171171
LL | fn option_non_zero_usize_incorrect() -> usize;
172172
| ---------------------------------------------- `option_non_zero_usize_incorrect` previously declared here
@@ -178,7 +178,7 @@ LL | fn option_non_zero_usize_incorrect() -> isize;
178178
found `unsafe extern "C" fn() -> isize`
179179

180180
warning: `option_non_null_ptr_incorrect` redeclared with a different signature
181-
--> $DIR/clashing-extern-fn.rs:358:13
181+
--> $DIR/clashing-extern-fn.rs:379:13
182182
|
183183
LL | fn option_non_null_ptr_incorrect() -> *const usize;
184184
| --------------------------------------------------- `option_non_null_ptr_incorrect` previously declared here
@@ -190,7 +190,7 @@ LL | fn option_non_null_ptr_incorrect() -> *const isize;
190190
found `unsafe extern "C" fn() -> *const isize`
191191

192192
warning: `hidden_niche_transparent_no_niche` redeclared with a different signature
193-
--> $DIR/clashing-extern-fn.rs:408:13
193+
--> $DIR/clashing-extern-fn.rs:433:13
194194
|
195195
LL | fn hidden_niche_transparent_no_niche() -> usize;
196196
| ------------------------------------------------ `hidden_niche_transparent_no_niche` previously declared here
@@ -202,7 +202,7 @@ LL | fn hidden_niche_transparent_no_niche() -> Option<TransparentNoN
202202
found `unsafe extern "C" fn() -> Option<TransparentNoNiche>`
203203

204204
warning: `hidden_niche_unsafe_cell` redeclared with a different signature
205-
--> $DIR/clashing-extern-fn.rs:412:13
205+
--> $DIR/clashing-extern-fn.rs:437:13
206206
|
207207
LL | fn hidden_niche_unsafe_cell() -> usize;
208208
| --------------------------------------- `hidden_niche_unsafe_cell` previously declared here
@@ -214,7 +214,7 @@ LL | fn hidden_niche_unsafe_cell() -> Option<UnsafeCell<NonZeroUsize
214214
found `unsafe extern "C" fn() -> Option<UnsafeCell<NonZeroUsize>>`
215215

216216
warning: `extern` block uses type `Option<TransparentNoNiche>`, which is not FFI-safe
217-
--> $DIR/clashing-extern-fn.rs:408:55
217+
--> $DIR/clashing-extern-fn.rs:433:55
218218
|
219219
LL | fn hidden_niche_transparent_no_niche() -> Option<TransparentNoNiche>;
220220
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -224,7 +224,7 @@ LL | fn hidden_niche_transparent_no_niche() -> Option<TransparentNoN
224224
= note: `#[warn(improper_ctypes)]` on by default
225225

226226
warning: `extern` block uses type `Option<UnsafeCell<NonZeroUsize>>`, which is not FFI-safe
227-
--> $DIR/clashing-extern-fn.rs:412:46
227+
--> $DIR/clashing-extern-fn.rs:437:46
228228
|
229229
LL | fn hidden_niche_unsafe_cell() -> Option<UnsafeCell<NonZeroUsize>>;
230230
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe

0 commit comments

Comments
 (0)