about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFabian Wolff <fabian.wolff@alumni.ethz.ch>2021-07-27 23:40:32 +0200
committerFabian Wolff <fabian.wolff@alumni.ethz.ch>2021-07-31 15:57:51 +0200
commit4e76c3820fea97e06f08555d4eeee3de3be4eb5a (patch)
treee27651b61975fc2f601d5aefa372c06d727bc53c
parent7069a8c2b78c5d23205de1cabb4c2a65229dbd8f (diff)
downloadrust-4e76c3820fea97e06f08555d4eeee3de3be4eb5a.tar.gz
rust-4e76c3820fea97e06f08555d4eeee3de3be4eb5a.zip
Fix ICE in `improper_ctypes_definitions` lint with all-ZST transparent types
-rw-r--r--compiler/rustc_lint/src/types.rs10
-rw-r--r--src/test/ui/repr/repr-transparent-issue-87496.rs12
-rw-r--r--src/test/ui/repr/repr-transparent-issue-87496.stderr16
3 files changed, 36 insertions, 2 deletions
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index a3a87a48768..639fe5ca2a4 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -851,12 +851,18 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
         use FfiResult::*;
 
         if def.repr.transparent() {
-            // Can assume that only one field is not a ZST, so only check
+            // Can assume that at most one field is not a ZST, so only check
             // that field's type for FFI-safety.
             if let Some(field) = transparent_newtype_field(self.cx.tcx, variant) {
                 self.check_field_type_for_ffi(cache, field, substs)
             } else {
-                bug!("malformed transparent type");
+                // All fields are ZSTs; this means that the type should behave
+                // like (), which is FFI-unsafe
+                FfiUnsafe {
+                    ty,
+                    reason: "this struct contains only zero-sized fields".into(),
+                    help: None,
+                }
             }
         } else {
             // We can't completely trust repr(C) markings; make sure the fields are
diff --git a/src/test/ui/repr/repr-transparent-issue-87496.rs b/src/test/ui/repr/repr-transparent-issue-87496.rs
new file mode 100644
index 00000000000..a4dd45c63f5
--- /dev/null
+++ b/src/test/ui/repr/repr-transparent-issue-87496.rs
@@ -0,0 +1,12 @@
+// Regression test for the ICE described in #87496.
+
+// check-pass
+
+#[repr(transparent)]
+struct TransparentCustomZst(());
+extern "C" {
+    fn good17(p: TransparentCustomZst);
+    //~^ WARNING: `extern` block uses type `TransparentCustomZst`, which is not FFI-safe
+}
+
+fn main() {}
diff --git a/src/test/ui/repr/repr-transparent-issue-87496.stderr b/src/test/ui/repr/repr-transparent-issue-87496.stderr
new file mode 100644
index 00000000000..c488755cc24
--- /dev/null
+++ b/src/test/ui/repr/repr-transparent-issue-87496.stderr
@@ -0,0 +1,16 @@
+warning: `extern` block uses type `TransparentCustomZst`, which is not FFI-safe
+  --> $DIR/repr-transparent-issue-87496.rs:8:18
+   |
+LL |     fn good17(p: TransparentCustomZst);
+   |                  ^^^^^^^^^^^^^^^^^^^^ not FFI-safe
+   |
+   = note: `#[warn(improper_ctypes)]` on by default
+   = note: this struct contains only zero-sized fields
+note: the type is defined here
+  --> $DIR/repr-transparent-issue-87496.rs:6:1
+   |
+LL | struct TransparentCustomZst(());
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: 1 warning emitted
+