@@ -3190,11 +3190,11 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
3190
3190
self . resolve_pattern_top ( & local. pat , PatternSource :: Let ) ;
3191
3191
}
3192
3192
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 > {
3198
3198
let mut binding_map = FxIndexMap :: default ( ) ;
3199
3199
3200
3200
pat. walk ( & mut |pat| {
@@ -3207,9 +3207,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
3207
3207
PatKind :: Or ( ref ps) => {
3208
3208
// Check the consistency of this or-pattern and
3209
3209
// 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) ;
3213
3212
return false ;
3214
3213
}
3215
3214
_ => { }
@@ -3228,18 +3227,19 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
3228
3227
)
3229
3228
}
3230
3229
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 (
3234
3234
& mut self ,
3235
3235
pats : & [ P < Pat > ] ,
3236
- ) -> Vec < FxIndexMap < Ident , BindingInfo > > {
3237
- // pats is consistent.
3236
+ ) -> FxIndexMap < Ident , BindingInfo > {
3238
3237
let mut missing_vars = FxIndexMap :: default ( ) ;
3239
3238
let mut inconsistent_vars = FxIndexMap :: default ( ) ;
3240
3239
3241
3240
// 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 < _ > > ( ) ;
3243
3243
3244
3244
// 2) Record any missing bindings or binding mode inconsistencies.
3245
3245
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> {
3248
3248
. iter ( )
3249
3249
. zip ( pats. iter ( ) )
3250
3250
. 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) ;
3255
3252
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) {
3258
3256
None => {
3259
3257
// The inner binding is missing in the outer.
3260
3258
let binding_error =
@@ -3295,15 +3293,19 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
3295
3293
self . report_error ( v. 0 , ResolutionError :: VariableBoundWithDifferentMode ( name, v. 1 ) ) ;
3296
3294
}
3297
3295
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
3300
3302
}
3301
3303
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 ) {
3304
3306
pat. walk ( & mut |pat| match pat. kind {
3305
3307
PatKind :: Or ( ref ps) => {
3306
- self . check_consistent_bindings ( ps) ;
3308
+ let _ = self . compute_and_check_or_pat_binding_map ( ps) ;
3307
3309
false
3308
3310
}
3309
3311
_ => true ,
@@ -3336,7 +3338,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
3336
3338
visit:: walk_pat ( self , pat) ;
3337
3339
self . resolve_pattern_inner ( pat, pat_src, bindings) ;
3338
3340
// 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) ;
3340
3342
}
3341
3343
3342
3344
/// Resolve bindings in a pattern. This is a helper to `resolve_pattern`.
0 commit comments