@@ -2176,12 +2176,13 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
21762176 let mut parameter_info = Vec :: new ( ) ;
21772177 let mut all_candidates = Vec :: new ( ) ;
21782178
2179+ let top_rib_idx = self . ribs [ ValueNS ] . len ( ) - 1 ;
21792180 let mut bindings = smallvec ! [ ( PatBoundCtx :: Product , Default :: default ( ) ) ] ;
21802181 for ( index, ( pat, ty) ) in inputs. enumerate ( ) {
21812182 debug ! ( ?pat, ?ty) ;
21822183 self . with_lifetime_rib ( LifetimeRibKind :: Elided ( LifetimeRes :: Infer ) , |this| {
21832184 if let Some ( pat) = pat {
2184- this. resolve_pattern ( pat, PatternSource :: FnParam , & mut bindings) ;
2185+ this. resolve_pattern ( pat, PatternSource :: FnParam , top_rib_idx , & mut bindings) ;
21852186 }
21862187 } ) ;
21872188
@@ -3445,6 +3446,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
34453446 Ident :: new ( kw:: SelfLower , span) ,
34463447 delegation. id ,
34473448 PatternSource :: FnParam ,
3449+ this. ribs [ ValueNS ] . len ( ) - 1 ,
34483450 & mut bindings,
34493451 ) ;
34503452 this. visit_block ( body) ;
@@ -3453,10 +3455,11 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
34533455 }
34543456
34553457 fn resolve_params ( & mut self , params : & ' ast [ Param ] ) {
3458+ let top_rib_idx = self . ribs [ ValueNS ] . len ( ) - 1 ;
34563459 let mut bindings = smallvec ! [ ( PatBoundCtx :: Product , Default :: default ( ) ) ] ;
34573460 self . with_lifetime_rib ( LifetimeRibKind :: Elided ( LifetimeRes :: Infer ) , |this| {
34583461 for Param { pat, .. } in params {
3459- this. resolve_pattern ( pat, PatternSource :: FnParam , & mut bindings) ;
3462+ this. resolve_pattern ( pat, PatternSource :: FnParam , top_rib_idx , & mut bindings) ;
34603463 }
34613464 } ) ;
34623465 for Param { ty, .. } in params {
@@ -3674,20 +3677,22 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
36743677 /// Arising from `source`, resolve a top level pattern.
36753678 fn resolve_pattern_top ( & mut self , pat : & ' ast Pat , pat_src : PatternSource ) {
36763679 let mut bindings = smallvec ! [ ( PatBoundCtx :: Product , Default :: default ( ) ) ] ;
3677- self . resolve_pattern ( pat, pat_src, & mut bindings) ;
3680+ let top_rib_idx = self . ribs [ ValueNS ] . len ( ) - 1 ;
3681+ self . resolve_pattern ( pat, pat_src, top_rib_idx, & mut bindings) ;
36783682 }
36793683
36803684 fn resolve_pattern (
36813685 & mut self ,
36823686 pat : & ' ast Pat ,
36833687 pat_src : PatternSource ,
3688+ top_rib_idx : usize ,
36843689 bindings : & mut SmallVec < [ ( PatBoundCtx , FxHashSet < Ident > ) ; 1 ] > ,
36853690 ) {
36863691 // We walk the pattern before declaring the pattern's inner bindings,
36873692 // so that we avoid resolving a literal expression to a binding defined
36883693 // by the pattern.
36893694 visit:: walk_pat ( self , pat) ;
3690- self . resolve_pattern_inner ( pat, pat_src, bindings) ;
3695+ self . resolve_pattern_inner ( pat, pat_src, top_rib_idx , bindings) ;
36913696 // This has to happen *after* we determine which pat_idents are variants:
36923697 self . check_consistent_bindings ( pat) ;
36933698 }
@@ -3715,6 +3720,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
37153720 & mut self ,
37163721 pat : & ' ast Pat ,
37173722 pat_src : PatternSource ,
3723+ top_rib_idx : usize ,
37183724 bindings : & mut SmallVec < [ ( PatBoundCtx , FxHashSet < Ident > ) ; 1 ] > ,
37193725 ) {
37203726 // Visit all direct subpatterns of this pattern.
@@ -3727,7 +3733,9 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
37273733 let has_sub = sub. is_some ( ) ;
37283734 let res = self
37293735 . try_resolve_as_non_binding ( pat_src, bmode, ident, has_sub)
3730- . unwrap_or_else ( || self . fresh_binding ( ident, pat. id , pat_src, bindings) ) ;
3736+ . unwrap_or_else ( || {
3737+ self . fresh_binding ( ident, pat. id , pat_src, top_rib_idx, bindings)
3738+ } ) ;
37313739 self . r . record_partial_res ( pat. id , PartialRes :: new ( res) ) ;
37323740 self . r . record_pat_span ( pat. id , pat. span ) ;
37333741 }
@@ -3758,7 +3766,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
37583766 // part of the or-pattern internally rejects already bound names.
37593767 // For example, `V1(a) | V2(a, a)` and `V1(a, a) | V2(a)` are bad.
37603768 bindings. push ( ( PatBoundCtx :: Product , Default :: default ( ) ) ) ;
3761- self . resolve_pattern_inner ( p, pat_src, bindings) ;
3769+ self . resolve_pattern_inner ( p, pat_src, top_rib_idx , bindings) ;
37623770 // Move up the non-overlapping bindings to the or-pattern.
37633771 // Existing bindings just get "merged".
37643772 let collected = bindings. pop ( ) . unwrap ( ) . 1 ;
@@ -3775,7 +3783,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
37753783 }
37763784 PatKind :: Guard ( ref subpat, ref cond) => {
37773785 self . with_rib ( ValueNS , RibKind :: Normal , |this| {
3778- this. resolve_pattern_inner ( subpat, pat_src, bindings) ;
3786+ this. resolve_pattern_inner ( subpat, pat_src, top_rib_idx , bindings) ;
37793787 this. resolve_expr ( cond, None ) ;
37803788 } ) ;
37813789
@@ -3793,6 +3801,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
37933801 ident : Ident ,
37943802 pat_id : NodeId ,
37953803 pat_src : PatternSource ,
3804+ top_rib_idx : usize ,
37963805 bindings : & mut SmallVec < [ ( PatBoundCtx , FxHashSet < Ident > ) ; 1 ] > ,
37973806 ) -> Res {
37983807 // Add the binding to the local ribs, if it doesn't already exist in the bindings map.
@@ -3825,18 +3834,23 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
38253834 bindings. last_mut ( ) . unwrap ( ) . 1 . insert ( ident) ;
38263835 }
38273836
3828- if already_bound_or {
3837+ let res = if already_bound_or {
38293838 // `Variant1(a) | Variant2(a)`, ok
38303839 // Reuse definition from the first `a`.
3831- self . innermost_rib_bindings ( ValueNS ) [ & ident]
3840+ self . ribs [ ValueNS ] [ top_rib_idx ] . bindings [ & ident]
38323841 } else {
38333842 let res = Res :: Local ( pat_id) ;
38343843 if ident_valid {
38353844 // A completely fresh binding add to the set if it's valid.
3836- self . innermost_rib_bindings ( ValueNS ) . insert ( ident, res) ;
3845+ self . ribs [ ValueNS ] [ top_rib_idx ] . bindings . insert ( ident, res) ;
38373846 }
38383847 res
3839- }
3848+ } ;
3849+
3850+ // Record the binding in the innermost rib so guard expressions can use it.
3851+ self . innermost_rib_bindings ( ValueNS ) . insert ( ident, res) ;
3852+
3853+ res
38403854 }
38413855
38423856 fn innermost_rib_bindings ( & mut self , ns : Namespace ) -> & mut IdentMap < Res > {
0 commit comments