Also handle transparent single-variant enums
This commit is contained in:
parent
f38eb93634
commit
671770ed85
@ -38,6 +38,7 @@ use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::{ForeignItemKind, GenericParamKind, PatKind};
|
||||
use rustc_hir::{HirId, HirIdSet, Node};
|
||||
use rustc_index::vec::Idx;
|
||||
use rustc_middle::lint::LintDiagnosticBuilder;
|
||||
use rustc_middle::ty::subst::{GenericArgKind, Subst};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
@ -2171,18 +2172,19 @@ impl ClashingExternDeclarations {
|
||||
loop {
|
||||
if let ty::Adt(def, substs) = ty.kind {
|
||||
let is_transparent = def.subst(tcx, substs).repr.transparent();
|
||||
let is_enum = def.is_enum();
|
||||
let is_non_null = crate::types::guaranteed_nonnull_optimization(tcx, &def);
|
||||
debug!(
|
||||
"non_transparent_ty({:?}) -- type is transparent? {}, type is enum? {}, type is non-null? {}",
|
||||
ty, is_transparent, is_enum, is_non_null
|
||||
"non_transparent_ty({:?}) -- type is transparent? {}, type is non-null? {}",
|
||||
ty, is_transparent, is_non_null
|
||||
);
|
||||
if is_transparent && !is_enum && !is_non_null {
|
||||
ty = def
|
||||
.non_enum_variant()
|
||||
.transparent_newtype_field(tcx)
|
||||
.unwrap()
|
||||
.ty(tcx, substs);
|
||||
if is_transparent && !is_non_null {
|
||||
debug_assert!(def.variants.len() == 1);
|
||||
let v = &def.variants[VariantIdx::new(0)];
|
||||
assert!(
|
||||
v.fields.len() > 0,
|
||||
"single-variant transparent structure with zero-sized field"
|
||||
);
|
||||
ty = v.transparent_newtype_field(tcx).unwrap().ty(tcx, substs);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -182,7 +182,9 @@ mod same_sized_members_clash {
|
||||
y: f32,
|
||||
z: f32,
|
||||
}
|
||||
extern "C" { fn origin() -> Point3; }
|
||||
extern "C" {
|
||||
fn origin() -> Point3;
|
||||
}
|
||||
}
|
||||
mod b {
|
||||
#[repr(C)]
|
||||
@ -191,8 +193,9 @@ mod same_sized_members_clash {
|
||||
y: i32,
|
||||
z: i32, // NOTE: Incorrectly redeclared as i32
|
||||
}
|
||||
extern "C" { fn origin() -> Point3; }
|
||||
//~^ WARN `origin` redeclared with a different signature
|
||||
extern "C" {
|
||||
fn origin() -> Point3; //~ WARN `origin` redeclared with a different signature
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -312,6 +315,22 @@ mod non_zero_transparent {
|
||||
fn f3() -> core::ptr::NonNull<i32>;
|
||||
}
|
||||
}
|
||||
|
||||
mod a4 {
|
||||
#[repr(transparent)]
|
||||
enum E {
|
||||
X(std::num::NonZeroUsize),
|
||||
}
|
||||
extern "C" {
|
||||
fn f4() -> E;
|
||||
}
|
||||
}
|
||||
|
||||
mod b4 {
|
||||
extern "C" {
|
||||
fn f4() -> std::num::NonZeroUsize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod null_optimised_enums {
|
||||
|
@ -106,19 +106,19 @@ LL | fn draw_point(p: Point);
|
||||
found `unsafe extern "C" fn(sameish_members::b::Point)`
|
||||
|
||||
warning: `origin` redeclared with a different signature
|
||||
--> $DIR/clashing-extern-fn.rs:194:22
|
||||
--> $DIR/clashing-extern-fn.rs:197:13
|
||||
|
|
||||
LL | extern "C" { fn origin() -> Point3; }
|
||||
| ---------------------- `origin` previously declared here
|
||||
LL | fn origin() -> Point3;
|
||||
| ---------------------- `origin` previously declared here
|
||||
...
|
||||
LL | extern "C" { fn origin() -> Point3; }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
|
||||
LL | fn origin() -> Point3;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
|
||||
|
|
||||
= note: expected `unsafe extern "C" fn() -> same_sized_members_clash::a::Point3`
|
||||
found `unsafe extern "C" fn() -> same_sized_members_clash::b::Point3`
|
||||
|
||||
warning: `transparent_incorrect` redeclared with a different signature
|
||||
--> $DIR/clashing-extern-fn.rs:217:13
|
||||
--> $DIR/clashing-extern-fn.rs:220:13
|
||||
|
|
||||
LL | fn transparent_incorrect() -> T;
|
||||
| -------------------------------- `transparent_incorrect` previously declared here
|
||||
@ -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:235:13
|
||||
--> $DIR/clashing-extern-fn.rs:238: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:253:13
|
||||
--> $DIR/clashing-extern-fn.rs:256: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:255:13
|
||||
--> $DIR/clashing-extern-fn.rs:258: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:337:13
|
||||
--> $DIR/clashing-extern-fn.rs:356: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:339:13
|
||||
--> $DIR/clashing-extern-fn.rs:358:13
|
||||
|
|
||||
LL | fn option_non_null_ptr_incorrect() -> *const usize;
|
||||
| --------------------------------------------------- `option_non_null_ptr_incorrect` previously declared here
|
||||
|
Loading…
Reference in New Issue
Block a user