15
15
#![ feature( crate_visibility_modifier) ]
16
16
#![ feature( rustc_diagnostic_macros) ]
17
17
#![ feature( slice_sort_by_cached_key) ]
18
+ #![ feature( entry_or_default) ]
18
19
19
20
#[ macro_use]
20
21
extern crate log;
@@ -27,7 +28,8 @@ extern crate arena;
27
28
extern crate rustc;
28
29
extern crate rustc_data_structures;
29
30
30
- use self :: Namespace :: * ;
31
+ pub use rustc:: hir:: def:: { Namespace , PerNS } ;
32
+
31
33
use self :: TypeParameters :: * ;
32
34
use self :: RibKind :: * ;
33
35
@@ -37,7 +39,9 @@ use rustc::middle::cstore::{CrateStore, CrateLoader};
37
39
use rustc:: session:: Session ;
38
40
use rustc:: lint;
39
41
use rustc:: hir:: def:: * ;
42
+ use rustc:: hir:: def:: Namespace :: * ;
40
43
use rustc:: hir:: def_id:: { CRATE_DEF_INDEX , LOCAL_CRATE , DefId } ;
44
+ use rustc:: hir:: lowering:: Resolver as ResolverTrait ;
41
45
use rustc:: ty;
42
46
use rustc:: hir:: { Freevar , FreevarMap , TraitCandidate , TraitMap , GlobMap } ;
43
47
use rustc:: util:: nodemap:: { NodeMap , NodeSet , FxHashMap , FxHashSet , DefIdMap } ;
@@ -614,45 +618,6 @@ impl<'a> PathSource<'a> {
614
618
}
615
619
}
616
620
617
- /// Different kinds of symbols don't influence each other.
618
- ///
619
- /// Therefore, they have a separate universe (namespace).
620
- #[ derive( Copy , Clone , PartialEq , Eq , PartialOrd , Ord , Hash , Debug ) ]
621
- pub enum Namespace {
622
- TypeNS ,
623
- ValueNS ,
624
- MacroNS ,
625
- }
626
-
627
- /// Just a helper ‒ separate structure for each namespace.
628
- #[ derive( Clone , Default , Debug ) ]
629
- pub struct PerNS < T > {
630
- value_ns : T ,
631
- type_ns : T ,
632
- macro_ns : T ,
633
- }
634
-
635
- impl < T > :: std:: ops:: Index < Namespace > for PerNS < T > {
636
- type Output = T ;
637
- fn index ( & self , ns : Namespace ) -> & T {
638
- match ns {
639
- ValueNS => & self . value_ns ,
640
- TypeNS => & self . type_ns ,
641
- MacroNS => & self . macro_ns ,
642
- }
643
- }
644
- }
645
-
646
- impl < T > :: std:: ops:: IndexMut < Namespace > for PerNS < T > {
647
- fn index_mut ( & mut self , ns : Namespace ) -> & mut T {
648
- match ns {
649
- ValueNS => & mut self . value_ns ,
650
- TypeNS => & mut self . type_ns ,
651
- MacroNS => & mut self . macro_ns ,
652
- }
653
- }
654
- }
655
-
656
621
struct UsePlacementFinder {
657
622
target_module : NodeId ,
658
623
span : Option < Span > ,
@@ -752,7 +717,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
752
717
let self_ty = keywords:: SelfType . ident ( ) ;
753
718
let def = self . resolve_ident_in_lexical_scope ( self_ty, TypeNS , true , ty. span )
754
719
. map_or ( Def :: Err , |d| d. def ( ) ) ;
755
- self . record_def ( ty. id , PathResolution :: new ( def) ) ;
720
+ self . record_def ( ty. id , TypeNS , PathResolution :: new ( def) ) ;
756
721
}
757
722
_ => ( ) ,
758
723
}
@@ -1512,7 +1477,17 @@ impl<'a> hir::lowering::Resolver for Resolver<'a> {
1512
1477
}
1513
1478
1514
1479
fn get_resolution ( & mut self , id : NodeId ) -> Option < PathResolution > {
1515
- self . def_map . get ( & id) . cloned ( )
1480
+ //for people calling this one, they don't necessarily care which namespace it's in, so just
1481
+ //have a preference but check all of them
1482
+ if let Some ( def) = self . def_map . get ( & id) {
1483
+ for ns in [ TypeNS , ValueNS , MacroNS ] . iter ( ) . cloned ( ) {
1484
+ if let Some ( res) = def[ ns] {
1485
+ return Some ( res) ;
1486
+ }
1487
+ }
1488
+ }
1489
+
1490
+ None
1516
1491
}
1517
1492
1518
1493
fn definitions ( & mut self ) -> & mut Definitions {
@@ -2241,7 +2216,7 @@ impl<'a> Resolver<'a> {
2241
2216
let def_id = self . definitions . local_def_id ( type_parameter. id ) ;
2242
2217
let def = Def :: TyParam ( def_id) ;
2243
2218
function_type_rib. bindings . insert ( ident, def) ;
2244
- self . record_def ( type_parameter. id , PathResolution :: new ( def) ) ;
2219
+ self . record_def ( type_parameter. id , TypeNS , PathResolution :: new ( def) ) ;
2245
2220
}
2246
2221
}
2247
2222
self . ribs [ TypeNS ] . push ( function_type_rib) ;
@@ -2454,7 +2429,9 @@ impl<'a> Resolver<'a> {
2454
2429
2455
2430
pat. walk ( & mut |pat| {
2456
2431
if let PatKind :: Ident ( binding_mode, ident, ref sub_pat) = pat. node {
2457
- if sub_pat. is_some ( ) || match self . def_map . get ( & pat. id ) . map ( |res| res. base_def ( ) ) {
2432
+ //FIXME(misdreavus): `get_resolution` is the "i don't care what namespace" version,
2433
+ //is that valid?
2434
+ if sub_pat. is_some ( ) || match self . get_resolution ( pat. id ) . map ( |res| res. base_def ( ) ) {
2458
2435
Some ( Def :: Local ( ..) ) => true ,
2459
2436
_ => false ,
2460
2437
} {
@@ -2710,7 +2687,7 @@ impl<'a> Resolver<'a> {
2710
2687
self . fresh_binding ( ident, pat. id , outer_pat_id, pat_src, bindings)
2711
2688
} ) ;
2712
2689
2713
- self . record_def ( pat. id , resolution) ;
2690
+ self . record_def ( pat. id , ValueNS , resolution) ;
2714
2691
}
2715
2692
2716
2693
PatKind :: TupleStruct ( ref path, ..) => {
@@ -3026,7 +3003,7 @@ impl<'a> Resolver<'a> {
3026
3003
3027
3004
if let PathSource :: TraitItem ( ..) = source { } else {
3028
3005
// Avoid recording definition of `A::B` in `<T as A>::B::C`.
3029
- self . record_def ( id, resolution) ;
3006
+ self . record_def ( id, ns , resolution) ;
3030
3007
}
3031
3008
resolution
3032
3009
}
@@ -3624,7 +3601,7 @@ impl<'a> Resolver<'a> {
3624
3601
if filter_fn ( Def :: Local ( ast:: DUMMY_NODE_ID ) ) {
3625
3602
if let Some ( node_id) = self . current_self_type . as_ref ( ) . and_then ( extract_node_id) {
3626
3603
// Look for a field with the same name in the current self_type.
3627
- if let Some ( resolution) = self . def_map . get ( & node_id) {
3604
+ if let Some ( resolution) = self . get_resolution ( node_id) {
3628
3605
match resolution. base_def ( ) {
3629
3606
Def :: Struct ( did) | Def :: Union ( did)
3630
3607
if resolution. unresolved_segments ( ) == 0 => {
@@ -3777,15 +3754,15 @@ impl<'a> Resolver<'a> {
3777
3754
let names = rib. bindings . iter ( ) . map ( |( id, _) | & id. name ) ;
3778
3755
find_best_match_for_name ( names, & * ident. as_str ( ) , None )
3779
3756
} ) ;
3780
- self . record_def ( expr. id , err_path_resolution ( ) ) ;
3757
+ self . record_def ( expr. id , ValueNS , err_path_resolution ( ) ) ;
3781
3758
resolve_error ( self ,
3782
3759
label. ident . span ,
3783
3760
ResolutionError :: UndeclaredLabel ( & label. ident . as_str ( ) ,
3784
3761
close_match) ) ;
3785
3762
}
3786
3763
Some ( Def :: Label ( id) ) => {
3787
3764
// Since this def is a label, it is never read.
3788
- self . record_def ( expr. id , PathResolution :: new ( Def :: Label ( id) ) ) ;
3765
+ self . record_def ( expr. id , ValueNS , PathResolution :: new ( Def :: Label ( id) ) ) ;
3789
3766
self . unused_labels . remove ( & id) ;
3790
3767
}
3791
3768
Some ( _) => {
@@ -4111,9 +4088,10 @@ impl<'a> Resolver<'a> {
4111
4088
} )
4112
4089
}
4113
4090
4114
- fn record_def ( & mut self , node_id : NodeId , resolution : PathResolution ) {
4091
+ fn record_def ( & mut self , node_id : NodeId , ns : Namespace , resolution : PathResolution ) {
4115
4092
debug ! ( "(recording def) recording {:?} for {}" , resolution, node_id) ;
4116
- if let Some ( prev_res) = self . def_map . insert ( node_id, resolution) {
4093
+ let record = self . def_map . entry ( node_id) . or_default ( ) ;
4094
+ if let Some ( prev_res) = replace ( & mut record[ ns] , Some ( resolution) ) {
4117
4095
panic ! ( "path resolved multiple times ({:?} before, {:?} now)" , prev_res, resolution) ;
4118
4096
}
4119
4097
}
0 commit comments