Skip to content

Commit e5d482e

Browse files
committed
Create a new LoweringContext for each item-like.
1 parent 6e4fb20 commit e5d482e

File tree

2 files changed

+104
-129
lines changed

2 files changed

+104
-129
lines changed

Diff for: compiler/rustc_ast_lowering/src/item.rs

+91-92
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
11
use super::{AnonymousLifetimeMode, LoweringContext, ParamMode};
2-
use super::{AstOwner, ImplTraitContext, ImplTraitPosition};
2+
use super::{AstOwner, ImplTraitContext, ImplTraitPosition, ResolverAstLowering};
33
use crate::{Arena, FnDeclKind};
44

55
use rustc_ast::ptr::P;
66
use rustc_ast::visit::AssocCtxt;
77
use rustc_ast::*;
88
use rustc_data_structures::fx::FxHashSet;
9+
use rustc_data_structures::sorted_map::SortedMap;
910
use rustc_errors::struct_span_err;
1011
use rustc_hir as hir;
1112
use rustc_hir::def::{DefKind, Res};
1213
use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
1314
use rustc_index::vec::{Idx, IndexVec};
15+
use rustc_session::utils::NtToTokenstream;
16+
use rustc_session::Session;
1417
use rustc_span::source_map::{respan, DesugaringKind};
1518
use rustc_span::symbol::{kw, sym, Ident};
1619
use rustc_span::Span;
@@ -19,11 +22,14 @@ use smallvec::{smallvec, SmallVec};
1922
use tracing::debug;
2023

2124
use std::iter;
22-
use std::mem;
2325

24-
pub(super) struct ItemLowerer<'a, 'lowering, 'hir> {
25-
pub(super) lctx: &'a mut LoweringContext<'lowering, 'hir>,
26-
pub(super) ast_index: &'a IndexVec<LocalDefId, AstOwner<'lowering>>,
26+
pub(super) struct ItemLowerer<'a, 'hir> {
27+
pub(super) sess: &'a Session,
28+
pub(super) resolver: &'a mut dyn ResolverAstLowering,
29+
pub(super) nt_to_tokenstream: NtToTokenstream,
30+
pub(super) arena: &'hir Arena<'hir>,
31+
pub(super) ast_index: &'a IndexVec<LocalDefId, AstOwner<'a>>,
32+
pub(super) owners: &'a mut IndexVec<LocalDefId, hir::MaybeOwner<&'hir hir::OwnerInfo<'hir>>>,
2733
}
2834

2935
/// When we have a ty alias we *may* have two where clauses. To give the best diagnostics, we set the span
@@ -46,76 +52,50 @@ fn add_ty_alias_where_clause(
4652
}
4753
}
4854

