]> git.lizzy.rs Git - rust.git/commitdiff
Also handle transparent single-variant enums
authorjumbatm <30644300+jumbatm@users.noreply.github.com>
Tue, 25 Aug 2020 04:00:24 +0000 (14:00 +1000)
committerjumbatm <30644300+jumbatm@users.noreply.github.com>
Tue, 25 Aug 2020 13:51:30 +0000 (23:51 +1000)
src/librustc_lint/builtin.rs
src/test/ui/lint/clashing-extern-fn.rs
src/test/ui/lint/clashing-extern-fn.stderr

index bfdf3e3b3956a2f2351153369e19384b47a16ffd..f51d7662d058c8dad70b2f867adb03beedd13d26 100644 (file)
@@ -38,6 +38,7 @@
 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 @@ fn structurally_same_type_impl<'tcx>(
                 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;
                         }
                     }
index a2de01254477df330e3ada3948559d7170e270c2..79e3b4cbf70efc9f48fe84fff3d072f0340fa4ca 100644 (file)
@@ -182,7 +182,9 @@ struct Point3 {
             y: f32,
             z: f32,
         }
-        extern "C" { fn origin() -> Point3; }
+        extern "C" {
+            fn origin() -> Point3;
+        }
     }
     mod b {
         #[repr(C)]
@@ -191,8 +193,9 @@ struct Point3 {
             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 b3 {
             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 {
index f2e53e4a3cc0e512171661ee8cf8d32a3b2ca2b5..0a18f05ba2903ca915219a80db4fd94fbd35ede1 100644 (file)
@@ -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