@@ -3190,11 +3190,11 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
31903190 self . resolve_pattern_top ( & local. pat , PatternSource :: Let ) ;
31913191 }
31923192
3193- /// build a map from pattern identifiers to binding-info's.
3194- /// this is done hygienically. This could arise for a macro
3195- /// that expands into an or-pattern where one 'x' was from the
3196- /// user and one 'x' came from the macro.
3197- fn binding_mode_map ( & mut self , pat : & Pat ) -> FxIndexMap < Ident , BindingInfo > {
3193+ /// Build a map from pattern identifiers to binding-info's, and check the bindings are
3194+ /// consistent when encountering or-patterns.
3195+ /// This is done hygienically: this could arise for a macro that expands into an or-pattern
3196+ /// where one 'x' was from the user and one 'x' came from the macro.
3197+ fn compute_and_check_binding_map ( & mut self , pat : & Pat ) -> FxIndexMap < Ident , BindingInfo > {
31983198 let mut binding_map = FxIndexMap :: default ( ) ;
31993199
32003200 pat. walk ( & mut |pat| {
@@ -3207,9 +3207,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
32073207 PatKind :: Or ( ref ps) => {
32083208 // Check the consistency of this or-pattern and
32093209 // then add all bindings to the larger map.
3210- for bm in self . check_consistent_bindings ( ps) {
3211- binding_map. extend ( bm) ;
3212- }
3210+ let bm = self . compute_and_check_or_pat_binding_map ( ps) ;
3211+ binding_map. extend ( bm) ;
32133212 return false ;
32143213 }
32153214 _ => { }
@@ -3228,18 +3227,19 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
32283227 )
32293228 }
32303229
3231- /// Checks that all of the arms in an or-pattern have exactly the
3232- /// same set of bindings, with the same binding modes for each.
3233- fn check_consistent_bindings (
3230+ /// Compute the binding map for an or-pattern. Checks that all of the arms in the or-pattern
3231+ /// have exactly the same set of bindings, with the same binding modes for each.
3232+ /// Returns the computed binding map.
3233+ fn compute_and_check_or_pat_binding_map (
32343234 & mut self ,
32353235 pats : & [ P < Pat > ] ,
3236- ) -> Vec < FxIndexMap < Ident , BindingInfo > > {
3237- // pats is consistent.
3236+ ) -> FxIndexMap < Ident , BindingInfo > {
32383237 let mut missing_vars = FxIndexMap :: default ( ) ;
32393238 let mut inconsistent_vars = FxIndexMap :: default ( ) ;
32403239
32413240 // 1) Compute the binding maps of all arms.
3242- let maps = pats. iter ( ) . map ( |pat| self . binding_mode_map ( pat) ) . collect :: < Vec < _ > > ( ) ;
3241+ let maps =
3242+ pats. iter ( ) . map ( |pat| self . compute_and_check_binding_map ( pat) ) . collect :: < Vec < _ > > ( ) ;
32433243
32443244 // 2) Record any missing bindings or binding mode inconsistencies.
32453245 for ( map_outer, pat_outer) in maps. iter ( ) . zip ( pats. iter ( ) ) {
@@ -3248,13 +3248,11 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
32483248 . iter ( )
32493249 . zip ( pats. iter ( ) )
32503250 . filter ( |( _, pat) | pat. id != pat_outer. id )
3251- . flat_map ( |( map, _) | map)
3252- . map ( |( key, binding) | ( key. name , map_outer. get ( key) , binding) ) ;
3253-
3254- let inners = inners. collect :: < Vec < _ > > ( ) ;
3251+ . flat_map ( |( map, _) | map) ;
32553252
3256- for ( name, info, & binding_inner) in inners {
3257- match info {
3253+ for ( key, binding_inner) in inners {
3254+ let name = key. name ;
3255+ match map_outer. get ( key) {
32583256 None => {
32593257 // The inner binding is missing in the outer.
32603258 let binding_error =
@@ -3295,15 +3293,19 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
32953293 self . report_error ( v. 0 , ResolutionError :: VariableBoundWithDifferentMode ( name, v. 1 ) ) ;
32963294 }
32973295
3298- // 5) Finally bubble up all the binding maps.
3299- maps
3296+ // 5) Bubble up the final binding map.
3297+ let mut binding_map = FxIndexMap :: default ( ) ;
3298+ for bm in maps {
3299+ binding_map. extend ( bm) ;
3300+ }
3301+ binding_map
33003302 }
33013303
3302- /// Check the consistency of the outermost or-patterns.
3303- fn check_consistent_bindings_top ( & mut self , pat : & ' ast Pat ) {
3304+ /// Check the consistency of bindings wrt or-patterns.
3305+ fn check_consistent_bindings ( & mut self , pat : & ' ast Pat ) {
33043306 pat. walk ( & mut |pat| match pat. kind {
33053307 PatKind :: Or ( ref ps) => {
3306- self . check_consistent_bindings ( ps) ;
3308+ let _ = self . compute_and_check_or_pat_binding_map ( ps) ;
33073309 false
33083310 }
33093311 _ => true ,
@@ -3336,7 +3338,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
33363338 visit:: walk_pat ( self , pat) ;
33373339 self . resolve_pattern_inner ( pat, pat_src, bindings) ;
33383340 // This has to happen *after* we determine which pat_idents are variants:
3339- self . check_consistent_bindings_top ( pat) ;
3341+ self . check_consistent_bindings ( pat) ;
33403342 }
33413343
33423344 /// Resolve bindings in a pattern. This is a helper to `resolve_pattern`.
0 commit comments