@@ -4,10 +4,11 @@ use crate::solve::Solver;
4
4
use crate :: RustIrDatabase ;
5
5
use chalk_ir:: interner:: Interner ;
6
6
use chalk_ir:: { self , ImplId , TraitId } ;
7
- use std:: collections:: BTreeMap ;
8
7
use std:: fmt;
9
8
use std:: sync:: Arc ;
10
9
10
+ use indexmap:: IndexMap ;
11
+
11
12
pub mod orphan;
12
13
mod solve;
13
14
@@ -42,13 +43,13 @@ impl<I: Interner> std::error::Error for CoherenceError<I> {}
42
43
/// This basically encodes which impls specialize one another.
43
44
#[ derive( Clone , Debug , Default , PartialEq , Eq ) ]
44
45
pub struct SpecializationPriorities < I : Interner > {
45
- map : BTreeMap < ImplId < I > , SpecializationPriority > ,
46
+ map : IndexMap < ImplId < I > , SpecializationPriority > ,
46
47
}
47
48
48
49
impl < I : Interner > SpecializationPriorities < I > {
49
50
pub fn new ( ) -> Self {
50
51
Self {
51
- map : BTreeMap :: new ( ) ,
52
+ map : IndexMap :: new ( ) ,
52
53
}
53
54
}
54
55
@@ -60,8 +61,7 @@ impl<I: Interner> SpecializationPriorities<I> {
60
61
/// Store the priority of an impl (used during construction).
61
62
/// Panics if we have already stored the priority for this impl.
62
63
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) ;
65
65
}
66
66
}
67
67
@@ -106,18 +106,24 @@ where
106
106
107
107
// Build the forest of specialization relationships.
108
108
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 ( ) ;
112
112
113
113
// Find all specializations (implemented in coherence/solve)
114
114
// Record them in the forest by adding an edge from the less special
115
115
// to the more special.
116
116
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
+ }
118
124
} ) ?;
119
125
120
- Ok ( forest. into_graph ( ) )
126
+ Ok ( forest)
121
127
}
122
128
123
129
// Recursively set priorities for those node and all of its children.
0 commit comments