about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorDavid Wood <david@davidtw.co>2020-06-12 16:14:05 +0100
committerDavid Wood <david@davidtw.co>2020-06-19 11:16:16 +0100
commita730d888aee99f9a556dae799deadacb83c34d0e (patch)
treeb222233424e47cec2374b29d4cace7e875772b72 /src
parent0cccaa0a27499f742ed4dbf4b5d09beee08eb2d6 (diff)
downloadrust-a730d888aee99f9a556dae799deadacb83c34d0e.tar.gz
rust-a730d888aee99f9a556dae799deadacb83c34d0e.zip
ty: simplify `transparent_newtype_field`
This commit removes the normalization from `transparent_newtype_field` -
turns out it wasn't necessary and that makes it a bunch simpler -
particularly when handling projections.

Signed-off-by: David Wood <david@davidtw.co>
Diffstat (limited to 'src')
-rw-r--r--src/librustc_lint/types.rs2
-rw-r--r--src/librustc_middle/ty/mod.rs14
-rw-r--r--src/test/ui/lint/lint-ctypes-73249-4.rs24
3 files changed, 26 insertions, 14 deletions
diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs
index b20bf432614..b490c06403d 100644
--- a/src/librustc_lint/types.rs
+++ b/src/librustc_lint/types.rs
@@ -627,7 +627,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
         if def.repr.transparent() {
             // Can assume that only one field is not a ZST, so only check
             // that field's type for FFI-safety.
-            if let Some(field) = variant.transparent_newtype_field(self.cx.tcx, self.cx.param_env) {
+            if let Some(field) = variant.transparent_newtype_field(self.cx.tcx) {
                 self.check_field_type_for_ffi(cache, field, substs)
             } else {
                 bug!("malformed transparent type");
diff --git a/src/librustc_middle/ty/mod.rs b/src/librustc_middle/ty/mod.rs
index 30643165ce9..b4e3e6ab5ab 100644
--- a/src/librustc_middle/ty/mod.rs
+++ b/src/librustc_middle/ty/mod.rs
@@ -1810,21 +1810,9 @@ impl<'tcx> VariantDef {
 
     /// `repr(transparent)` structs can have a single non-ZST field, this function returns that
     /// field.
-    pub fn transparent_newtype_field(
-        &self,
-        tcx: TyCtxt<'tcx>,
-        param_env: ParamEnv<'tcx>,
-    ) -> Option<&FieldDef> {
+    pub fn transparent_newtype_field(&self, tcx: TyCtxt<'tcx>) -> Option<&FieldDef> {
         for field in &self.fields {
             let field_ty = field.ty(tcx, InternalSubsts::identity_for_item(tcx, self.def_id));
-
-            // `normalize_erasing_regions` will fail for projections that contain generic
-            // parameters, so check these before normalizing.
-            if field_ty.has_projections() && field_ty.needs_subst() {
-                return Some(field);
-            }
-
-            let field_ty = tcx.normalize_erasing_regions(param_env, field_ty);
             if !field_ty.is_zst(tcx, self.def_id) {
                 return Some(field);
             }
diff --git a/src/test/ui/lint/lint-ctypes-73249-4.rs b/src/test/ui/lint/lint-ctypes-73249-4.rs
new file mode 100644
index 00000000000..6c72bd691b1
--- /dev/null
+++ b/src/test/ui/lint/lint-ctypes-73249-4.rs
@@ -0,0 +1,24 @@
+// check-pass
+#![deny(improper_ctypes)]
+
+use std::marker::PhantomData;
+
+trait Foo {
+    type Assoc;
+}
+
+impl Foo for () {
+    type Assoc = PhantomData<()>;
+}
+
+#[repr(transparent)]
+struct Wow<T> where T: Foo<Assoc = PhantomData<T>> {
+    x: <T as Foo>::Assoc,
+    v: u32,
+}
+
+extern "C" {
+    fn test(v: Wow<()>);
+}
+
+fn main() {}