do not introduce *false* results from lifetime resolution
This commit is contained in:
parent
b36917b331
commit
a2a019a28a
3 changed files with 34 additions and 6 deletions
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 `()`
|
||||
|
||||
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<Id<_> + '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`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue