43
43
use hir;
44
44
use hir:: map:: Definitions ;
45
45
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 } ;
47
48
48
49
use std:: collections:: BTreeMap ;
49
50
use std:: iter;
@@ -63,19 +64,25 @@ pub struct LoweringContext<'a> {
63
64
crate_root : Option < & ' static str > ,
64
65
// Use to assign ids to hir nodes that do not directly correspond to an ast node
65
66
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 > > ,
69
67
// As we walk the AST we must keep track of the current 'parent' def id (in
70
68
// the form of a DefIndex) so that if we create a new node which introduces
71
69
// a definition, then we can properly create the def id.
72
70
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 ;
73
80
}
74
81
75
82
impl < ' a , ' hir > LoweringContext < ' a > {
76
83
pub fn new ( id_assigner : & ' a NodeIdAssigner ,
77
84
c : Option < & Crate > ,
78
- defs : & ' a RefCell < Definitions > )
85
+ resolver : & ' a mut Resolver )
79
86
-> LoweringContext < ' a > {
80
87
let crate_root = c. and_then ( |c| {
81
88
if std_inject:: no_core ( c) {
@@ -90,8 +97,8 @@ impl<'a, 'hir> LoweringContext<'a> {
90
97
LoweringContext {
91
98
crate_root : crate_root,
92
99
id_assigner : id_assigner,
93
- definitions : Some ( defs) ,
94
100
parent_def : Cell :: new ( None ) ,
101
+ resolver : Some ( RefCell :: new ( resolver) ) ,
95
102
}
96
103
}
97
104
@@ -101,8 +108,8 @@ impl<'a, 'hir> LoweringContext<'a> {
101
108
LoweringContext {
102
109
crate_root : None ,
103
110
id_assigner : id_assigner,
104
- definitions : None ,
105
111
parent_def : Cell :: new ( None ) ,
112
+ resolver : None ,
106
113
}
107
114
}
108
115
@@ -120,7 +127,7 @@ impl<'a, 'hir> LoweringContext<'a> {
120
127
}
121
128
122
129
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 ( ) {
124
131
// This should only be used for testing.
125
132
return f ( ) ;
126
133
}
@@ -134,8 +141,22 @@ impl<'a, 'hir> LoweringContext<'a> {
134
141
}
135
142
136
143
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
+ }
139
160
}
140
161
}
141
162
@@ -999,7 +1020,7 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
999
1020
} ;
1000
1021
1001
1022
// let placer = <placer_expr> ;
1002
- let s1 = {
1023
+ let ( s1 , placer_binding ) = {
1003
1024
let placer_expr = signal_block_expr ( lctx,
1004
1025
hir_vec ! [ ] ,
1005
1026
placer_expr,
@@ -1010,15 +1031,15 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
1010
1031
} ;
1011
1032
1012
1033
// 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 ) ;
1015
1036
let call = make_call ( lctx, & make_place, hir_vec ! [ placer] ) ;
1016
1037
mk_stmt_let_mut ( lctx, place_ident, call)
1017
1038
} ;
1018
1039
1019
1040
// 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 ) ;
1022
1043
let args = hir_vec ! [ expr_mut_addr_of( lctx, e. span, agent, None ) ] ;
1023
1044
let call = make_call ( lctx, & place_pointer, args) ;
1024
1045
mk_stmt_let ( lctx, p_ptr_ident, call)
@@ -1044,14 +1065,14 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
1044
1065
// InPlace::finalize(place)
1045
1066
// })
1046
1067
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 ) ;
1048
1069
let call_move_val_init =
1049
1070
hir:: StmtSemi (
1050
1071
make_call ( lctx, & move_val_init, hir_vec ! [ ptr, pop_unsafe_expr] ) ,
1051
1072
lctx. next_id ( ) ) ;
1052
1073
let call_move_val_init = respan ( e. span , call_move_val_init) ;
1053
1074
1054
- let place = expr_ident ( lctx, e. span , place_ident, None ) ;
1075
+ let place = expr_ident ( lctx, e. span , place_ident, None , place_binding ) ;
1055
1076
let call = make_call ( lctx, & inplace_finalize, hir_vec ! [ place] ) ;
1056
1077
signal_block_expr ( lctx,
1057
1078
hir_vec ! [ call_move_val_init] ,
@@ -1489,14 +1510,18 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
1489
1510
arm ( hir_vec ! [ pat_none( lctx, e. span) ] , break_expr)
1490
1511
} ;
1491
1512
1513
+ // `mut iter`
1514
+ let iter_pat =
1515
+ pat_ident_binding_mode ( lctx, e. span , iter, hir:: BindByValue ( hir:: MutMutable ) ) ;
1516
+
1492
1517
// `match ::std::iter::Iterator::next(&mut iter) { ... }`
1493
1518
let match_expr = {
1494
1519
let next_path = {
1495
1520
let strs = std_path ( lctx, & [ "iter" , "Iterator" , "next" ] ) ;
1496
1521
1497
1522
path_global ( e. span , strs)
1498
1523
} ;
1499
- let iter = expr_ident ( lctx, e. span , iter, None ) ;
1524
+ let iter = expr_ident ( lctx, e. span , iter, None , iter_pat . id ) ;
1500
1525
let ref_mut_iter = expr_mut_addr_of ( lctx, e. span , iter, None ) ;
1501
1526
let next_path = expr_path ( lctx, next_path, None ) ;
1502
1527
let next_expr = expr_call ( lctx,
@@ -1520,13 +1545,7 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
1520
1545
P ( hir:: Expr { id : e. id , node : loop_expr, span : e. span , attrs : None } ) ;
1521
1546
1522
1547
// `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) ;
1530
1549
1531
1550
// `match ::std::iter::IntoIterator::into_iter(<head>) { ... }`
1532
1551
let into_iter_expr = {
@@ -1550,13 +1569,10 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
1550
1569
// `{ let _result = ...; _result }`
1551
1570
// underscore prevents an unused_variables lint if the head diverges
1552
1571
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) ;
1560
1576
let block = block_all ( lctx, e. span , hir_vec ! [ let_stmt] , Some ( result) ) ;
1561
1577
// add the attributes to the outer returned expr node
1562
1578
return expr_block ( lctx, block, e. attrs . clone ( ) ) ;
@@ -1583,7 +1599,7 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
1583
1599
let ok_arm = {
1584
1600
let val_ident = lctx. str_to_ident ( "val" ) ;
1585
1601
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 ) ;
1587
1603
let ok_pat = pat_ok ( lctx, e. span , val_pat) ;
1588
1604
1589
1605
arm ( hir_vec ! [ ok_pat] , val_expr)
@@ -1592,11 +1608,12 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
1592
1608
// Err(err) => return Err(From::from(err))
1593
1609
let err_arm = {
1594
1610
let err_ident = lctx. str_to_ident ( "err" ) ;
1611
+ let err_local = pat_ident ( lctx, e. span , err_ident) ;
1595
1612
let from_expr = {
1596
1613
let path = std_path ( lctx, & [ "convert" , "From" , "from" ] ) ;
1597
1614
let path = path_global ( e. span , path) ;
1598
1615
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 ) ;
1600
1617
1601
1618
expr_call ( lctx, e. span , from, hir_vec ! [ err_expr] , None )
1602
1619
} ;
@@ -1606,8 +1623,7 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
1606
1623
let err_ctor = expr_path ( lctx, path, None ) ;
1607
1624
expr_call ( lctx, e. span , err_ctor, hir_vec ! [ from_expr] , None )
1608
1625
} ;
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) ;
1611
1627
let ret_expr = expr ( lctx, e. span ,
1612
1628
hir:: Expr_ :: ExprRet ( Some ( err_expr) ) , None ) ;
1613
1629
@@ -1747,8 +1763,13 @@ fn expr_call(lctx: &LoweringContext,
1747
1763
}
1748
1764
1749
1765
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
1752
1773
}
1753
1774
1754
1775
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>,
1758
1779
1759
1780
fn expr_path ( lctx : & LoweringContext , path : hir:: Path ,
1760
1781
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
1762
1786
}
1763
1787
1764
1788
fn expr_match ( lctx : & LoweringContext ,
@@ -1787,7 +1811,11 @@ fn expr_struct(lctx: &LoweringContext,
1787
1811
fields : hir:: HirVec < hir:: Field > ,
1788
1812
e : Option < P < hir:: Expr > > ,
1789
1813
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
+
1791
1819
}
1792
1820
1793
1821
fn expr ( lctx : & LoweringContext , span : Span , node : hir:: Expr_ ,
@@ -1806,12 +1834,13 @@ fn stmt_let(lctx: &LoweringContext,
1806
1834
ident : hir:: Ident ,
1807
1835
ex : P < hir:: Expr > ,
1808
1836
attrs : ThinAttributes )
1809
- -> hir:: Stmt {
1837
+ -> ( hir:: Stmt , NodeId ) {
1810
1838
let pat = if mutbl {
1811
1839
pat_ident_binding_mode ( lctx, sp, ident, hir:: BindByValue ( hir:: MutMutable ) )
1812
1840
} else {
1813
1841
pat_ident ( lctx, sp, ident)
1814
1842
} ;
1843
+ let pat_id = pat. id ;
1815
1844
let local = P ( hir:: Local {
1816
1845
pat : pat,
1817
1846
ty : None ,
@@ -1821,7 +1850,7 @@ fn stmt_let(lctx: &LoweringContext,
1821
1850
attrs : attrs,
1822
1851
} ) ;
1823
1852
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 )
1825
1854
}
1826
1855
1827
1856
fn block_expr ( lctx : & LoweringContext , expr : P < hir:: Expr > ) -> P < hir:: Block > {
@@ -1871,12 +1900,15 @@ fn pat_enum(lctx: &LoweringContext,
1871
1900
path : hir:: Path ,
1872
1901
subpats : hir:: HirVec < P < hir:: Pat > > )
1873
1902
-> P < hir:: Pat > {
1903
+ let def = lctx. resolve_generated_global_path ( & path, true ) ;
1874
1904
let pt = if subpats. is_empty ( ) {
1875
1905
hir:: PatKind :: Path ( path)
1876
1906
} else {
1877
1907
hir:: PatKind :: TupleStruct ( path, Some ( subpats) )
1878
1908
} ;
1879
- pat ( lctx, span, pt)
1909
+ let pat = pat ( lctx, span, pt) ;
1910
+ lctx. record_def ( pat. id , def) ;
1911
+ pat
1880
1912
}
1881
1913
1882
1914
fn pat_ident ( lctx : & LoweringContext , span : Span , ident : hir:: Ident ) -> P < hir:: Pat > {
@@ -1897,11 +1929,13 @@ fn pat_ident_binding_mode(lctx: &LoweringContext,
1897
1929
1898
1930
let pat = pat ( lctx, span, pat_ident) ;
1899
1931
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 ) ) ;
1905
1939
}
1906
1940
1907
1941
pat
0 commit comments