@@ -44,7 +44,7 @@ use rustc_ast::{self as ast, *};
44
44
use rustc_ast_pretty:: pprust;
45
45
use rustc_data_structures:: captures:: Captures ;
46
46
use rustc_data_structures:: fingerprint:: Fingerprint ;
47
- use rustc_data_structures:: fx:: FxHashSet ;
47
+ use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
48
48
use rustc_data_structures:: sorted_map:: SortedMap ;
49
49
use rustc_data_structures:: stable_hasher:: { HashStable , StableHasher } ;
50
50
use rustc_data_structures:: sync:: Lrc ;
@@ -54,7 +54,7 @@ use rustc_hir::def::{DefKind, Namespace, PartialRes, PerNS, Res};
54
54
use rustc_hir:: def_id:: { DefId , DefPathHash , LocalDefId , CRATE_DEF_ID } ;
55
55
use rustc_hir:: definitions:: { DefKey , DefPathData , Definitions } ;
56
56
use rustc_hir:: intravisit;
57
- use rustc_hir:: { ConstArg , GenericArg , ParamName } ;
57
+ use rustc_hir:: { ConstArg , GenericArg , ItemLocalId , ParamName , TraitCandidate } ;
58
58
use rustc_index:: vec:: { Idx , IndexVec } ;
59
59
use rustc_query_system:: ich:: StableHashingContext ;
60
60
use rustc_session:: lint:: LintBuffer ;
@@ -67,6 +67,7 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol};
67
67
use rustc_span:: { Span , DUMMY_SP } ;
68
68
69
69
use smallvec:: SmallVec ;
70
+ use std:: collections:: hash_map:: Entry ;
70
71
use tracing:: { debug, trace} ;
71
72
72
73
macro_rules! arena_vec {
@@ -154,10 +155,11 @@ struct LoweringContext<'a, 'hir: 'a> {
154
155
155
156
current_hir_id_owner : LocalDefId ,
156
157
item_local_id_counter : hir:: ItemLocalId ,
157
- node_id_to_hir_id : IndexVec < NodeId , Option < hir:: HirId > > ,
158
+ local_id_to_def_id : SortedMap < ItemLocalId , LocalDefId > ,
159
+ trait_map : FxHashMap < ItemLocalId , Box < [ TraitCandidate ] > > ,
158
160
159
161
/// NodeIds that are lowered inside the current HIR owner.
160
- local_node_ids : Vec < NodeId > ,
162
+ node_id_to_local_id : FxHashMap < NodeId , hir :: ItemLocalId > ,
161
163
162
164
allow_try_trait : Option < Lrc < [ Symbol ] > > ,
163
165
allow_gen_future : Option < Lrc < [ Symbol ] > > ,
@@ -368,8 +370,9 @@ pub fn lower_crate<'a, 'hir>(
368
370
anonymous_lifetime_mode : AnonymousLifetimeMode :: PassThrough ,
369
371
current_hir_id_owner : CRATE_DEF_ID ,
370
372
item_local_id_counter : hir:: ItemLocalId :: new ( 0 ) ,
371
- node_id_to_hir_id : IndexVec :: new ( ) ,
372
- local_node_ids : Vec :: new ( ) ,
373
+ node_id_to_local_id : FxHashMap :: default ( ) ,
374
+ local_id_to_def_id : SortedMap :: new ( ) ,
375
+ trait_map : FxHashMap :: default ( ) ,
373
376
generator_kind : None ,
374
377
task_context : None ,
375
378
current_item : None ,
@@ -496,23 +499,26 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
496
499
497
500
let current_attrs = std:: mem:: take ( & mut self . attrs ) ;
498
501
let current_bodies = std:: mem:: take ( & mut self . bodies ) ;
499
- let current_node_ids = std:: mem:: take ( & mut self . local_node_ids ) ;
502
+ let current_node_ids = std:: mem:: take ( & mut self . node_id_to_local_id ) ;
503
+ let current_id_to_def_id = std:: mem:: take ( & mut self . local_id_to_def_id ) ;
504
+ let current_trait_map = std:: mem:: take ( & mut self . trait_map ) ;
500
505
let current_owner = std:: mem:: replace ( & mut self . current_hir_id_owner , def_id) ;
501
506
let current_local_counter =
502
507
std:: mem:: replace ( & mut self . item_local_id_counter , hir:: ItemLocalId :: new ( 1 ) ) ;
503
508
504
509
// Always allocate the first `HirId` for the owner itself.
505
- let _old = self . node_id_to_hir_id . insert ( owner, hir:: HirId :: make_owner ( def_id ) ) ;
510
+ let _old = self . node_id_to_local_id . insert ( owner, hir:: ItemLocalId :: new ( 0 ) ) ;
506
511
debug_assert_eq ! ( _old, None ) ;
507
- self . local_node_ids . push ( owner) ;
508
512
509
513
let item = f ( self ) ;
510
514
debug_assert_eq ! ( def_id, item. def_id( ) ) ;
511
515
let info = self . make_owner_info ( item) ;
512
516
513
517
self . attrs = current_attrs;
514
518
self . bodies = current_bodies;
515
- self . local_node_ids = current_node_ids;
519
+ self . node_id_to_local_id = current_node_ids;
520
+ self . local_id_to_def_id = current_id_to_def_id;
521
+ self . trait_map = current_trait_map;
516
522
self . current_hir_id_owner = current_owner;
517
523
self . item_local_id_counter = current_local_counter;
518
524
@@ -525,34 +531,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
525
531
fn make_owner_info ( & mut self , node : hir:: OwnerNode < ' hir > ) -> hir:: OwnerInfo < ' hir > {
526
532
let attrs = std:: mem:: take ( & mut self . attrs ) ;
527
533
let mut bodies = std:: mem:: take ( & mut self . bodies ) ;
528
- let local_node_ids = std:: mem:: take ( & mut self . local_node_ids ) ;
529
-
530
- let local_id_to_def_id = local_node_ids
531
- . iter ( )
532
- . filter_map ( |& node_id| {
533
- let hir_id = self . node_id_to_hir_id [ node_id] ?;
534
- if hir_id. local_id == hir:: ItemLocalId :: new ( 0 ) {
535
- None
536
- } else {
537
- let def_id = self . resolver . opt_local_def_id ( node_id) ?;
538
- self . owners . ensure_contains_elem ( def_id, || hir:: MaybeOwner :: Phantom ) ;
539
- if let o @ hir:: MaybeOwner :: Phantom = & mut self . owners [ def_id] {
540
- // Do not override a `MaybeOwner::Owner` that may already here.
541
- * o = hir:: MaybeOwner :: NonOwner ( hir_id) ;
542
- }
543
- Some ( ( hir_id. local_id , def_id) )
544
- }
545
- } )
546
- . collect ( ) ;
547
-
548
- let trait_map = local_node_ids
549
- . into_iter ( )
550
- . filter_map ( |node_id| {
551
- let hir_id = self . node_id_to_hir_id [ node_id] ?;
552
- let traits = self . resolver . take_trait_map ( node_id) ?;
553
- Some ( ( hir_id. local_id , traits. into_boxed_slice ( ) ) )
554
- } )
555
- . collect ( ) ;
556
534
557
535
#[ cfg( debug_assertions) ]
558
536
for ( id, attrs) in attrs. iter ( ) {
@@ -572,7 +550,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
572
550
hash_without_bodies,
573
551
nodes,
574
552
bodies,
575
- local_id_to_def_id,
553
+ local_id_to_def_id : std :: mem :: take ( & mut self . local_id_to_def_id ) ,
576
554
} ;
577
555
let attrs = {
578
556
let mut hcx = self . resolver . create_stable_hashing_context ( ) ;
@@ -582,7 +560,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
582
560
hir:: AttributeMap { map : attrs, hash }
583
561
} ;
584
562
585
- hir:: OwnerInfo { nodes, parenting, attrs, trait_map }
563
+ hir:: OwnerInfo { nodes, parenting, attrs, trait_map : std :: mem :: take ( & mut self . trait_map ) }
586
564
}
587
565
588
566
/// Hash the HIR node twice, one deep and one shallow hash. This allows to differentiate
@@ -615,14 +593,36 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
615
593
fn lower_node_id ( & mut self , ast_node_id : NodeId ) -> hir:: HirId {
616
594
assert_ne ! ( ast_node_id, DUMMY_NODE_ID ) ;
617
595
618
- * self . node_id_to_hir_id . get_or_insert_with ( ast_node_id, || {
619
- // Generate a new `HirId`.
620
- let owner = self . current_hir_id_owner ;
621
- let local_id = self . item_local_id_counter ;
622
- self . item_local_id_counter . increment_by ( 1 ) ;
623
- self . local_node_ids . push ( ast_node_id) ;
624
- hir:: HirId { owner, local_id }
625
- } )
596
+ match self . node_id_to_local_id . entry ( ast_node_id) {
597
+ Entry :: Occupied ( o) => {
598
+ hir:: HirId { owner : self . current_hir_id_owner , local_id : * o. get ( ) }
599
+ }
600
+ Entry :: Vacant ( v) => {
601
+ // Generate a new `HirId`.
602
+ let owner = self . current_hir_id_owner ;
603
+ let local_id = self . item_local_id_counter ;
604
+ let hir_id = hir:: HirId { owner, local_id } ;
605
+
606
+ v. insert ( local_id) ;
607
+ self . item_local_id_counter . increment_by ( 1 ) ;
608
+
609
+ assert_ne ! ( local_id, hir:: ItemLocalId :: new( 0 ) ) ;
610
+ if let Some ( def_id) = self . resolver . opt_local_def_id ( ast_node_id) {
611
+ self . owners . ensure_contains_elem ( def_id, || hir:: MaybeOwner :: Phantom ) ;
612
+ if let o @ hir:: MaybeOwner :: Phantom = & mut self . owners [ def_id] {
613
+ // Do not override a `MaybeOwner::Owner` that may already here.
614
+ * o = hir:: MaybeOwner :: NonOwner ( hir_id) ;
615
+ }
616
+ self . local_id_to_def_id . insert ( local_id, def_id) ;
617
+ }
618
+
619
+ if let Some ( traits) = self . resolver . take_trait_map ( ast_node_id) {
620
+ self . trait_map . insert ( hir_id. local_id , traits. into_boxed_slice ( ) ) ;
621
+ }
622
+
623
+ hir_id
624
+ }
625
+ }
626
626
}
627
627
628
628
fn next_id ( & mut self ) -> hir:: HirId {
@@ -631,11 +631,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
631
631
}
632
632
633
633
fn lower_res ( & mut self , res : Res < NodeId > ) -> Res {
634
- res. map_id ( |id| {
635
- self . node_id_to_hir_id . get ( id) . copied ( ) . flatten ( ) . unwrap_or_else ( || {
636
- panic ! ( "expected `NodeId` to be lowered already for res {:#?}" , res) ;
637
- } )
638
- } )
634
+ let res: Result < Res , ( ) > = res. apply_id ( |id| {
635
+ let owner = self . current_hir_id_owner ;
636
+ let local_id = self . node_id_to_local_id . get ( & id) . copied ( ) . ok_or ( ( ) ) ?;
637
+ Ok ( hir:: HirId { owner, local_id } )
638
+ } ) ;
639
+ // We may fail to find a HirId when the Res points to a Local from an enclosing HIR owner.
640
+ // This can happen when trying to lower the return type `x` in erroneous code like
641
+ // async fn foo(x: u8) -> x {}
642
+ // In that case, `x` is lowered as a function parameter, and the return type is lowered as
643
+ // an opaque type as a synthetized HIR owner.
644
+ res. unwrap_or ( Res :: Err )
639
645
}
640
646
641
647
fn expect_full_res ( & mut self , id : NodeId ) -> Res < NodeId > {
@@ -1476,14 +1482,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1476
1482
let lifetime_defs =
1477
1483
lctx. arena . alloc_from_iter ( collected_lifetimes. iter ( ) . map ( |& ( name, span) | {
1478
1484
let def_node_id = lctx. resolver . next_node_id ( ) ;
1479
- let hir_id = lctx. lower_node_id ( def_node_id) ;
1480
1485
lctx. resolver . create_def (
1481
1486
opaque_ty_def_id,
1482
1487
def_node_id,
1483
1488
DefPathData :: LifetimeNs ( name. ident ( ) . name ) ,
1484
1489
ExpnId :: root ( ) ,
1485
1490
span. with_parent ( None ) ,
1486
1491
) ;
1492
+ let hir_id = lctx. lower_node_id ( def_node_id) ;
1487
1493
1488
1494
let ( name, kind) = match name {
1489
1495
hir:: LifetimeName :: Underscore => (
0 commit comments