@@ -4,10 +4,11 @@ use crate::solve::Solver;
44use crate :: RustIrDatabase ;
55use chalk_ir:: interner:: Interner ;
66use chalk_ir:: { self , ImplId , TraitId } ;
7- use std:: collections:: BTreeMap ;
87use std:: fmt;
98use std:: sync:: Arc ;
109
10+ use indexmap:: IndexMap ;
11+
1112pub mod orphan;
1213mod 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 ) ]
4445pub struct SpecializationPriorities < I : Interner > {
45- map : BTreeMap < ImplId < I > , SpecializationPriority > ,
46+ map : IndexMap < ImplId < I > , SpecializationPriority > ,
4647}
4748
4849impl < 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.
0 commit comments