Skip to content

Commit a264f5b

Browse files
committed
Auto merge of #33089 - nrc:hir-name-res, r=eddyb
Move def id collection and extern crate handling to before AST->HIR lowering r? @jseyfried, @eddyb, or @nikomatsakis
2 parents 887e947 + 0be3c8c commit a264f5b

File tree

17 files changed

+765
-438
lines changed

17 files changed

+765
-438
lines changed

src/librustc/hir/lowering.rs

+148-70
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@
6262
// in the HIR, especially for multiple identifiers.
6363

6464
use hir;
65+
use hir::map::Definitions;
66+
use hir::map::definitions::DefPathData;
67+
use hir::def_id::DefIndex;
6568

6669
use std::collections::BTreeMap;
6770
use std::collections::HashMap;
@@ -92,10 +95,20 @@ pub struct LoweringContext<'a> {
9295
// A copy of cached_id, but is also set to an id while a node is lowered for
9396
// the first time.
9497
gensym_key: Cell<u32>,
98+
// We must keep the set of definitions up to date as we add nodes that
99+
// weren't in the AST.
100+
definitions: Option<&'a RefCell<Definitions>>,
101+
// As we walk the AST we must keep track of the current 'parent' def id (in
102+
// the form of a DefIndex) so that if we create a new node which introduces
103+
// a definition, then we can properly create the def id.
104+
parent_def: Cell<Option<DefIndex>>,
95105
}
96106

