Skip to content

Commit b31735a

Browse files
committed
Tweak binding map computation
1 parent 342ea15 commit b31735a

File tree

1 file changed

+28
-26
lines changed

1 file changed

+28
-26
lines changed

compiler/rustc_resolve/src/late.rs

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)