@@ -168,6 +168,14 @@ impl<T: Ord, I: Iterator<Item = T>> UnordItems<T, I> {
168168 }
169169}
170170
171+ /// A marker trait specifying that `Self` can consume `UnordItems<_>` without
172+ /// exposing any internal ordering.
173+ ///
174+ /// Note: right now this is just a marker trait. It could be extended to contain
175+ /// some useful, common methods though, like `len`, `clear`, or the various
176+ /// kinds of `to_sorted`.
177+ trait UnordCollection { }
178+
171179/// This is a set collection type that tries very hard to not expose
172180/// any internal iteration. This is a useful property when trying to
173181/// uphold the determinism invariants imposed by the query system.
@@ -182,6 +190,8 @@ pub struct UnordSet<V: Eq + Hash> {
182190 inner : FxHashSet < V > ,
183191}
184192
193+ impl < V : Eq + Hash > UnordCollection for UnordSet < V > { }
194+
185195impl < V : Eq + Hash > Default for UnordSet < V > {
186196 #[ inline]
187197 fn default ( ) -> Self {
@@ -285,16 +295,28 @@ impl<V: Eq + Hash> UnordSet<V> {
285295 to_sorted_vec ( hcx, self . inner . into_iter ( ) , cache_sort_key, |x| x)
286296 }
287297
288- // We can safely extend this UnordSet from a set of unordered values because that
289- // won't expose the internal ordering anywhere.
290298 #[ inline]
291- pub fn extend_unord < I : Iterator < Item = V > > ( & mut self , items : UnordItems < V , I > ) {
292- self . inner . extend ( items . 0 )
299+ pub fn clear ( & mut self ) {
300+ self . inner . clear ( ) ;
293301 }
302+ }
303+
304+ pub trait ExtendUnord < T > {
305+ /// Extend this unord collection with the given `UnordItems`.
306+ /// This method is called `extend_unord` instead of just `extend` so it
307+ /// does not conflict with `Extend::extend`. Otherwise there would be many
308+ /// places where the two methods would have to be explicitly disambiguated
309+ /// via UFCS.
310+ fn extend_unord < I : Iterator < Item = T > > ( & mut self , items : UnordItems < T , I > ) ;
311+ }
294312
313+ // Note: it is important that `C` implements `UnordCollection` in addition to
314+ // `Extend`, otherwise this impl would leak the internal iteration order of
315+ // `items`, e.g. when calling `some_vec.extend_unord(some_unord_items)`.
316+ impl < C : Extend < T > + UnordCollection , T > ExtendUnord < T > for C {
295317 #[ inline]
296- pub fn clear ( & mut self ) {
297- self . inner . clear ( ) ;
318+ fn extend_unord < I : Iterator < Item = T > > ( & mut self , items : UnordItems < T , I > ) {
319+ self . extend ( items . 0 )
298320 }
299321}
300322
@@ -345,6 +367,8 @@ pub struct UnordMap<K: Eq + Hash, V> {
345367 inner : FxHashMap < K , V > ,
346368}
347369
370+ impl < K : Eq + Hash , V > UnordCollection for UnordMap < K , V > { }
371+
348372impl < K : Eq + Hash , V > Default for UnordMap < K , V > {
349373 #[ inline]
350374 fn default ( ) -> Self {
@@ -445,13 +469,6 @@ impl<K: Eq + Hash, V> UnordMap<K, V> {
445469 UnordItems ( self . inner . into_iter ( ) )
446470 }
447471
448- // We can safely extend this UnordMap from a set of unordered values because that
449- // won't expose the internal ordering anywhere.
450- #[ inline]
451- pub fn extend < I : Iterator < Item = ( K , V ) > > ( & mut self , items : UnordItems < ( K , V ) , I > ) {
452- self . inner . extend ( items. 0 )
453- }
454-
455472 /// Returns the entries of this map in stable sort order (as defined by `ToStableHashKey`).
456473 ///
457474 /// The `cache_sort_key` parameter controls if [slice::sort_by_cached_key] or
@@ -571,15 +588,10 @@ impl<V> UnordBag<V> {
571588 pub fn into_items ( self ) -> UnordItems < V , impl Iterator < Item = V > > {
572589 UnordItems ( self . inner . into_iter ( ) )
573590 }
574-
575- // We can safely extend this UnordSet from a set of unordered values because that
576- // won't expose the internal ordering anywhere.
577- #[ inline]
578- pub fn extend < I : Iterator < Item = V > > ( & mut self , items : UnordItems < V , I > ) {
579- self . inner . extend ( items. 0 )
580- }
581591}
582592
593+ impl < T > UnordCollection for UnordBag < T > { }
594+
583595impl < T > Extend < T > for UnordBag < T > {
584596 fn extend < I : IntoIterator < Item = T > > ( & mut self , iter : I ) {
585597 self . inner . extend ( iter)
0 commit comments