]> git.lizzy.rs Git - rust.git/commitdiff
Prepare for using wfcheck on existential types
authorOliver Schneider <github35764891676564198441@oli-obk.de>
Tue, 17 Jul 2018 11:44:42 +0000 (13:44 +0200)
committerOliver Schneider <github35764891676564198441@oli-obk.de>
Wed, 18 Jul 2018 08:53:10 +0000 (10:53 +0200)
src/librustc/ty/mod.rs
src/librustc/ty/wf.rs
src/librustc_typeck/astconv.rs
src/test/ui/existential_types/generic_type_does_not_live_long_enough.nll.stderr
src/test/ui/existential_types/generic_type_does_not_live_long_enough.rs
src/test/ui/existential_types/generic_type_does_not_live_long_enough.stderr

index 7ae6f81264981654fb25494531de5a3c3c3b2fa5..178f0d3cdcbc109cdfd3df17bc4346dcb7c190ed 100644 (file)
@@ -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.
 
index 5376acca0d8cdabf5402fc13631a2731f63abfb9..b99cdd59773aa71f18dfbf97332e4eed4c11a8a8 100644 (file)
@@ -360,10 +360,16 @@ fn compute(&mut self, ty0: Ty<'tcx>) -> bool {
                     // 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) => {
index 60aea074f2421b51fde29832f86058e66e8271ff..465faa1d4779c65ba52dc110efe62e851cf461b4 100644 (file)
@@ -1037,15 +1037,9 @@ pub fn def_to_ty(&self,
         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);
index 8a6cae08ce058b14e56e8a3bd8b9195058de77e3..84af8e1dca2b1dbae5f7077b8805d8c0a1d2bce1 100644 (file)
@@ -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`.
index 092aa1eda1646b3ad07d973479e34a609572efda..440fc2d1284046e04eecbf2eaffa2ef021e2e829 100644 (file)
@@ -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
index cbf994defc8d956633f0b83bc35278565bcab196..189ad7d49a485d8f84f2e4f111924c429598efce 100644 (file)
@@ -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`.