77
88use RibKind :: * ;
99
10- use crate :: { path_names_to_string, BindingError , CrateLint , NameBinding , ToNameBinding } ;
10+ use crate :: { path_names_to_string, BindingError , CrateLint , LexicalScopeBinding } ;
1111use crate :: { Module , ModuleOrUniformRoot , ParentScope , PathResult } ;
1212use crate :: { ResolutionError , Resolver , Segment , UseError } ;
1313
@@ -21,22 +21,27 @@ use rustc_hir::def::Namespace::{self, *};
2121use rustc_hir:: def:: { self , CtorKind , DefKind , PartialRes , PerNS } ;
2222use rustc_hir:: def_id:: { DefId , CRATE_DEF_INDEX } ;
2323use rustc_hir:: { PrimTy , TraitCandidate } ;
24- use rustc_middle:: { bug, span_bug, ty } ;
24+ use rustc_middle:: { bug, span_bug} ;
2525use rustc_session:: lint;
26- use rustc_span:: source_map:: { respan, Spanned } ;
2726use rustc_span:: symbol:: { kw, sym, Ident , Symbol } ;
28- use rustc_span:: { Span , DUMMY_SP } ;
27+ use rustc_span:: Span ;
2928use smallvec:: { smallvec, SmallVec } ;
30- use tracing:: debug;
3129
30+ use rustc_span:: source_map:: { respan, Spanned } ;
3231use std:: collections:: { hash_map:: Entry , BTreeSet } ;
3332use std:: mem:: { replace, take} ;
33+ use tracing:: debug;
3434
3535mod diagnostics;
3636crate mod lifetimes;
3737
3838type Res = def:: Res < NodeId > ;
3939
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+
4045#[ derive( Copy , Clone , Debug ) ]
4146struct BindingInfo {
4247 span : Span ,
@@ -167,8 +172,8 @@ impl RibKind<'_> {
167172/// The resolution keeps a separate stack of ribs as it traverses the AST for each namespace. When
168173/// resolving, the name is looked up from inside out.
169174#[ 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 > ,
172177 pub kind : RibKind < ' a > ,
173178}
174179
@@ -562,12 +567,12 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
562567 GenericParamKind :: Type { .. } => {
563568 forward_ty_ban_rib
564569 . 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 ) ;
566571 }
567572 GenericParamKind :: Const { .. } => {
568573 forward_const_ban_rib
569574 . 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 ) ;
571576 }
572577 GenericParamKind :: Lifetime => { }
573578 }
@@ -584,9 +589,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
584589 // such as in the case of `trait Add<Rhs = Self>`.)
585590 if self . diagnostic_metadata . current_self_item . is_some ( ) {
586591 // (`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 ) ;
590593 }
591594
592595 for param in & generics. params {
@@ -734,17 +737,15 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
734737 ns : Namespace ,
735738 record_used_id : Option < NodeId > ,
736739 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+ )
748749 }
749750
750751 fn resolve_path (
@@ -902,10 +903,6 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
902903 }
903904
904905 fn future_proof_import ( & mut self , use_tree : & UseTree ) {
905- if !self . should_report_errs ( ) {
906- return ;
907- }
908-
909906 let segments = & use_tree. prefix . segments ;
910907 if !segments. is_empty ( ) {
911908 let ident = segments[ 0 ] . ident ;
@@ -917,42 +914,31 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
917914 UseTreeKind :: Simple ( ..) if segments. len ( ) == 1 => & [ TypeNS , ValueNS ] [ ..] ,
918915 _ => & [ TypeNS ] ,
919916 } ;
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- } ;
929917 let report_error = |this : & Self , ns| {
930918 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+ }
933924 } ;
934925
935926 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 ( ..) ) => {
940929 report_error ( self , ns) ;
941- } else {
930+ }
931+ Some ( LexicalScopeBinding :: Item ( binding) ) => {
942932 let orig_unusable_binding =
943933 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) ;
953938 }
954939 self . r . unusable_binding = orig_unusable_binding;
955940 }
941+ None => { }
956942 }
957943 }
958944 } else if let UseTreeKind :: Nested ( use_trees) = & use_tree. kind {
@@ -1149,12 +1135,8 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
11491135 _ => unreachable ! ( ) ,
11501136 } ;
11511137 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-
11561138 self . r . record_partial_res ( param. id , PartialRes :: new ( res) ) ;
1157- rib. bindings . insert ( ident, binding ) ;
1139+ rib. bindings . insert ( ident, res ) ;
11581140 }
11591141
11601142 self . ribs [ ValueNS ] . push ( function_value_rib) ;
@@ -1274,12 +1256,10 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
12741256 }
12751257
12761258 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 ) ;
12791259 let mut self_type_rib = Rib :: new ( NormalRibKind ) ;
12801260
12811261 // 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 ) ;
12831263 self . ribs [ ns] . push ( self_type_rib) ;
12841264 f ( self ) ;
12851265 self . ribs [ ns] . pop ( ) ;
@@ -1490,7 +1470,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
14901470 /// this is done hygienically. This could arise for a macro
14911471 /// that expands into an or-pattern where one 'x' was from the
14921472 /// 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 {
14941474 let mut binding_map = FxHashMap :: default ( ) ;
14951475
14961476 pat. walk ( & mut |pat| {
@@ -1523,7 +1503,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
15231503
15241504 /// Checks that all of the arms in an or-pattern have exactly the
15251505 /// 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 > {
15271507 let mut missing_vars = FxHashMap :: default ( ) ;
15281508 let mut inconsistent_vars = FxHashMap :: default ( ) ;
15291509
@@ -1665,6 +1645,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
16651645 . try_resolve_as_non_binding ( pat_src, pat, bmode, ident, has_sub)
16661646 . unwrap_or_else ( || self . fresh_binding ( ident, pat. id , pat_src, bindings) ) ;
16671647 self . r . record_partial_res ( pat. id , PartialRes :: new ( res) ) ;
1648+ self . r . record_pat_span ( pat. id , pat. span ) ;
16681649 }
16691650 PatKind :: TupleStruct ( ref qself, ref path, ref sub_patterns) => {
16701651 self . smart_resolve_path (
@@ -1754,24 +1735,18 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
17541735 if already_bound_or {
17551736 // `Variant1(a) | Variant2(a)`, ok
17561737 // Reuse definition from the first `a`.
1757- self . innermost_rib_bindings ( ValueNS ) [ & ident] . res ( )
1738+ self . innermost_rib_bindings ( ValueNS ) [ & ident]
17581739 } else {
17591740 let res = Res :: Local ( pat_id) ;
17601741 if ident_valid {
17611742 // 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) ;
17661744 }
17671745 res
17681746 }
17691747 }
17701748
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 > {
17751750 & mut self . ribs [ ns] . last_mut ( ) . unwrap ( ) . bindings
17761751 }
17771752
@@ -1788,25 +1763,32 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
17881763 // also be interpreted as a path to e.g. a constant, variant, etc.
17891764 let is_syntactic_ambiguity = !has_sub && bm == BindingMode :: ByValue ( Mutability :: Not ) ;
17901765
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+ } ;
18001781
1801- let res = binding. res ( ) ;
18021782 match res {
18031783 Res :: SelfCtor ( _) // See #70549.
18041784 | Res :: Def (
18051785 DefKind :: Ctor ( _, CtorKind :: Const ) | DefKind :: Const | DefKind :: ConstParam ,
18061786 _,
18071787 ) if is_syntactic_ambiguity => {
18081788 // 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+ }
18101792 Some ( res)
18111793 }
18121794 Res :: Def ( DefKind :: Ctor ( ..) | DefKind :: Const | DefKind :: Static , _) => {
@@ -1815,6 +1797,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
18151797 // to something unusable as a pattern (e.g., constructor function),
18161798 // but we still conservatively report an error, see
18171799 // issues/33118#issuecomment-233962221 for one reason why.
1800+ let binding = binding. expect ( "no binding for a ctor or static" ) ;
18181801 self . report_error (
18191802 ident. span ,
18201803 ResolutionError :: BindingShadowsSomethingUnacceptable {
@@ -2054,15 +2037,19 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
20542037 }
20552038
20562039 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 }
20602047 }
20612048
20622049 fn self_value_is_available ( & mut self , self_span : Span , path_span : Span ) -> bool {
20632050 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 }
20662053 }
20672054
20682055 /// A wrapper around [`Resolver::report_error`].
0 commit comments