@@ -168,6 +168,14 @@ impl<T: Ord, I: Iterator<Item = T>> UnordItems<T, I> {
168
168
}
169
169
}
170
170
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
+
171
179
/// This is a set collection type that tries very hard to not expose
172
180
/// any internal iteration. This is a useful property when trying to
173
181
/// uphold the determinism invariants imposed by the query system.
@@ -182,6 +190,8 @@ pub struct UnordSet<V: Eq + Hash> {
182
190
inner : FxHashSet < V > ,
183
191
}
184
192
193
+ impl < V : Eq + Hash > UnordCollection for UnordSet < V > { }
194
+
185
195
impl < V : Eq + Hash > Default for UnordSet < V > {
186
196
#[ inline]
187
197
fn default ( ) -> Self {
@@ -285,16 +295,28 @@ impl<V: Eq + Hash> UnordSet<V> {
285
295
to_sorted_vec ( hcx, self . inner . into_iter ( ) , cache_sort_key, |x| x)
286
296
}
287
297
288
- // We can safely extend this UnordSet from a set of unordered values because that
289
- // won't expose the internal ordering anywhere.
290
298
#[ 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 ( ) ;
293
301
}
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
+ }
294
312
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 {
295
317
#[ 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 )
298
320
}
299
321
}
300
322
@@ -345,6 +367,8 @@ pub struct UnordMap<K: Eq + Hash, V> {
345
367
inner : FxHashMap < K , V > ,
346
368
}
347
369
370
+ impl < K : Eq + Hash , V > UnordCollection for UnordMap < K , V > { }
371
+
348
372
impl < K : Eq + Hash , V > Default for UnordMap < K , V > {
349
373
#[ inline]
350
374
fn default ( ) -> Self {
@@ -445,13 +469,6 @@ impl<K: Eq + Hash, V> UnordMap<K, V> {
445
469
UnordItems ( self . inner . into_iter ( ) )
446
470
}
447
471
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
-
455
472
/// Returns the entries of this map in stable sort order (as defined by `ToStableHashKey`).
456
473
///
457
474
/// The `cache_sort_key` parameter controls if [slice::sort_by_cached_key] or
@@ -571,15 +588,10 @@ impl<V> UnordBag<V> {
571
588
pub fn into_items ( self ) -> UnordItems < V , impl Iterator < Item = V > > {
572
589
UnordItems ( self . inner . into_iter ( ) )
573
590
}
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
- }
581
591
}
582
592
593
+ impl < T > UnordCollection for UnordBag < T > { }
594
+
583
595
impl < T > Extend < T > for UnordBag < T > {
584
596
fn extend < I : IntoIterator < Item = T > > ( & mut self , iter : I ) {
585
597
self . inner . extend ( iter)
0 commit comments