4343use hir;
4444use hir:: map:: Definitions ;
4545use 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
4849use std:: collections:: BTreeMap ;
4950use 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
7582impl < ' 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
17491765fn 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
17541775fn 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
17591780fn 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
17641788fn 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
17931821fn 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
18271856fn 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
18821914fn 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
0 commit comments