Skip to content

Commit fb6d10d

Browse files
committed
Tweak binding map computation
1 parent 6d53602 commit fb6d10d

File tree

1 file changed

+28
-26
lines changed

1 file changed

+28
-26
lines changed

compiler/rustc_resolve/src/late.rs

+28-26
Original file line numberDiff line numberDiff line change
@@ -3181,11 +3181,11 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
31813181
self.resolve_pattern_top(&local.pat, PatternSource::Let);
31823182
}
31833183

3184-
/// build a map from pattern identifiers to binding-info's.
3185-
/// this is done hygienically. This could arise for a macro
3186-
/// that expands into an or-pattern where one 'x' was from the
3187-
/// user and one 'x' came from the macro.
3188-
fn binding_mode_map(&mut self, pat: &Pat) -> FxIndexMap<Ident, BindingInfo> {
3184+
/// Build a map from pattern identifiers to binding-info's, and check the bindings are
3185+
/// consistent when encountering or-patterns.
3186+
/// This is done hygienically: this could arise for a macro that expands into an or-pattern
3187+
/// where one 'x' was from the user and one 'x' came from the macro.
3188+
fn compute_and_check_binding_map(&mut self, pat: &Pat) -> FxIndexMap<Ident, BindingInfo> {
31893189
let mut binding_map = FxIndexMap::default();
31903190

31913191
pat.walk(&mut |pat| {
@@ -3198,9 +3198,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
31983198
PatKind::Or(ref ps) => {
31993199
// Check the consistency of this or-pattern and
32003200
// then add all bindings to the larger map.
3201-
for bm in self.check_consistent_bindings(ps) {
3202-
binding_map.extend(bm);
3203-
}
3201+
let bm = self.compute_and_check_or_pat_binding_map(ps);
3202+
binding_map.extend(bm);
32043203
return false;
32053204
}
32063205
_ => {}
@@ -3219,18 +3218,19 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
32193218
)
32203219
}
32213220

3222-
/// Checks that all of the arms in an or-pattern have exactly the
3223-
/// same set of bindings, with the same binding modes for each.
3224-
fn check_consistent_bindings(
3221+
/// Compute the binding map for an or-pattern. Checks that all of the arms in the or-pattern
3222+
/// have exactly the same set of bindings, with the same binding modes for each.
3223+
/// Returns the computed binding map.
3224+
fn compute_and_check_or_pat_binding_map(
32253225
&mut self,
32263226
pats: &[P<Pat>],
3227-
) -> Vec<FxIndexMap<Ident, BindingInfo>> {
3228-
// pats is consistent.
3227+
) -> FxIndexMap<Ident, BindingInfo> {
32293228
let mut missing_vars = FxIndexMap::default();
32303229
let mut inconsistent_vars = FxIndexMap::default();
32313230

32323231
// 1) Compute the binding maps of all arms.
3233-
let maps = pats.iter().map(|pat| self.binding_mode_map(pat)).collect::<Vec<_>>();
3232+
let maps =
3233+
pats.iter().map(|pat| self.compute_and_check_binding_map(pat)).collect::<Vec<_>>();
32343234

32353235
// 2) Record any missing bindings or binding mode inconsistencies.
32363236
for (map_outer, pat_outer) in maps.iter().zip(pats.iter()) {
@@ -3239,13 +3239,11 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
32393239
.iter()
32403240
.zip(pats.iter())
32413241
.filter(|(_, pat)| pat.id != pat_outer.id)
3242-
.flat_map(|(map, _)| map)
3243-
.map(|(key, binding)| (key.name, map_outer.get(key), binding));
3244-
3245-
let inners = inners.collect::<Vec<_>>();
3242+
.flat_map(|(map, _)| map);
32463243

3247-
for (name, info, &binding_inner) in inners {
3248-
match info {
3244+
for (key, binding_inner) in inners {
3245+
let name = key.name;
3246+
match map_outer.get(key) {
32493247
None => {
32503248
// The inner binding is missing in the outer.
32513249
let binding_error =
@@ -3286,15 +3284,19 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
32863284
self.report_error(v.0, ResolutionError::VariableBoundWithDifferentMode(name, v.1));
32873285
}
32883286

3289-
// 5) Finally bubble up all the binding maps.
3290-
maps
3287+
// 5) Bubble up the final binding map.
3288+
let mut binding_map = FxIndexMap::default();
3289+
for bm in maps {
3290+
binding_map.extend(bm);
3291+
}
3292+
binding_map
32913293
}
32923294

3293-
/// Check the consistency of the outermost or-patterns.
3294-
fn check_consistent_bindings_top(&mut self, pat: &'ast Pat) {
3295+
/// Check the consistency of bindings wrt or-patterns.
3296+
fn check_consistent_bindings(&mut self, pat: &'ast Pat) {
32953297
pat.walk(&mut |pat| match pat.kind {
32963298
PatKind::Or(ref ps) => {
3297-
self.check_consistent_bindings(ps);
3299+
let _ = self.compute_and_check_or_pat_binding_map(ps);
32983300
false
32993301
}
33003302
_ => true,
@@ -3327,7 +3329,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
33273329
visit::walk_pat(self, pat);
33283330
self.resolve_pattern_inner(pat, pat_src, bindings);
33293331
// This has to happen *after* we determine which pat_idents are variants:
3330-
self.check_consistent_bindings_top(pat);
3332+
self.check_consistent_bindings(pat);
33313333
}
33323334

33333335
/// Resolve bindings in a pattern. This is a helper to `resolve_pattern`.

0 commit comments

Comments
 (0)