Skip to content

Commit 3e62c12

Browse files
committed
fix non_blanket_impls iteration order
1 parent 385f8e2 commit 3e62c12

File tree

5 files changed

+37
-29
lines changed

5 files changed

+37
-29
lines changed

compiler/rustc_middle/src/ich/hcx.rs

+7-10
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::middle::cstore::CrateStore;
33
use crate::ty::{fast_reject, TyCtxt};
44

55
use rustc_ast as ast;
6-
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
6+
use rustc_data_structures::fx::FxHashSet;
77
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
88
use rustc_data_structures::sync::Lrc;
99
use rustc_hir as hir;
@@ -15,7 +15,7 @@ use rustc_span::symbol::Symbol;
1515
use rustc_span::{BytePos, CachingSourceMapView, SourceFile, SpanData};
1616

1717
use smallvec::SmallVec;
18-
use std::cmp::Ord;
18+
use std::collections::BTreeMap;
1919

2020
fn compute_ignored_attr_names() -> FxHashSet<Symbol> {
2121
debug_assert!(!ich::IGNORED_ATTRIBUTES.is_empty());
@@ -243,7 +243,7 @@ pub fn hash_stable_trait_impls<'a>(
243243
hcx: &mut StableHashingContext<'a>,
244244
hasher: &mut StableHasher,
245245
blanket_impls: &[DefId],
246-
non_blanket_impls: &FxHashMap<fast_reject::SimplifiedType, Vec<DefId>>,
246+
non_blanket_impls: &BTreeMap<fast_reject::StableSimplifiedType, Vec<DefId>>,
247247
) {
248248
{
249249
let mut blanket_impls: SmallVec<[_; 8]> =
@@ -257,14 +257,11 @@ pub fn hash_stable_trait_impls<'a>(
257257
}
258258

259259
{
260-
let mut keys: SmallVec<[_; 8]> =
261-
non_blanket_impls.keys().map(|k| (k, k.map_def(|d| hcx.def_path_hash(d)))).collect();
262-
keys.sort_unstable_by(|&(_, ref k1), &(_, ref k2)| k1.cmp(k2));
263-
keys.len().hash_stable(hcx, hasher);
264-
for (key, ref stable_key) in keys {
265-
stable_key.hash_stable(hcx, hasher);
260+
non_blanket_impls.len().hash_stable(hcx, hasher);
261+
for (key, impls) in non_blanket_impls.iter() {
262+
key.hash_stable(hcx, hasher);
266263
let mut impls: SmallVec<[_; 8]> =
267-
non_blanket_impls[key].iter().map(|&impl_id| hcx.def_path_hash(impl_id)).collect();
264+
impls.iter().map(|&impl_id| hcx.def_path_hash(impl_id)).collect();
268265

269266
if impls.len() > 1 {
270267
impls.sort_unstable();

compiler/rustc_middle/src/traits/specialization_graph.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
use crate::ich::{self, StableHashingContext};
2-
use crate::ty::fast_reject::SimplifiedType;
2+
use crate::ty::fast_reject::StableSimplifiedType;
33
use crate::ty::fold::TypeFoldable;
44
use crate::ty::{self, TyCtxt};
5-
use rustc_data_structures::fx::FxHashMap;
65
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
76
use rustc_errors::ErrorReported;
87
use rustc_hir::def_id::{DefId, DefIdMap};
98
use rustc_span::symbol::Ident;
9+
use std::collections::BTreeMap;
1010

1111
/// A per-trait graph of impls in specialization order. At the moment, this
1212
/// graph forms a tree rooted with the trait itself, with all other nodes
@@ -62,7 +62,7 @@ pub struct Children {
6262
// together *all* the impls for a trait, and are populated prior to building
6363
// the specialization graph.
6464
/// Impls of the trait.
65-
pub nonblanket_impls: FxHashMap<SimplifiedType, Vec<DefId>>,
65+
pub nonblanket_impls: BTreeMap<StableSimplifiedType, Vec<DefId>>,
6666

6767
/// Blanket impls associated with the trait.
6868
pub blanket_impls: Vec<DefId>,

compiler/rustc_middle/src/ty/fast_reject.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
use crate::ich::StableHashingContext;
22
use crate::ty::{self, Ty, TyCtxt};
33
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
4-
use rustc_hir::def_id::DefId;
4+
use rustc_hir::def_id::{DefId, DefPathHash};
55
use std::fmt::Debug;
66
use std::hash::Hash;
77
use std::mem;
88

99
use self::SimplifiedTypeGen::*;
1010

1111
pub type SimplifiedType = SimplifiedTypeGen<DefId>;
12+
pub type StableSimplifiedType = SimplifiedTypeGen<DefPathHash>;
1213

1314
/// See `simplify_type`
1415
///
@@ -107,6 +108,12 @@ pub fn simplify_type(
107108
}
108109
}
109110

111+
impl SimplifiedType {
112+
pub fn to_stable(self, tcx: TyCtxt<'tcx>) -> StableSimplifiedType {
113+
self.map_def(|def_id| tcx.def_path_hash(def_id))
114+
}
115+
}
116+
110117
impl<D: Copy + Debug + Ord + Eq> SimplifiedTypeGen<D> {
111118
pub fn map_def<U, F>(self, map: F) -> SimplifiedTypeGen<U>
112119
where

compiler/rustc_middle/src/ty/trait_def.rs

+11-8
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,13 @@ use crate::traits::specialization_graph;
33
use crate::ty::fast_reject;
44
use crate::ty::fold::TypeFoldable;
55
use crate::ty::{Ty, TyCtxt};
6+
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
7+
use rustc_errors::ErrorReported;
68
use rustc_hir as hir;
79
use rustc_hir::def_id::DefId;
810
use rustc_hir::definitions::DefPathHash;
9-
10-
use rustc_data_structures::fx::FxHashMap;
11-
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
12-
use rustc_errors::ErrorReported;
1311
use rustc_macros::HashStable;
12+
use std::collections::BTreeMap;
1413

1514
/// A trait's definition with type information.
1615
#[derive(HashStable)]
@@ -70,7 +69,7 @@ pub enum TraitSpecializationKind {
7069
pub struct TraitImpls {
7170
blanket_impls: Vec<DefId>,
7271
/// Impls indexed by their simplified self type, for fast lookup.
73-
non_blanket_impls: FxHashMap<fast_reject::SimplifiedType, Vec<DefId>>,
72+
non_blanket_impls: BTreeMap<fast_reject::StableSimplifiedType, Vec<DefId>>,
7473
}
7574

7675
impl TraitImpls {
@@ -182,7 +181,7 @@ impl<'tcx> TyCtxt<'tcx> {
182181
//
183182
// I think we'll cross that bridge when we get to it.
184183
if let Some(simp) = fast_reject::simplify_type(self, self_ty, true) {
185-
if let Some(impls) = impls.non_blanket_impls.get(&simp) {
184+
if let Some(impls) = impls.non_blanket_impls.get(&simp.to_stable(self)) {
186185
for &impl_def_id in impls {
187186
if let result @ Some(_) = f(impl_def_id) {
188187
return result;
@@ -222,7 +221,7 @@ pub(super) fn trait_impls_of_provider(tcx: TyCtxt<'_>, trait_id: DefId) -> Trait
222221
if let Some(simplified_self_ty) = simplified_self_ty {
223222
impls
224223
.non_blanket_impls
225-
.entry(simplified_self_ty)
224+
.entry(simplified_self_ty.to_stable(tcx))
226225
.or_default()
227226
.push(impl_def_id);
228227
} else {
@@ -241,7 +240,11 @@ pub(super) fn trait_impls_of_provider(tcx: TyCtxt<'_>, trait_id: DefId) -> Trait
241240
}
242241

243242
if let Some(simplified_self_ty) = fast_reject::simplify_type(tcx, impl_self_ty, false) {
244-
impls.non_blanket_impls.entry(simplified_self_ty).or_default().push(impl_def_id);
243+
impls
244+
.non_blanket_impls
245+
.entry(simplified_self_ty.to_stable(tcx))
246+
.or_default()
247+
.push(impl_def_id);
245248
} else {
246249
impls.blanket_impls.push(impl_def_id);
247250
}

compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs

+8-7
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use super::OverlapError;
22

33
use crate::traits;
44
use rustc_hir::def_id::DefId;
5-
use rustc_middle::ty::fast_reject::{self, SimplifiedType};
5+
use rustc_middle::ty::fast_reject::{self, StableSimplifiedType};
66
use rustc_middle::ty::print::with_no_trimmed_paths;
77
use rustc_middle::ty::{self, TyCtxt, TypeFoldable};
88

@@ -40,7 +40,7 @@ trait ChildrenExt {
4040
&mut self,
4141
tcx: TyCtxt<'tcx>,
4242
impl_def_id: DefId,
43-
simplified_self: Option<SimplifiedType>,
43+
simplified_self: Option<StableSimplifiedType>,
4444
) -> Result<Inserted, OverlapError>;
4545
}
4646

@@ -50,7 +50,7 @@ impl ChildrenExt for Children {
5050
let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
5151
if let Some(st) = fast_reject::simplify_type(tcx, trait_ref.self_ty(), false) {
5252
debug!("insert_blindly: impl_def_id={:?} st={:?}", impl_def_id, st);
53-
self.nonblanket_impls.entry(st).or_default().push(impl_def_id)
53+
self.nonblanket_impls.entry(st.to_stable(tcx)).or_default().push(impl_def_id)
5454
} else {
5555
debug!("insert_blindly: impl_def_id={:?} st=None", impl_def_id);
5656
self.blanket_impls.push(impl_def_id)
@@ -65,7 +65,7 @@ impl ChildrenExt for Children {
6565
let vec: &mut Vec<DefId>;
6666
if let Some(st) = fast_reject::simplify_type(tcx, trait_ref.self_ty(), false) {
6767
debug!("remove_existing: impl_def_id={:?} st={:?}", impl_def_id, st);
68-
vec = self.nonblanket_impls.get_mut(&st).unwrap();
68+
vec = self.nonblanket_impls.get_mut(&st.to_stable(tcx)).unwrap();
6969
} else {
7070
debug!("remove_existing: impl_def_id={:?} st=None", impl_def_id);
7171
vec = &mut self.blanket_impls;
@@ -81,7 +81,7 @@ impl ChildrenExt for Children {
8181
&mut self,
8282
tcx: TyCtxt<'tcx>,
8383
impl_def_id: DefId,
84-
simplified_self: Option<SimplifiedType>,
84+
simplified_self: Option<StableSimplifiedType>,
8585
) -> Result<Inserted, OverlapError> {
8686
let mut last_lint = None;
8787
let mut replace_children = Vec::new();
@@ -222,7 +222,7 @@ fn iter_children(children: &mut Children) -> impl Iterator<Item = DefId> + '_ {
222222

223223
fn filtered_children(
224224
children: &mut Children,
225-
st: SimplifiedType,
225+
st: StableSimplifiedType,
226226
) -> impl Iterator<Item = DefId> + '_ {
227227
let nonblanket = children.nonblanket_impls.entry(st).or_default().iter();
228228
children.blanket_impls.iter().chain(nonblanket).cloned()
@@ -304,7 +304,8 @@ impl GraphExt for Graph {
304304

305305
let mut parent = trait_def_id;
306306
let mut last_lint = None;
307-
let simplified = fast_reject::simplify_type(tcx, trait_ref.self_ty(), false);
307+
let simplified =
308+
fast_reject::simplify_type(tcx, trait_ref.self_ty(), false).map(|st| st.to_stable(tcx));
308309

309310
// Descend the specialization tree, where `parent` is the current parent node.
310311
loop {

0 commit comments

Comments
 (0)