about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2018-06-21 15:26:44 -0400
committerNiko Matsakis <niko@alum.mit.edu>2018-06-21 16:38:35 -0400
commita2a019a28a6b5e78fd696261f1906cfbcabedb01 (patch)
treeebfe7695186ef794fa662672bd7148f441ed8733
parentb36917b33104dc0af4d26d53899b7cd064a40b22 (diff)
downloadrust-a2a019a28a6b5e78fd696261f1906cfbcabedb01.tar.gz
rust-a2a019a28a6b5e78fd696261f1906cfbcabedb01.zip
do not introduce *false* results from lifetime resolution
-rw-r--r--src/librustc/middle/resolve_lifetime.rs13
-rw-r--r--src/test/ui/error-codes/E0657.rs4
-rw-r--r--src/test/ui/error-codes/E0657.stderr23
3 files changed, 34 insertions, 6 deletions
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index 13fe9a6eef3..abc81689df2 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -632,8 +632,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                     // and ban them. Type variables instantiated inside binders aren't
                     // well-supported at the moment, so this doesn't work.
                     // In the future, this should be fixed and this error should be removed.
-                    let def = self.map.defs.get(&lifetime.id);
-                    if let Some(&Region::LateBound(_, def_id, _)) = def {
+                    let def = self.map.defs.get(&lifetime.id).cloned();
+                    if let Some(Region::LateBound(_, def_id, _)) = def {
                         if let Some(node_id) = self.tcx.hir.as_local_node_id(def_id) {
                             // Ensure that the parent of the def is an item, not HRTB
                             let parent_id = self.tcx.hir.get_parent_node(node_id);
@@ -651,6 +651,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                                     "`impl Trait` can only capture lifetimes \
                                      bound at the fn or impl level"
                                 );
+                                self.uninsert_lifetime_on_error(lifetime, def.unwrap());
                             }
                         }
                     }
@@ -2377,6 +2378,14 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
             }
         }
     }
+
+    /// Sometimes we resolve a lifetime, but later find that it is an
+    /// error (esp. around impl trait). In that case, we remove the
+    /// entry into `map.defs` so as not to confuse later code.
+    fn uninsert_lifetime_on_error(&mut self, lifetime_ref: &'tcx hir::Lifetime, bad_def: Region) {
+        let old_value = self.map.defs.remove(&lifetime_ref.id);
+        assert_eq!(old_value, Some(bad_def));
+    }
 }
 
 ///////////////////////////////////////////////////////////////////////////
diff --git a/src/test/ui/error-codes/E0657.rs b/src/test/ui/error-codes/E0657.rs
index c23aa40ee37..05a4b8b3544 100644
--- a/src/test/ui/error-codes/E0657.rs
+++ b/src/test/ui/error-codes/E0657.rs
@@ -19,7 +19,7 @@ fn free_fn_capture_hrtb_in_impl_trait()
     -> Box<for<'a> Id<impl Lt<'a>>>
         //~^ ERROR `impl Trait` can only capture lifetimes bound at the fn or impl level [E0657]
 {
-    ()
+    () //~ ERROR mismatched types
 }
 
 struct Foo;
@@ -28,7 +28,7 @@ impl Foo {
         -> Box<for<'a> Id<impl Lt<'a>>>
             //~^ ERROR `impl Trait` can only capture lifetimes bound at the fn or impl level
     {
-        ()
+        () //~ ERROR mismatched types
     }
 }
 
diff --git a/src/test/ui/error-codes/E0657.stderr b/src/test/ui/error-codes/E0657.stderr
index 737ae3a163a..23b9666de3c 100644
--- a/src/test/ui/error-codes/E0657.stderr
+++ b/src/test/ui/error-codes/E0657.stderr
@@ -10,6 +10,25 @@ error[E0657]: `impl Trait` can only capture lifetimes bound at the fn or impl le
 LL |         -> Box<for<'a> Id<impl Lt<'a>>>
    |                                   ^^
 
-error: aborting due to 2 previous errors
+error[E0308]: mismatched types
+  --> $DIR/E0657.rs:22:5
+   |
+LL |     () //~ ERROR mismatched types
+   |     ^^ expected struct `std::boxed::Box`, found ()
+   |
+   = note: expected type `std::boxed::Box<Id<_> + 'static>`
+              found type `()`
+
+error[E0308]: mismatched types
+  --> $DIR/E0657.rs:31:9
+   |
+LL |         () //~ ERROR mismatched types
+   |         ^^ expected struct `std::boxed::Box`, found ()
+   |
+   = note: expected type `std::boxed::Box<Id<_> + 'static>`
+              found type `()`
+
+error: aborting due to 4 previous errors
 
-For more information about this error, try `rustc --explain E0657`.
+Some errors occurred: E0308, E0657.
+For more information about an error, try `rustc --explain E0308`.