Skip to content

Commit e5a0dd7

Browse files
committed
Resolve paths generated in the ast->hir lowerer
1 parent 983b4d3 commit e5a0dd7

File tree

3 files changed

+144
-76
lines changed

3 files changed

+144
-76
lines changed

src/librustc/hir/lowering.rs

Lines changed: 82 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@
4343
use hir;
4444
use hir::map::Definitions;
4545
use hir::map::definitions::DefPathData;
46-
use hir::def_id::DefIndex;
46+
use hir::def_id::{DefIndex, DefId};
47+
use hir::def::{Def, DefMap, PathResolution};
4748

4849
use std::collections::BTreeMap;
4950
use std::iter;
@@ -63,19 +64,25 @@ pub struct LoweringContext<'a> {
6364
crate_root: Option<&'static str>,
6465
// Use to assign ids to hir nodes that do not directly correspond to an ast node
6566
id_assigner: &'a NodeIdAssigner,
66-
// We must keep the set of definitions up to date as we add nodes that
67-
// weren't in the AST.
68-
definitions: Option<&'a RefCell<Definitions>>,
6967
// As we walk the AST we must keep track of the current 'parent' def id (in
7068
// the form of a DefIndex) so that if we create a new node which introduces
7169
// a definition, then we can properly create the def id.
7270
parent_def: Cell<Option<DefIndex>>,
71+
resolver: Option<RefCell<&'a mut Resolver>>,
72+
}
73+
74+
pub trait Resolver {
75+
fn resolve_generated_global_path(&mut self, path: &hir::Path, is_value: bool) -> Def;
76+
77+
fn def_map(&mut self) -> &mut DefMap;
78+
// We must keep the set of definitions up to date as we add nodes that weren't in the AST.
79+
fn definitions(&mut self) -> &mut Definitions;
7380
}
7481

7582
impl<'a, 'hir> LoweringContext<'a> {
7683
pub fn new(id_assigner: &'a NodeIdAssigner,
7784
c: Option<&Crate>,
78-
defs: &'a RefCell<Definitions>)
85+
resolver: &'a mut Resolver)
7986
-> LoweringContext<'a> {
8087
let crate_root = c.and_then(|c| {
8188
if std_inject::no_core(c) {
@@ -90,8 +97,8 @@ impl<'a, 'hir> LoweringContext<'a> {
9097
LoweringContext {
9198
crate_root: crate_root,
9299
id_assigner: id_assigner,
93-
definitions: Some(defs),
94100
parent_def: Cell::new(None),
101+
resolver: Some(RefCell::new(resolver)),
95102
}
96103
}
97104

@@ -101,8 +108,8 @@ impl<'a, 'hir> LoweringContext<'a> {
101108
LoweringContext {
102109
crate_root: None,
103110
id_assigner: id_assigner,
104-
definitions: None,
105111
parent_def: Cell::new(None),
112+
resolver: None,
106113
}
107114
}
108115

@@ -120,7 +127,7 @@ impl<'a, 'hir> LoweringContext<'a> {
120127
}
121128

122129
fn with_parent_def<T, F: FnOnce() -> T>(&self, parent_id: NodeId, f: F) -> T {
123-
if self.definitions.is_none() {
130+
if self.resolver.is_none() {
124131
// This should only be used for testing.
125132
return f();
126133
}
@@ -134,8 +141,22 @@ impl<'a, 'hir> LoweringContext<'a> {
134141
}
135142

136143
fn get_def(&self, id: NodeId) -> DefIndex {
137-
let defs = self.definitions.unwrap().borrow();
138-
defs.opt_def_index(id).unwrap()
144+
let mut resolver = self.resolver.as_ref().unwrap().borrow_mut();
145+
resolver.definitions().opt_def_index(id).unwrap()
146+
}
147+
148+
fn record_def(&self, id: NodeId, def: Def) {
149+
if let Some(ref resolver) = self.resolver {
150+
resolver.borrow_mut().def_map().insert(id, PathResolution { base_def: def, depth: 0 });
151+
}
152+
}
153+
154+
fn resolve_generated_global_path(&self, path: &hir::Path, is_value: bool) -> Def {
155+
if let Some(ref resolver) = self.resolver {
156+
resolver.borrow_mut().resolve_generated_global_path(path, is_value)
157+
} else {
158+
Def::Err
159+
}
139160
}
140161
}
141162

@@ -999,7 +1020,7 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
9991020
};
10001021

