Skip to content

Commit bf64232

Browse files
committed
Auto merge of #89016 - lcnr:non_blanket_impls, r=nikomatsakis,michaelwoerister
fix non_blanket_impls iteration order We sometimes iterate over all `non_blanket_impls`, not sure if this is observable outside of error messages (i.e. as incremental bugs). This should fix the underlying issue of #86986. second attempt of #88718 r? `@nikomatsakis`
2 parents 0132f82 + 01bcddb commit bf64232

File tree

8 files changed

+43
-118
lines changed

8 files changed

+43
-118
lines changed

compiler/rustc_metadata/src/dependency_format.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ fn attempt_static(tcx: TyCtxt<'_>) -> Option<DependencyList> {
277277
let all_crates_available_as_rlib = tcx
278278
.crates(())
279279
.iter()
280-
.cloned()
280+
.copied()
281281
.filter_map(|cnum| {
282282
if tcx.dep_kind(cnum).macros_only() {
283283
return None;
@@ -291,10 +291,11 @@ fn attempt_static(tcx: TyCtxt<'_>) -> Option<DependencyList> {
291291

292292
// All crates are available in an rlib format, so we're just going to link
293293
// everything in explicitly so long as it's actually required.
294-
let last_crate = tcx.crates(()).len();
295-
let mut ret = (1..last_crate + 1)
296-
.map(|cnum| {
297-
if tcx.dep_kind(CrateNum::new(cnum)) == CrateDepKind::Explicit {
294+
let mut ret = tcx
295+
.crates(())
296+
.iter()
297+
.map(|&cnum| {
298+
if tcx.dep_kind(cnum) == CrateDepKind::Explicit {
298299
Linkage::Static
299300
} else {
300301
Linkage::NotLinked

compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs

+20-34
Original file line numberDiff line numberDiff line change
@@ -304,17 +304,7 @@ pub fn provide(providers: &mut Providers) {
304304
// traversal, but not globally minimal across all crates.
305305
let bfs_queue = &mut VecDeque::new();
306306

307-
// Preferring shortest paths alone does not guarantee a
308-
// deterministic result; so sort by crate num to avoid
309-
// hashtable iteration non-determinism. This only makes
310-
// things as deterministic as crate-nums assignment is,
311-
// which is to say, its not deterministic in general. But
312-
// we believe that libstd is consistently assigned crate
313-
// num 1, so it should be enough to resolve #46112.
314-
let mut crates: Vec<CrateNum> = (*tcx.crates(())).to_owned();
315-
crates.sort();
316-
317-
for &cnum in crates.iter() {
307+
for &cnum in tcx.crates(()) {
318308
// Ignore crates without a corresponding local `extern crate` item.
319309
if tcx.missing_extern_crate_item(cnum) {
320310
continue;
@@ -323,35 +313,31 @@ pub fn provide(providers: &mut Providers) {
323313
bfs_queue.push_back(DefId { krate: cnum, index: CRATE_DEF_INDEX });
324314
}
325315

326-
// (restrict scope of mutable-borrow of `visible_parent_map`)
327-
{
328-
let visible_parent_map = &mut visible_parent_map;
329-
let mut add_child = |bfs_queue: &mut VecDeque<_>, child: &Export, parent: DefId| {
330-
if child.vis != ty::Visibility::Public {
331-
return;
332-
}
316+
let mut add_child = |bfs_queue: &mut VecDeque<_>, child: &Export, parent: DefId| {
317+
if child.vis != ty::Visibility::Public {
318+
return;
319+
}
333320

334-
if let Some(child) = child.res.opt_def_id() {
335-
match visible_parent_map.entry(child) {
336-
Entry::Occupied(mut entry) => {
337-
// If `child` is defined in crate `cnum`, ensure
338-
// that it is mapped to a parent in `cnum`.
339-
if child.is_local() && entry.get().is_local() {
340-
entry.insert(parent);
341-
}
342-
}
343-
Entry::Vacant(entry) => {
321+
if let Some(child) = child.res.opt_def_id() {
322+
match visible_parent_map.entry(child) {
323+
Entry::Occupied(mut entry) => {
324+
// If `child` is defined in crate `cnum`, ensure
325+
// that it is mapped to a parent in `cnum`.
326+
if child.is_local() && entry.get().is_local() {
344327
entry.insert(parent);
345-
bfs_queue.push_back(child);
346328
}
347329
}
330+
Entry::Vacant(entry) => {
331+
entry.insert(parent);
332+
bfs_queue.push_back(child);
333+
}
348334
}
349-
};
335+
}
336+
};
350337

351-
while let Some(def) = bfs_queue.pop_front() {
352-
for child in tcx.item_children(def).iter() {
353-
add_child(bfs_queue, child, def);
354-
}
338+
while let Some(def) = bfs_queue.pop_front() {
339+
for child in tcx.item_children(def).iter() {
340+
add_child(bfs_queue, child, def);
355341
}
356342
}
357343

compiler/rustc_metadata/src/rmeta/encoder.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -1708,9 +1708,10 @@ impl EncodeContext<'a, 'tcx> {
17081708

17091709
fn encode_crate_deps(&mut self) -> Lazy<[CrateDep]> {
17101710
empty_proc_macro!(self);
1711-
let crates = self.tcx.crates(());
17121711

1713-
let mut deps = crates
1712+
let deps = self
1713+
.tcx
1714+
.crates(())
17141715
.iter()
17151716
.map(|&cnum| {
17161717
let dep = CrateDep {
@@ -1724,8 +1725,6 @@ impl EncodeContext<'a, 'tcx> {
17241725
})
17251726
.collect::<Vec<_>>();
17261727

1727-
deps.sort_by_key(|&(cnum, _)| cnum);
1728-
17291728
{
17301729
// Sanity-check the crate numbers
17311730
let mut expected_cnum = 1;

compiler/rustc_middle/src/ich/hcx.rs

+2-41
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use crate::ich;
22
use crate::middle::cstore::CrateStore;
3-
use crate::ty::{fast_reject, TyCtxt};
3+
use crate::ty::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;
@@ -14,9 +14,6 @@ use rustc_span::source_map::SourceMap;
1414
use rustc_span::symbol::Symbol;
1515
use rustc_span::{BytePos, CachingSourceMapView, SourceFile, Span, SpanData};
1616

17-
use smallvec::SmallVec;
18-
use std::cmp::Ord;
19-
2017
fn compute_ignored_attr_names() -> FxHashSet<Symbol> {
2118
debug_assert!(!ich::IGNORED_ATTRIBUTES.is_empty());
2219
ich::IGNORED_ATTRIBUTES.iter().copied().collect()
@@ -241,39 +238,3 @@ impl<'a> rustc_span::HashStableContext for StableHashingContext<'a> {
241238
}
242239

243240
impl rustc_session::HashStableContext for StableHashingContext<'a> {}
244-
245-
pub fn hash_stable_trait_impls<'a>(
246-
hcx: &mut StableHashingContext<'a>,
247-
hasher: &mut StableHasher,
248-
blanket_impls: &[DefId],
249-
non_blanket_impls: &FxHashMap<fast_reject::SimplifiedType, Vec<DefId>>,
250-
) {
251-
{
252-
let mut blanket_impls: SmallVec<[_; 8]> =
253-
blanket_impls.iter().map(|&def_id| hcx.def_path_hash(def_id)).collect();
254-
255-
if blanket_impls.len() > 1 {
256-
blanket_impls.sort_unstable();
257-
}
258-
259-
blanket_impls.hash_stable(hcx, hasher);
260-
}
261-
262-
{
263-
let mut keys: SmallVec<[_; 8]> =
264-
non_blanket_impls.keys().map(|k| (k, k.map_def(|d| hcx.def_path_hash(d)))).collect();
265-
keys.sort_unstable_by(|&(_, ref k1), &(_, ref k2)| k1.cmp(k2));
266-
keys.len().hash_stable(hcx, hasher);
267-
for (key, ref stable_key) in keys {
268-
stable_key.hash_stable(hcx, hasher);
269-
let mut impls: SmallVec<[_; 8]> =
270-
non_blanket_impls[key].iter().map(|&impl_id| hcx.def_path_hash(impl_id)).collect();
271-
272-
if impls.len() > 1 {
273-
impls.sort_unstable();
274-
}
275-
276-
impls.hash_stable(hcx, hasher);
277-
}
278-
}
279-
}

compiler/rustc_middle/src/ich/mod.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
//! ICH - Incremental Compilation Hash
22
3-
pub use self::hcx::{
4-
hash_stable_trait_impls, NodeIdHashingMode, StableHashingContext, StableHashingContextProvider,
5-
};
3+
pub use self::hcx::{NodeIdHashingMode, StableHashingContext, StableHashingContextProvider};
64
use rustc_span::symbol::{sym, Symbol};
75

86
mod hcx;

compiler/rustc_middle/src/traits/specialization_graph.rs

+4-14
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
use crate::ich::{self, StableHashingContext};
21
use crate::ty::fast_reject::SimplifiedType;
32
use crate::ty::fold::TypeFoldable;
43
use crate::ty::{self, TyCtxt};
5-
use rustc_data_structures::fx::FxHashMap;
6-
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
4+
use rustc_data_structures::fx::FxIndexMap;
75
use rustc_errors::ErrorReported;
86
use rustc_hir::def_id::{DefId, DefIdMap};
97
use rustc_span::symbol::Ident;
@@ -50,19 +48,19 @@ impl Graph {
5048

5149
/// Children of a given impl, grouped into blanket/non-blanket varieties as is
5250
/// done in `TraitDef`.
53-
#[derive(Default, TyEncodable, TyDecodable, Debug)]
51+
#[derive(Default, TyEncodable, TyDecodable, Debug, HashStable)]
5452
pub struct Children {
5553
// Impls of a trait (or specializations of a given impl). To allow for
5654
// quicker lookup, the impls are indexed by a simplified version of their
5755
// `Self` type: impls with a simplifiable `Self` are stored in
58-
// `nonblanket_impls` keyed by it, while all other impls are stored in
56+
// `non_blanket_impls` keyed by it, while all other impls are stored in
5957
// `blanket_impls`.
6058
//
6159
// A similar division is used within `TraitDef`, but the lists there collect
6260
// together *all* the impls for a trait, and are populated prior to building
6361
// the specialization graph.
6462
/// Impls of the trait.
65-
pub nonblanket_impls: FxHashMap<SimplifiedType, Vec<DefId>>,
63+
pub non_blanket_impls: FxIndexMap<SimplifiedType, Vec<DefId>>,
6664

6765
/// Blanket impls associated with the trait.
6866
pub blanket_impls: Vec<DefId>,
@@ -235,11 +233,3 @@ pub fn ancestors(
235233
})
236234
}
237235
}
238-
239-
impl<'a> HashStable<StableHashingContext<'a>> for Children {
240-
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
241-
let Children { ref nonblanket_impls, ref blanket_impls } = *self;
242-
243-
ich::hash_stable_trait_impls(hcx, hasher, blanket_impls, nonblanket_impls);
244-
}
245-
}

compiler/rustc_middle/src/ty/trait_def.rs

+3-13
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use crate::ich::{self, StableHashingContext};
21
use crate::traits::specialization_graph;
32
use crate::ty::fast_reject;
43
use crate::ty::fold::TypeFoldable;
@@ -7,8 +6,7 @@ use rustc_hir as hir;
76
use rustc_hir::def_id::DefId;
87
use rustc_hir::definitions::DefPathHash;
98

10-
use rustc_data_structures::fx::FxHashMap;
11-
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
9+
use rustc_data_structures::fx::FxIndexMap;
1210
use rustc_errors::ErrorReported;
1311
use rustc_macros::HashStable;
1412

@@ -66,11 +64,11 @@ pub enum TraitSpecializationKind {
6664
AlwaysApplicable,
6765
}
6866

69-
#[derive(Default, Debug)]
67+
#[derive(Default, Debug, HashStable)]
7068
pub struct TraitImpls {
7169
blanket_impls: Vec<DefId>,
7270
/// Impls indexed by their simplified self type, for fast lookup.
73-
non_blanket_impls: FxHashMap<fast_reject::SimplifiedType, Vec<DefId>>,
71+
non_blanket_impls: FxIndexMap<fast_reject::SimplifiedType, Vec<DefId>>,
7472
}
7573

7674
impl TraitImpls {
@@ -249,11 +247,3 @@ pub(super) fn trait_impls_of_provider(tcx: TyCtxt<'_>, trait_id: DefId) -> Trait
249247

250248
impls
251249
}
252-
253-
impl<'a> HashStable<StableHashingContext<'a>> for TraitImpls {
254-
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
255-
let TraitImpls { ref blanket_impls, ref non_blanket_impls } = *self;
256-
257-
ich::hash_stable_trait_impls(hcx, hasher, blanket_impls, non_blanket_impls);
258-
}
259-
}

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

+4-4
Original file line numberDiff line numberDiff line change
@@ -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.non_blanket_impls.entry(st).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.non_blanket_impls.get_mut(&st).unwrap();
6969
} else {
7070
debug!("remove_existing: impl_def_id={:?} st=None", impl_def_id);
7171
vec = &mut self.blanket_impls;
@@ -218,15 +218,15 @@ impl ChildrenExt for Children {
218218
}
219219

220220
fn iter_children(children: &mut Children) -> impl Iterator<Item = DefId> + '_ {
221-
let nonblanket = children.nonblanket_impls.iter_mut().flat_map(|(_, v)| v.iter());
221+
let nonblanket = children.non_blanket_impls.iter().flat_map(|(_, v)| v.iter());
222222
children.blanket_impls.iter().chain(nonblanket).cloned()
223223
}
224224

225225
fn filtered_children(
226226
children: &mut Children,
227227
st: SimplifiedType,
228228
) -> impl Iterator<Item = DefId> + '_ {
229-
let nonblanket = children.nonblanket_impls.entry(st).or_default().iter();
229+
let nonblanket = children.non_blanket_impls.entry(st).or_default().iter();
230230
children.blanket_impls.iter().chain(nonblanket).cloned()
231231
}
232232

0 commit comments

Comments
 (0)