Skip to content

Commit fca9b1a

Browse files
committed
Remove ordering traits from chalk_ir::interner::DefId
Use `indexmap` to obviate need for ordering `DefId`s.
1 parent 977b0a5 commit fca9b1a

File tree

8 files changed

+40
-64
lines changed

8 files changed

+40
-64
lines changed

Cargo.lock

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

chalk-integration/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,4 @@ chalk-solve = { version = "0.76.0-dev.0", path = "../chalk-solve" }
2020
chalk-recursive = { version = "0.76.0-dev.0", path = "../chalk-recursive" }
2121
chalk-engine = { version = "0.76.0-dev.0", path = "../chalk-engine" }
2222
chalk-parse = { version = "0.76.0-dev.0", path = "../chalk-parse" }
23+
indexmap = "1.7.0"

chalk-ir/src/interner.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ use std::sync::Arc;
5757
/// (e.g., `SourceI` and `TargetI`) -- even if those type parameters
5858
/// wind up being mapped to the same underlying type families in the
5959
/// end.
60-
pub trait Interner: Debug + Copy + Eq + Ord + Hash + Sized {
60+
pub trait Interner: Debug + Copy + Eq + Hash + Sized {
6161
/// "Interned" representation of types. In normal user code,
6262
/// `Self::InternedType` is not referenced. Instead, we refer to
6363
/// `Ty<Self>`, which wraps this type.
@@ -188,10 +188,10 @@ pub trait Interner: Debug + Copy + Eq + Ord + Hash + Sized {
188188
type InternedVariances: Debug + Clone + Eq + Hash;
189189

190190
/// The core "id" type used for trait-ids and the like.
191-
type DefId: Debug + Copy + Eq + Ord + Hash;
191+
type DefId: Debug + Copy + Eq + Hash;
192192

193193
/// The ID type for ADTs
194-
type InternedAdtId: Debug + Copy + Eq + Ord + Hash;
194+
type InternedAdtId: Debug + Copy + Eq + Hash;
195195

196196
/// Representation of identifiers.
197197
type Identifier: Debug + Clone + Eq + Hash;

chalk-solve/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ rustc-hash = { version = "1.1.0" }
2020

2121
chalk-derive = { version = "0.76.0-dev.0", path = "../chalk-derive" }
2222
chalk-ir = { version = "0.76.0-dev.0", path = "../chalk-ir" }
23+
indexmap = "1.7.0"
2324

2425
[dev-dependencies]
2526
chalk-integration = { path = "../chalk-integration" }

chalk-solve/src/coherence.rs

+16-10
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ use crate::solve::Solver;
44
use crate::RustIrDatabase;
55
use chalk_ir::interner::Interner;
66
use chalk_ir::{self, ImplId, TraitId};
7-
use std::collections::BTreeMap;
87
use std::fmt;
98
use std::sync::Arc;
109

10+
use indexmap::IndexMap;
11+
1112
pub mod orphan;
1213
mod solve;
1314

@@ -42,13 +43,13 @@ impl<I: Interner> std::error::Error for CoherenceError<I> {}
4243
/// This basically encodes which impls specialize one another.
4344
#[derive(Clone, Debug, Default, PartialEq, Eq)]
4445
pub struct SpecializationPriorities<I: Interner> {
45-
map: BTreeMap<ImplId<I>, SpecializationPriority>,
46+
map: IndexMap<ImplId<I>, SpecializationPriority>,
4647
}
4748

4849
impl<I: Interner> SpecializationPriorities<I> {
4950
pub fn new() -> Self {
5051
Self {
51-
map: BTreeMap::new(),
52+
map: IndexMap::new(),
5253
}
5354
}
5455

@@ -60,8 +61,7 @@ impl<I: Interner> SpecializationPriorities<I> {
6061
/// Store the priority of an impl (used during construction).
6162
/// Panics if we have already stored the priority for this impl.
6263
fn insert(&mut self, impl_id: ImplId<I>, p: SpecializationPriority) {
63-
let old_value = self.map.insert(impl_id, p);
64-
assert!(old_value.is_none());
64+
self.map.insert(impl_id, p);
6565
}
6666
}
6767

@@ -106,18 +106,24 @@ where
106106

107107
// Build the forest of specialization relationships.
108108
fn build_specialization_forest(&self) -> Result<Graph<ImplId<I>, ()>, CoherenceError<I>> {
109-
// The forest is returned as a graph but built as a GraphMap; this is
110-
// so that we never add multiple nodes with the same ItemId.
111-
let mut forest = DiGraphMap::new();
109+
let mut forest = DiGraph::new();
110+
111+
let node_impls: Vec<ImplId<_>> = forest.raw_nodes().iter().map(|x| x.weight).collect();
112112

113113
// Find all specializations (implemented in coherence/solve)
114114
// Record them in the forest by adding an edge from the less special
115115
// to the more special.
116116
self.visit_specializations_of_trait(|less_special, more_special| {
117-
forest.add_edge(less_special, more_special, ());
117+
// Check so that we never add multiple nodes with the same ImplId.
118+
if !node_impls.contains(&less_special) && !node_impls.contains(&more_special) {
119+
let l = forest.add_node(less_special);
120+
let m = forest.add_node(more_special);
121+
122+
forest.add_edge(l, m, ());
123+
}
118124
})?;
119125

120-
Ok(forest.into_graph())
126+
Ok(forest)
121127
}
122128

123129
// Recursively set priorities for those node and all of its children.

chalk-solve/src/display/state.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
//! Persistent state passed down between writers.
21
//!
32
//! This is essentially `InternalWriterState` and other things supporting that.
43
use std::{
@@ -12,6 +11,7 @@ use std::{
1211

1312
use crate::RustIrDatabase;
1413
use chalk_ir::{interner::Interner, *};
14+
use indexmap::IndexMap;
1515
use itertools::Itertools;
1616

1717
/// Like a BoundVar, but with the debrujin index inverted so as to create a
@@ -36,31 +36,31 @@ impl Display for InvertedBoundVar {
3636
}
3737
}
3838

39-
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
39+
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
4040
enum UnifiedId<I: Interner> {
4141
AdtId(I::InternedAdtId),
4242
DefId(I::DefId),
4343
}
4444

4545
#[derive(Debug)]
46-
pub struct IdAliasStore<T: Ord> {
46+
pub struct IdAliasStore<T> {
4747
/// Map from the DefIds we've encountered to a u32 alias id unique to all ids
4848
/// the same name.
49-
aliases: BTreeMap<T, u32>,
49+
aliases: IndexMap<T, u32>,
5050
/// Map from each name to the next unused u32 alias id.
5151
next_unused_for_name: BTreeMap<String, u32>,
5252
}
5353

54-
impl<T: Ord> Default for IdAliasStore<T> {
54+
impl<T> Default for IdAliasStore<T> {
5555
fn default() -> Self {
5656
IdAliasStore {
57-
aliases: BTreeMap::default(),
57+
aliases: IndexMap::default(),
5858
next_unused_for_name: BTreeMap::default(),
5959
}
6060
}
6161
}
6262

63-
impl<T: Copy + Ord> IdAliasStore<T> {
63+
impl<T: Copy + Eq + core::hash::Hash> IdAliasStore<T> {
6464
fn alias_for_id_name(&mut self, id: T, name: String) -> String {
6565
let next_unused_for_name = &mut self.next_unused_for_name;
6666
let alias = *self.aliases.entry(id).or_insert_with(|| {

chalk-solve/src/logging_db.rs

+4-39
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
//! `.chalk` files containing those definitions.
33
use std::{
44
borrow::Borrow,
5-
cmp::{Ord, Ordering},
6-
collections::BTreeSet,
75
fmt::{self, Debug, Display},
86
io::Write,
97
marker::PhantomData,
@@ -18,6 +16,8 @@ use crate::{
1816
};
1917
use chalk_ir::{interner::Interner, *};
2018

19+
use indexmap::IndexSet;
20+
2121
mod id_collector;
2222

2323
/// Wraps another `RustIrDatabase` (`DB`) and records which definitions are
@@ -36,7 +36,7 @@ where
3636
I: Interner,
3737
{
3838
ws: WriterState<I, DB, P>,
39-
def_ids: Mutex<BTreeSet<RecordedItemId<I>>>,
39+
def_ids: Mutex<IndexSet<RecordedItemId<I>>>,
4040
_phantom: PhantomData<DB>,
4141
}
4242

@@ -535,7 +535,7 @@ where
535535
}
536536
}
537537

538-
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
538+
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
539539
pub enum RecordedItemId<I: Interner> {
540540
Adt(AdtId<I>),
541541
Trait(TraitId<I>),
@@ -580,38 +580,3 @@ impl<I: Interner> From<GeneratorId<I>> for RecordedItemId<I> {
580580
RecordedItemId::Generator(v)
581581
}
582582
}
583-
584-
/// Utility for implementing Ord for RecordedItemId.
585-
#[derive(PartialEq, Eq, PartialOrd, Ord)]
586-
enum OrderedItemId<'a, DefId, AdtId> {
587-
DefId(&'a DefId),
588-
AdtId(&'a AdtId),
589-
}
590-
591-
impl<I: Interner> RecordedItemId<I> {
592-
/// Extract internal identifier. Allows for absolute ordering matching the
593-
/// order in which chalk saw things (and thus reproducing that order in
594-
/// printed programs)
595-
fn ordered_item_id(&self) -> OrderedItemId<'_, I::DefId, I::InternedAdtId> {
596-
match self {
597-
RecordedItemId::Trait(TraitId(x))
598-
| RecordedItemId::Impl(ImplId(x))
599-
| RecordedItemId::OpaqueTy(OpaqueTyId(x))
600-
| RecordedItemId::Generator(GeneratorId(x))
601-
| RecordedItemId::FnDef(FnDefId(x)) => OrderedItemId::DefId(x),
602-
RecordedItemId::Adt(AdtId(x)) => OrderedItemId::AdtId(x),
603-
}
604-
}
605-
}
606-
607-
impl<I: Interner> PartialOrd for RecordedItemId<I> {
608-
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
609-
Some(self.cmp(other))
610-
}
611-
}
612-
613-
impl<I: Interner> Ord for RecordedItemId<I> {
614-
fn cmp(&self, other: &Self) -> Ordering {
615-
self.ordered_item_id().cmp(&other.ordered_item_id())
616-
}
617-
}

chalk-solve/src/logging_db/id_collector.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ use chalk_ir::{
66
visit::{SuperVisit, Visit},
77
AliasTy, DebruijnIndex, TyKind, WhereClause,
88
};
9-
use std::collections::BTreeSet;
109
use std::ops::ControlFlow;
1110

11+
use indexmap::IndexSet;
12+
1213
/// Collects the identifiers needed to resolve all the names for a given
1314
/// set of identifers, excluding identifiers we already have.
1415
///
@@ -34,11 +35,11 @@ use std::ops::ControlFlow;
3435
/// resolution is successful.
3536
pub fn collect_unrecorded_ids<'i, I: Interner, DB: RustIrDatabase<I>>(
3637
db: &'i DB,
37-
identifiers: &'_ BTreeSet<RecordedItemId<I>>,
38-
) -> BTreeSet<RecordedItemId<I>> {
38+
identifiers: &'_ IndexSet<RecordedItemId<I>>,
39+
) -> IndexSet<RecordedItemId<I>> {
3940
let mut collector = IdCollector {
4041
db,
41-
found_identifiers: BTreeSet::new(),
42+
found_identifiers: IndexSet::new(),
4243
};
4344
for id in identifiers {
4445
match *id {
@@ -96,7 +97,7 @@ pub fn collect_unrecorded_ids<'i, I: Interner, DB: RustIrDatabase<I>>(
9697

9798
struct IdCollector<'i, I: Interner, DB: RustIrDatabase<I>> {
9899
db: &'i DB,
99-
found_identifiers: BTreeSet<RecordedItemId<I>>,
100+
found_identifiers: IndexSet<RecordedItemId<I>>,
100101
}
101102

102103
impl<'i, I: Interner, DB: RustIrDatabase<I>> IdCollector<'i, I, DB> {

0 commit comments

Comments
 (0)