@@ -2227,12 +2227,13 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
22272227 let mut parameter_info = Vec :: new ( ) ;
22282228 let mut all_candidates = Vec :: new ( ) ;
22292229
2230+ let top_rib_idx = self . ribs [ ValueNS ] . len ( ) - 1 ;
22302231 let mut bindings = smallvec ! [ ( PatBoundCtx :: Product , Default :: default ( ) ) ] ;
22312232 for ( index, ( pat, ty) ) in inputs. enumerate ( ) {
22322233 debug ! ( ?pat, ?ty) ;
22332234 self . with_lifetime_rib ( LifetimeRibKind :: Elided ( LifetimeRes :: Infer ) , |this| {
22342235 if let Some ( pat) = pat {
2235- this. resolve_pattern ( pat, PatternSource :: FnParam , & mut bindings) ;
2236+ this. resolve_pattern ( pat, PatternSource :: FnParam , top_rib_idx , & mut bindings) ;
22362237 }
22372238 } ) ;
22382239
@@ -3490,6 +3491,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
34903491 Ident :: new ( kw:: SelfLower , span) ,
34913492 delegation. id ,
34923493 PatternSource :: FnParam ,
3494+ this. ribs [ ValueNS ] . len ( ) - 1 ,
34933495 & mut bindings,
34943496 ) ;
34953497 this. visit_block ( body) ;
@@ -3498,10 +3500,11 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
34983500 }
34993501
35003502 fn resolve_params ( & mut self , params : & ' ast [ Param ] ) {
3503+ let top_rib_idx = self . ribs [ ValueNS ] . len ( ) - 1 ;
35013504 let mut bindings = smallvec ! [ ( PatBoundCtx :: Product , Default :: default ( ) ) ] ;
35023505 self . with_lifetime_rib ( LifetimeRibKind :: Elided ( LifetimeRes :: Infer ) , |this| {
35033506 for Param { pat, .. } in params {
3504- this. resolve_pattern ( pat, PatternSource :: FnParam , & mut bindings) ;
3507+ this. resolve_pattern ( pat, PatternSource :: FnParam , top_rib_idx , & mut bindings) ;
35053508 }
35063509 } ) ;
35073510 for Param { ty, .. } in params {
@@ -3719,20 +3722,22 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
37193722 /// Arising from `source`, resolve a top level pattern.
37203723 fn resolve_pattern_top ( & mut self , pat : & ' ast Pat , pat_src : PatternSource ) {
37213724 let mut bindings = smallvec ! [ ( PatBoundCtx :: Product , Default :: default ( ) ) ] ;
3722- self . resolve_pattern ( pat, pat_src, & mut bindings) ;
3725+ let top_rib_idx = self . ribs [ ValueNS ] . len ( ) - 1 ;
3726+ self . resolve_pattern ( pat, pat_src, top_rib_idx, & mut bindings) ;
37233727 }
37243728
37253729 fn resolve_pattern (
37263730 & mut self ,
37273731 pat : & ' ast Pat ,
37283732 pat_src : PatternSource ,
3733+ top_rib_idx : usize ,
37293734 bindings : & mut SmallVec < [ ( PatBoundCtx , FxHashSet < Ident > ) ; 1 ] > ,
37303735 ) {
37313736 // We walk the pattern before declaring the pattern's inner bindings,
37323737 // so that we avoid resolving a literal expression to a binding defined
37333738 // by the pattern.
37343739 visit:: walk_pat ( self , pat) ;
3735- self . resolve_pattern_inner ( pat, pat_src, bindings) ;
3740+ self . resolve_pattern_inner ( pat, pat_src, top_rib_idx , bindings) ;
37363741 // This has to happen *after* we determine which pat_idents are variants:
37373742 self . check_consistent_bindings ( pat) ;
37383743 }
@@ -3760,6 +3765,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
37603765 & mut self ,
37613766 pat : & ' ast Pat ,
37623767 pat_src : PatternSource ,
3768+ top_rib_idx : usize ,
37633769 bindings : & mut SmallVec < [ ( PatBoundCtx , FxHashSet < Ident > ) ; 1 ] > ,
37643770 ) {
37653771 // Visit all direct subpatterns of this pattern.
@@ -3772,7 +3778,9 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
37723778 let has_sub = sub. is_some ( ) ;
37733779 let res = self
37743780 . try_resolve_as_non_binding ( pat_src, bmode, ident, has_sub)
3775- . unwrap_or_else ( || self . fresh_binding ( ident, pat. id , pat_src, bindings) ) ;
3781+ . unwrap_or_else ( || {
3782+ self . fresh_binding ( ident, pat. id , pat_src, top_rib_idx, bindings)
3783+ } ) ;
37763784 self . r . record_partial_res ( pat. id , PartialRes :: new ( res) ) ;
37773785 self . r . record_pat_span ( pat. id , pat. span ) ;
37783786 }
@@ -3803,7 +3811,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
38033811 // part of the or-pattern internally rejects already bound names.
38043812 // For example, `V1(a) | V2(a, a)` and `V1(a, a) | V2(a)` are bad.
38053813 bindings. push ( ( PatBoundCtx :: Product , Default :: default ( ) ) ) ;
3806- self . resolve_pattern_inner ( p, pat_src, bindings) ;
3814+ self . resolve_pattern_inner ( p, pat_src, top_rib_idx , bindings) ;
38073815 // Move up the non-overlapping bindings to the or-pattern.
38083816 // Existing bindings just get "merged".
38093817 let collected = bindings. pop ( ) . unwrap ( ) . 1 ;
@@ -3820,7 +3828,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
38203828 }
38213829 PatKind :: Guard ( ref subpat, ref cond) => {
38223830 self . with_rib ( ValueNS , RibKind :: Normal , |this| {
3823- this. resolve_pattern_inner ( subpat, pat_src, bindings) ;
3831+ this. resolve_pattern_inner ( subpat, pat_src, top_rib_idx , bindings) ;
38243832 this. resolve_expr ( cond, None ) ;
38253833 } ) ;
38263834
@@ -3838,6 +3846,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
38383846 ident : Ident ,
38393847 pat_id : NodeId ,
38403848 pat_src : PatternSource ,
3849+ top_rib_idx : usize ,
38413850 bindings : & mut SmallVec < [ ( PatBoundCtx , FxHashSet < Ident > ) ; 1 ] > ,
38423851 ) -> Res {
38433852 // Add the binding to the local ribs, if it doesn't already exist in the bindings map.
@@ -3870,18 +3879,23 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
38703879 bindings. last_mut ( ) . unwrap ( ) . 1 . insert ( ident) ;
38713880 }
38723881
3873- if already_bound_or {
3882+ let res = if already_bound_or {
38743883 // `Variant1(a) | Variant2(a)`, ok
38753884 // Reuse definition from the first `a`.
3876- self . innermost_rib_bindings ( ValueNS ) [ & ident]
3885+ self . ribs [ ValueNS ] [ top_rib_idx ] . bindings [ & ident]
38773886 } else {
38783887 let res = Res :: Local ( pat_id) ;
38793888 if ident_valid {
38803889 // A completely fresh binding add to the set if it's valid.
3881- self . innermost_rib_bindings ( ValueNS ) . insert ( ident, res) ;
3890+ self . ribs [ ValueNS ] [ top_rib_idx ] . bindings . insert ( ident, res) ;
38823891 }
38833892 res
3884- }
3893+ } ;
3894+
3895+ // Record the binding in the innermost rib so guard expressions can use it.
3896+ self . innermost_rib_bindings ( ValueNS ) . insert ( ident, res) ;
3897+
3898+ res
38853899 }
38863900
38873901 fn innermost_rib_bindings ( & mut self , ns : Namespace ) -> & mut IdentMap < Res > {
0 commit comments