@@ -2122,12 +2122,13 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
21222122 let mut parameter_info = Vec :: new ( ) ;
21232123 let mut all_candidates = Vec :: new ( ) ;
21242124
2125+ let top_rib_idx = self . ribs [ ValueNS ] . len ( ) - 1 ;
21252126 let mut bindings = smallvec ! [ ( PatBoundCtx :: Product , Default :: default ( ) ) ] ;
21262127 for ( index, ( pat, ty) ) in inputs. enumerate ( ) {
21272128 debug ! ( ?pat, ?ty) ;
21282129 self . with_lifetime_rib ( LifetimeRibKind :: Elided ( LifetimeRes :: Infer ) , |this| {
21292130 if let Some ( pat) = pat {
2130- this. resolve_pattern ( pat, PatternSource :: FnParam , & mut bindings) ;
2131+ this. resolve_pattern ( pat, PatternSource :: FnParam , top_rib_idx , & mut bindings) ;
21312132 }
21322133 } ) ;
21332134
@@ -3384,6 +3385,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
33843385 Ident :: new ( kw:: SelfLower , span) ,
33853386 delegation. id ,
33863387 PatternSource :: FnParam ,
3388+ this. ribs [ ValueNS ] . len ( ) - 1 ,
33873389 & mut bindings,
33883390 ) ;
33893391 this. visit_block ( body) ;
@@ -3392,10 +3394,11 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
33923394 }
33933395
33943396 fn resolve_params ( & mut self , params : & ' ast [ Param ] ) {
3397+ let top_rib_idx = self . ribs [ ValueNS ] . len ( ) - 1 ;
33953398 let mut bindings = smallvec ! [ ( PatBoundCtx :: Product , Default :: default ( ) ) ] ;
33963399 self . with_lifetime_rib ( LifetimeRibKind :: Elided ( LifetimeRes :: Infer ) , |this| {
33973400 for Param { pat, .. } in params {
3398- this. resolve_pattern ( pat, PatternSource :: FnParam , & mut bindings) ;
3401+ this. resolve_pattern ( pat, PatternSource :: FnParam , top_rib_idx , & mut bindings) ;
33993402 }
34003403 } ) ;
34013404 for Param { ty, .. } in params {
@@ -3613,20 +3616,22 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
36133616 /// Arising from `source`, resolve a top level pattern.
36143617 fn resolve_pattern_top ( & mut self , pat : & ' ast Pat , pat_src : PatternSource ) {
36153618 let mut bindings = smallvec ! [ ( PatBoundCtx :: Product , Default :: default ( ) ) ] ;
3616- self . resolve_pattern ( pat, pat_src, & mut bindings) ;
3619+ let top_rib_idx = self . ribs [ ValueNS ] . len ( ) - 1 ;
3620+ self . resolve_pattern ( pat, pat_src, top_rib_idx, & mut bindings) ;
36173621 }
36183622
36193623 fn resolve_pattern (
36203624 & mut self ,
36213625 pat : & ' ast Pat ,
36223626 pat_src : PatternSource ,
3627+ top_rib_idx : usize ,
36233628 bindings : & mut SmallVec < [ ( PatBoundCtx , FxHashSet < Ident > ) ; 1 ] > ,
36243629 ) {
36253630 // We walk the pattern before declaring the pattern's inner bindings,
36263631 // so that we avoid resolving a literal expression to a binding defined
36273632 // by the pattern.
36283633 visit:: walk_pat ( self , pat) ;
3629- self . resolve_pattern_inner ( pat, pat_src, bindings) ;
3634+ self . resolve_pattern_inner ( pat, pat_src, top_rib_idx , bindings) ;
36303635 // This has to happen *after* we determine which pat_idents are variants:
36313636 self . check_consistent_bindings ( pat) ;
36323637 }
@@ -3654,6 +3659,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
36543659 & mut self ,
36553660 pat : & ' ast Pat ,
36563661 pat_src : PatternSource ,
3662+ top_rib_idx : usize ,
36573663 bindings : & mut SmallVec < [ ( PatBoundCtx , FxHashSet < Ident > ) ; 1 ] > ,
36583664 ) {
36593665 // Visit all direct subpatterns of this pattern.
@@ -3666,7 +3672,9 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
36663672 let has_sub = sub. is_some ( ) ;
36673673 let res = self
36683674 . try_resolve_as_non_binding ( pat_src, bmode, ident, has_sub)
3669- . unwrap_or_else ( || self . fresh_binding ( ident, pat. id , pat_src, bindings) ) ;
3675+ . unwrap_or_else ( || {
3676+ self . fresh_binding ( ident, pat. id , pat_src, top_rib_idx, bindings)
3677+ } ) ;
36703678 self . r . record_partial_res ( pat. id , PartialRes :: new ( res) ) ;
36713679 self . r . record_pat_span ( pat. id , pat. span ) ;
36723680 }
@@ -3697,7 +3705,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
36973705 // part of the or-pattern internally rejects already bound names.
36983706 // For example, `V1(a) | V2(a, a)` and `V1(a, a) | V2(a)` are bad.
36993707 bindings. push ( ( PatBoundCtx :: Product , Default :: default ( ) ) ) ;
3700- self . resolve_pattern_inner ( p, pat_src, bindings) ;
3708+ self . resolve_pattern_inner ( p, pat_src, top_rib_idx , bindings) ;
37013709 // Move up the non-overlapping bindings to the or-pattern.
37023710 // Existing bindings just get "merged".
37033711 let collected = bindings. pop ( ) . unwrap ( ) . 1 ;
@@ -3714,7 +3722,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
37143722 }
37153723 PatKind :: Guard ( ref subpat, ref cond) => {
37163724 self . with_rib ( ValueNS , RibKind :: Normal , |this| {
3717- this. resolve_pattern_inner ( subpat, pat_src, bindings) ;
3725+ this. resolve_pattern_inner ( subpat, pat_src, top_rib_idx , bindings) ;
37183726 this. resolve_expr ( cond, None ) ;
37193727 } ) ;
37203728
@@ -3732,6 +3740,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
37323740 ident : Ident ,
37333741 pat_id : NodeId ,
37343742 pat_src : PatternSource ,
3743+ top_rib_idx : usize ,
37353744 bindings : & mut SmallVec < [ ( PatBoundCtx , FxHashSet < Ident > ) ; 1 ] > ,
37363745 ) -> Res {
37373746 // Add the binding to the local ribs, if it doesn't already exist in the bindings map.
@@ -3764,18 +3773,23 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
37643773 bindings. last_mut ( ) . unwrap ( ) . 1 . insert ( ident) ;
37653774 }
37663775
3767- if already_bound_or {
3776+ let res = if already_bound_or {
37683777 // `Variant1(a) | Variant2(a)`, ok
37693778 // Reuse definition from the first `a`.
3770- self . innermost_rib_bindings ( ValueNS ) [ & ident]
3779+ self . ribs [ ValueNS ] [ top_rib_idx ] . bindings [ & ident]
37713780 } else {
37723781 let res = Res :: Local ( pat_id) ;
37733782 if ident_valid {
37743783 // A completely fresh binding add to the set if it's valid.
3775- self . innermost_rib_bindings ( ValueNS ) . insert ( ident, res) ;
3784+ self . ribs [ ValueNS ] [ top_rib_idx ] . bindings . insert ( ident, res) ;
37763785 }
37773786 res
3778- }
3787+ } ;
3788+
3789+ // Record the binding in the innermost rib so guard expressions can use it.
3790+ self . innermost_rib_bindings ( ValueNS ) . insert ( ident, res) ;
3791+
3792+ res
37793793 }
37803794
37813795 fn innermost_rib_bindings ( & mut self , ns : Namespace ) -> & mut IdentMap < Res > {
0 commit comments