Skip to content

Commit 29c1d17

Browse files
committed
Remove ordering traits from chalk_ir::interner::DefId
Use `indexmap` to obviate need for ordering `DefId`s. In specialization forest, use a map of ImplIds to node indices to avoid duplicate nodes.
1 parent 1571806 commit 29c1d17

File tree

8 files changed

+41
-64
lines changed

8 files changed

+41
-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-11
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1+
use indexmap::IndexMap;
12
use petgraph::prelude::*;
3+
use rustc_hash::FxHashMap;
24

35
use crate::solve::Solver;
46
use crate::RustIrDatabase;
57
use chalk_ir::interner::Interner;
68
use chalk_ir::{self, ImplId, TraitId};
7-
use std::collections::BTreeMap;
89
use std::fmt;
910
use std::sync::Arc;
1011

@@ -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

@@ -106,18 +107,22 @@ where
106107

107108
// Build the forest of specialization relationships.
108109
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();
110+
let mut forest = DiGraph::new();
111+
let mut node_map = FxHashMap::default();
112112

113-
// Find all specializations (implemented in coherence/solve)
114-
// Record them in the forest by adding an edge from the less special
115-
// to the more special.
113+
// Find all specializations. Record them in the forest
114+
// by adding an edge from the less special to the more special.
116115
self.visit_specializations_of_trait(|less_special, more_special| {
117-
forest.add_edge(less_special, more_special, ());
116+
let less_special_node = *node_map
117+
.entry(less_special)
118+
.or_insert_with(|| forest.add_node(less_special));
119+
let more_special_node = *node_map
120+
.entry(more_special)
121+
.or_insert_with(|| forest.add_node(more_special));
122+
forest.update_edge(less_special_node, more_special_node, ());
118123
})?;
119124

120-
Ok(forest.into_graph())
125+
Ok(forest)
121126
}
122127

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

chalk-solve/src/display/state.rs

+8-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! Persistent state passed down between writers.
22
//!
33
//! This is essentially `InternalWriterState` and other things supporting that.
4+
use core::hash::Hash;
45
use std::{
56
borrow::Borrow,
67
collections::BTreeMap,
@@ -12,6 +13,7 @@ use std::{
1213

1314
use crate::RustIrDatabase;
1415
use chalk_ir::{interner::Interner, *};
16+
use indexmap::IndexMap;
1517
use itertools::Itertools;
1618

1719
/// Like a BoundVar, but with the debrujin index inverted so as to create a
@@ -36,31 +38,31 @@ impl Display for InvertedBoundVar {
3638
}
3739
}
3840

39-
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
41+
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
4042
enum UnifiedId<I: Interner> {
4143
AdtId(I::InternedAdtId),
4244
DefId(I::DefId),
4345
}
4446

4547
#[derive(Debug)]
46-
pub struct IdAliasStore<T: Ord> {
48+
pub struct IdAliasStore<T> {
4749
/// Map from the DefIds we've encountered to a u32 alias id unique to all ids
4850
/// the same name.
49-
aliases: BTreeMap<T, u32>,
51+
aliases: IndexMap<T, u32>,
5052
/// Map from each name to the next unused u32 alias id.
5153
next_unused_for_name: BTreeMap<String, u32>,
5254
}
5355

54-
impl<T: Ord> Default for IdAliasStore<T> {
56+
impl<T> Default for IdAliasStore<T> {
5557
fn default() -> Self {
5658
IdAliasStore {
57-
aliases: BTreeMap::default(),
59+
aliases: IndexMap::default(),
5860
next_unused_for_name: BTreeMap::default(),
5961
}
6062
}
6163
}
6264

63-
impl<T: Copy + Ord> IdAliasStore<T> {
65+
impl<T: Copy + Eq + Hash> IdAliasStore<T> {
6466
fn alias_for_id_name(&mut self, id: T, name: String) -> String {
6567
let next_unused_for_name = &mut self.next_unused_for_name;
6668
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)