Skip to content

Commit 0ecb033

Browse files
committed
Try to sort bindings before usage to have a stable result
The `FxIndexMap` solution seems costly.
1 parent f09b6a8 commit 0ecb033

File tree

2 files changed

+36
-10
lines changed

2 files changed

+36
-10
lines changed

compiler/rustc_resolve/src/late.rs

+10-6
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ impl RibKind<'_> {
259259
/// resolving, the name is looked up from inside out.
260260
#[derive(Debug)]
261261
pub(crate) struct Rib<'ra, R = Res> {
262-
pub bindings: FxIndexMap<Ident, R>,
262+
pub bindings: FxHashMap<Ident, R>,
263263
pub kind: RibKind<'ra>,
264264
}
265265

@@ -1548,7 +1548,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
15481548
// Allow all following defaults to refer to this type parameter.
15491549
forward_ty_ban_rib
15501550
.bindings
1551-
.shift_remove(&Ident::with_dummy_span(param.ident.name));
1551+
.remove(&Ident::with_dummy_span(param.ident.name));
15521552
}
15531553
GenericParamKind::Const { ref ty, kw_span: _, ref default } => {
15541554
// Const parameters can't have param bounds.
@@ -1576,7 +1576,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
15761576
// Allow all following defaults to refer to this const parameter.
15771577
forward_const_ban_rib
15781578
.bindings
1579-
.shift_remove(&Ident::with_dummy_span(param.ident.name));
1579+
.remove(&Ident::with_dummy_span(param.ident.name));
15801580
}
15811581
}
15821582
}
@@ -2795,8 +2795,12 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
27952795
break;
27962796
}
27972797

2798-
seen_bindings
2799-
.extend(parent_rib.bindings.keys().map(|ident| (*ident, ident.span)));
2798+
// It is sorted before usage so ordering is not important here.
2799+
#[allow(rustc::potential_query_instability)]
2800+
let mut idents: Vec<_> = parent_rib.bindings.keys().into_iter().collect();
2801+
idents.sort_by_key(|&ident| ident.span);
2802+
2803+
seen_bindings.extend(idents.into_iter().map(|ident| (*ident, ident.span)));
28002804
}
28012805
}
28022806

@@ -3868,7 +3872,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
38683872
}
38693873
}
38703874

3871-
fn innermost_rib_bindings(&mut self, ns: Namespace) -> &mut FxIndexMap<Ident, Res> {
3875+
fn innermost_rib_bindings(&mut self, ns: Namespace) -> &mut FxHashMap<Ident, Res> {
38723876
&mut self.ribs[ns].last_mut().unwrap().bindings
38733877
}
38743878

compiler/rustc_resolve/src/late/diagnostics.rs

+26-4
Original file line numberDiff line numberDiff line change
@@ -762,7 +762,12 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
762762
if let Some(rib) = &self.last_block_rib
763763
&& let RibKind::Normal = rib.kind
764764
{
765-
for (ident, &res) in &rib.bindings {
765+
// It is sorted before usage so ordering is not important here.
766+
#[allow(rustc::potential_query_instability)]
767+
let mut bindings: Vec<_> = rib.bindings.clone().into_iter().collect();
768+
bindings.sort_by_key(|(ident, _)| ident.span);
769+
770+
for (ident, res) in &bindings {
766771
if let Res::Local(_) = res
767772
&& path.len() == 1
768773
&& ident.span.eq_ctxt(path[0].ident.span)
@@ -944,7 +949,12 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
944949
if let Some(err_code) = err.code {
945950
if err_code == E0425 {
946951
for label_rib in &self.label_ribs {
947-
for (label_ident, node_id) in &label_rib.bindings {
952+
// It is sorted before usage so ordering is not important here.
953+
#[allow(rustc::potential_query_instability)]
954+
let mut bindings: Vec<_> = label_rib.bindings.clone().into_iter().collect();
955+
bindings.sort_by_key(|(ident, _)| ident.span);
956+
957+
for (label_ident, node_id) in &bindings {
948958
let ident = path.last().unwrap().ident;
949959
if format!("'{ident}") == label_ident.to_string() {
950960
err.span_label(label_ident.span, "a label with a similar name exists");
@@ -2142,6 +2152,8 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
21422152
};
21432153

21442154
// Locals and type parameters
2155+
// `names` is sorted below so ordering is not important here.
2156+
#[allow(rustc::potential_query_instability)]
21452157
for (ident, &res) in &rib.bindings {
21462158
if filter_fn(res) && ident.span.ctxt() == rib_ctxt {
21472159
names.push(TypoSuggestion::typo_from_ident(*ident, res));
@@ -2605,18 +2617,28 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
26052617
let within_scope = self.is_label_valid_from_rib(rib_index);
26062618

26072619
let rib = &self.label_ribs[rib_index];
2608-
let names = rib
2620+
// `names` is sorted below so ordering is not important here.
2621+
#[allow(rustc::potential_query_instability)]
2622+
let mut names = rib
26092623
.bindings
26102624
.iter()
26112625
.filter(|(id, _)| id.span.eq_ctxt(label.span))
26122626
.map(|(id, _)| id.name)
26132627
.collect::<Vec<Symbol>>();
26142628

2629+
// Make sure error reporting is deterministic.
2630+
names.sort();
2631+
26152632
find_best_match_for_name(&names, label.name, None).map(|symbol| {
2633+
// It is sorted before usage so ordering is not important here.
2634+
#[allow(rustc::potential_query_instability)]
2635+
let mut bindings: Vec<_> = rib.bindings.clone().into_iter().collect();
2636+
bindings.sort_by_key(|(ident, _)| ident.span);
2637+
26162638
// Upon finding a similar name, get the ident that it was from - the span
26172639
// contained within helps make a useful diagnostic. In addition, determine
26182640
// whether this candidate is within scope.
2619-
let (ident, _) = rib.bindings.iter().find(|(ident, _)| ident.name == symbol).unwrap();
2641+
let (ident, _) = bindings.iter().find(|(ident, _)| ident.name == symbol).unwrap();
26202642
(*ident, within_scope)
26212643
})
26222644
}

0 commit comments

Comments
 (0)