about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2023-03-20 07:10:34 +0100
committerGitHub <noreply@github.com>2023-03-20 07:10:34 +0100
commiteb1f8dc2cb3b0a99d7fac7bac9e2bfba53c8fc0b (patch)
treefc4669a4aa99a27c7dd9d13e9d477768e7e220b4 /compiler
parentcd9fadea5b494c8b8b597289230c7a681089b8a7 (diff)
parent7ab612a7eea5151ed0a47fd7b98aff5e114b3e07 (diff)
downloadrust-eb1f8dc2cb3b0a99d7fac7bac9e2bfba53c8fc0b.tar.gz
rust-eb1f8dc2cb3b0a99d7fac7bac9e2bfba53c8fc0b.zip
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`
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_lint/src/builtin.rs23
1 files changed, 10 insertions, 13 deletions
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 5b2100b5da9..b1ff76865ab 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -2781,8 +2781,7 @@ 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;
+            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();
@@ -2792,14 +2791,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);
@@ -2813,10 +2812,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 {