diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 13fe9a6eef39..abc81689df24 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 c23aa40ee379..05a4b8b3544f 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 Id>> //~^ 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 Id>> //~^ 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 737ae3a163ac..23b9666de3cd 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 Id>> | ^^ -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 + 'static>` + found type `()` -For more information about this error, try `rustc --explain E0657`. +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 + 'static>` + found type `()` + +error: aborting due to 4 previous errors + +Some errors occurred: E0308, E0657. +For more information about an error, try `rustc --explain E0308`.