@@ -511,7 +511,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
511511 opt_match_place : Option < ( Option < & Place < ' tcx > > , Span ) > ,
512512 ) -> Option < SourceScope > {
513513 debug ! ( "declare_bindings: pattern={:?}" , pattern) ;
514- self . visit_bindings (
514+ self . visit_primary_bindings (
515515 & pattern,
516516 UserTypeProjections :: none ( ) ,
517517 & mut |this, mutability, name, mode, var, span, ty, user_ty| {
@@ -563,7 +563,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
563563 self . schedule_drop ( span, region_scope, local_id, DropKind :: Value ) ;
564564 }
565565
566- pub ( super ) fn visit_bindings (
566+ /// Visit all of the primary bindings in a patterns, that is, visit the
567+ /// leftmost occurrence of each variable bound in a pattern. A variable
568+ /// will occur more than once in an or-pattern.
569+ pub ( super ) fn visit_primary_bindings (
567570 & mut self ,
568571 pattern : & Pat < ' tcx > ,
569572 pattern_user_ty : UserTypeProjections ,
@@ -578,12 +581,26 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
578581 UserTypeProjections ,
579582 ) ,
580583 ) {
581- debug ! ( "visit_bindings: pattern={:?} pattern_user_ty={:?}" , pattern, pattern_user_ty) ;
584+ debug ! (
585+ "visit_primary_bindings: pattern={:?} pattern_user_ty={:?}" ,
586+ pattern, pattern_user_ty
587+ ) ;
582588 match * pattern. kind {
583- PatKind :: Binding { mutability, name, mode, var, ty, ref subpattern, .. } => {
584- f ( self , mutability, name, mode, var, pattern. span , ty, pattern_user_ty. clone ( ) ) ;
589+ PatKind :: Binding {
590+ mutability,
591+ name,
592+ mode,
593+ var,
594+ ty,
595+ ref subpattern,
596+ is_primary,
597+ ..
598+ } => {
599+ if is_primary {
600+ f ( self , mutability, name, mode, var, pattern. span , ty, pattern_user_ty. clone ( ) ) ;
601+ }
585602 if let Some ( subpattern) = subpattern. as_ref ( ) {
586- self . visit_bindings ( subpattern, pattern_user_ty, f) ;
603+ self . visit_primary_bindings ( subpattern, pattern_user_ty, f) ;
587604 }
588605 }
589606
@@ -592,20 +609,24 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
592609 let from = u32:: try_from ( prefix. len ( ) ) . unwrap ( ) ;
593610 let to = u32:: try_from ( suffix. len ( ) ) . unwrap ( ) ;
594611 for subpattern in prefix {
595- self . visit_bindings ( subpattern, pattern_user_ty. clone ( ) . index ( ) , f) ;
612+ self . visit_primary_bindings ( subpattern, pattern_user_ty. clone ( ) . index ( ) , f) ;
596613 }
597614 for subpattern in slice {
598- self . visit_bindings ( subpattern, pattern_user_ty. clone ( ) . subslice ( from, to) , f) ;
615+ self . visit_primary_bindings (
616+ subpattern,
617+ pattern_user_ty. clone ( ) . subslice ( from, to) ,
618+ f,
619+ ) ;
599620 }
600621 for subpattern in suffix {
601- self . visit_bindings ( subpattern, pattern_user_ty. clone ( ) . index ( ) , f) ;
622+ self . visit_primary_bindings ( subpattern, pattern_user_ty. clone ( ) . index ( ) , f) ;
602623 }
603624 }
604625
605626 PatKind :: Constant { .. } | PatKind :: Range { .. } | PatKind :: Wild => { }
606627
607628 PatKind :: Deref { ref subpattern } => {
608- self . visit_bindings ( subpattern, pattern_user_ty. deref ( ) , f) ;
629+ self . visit_primary_bindings ( subpattern, pattern_user_ty. deref ( ) , f) ;
609630 }
610631
611632 PatKind :: AscribeUserType {
@@ -630,26 +651,32 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
630651 projs : Vec :: new ( ) ,
631652 } ;
632653 let subpattern_user_ty = pattern_user_ty. push_projection ( & projection, user_ty_span) ;
633- self . visit_bindings ( subpattern, subpattern_user_ty, f)
654+ self . visit_primary_bindings ( subpattern, subpattern_user_ty, f)
634655 }
635656
636657 PatKind :: Leaf { ref subpatterns } => {
637658 for subpattern in subpatterns {
638659 let subpattern_user_ty = pattern_user_ty. clone ( ) . leaf ( subpattern. field ) ;
639- debug ! ( "visit_bindings : subpattern_user_ty={:?}" , subpattern_user_ty) ;
640- self . visit_bindings ( & subpattern. pattern , subpattern_user_ty, f) ;
660+ debug ! ( "visit_primary_bindings : subpattern_user_ty={:?}" , subpattern_user_ty) ;
661+ self . visit_primary_bindings ( & subpattern. pattern , subpattern_user_ty, f) ;
641662 }
642663 }
643664
644665 PatKind :: Variant { adt_def, substs : _, variant_index, ref subpatterns } => {
645666 for subpattern in subpatterns {
646667 let subpattern_user_ty =
647668 pattern_user_ty. clone ( ) . variant ( adt_def, variant_index, subpattern. field ) ;
648- self . visit_bindings ( & subpattern. pattern , subpattern_user_ty, f) ;
669+ self . visit_primary_bindings ( & subpattern. pattern , subpattern_user_ty, f) ;
649670 }
650671 }
651672 PatKind :: Or { ref pats } => {
652- self . visit_bindings ( & pats[ 0 ] , pattern_user_ty, f) ;
673+ // In cases where we recover from errors the primary bindings
674+ // may not all be in the leftmost subpattern. For example in
675+ // `let (x | y) = ...`, the primary binding of `y` occurs in
676+ // the right subpattern
677+ for subpattern in pats {
678+ self . visit_primary_bindings ( subpattern, pattern_user_ty. clone ( ) , f) ;
679+ }
653680 }
654681 }
655682 }
@@ -1955,7 +1982,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
19551982 is_block_tail : None ,
19561983 local_info : Some ( box LocalInfo :: User ( ClearCrossCrate :: Set ( BindingForm :: Var ( VarBindingForm {
19571984 binding_mode,
1958- // hypothetically, `visit_bindings ` could try to unzip
1985+ // hypothetically, `visit_primary_bindings ` could try to unzip
19591986 // an outermost hir::Ty as we descend, matching up
19601987 // idents in pat; but complex w/ unclear UI payoff.
19611988 // Instead, just abandon providing diagnostic info.
0 commit comments