Rollup merge of #114454 - Nilstrieb:no-evil-sorting, r=cjgillot
Replace `HashMap` with `IndexMap` in pattern binding resolve fixes https://github.com/rust-lang/rust/pull/114332#discussion_r1284189179
This commit is contained in:
commit
af77806bee
4 changed files with 98 additions and 100 deletions
|
@ -41,9 +41,6 @@ type Res = def::Res<NodeId>;
|
|||
|
||||
type IdentMap<T> = FxHashMap<Ident, T>;
|
||||
|
||||
/// Map from the name in a pattern to its binding mode.
|
||||
type BindingMap = IdentMap<BindingInfo>;
|
||||
|
||||
use diagnostics::{
|
||||
ElisionFnParameter, LifetimeElisionCandidate, MissingLifetime, MissingLifetimeKind,
|
||||
};
|
||||
|
@ -3164,8 +3161,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
|||
/// this is done hygienically. This could arise for a macro
|
||||
/// that expands into an or-pattern where one 'x' was from the
|
||||
/// user and one 'x' came from the macro.
|
||||
fn binding_mode_map(&mut self, pat: &Pat) -> BindingMap {
|
||||
let mut binding_map = FxHashMap::default();
|
||||
fn binding_mode_map(&mut self, pat: &Pat) -> FxIndexMap<Ident, BindingInfo> {
|
||||
let mut binding_map = FxIndexMap::default();
|
||||
|
||||
pat.walk(&mut |pat| {
|
||||
match pat.kind {
|
||||
|
@ -3200,22 +3197,28 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
|||
|
||||
/// Checks that all of the arms in an or-pattern have exactly the
|
||||
/// same set of bindings, with the same binding modes for each.
|
||||
fn check_consistent_bindings(&mut self, pats: &[P<Pat>]) -> Vec<BindingMap> {
|
||||
let mut missing_vars = FxHashMap::default();
|
||||
let mut inconsistent_vars = FxHashMap::default();
|
||||
fn check_consistent_bindings(
|
||||
&mut self,
|
||||
pats: &[P<Pat>],
|
||||
) -> Vec<FxIndexMap<Ident, BindingInfo>> {
|
||||
// pats is consistent.
|
||||
let mut missing_vars = FxIndexMap::default();
|
||||
let mut inconsistent_vars = FxIndexMap::default();
|
||||
|
||||
// 1) Compute the binding maps of all arms.
|
||||
let maps = pats.iter().map(|pat| self.binding_mode_map(pat)).collect::<Vec<_>>();
|
||||
|
||||
// 2) Record any missing bindings or binding mode inconsistencies.
|
||||
for (map_outer, pat_outer) in pats.iter().enumerate().map(|(idx, pat)| (&maps[idx], pat)) {
|
||||
for (map_outer, pat_outer) in maps.iter().zip(pats.iter()) {
|
||||
// Check against all arms except for the same pattern which is always self-consistent.
|
||||
let inners = pats
|
||||
let inners = maps
|
||||
.iter()
|
||||
.enumerate()
|
||||
.zip(pats.iter())
|
||||
.filter(|(_, pat)| pat.id != pat_outer.id)
|
||||
.flat_map(|(idx, _)| maps[idx].iter())
|
||||
.map(|(key, binding)| (key.name, map_outer.get(&key), binding));
|
||||
.flat_map(|(map, _)| map)
|
||||
.map(|(key, binding)| (key.name, map_outer.get(key), binding));
|
||||
|
||||
let inners = inners.collect::<Vec<_>>();
|
||||
|
||||
for (name, info, &binding_inner) in inners {
|
||||
match info {
|
||||
|
@ -3244,10 +3247,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
|||
}
|
||||
|
||||
// 3) Report all missing variables we found.
|
||||
let mut missing_vars = missing_vars.into_iter().collect::<Vec<_>>();
|
||||
missing_vars.sort_by_key(|&(sym, ref _err)| sym);
|
||||
|
||||
for (name, mut v) in missing_vars.into_iter() {
|
||||
for (name, mut v) in missing_vars {
|
||||
if inconsistent_vars.contains_key(&name) {
|
||||
v.could_be_path = false;
|
||||
}
|
||||
|
@ -3258,10 +3258,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
|||
}
|
||||
|
||||
// 4) Report all inconsistencies in binding modes we found.
|
||||
let mut inconsistent_vars = inconsistent_vars.iter().collect::<Vec<_>>();
|
||||
inconsistent_vars.sort();
|
||||
for (name, v) in inconsistent_vars {
|
||||
self.report_error(v.0, ResolutionError::VariableBoundWithDifferentMode(*name, v.1));
|
||||
self.report_error(v.0, ResolutionError::VariableBoundWithDifferentMode(name, v.1));
|
||||
}
|
||||
|
||||
// 5) Finally bubble up all the binding maps.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue