about summary refs log tree commit diff
diff options
context:
space:
mode:
authorManish Goregaokar <manishsmail@gmail.com>2020-06-27 22:29:59 -0700
committerGitHub <noreply@github.com>2020-06-27 22:29:59 -0700
commitd5205f23d3ba4b51e56b2c1a7ca68f8a1b9fa15f (patch)
tree4feb1ffaa67d20a85e50b8faec2c7b20b1ed3b9d
parentb236e49f097dbe7089d8349974f9c0bcd73993b2 (diff)
parenta6417b9c3822a08e27e0f556d76b880e26c0554d (diff)
downloadrust-d5205f23d3ba4b51e56b2c1a7ca68f8a1b9fa15f.tar.gz
rust-d5205f23d3ba4b51e56b2c1a7ca68f8a1b9fa15f.zip
Rollup merge of #73758 - davidtwco:issue-60855-remaining-reveal-all, r=matthewjasper
improper_ctypes: fix remaining `Reveal:All`

Fixes #60855.

This PR replaces the remaining uses of `ParamEnv::reveal_all` with `LateContext`'s `param_env` (normally `Reveal::UserFacing`) in the improper ctypes lint.
-rw-r--r--src/librustc_lint/types.rs128
1 files changed, 66 insertions, 62 deletions
diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs
index 814ca627e2c..d0275a0dd0d 100644
--- a/src/librustc_lint/types.rs
+++ b/src/librustc_lint/types.rs
@@ -11,7 +11,7 @@ use rustc_index::vec::Idx;
 use rustc_middle::mir::interpret::{sign_extend, truncate};
 use rustc_middle::ty::layout::{IntegerExt, SizeSkeleton};
 use rustc_middle::ty::subst::SubstsRef;
-use rustc_middle::ty::{self, AdtKind, ParamEnv, Ty, TyCtxt, TypeFoldable};
+use rustc_middle::ty::{self, AdtKind, Ty, TypeFoldable};
 use rustc_span::source_map;
 use rustc_span::symbol::sym;
 use rustc_span::{Span, DUMMY_SP};
@@ -525,78 +525,82 @@ enum FfiResult<'tcx> {
     FfiUnsafe { ty: Ty<'tcx>, reason: String, help: Option<String> },
 }
 
-fn ty_is_known_nonnull<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
-    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 =
-                    tcx.normalize_erasing_regions(ParamEnv::reveal_all(), field.ty(tcx, substs));
-                if field_ty.is_zst(tcx, field.did) {
-                    continue;
-                }
+impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
+    /// Is type known to be non-null?
+    fn ty_is_known_nonnull(&self, ty: Ty<'tcx>) -> bool {
+        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;
+                    }
 
-                let attrs = tcx.get_attrs(field_def.did);
-                if attrs.iter().any(|a| a.check_name(sym::rustc_nonnull_optimization_guaranteed))
-                    || ty_is_known_nonnull(tcx, field_ty)
-                {
-                    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;
+                    }
                 }
-            }
 
-            false
+                false
+            }
+            _ => false,
         }
-        _ => false,
     }
-}
 
-/// Check if this enum can be safely exported based on the
-/// "nullable pointer optimization". Currently restricted
-/// to function pointers, references, core::num::NonZero*,
-/// core::ptr::NonNull, and #[repr(transparent)] newtypes.
-/// FIXME: This duplicates code in codegen.
-fn is_repr_nullable_ptr<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    ty: Ty<'tcx>,
-    ty_def: &'tcx ty::AdtDef,
-    substs: SubstsRef<'tcx>,
-) -> bool {
-    if ty_def.variants.len() != 2 {
-        return false;
-    }
+    /// Check if this enum can be safely exported based on the "nullable pointer optimization".
+    /// Currently restricted to function pointers, references, `core::num::NonZero*`,
+    /// `core::ptr::NonNull`, and `#[repr(transparent)]` newtypes.
+    fn is_repr_nullable_ptr(
+        &self,
+        ty: Ty<'tcx>,
+        ty_def: &'tcx ty::AdtDef,
+        substs: SubstsRef<'tcx>,
+    ) -> bool {
+        if ty_def.variants.len() != 2 {
+            return false;
+        }
 
-    let get_variant_fields = |index| &ty_def.variants[VariantIdx::new(index)].fields;
-    let variant_fields = [get_variant_fields(0), get_variant_fields(1)];
-    let fields = if variant_fields[0].is_empty() {
-        &variant_fields[1]
-    } else if variant_fields[1].is_empty() {
-        &variant_fields[0]
-    } else {
-        return false;
-    };
+        let get_variant_fields = |index| &ty_def.variants[VariantIdx::new(index)].fields;
+        let variant_fields = [get_variant_fields(0), get_variant_fields(1)];
+        let fields = if variant_fields[0].is_empty() {
+            &variant_fields[1]
+        } else if variant_fields[1].is_empty() {
+            &variant_fields[0]
+        } else {
+            return false;
+        };
 
-    if fields.len() != 1 {
-        return false;
-    }
+        if fields.len() != 1 {
+            return false;
+        }
 
-    let field_ty = fields[0].ty(tcx, substs);
-    if !ty_is_known_nonnull(tcx, field_ty) {
-        return false;
-    }
+        let field_ty = fields[0].ty(self.cx.tcx, substs);
+        if !self.ty_is_known_nonnull(field_ty) {
+            return false;
+        }
 
-    // At this point, the field's type is known to be nonnull and the parent enum is Option-like.
-    // If the computed size for the field and the enum are different, the nonnull optimization isn't
-    // being applied (and we've got a problem somewhere).
-    let compute_size_skeleton = |t| SizeSkeleton::compute(t, tcx, ParamEnv::reveal_all()).unwrap();
-    if !compute_size_skeleton(ty).same_size(compute_size_skeleton(field_ty)) {
-        bug!("improper_ctypes: Option nonnull optimization not applied?");
-    }
+        // At this point, the field's type is known to be nonnull and the parent enum is
+        // Option-like. If the computed size for the field and the enum are different, the non-null
+        // optimization isn't being applied (and we've got a problem somewhere).
+        let compute_size_skeleton =
+            |t| SizeSkeleton::compute(t, self.cx.tcx, self.cx.param_env).unwrap();
+        if !compute_size_skeleton(ty).same_size(compute_size_skeleton(field_ty)) {
+            bug!("improper_ctypes: Option nonnull optimization not applied?");
+        }
 
-    true
-}
+        true
+    }
 
-impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
     /// Check if the type is array and emit an unsafe type lint.
     fn check_for_array_ty(&mut self, sp: Span, ty: Ty<'tcx>) -> bool {
         if let ty::Array(..) = ty.kind {
@@ -738,7 +742,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
                         // discriminant.
                         if !def.repr.c() && !def.repr.transparent() && def.repr.int.is_none() {
                             // Special-case types like `Option<extern fn()>`.
-                            if !is_repr_nullable_ptr(cx, ty, def, substs) {
+                            if !self.is_repr_nullable_ptr(ty, def, substs) {
                                 return FfiUnsafe {
                                     ty,
                                     reason: "enum has no representation hint".into(),