7
7
8
8
use RibKind :: * ;
9
9
10
- use crate :: { path_names_to_string, BindingError , CrateLint , NameBinding , ToNameBinding } ;
10
+ use crate :: { path_names_to_string, BindingError , CrateLint , LexicalScopeBinding } ;
11
11
use crate :: { Module , ModuleOrUniformRoot , ParentScope , PathResult } ;
12
12
use crate :: { ResolutionError , Resolver , Segment , UseError } ;
13
13
@@ -21,22 +21,27 @@ 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, ty } ;
24
+ use rustc_middle:: { bug, span_bug} ;
25
25
use rustc_session:: lint;
26
- use rustc_span:: source_map:: { respan, Spanned } ;
27
26
use rustc_span:: symbol:: { kw, sym, Ident , Symbol } ;
28
- use rustc_span:: { Span , DUMMY_SP } ;
27
+ use rustc_span:: Span ;
29
28
use smallvec:: { smallvec, SmallVec } ;
30
- use tracing:: debug;
31
29
30
+ use rustc_span:: source_map:: { respan, Spanned } ;
32
31
use std:: collections:: { hash_map:: Entry , BTreeSet } ;
33
32
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
+
40
45
#[ derive( Copy , Clone , Debug ) ]
41
46
struct BindingInfo {
42
47
span : Span ,
@@ -167,8 +172,8 @@ impl RibKind<'_> {
167
172
/// The resolution keeps a separate stack of ribs as it traverses the AST for each namespace. When
168
173
/// resolving, the name is looked up from inside out.
169
174
#[ derive( Debug ) ]
170
- crate struct Rib < ' a , R = & ' a NameBinding < ' a > > {
171
- pub bindings : FxHashMap < Ident , R > ,
175
+ crate struct Rib < ' a , R = Res > {
176
+ pub bindings : IdentMap < R > ,
172
177
pub kind : RibKind < ' a > ,
173
178
}
174
179
@@ -562,12 +567,12 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
562
567
GenericParamKind :: Type { .. } => {
563
568
forward_ty_ban_rib
564
569
. bindings
565
- . insert ( Ident :: with_dummy_span ( param. ident . name ) , self . r . dummy_binding ) ;
570
+ . insert ( Ident :: with_dummy_span ( param. ident . name ) , Res :: Err ) ;
566
571
}
567
572
GenericParamKind :: Const { .. } => {
568
573
forward_const_ban_rib
569
574
. bindings
570
- . insert ( Ident :: with_dummy_span ( param. ident . name ) , self . r . dummy_binding ) ;
575
+ . insert ( Ident :: with_dummy_span ( param. ident . name ) , Res :: Err ) ;
571
576
}
572
577
GenericParamKind :: Lifetime => { }
573
578
}
@@ -584,9 +589,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
584
589
// such as in the case of `trait Add<Rhs = Self>`.)
585
590
if self . diagnostic_metadata . current_self_item . is_some ( ) {
586
591
// (`Some` if + only if we are in ADT's generics.)
587
- forward_ty_ban_rib
588
- . bindings
589
- . insert ( Ident :: with_dummy_span ( kw:: SelfUpper ) , self . r . dummy_binding ) ;
592
+ forward_ty_ban_rib. bindings . insert ( Ident :: with_dummy_span ( kw:: SelfUpper ) , Res :: Err ) ;
590
593
}
591
594
592
595
for param in & generics. params {
@@ -734,17 +737,15 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
734
737
ns : Namespace ,
735
738
record_used_id : Option < NodeId > ,
736
739
path_span : Span ,
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 ( )
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
+ )
748
749
}
749
750
750
751
fn resolve_path (
@@ -902,10 +903,6 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
902
903
}
903
904
904
905
fn future_proof_import ( & mut self , use_tree : & UseTree ) {
905
- if !self . should_report_errs ( ) {
906
- return ;
907
- }
908
-
909
906
let segments = & use_tree. prefix . segments ;
910
907
if !segments. is_empty ( ) {
911
908
let ident = segments[ 0 ] . ident ;
@@ -917,42 +914,31 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
917
914
UseTreeKind :: Simple ( ..) if segments. len ( ) == 1 => & [ TypeNS , ValueNS ] [ ..] ,
918
915
_ => & [ TypeNS ] ,
919
916
} ;
920
-
921
- let from_ribs = |binding : & NameBinding < ' _ > | {
922
- matches ! (
923
- binding. res( ) ,
924
- Res :: Local ( ..)
925
- | Res :: SelfTy ( ..)
926
- | Res :: Def ( DefKind :: TyParam | DefKind :: ConstParam , ..)
927
- )
928
- } ;
929
917
let report_error = |this : & Self , ns| {
930
918
let what = if ns == TypeNS { "type parameters" } else { "local variables" } ;
931
- let msg = format ! ( "imports cannot refer to {what}" ) ;
932
- this. r . session . span_err ( ident. span , & msg) ;
919
+ if this. should_report_errs ( ) {
920
+ this. r
921
+ . session
922
+ . span_err ( ident. span , & format ! ( "imports cannot refer to {}" , what) ) ;
923
+ }
933
924
} ;
934
925
935
926
for & ns in nss {
936
- if let Some ( binding) =
937
- self . resolve_ident_in_lexical_scope ( ident, ns, None , use_tree. prefix . span )
938
- {
939
- if from_ribs ( binding) {
927
+ match self . resolve_ident_in_lexical_scope ( ident, ns, None , use_tree. prefix . span ) {
928
+ Some ( LexicalScopeBinding :: Res ( ..) ) => {
940
929
report_error ( self , ns) ;
941
- } else {
930
+ }
931
+ Some ( LexicalScopeBinding :: Item ( binding) ) => {
942
932
let orig_unusable_binding =
943
933
replace ( & mut self . r . unusable_binding , Some ( binding) ) ;
944
- if let Some ( binding) = self . resolve_ident_in_lexical_scope (
945
- ident,
946
- ns,
947
- None ,
948
- use_tree. prefix . span ,
949
- ) {
950
- if from_ribs ( binding) {
951
- report_error ( self , ns) ;
952
- }
934
+ if let Some ( LexicalScopeBinding :: Res ( ..) ) = self
935
+ . resolve_ident_in_lexical_scope ( ident, ns, None , use_tree. prefix . span )
936
+ {
937
+ report_error ( self , ns) ;
953
938
}
954
939
self . r . unusable_binding = orig_unusable_binding;
955
940
}
941
+ None => { }
956
942
}
957
943
}
958
944
} else if let UseTreeKind :: Nested ( use_trees) = & use_tree. kind {
@@ -1149,12 +1135,8 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
1149
1135
_ => unreachable ! ( ) ,
1150
1136
} ;
1151
1137
let res = Res :: Def ( def_kind, self . r . local_def_id ( param. id ) . to_def_id ( ) ) ;
1152
- let binding =
1153
- ( res, ty:: Visibility :: Invisible , param. ident . span , self . parent_scope . expansion )
1154
- . to_name_binding ( self . r . arenas ) ;
1155
-
1156
1138
self . r . record_partial_res ( param. id , PartialRes :: new ( res) ) ;
1157
- rib. bindings . insert ( ident, binding ) ;
1139
+ rib. bindings . insert ( ident, res ) ;
1158
1140
}
1159
1141
1160
1142
self . ribs [ ValueNS ] . push ( function_value_rib) ;
@@ -1274,12 +1256,10 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
1274
1256
}
1275
1257
1276
1258
fn with_self_rib_ns ( & mut self , ns : Namespace , self_res : Res , f : impl FnOnce ( & mut Self ) ) {
1277
- let binding = ( self_res, ty:: Visibility :: Invisible , DUMMY_SP , self . parent_scope . expansion )
1278
- . to_name_binding ( self . r . arenas ) ;
1279
1259
let mut self_type_rib = Rib :: new ( NormalRibKind ) ;
1280
1260
1281
1261
// Plain insert (no renaming, since types are not currently hygienic)
1282
- self_type_rib. bindings . insert ( Ident :: with_dummy_span ( kw:: SelfUpper ) , binding ) ;
1262
+ self_type_rib. bindings . insert ( Ident :: with_dummy_span ( kw:: SelfUpper ) , self_res ) ;
1283
1263
self . ribs [ ns] . push ( self_type_rib) ;
1284
1264
f ( self ) ;
1285
1265
self . ribs [ ns] . pop ( ) ;
@@ -1490,7 +1470,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
1490
1470
/// this is done hygienically. This could arise for a macro
1491
1471
/// that expands into an or-pattern where one 'x' was from the
1492
1472
/// user and one 'x' came from the macro.
1493
- fn binding_mode_map ( & mut self , pat : & Pat ) -> FxHashMap < Ident , BindingInfo > {
1473
+ fn binding_mode_map ( & mut self , pat : & Pat ) -> BindingMap {
1494
1474
let mut binding_map = FxHashMap :: default ( ) ;
1495
1475
1496
1476
pat. walk ( & mut |pat| {
@@ -1523,7 +1503,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
1523
1503
1524
1504
/// Checks that all of the arms in an or-pattern have exactly the
1525
1505
/// same set of bindings, with the same binding modes for each.
1526
- fn check_consistent_bindings ( & mut self , pats : & [ P < Pat > ] ) -> Vec < FxHashMap < Ident , BindingInfo > > {
1506
+ fn check_consistent_bindings ( & mut self , pats : & [ P < Pat > ] ) -> Vec < BindingMap > {
1527
1507
let mut missing_vars = FxHashMap :: default ( ) ;
1528
1508
let mut inconsistent_vars = FxHashMap :: default ( ) ;
1529
1509
@@ -1665,6 +1645,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
1665
1645
. try_resolve_as_non_binding ( pat_src, pat, bmode, ident, has_sub)
1666
1646
. unwrap_or_else ( || self . fresh_binding ( ident, pat. id , pat_src, bindings) ) ;
1667
1647
self . r . record_partial_res ( pat. id , PartialRes :: new ( res) ) ;
1648
+ self . r . record_pat_span ( pat. id , pat. span ) ;
1668
1649
}
1669
1650
PatKind :: TupleStruct ( ref qself, ref path, ref sub_patterns) => {
1670
1651
self . smart_resolve_path (
@@ -1754,24 +1735,18 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
1754
1735
if already_bound_or {
1755
1736
// `Variant1(a) | Variant2(a)`, ok
1756
1737
// Reuse definition from the first `a`.
1757
- self . innermost_rib_bindings ( ValueNS ) [ & ident] . res ( )
1738
+ self . innermost_rib_bindings ( ValueNS ) [ & ident]
1758
1739
} else {
1759
1740
let res = Res :: Local ( pat_id) ;
1760
1741
if ident_valid {
1761
1742
// A completely fresh binding add to the set if it's valid.
1762
- let binding =
1763
- ( res, ty:: Visibility :: Invisible , ident. span , self . parent_scope . expansion )
1764
- . to_name_binding ( self . r . arenas ) ;
1765
- self . innermost_rib_bindings ( ValueNS ) . insert ( ident, binding) ;
1743
+ self . innermost_rib_bindings ( ValueNS ) . insert ( ident, res) ;
1766
1744
}
1767
1745
res
1768
1746
}
1769
1747
}
1770
1748
1771
- fn innermost_rib_bindings (
1772
- & mut self ,
1773
- ns : Namespace ,
1774
- ) -> & mut FxHashMap < Ident , & ' a NameBinding < ' a > > {
1749
+ fn innermost_rib_bindings ( & mut self , ns : Namespace ) -> & mut IdentMap < Res > {
1775
1750
& mut self . ribs [ ns] . last_mut ( ) . unwrap ( ) . bindings
1776
1751
}
1777
1752
@@ -1788,25 +1763,32 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
1788
1763
// also be interpreted as a path to e.g. a constant, variant, etc.
1789
1764
let is_syntactic_ambiguity = !has_sub && bm == BindingMode :: ByValue ( Mutability :: Not ) ;
1790
1765
1791
- let binding = self . resolve_ident_in_lexical_scope ( ident, ValueNS , None , pat. span ) ?;
1792
- if is_syntactic_ambiguity && binding. is_ambiguity ( ) {
1793
- // For ambiguous bindings we don't know all their definitions and cannot check
1794
- // whether they can be shadowed by fresh bindings or not, so force an error.
1795
- // issues/33118#issuecomment-233962221 (see below) still applies here,
1796
- // but we have to ignore it for backward compatibility.
1797
- self . r . record_use ( ident, binding, false ) ;
1798
- return None ;
1799
- }
1766
+ let ls_binding = self . resolve_ident_in_lexical_scope ( ident, ValueNS , None , pat. span ) ?;
1767
+ let ( res, binding) = match ls_binding {
1768
+ LexicalScopeBinding :: Item ( binding)
1769
+ if is_syntactic_ambiguity && binding. is_ambiguity ( ) =>
1770
+ {
1771
+ // For ambiguous bindings we don't know all their definitions and cannot check
1772
+ // whether they can be shadowed by fresh bindings or not, so force an error.
1773
+ // issues/33118#issuecomment-233962221 (see below) still applies here,
1774
+ // but we have to ignore it for backward compatibility.
1775
+ self . r . record_use ( ident, binding, false ) ;
1776
+ return None ;
1777
+ }
1778
+ LexicalScopeBinding :: Item ( binding) => ( binding. res ( ) , Some ( binding) ) ,
1779
+ LexicalScopeBinding :: Res ( res) => ( res, None ) ,
1780
+ } ;
1800
1781
1801
- let res = binding. res ( ) ;
1802
1782
match res {
1803
1783
Res :: SelfCtor ( _) // See #70549.
1804
1784
| Res :: Def (
1805
1785
DefKind :: Ctor ( _, CtorKind :: Const ) | DefKind :: Const | DefKind :: ConstParam ,
1806
1786
_,
1807
1787
) if is_syntactic_ambiguity => {
1808
1788
// Disambiguate in favor of a unit struct/variant or constant pattern.
1809
- self . r . record_use ( ident, binding, false ) ;
1789
+ if let Some ( binding) = binding {
1790
+ self . r . record_use ( ident, binding, false ) ;
1791
+ }
1810
1792
Some ( res)
1811
1793
}
1812
1794
Res :: Def ( DefKind :: Ctor ( ..) | DefKind :: Const | DefKind :: Static , _) => {
@@ -1815,6 +1797,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
1815
1797
// to something unusable as a pattern (e.g., constructor function),
1816
1798
// but we still conservatively report an error, see
1817
1799
// issues/33118#issuecomment-233962221 for one reason why.
1800
+ let binding = binding. expect ( "no binding for a ctor or static" ) ;
1818
1801
self . report_error (
1819
1802
ident. span ,
1820
1803
ResolutionError :: BindingShadowsSomethingUnacceptable {
@@ -2054,15 +2037,19 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
2054
2037
}
2055
2038
2056
2039
fn self_type_is_available ( & mut self , span : Span ) -> bool {
2057
- let ident = Ident :: with_dummy_span ( kw:: SelfUpper ) ;
2058
- self . resolve_ident_in_lexical_scope ( ident, TypeNS , None , span)
2059
- . map_or ( false , |binding| binding. res ( ) != Res :: Err )
2040
+ let binding = self . resolve_ident_in_lexical_scope (
2041
+ Ident :: with_dummy_span ( kw:: SelfUpper ) ,
2042
+ TypeNS ,
2043
+ None ,
2044
+ span,
2045
+ ) ;
2046
+ if let Some ( LexicalScopeBinding :: Res ( res) ) = binding { res != Res :: Err } else { false }
2060
2047
}
2061
2048
2062
2049
fn self_value_is_available ( & mut self , self_span : Span , path_span : Span ) -> bool {
2063
2050
let ident = Ident :: new ( kw:: SelfLower , self_span) ;
2064
- self . resolve_ident_in_lexical_scope ( ident, ValueNS , None , path_span)
2065
- . map_or ( false , |binding| binding. res ( ) != Res :: Err )
2051
+ let binding = self . resolve_ident_in_lexical_scope ( ident, ValueNS , None , path_span) ;
2052
+ if let Some ( LexicalScopeBinding :: Res ( res ) ) = binding { res != Res :: Err } else { false }
2066
2053
}
2067
2054
2068
2055
/// A wrapper around [`Resolver::report_error`].
0 commit comments