29
29
// are unique). Every new node must have a unique id. Avoid cloning HIR nodes.
30
30
// If you do, you must then set the new node's id to a fresh one.
31
31
//
32
- // Lowering must be reproducable (the compiler only lowers once, but tools and
33
- // custom lints may lower an AST node to a HIR node to interact with the
34
- // compiler). The most interesting bit of this is ids - if you lower an AST node
35
- // and create new HIR nodes with fresh ids, when re-lowering the same node, you
36
- // must ensure you get the same ids! To do this, we keep track of the next id
37
- // when we translate a node which requires new ids. By checking this cache and
38
- // using node ids starting with the cached id, we ensure ids are reproducible.
39
- // To use this system, you just need to hold on to a CachedIdSetter object
40
- // whilst lowering. This is an RAII object that takes care of setting and
41
- // restoring the cached id, etc.
42
- //
43
- // This whole system relies on node ids being incremented one at a time and
44
- // all increments being for lowering. This means that you should not call any
45
- // non-lowering function which will use new node ids.
46
- //
47
32
// We must also cache gensym'ed Idents to ensure that we get the same Ident
48
33
// every time we lower a node with gensym'ed names. One consequence of this is
49
34
// that you can only gensym a name once in a lowering (you don't need to worry
@@ -67,7 +52,6 @@ use hir::map::definitions::DefPathData;
67
52
use hir:: def_id:: DefIndex ;
68
53
69
54
use std:: collections:: BTreeMap ;
70
- use std:: collections:: HashMap ;
71
55
use std:: iter;
72
56
use syntax:: ast:: * ;
73
57
use syntax:: attr:: { ThinAttributes , ThinAttributesExt } ;
@@ -83,18 +67,8 @@ use std::cell::{Cell, RefCell};
83
67
84
68
pub struct LoweringContext < ' a > {
85
69
crate_root : Option < & ' static str > ,
86
- // Map AST ids to ids used for expanded nodes.
87
- id_cache : RefCell < HashMap < NodeId , NodeId > > ,
88
- // Use if there are no cached ids for the current node.
70
+ // Use to assign ids to hir nodes that do not directly correspond to an ast node
89
71
id_assigner : & ' a NodeIdAssigner ,
90
- // 0 == no cached id. Must be incremented to align with previous id
91
- // incrementing.
92
- cached_id : Cell < u32 > ,
93
- // Keep track of gensym'ed idents.
94
- gensym_cache : RefCell < HashMap < ( NodeId , & ' static str ) , hir:: Ident > > ,
95
- // A copy of cached_id, but is also set to an id while a node is lowered for
96
- // the first time.
97
- gensym_key : Cell < u32 > ,
98
72
// We must keep the set of definitions up to date as we add nodes that
99
73
// weren't in the AST.
100
74
definitions : Option < & ' a RefCell < Definitions > > ,
@@ -121,11 +95,7 @@ impl<'a, 'hir> LoweringContext<'a> {
121
95
122
96
LoweringContext {
123
97
crate_root : crate_root,
124
- id_cache : RefCell :: new ( HashMap :: new ( ) ) ,
125
98
id_assigner : id_assigner,
126
- cached_id : Cell :: new ( 0 ) ,
127
- gensym_cache : RefCell :: new ( HashMap :: new ( ) ) ,
128
- gensym_key : Cell :: new ( 0 ) ,
129
99
definitions : Some ( defs) ,
130
100
parent_def : Cell :: new ( None ) ,
131
101
}
@@ -136,40 +106,18 @@ impl<'a, 'hir> LoweringContext<'a> {
136
106
pub fn testing_context ( id_assigner : & ' a NodeIdAssigner ) -> LoweringContext < ' a > {
137
107
LoweringContext {
138
108
crate_root : None ,
139
- id_cache : RefCell :: new ( HashMap :: new ( ) ) ,
140
109
id_assigner : id_assigner,
141
- cached_id : Cell :: new ( 0 ) ,
142
- gensym_cache : RefCell :: new ( HashMap :: new ( ) ) ,
143
- gensym_key : Cell :: new ( 0 ) ,
144
110
definitions : None ,
145
111
parent_def : Cell :: new ( None ) ,
146
112
}
147
113
}
148
114
149
115
fn next_id ( & self ) -> NodeId {
150
- let cached_id = self . cached_id . get ( ) ;
151
- if cached_id == 0 {
152
- return self . id_assigner . next_node_id ( ) ;
153
- }
154
-
155
- self . cached_id . set ( cached_id + 1 ) ;
156
- cached_id
116
+ self . id_assigner . next_node_id ( )
157
117
}
158
118
159
119
fn str_to_ident ( & self , s : & ' static str ) -> hir:: Ident {
160
- let gensym_key = self . gensym_key . get ( ) ;
161
- if gensym_key == 0 {
162
- return hir:: Ident :: from_name ( token:: gensym ( s) ) ;
163
- }
164
-
165
- let cached = self . gensym_cache . borrow ( ) . contains_key ( & ( gensym_key, s) ) ;
166
- if cached {
167
- self . gensym_cache . borrow ( ) [ & ( gensym_key, s) ]
168
- } else {
169
- let result = hir:: Ident :: from_name ( token:: gensym ( s) ) ;
170
- self . gensym_cache . borrow_mut ( ) . insert ( ( gensym_key, s) , result) ;
171
- result
172
- }
120
+ hir:: Ident :: from_name ( token:: gensym ( s) )
173
121
}
174
122
175
123
// Panics if this LoweringContext's NodeIdAssigner is not able to emit diagnostics.
@@ -197,56 +145,6 @@ impl<'a, 'hir> LoweringContext<'a> {
197
145
}
198
146
}
199
147
200
- // Utility fn for setting and unsetting the cached id.
201
- fn cache_ids < ' a , OP , R > ( lctx : & LoweringContext , expr_id : NodeId , op : OP ) -> R
202
- where OP : FnOnce ( & LoweringContext ) -> R
203
- {
204
- // Only reset the id if it was previously 0, i.e., was not cached.
205
- // If it was cached, we are in a nested node, but our id count will
206
- // still count towards the parent's count.
207
- let reset_cached_id = lctx. cached_id . get ( ) == 0 ;
208
- // We always reset gensym_key so that if we use the same name in a nested
209
- // node and after that node, they get different values.
210
- let old_gensym_key = lctx. gensym_key . get ( ) ;
211
-
212
- {
213
- let id_cache: & mut HashMap < _ , _ > = & mut lctx. id_cache . borrow_mut ( ) ;
214
-
215
- if id_cache. contains_key ( & expr_id) {
216
- panic ! ( "relowering!!!" ) ;
217
- /*
218
- let cached_id = lctx.cached_id.get();
219
- if cached_id == 0 {
220
- // We're entering a node where we need to track ids, but are not
221
- // yet tracking.
222
- lctx.cached_id.set(id_cache[&expr_id]);
223
- } else {
224
- // We're already tracking - check that the tracked id is the same
225
- // as the expected id.
226
- assert!(cached_id == id_cache[&expr_id], "id mismatch");
227
- }
228
- lctx.gensym_key.set(id_cache[&expr_id]);
229
- */
230
- } else {
231
- // We've never lowered this node before, remember it for next time.
232
- let next_id = lctx. id_assigner . peek_node_id ( ) ;
233
- id_cache. insert ( expr_id, next_id) ;
234
- lctx. gensym_key . set ( next_id) ;
235
- // self.cached_id is not set when we lower a node for the first time,
236
- // only on re-lowering.
237
- }
238
- }
239
-
240
- let result = op ( lctx) ;
241
-
242
- if reset_cached_id {
243
- lctx. cached_id . set ( 0 ) ;
244
- }
245
- lctx. gensym_key . set ( old_gensym_key) ;
246
-
247
- result
248
- }
249
-
250
148
pub fn lower_ident ( _lctx : & LoweringContext , ident : Ident ) -> hir:: Ident {
251
149
hir:: Ident {
252
150
name : mtwt:: resolve ( ident) ,
@@ -1080,7 +978,7 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
1080
978
// std::intrinsics::move_val_init(raw_place, pop_unsafe!( EXPR ));
1081
979
// InPlace::finalize(place)
1082
980
// })
1083
- return cache_ids ( lctx , e . id , |lctx| {
981
+ return {
1084
982
let placer_expr = lower_expr ( lctx, placer) ;
1085
983
let value_expr = lower_expr ( lctx, value_expr) ;
1086
984
@@ -1175,7 +1073,7 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
1175
1073
e. span ,
1176
1074
hir:: PushUnstableBlock ,
1177
1075
e. attrs . clone ( ) )
1178
- } ) ;
1076
+ }
1179
1077
}
1180
1078
1181
1079
ExprKind :: Vec ( ref exprs) => {
@@ -1229,20 +1127,18 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
1229
1127
let else_opt = else_opt. as_ref ( ) . map ( |els| {
1230
1128
match els. node {
1231
1129
ExprKind :: IfLet ( ..) => {
1232
- cache_ids ( lctx, e. id , |lctx| {
1233
- // wrap the if-let expr in a block
1234
- let span = els. span ;
1235
- let els = lower_expr ( lctx, els) ;
1236
- let id = lctx. next_id ( ) ;
1237
- let blk = P ( hir:: Block {
1238
- stmts : hir_vec ! [ ] ,
1239
- expr : Some ( els) ,
1240
- id : id,
1241
- rules : hir:: DefaultBlock ,
1242
- span : span,
1243
- } ) ;
1244
- expr_block ( lctx, blk, None )
1245
- } )
1130
+ // wrap the if-let expr in a block
1131
+ let span = els. span ;
1132
+ let els = lower_expr ( lctx, els) ;
1133
+ let id = lctx. next_id ( ) ;
1134
+ let blk = P ( hir:: Block {
1135
+ stmts : hir_vec ! [ ] ,
1136
+ expr : Some ( els) ,
1137
+ id : id,
1138
+ rules : hir:: DefaultBlock ,
1139
+ span : span,
1140
+ } ) ;
1141
+ expr_block ( lctx, blk, None )
1246
1142
}
1247
1143
_ => lower_expr ( lctx, els) ,
1248
1144
}
@@ -1331,7 +1227,7 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
1331
1227
None )
1332
1228
}
1333
1229
1334
- return cache_ids ( lctx , e . id , |lctx| {
1230
+ return {
1335
1231
use syntax:: ast:: RangeLimits :: * ;
1336
1232
1337
1233
match ( e1, e2, lims) {
@@ -1362,7 +1258,7 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
1362
1258
_ => panic ! ( lctx. diagnostic( ) . span_fatal( e. span,
1363
1259
"inclusive range with no end" ) )
1364
1260
}
1365
- } ) ;
1261
+ }
1366
1262
}
1367
1263
ExprKind :: Path ( ref qself, ref path) => {
1368
1264
let hir_qself = qself. as_ref ( ) . map ( |& QSelf { ref ty, position } | {
@@ -1436,7 +1332,7 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
1436
1332
// _ => [<else_opt> | ()]
1437
1333
// }
1438
1334
1439
- return cache_ids ( lctx , e . id , |lctx| {
1335
+ return {
1440
1336
// `<pat> => <body>`
1441
1337
let pat_arm = {
1442
1338
let body = lower_block ( lctx, body) ;
@@ -1510,7 +1406,7 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
1510
1406
contains_else_clause : contains_else_clause,
1511
1407
} ) ,
1512
1408
e. attrs . clone ( ) )
1513
- } ) ;
1409
+ }
1514
1410
}
1515
1411
1516
1412
// Desugar ExprWhileLet
@@ -1525,7 +1421,7 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
1525
1421
// }
1526
1422
// }
1527
1423
1528
- return cache_ids ( lctx , e . id , |lctx| {
1424
+ return {
1529
1425
// `<pat> => <body>`
1530
1426
let pat_arm = {
1531
1427
let body = lower_block ( lctx, body) ;
@@ -1556,7 +1452,7 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
1556
1452
opt_ident. map ( |ident| lower_ident ( lctx, ident) ) ) ;
1557
1453
// add attributes to the outer returned expr node
1558
1454
expr ( lctx, e. span , loop_expr, e. attrs . clone ( ) )
1559
- } ) ;
1455
+ }
1560
1456
}
1561
1457
1562
1458
// Desugar ExprForLoop
@@ -1578,7 +1474,7 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
1578
1474
// result
1579
1475
// }
1580
1476
1581
- return cache_ids ( lctx , e . id , |lctx| {
1477
+ return {
1582
1478
// expand <head>
1583
1479
let head = lower_expr ( lctx, head) ;
1584
1480
@@ -1677,7 +1573,7 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
1677
1573
let block = block_all ( lctx, e. span , hir_vec ! [ let_stmt] , Some ( result) ) ;
1678
1574
// add the attributes to the outer returned expr node
1679
1575
expr_block ( lctx, block, e. attrs . clone ( ) )
1680
- } ) ;
1576
+ }
1681
1577
}
1682
1578
1683
1579
// Desugar ExprKind::Try
@@ -1694,7 +1590,7 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
1694
1590
// }
1695
1591
// }
1696
1592
1697
- return cache_ids ( lctx , e . id , |lctx| {
1593
+ return {
1698
1594
// expand <expr>
1699
1595
let sub_expr = lower_expr ( lctx, sub_expr) ;
1700
1596
@@ -1735,7 +1631,7 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
1735
1631
1736
1632
expr_match ( lctx, e. span , sub_expr, hir_vec ! [ err_arm, ok_arm] ,
1737
1633
hir:: MatchSource :: TryDesugar , None )
1738
- } )
1634
+ }
1739
1635
}
1740
1636
1741
1637
ExprKind :: Mac ( _) => panic ! ( "Shouldn't exist here" ) ,
0 commit comments