about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorManish Goregaokar <manishsmail@gmail.com>2020-07-14 13:19:39 -0700
committerGitHub <noreply@github.com>2020-07-14 13:19:39 -0700
commitdbe7ed33cd14166ed52ff02f4db145e199c348cd (patch)
tree873851698947a162abdd85a971618981b1e19b2a /src
parentc4fcf5a7a4e70073e2229641fedfd57a63f3dfed (diff)
parentcccc3109ffc61a742bcaa9241e457ceadb96ce95 (diff)
downloadrust-dbe7ed33cd14166ed52ff02f4db145e199c348cd.tar.gz
rust-dbe7ed33cd14166ed52ff02f4db145e199c348cd.zip
Rollup merge of #74340 - davidtwco:issue-73747-improper-ctypes-defns-is-zst-with-params, r=pnkfelix
lint: use `transparent_newtype_field` to avoid ICE

Fixes #73747.

This PR re-uses the `transparent_newtype_field` function instead of manually calling `is_zst` on normalized fields to determine which field in a transparent type is the non-zero-sized field, thus avoiding an ICE.
Diffstat (limited to 'src')
-rw-r--r--src/librustc_lint/types.rs32
-rw-r--r--src/test/ui/lint/lint-ctypes-73747.rs14
2 files changed, 30 insertions, 16 deletions
diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs
index b3015dcc2ae..46741fcf2ba 100644
--- a/src/librustc_lint/types.rs
+++ b/src/librustc_lint/types.rs
@@ -531,23 +531,23 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
         match ty.kind {
             ty::FnPtr(_) => true,
             ty::Ref(..) => true,
-            ty::Adt(field_def, substs) if field_def.repr.transparent() && !field_def.is_union() => {
-                for field in field_def.all_fields() {
-                    let field_ty = self.cx.tcx.normalize_erasing_regions(
-                        self.cx.param_env,
-                        field.ty(self.cx.tcx, substs),
-                    );
-                    if field_ty.is_zst(self.cx.tcx, field.did) {
-                        continue;
-                    }
+            ty::Adt(def, substs) if def.repr.transparent() && !def.is_union() => {
+                let guaranteed_nonnull_optimization = self
+                    .cx
+                    .tcx
+                    .get_attrs(def.did)
+                    .iter()
+                    .any(|a| a.check_name(sym::rustc_nonnull_optimization_guaranteed));
+
+                if guaranteed_nonnull_optimization {
+                    return true;
+                }
 
-                    let attrs = self.cx.tcx.get_attrs(field_def.did);
-                    if attrs
-                        .iter()
-                        .any(|a| a.check_name(sym::rustc_nonnull_optimization_guaranteed))
-                        || self.ty_is_known_nonnull(field_ty)
-                    {
-                        return true;
+                for variant in &def.variants {
+                    if let Some(field) = variant.transparent_newtype_field(self.cx.tcx) {
+                        if self.ty_is_known_nonnull(field.ty(self.cx.tcx, substs)) {
+                            return true;
+                        }
                     }
                 }
 
diff --git a/src/test/ui/lint/lint-ctypes-73747.rs b/src/test/ui/lint/lint-ctypes-73747.rs
new file mode 100644
index 00000000000..293ffd5c28e
--- /dev/null
+++ b/src/test/ui/lint/lint-ctypes-73747.rs
@@ -0,0 +1,14 @@
+// check-pass
+
+#[repr(transparent)]
+struct NonNullRawComPtr<T: ComInterface> {
+    inner: std::ptr::NonNull<<T as ComInterface>::VTable>,
+}
+
+trait ComInterface {
+    type VTable;
+}
+
+extern "C" fn invoke<T: ComInterface>(_: Option<NonNullRawComPtr<T>>) {}
+
+fn main() {}