97107
impl<'a, 'hir> LoweringContext<'a> {
98-
pub fn new(id_assigner: &'a NodeIdAssigner, c: Option<&Crate>) -> LoweringContext<'a> {
108+
pub fn new(id_assigner: &'a NodeIdAssigner,
109+
c: Option<&Crate>,
110+
defs: &'a RefCell<Definitions>)
111+
-> LoweringContext<'a> {
99112
let crate_root = c.and_then(|c| {
100113
if std_inject::no_core(c) {
101114
None
@@ -113,6 +126,23 @@ impl<'a, 'hir> LoweringContext<'a> {
113126
cached_id: Cell::new(0),
114127
gensym_cache: RefCell::new(HashMap::new()),
115128
gensym_key: Cell::new(0),
129+
definitions: Some(defs),
130+
parent_def: Cell::new(None),
131+
}
132+
}
133+
134+
// Only use this when you want a LoweringContext for testing and won't look
135+
// up def ids for anything created during lowering.
136+
pub fn testing_context(id_assigner: &'a NodeIdAssigner) -> LoweringContext<'a> {
137+
LoweringContext {
138+
crate_root: None,
139+
id_cache: RefCell::new(HashMap::new()),
140+
id_assigner: id_assigner,
141+
cached_id: Cell::new(0),
142+
gensym_cache: RefCell::new(HashMap::new()),
143+
gensym_key: Cell::new(0),
144+
definitions: None,
145+
parent_def: Cell::new(None),
116146
}
117147
}
118148

@@ -146,6 +176,25 @@ impl<'a, 'hir> LoweringContext<'a> {
146176
fn diagnostic(&self) -> &Handler {
147177
self.id_assigner.diagnostic()
148178
}
179+
180+
fn with_parent_def<T, F: FnOnce() -> T>(&self, parent_id: NodeId, f: F) -> T {
181+
if self.definitions.is_none() {
182+
// This should only be used for testing.
183+
return f();
184+
}
185+
186+
let old_def = self.parent_def.get();
187+
self.parent_def.set(Some(self.get_def(parent_id)));
188+
let result = f();
189+
self.parent_def.set(old_def);
190+
191+
result
192+
}
193+
194+
fn get_def(&self, id: NodeId) -> DefIndex {
195+
let defs = self.definitions.unwrap().borrow();
196+
defs.opt_def_index(id).unwrap()
197+
}
149198
}
150199

151200
// Utility fn for setting and unsetting the cached id.
@@ -733,47 +782,51 @@ pub fn lower_item_kind(lctx: &LoweringContext, i: &ItemKind) -> hir::Item_ {
733782
}
734783

735784
pub fn lower_trait_item(lctx: &LoweringContext, i: &TraitItem) -> hir::TraitItem {
736-
hir::TraitItem {
737-
id: i.id,
738-
name: i.ident.name,
739-
attrs: lower_attrs(lctx, &i.attrs),
740-
node: match i.node {
741-
TraitItemKind::Const(ref ty, ref default) => {
742-
hir::ConstTraitItem(lower_ty(lctx, ty),
743-
default.as_ref().map(|x| lower_expr(lctx, x)))
744-
}
745-
TraitItemKind::Method(ref sig, ref body) => {
746-
hir::MethodTraitItem(lower_method_sig(lctx, sig),
747-
body.as_ref().map(|x| lower_block(lctx, x)))
748-
}
749-
TraitItemKind::Type(ref bounds, ref default) => {
750-
hir::TypeTraitItem(lower_bounds(lctx, bounds),
751-
default.as_ref().map(|x| lower_ty(lctx, x)))
752-
}
753-
},
754-
span: i.span,
755-
}
785+
lctx.with_parent_def(i.id, || {
786+
hir::TraitItem {
787+
id: i.id,
788+
name: i.ident.name,
789+
attrs: lower_attrs(lctx, &i.attrs),
790+
node: match i.node {
791+
TraitItemKind::Const(ref ty, ref default) => {
792+
hir::ConstTraitItem(lower_ty(lctx, ty),
793+
default.as_ref().map(|x| lower_expr(lctx, x)))
794+
}
795+
TraitItemKind::Method(ref sig, ref body) => {
796+
hir::MethodTraitItem(lower_method_sig(lctx, sig),
797+
body.as_ref().map(|x| lower_block(lctx, x)))
798+
}
799+
TraitItemKind::Type(ref bounds, ref default) => {
800+
hir::TypeTraitItem(lower_bounds(lctx, bounds),
801+
default.as_ref().map(|x| lower_ty(lctx, x)))
802+
}
803+
},
804+
span: i.span,
805+
}
806+
})
756807
}
757808

758809
pub fn lower_impl_item(lctx: &LoweringContext, i: &ImplItem) -> hir::ImplItem {
759-
hir::ImplItem {
760-
id: i.id,
761-
name: i.ident.name,
762-
attrs: lower_attrs(lctx, &i.attrs),
763-
vis: lower_visibility(lctx, &i.vis),
764-
defaultness: lower_defaultness(lctx, i.defaultness),
765-
node: match i.node {
766-
ImplItemKind::Const(ref ty, ref expr) => {
767-
hir::ImplItemKind::Const(lower_ty(lctx, ty), lower_expr(lctx, expr))
768-
}
769-
ImplItemKind::Method(ref sig, ref body) => {
770-
hir::ImplItemKind::Method(lower_method_sig(lctx, sig), lower_block(lctx, body))
771-
}
772-
ImplItemKind::Type(ref ty) => hir::ImplItemKind::Type(lower_ty(lctx, ty)),
773-
ImplItemKind::Macro(..) => panic!("Shouldn't exist any more"),
774-
},
775-
span: i.span,
776-
}
810+
lctx.with_parent_def(i.id, || {
811+
hir::ImplItem {
812+
id: i.id,
813+
name: i.ident.name,
814+
attrs: lower_attrs(lctx, &i.attrs),
815+
vis: lower_visibility(lctx, &i.vis),
816+
defaultness: lower_defaultness(lctx, i.defaultness),
817+
node: match i.node {
818+
ImplItemKind::Const(ref ty, ref expr) => {
819+
hir::ImplItemKind::Const(lower_ty(lctx, ty), lower_expr(lctx, expr))
820+
}
821+
ImplItemKind::Method(ref sig, ref body) => {
822+
hir::ImplItemKind::Method(lower_method_sig(lctx, sig), lower_block(lctx, body))
823+
}
824+
ImplItemKind::Type(ref ty) => hir::ImplItemKind::Type(lower_ty(lctx, ty)),
825+
ImplItemKind::Macro(..) => panic!("Shouldn't exist any more"),
826+
},
827+
span: i.span,
828+
}
829+
})
777830
}
778831

779832
pub fn lower_mod(lctx: &LoweringContext, m: &Mod) -> hir::Mod {
@@ -831,7 +884,9 @@ pub fn lower_item_id(_lctx: &LoweringContext, i: &Item) -> hir::ItemId {
831884
}
832885

833886
pub fn lower_item(lctx: &LoweringContext, i: &Item) -> hir::Item {
834-
let node = lower_item_kind(lctx, &i.node);
887+
let node = lctx.with_parent_def(i.id, || {
888+
lower_item_kind(lctx, &i.node)
889+
});
835890

836891
hir::Item {
837892
id: i.id,
@@ -844,21 +899,23 @@ pub fn lower_item(lctx: &LoweringContext, i: &Item) -> hir::Item {
844899
}
845900

846901
pub fn lower_foreign_item(lctx: &LoweringContext, i: &ForeignItem) -> hir::ForeignItem {
847-
hir::ForeignItem {
848-
id: i.id,
849-
name: i.ident.name,
850-
attrs: lower_attrs(lctx, &i.attrs),
851-
node: match i.node {
852-
ForeignItemKind::Fn(ref fdec, ref generics) => {
853-
hir::ForeignItemFn(lower_fn_decl(lctx, fdec), lower_generics(lctx, generics))
854-
}
855-
ForeignItemKind::Static(ref t, m) => {
856-
hir::ForeignItemStatic(lower_ty(lctx, t), m)
857-
}
858-
},
859-
vis: lower_visibility(lctx, &i.vis),
860-
span: i.span,
861-
}
902+
lctx.with_parent_def(i.id, || {
903+
hir::ForeignItem {
904+
id: i.id,
905+
name: i.ident.name,
906+
attrs: lower_attrs(lctx, &i.attrs),
907+
node: match i.node {
908+
ForeignItemKind::Fn(ref fdec, ref generics) => {
909+
hir::ForeignItemFn(lower_fn_decl(lctx, fdec), lower_generics(lctx, generics))
910+
}
911+
ForeignItemKind::Static(ref t, m) => {
912+
hir::ForeignItemStatic(lower_ty(lctx, t), m)
913+
}
914+
},
915+
vis: lower_visibility(lctx, &i.vis),
916+
span: i.span,
917+
}
918+
})
862919
}
863920

864921
pub fn lower_method_sig(lctx: &LoweringContext, sig: &MethodSig) -> hir::MethodSig {
@@ -926,9 +983,11 @@ pub fn lower_pat(lctx: &LoweringContext, p: &Pat) -> P<hir::Pat> {
926983
node: match p.node {
927984
PatKind::Wild => hir::PatKind::Wild,
928985
PatKind::Ident(ref binding_mode, pth1, ref sub) => {
929-
hir::PatKind::Ident(lower_binding_mode(lctx, binding_mode),
930-
respan(pth1.span, lower_ident(lctx, pth1.node)),
931-
sub.as_ref().map(|x| lower_pat(lctx, x)))
986+
lctx.with_parent_def(p.id, || {
987+
hir::PatKind::Ident(lower_binding_mode(lctx, binding_mode),
988+
respan(pth1.span, lower_ident(lctx, pth1.node)),
989+
sub.as_ref().map(|x| lower_pat(lctx, x)))
990+
})
932991
}
933992
PatKind::Lit(ref e) => hir::PatKind::Lit(lower_expr(lctx, e)),
934993
PatKind::TupleStruct(ref pth, ref pats) => {
@@ -1202,9 +1261,11 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
12021261
hir::MatchSource::Normal)
12031262
}
12041263
ExprKind::Closure(capture_clause, ref decl, ref body) => {
1205-
hir::ExprClosure(lower_capture_clause(lctx, capture_clause),
1206-
lower_fn_decl(lctx, decl),
1207-
lower_block(lctx, body))
1264+
lctx.with_parent_def(e.id, || {
1265+
hir::ExprClosure(lower_capture_clause(lctx, capture_clause),
1266+
lower_fn_decl(lctx, decl),
1267+
lower_block(lctx, body))
1268+
})
12081269
}
12091270
ExprKind::Block(ref blk) => hir::ExprBlock(lower_block(lctx, blk)),
12101271
ExprKind::Assign(ref el, ref er) => {
@@ -1602,7 +1663,12 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
16021663
// `{ let _result = ...; _result }`
16031664
// underscore prevents an unused_variables lint if the head diverges
16041665
let result_ident = lctx.str_to_ident("_result");
1605-
let let_stmt = stmt_let(lctx, e.span, false, result_ident, match_expr, None);
1666+
let let_stmt = stmt_let(lctx,
1667+
e.span,
1668+
false,
1669+
result_ident,
1670+
match_expr,
1671+
None);
16061672
let result = expr_ident(lctx, e.span, result_ident, None);
16071673
let block = block_all(lctx, e.span, hir_vec![let_stmt], Some(result));
16081674
// add the attributes to the outer returned expr node
@@ -1655,7 +1721,8 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
16551721
let err_ctor = expr_path(lctx, path, None);
16561722
expr_call(lctx, e.span, err_ctor, hir_vec![from_expr], None)
16571723
};
1658-
let err_pat = pat_err(lctx, e.span, pat_ident(lctx, e.span, err_ident));
1724+
let err_pat = pat_err(lctx, e.span,
1725+
pat_ident(lctx, e.span, err_ident));
16591726
let ret_expr = expr(lctx, e.span,
16601727
hir::Expr_::ExprRet(Some(err_expr)), None);
16611728

@@ -1938,12 +2005,22 @@ fn pat_ident_binding_mode(lctx: &LoweringContext,
19382005
bm: hir::BindingMode)
19392006
-> P<hir::Pat> {
19402007
let pat_ident = hir::PatKind::Ident(bm,
1941-
Spanned {
1942-
span: span,
1943-
node: ident,
1944-
},
1945-
None);
1946-
pat(lctx, span, pat_ident)
2008+
Spanned {
2009+
span: span,
2010+
node: ident,
2011+
},
2012+
None);
2013+
2014+
let pat = pat(lctx, span, pat_ident);
2015+
2016+
if let Some(defs) = lctx.definitions {
2017+
let mut defs = defs.borrow_mut();
2018+
defs.create_def_with_parent(lctx.parent_def.get(),
2019+
pat.id,
2020+
DefPathData::Binding(ident.name));
2021+
}
2022+
2023+
pat
19472024
}
19482025

19492026
fn pat_wild(lctx: &LoweringContext, span: Span) -> P<hir::Pat> {
@@ -2130,7 +2207,8 @@ mod test {
21302207
let ast_in = quote_expr!(&cx, in HEAP { foo() });
21312208
let ast_in = assigner.fold_expr(ast_in);
21322209

2133-
let lctx = LoweringContext::new(&assigner, None);
2210+
let lctx = LoweringContext::testing_context(&assigner);
2211+
21342212
let hir1 = lower_expr(&lctx, &ast_if_let);
21352213
let hir2 = lower_expr(&lctx, &ast_if_let);
21362214
assert!(hir1 == hir2);

0 commit comments

Comments
 (0)