35
35
#![ feature( iter_zip) ]
36
36
#![ recursion_limit = "256" ]
37
37
38
- use rustc_ast:: node_id:: NodeMap ;
39
38
use rustc_ast:: token:: { self , Token } ;
40
39
use rustc_ast:: tokenstream:: { CanSynthesizeMissingTokens , TokenStream , TokenTree } ;
41
40
use rustc_ast:: visit;
42
41
use rustc_ast:: { self as ast, * } ;
43
42
use rustc_ast_pretty:: pprust;
44
43
use rustc_data_structures:: captures:: Captures ;
45
- use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
44
+ use rustc_data_structures:: fx:: FxHashSet ;
46
45
use rustc_data_structures:: sync:: Lrc ;
47
46
use rustc_errors:: { struct_span_err, Applicability } ;
48
47
use rustc_hir as hir;
@@ -97,13 +96,12 @@ struct LoweringContext<'a, 'hir: 'a> {
97
96
arena : & ' hir Arena < ' hir > ,
98
97
99
98
/// The items being lowered are collected here.
100
- owners : IndexVec < LocalDefId , Option < hir:: OwnerNode < ' hir > > > ,
101
- bodies : BTreeMap < hir:: BodyId , hir:: Body < ' hir > > ,
99
+ owners : IndexVec < LocalDefId , Option < hir:: OwnerInfo < ' hir > > > ,
100
+ bodies : BTreeMap < hir:: ItemLocalId , hir:: Body < ' hir > > ,
101
+ attrs : BTreeMap < hir:: ItemLocalId , & ' hir [ Attribute ] > ,
102
102
103
103
generator_kind : Option < hir:: GeneratorKind > ,
104
104
105
- attrs : BTreeMap < hir:: HirId , & ' hir [ Attribute ] > ,
106
-
107
105
/// When inside an `async` context, this is the `HirId` of the
108
106
/// `task_context` local bound to the resume argument of the generator.
109
107
task_context : Option < hir:: HirId > ,
@@ -152,6 +150,9 @@ struct LoweringContext<'a, 'hir: 'a> {
152
150
item_local_id_counter : hir:: ItemLocalId ,
153
151
node_id_to_hir_id : IndexVec < NodeId , Option < hir:: HirId > > ,
154
152
153
+ /// NodeIds that are lowered inside the current HIR owner.
154
+ local_node_ids : Vec < NodeId > ,
155
+
155
156
allow_try_trait : Option < Lrc < [ Symbol ] > > ,
156
157
allow_gen_future : Option < Lrc < [ Symbol ] > > ,
157
158
}
@@ -182,7 +183,7 @@ pub trait ResolverAstLowering {
182
183
183
184
fn next_node_id ( & mut self ) -> NodeId ;
184
185
185
- fn take_trait_map ( & mut self ) -> NodeMap < Vec < hir:: TraitCandidate > > ;
186
+ fn take_trait_map ( & mut self , node : NodeId ) -> Option < Vec < hir:: TraitCandidate > > ;
186
187
187
188
fn opt_local_def_id ( & self , node : NodeId ) -> Option < LocalDefId > ;
188
189
@@ -314,12 +315,13 @@ pub fn lower_crate<'a, 'hir>(
314
315
) -> & ' hir hir:: Crate < ' hir > {
315
316
let _prof_timer = sess. prof . verbose_generic_activity ( "hir_lowering" ) ;
316
317
318
+ let owners = IndexVec :: from_fn_n ( |_| None , resolver. definitions ( ) . def_index_count ( ) ) ;
317
319
LoweringContext {
318
320
sess,
319
321
resolver,
320
322
nt_to_tokenstream,
321
323
arena,
322
- owners : IndexVec :: default ( ) ,
324
+ owners,
323
325
bodies : BTreeMap :: new ( ) ,
324
326
attrs : BTreeMap :: default ( ) ,
325
327
catch_scope : None ,
@@ -331,6 +333,7 @@ pub fn lower_crate<'a, 'hir>(
331
333
current_hir_id_owner : CRATE_DEF_ID ,
332
334
item_local_id_counter : hir:: ItemLocalId :: new ( 0 ) ,
333
335
node_id_to_hir_id : IndexVec :: new ( ) ,
336
+ local_node_ids : Vec :: new ( ) ,
334
337
generator_kind : None ,
335
338
task_context : None ,
336
339
current_item : None ,
@@ -420,14 +423,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
420
423
hir:: OwnerNode :: Crate ( lctx. arena . alloc ( module) )
421
424
} ) ;
422
425
423
- let mut trait_map: FxHashMap < _ , FxHashMap < _ , _ > > = FxHashMap :: default ( ) ;
424
- for ( k, v) in self . resolver . take_trait_map ( ) . into_iter ( ) {
425
- if let Some ( Some ( hir_id) ) = self . node_id_to_hir_id . get ( k) {
426
- let map = trait_map. entry ( hir_id. owner ) . or_default ( ) ;
427
- map. insert ( hir_id. local_id , v. into_boxed_slice ( ) ) ;
428
- }
429
- }
430
-
431
426
let mut def_id_to_hir_id = IndexVec :: default ( ) ;
432
427
433
428
for ( node_id, hir_id) in self . node_id_to_hir_id . into_iter_enumerated ( ) {
@@ -441,16 +436,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
441
436
442
437
self . resolver . definitions ( ) . init_def_id_to_hir_id_mapping ( def_id_to_hir_id) ;
443
438
444
- #[ cfg( debug_assertions) ]
445
- for ( & id, attrs) in self . attrs . iter ( ) {
446
- // Verify that we do not store empty slices in the map.
447
- if attrs. is_empty ( ) {
448
- panic ! ( "Stored empty attributes for {:?}" , id) ;
449
- }
450
- }
451
-
452
- let krate =
453
- hir:: Crate { owners : self . owners , bodies : self . bodies , trait_map, attrs : self . attrs } ;
439
+ let krate = hir:: Crate { owners : self . owners } ;
454
440
self . arena . alloc ( krate)
455
441
}
456
442
@@ -468,25 +454,57 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
468
454
) -> LocalDefId {
469
455
let def_id = self . resolver . local_def_id ( owner) ;
470
456
471
- // Always allocate the first `HirId` for the owner itself.
472
- let _old = self . node_id_to_hir_id . insert ( owner, hir:: HirId :: make_owner ( def_id) ) ;
473
- debug_assert_eq ! ( _old, None ) ;
474
-
457
+ let current_attrs = std:: mem:: take ( & mut self . attrs ) ;
458
+ let current_bodies = std:: mem:: take ( & mut self . bodies ) ;
459
+ let current_node_ids = std:: mem:: take ( & mut self . local_node_ids ) ;
475
460
let current_owner = std:: mem:: replace ( & mut self . current_hir_id_owner , def_id) ;
476
461
let current_local_counter =
477
462
std:: mem:: replace ( & mut self . item_local_id_counter , hir:: ItemLocalId :: new ( 1 ) ) ;
478
463
464
+ // Always allocate the first `HirId` for the owner itself.
465
+ let _old = self . node_id_to_hir_id . insert ( owner, hir:: HirId :: make_owner ( def_id) ) ;
466
+ debug_assert_eq ! ( _old, None ) ;
467
+ self . local_node_ids . push ( owner) ;
468
+
479
469
let item = f ( self ) ;
470
+ let info = self . make_owner_info ( item) ;
480
471
472
+ self . attrs = current_attrs;
473
+ self . bodies = current_bodies;
474
+ self . local_node_ids = current_node_ids;
481
475
self . current_hir_id_owner = current_owner;
482
476
self . item_local_id_counter = current_local_counter;
483
477
484
- let _old = self . owners . insert ( def_id, item ) ;
478
+ let _old = self . owners . insert ( def_id, info ) ;
485
479
debug_assert ! ( _old. is_none( ) ) ;
486
480
487
481
def_id
488
482
}
489
483
484
+ fn make_owner_info ( & mut self , node : hir:: OwnerNode < ' hir > ) -> hir:: OwnerInfo < ' hir > {
485
+ let attrs = std:: mem:: take ( & mut self . attrs ) ;
486
+ let bodies = std:: mem:: take ( & mut self . bodies ) ;
487
+ let local_node_ids = std:: mem:: take ( & mut self . local_node_ids ) ;
488
+ let trait_map = local_node_ids
489
+ . into_iter ( )
490
+ . filter_map ( |node_id| {
491
+ let hir_id = self . node_id_to_hir_id [ node_id] ?;
492
+ let traits = self . resolver . take_trait_map ( node_id) ?;
493
+ Some ( ( hir_id. local_id , traits. into_boxed_slice ( ) ) )
494
+ } )
495
+ . collect ( ) ;
496
+
497
+ #[ cfg( debug_assertions) ]
498
+ for ( & id, attrs) in attrs. iter ( ) {
499
+ // Verify that we do not store empty slices in the map.
500
+ if attrs. is_empty ( ) {
501
+ panic ! ( "Stored empty attributes for {:?}" , id) ;
502
+ }
503
+ }
504
+
505
+ hir:: OwnerInfo { node, attrs, bodies, trait_map }
506
+ }
507
+
490
508
/// This method allocates a new `HirId` for the given `NodeId` and stores it in
491
509
/// the `LoweringContext`'s `NodeId => HirId` map.
492
510
/// Take care not to call this method if the resulting `HirId` is then not
@@ -501,6 +519,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
501
519
let owner = self . current_hir_id_owner ;
502
520
let local_id = self . item_local_id_counter ;
503
521
self . item_local_id_counter . increment_by ( 1 ) ;
522
+ self . local_node_ids . push ( ast_node_id) ;
504
523
hir:: HirId { owner, local_id }
505
524
} )
506
525
}
@@ -791,9 +810,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
791
810
if attrs. is_empty ( ) {
792
811
None
793
812
} else {
813
+ debug_assert_eq ! ( id. owner, self . current_hir_id_owner) ;
794
814
let ret = self . arena . alloc_from_iter ( attrs. iter ( ) . map ( |a| self . lower_attr ( a) ) ) ;
795
815
debug_assert ! ( !ret. is_empty( ) ) ;
796
- self . attrs . insert ( id, ret) ;
816
+ self . attrs . insert ( id. local_id , ret) ;
797
817
Some ( ret)
798
818
}
799
819
}
@@ -819,9 +839,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
819
839
}
820
840
821
841
fn alias_attrs ( & mut self , id : hir:: HirId , target_id : hir:: HirId ) {
822
- if let Some ( & a) = self . attrs . get ( & target_id) {
842
+ debug_assert_eq ! ( id. owner, self . current_hir_id_owner) ;
843
+ debug_assert_eq ! ( target_id. owner, self . current_hir_id_owner) ;
844
+ if let Some ( & a) = self . attrs . get ( & target_id. local_id ) {
823
845
debug_assert ! ( !a. is_empty( ) ) ;
824
- self . attrs . insert ( id, a) ;
846
+ self . attrs . insert ( id. local_id , a) ;
825
847
}
826
848
}
827
849
@@ -2066,7 +2088,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
2066
2088
let hir_id = self . next_id ( ) ;
2067
2089
if let Some ( a) = attrs {
2068
2090
debug_assert ! ( !a. is_empty( ) ) ;
2069
- self . attrs . insert ( hir_id, a) ;
2091
+ self . attrs . insert ( hir_id. local_id , a) ;
2070
2092
}
2071
2093
let local = hir:: Local { hir_id, init, pat, source, span : self . lower_span ( span) , ty : None } ;
2072
2094
self . stmt ( span, hir:: StmtKind :: Local ( self . arena . alloc ( local) ) )
0 commit comments