Skip to content

Commit d31a656

Browse files
fee1-deadcjgillot
andcommitted
Make lowering incremental.
Co-authored-by: Camille Gillot <gillot.camille@gmail.com>
1 parent 14a40e2 commit d31a656

File tree

16 files changed

+233
-246
lines changed

16 files changed

+233
-246
lines changed

compiler/rustc_ast/src/ast.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4027,6 +4027,17 @@ impl TryFrom<ItemKind> for ForeignItemKind {
40274027

40284028
pub type ForeignItem = Item<ForeignItemKind>;
40294029

4030+
#[derive(Debug)]
4031+
pub enum AstOwner<'a> {
4032+
NonOwner,
4033+
Synthetic(rustc_span::def_id::LocalDefId),
4034+
Crate(&'a Crate),
4035+
Item(&'a Item),
4036+
TraitItem(&'a AssocItem),
4037+
ImplItem(&'a AssocItem),
4038+
ForeignItem(&'a ForeignItem),
4039+
}
4040+
40304041
// Some nodes are used a lot. Make sure they don't unintentionally get bigger.
40314042
#[cfg(target_pointer_width = "64")]
40324043
mod size_asserts {

compiler/rustc_ast_lowering/src/item.rs

Lines changed: 54 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -4,31 +4,28 @@ use rustc_ast::*;
44
use rustc_errors::{E0570, ErrorGuaranteed, struct_span_code_err};
55
use rustc_hir::attrs::AttributeKind;
66
use rustc_hir::def::{DefKind, PerNS, Res};
7-
use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId};
7+
use rustc_hir::def_id::CRATE_DEF_ID;
88
use rustc_hir::{
99
self as hir, HirId, ImplItemImplKind, LifetimeSource, PredicateOrigin, Target, find_attr,
1010
};
11-
use rustc_index::{IndexSlice, IndexVec};
1211
use rustc_middle::span_bug;
1312
use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
1413
use rustc_span::edit_distance::find_best_match_for_name;
15-
use rustc_span::{DUMMY_SP, DesugaringKind, Ident, Span, Symbol, kw, sym};
14+
use rustc_span::{DesugaringKind, Ident, Span, Symbol, kw, sym};
1615
use smallvec::{SmallVec, smallvec};
1716
use thin_vec::ThinVec;
1817
use tracing::instrument;
1918

2019
use super::errors::{InvalidAbi, InvalidAbiSuggestion, TupleStructWithDefault, UnionWithDefault};
2120
use super::stability::{enabled_names, gate_unstable_abi};
2221
use super::{
23-
AstOwner, FnDeclKind, ImplTraitContext, ImplTraitPosition, LoweringContext, ParamMode,
22+
FnDeclKind, ImplTraitContext, ImplTraitPosition, LoweringContext, ParamMode,
2423
RelaxedBoundForbiddenReason, RelaxedBoundPolicy, ResolverAstLoweringExt,
2524
};
2625

27-
pub(super) struct ItemLowerer<'a, 'hir> {
26+
pub(super) struct ItemLowerer<'hir> {
2827
pub(super) tcx: TyCtxt<'hir>,
2928
pub(super) resolver: &'hir ResolverAstLowering,
30-
pub(super) ast_index: &'a IndexSlice<LocalDefId, AstOwner<'a>>,
31-
pub(super) owners: &'a mut IndexVec<LocalDefId, hir::MaybeOwner<'hir>>,
3229
}
3330

3431
/// When we have a ty alias we *may* have two where clauses. To give the best diagnostics, we set the span
@@ -50,51 +47,47 @@ fn add_ty_alias_where_clause(
5047
if before.0 || !after.0 { before } else { after };
5148
}
5249

53-
impl<'a, 'hir> ItemLowerer<'a, 'hir> {
50+
impl<'hir> ItemLowerer<'hir> {
5451
fn with_lctx(
5552
&mut self,
5653
owner: NodeId,
5754
f: impl FnOnce(&mut LoweringContext<'hir>) -> hir::OwnerNode<'hir>,
58-
) {
59-
let mut lctx = LoweringContext::new(self.tcx, self.resolver);
60-
lctx.with_hir_id_owner(owner, |lctx| f(lctx));
61-
62-
for (def_id, info) in lctx.children {
63-
let owner = self.owners.ensure_contains_elem(def_id, || hir::MaybeOwner::Phantom);
64-
assert!(
65-
matches!(owner, hir::MaybeOwner::Phantom),
66-
"duplicate copy of {def_id:?} in lctx.children"
67-
);
68-
*owner = info;
69-
}
55+
) -> hir::MaybeOwner<'hir> {
56+
let mut lctx = LoweringContext::new(self.tcx, self.resolver, owner);
57+
58+
let item = f(&mut lctx);
59+
debug_assert_eq!(lctx.current_hir_id_owner, item.def_id());
60+
61+
let info = lctx.make_owner_info(item);
62+
63+
hir::MaybeOwner::Owner(lctx.arena.alloc(info))
7064
}
7165

72-
pub(super) fn lower_node(&mut self, def_id: LocalDefId) {
73-
let owner = self.owners.ensure_contains_elem(def_id, || hir::MaybeOwner::Phantom);
74-
if let hir::MaybeOwner::Phantom = owner {
75-
let node = self.ast_index[def_id];
76-
match node {
77-
AstOwner::NonOwner => {}
78-
AstOwner::Crate(c) => {
79-
assert_eq!(self.resolver.node_id_to_def_id[&CRATE_NODE_ID], CRATE_DEF_ID);
80-
self.with_lctx(CRATE_NODE_ID, |lctx| {
81-
let module = lctx.lower_mod(&c.items, &c.spans);
82-
// FIXME(jdonszelman): is dummy span ever a problem here?
83-
lctx.lower_attrs(hir::CRATE_HIR_ID, &c.attrs, DUMMY_SP, Target::Crate);
84-
hir::OwnerNode::Crate(module)
85-
})
86-
}
87-
AstOwner::Item(item) => {
88-
self.with_lctx(item.id, |lctx| hir::OwnerNode::Item(lctx.lower_item(item)))
89-
}
90-
AstOwner::AssocItem(item, ctxt) => {
91-
self.with_lctx(item.id, |lctx| lctx.lower_assoc_item(item, ctxt))
92-
}
93-
AstOwner::ForeignItem(item) => self.with_lctx(item.id, |lctx| {
94-
hir::OwnerNode::ForeignItem(lctx.lower_foreign_item(item))
95-
}),
96-
}
97-
}
66+
#[instrument(level = "debug", skip(self, c))]
67+
pub(super) fn lower_crate(&mut self, c: &Crate) -> hir::MaybeOwner<'hir> {
68+
debug_assert_eq!(self.resolver.node_id_to_def_id[&CRATE_NODE_ID], CRATE_DEF_ID);
69+
self.with_lctx(CRATE_NODE_ID, |lctx| {
70+
let module = lctx.lower_mod(&c.items, &c.spans);
71+
lctx.lower_attrs(hir::CRATE_HIR_ID, &c.attrs, c.spans.inner_span, Target::Crate);
72+
hir::OwnerNode::Crate(module)
73+
})
74+
}
75+
76+
#[instrument(level = "debug", skip(self))]
77+
pub(super) fn lower_item(&mut self, item: &Item) -> hir::MaybeOwner<'hir> {
78+
self.with_lctx(item.id, |lctx| hir::OwnerNode::Item(lctx.lower_item(item)))
79+
}
80+
81+
pub(super) fn lower_trait_item(&mut self, item: &AssocItem) -> hir::MaybeOwner<'hir> {
82+
self.with_lctx(item.id, |lctx| hir::OwnerNode::TraitItem(lctx.lower_trait_item(item)))
83+
}
84+
85+
pub(super) fn lower_impl_item(&mut self, item: &AssocItem) -> hir::MaybeOwner<'hir> {
86+
self.with_lctx(item.id, |lctx| hir::OwnerNode::ImplItem(lctx.lower_impl_item(item)))
87+
}
88+
89+
pub(super) fn lower_foreign_item(&mut self, item: &ForeignItem) -> hir::MaybeOwner<'hir> {
90+
self.with_lctx(item.id, |lctx| hir::OwnerNode::ForeignItem(lctx.lower_foreign_item(item)))
9891
}
9992
}
10093

@@ -134,12 +127,13 @@ impl<'hir> LoweringContext<'hir> {
134127
}
135128

136129
fn lower_item(&mut self, i: &Item) -> &'hir hir::Item<'hir> {
130+
let owner_id = self.current_hir_id_owner;
131+
let hir_id: HirId = owner_id.into();
137132
let vis_span = self.lower_span(i.vis.span);
138-
let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
139133
let attrs = self.lower_attrs(hir_id, &i.attrs, i.span, Target::from_ast_item(i));
140134
let kind = self.lower_item_kind(i.span, i.id, hir_id, attrs, vis_span, &i.kind);
141135
let item = hir::Item {
142-
owner_id: hir_id.expect_owner(),
136+
owner_id,
143137
kind,
144138
vis_span,
145139
span: self.lower_span(i.span),
@@ -606,21 +600,9 @@ impl<'hir> LoweringContext<'hir> {
606600
}
607601
}
608602

609-
fn lower_assoc_item(&mut self, item: &AssocItem, ctxt: AssocCtxt) -> hir::OwnerNode<'hir> {
610-
// Evaluate with the lifetimes in `params` in-scope.
611-
// This is used to track which lifetimes have already been defined,
612-
// and which need to be replicated when lowering an async fn.
613-
match ctxt {
614-
AssocCtxt::Trait => hir::OwnerNode::TraitItem(self.lower_trait_item(item)),
615-
AssocCtxt::Impl { of_trait } => {
616-
hir::OwnerNode::ImplItem(self.lower_impl_item(item, of_trait))
617-
}
618-
}
619-
}
620-
621603
fn lower_foreign_item(&mut self, i: &ForeignItem) -> &'hir hir::ForeignItem<'hir> {
622-
let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
623-
let owner_id = hir_id.expect_owner();
604+
let owner_id = self.current_hir_id_owner;
605+
let hir_id: HirId = owner_id.into();
624606
let attrs =
625607
self.lower_attrs(hir_id, &i.attrs, i.span, Target::from_foreign_item_kind(&i.kind));
626608
let (ident, kind) = match &i.kind {
@@ -792,14 +774,14 @@ impl<'hir> LoweringContext<'hir> {
792774
}
793775

794776
fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> {
795-
let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
777+
let trait_item_def_id = self.current_hir_id_owner;
778+
let hir_id: HirId = trait_item_def_id.into();
796779
let attrs = self.lower_attrs(
797780
hir_id,
798781
&i.attrs,
799782
i.span,
800783
Target::from_assoc_item_kind(&i.kind, AssocCtxt::Trait),
801784
);
802-
let trait_item_def_id = hir_id.expect_owner();
803785

804786
let (ident, generics, kind, has_default) = match &i.kind {
805787
AssocItemKind::Const(box ConstItem {
@@ -1003,15 +985,16 @@ impl<'hir> LoweringContext<'hir> {
1003985
})
1004986
}
1005987

1006-
fn lower_impl_item(
1007-
&mut self,
1008-
i: &AssocItem,
1009-
is_in_trait_impl: bool,
1010-
) -> &'hir hir::ImplItem<'hir> {
988+
fn lower_impl_item(&mut self, i: &AssocItem) -> &'hir hir::ImplItem<'hir> {
989+
let owner_id = self.current_hir_id_owner;
990+
let hir_id: HirId = owner_id.into();
991+
let parent_id = self.tcx.local_parent(owner_id.def_id);
992+
let is_in_trait_impl =
993+
matches!(self.tcx.def_kind(parent_id), DefKind::Impl { of_trait: true });
994+
1011995
// Since `default impl` is not yet implemented, this is always true in impls.
1012996
let has_value = true;
1013997
let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value);
1014-
let hir_id = hir::HirId::make_owner(self.current_hir_id_owner.def_id);
1015998
let attrs = self.lower_attrs(
1016999
hir_id,
10171000
&i.attrs,
@@ -1126,7 +1109,7 @@ impl<'hir> LoweringContext<'hir> {
11261109

11271110
let span = self.lower_span(i.span);
11281111
let item = hir::ImplItem {
1129-
owner_id: hir_id.expect_owner(),
1112+
owner_id,
11301113
ident: self.lower_ident(ident),
11311114
generics,
11321115
impl_kind: if is_in_trait_impl {

0 commit comments

Comments
 (0)