3535#![ feature( iter_zip) ]
3636#![ recursion_limit = "256" ]
3737
38- use rustc_ast:: node_id:: NodeMap ;
3938use rustc_ast:: token:: { self , Token } ;
4039use rustc_ast:: tokenstream:: { CanSynthesizeMissingTokens , TokenStream , TokenTree } ;
4140use rustc_ast:: visit;
4241use rustc_ast:: { self as ast, * } ;
4342use rustc_ast_pretty:: pprust;
4443use rustc_data_structures:: captures:: Captures ;
45- use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
44+ use rustc_data_structures:: fx:: FxHashSet ;
4645use rustc_data_structures:: sync:: Lrc ;
4746use rustc_errors:: { struct_span_err, Applicability } ;
4847use rustc_hir as hir;
@@ -97,13 +96,12 @@ struct LoweringContext<'a, 'hir: 'a> {
9796 arena : & ' hir Arena < ' hir > ,
9897
9998 /// 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 ] > ,
102102
103103 generator_kind : Option < hir:: GeneratorKind > ,
104104
105- attrs : BTreeMap < hir:: HirId , & ' hir [ Attribute ] > ,
106-
107105 /// When inside an `async` context, this is the `HirId` of the
108106 /// `task_context` local bound to the resume argument of the generator.
109107 task_context : Option < hir:: HirId > ,
@@ -152,6 +150,9 @@ struct LoweringContext<'a, 'hir: 'a> {
152150 item_local_id_counter : hir:: ItemLocalId ,
153151 node_id_to_hir_id : IndexVec < NodeId , Option < hir:: HirId > > ,
154152
153+ /// NodeIds that are lowered inside the current HIR owner.
154+ local_node_ids : Vec < NodeId > ,
155+
155156 allow_try_trait : Option < Lrc < [ Symbol ] > > ,
156157 allow_gen_future : Option < Lrc < [ Symbol ] > > ,
157158}
@@ -182,7 +183,7 @@ pub trait ResolverAstLowering {
182183
183184 fn next_node_id ( & mut self ) -> NodeId ;
184185
185- fn take_trait_map ( & mut self ) -> NodeMap < Vec < hir:: TraitCandidate > > ;
186+ fn take_trait_map ( & mut self , node : NodeId ) -> Option < Vec < hir:: TraitCandidate > > ;
186187
187188 fn opt_local_def_id ( & self , node : NodeId ) -> Option < LocalDefId > ;
188189
@@ -314,12 +315,13 @@ pub fn lower_crate<'a, 'hir>(
314315) -> & ' hir hir:: Crate < ' hir > {
315316 let _prof_timer = sess. prof . verbose_generic_activity ( "hir_lowering" ) ;
316317
318+ let owners = IndexVec :: from_fn_n ( |_| None , resolver. definitions ( ) . def_index_count ( ) ) ;
317319 LoweringContext {
318320 sess,
319321 resolver,
320322 nt_to_tokenstream,
321323 arena,
322- owners : IndexVec :: default ( ) ,
324+ owners,
323325 bodies : BTreeMap :: new ( ) ,
324326 attrs : BTreeMap :: default ( ) ,
325327 catch_scope : None ,
@@ -331,6 +333,7 @@ pub fn lower_crate<'a, 'hir>(
331333 current_hir_id_owner : CRATE_DEF_ID ,
332334 item_local_id_counter : hir:: ItemLocalId :: new ( 0 ) ,
333335 node_id_to_hir_id : IndexVec :: new ( ) ,
336+ local_node_ids : Vec :: new ( ) ,
334337 generator_kind : None ,
335338 task_context : None ,
336339 current_item : None ,
@@ -420,14 +423,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
420423 hir:: OwnerNode :: Crate ( lctx. arena . alloc ( module) )
421424 } ) ;
422425
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-
431426 let mut def_id_to_hir_id = IndexVec :: default ( ) ;
432427
433428 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> {
441436
442437 self . resolver . definitions ( ) . init_def_id_to_hir_id_mapping ( def_id_to_hir_id) ;
443438
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 } ;
454440 self . arena . alloc ( krate)
455441 }
456442
@@ -468,25 +454,57 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
468454 ) -> LocalDefId {
469455 let def_id = self . resolver . local_def_id ( owner) ;
470456
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 ) ;
475460 let current_owner = std:: mem:: replace ( & mut self . current_hir_id_owner , def_id) ;
476461 let current_local_counter =
477462 std:: mem:: replace ( & mut self . item_local_id_counter , hir:: ItemLocalId :: new ( 1 ) ) ;
478463
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+
479469 let item = f ( self ) ;
470+ let info = self . make_owner_info ( item) ;
480471
472+ self . attrs = current_attrs;
473+ self . bodies = current_bodies;
474+ self . local_node_ids = current_node_ids;
481475 self . current_hir_id_owner = current_owner;
482476 self . item_local_id_counter = current_local_counter;
483477
484- let _old = self . owners . insert ( def_id, item ) ;
478+ let _old = self . owners . insert ( def_id, info ) ;
485479 debug_assert ! ( _old. is_none( ) ) ;
486480
487481 def_id
488482 }
489483
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+
490508 /// This method allocates a new `HirId` for the given `NodeId` and stores it in
491509 /// the `LoweringContext`'s `NodeId => HirId` map.
492510 /// Take care not to call this method if the resulting `HirId` is then not
@@ -501,6 +519,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
501519 let owner = self . current_hir_id_owner ;
502520 let local_id = self . item_local_id_counter ;
503521 self . item_local_id_counter . increment_by ( 1 ) ;
522+ self . local_node_ids . push ( ast_node_id) ;
504523 hir:: HirId { owner, local_id }
505524 } )
506525 }
@@ -791,9 +810,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
791810 if attrs. is_empty ( ) {
792811 None
793812 } else {
813+ debug_assert_eq ! ( id. owner, self . current_hir_id_owner) ;
794814 let ret = self . arena . alloc_from_iter ( attrs. iter ( ) . map ( |a| self . lower_attr ( a) ) ) ;
795815 debug_assert ! ( !ret. is_empty( ) ) ;
796- self . attrs . insert ( id, ret) ;
816+ self . attrs . insert ( id. local_id , ret) ;
797817 Some ( ret)
798818 }
799819 }
@@ -819,9 +839,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
819839 }
820840
821841 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 ) {
823845 debug_assert ! ( !a. is_empty( ) ) ;
824- self . attrs . insert ( id, a) ;
846+ self . attrs . insert ( id. local_id , a) ;
825847 }
826848 }
827849
@@ -2066,7 +2088,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
20662088 let hir_id = self . next_id ( ) ;
20672089 if let Some ( a) = attrs {
20682090 debug_assert ! ( !a. is_empty( ) ) ;
2069- self . attrs . insert ( hir_id, a) ;
2091+ self . attrs . insert ( hir_id. local_id , a) ;
20702092 }
20712093 let local = hir:: Local { hir_id, init, pat, source, span : self . lower_span ( span) , ty : None } ;
20722094 self . stmt ( span, hir:: StmtKind :: Local ( self . arena . alloc ( local) ) )
0 commit comments