49-
impl<'a, 'hir> ItemLowerer<'_, 'a, 'hir> {
50-
/// Clears (and restores) the `in_scope_lifetimes` field. Used when
51-
/// visiting nested items, which never inherit in-scope lifetimes
52-
/// from their surrounding environment.
53-
#[tracing::instrument(level = "debug", skip(self, f))]
54-
fn without_in_scope_lifetime_defs<T>(&mut self, f: impl FnOnce(&mut Self) -> T) -> T {
55-
let old_in_scope_lifetimes = mem::take(&mut self.lctx.in_scope_lifetimes);
56-
debug!(?old_in_scope_lifetimes);
57-
58-
// this vector is only used when walking over impl headers,
59-
// input types, and the like, and should not be non-empty in
60-
// between items
61-
assert!(self.lctx.lifetimes_to_define.is_empty());
62-
63-
let res = f(self);
64-
65-
assert!(self.lctx.in_scope_lifetimes.is_empty());
66-
self.lctx.in_scope_lifetimes = old_in_scope_lifetimes;
67-
68-
res
69-
}
70-
71-
/// Evaluates `f` with the lifetimes in `params` in-scope.
72-
/// This is used to track which lifetimes have already been defined, and
73-
/// which are new in-band lifetimes that need to have a definition created
74-
/// for them.
75-
fn with_parent_item_lifetime_defs(
76-
&mut self,
77-
parent_hir: &'hir hir::Item<'hir>,
78-
f: impl FnOnce(&mut Self),
79-
) {
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(
102-
&mut self,
103-
impl_ref: &Option<hir::TraitRef<'_>>,
104-
f: impl FnOnce(&mut Self),
105-
) {
106-
let old = self.lctx.is_in_trait_impl;
107-
self.lctx.is_in_trait_impl = impl_ref.is_some();
108-
let ret = f(self);
109-
self.lctx.is_in_trait_impl = old;
110-
ret
55+
impl<'a, 'hir> ItemLowerer<'a, 'hir> {
56+
fn make_lctx(&mut self) -> LoweringContext<'_, 'hir> {
57+
LoweringContext {
58+
// Pseudo-globals.
59+
sess: &self.sess,
60+
resolver: self.resolver,
61+
nt_to_tokenstream: self.nt_to_tokenstream,
62+
arena: self.arena,
63+
owners: self.owners,
64+
65+
// HirId handling.
66+
bodies: Vec::new(),
67+
attrs: SortedMap::default(),
68+
current_hir_id_owner: CRATE_DEF_ID,
69+
item_local_id_counter: hir::ItemLocalId::new(0),
70+
node_id_to_local_id: Default::default(),
71+
local_id_to_def_id: SortedMap::new(),
72+
trait_map: Default::default(),
73+
74+
// Lowering state.
75+
catch_scope: None,
76+
loop_scope: None,
77+
is_in_loop_condition: false,
78+
is_in_trait_impl: false,
79+
is_in_dyn_type: false,
80+
anonymous_lifetime_mode: AnonymousLifetimeMode::PassThrough,
81+
generator_kind: None,
82+
task_context: None,
83+
current_item: None,
84+
lifetimes_to_define: Vec::new(),
85+
is_collecting_anonymous_lifetimes: None,
86+
in_scope_lifetimes: Vec::new(),
87+
allow_try_trait: Some([sym::try_trait_v2][..].into()),
88+
allow_gen_future: Some([sym::gen_future][..].into()),
89+
allow_into_future: Some([sym::into_future][..].into()),
90+
}
11191
}
11292

11393
pub(super) fn lower_node(
11494
&mut self,
11595
def_id: LocalDefId,
11696
) -> hir::MaybeOwner<&'hir hir::OwnerInfo<'hir>> {
117-
self.lctx.owners.ensure_contains_elem(def_id, || hir::MaybeOwner::Phantom);
118-
if let hir::MaybeOwner::Phantom = self.lctx.owners[def_id] {
97+
self.owners.ensure_contains_elem(def_id, || hir::MaybeOwner::Phantom);
98+
if let hir::MaybeOwner::Phantom = self.owners[def_id] {
11999
let node = self.ast_index[def_id];
120100
match node {
121101
AstOwner::NonOwner => {}
@@ -126,53 +106,72 @@ impl<'a, 'hir> ItemLowerer<'_, 'a, 'hir> {
126106
}
127107
}
128108

129-
self.lctx.owners[def_id]
109+
self.owners[def_id]
130110
}
131111

132112
fn lower_crate(&mut self, c: &'a Crate) {
133-
debug_assert_eq!(self.lctx.resolver.local_def_id(CRATE_NODE_ID), CRATE_DEF_ID);
113+
debug_assert_eq!(self.resolver.local_def_id(CRATE_NODE_ID), CRATE_DEF_ID);
134114

135-
self.lctx.with_hir_id_owner(CRATE_NODE_ID, |lctx| {
115+
let mut lctx = self.make_lctx();
116+
lctx.with_hir_id_owner(CRATE_NODE_ID, |lctx| {
136117
let module = lctx.lower_mod(&c.items, c.spans.inner_span);
137118
lctx.lower_attrs(hir::CRATE_HIR_ID, &c.attrs);
138119
hir::OwnerNode::Crate(lctx.arena.alloc(module))
139-
});
120+
})
140121
}
141122

142123
fn lower_item(&mut self, item: &'a Item) {
143-
self.without_in_scope_lifetime_defs(|this| {
144-
this.lctx.with_hir_id_owner(item.id, |lctx| hir::OwnerNode::Item(lctx.lower_item(item)))
145-
});
124+
let mut lctx = self.make_lctx();
125+
lctx.with_hir_id_owner(item.id, |lctx| hir::OwnerNode::Item(lctx.lower_item(item)))
146126
}
147127

148128
fn lower_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) {
149-
let def_id = self.lctx.resolver.local_def_id(item.id);
150-
151-
let do_lower = |lctx: &mut LoweringContext<'_, '_>| {
152-
lctx.with_hir_id_owner(item.id, |lctx| match ctxt {
153-
AssocCtxt::Trait => hir::OwnerNode::TraitItem(lctx.lower_trait_item(item)),
154-
AssocCtxt::Impl => hir::OwnerNode::ImplItem(lctx.lower_impl_item(item)),
155-
});
156-
};
129+
let def_id = self.resolver.local_def_id(item.id);
157130

158131
let parent_id = {
159-
let parent = self.lctx.resolver.definitions().def_key(def_id).parent;
132+
let parent = self.resolver.definitions().def_key(def_id).parent;
160133
let local_def_index = parent.unwrap();
161134
LocalDefId { local_def_index }
162135
};
136+
163137
let parent_hir = self.lower_node(parent_id).unwrap().node().expect_item();
164-
self.with_parent_item_lifetime_defs(parent_hir, |this| match parent_hir.kind {
165-
hir::ItemKind::Impl(hir::Impl { ref of_trait, .. }) => {
166-
this.with_trait_impl_ref(of_trait, |this| do_lower(this.lctx))
138+
let mut lctx = self.make_lctx();
139+
140+
// Evaluate with the lifetimes in `params` in-scope.
141+
// This is used to track which lifetimes have already been defined,
142+
// and which need to be replicated when lowering an async fn.
143+
match parent_hir.kind {
144+
hir::ItemKind::Impl(hir::Impl { ref of_trait, ref generics, .. }) => {
145+
lctx.is_in_trait_impl = of_trait.is_some();
146+
lctx.in_scope_lifetimes = generics
147+
.params
148+
.iter()
149+
.filter(|param| matches!(param.kind, hir::GenericParamKind::Lifetime { .. }))
150+
.map(|param| param.name)
151+
.collect();
152+
}
153+
hir::ItemKind::Trait(_, _, ref generics, ..) => {
154+
lctx.in_scope_lifetimes = generics
155+
.params
156+
.iter()
157+
.filter(|param| matches!(param.kind, hir::GenericParamKind::Lifetime { .. }))
158+
.map(|param| param.name)
159+
.collect();
167160
}
168-
_ => do_lower(this.lctx),
169-
});
161+
_ => {}
162+
};
163+
164+
lctx.with_hir_id_owner(item.id, |lctx| match ctxt {
165+
AssocCtxt::Trait => hir::OwnerNode::TraitItem(lctx.lower_trait_item(item)),
166+
AssocCtxt::Impl => hir::OwnerNode::ImplItem(lctx.lower_impl_item(item)),
167+
})
170168
}
171169

172170
fn lower_foreign_item(&mut self, item: &'a ForeignItem) {
173-
self.lctx.with_hir_id_owner(item.id, |lctx| {
171+
let mut lctx = self.make_lctx();
172+
lctx.with_hir_id_owner(item.id, |lctx| {
174173
hir::OwnerNode::ForeignItem(lctx.lower_foreign_item(item))
175-
});
174+
})
176175
}
177176
}
178177

Diff for: compiler/rustc_ast_lowering/src/lib.rs

+13-37
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ mod path;
8585

8686
rustc_hir::arena_types!(rustc_arena::declare_arena);
8787

88-
struct LoweringContext<'a, 'hir: 'a> {
88+
struct LoweringContext<'a, 'hir> {
8989
/// Used to assign IDs to HIR nodes that do not directly correspond to AST nodes.
9090
sess: &'a Session,
9191

@@ -100,7 +100,7 @@ struct LoweringContext<'a, 'hir: 'a> {
100100
arena: &'hir Arena<'hir>,
101101

102102
/// The items being lowered are collected here.
103-
owners: IndexVec<LocalDefId, hir::MaybeOwner<&'hir hir::OwnerInfo<'hir>>>,
103+
owners: &'a mut IndexVec<LocalDefId, hir::MaybeOwner<&'hir hir::OwnerInfo<'hir>>>,
104104
/// Bodies inside the owner being lowered.
105105
bodies: Vec<(hir::ItemLocalId, &'hir hir::Body<'hir>)>,
106106
/// Attributes inside the owner being lowered.
@@ -418,42 +418,20 @@ pub fn lower_crate<'a, 'hir>(
418418

419419
let ast_index = index_crate(resolver, krate);
420420

421-
let owners =
421+
let mut owners =
422422
IndexVec::from_fn_n(|_| hir::MaybeOwner::Phantom, resolver.definitions().def_index_count());
423-
let mut lctx = LoweringContext {
424-
sess,
425-
resolver,
426-
nt_to_tokenstream,
427-
arena,
428-
owners,
429-
bodies: Vec::new(),
430-
attrs: SortedMap::new(),
431-
catch_scope: None,
432-
loop_scope: None,
433-
is_in_loop_condition: false,
434-
is_in_trait_impl: false,
435-
is_in_dyn_type: false,
436-
anonymous_lifetime_mode: AnonymousLifetimeMode::PassThrough,
437-
current_hir_id_owner: CRATE_DEF_ID,
438-
item_local_id_counter: hir::ItemLocalId::new(0),
439-
node_id_to_local_id: FxHashMap::default(),
440-
local_id_to_def_id: SortedMap::new(),
441-
trait_map: FxHashMap::default(),
442-
generator_kind: None,
443-
task_context: None,
444-
current_item: None,
445-
lifetimes_to_define: Vec::new(),
446-
is_collecting_anonymous_lifetimes: None,
447-
in_scope_lifetimes: Vec::new(),
448-
allow_try_trait: Some([sym::try_trait_v2][..].into()),
449-
allow_gen_future: Some([sym::gen_future][..].into()),
450-
allow_into_future: Some([sym::into_future][..].into()),
451-
};
452423

453424
for def_id in ast_index.indices() {
454-
item::ItemLowerer { lctx: &mut lctx, ast_index: &ast_index }.lower_node(def_id);
425+
item::ItemLowerer {
426+
sess,
427+
resolver,
428+
nt_to_tokenstream,
429+
arena,
430+
ast_index: &ast_index,
431+
owners: &mut owners,
432+
}
433+
.lower_node(def_id);
455434
}
456-
let owners = lctx.owners;
457435

458436
let hir_hash = compute_hir_hash(resolver, &owners);
459437
let krate = hir::Crate { owners, hir_hash };
@@ -530,7 +508,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
530508
&mut self,
531509
owner: NodeId,
532510
f: impl FnOnce(&mut Self) -> hir::OwnerNode<'hir>,
533-
) -> LocalDefId {
511+
) {
534512
let def_id = self.resolver.local_def_id(owner);
535513

536514
let current_attrs = std::mem::take(&mut self.attrs);
@@ -560,8 +538,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
560538

561539
self.owners.ensure_contains_elem(def_id, || hir::MaybeOwner::Phantom);
562540
self.owners[def_id] = hir::MaybeOwner::Owner(self.arena.alloc(info));
563-
564-
def_id
565541
}
566542

567543
fn make_owner_info(&mut self, node: hir::OwnerNode<'hir>) -> hir::OwnerInfo<'hir> {

0 commit comments

Comments
 (0)