7
7
8
8
use RibKind :: * ;
9
9
10
- use crate :: { path_names_to_string, BindingError , CrateLint , LexicalScopeBinding } ;
10
+ use crate :: { path_names_to_string, BindingError , CrateLint , NameBinding , ToNameBinding } ;
11
11
use crate :: { Module , ModuleOrUniformRoot , ParentScope , PathResult } ;
12
12
use crate :: { ResolutionError , Resolver , Segment , UseError } ;
13
13
@@ -21,27 +21,22 @@ use rustc_hir::def::Namespace::{self, *};
21
21
use rustc_hir:: def:: { self , CtorKind , DefKind , PartialRes , PerNS } ;
22
22
use rustc_hir:: def_id:: { DefId , CRATE_DEF_INDEX } ;
23
23
use rustc_hir:: { PrimTy , TraitCandidate } ;
24
- use rustc_middle:: { bug, span_bug} ;
24
+ use rustc_middle:: { bug, span_bug, ty } ;
25
25
use rustc_session:: lint;
26
+ use rustc_span:: source_map:: { respan, Spanned } ;
26
27
use rustc_span:: symbol:: { kw, sym, Ident , Symbol } ;
27
- use rustc_span:: Span ;
28
+ use rustc_span:: { Span , DUMMY_SP } ;
28
29
use smallvec:: { smallvec, SmallVec } ;
30
+ use tracing:: debug;
29
31
30
- use rustc_span:: source_map:: { respan, Spanned } ;
31
32
use std:: collections:: { hash_map:: Entry , BTreeSet } ;
32
33
use std:: mem:: { replace, take} ;
33
- use tracing:: debug;
34
34
35
35
mod diagnostics;
36
36
crate mod lifetimes;
37
37
38
38
type Res = def:: Res < NodeId > ;
39
39
40
- type IdentMap < T > = FxHashMap < Ident , T > ;
41
-
42
- /// Map from the name in a pattern to its binding mode.
43
- type BindingMap = IdentMap < BindingInfo > ;
44
-
45
40
#[ derive( Copy , Clone , Debug ) ]
46
41
struct BindingInfo {
47
42
span : Span ,
@@ -172,8 +167,8 @@ impl RibKind<'_> {
172
167
/// The resolution keeps a separate stack of ribs as it traverses the AST for each namespace. When
173
168
/// resolving, the name is looked up from inside out.
174
169
#[ derive( Debug ) ]
175
- crate struct Rib < ' a , R = Res > {
176
- pub bindings : IdentMap < R > ,
170
+ crate struct Rib < ' a , R = & ' a NameBinding < ' a > > {
171
+ pub bindings : FxHashMap < Ident , R > ,
177
172
pub kind : RibKind < ' a > ,
178
173
}
179
174
@@ -567,12 +562,12 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
567
562
GenericParamKind :: Type { .. } => {
568
563
forward_ty_ban_rib
569
564
. bindings
570
- . insert ( Ident :: with_dummy_span ( param. ident . name ) , Res :: Err ) ;
565
+ . insert ( Ident :: with_dummy_span ( param. ident . name ) , self . r . dummy_binding ) ;
571
566
}
572
567
GenericParamKind :: Const { .. } => {
573
568
forward_const_ban_rib
574
569
. bindings
575
- . insert ( Ident :: with_dummy_span ( param. ident . name ) , Res :: Err ) ;
570
+ . insert ( Ident :: with_dummy_span ( param. ident . name ) , self . r . dummy_binding ) ;
576
571
}
577
572
GenericParamKind :: Lifetime => { }
578
573
}
@@ -589,7 +584,9 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
589
584
// such as in the case of `trait Add<Rhs = Self>`.)
590
585
if self . diagnostic_metadata . current_self_item . is_some ( ) {
591
586
// (`Some` if + only if we are in ADT's generics.)
592
- forward_ty_ban_rib. bindings . insert ( Ident :: with_dummy_span ( kw:: SelfUpper ) , Res :: Err ) ;
587
+ forward_ty_ban_rib
588
+ . bindings
589
+ . insert ( Ident :: with_dummy_span ( kw:: SelfUpper ) , self . r . dummy_binding ) ;
593
590
}
594
591
595
592
for param in & generics. params {
@@ -737,15 +734,17 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
737
734
ns : Namespace ,
738
735
record_used_id : Option < NodeId > ,
739
736
path_span : Span ,
740
- ) -> Option < LexicalScopeBinding < ' a > > {
741
- self . r . resolve_ident_in_lexical_scope (
742
- ident,
743
- ns,
744
- & self . parent_scope ,
745
- record_used_id,
746
- path_span,
747
- & self . ribs [ ns] ,
748
- )
737
+ ) -> Option < & ' a NameBinding < ' a > > {
738
+ self . r
739
+ . resolve_ident_in_lexical_scope (
740
+ ident,
741
+ ns,
742
+ & self . parent_scope ,
743
+ record_used_id,
744
+ path_span,
745
+ & self . ribs [ ns] ,
746
+ )
747
+ . ok ( )
749
748
}
750
749
751
750
fn resolve_path (
@@ -905,6 +904,10 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
905
904
}
906
905
907
906
fn future_proof_import ( & mut self , use_tree : & UseTree ) {
907
+ if !self . should_report_errs ( ) {
908
+ return ;
909
+ }
910
+
908
911
let segments = & use_tree. prefix . segments ;
909
912
if !segments. is_empty ( ) {
910
913
let ident = segments[ 0 ] . ident ;
@@ -916,31 +919,42 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
916
919
UseTreeKind :: Simple ( ..) if segments. len ( ) == 1 => & [ TypeNS , ValueNS ] [ ..] ,
917
920
_ => & [ TypeNS ] ,
918
921
} ;
922
+
923
+ let from_ribs = |binding : & NameBinding < ' _ > | {
924
+ matches ! (
925
+ binding. res( ) ,
926
+ Res :: Local ( ..)
927
+ | Res :: SelfTy ( ..)
928
+ | Res :: Def ( DefKind :: TyParam | DefKind :: ConstParam , ..)
929
+ )
930
+ } ;
919
931
let report_error = |this : & Self , ns| {
920
932
let what = if ns == TypeNS { "type parameters" } else { "local variables" } ;
921
- if this. should_report_errs ( ) {
922
- this. r
923
- . session
924
- . span_err ( ident. span , & format ! ( "imports cannot refer to {}" , what) ) ;
925
- }
933
+ let msg = format ! ( "imports cannot refer to {what}" ) ;
934
+ this. r . session . span_err ( ident. span , & msg) ;
926
935
} ;
927
936
928
937
for & ns in nss {
929
- match self . resolve_ident_in_lexical_scope ( ident, ns, None , use_tree. prefix . span ) {
930
- Some ( LexicalScopeBinding :: Res ( ..) ) => {
938
+ if let Some ( binding) =
939
+ self . resolve_ident_in_lexical_scope ( ident, ns, None , use_tree. prefix . span )
940
+ {
941
+ if from_ribs ( binding) {
931
942
report_error ( self , ns) ;
932
- }
933
- Some ( LexicalScopeBinding :: Item ( binding) ) => {
943
+ } else {
934
944
let orig_unusable_binding =
935
945
replace ( & mut self . r . unusable_binding , Some ( binding) ) ;
936
- if let Some ( LexicalScopeBinding :: Res ( ..) ) = self
937
- . resolve_ident_in_lexical_scope ( ident, ns, None , use_tree. prefix . span )
938
- {
939
- report_error ( self , ns) ;
946
+ if let Some ( binding) = self . resolve_ident_in_lexical_scope (
947
+ ident,
948
+ ns,
949
+ None ,
950
+ use_tree. prefix . span ,
951
+ ) {
952
+ if from_ribs ( binding) {
953
+ report_error ( self , ns) ;
954
+ }
940
955
}
941
956
self . r . unusable_binding = orig_unusable_binding;
942
957
}
943
- None => { }
944
958
}
945
959
}
946
960
} else if let UseTreeKind :: Nested ( use_trees) = & use_tree. kind {
@@ -1137,8 +1151,12 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
1137
1151
_ => unreachable ! ( ) ,
1138
1152
} ;
1139
1153
let res = Res :: Def ( def_kind, self . r . local_def_id ( param. id ) . to_def_id ( ) ) ;
1154
+ let binding =
1155
+ ( res, ty:: Visibility :: Invisible , param. ident . span , self . parent_scope . expansion )
1156
+ . to_name_binding ( self . r . arenas ) ;
1157
+
1140
1158
self . r . record_partial_res ( param. id , PartialRes :: new ( res) ) ;
1141
- rib. bindings . insert ( ident, res ) ;
1159
+ rib. bindings . insert ( ident, binding ) ;
1142
1160
}
1143
1161
1144
1162
self . ribs [ ValueNS ] . push ( function_value_rib) ;
@@ -1258,10 +1276,12 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
1258
1276
}
1259
1277
1260
1278
fn with_self_rib_ns ( & mut self , ns : Namespace , self_res : Res , f : impl FnOnce ( & mut Self ) ) {
1279
+ let binding = ( self_res, ty:: Visibility :: Invisible , DUMMY_SP , self . parent_scope . expansion )
1280
+ . to_name_binding ( self . r . arenas ) ;
1261
1281
let mut self_type_rib = Rib :: new ( NormalRibKind ) ;
1262
1282
1263
1283
// Plain insert (no renaming, since types are not currently hygienic)
1264
- self_type_rib. bindings . insert ( Ident :: with_dummy_span ( kw:: SelfUpper ) , self_res ) ;
1284
+ self_type_rib. bindings . insert ( Ident :: with_dummy_span ( kw:: SelfUpper ) , binding ) ;
1265
1285
self . ribs [ ns] . push ( self_type_rib) ;
1266
1286
f ( self ) ;
1267
1287
self . ribs [ ns] . pop ( ) ;
@@ -1460,7 +1480,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
1460
1480
/// this is done hygienically. This could arise for a macro
1461
1481
/// that expands into an or-pattern where one 'x' was from the
1462
1482
/// user and one 'x' came from the macro.
1463
- fn binding_mode_map ( & mut self , pat : & Pat ) -> BindingMap {
1483
+ fn binding_mode_map ( & mut self , pat : & Pat ) -> FxHashMap < Ident , BindingInfo > {
1464
1484
let mut binding_map = FxHashMap :: default ( ) ;
1465
1485
1466
1486
pat. walk ( & mut |pat| {
@@ -1493,7 +1513,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
1493
1513
1494
1514
/// Checks that all of the arms in an or-pattern have exactly the
1495
1515
/// same set of bindings, with the same binding modes for each.
1496
- fn check_consistent_bindings ( & mut self , pats : & [ P < Pat > ] ) -> Vec < BindingMap > {
1516
+ fn check_consistent_bindings ( & mut self , pats : & [ P < Pat > ] ) -> Vec < FxHashMap < Ident , BindingInfo > > {
1497
1517
let mut missing_vars = FxHashMap :: default ( ) ;
1498
1518
let mut inconsistent_vars = FxHashMap :: default ( ) ;
1499
1519
@@ -1635,7 +1655,6 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
1635
1655
. try_resolve_as_non_binding ( pat_src, pat, bmode, ident, has_sub)
1636
1656
. unwrap_or_else ( || self . fresh_binding ( ident, pat. id , pat_src, bindings) ) ;
1637
1657
self . r . record_partial_res ( pat. id , PartialRes :: new ( res) ) ;
1638
- self . r . record_pat_span ( pat. id , pat. span ) ;
1639
1658
}
1640
1659
PatKind :: TupleStruct ( ref qself, ref path, ref sub_patterns) => {
1641
1660
self . smart_resolve_path (
@@ -1725,18 +1744,24 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
1725
1744
if already_bound_or {
1726
1745
// `Variant1(a) | Variant2(a)`, ok
1727
1746
// Reuse definition from the first `a`.
1728
- self . innermost_rib_bindings ( ValueNS ) [ & ident]
1747
+ self . innermost_rib_bindings ( ValueNS ) [ & ident] . res ( )
1729
1748
} else {
1730
1749
let res = Res :: Local ( pat_id) ;
1731
1750
if ident_valid {
1732
1751
// A completely fresh binding add to the set if it's valid.
1733
- self . innermost_rib_bindings ( ValueNS ) . insert ( ident, res) ;
1752
+ let binding =
1753
+ ( res, ty:: Visibility :: Invisible , ident. span , self . parent_scope . expansion )
1754
+ . to_name_binding ( self . r . arenas ) ;
1755
+ self . innermost_rib_bindings ( ValueNS ) . insert ( ident, binding) ;
1734
1756
}
1735
1757
res
1736
1758
}
1737
1759
}
1738
1760
1739
- fn innermost_rib_bindings ( & mut self , ns : Namespace ) -> & mut IdentMap < Res > {
1761
+ fn innermost_rib_bindings (
1762
+ & mut self ,
1763
+ ns : Namespace ,
1764
+ ) -> & mut FxHashMap < Ident , & ' a NameBinding < ' a > > {
1740
1765
& mut self . ribs [ ns] . last_mut ( ) . unwrap ( ) . bindings
1741
1766
}
1742
1767
@@ -1753,32 +1778,25 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
1753
1778
// also be interpreted as a path to e.g. a constant, variant, etc.
1754
1779
let is_syntactic_ambiguity = !has_sub && bm == BindingMode :: ByValue ( Mutability :: Not ) ;
1755
1780
1756
- let ls_binding = self . resolve_ident_in_lexical_scope ( ident, ValueNS , None , pat. span ) ?;
1757
- let ( res, binding) = match ls_binding {
1758
- LexicalScopeBinding :: Item ( binding)
1759
- if is_syntactic_ambiguity && binding. is_ambiguity ( ) =>
1760
- {
1761
- // For ambiguous bindings we don't know all their definitions and cannot check
1762
- // whether they can be shadowed by fresh bindings or not, so force an error.
1763
- // issues/33118#issuecomment-233962221 (see below) still applies here,
1764
- // but we have to ignore it for backward compatibility.
1765
- self . r . record_use ( ident, binding, false ) ;
1766
- return None ;
1767
- }
1768
- LexicalScopeBinding :: Item ( binding) => ( binding. res ( ) , Some ( binding) ) ,
1769
- LexicalScopeBinding :: Res ( res) => ( res, None ) ,
1770
- } ;
1781
+ let binding = self . resolve_ident_in_lexical_scope ( ident, ValueNS , None , pat. span ) ?;
1782
+ if is_syntactic_ambiguity && binding. is_ambiguity ( ) {
1783
+ // For ambiguous bindings we don't know all their definitions and cannot check
1784
+ // whether they can be shadowed by fresh bindings or not, so force an error.
1785
+ // issues/33118#issuecomment-233962221 (see below) still applies here,
1786
+ // but we have to ignore it for backward compatibility.
1787
+ self . r . record_use ( ident, binding, false ) ;
1788
+ return None ;
1789
+ }
1771
1790
1791
+ let res = binding. res ( ) ;
1772
1792
match res {
1773
1793
Res :: SelfCtor ( _) // See #70549.
1774
1794
| Res :: Def (
1775
1795
DefKind :: Ctor ( _, CtorKind :: Const ) | DefKind :: Const | DefKind :: ConstParam ,
1776
1796
_,
1777
1797
) if is_syntactic_ambiguity => {
1778
1798
// Disambiguate in favor of a unit struct/variant or constant pattern.
1779
- if let Some ( binding) = binding {
1780
- self . r . record_use ( ident, binding, false ) ;
1781
- }
1799
+ self . r . record_use ( ident, binding, false ) ;
1782
1800
Some ( res)
1783
1801
}
1784
1802
Res :: Def ( DefKind :: Ctor ( ..) | DefKind :: Const | DefKind :: Static , _) => {
@@ -1787,7 +1805,6 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
1787
1805
// to something unusable as a pattern (e.g., constructor function),
1788
1806
// but we still conservatively report an error, see
1789
1807
// issues/33118#issuecomment-233962221 for one reason why.
1790
- let binding = binding. expect ( "no binding for a ctor or static" ) ;
1791
1808
self . report_error (
1792
1809
ident. span ,
1793
1810
ResolutionError :: BindingShadowsSomethingUnacceptable {
@@ -2027,19 +2044,15 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
2027
2044
}
2028
2045
2029
2046
fn self_type_is_available ( & mut self , span : Span ) -> bool {
2030
- let binding = self . resolve_ident_in_lexical_scope (
2031
- Ident :: with_dummy_span ( kw:: SelfUpper ) ,
2032
- TypeNS ,
2033
- None ,
2034
- span,
2035
- ) ;
2036
- if let Some ( LexicalScopeBinding :: Res ( res) ) = binding { res != Res :: Err } else { false }
2047
+ let ident = Ident :: with_dummy_span ( kw:: SelfUpper ) ;
2048
+ self . resolve_ident_in_lexical_scope ( ident, TypeNS , None , span)
2049
+ . map_or ( false , |binding| binding. res ( ) != Res :: Err )
2037
2050
}
2038
2051
2039
2052
fn self_value_is_available ( & mut self , self_span : Span , path_span : Span ) -> bool {
2040
2053
let ident = Ident :: new ( kw:: SelfLower , self_span) ;
2041
- let binding = self . resolve_ident_in_lexical_scope ( ident, ValueNS , None , path_span) ;
2042
- if let Some ( LexicalScopeBinding :: Res ( res ) ) = binding { res != Res :: Err } else { false }
2054
+ self . resolve_ident_in_lexical_scope ( ident, ValueNS , None , path_span)
2055
+ . map_or ( false , | binding| binding . res ( ) != Res :: Err )
2043
2056
}
2044
2057
2045
2058
/// A wrapper around [`Resolver::report_error`].
0 commit comments