diff options
| author | jumbatm <30644300+jumbatm@users.noreply.github.com> | 2020-08-25 14:00:24 +1000 |
|---|---|---|
| committer | jumbatm <30644300+jumbatm@users.noreply.github.com> | 2020-08-25 23:51:30 +1000 |
| commit | 671770ed852daf803e6a49fc9b622a4a2e478efb (patch) | |
| tree | 0de16388d6bf618d0a7e666fdc94547a6d8fe743 | |
| parent | f38eb93634b844ee8351501502f5331b04f063a5 (diff) | |
| download | rust-671770ed852daf803e6a49fc9b622a4a2e478efb.tar.gz rust-671770ed852daf803e6a49fc9b622a4a2e478efb.zip | |
Also handle transparent single-variant enums
| -rw-r--r-- | src/librustc_lint/builtin.rs | 20 | ||||
| -rw-r--r-- | src/test/ui/lint/clashing-extern-fn.rs | 25 | ||||
| -rw-r--r-- | src/test/ui/lint/clashing-extern-fn.stderr | 22 |
3 files changed, 44 insertions, 23 deletions
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index bfdf3e3b395..f51d7662d05 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -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; } } diff --git a/src/test/ui/lint/clashing-extern-fn.rs b/src/test/ui/lint/clashing-extern-fn.rs index a2de0125447..79e3b4cbf70 100644 --- a/src/test/ui/lint/clashing-extern-fn.rs +++ b/src/test/ui/lint/clashing-extern-fn.rs @@ -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 { diff --git a/src/test/ui/lint/clashing-extern-fn.stderr b/src/test/ui/lint/clashing-extern-fn.stderr index f2e53e4a3cc..0a18f05ba29 100644 --- a/src/test/ui/lint/clashing-extern-fn.stderr +++ b/src/test/ui/lint/clashing-extern-fn.stderr @@ -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 |
