@@ -4,11 +4,12 @@ This module provides interfaces and simple wrapper types to enable sets to be
44treated in a generic way.
55 */
66
7+ use std:: hash:: Hash ;
78use std:: ops:: Range ;
8- use std:: { collections:: HashSet , hash:: Hash } ;
99
1010use derivative:: Derivative ;
1111use derive_more:: { From , Into } ;
12+ use indexmap:: IndexSet ;
1213use ref_cast:: RefCast ;
1314use ustr:: Ustr ;
1415
@@ -116,12 +117,17 @@ impl IntoIterator for SkelFinSet {
116117 }
117118}
118119
119- /// A finite set backed by a hash set.
120- #[ derive( Clone , Debug , From , Into , Derivative ) ]
120+ /** A finite set backed by a hash set.
121+
122+ A stable order is guaranteed when iterating over the elements of the set.
123+ Currently, this achieved by using an [`IndexSet`] rather than a `HashSet` for
124+ the underlying data structure.
125+ */
126+ #[ derive( Clone , Debug , Derivative ) ]
121127#[ derivative( Default ( bound = "" ) ) ]
122128#[ derivative( PartialEq ( bound = "T: Eq + Hash" ) ) ]
123129#[ derivative( Eq ( bound = "T: Eq + Hash" ) ) ]
124- pub struct HashFinSet < T > ( HashSet < T > ) ;
130+ pub struct HashFinSet < T > ( IndexSet < T > ) ;
125131
126132/// A finite set with elements of type `Ustr`.
127133pub type UstrFinSet = HashFinSet < Ustr > ;
@@ -179,7 +185,7 @@ where
179185 T : Eq + Hash ,
180186{
181187 type Item = T ;
182- type IntoIter = std :: collections :: hash_set :: IntoIter < T > ;
188+ type IntoIter = indexmap :: set :: IntoIter < T > ;
183189
184190 fn into_iter ( self ) -> Self :: IntoIter {
185191 self . 0 . into_iter ( )
@@ -275,10 +281,7 @@ mod tests {
275281 assert ! ( s. contains( & 3 ) ) ;
276282 assert ! ( s. contains( & 7 ) ) ;
277283 assert ! ( !s. contains( & 2 ) ) ;
278-
279- let s = HashFinSet :: from ( HashSet :: from ( [ 3 , 5 , 7 ] ) ) ;
280- let sum: i32 = s. iter ( ) . sum ( ) ;
281- assert_eq ! ( sum, 15 ) ;
284+ assert_eq ! ( s. iter( ) . sum:: <i32 >( ) , 15 ) ;
282285 assert_eq ! ( s. len( ) , 3 ) ;
283286 }
284287
0 commit comments