10011022
// let placer = <placer_expr> ;
1002-
let s1 = {
1023+
let (s1, placer_binding) = {
10031024
let placer_expr = signal_block_expr(lctx,
10041025
hir_vec![],
10051026
placer_expr,
@@ -1010,15 +1031,15 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
10101031
};
10111032

10121033
// let mut place = Placer::make_place(placer);
1013-
let s2 = {
1014-
let placer = expr_ident(lctx, e.span, placer_ident, None);
1034+
let (s2, place_binding) = {
1035+
let placer = expr_ident(lctx, e.span, placer_ident, None, placer_binding);
10151036
let call = make_call(lctx, &make_place, hir_vec![placer]);
10161037
mk_stmt_let_mut(lctx, place_ident, call)
10171038
};
10181039

10191040
// let p_ptr = Place::pointer(&mut place);
1020-
let s3 = {
1021-
let agent = expr_ident(lctx, e.span, place_ident, None);
1041+
let (s3, p_ptr_binding) = {
1042+
let agent = expr_ident(lctx, e.span, place_ident, None, place_binding);
10221043
let args = hir_vec![expr_mut_addr_of(lctx, e.span, agent, None)];
10231044
let call = make_call(lctx, &place_pointer, args);
10241045
mk_stmt_let(lctx, p_ptr_ident, call)
@@ -1044,14 +1065,14 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
10441065
// InPlace::finalize(place)
10451066
// })
10461067
let expr = {
1047-
let ptr = expr_ident(lctx, e.span, p_ptr_ident, None);
1068+
let ptr = expr_ident(lctx, e.span, p_ptr_ident, None, p_ptr_binding);
10481069
let call_move_val_init =
10491070
hir::StmtSemi(
10501071
make_call(lctx, &move_val_init, hir_vec![ptr, pop_unsafe_expr]),
10511072
lctx.next_id());
10521073
let call_move_val_init = respan(e.span, call_move_val_init);
10531074

1054-
let place = expr_ident(lctx, e.span, place_ident, None);
1075+
let place = expr_ident(lctx, e.span, place_ident, None, place_binding);
10551076
let call = make_call(lctx, &inplace_finalize, hir_vec![place]);
10561077
signal_block_expr(lctx,
10571078
hir_vec![call_move_val_init],
@@ -1489,14 +1510,18 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
14891510
arm(hir_vec![pat_none(lctx, e.span)], break_expr)
14901511
};
14911512

1513+
// `mut iter`
1514+
let iter_pat =
1515+
pat_ident_binding_mode(lctx, e.span, iter, hir::BindByValue(hir::MutMutable));
1516+
14921517
// `match ::std::iter::Iterator::next(&mut iter) { ... }`
14931518
let match_expr = {
14941519
let next_path = {
14951520
let strs = std_path(lctx, &["iter", "Iterator", "next"]);
14961521

14971522
path_global(e.span, strs)
14981523
};
1499-
let iter = expr_ident(lctx, e.span, iter, None);
1524+
let iter = expr_ident(lctx, e.span, iter, None, iter_pat.id);
15001525
let ref_mut_iter = expr_mut_addr_of(lctx, e.span, iter, None);
15011526
let next_path = expr_path(lctx, next_path, None);
15021527
let next_expr = expr_call(lctx,
@@ -1520,13 +1545,7 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
15201545
P(hir::Expr { id: e.id, node: loop_expr, span: e.span, attrs: None });
15211546

15221547
// `mut iter => { ... }`
1523-
let iter_arm = {
1524-
let iter_pat = pat_ident_binding_mode(lctx,
1525-
e.span,
1526-
iter,
1527-
hir::BindByValue(hir::MutMutable));
1528-
arm(hir_vec![iter_pat], loop_expr)
1529-
};
1548+
let iter_arm = arm(hir_vec![iter_pat], loop_expr);
15301549

15311550
// `match ::std::iter::IntoIterator::into_iter(<head>) { ... }`
15321551
let into_iter_expr = {
@@ -1550,13 +1569,10 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
15501569
// `{ let _result = ...; _result }`
15511570
// underscore prevents an unused_variables lint if the head diverges
15521571
let result_ident = lctx.str_to_ident("_result");
1553-
let let_stmt = stmt_let(lctx,
1554-
e.span,
1555-
false,
1556-
result_ident,
1557-
match_expr,
1558-
None);
1559-
let result = expr_ident(lctx, e.span, result_ident, None);
1572+
let (let_stmt, let_stmt_binding) =
1573+
stmt_let(lctx, e.span, false, result_ident, match_expr, None);
1574+
1575+
let result = expr_ident(lctx, e.span, result_ident, None, let_stmt_binding);
15601576
let block = block_all(lctx, e.span, hir_vec![let_stmt], Some(result));
15611577
// add the attributes to the outer returned expr node
15621578
return expr_block(lctx, block, e.attrs.clone());
@@ -1583,7 +1599,7 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
15831599
let ok_arm = {
15841600
let val_ident = lctx.str_to_ident("val");
15851601
let val_pat = pat_ident(lctx, e.span, val_ident);
1586-
let val_expr = expr_ident(lctx, e.span, val_ident, None);
1602+
let val_expr = expr_ident(lctx, e.span, val_ident, None, val_pat.id);
15871603
let ok_pat = pat_ok(lctx, e.span, val_pat);
15881604

15891605
arm(hir_vec![ok_pat], val_expr)
@@ -1592,11 +1608,12 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
15921608
// Err(err) => return Err(From::from(err))
15931609
let err_arm = {
15941610
let err_ident = lctx.str_to_ident("err");
1611+
let err_local = pat_ident(lctx, e.span, err_ident);
15951612
let from_expr = {
15961613
let path = std_path(lctx, &["convert", "From", "from"]);
15971614
let path = path_global(e.span, path);
15981615
let from = expr_path(lctx, path, None);
1599-
let err_expr = expr_ident(lctx, e.span, err_ident, None);
1616+
let err_expr = expr_ident(lctx, e.span, err_ident, None, err_local.id);
16001617

16011618
expr_call(lctx, e.span, from, hir_vec![err_expr], None)
16021619
};
@@ -1606,8 +1623,7 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
16061623
let err_ctor = expr_path(lctx, path, None);
16071624
expr_call(lctx, e.span, err_ctor, hir_vec![from_expr], None)
16081625
};
1609-
let err_pat = pat_err(lctx, e.span,
1610-
pat_ident(lctx, e.span, err_ident));
1626+
let err_pat = pat_err(lctx, e.span, err_local);
16111627
let ret_expr = expr(lctx, e.span,
16121628
hir::Expr_::ExprRet(Some(err_expr)), None);
16131629

@@ -1747,8 +1763,13 @@ fn expr_call(lctx: &LoweringContext,
17471763
}
17481764

17491765
fn expr_ident(lctx: &LoweringContext, span: Span, id: hir::Ident,
1750-
attrs: ThinAttributes) -> P<hir::Expr> {
1751-
expr_path(lctx, path_ident(span, id), attrs)
1766+
attrs: ThinAttributes, binding: NodeId) -> P<hir::Expr> {
1767+
let expr = expr(lctx, span, hir::ExprPath(None, path_ident(span, id)), attrs);
1768+
if let Some(ref resolver) = lctx.resolver {
1769+
let def_id = resolver.borrow_mut().definitions().local_def_id(binding);
1770+
lctx.record_def(expr.id, Def::Local(def_id, binding));
1771+
}
1772+
expr
17521773
}
17531774

17541775
fn expr_mut_addr_of(lctx: &LoweringContext, span: Span, e: P<hir::Expr>,
@@ -1758,7 +1779,10 @@ fn expr_mut_addr_of(lctx: &LoweringContext, span: Span, e: P<hir::Expr>,
17581779

17591780
fn expr_path(lctx: &LoweringContext, path: hir::Path,
17601781
attrs: ThinAttributes) -> P<hir::Expr> {
1761-
expr(lctx, path.span, hir::ExprPath(None, path), attrs)
1782+
let def = lctx.resolve_generated_global_path(&path, true);
1783+
let expr = expr(lctx, path.span, hir::ExprPath(None, path), attrs);
1784+
lctx.record_def(expr.id, def);
1785+
expr
17621786
}
17631787

17641788
fn expr_match(lctx: &LoweringContext,
@@ -1787,7 +1811,11 @@ fn expr_struct(lctx: &LoweringContext,
17871811
fields: hir::HirVec<hir::Field>,
17881812
e: Option<P<hir::Expr>>,
17891813
attrs: ThinAttributes) -> P<hir::Expr> {
1790-
expr(lctx, sp, hir::ExprStruct(path, fields, e), attrs)
1814+
let def = lctx.resolve_generated_global_path(&path, false);
1815+
let expr = expr(lctx, sp, hir::ExprStruct(path, fields, e), attrs);
1816+
lctx.record_def(expr.id, def);
1817+
expr
1818+
17911819
}
17921820

17931821
fn expr(lctx: &LoweringContext, span: Span, node: hir::Expr_,
@@ -1806,12 +1834,13 @@ fn stmt_let(lctx: &LoweringContext,
18061834
ident: hir::Ident,
18071835
ex: P<hir::Expr>,
18081836
attrs: ThinAttributes)
1809-
-> hir::Stmt {
1837+
-> (hir::Stmt, NodeId) {
18101838
let pat = if mutbl {
18111839
pat_ident_binding_mode(lctx, sp, ident, hir::BindByValue(hir::MutMutable))
18121840
} else {
18131841
pat_ident(lctx, sp, ident)
18141842
};
1843+
let pat_id = pat.id;
18151844
let local = P(hir::Local {
18161845
pat: pat,
18171846
ty: None,
@@ -1821,7 +1850,7 @@ fn stmt_let(lctx: &LoweringContext,
18211850
attrs: attrs,
18221851
});
18231852
let decl = respan(sp, hir::DeclLocal(local));
1824-
respan(sp, hir::StmtDecl(P(decl), lctx.next_id()))
1853+
(respan(sp, hir::StmtDecl(P(decl), lctx.next_id())), pat_id)
18251854
}
18261855

18271856
fn block_expr(lctx: &LoweringContext, expr: P<hir::Expr>) -> P<hir::Block> {
@@ -1871,12 +1900,15 @@ fn pat_enum(lctx: &LoweringContext,
18711900
path: hir::Path,
18721901
subpats: hir::HirVec<P<hir::Pat>>)
18731902
-> P<hir::Pat> {
1903+
let def = lctx.resolve_generated_global_path(&path, true);
18741904
let pt = if subpats.is_empty() {
18751905
hir::PatKind::Path(path)
18761906
} else {
18771907
hir::PatKind::TupleStruct(path, Some(subpats))
18781908
};
1879-
pat(lctx, span, pt)
1909+
let pat = pat(lctx, span, pt);
1910+
lctx.record_def(pat.id, def);
1911+
pat
18801912
}
18811913

18821914
fn pat_ident(lctx: &LoweringContext, span: Span, ident: hir::Ident) -> P<hir::Pat> {
@@ -1897,11 +1929,13 @@ fn pat_ident_binding_mode(lctx: &LoweringContext,
18971929

18981930
let pat = pat(lctx, span, pat_ident);
18991931

1900-
if let Some(defs) = lctx.definitions {
1901-
let mut defs = defs.borrow_mut();
1902-
defs.create_def_with_parent(lctx.parent_def.get(),
1903-
pat.id,
1904-
DefPathData::Binding(ident.name));
1932+
if let Some(ref resolver) = lctx.resolver {
1933+
let def_index =
1934+
resolver.borrow_mut().definitions()
1935+
.create_def_with_parent(lctx.parent_def.get(),
1936+
pat.id,
1937+
DefPathData::Binding(ident.name));
1938+
lctx.record_def(pat.id, Def::Local(DefId::local(def_index), pat.id));
19051939
}
19061940

19071941
pat

src/librustc_driver/driver.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -154,12 +154,19 @@ pub fn compile_input(sess: &Session,
154154
"early lint checks",
155155
|| lint::check_ast_crate(sess, &expanded_crate));
156156

157-
let (analysis, resolutions) = {
158-
resolve::with_resolver(sess, &defs.borrow(), control.make_glob_map, |mut resolver| {
157+
let (analysis, resolutions, mut hir_forest) = {
158+
let defs = &mut *defs.borrow_mut();
159+
resolve::with_resolver(sess, defs, control.make_glob_map, |mut resolver| {
159160
time(sess.time_passes(), "name resolution", || {
160161
resolve::resolve_crate(&mut resolver, &expanded_crate);
161162
});
162163

164+
// Lower ast -> hir.
165+
let hir_forest = time(sess.time_passes(), "lowering ast -> hir", || {
166+
let lcx = LoweringContext::new(sess, Some(&expanded_crate), &mut resolver);
167+
hir_map::Forest::new(lower_crate(&lcx, &expanded_crate), dep_graph)
168+
});
169+
163170
(ty::CrateAnalysis {
164171
export_map: resolver.export_map,
165172
access_levels: AccessLevels::default(),
@@ -171,17 +178,10 @@ pub fn compile_input(sess: &Session,
171178
freevars: resolver.freevars,
172179
trait_map: resolver.trait_map,
173180
maybe_unused_trait_imports: resolver.maybe_unused_trait_imports,
174-
})
181+
}, hir_forest)
175182
})
176183
};
177184

178-
// Lower ast -> hir.
179-
let lcx = LoweringContext::new(sess, Some(&expanded_crate), defs);
180-
let hir_forest = &mut time(sess.time_passes(),
181-
"lowering ast -> hir",
182-
|| hir_map::Forest::new(lower_crate(&lcx, &expanded_crate),
183-
dep_graph));
184-
185185
// Discard MTWT tables that aren't required past lowering to HIR.
186186
if !keep_mtwt_tables(sess) {
187187
syntax::ext::mtwt::clear_tables();
@@ -190,6 +190,7 @@ pub fn compile_input(sess: &Session,
190190
let arenas = ty::CtxtArenas::new();
191191

192192
// Construct the HIR map
193+
let hir_forest = &mut hir_forest;
193194
let hir_map = time(sess.time_passes(),
194195
"indexing hir",
195196
move || hir_map::map_crate(hir_forest, defs));

0 commit comments

Comments
 (0)