Skip to content

Commit 41902f2

Browse files
committed
Implement with_parent_item_lifetime_defs on ItemLowerer.
1 parent dc8b6b4 commit 41902f2

File tree

1 file changed

+62
-70
lines changed
  • compiler/rustc_ast_lowering/src

1 file changed

+62
-70
lines changed

compiler/rustc_ast_lowering/src/item.rs

+62-70
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,59 @@ fn add_ty_alias_where_clause(
4646
}
4747

4848
impl ItemLowerer<'_, '_, '_> {
49-
fn with_trait_impl_ref<T>(
49+
/// Clears (and restores) the `in_scope_lifetimes` field. Used when
50+
/// visiting nested items, which never inherit in-scope lifetimes
51+
/// from their surrounding environment.
52+
#[tracing::instrument(level = "debug", skip(self, f))]
53+
fn without_in_scope_lifetime_defs<T>(&mut self, f: impl FnOnce(&mut Self) -> T) -> T {
54+
let old_in_scope_lifetimes = mem::take(&mut self.lctx.in_scope_lifetimes);
55+
debug!(?old_in_scope_lifetimes);
56+
57+
// this vector is only used when walking over impl headers,
58+
// input types, and the like, and should not be non-empty in
59+
// between items
60+
assert!(self.lctx.lifetimes_to_define.is_empty());
61+
62+
let res = f(self);
63+
64+
assert!(self.lctx.in_scope_lifetimes.is_empty());
65+
self.lctx.in_scope_lifetimes = old_in_scope_lifetimes;
66+
67+
res
68+
}
69+
70+
/// Evaluates `f` with the lifetimes in `params` in-scope.
71+
/// This is used to track which lifetimes have already been defined, and
72+
/// which are new in-band lifetimes that need to have a definition created
73+
/// for them.
74+
fn with_parent_item_lifetime_defs(
5075
&mut self,
51-
impl_ref: &Option<TraitRef>,
52-
f: impl FnOnce(&mut Self) -> T,
53-
) -> T {
76+
parent_item: LocalDefId,
77+
f: impl FnOnce(&mut Self),
78+
) {
79+
let parent_hir = self.lctx.owners[parent_item].unwrap().node().expect_item();
80+
let parent_generics = match parent_hir.kind {
81+
hir::ItemKind::Impl(hir::Impl { ref generics, .. })
82+
| hir::ItemKind::Trait(_, _, ref generics, ..) => generics.params,
83+
_ => &[],
84+
};
85+
let lt_def_names = parent_generics
86+
.iter()
87+
.filter_map(|param| match param.kind {
88+
hir::GenericParamKind::Lifetime { .. } => {
89+
Some(param.name.normalize_to_macros_2_0())
90+
}
91+
_ => None,
92+
})
93+
.collect();
94+
let old_in_scope_lifetimes = mem::replace(&mut self.lctx.in_scope_lifetimes, lt_def_names);
95+
96+
f(self);
97+
98+
self.lctx.in_scope_lifetimes = old_in_scope_lifetimes;
99+
}
100+
101+
fn with_trait_impl_ref(&mut self, impl_ref: &Option<TraitRef>, f: impl FnOnce(&mut Self)) {
54102
let old = self.lctx.is_in_trait_impl;
55103
self.lctx.is_in_trait_impl = impl_ref.is_some();
56104
let ret = f(self);
@@ -66,20 +114,19 @@ impl<'a> Visitor<'a> for ItemLowerer<'a, '_, '_> {
66114
}
67115

68116
fn visit_item(&mut self, item: &'a Item) {
69-
let hir_id = self.lctx.with_hir_id_owner(item.id, |lctx| {
70-
let node = lctx.without_in_scope_lifetime_defs(|lctx| lctx.lower_item(item));
71-
hir::OwnerNode::Item(node)
117+
let hir_id = self.without_in_scope_lifetime_defs(|this| {
118+
this.lctx.with_hir_id_owner(item.id, |lctx| {
119+
let node = lctx.lower_item(item);
120+
hir::OwnerNode::Item(node)
121+
})
72122
});
73123

74-
self.lctx.with_parent_item_lifetime_defs(hir_id, |this| {
75-
let this = &mut ItemLowerer { lctx: this };
76-
match item.kind {
77-
ItemKind::Impl(box Impl { ref of_trait, .. }) => {
78-
this.with_trait_impl_ref(of_trait, |this| visit::walk_item(this, item));
79-
}
80-
_ => visit::walk_item(this, item),
124+
self.with_parent_item_lifetime_defs(hir_id, |this| match item.kind {
125+
ItemKind::Impl(box Impl { ref of_trait, .. }) => {
126+
this.with_trait_impl_ref(of_trait, |this| visit::walk_item(this, item));
81127
}
82-
});
128+
_ => visit::walk_item(this, item),
129+
})
83130
}
84131

85132
fn visit_fn(&mut self, fk: FnKind<'a>, sp: Span, _: NodeId) {
@@ -114,61 +161,6 @@ impl<'a> Visitor<'a> for ItemLowerer<'a, '_, '_> {
114161
}
115162

116163
impl<'hir> LoweringContext<'_, 'hir> {
117-
// Same as the method above, but accepts `hir::GenericParam`s
118-
// instead of `ast::GenericParam`s.
119-
// This should only be used with generics that have already had their
120-
// in-band lifetimes added. In practice, this means that this function is
121-
// only used when lowering a child item of a trait or impl.
122-
#[tracing::instrument(level = "debug", skip(self, f))]
123-
fn with_parent_item_lifetime_defs<T>(
124-
&mut self,
125-
parent_hir_id: LocalDefId,
126-
f: impl FnOnce(&mut Self) -> T,
127-
) -> T {
128-
let parent_generics = match self.owners[parent_hir_id].unwrap().node().expect_item().kind {
129-
hir::ItemKind::Impl(hir::Impl { ref generics, .. })
130-
| hir::ItemKind::Trait(_, _, ref generics, ..) => generics.params,
131-
_ => &[],
132-
};
133-
let lt_def_names = parent_generics
134-
.iter()
135-
.filter_map(|param| match param.kind {
136-
hir::GenericParamKind::Lifetime { .. } => {
137-
Some(param.name.normalize_to_macros_2_0())
138-
}
139-
_ => None,
140-
})
141-
.collect();
142-
let old_in_scope_lifetimes = mem::replace(&mut self.in_scope_lifetimes, lt_def_names);
143-
debug!(in_scope_lifetimes = ?self.in_scope_lifetimes);
144-
145-
let res = f(self);
146-
147-
self.in_scope_lifetimes = old_in_scope_lifetimes;
148-
res
149-
}
150-
151-
// Clears (and restores) the `in_scope_lifetimes` field. Used when
152-
// visiting nested items, which never inherit in-scope lifetimes
153-
// from their surrounding environment.
154-
#[tracing::instrument(level = "debug", skip(self, f))]
155-
fn without_in_scope_lifetime_defs<T>(&mut self, f: impl FnOnce(&mut Self) -> T) -> T {
156-
let old_in_scope_lifetimes = mem::replace(&mut self.in_scope_lifetimes, vec![]);
157-
debug!(?old_in_scope_lifetimes);
158-
159-
// this vector is only used when walking over impl headers,
160-
// input types, and the like, and should not be non-empty in
161-
// between items
162-
assert!(self.lifetimes_to_define.is_empty());
163-
164-
let res = f(self);
165-
166-
assert!(self.in_scope_lifetimes.is_empty());
167-
self.in_scope_lifetimes = old_in_scope_lifetimes;
168-
169-
res
170-
}
171-
172164
pub(super) fn lower_mod(&mut self, items: &[P<Item>], inner: Span) -> hir::Mod<'hir> {
173165
hir::Mod {
174166
inner: self.lower_span(inner),

0 commit comments

Comments
 (0)