@@ -2122,12 +2122,13 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
2122
2122
let mut parameter_info = Vec :: new ( ) ;
2123
2123
let mut all_candidates = Vec :: new ( ) ;
2124
2124
2125
+ let top_rib_idx = self . ribs [ ValueNS ] . len ( ) - 1 ;
2125
2126
let mut bindings = smallvec ! [ ( PatBoundCtx :: Product , Default :: default ( ) ) ] ;
2126
2127
for ( index, ( pat, ty) ) in inputs. enumerate ( ) {
2127
2128
debug ! ( ?pat, ?ty) ;
2128
2129
self . with_lifetime_rib ( LifetimeRibKind :: Elided ( LifetimeRes :: Infer ) , |this| {
2129
2130
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) ;
2131
2132
}
2132
2133
} ) ;
2133
2134
@@ -3384,6 +3385,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
3384
3385
Ident :: new ( kw:: SelfLower , span) ,
3385
3386
delegation. id ,
3386
3387
PatternSource :: FnParam ,
3388
+ this. ribs [ ValueNS ] . len ( ) - 1 ,
3387
3389
& mut bindings,
3388
3390
) ;
3389
3391
this. visit_block ( body) ;
@@ -3392,10 +3394,11 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
3392
3394
}
3393
3395
3394
3396
fn resolve_params ( & mut self , params : & ' ast [ Param ] ) {
3397
+ let top_rib_idx = self . ribs [ ValueNS ] . len ( ) - 1 ;
3395
3398
let mut bindings = smallvec ! [ ( PatBoundCtx :: Product , Default :: default ( ) ) ] ;
3396
3399
self . with_lifetime_rib ( LifetimeRibKind :: Elided ( LifetimeRes :: Infer ) , |this| {
3397
3400
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) ;
3399
3402
}
3400
3403
} ) ;
3401
3404
for Param { ty, .. } in params {
@@ -3613,20 +3616,22 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
3613
3616
/// Arising from `source`, resolve a top level pattern.
3614
3617
fn resolve_pattern_top ( & mut self , pat : & ' ast Pat , pat_src : PatternSource ) {
3615
3618
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) ;
3617
3621
}
3618
3622
3619
3623
fn resolve_pattern (
3620
3624
& mut self ,
3621
3625
pat : & ' ast Pat ,
3622
3626
pat_src : PatternSource ,
3627
+ top_rib_idx : usize ,
3623
3628
bindings : & mut SmallVec < [ ( PatBoundCtx , FxHashSet < Ident > ) ; 1 ] > ,
3624
3629
) {
3625
3630
// We walk the pattern before declaring the pattern's inner bindings,
3626
3631
// so that we avoid resolving a literal expression to a binding defined
3627
3632
// by the pattern.
3628
3633
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) ;
3630
3635
// This has to happen *after* we determine which pat_idents are variants:
3631
3636
self . check_consistent_bindings ( pat) ;
3632
3637
}
@@ -3654,6 +3659,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
3654
3659
& mut self ,
3655
3660
pat : & ' ast Pat ,
3656
3661
pat_src : PatternSource ,
3662
+ top_rib_idx : usize ,
3657
3663
bindings : & mut SmallVec < [ ( PatBoundCtx , FxHashSet < Ident > ) ; 1 ] > ,
3658
3664
) {
3659
3665
// Visit all direct subpatterns of this pattern.
@@ -3666,7 +3672,9 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
3666
3672
let has_sub = sub. is_some ( ) ;
3667
3673
let res = self
3668
3674
. 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
+ } ) ;
3670
3678
self . r . record_partial_res ( pat. id , PartialRes :: new ( res) ) ;
3671
3679
self . r . record_pat_span ( pat. id , pat. span ) ;
3672
3680
}
@@ -3697,7 +3705,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
3697
3705
// part of the or-pattern internally rejects already bound names.
3698
3706
// For example, `V1(a) | V2(a, a)` and `V1(a, a) | V2(a)` are bad.
3699
3707
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) ;
3701
3709
// Move up the non-overlapping bindings to the or-pattern.
3702
3710
// Existing bindings just get "merged".
3703
3711
let collected = bindings. pop ( ) . unwrap ( ) . 1 ;
@@ -3714,7 +3722,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
3714
3722
}
3715
3723
PatKind :: Guard ( ref subpat, ref cond) => {
3716
3724
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) ;
3718
3726
this. resolve_expr ( cond, None ) ;
3719
3727
} ) ;
3720
3728
@@ -3732,6 +3740,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
3732
3740
ident : Ident ,
3733
3741
pat_id : NodeId ,
3734
3742
pat_src : PatternSource ,
3743
+ top_rib_idx : usize ,
3735
3744
bindings : & mut SmallVec < [ ( PatBoundCtx , FxHashSet < Ident > ) ; 1 ] > ,
3736
3745
) -> Res {
3737
3746
// 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> {
3764
3773
bindings. last_mut ( ) . unwrap ( ) . 1 . insert ( ident) ;
3765
3774
}
3766
3775
3767
- if already_bound_or {
3776
+ let res = if already_bound_or {
3768
3777
// `Variant1(a) | Variant2(a)`, ok
3769
3778
// Reuse definition from the first `a`.
3770
- self . innermost_rib_bindings ( ValueNS ) [ & ident]
3779
+ self . ribs [ ValueNS ] [ top_rib_idx ] . bindings [ & ident]
3771
3780
} else {
3772
3781
let res = Res :: Local ( pat_id) ;
3773
3782
if ident_valid {
3774
3783
// 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) ;
3776
3785
}
3777
3786
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
3779
3793
}
3780
3794
3781
3795
fn innermost_rib_bindings ( & mut self , ns : Namespace ) -> & mut IdentMap < Res > {
0 commit comments