@@ -44,7 +44,7 @@ use hir;
44
44
use hir:: map:: Definitions ;
45
45
use hir:: map:: definitions:: DefPathData ;
46
46
use hir:: def_id:: { DefIndex , DefId } ;
47
- use hir:: def:: { Def , DefMap , PathResolution } ;
47
+ use hir:: def:: Def ;
48
48
49
49
use std:: collections:: BTreeMap ;
50
50
use std:: iter;
@@ -68,15 +68,30 @@ pub struct LoweringContext<'a> {
68
68
// the form of a DefIndex) so that if we create a new node which introduces
69
69
// a definition, then we can properly create the def id.
70
70
parent_def : Cell < Option < DefIndex > > ,
71
- resolver : Option < RefCell < & ' a mut Resolver > > ,
71
+ resolver : RefCell < & ' a mut Resolver > ,
72
72
}
73
73
74
74
pub trait Resolver {
75
+ // Resolve a global hir path generated by the lowerer when expanding `for`, `if let`, etc.
75
76
fn resolve_generated_global_path ( & mut self , path : & hir:: Path , is_value : bool ) -> Def ;
76
77
77
- fn def_map ( & mut self ) -> & mut DefMap ;
78
+ // Record the resolution of a path or binding generated by the lowerer when expanding.
79
+ fn record_resolution ( & mut self , id : NodeId , def : Def ) ;
80
+
78
81
// 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 ;
82
+ // This should only return `None` during testing.
83
+ fn definitions ( & mut self ) -> Option < & mut Definitions > ;
84
+ }
85
+
86
+ pub struct DummyResolver ;
87
+ impl Resolver for DummyResolver {
88
+ fn resolve_generated_global_path ( & mut self , _path : & hir:: Path , _is_value : bool ) -> Def {
89
+ Def :: Err
90
+ }
91
+ fn record_resolution ( & mut self , _id : NodeId , _def : Def ) { }
92
+ fn definitions ( & mut self ) -> Option < & mut Definitions > {
93
+ None
94
+ }
80
95
}
81
96
82
97
impl < ' a , ' hir > LoweringContext < ' a > {
@@ -98,18 +113,7 @@ impl<'a, 'hir> LoweringContext<'a> {
98
113
crate_root : crate_root,
99
114
id_assigner : id_assigner,
100
115
parent_def : Cell :: new ( None ) ,
101
- resolver : Some ( RefCell :: new ( resolver) ) ,
102
- }
103
- }
104
-
105
- // Only use this when you want a LoweringContext for testing and won't look
106
- // up def ids for anything created during lowering.
107
- pub fn testing_context ( id_assigner : & ' a NodeIdAssigner ) -> LoweringContext < ' a > {
108
- LoweringContext {
109
- crate_root : None ,
110
- id_assigner : id_assigner,
111
- parent_def : Cell :: new ( None ) ,
112
- resolver : None ,
116
+ resolver : RefCell :: new ( resolver) ,
113
117
}
114
118
}
115
119
@@ -127,37 +131,17 @@ impl<'a, 'hir> LoweringContext<'a> {
127
131
}
128
132
129
133
fn with_parent_def < T , F : FnOnce ( ) -> T > ( & self , parent_id : NodeId , f : F ) -> T {
130
- if self . resolver . is_none ( ) {
131
- // This should only be used for testing.
132
- return f ( ) ;
133
- }
134
-
135
134
let old_def = self . parent_def . get ( ) ;
136
- self . parent_def . set ( Some ( self . get_def ( parent_id) ) ) ;
135
+ self . parent_def . set ( match self . resolver . borrow_mut ( ) . definitions ( ) {
136
+ Some ( defs) => Some ( defs. opt_def_index ( parent_id) . unwrap ( ) ) ,
137
+ None => old_def,
138
+ } ) ;
139
+
137
140
let result = f ( ) ;
138
- self . parent_def . set ( old_def) ;
139
141
142
+ self . parent_def . set ( old_def) ;
140
143
result
141
144
}
142
-
143
- fn get_def ( & self , id : NodeId ) -> DefIndex {
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
- }
160
- }
161
145
}
162
146
163
147
pub fn lower_ident ( _lctx : & LoweringContext , ident : Ident ) -> hir:: Ident {
@@ -1765,10 +1749,12 @@ fn expr_call(lctx: &LoweringContext,
1765
1749
fn expr_ident ( lctx : & LoweringContext , span : Span , id : hir:: Ident ,
1766
1750
attrs : ThinAttributes , binding : NodeId ) -> P < hir:: Expr > {
1767
1751
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
- }
1752
+
1753
+ let mut resolver = lctx. resolver . borrow_mut ( ) ;
1754
+ let def = resolver. definitions ( ) . map ( |defs| Def :: Local ( defs. local_def_id ( binding) , binding) )
1755
+ . unwrap_or ( Def :: Err ) ;
1756
+ resolver. record_resolution ( expr. id , def) ;
1757
+
1772
1758
expr
1773
1759
}
1774
1760
@@ -1779,9 +1765,9 @@ fn expr_mut_addr_of(lctx: &LoweringContext, span: Span, e: P<hir::Expr>,
1779
1765
1780
1766
fn expr_path ( lctx : & LoweringContext , path : hir:: Path ,
1781
1767
attrs : ThinAttributes ) -> P < hir:: Expr > {
1782
- let def = lctx. resolve_generated_global_path ( & path, true ) ;
1768
+ let def = lctx. resolver . borrow_mut ( ) . resolve_generated_global_path ( & path, true ) ;
1783
1769
let expr = expr ( lctx, path. span , hir:: ExprPath ( None , path) , attrs) ;
1784
- lctx. record_def ( expr. id , def) ;
1770
+ lctx. resolver . borrow_mut ( ) . record_resolution ( expr. id , def) ;
1785
1771
expr
1786
1772
}
1787
1773
@@ -1811,9 +1797,9 @@ fn expr_struct(lctx: &LoweringContext,
1811
1797
fields : hir:: HirVec < hir:: Field > ,
1812
1798
e : Option < P < hir:: Expr > > ,
1813
1799
attrs : ThinAttributes ) -> P < hir:: Expr > {
1814
- let def = lctx. resolve_generated_global_path ( & path, false ) ;
1800
+ let def = lctx. resolver . borrow_mut ( ) . resolve_generated_global_path ( & path, false ) ;
1815
1801
let expr = expr ( lctx, sp, hir:: ExprStruct ( path, fields, e) , attrs) ;
1816
- lctx. record_def ( expr. id , def) ;
1802
+ lctx. resolver . borrow_mut ( ) . record_resolution ( expr. id , def) ;
1817
1803
expr
1818
1804
1819
1805
}
@@ -1900,14 +1886,14 @@ fn pat_enum(lctx: &LoweringContext,
1900
1886
path : hir:: Path ,
1901
1887
subpats : hir:: HirVec < P < hir:: Pat > > )
1902
1888
-> P < hir:: Pat > {
1903
- let def = lctx. resolve_generated_global_path ( & path, true ) ;
1889
+ let def = lctx. resolver . borrow_mut ( ) . resolve_generated_global_path ( & path, true ) ;
1904
1890
let pt = if subpats. is_empty ( ) {
1905
1891
hir:: PatKind :: Path ( path)
1906
1892
} else {
1907
1893
hir:: PatKind :: TupleStruct ( path, Some ( subpats) )
1908
1894
} ;
1909
1895
let pat = pat ( lctx, span, pt) ;
1910
- lctx. record_def ( pat. id , def) ;
1896
+ lctx. resolver . borrow_mut ( ) . record_resolution ( pat. id , def) ;
1911
1897
pat
1912
1898
}
1913
1899
@@ -1929,14 +1915,13 @@ fn pat_ident_binding_mode(lctx: &LoweringContext,
1929
1915
1930
1916
let pat = pat ( lctx, span, pat_ident) ;
1931
1917
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 ) ) ;
1939
- }
1918
+ let mut resolver = lctx. resolver . borrow_mut ( ) ;
1919
+ let def = resolver. definitions ( ) . map ( |defs| {
1920
+ let def_path_data = DefPathData :: Binding ( ident. name ) ;
1921
+ let def_index = defs. create_def_with_parent ( lctx. parent_def . get ( ) , pat. id , def_path_data) ;
1922
+ Def :: Local ( DefId :: local ( def_index) , pat. id )
1923
+ } ) . unwrap_or ( Def :: Err ) ;
1924
+ resolver. record_resolution ( pat. id , def) ;
1940
1925
1941
1926
pat
1942
1927
}
0 commit comments