clear in-scope lifetimes for nested items in HIR lowering
This was causing us to incorrectly think the lifetimes were already declared on the scope for the nested item, when in fact they are not inherited.
This commit is contained in:
parent
a02a171e6a
commit
e4756e6b07
@ -60,10 +60,12 @@ impl<'tcx, 'interner> Visitor<'tcx> for ItemLowerer<'tcx, 'interner> {
|
||||
fn visit_item(&mut self, item: &'tcx Item) {
|
||||
let mut item_hir_id = None;
|
||||
self.lctx.with_hir_id_owner(item.id, |lctx| {
|
||||
if let Some(hir_item) = lctx.lower_item(item) {
|
||||
item_hir_id = Some(hir_item.hir_id);
|
||||
lctx.insert_item(hir_item);
|
||||
}
|
||||
lctx.without_in_scope_lifetime_defs(|lctx| {
|
||||
if let Some(hir_item) = lctx.lower_item(item) {
|
||||
item_hir_id = Some(hir_item.hir_id);
|
||||
lctx.insert_item(hir_item);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
if let Some(hir_id) = item_hir_id {
|
||||
@ -134,6 +136,28 @@ impl LoweringContext<'_> {
|
||||
res
|
||||
}
|
||||
|
||||
// Clears (and restores) the `in_scope_lifetimes` field. Used when
|
||||
// visiting nested items, which never inherit in-scope lifetimes
|
||||
// from their surrounding environment.
|
||||
fn without_in_scope_lifetime_defs<T>(
|
||||
&mut self,
|
||||
f: impl FnOnce(&mut LoweringContext<'_>) -> T,
|
||||
) -> T {
|
||||
let old_in_scope_lifetimes = std::mem::replace(&mut self.in_scope_lifetimes, vec![]);
|
||||
|
||||
// this vector is only used when walking over impl headers,
|
||||
// input types, and the like, and should not be non-empty in
|
||||
// between items
|
||||
assert!(self.lifetimes_to_define.is_empty());
|
||||
|
||||
let res = f(self);
|
||||
|
||||
assert!(self.in_scope_lifetimes.is_empty());
|
||||
self.in_scope_lifetimes = old_in_scope_lifetimes;
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
pub(super) fn lower_mod(&mut self, m: &Mod) -> hir::Mod {
|
||||
hir::Mod {
|
||||
inner: m.inner,
|
||||
|
17
src/test/ui/async-await/nested-in-impl.rs
Normal file
17
src/test/ui/async-await/nested-in-impl.rs
Normal file
@ -0,0 +1,17 @@
|
||||
// Test that async fn works when nested inside of
|
||||
// impls with lifetime parameters.
|
||||
//
|
||||
// check-pass
|
||||
// edition:2018
|
||||
|
||||
#![feature(async_await)]
|
||||
|
||||
struct Foo<'a>(&'a ());
|
||||
|
||||
impl<'a> Foo<'a> {
|
||||
fn test() {
|
||||
async fn test() {}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() { }
|
20
src/test/ui/in-band-lifetimes/nested-items.rs
Normal file
20
src/test/ui/in-band-lifetimes/nested-items.rs
Normal file
@ -0,0 +1,20 @@
|
||||
// Test that the `'a` from the impl doesn't
|
||||
// prevent us from creating a `'a` parameter
|
||||
// on the `blah` function.
|
||||
//
|
||||
// check-pass
|
||||
|
||||
#![feature(in_band_lifetimes)]
|
||||
|
||||
struct Foo<'a> {
|
||||
x: &'a u32
|
||||
|
||||
}
|
||||
|
||||
impl Foo<'a> {
|
||||
fn method(&self) {
|
||||
fn blah(f: Foo<'a>) { }
|
||||
}
|
||||
}
|
||||
|
||||
fn main() { }
|
Loading…
x
Reference in New Issue
Block a user