about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOliver Schneider <github35764891676564198441@oli-obk.de>2018-07-17 13:44:42 +0200
committerOliver Schneider <github35764891676564198441@oli-obk.de>2018-07-18 10:53:10 +0200
commitfdd719aa3df9bdbbd64b26ca12955605e57ea566 (patch)
tree790fd18954f9fe6b739a9737b5d56b087e721e97
parentfeb139f53f62b936ad94e9449212e130a71723b7 (diff)
downloadrust-fdd719aa3df9bdbbd64b26ca12955605e57ea566.tar.gz
rust-fdd719aa3df9bdbbd64b26ca12955605e57ea566.zip
Prepare for using wfcheck on existential types
-rw-r--r--src/librustc/ty/mod.rs24
-rw-r--r--src/librustc/ty/wf.rs8
-rw-r--r--src/librustc_typeck/astconv.rs12
-rw-r--r--src/test/ui/existential_types/generic_type_does_not_live_long_enough.nll.stderr21
-rw-r--r--src/test/ui/existential_types/generic_type_does_not_live_long_enough.rs7
-rw-r--r--src/test/ui/existential_types/generic_type_does_not_live_long_enough.stderr18
6 files changed, 54 insertions, 36 deletions
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 7ae6f812649..178f0d3cdcb 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -2856,22 +2856,26 @@ fn trait_of_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Option
         })
 }
 
+/// Yields the parent function's `DefId` if `def_id` is an `impl Trait` definition
+pub fn is_impl_trait_defn(tcx: TyCtxt, def_id: DefId) -> Option<DefId> {
+    if let Some(node_id) = tcx.hir.as_local_node_id(def_id) {
+        if let hir::map::NodeItem(item) = tcx.hir.get(node_id) {
+            if let hir::ItemKind::Existential(ref exist_ty) = item.node {
+                return exist_ty.impl_trait_fn;
+            }
+        }
+    }
+    None
+}
+
 /// See `ParamEnv` struct def'n for details.
 fn param_env<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                        def_id: DefId)
                        -> ParamEnv<'tcx> {
 
     // The param_env of an impl Trait type is its defining function's param_env
-    if let Some(Def::Existential(_)) = tcx.describe_def(def_id) {
-        if let Some(node_id) = tcx.hir.as_local_node_id(def_id) {
-            if let hir::map::NodeItem(item) = tcx.hir.get(node_id) {
-                if let hir::ItemKind::Existential(ref exist_ty) = item.node {
-                    if let Some(parent) = exist_ty.impl_trait_fn {
-                        return param_env(tcx, parent);
-                    }
-                }
-            }
-        }
+    if let Some(parent) = is_impl_trait_defn(tcx, def_id) {
+        return param_env(tcx, parent);
     }
     // Compute the bounds on Self and the type parameters.
 
diff --git a/src/librustc/ty/wf.rs b/src/librustc/ty/wf.rs
index 5376acca0d8..b99cdd59773 100644
--- a/src/librustc/ty/wf.rs
+++ b/src/librustc/ty/wf.rs
@@ -360,10 +360,16 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
                     // types appearing in the fn signature
                 }
 
-                ty::TyAnon(..) => {
+                ty::TyAnon(did, substs) => {
                     // all of the requirements on type parameters
                     // should've been checked by the instantiation
                     // of whatever returned this exact `impl Trait`.
+
+                    // for named existential types we still need to check them
+                    if super::is_impl_trait_defn(self.infcx.tcx, did).is_none() {
+                        let obligations = self.nominal_obligations(did, substs);
+                        self.out.extend(obligations);
+                    }
                 }
 
                 ty::TyDynamic(data, r) => {
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 60aea074f24..465faa1d477 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -1037,15 +1037,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
         match path.def {
             Def::Existential(did) => {
                 // check for desugared impl trait
-                if let Some(node_id) = tcx.hir.as_local_node_id(did) {
-                    if let hir::map::NodeItem(item) = tcx.hir.get(node_id) {
-                        if let hir::ItemKind::Existential(ref exist_ty) = item.node {
-                            if exist_ty.impl_trait_fn.is_some() {
-                                let lifetimes = &path.segments[0].args.as_ref().unwrap().args;
-                                return self.impl_trait_ty_to_ty(did, lifetimes);
-                            }
-                        }
-                    }
+                if ty::is_impl_trait_defn(tcx, did).is_some() {
+                    let lifetimes = &path.segments[0].args.as_ref().unwrap().args;
+                    return self.impl_trait_ty_to_ty(did, lifetimes);
                 }
                 let item_segment = path.segments.split_last().unwrap();
                 self.prohibit_generics(item_segment.1);
diff --git a/src/test/ui/existential_types/generic_type_does_not_live_long_enough.nll.stderr b/src/test/ui/existential_types/generic_type_does_not_live_long_enough.nll.stderr
index 8a6cae08ce0..84af8e1dca2 100644
--- a/src/test/ui/existential_types/generic_type_does_not_live_long_enough.nll.stderr
+++ b/src/test/ui/existential_types/generic_type_does_not_live_long_enough.nll.stderr
@@ -1,17 +1,18 @@
+error[E0308]: mismatched types
+  --> $DIR/generic_type_does_not_live_long_enough.rs:16:18
+   |
+LL |     let z: i32 = x; //~ ERROR mismatched types
+   |                  ^ expected i32, found anonymized type
+   |
+   = note: expected type `i32`
+              found type `WrongGeneric::<&{integer}>`
+
 warning: not reporting region error due to nll
-  --> $DIR/generic_type_does_not_live_long_enough.rs:16:1
+  --> $DIR/generic_type_does_not_live_long_enough.rs:19:1
    |
 LL | existential type WrongGeneric<T>: 'static;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0310]: the parameter type `T` may not live long enough
-  --> $DIR/generic_type_does_not_live_long_enough.rs:20:5
-   |
-LL |     t
-   |     ^
-   |
-   = help: consider adding an explicit lifetime bound `T: 'static`...
-
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0310`.
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/existential_types/generic_type_does_not_live_long_enough.rs b/src/test/ui/existential_types/generic_type_does_not_live_long_enough.rs
index 092aa1eda16..440fc2d1284 100644
--- a/src/test/ui/existential_types/generic_type_does_not_live_long_enough.rs
+++ b/src/test/ui/existential_types/generic_type_does_not_live_long_enough.rs
@@ -8,10 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
 #![feature(existential_type)]
 
-fn main() {}
+fn main() {
+    let y = 42;
+    let x = wrong_generic(&y);
+    let z: i32 = x; //~ ERROR mismatched types
+}
 
 existential type WrongGeneric<T>: 'static;
 //~^ ERROR the parameter type `T` may not live long enough
diff --git a/src/test/ui/existential_types/generic_type_does_not_live_long_enough.stderr b/src/test/ui/existential_types/generic_type_does_not_live_long_enough.stderr
index cbf994defc8..189ad7d49a4 100644
--- a/src/test/ui/existential_types/generic_type_does_not_live_long_enough.stderr
+++ b/src/test/ui/existential_types/generic_type_does_not_live_long_enough.stderr
@@ -1,5 +1,14 @@
+error[E0308]: mismatched types
+  --> $DIR/generic_type_does_not_live_long_enough.rs:16:18
+   |
+LL |     let z: i32 = x; //~ ERROR mismatched types
+   |                  ^ expected i32, found anonymized type
+   |
+   = note: expected type `i32`
+              found type `WrongGeneric::<&{integer}>`
+
 error[E0310]: the parameter type `T` may not live long enough
-  --> $DIR/generic_type_does_not_live_long_enough.rs:16:1
+  --> $DIR/generic_type_does_not_live_long_enough.rs:19:1
    |
 LL | existential type WrongGeneric<T>: 'static;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -8,11 +17,12 @@ LL | fn wrong_generic<T>(t: T) -> WrongGeneric<T> {
    |                  - help: consider adding an explicit lifetime bound `T: 'static`...
    |
 note: ...so that the type `T` will meet its required lifetime bounds
-  --> $DIR/generic_type_does_not_live_long_enough.rs:16:1
+  --> $DIR/generic_type_does_not_live_long_enough.rs:19:1
    |
 LL | existential type WrongGeneric<T>: 'static;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to previous error
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0310`.
+Some errors occurred: E0308, E0310.
+For more information about an error, try `rustc --explain E0308`.