Skip to main content

rustc_data_structures/
unord.rs

1//! This module contains collection types that don't expose their internal
2//! ordering. This is a useful property for deterministic computations, such
3//! as required by the query system.
4
5use std::borrow::{Borrow, BorrowMut};
6use std::collections::hash_map::{Entry, OccupiedError};
7use std::hash::Hash;
8use std::iter::{Product, Sum};
9use std::ops::Index;
10
11use rustc_macros::{Decodable_NoContext, Encodable_NoContext};
12
13use crate::fingerprint::Fingerprint;
14use crate::fx::{FxBuildHasher, FxHashMap, FxHashSet};
15use crate::stable_hash::{
16    StableCompare, StableHash, StableHashCtxt, StableHasher, ToStableHashKey,
17};
18
19/// `UnordItems` is the order-less version of `Iterator`. It only contains methods
20/// that don't (easily) expose an ordering of the underlying items.
21///
22/// Most methods take an `Fn` where the `Iterator`-version takes an `FnMut`. This
23/// is to reduce the risk of accidentally leaking the internal order via the closure
24/// environment. Otherwise one could easily do something like
25///
26/// ```rust,ignore (pseudo code)
27/// let mut ordered = vec![];
28/// unordered_items.all(|x| ordered.push(x));
29/// ```
30///
31/// It's still possible to do the same thing with an `Fn` by using interior mutability,
32/// but the chance of doing it accidentally is reduced.
33#[derive(#[automatically_derived]
impl<T: ::core::clone::Clone, I: ::core::clone::Clone + Iterator<Item = T>>
    ::core::clone::Clone for UnordItems<T, I> {
    #[inline]
    fn clone(&self) -> UnordItems<T, I> {
        UnordItems(::core::clone::Clone::clone(&self.0))
    }
}Clone)]
34pub struct UnordItems<T, I: Iterator<Item = T>>(I);
35
36impl<T, I: Iterator<Item = T>> UnordItems<T, I> {
37    #[inline]
38    pub fn new(iter: I) -> UnordItems<T, I> {
39        UnordItems(iter)
40    }
41
42    #[inline]
43    pub fn map<U, F: Fn(T) -> U>(self, f: F) -> UnordItems<U, impl Iterator<Item = U>> {
44        UnordItems(self.0.map(f))
45    }
46
47    #[inline]
48    pub fn all<F: Fn(T) -> bool>(mut self, f: F) -> bool {
49        self.0.all(f)
50    }
51
52    #[inline]
53    pub fn any<F: Fn(T) -> bool>(mut self, f: F) -> bool {
54        self.0.any(f)
55    }
56
57    #[inline]
58    pub fn filter<F: Fn(&T) -> bool>(self, f: F) -> UnordItems<T, impl Iterator<Item = T>> {
59        UnordItems(self.0.filter(f))
60    }
61
62    #[inline]
63    pub fn filter_map<U, F: Fn(T) -> Option<U>>(
64        self,
65        f: F,
66    ) -> UnordItems<U, impl Iterator<Item = U>> {
67        UnordItems(self.0.filter_map(f))
68    }
69
70    #[inline]
71    pub fn chain(
72        self,
73        other: UnordItems<T, impl Iterator<Item = T>>,
74    ) -> UnordItems<T, impl Iterator<Item = T>> {
75        UnordItems(self.0.chain(other.0))
76    }
77
78    #[inline]
79    pub fn max(self) -> Option<T>
80    where
81        T: Ord,
82    {
83        self.0.max()
84    }
85
86    #[inline]
87    pub fn min(self) -> Option<T>
88    where
89        T: Ord,
90    {
91        self.0.min()
92    }
93
94    #[inline]
95    pub fn sum<S>(self) -> S
96    where
97        S: Sum<T>,
98    {
99        self.0.sum()
100    }
101
102    #[inline]
103    pub fn product<S>(self) -> S
104    where
105        S: Product<T>,
106    {
107        self.0.product()
108    }
109
110    #[inline]
111    pub fn count(self) -> usize {
112        self.0.count()
113    }
114
115    #[inline]
116    pub fn flat_map<U, F, O>(self, f: F) -> UnordItems<O, impl Iterator<Item = O>>
117    where
118        U: Iterator<Item = O>,
119        F: Fn(T) -> UnordItems<O, U>,
120    {
121        UnordItems(self.0.flat_map(move |x| f(x).0))
122    }
123
124    pub fn collect<C: From<UnordItems<T, I>>>(self) -> C {
125        self.into()
126    }
127
128    /// If the iterator has only one element, returns it, otherwise returns `None`.
129    #[track_caller]
130    pub fn get_only(mut self) -> Option<T> {
131        let item = self.0.next();
132        if self.0.next().is_some() {
133            return None;
134        }
135        item
136    }
137}
138
139impl<T> UnordItems<T, std::iter::Empty<T>> {
140    pub fn empty() -> Self {
141        UnordItems(std::iter::empty())
142    }
143}
144
145impl<'a, T: Clone + 'a, I: Iterator<Item = &'a T>> UnordItems<&'a T, I> {
146    #[inline]
147    pub fn cloned(self) -> UnordItems<T, impl Iterator<Item = T>> {
148        UnordItems(self.0.cloned())
149    }
150}
151
152impl<'a, T: Copy + 'a, I: Iterator<Item = &'a T>> UnordItems<&'a T, I> {
153    #[inline]
154    pub fn copied(self) -> UnordItems<T, impl Iterator<Item = T>> {
155        UnordItems(self.0.copied())
156    }
157}
158
159impl<T, I: Iterator<Item = T>> UnordItems<T, I> {
160    #[inline]
161    pub fn into_sorted<Hcx: StableHashCtxt>(self, hcx: &mut Hcx) -> Vec<T>
162    where
163        T: ToStableHashKey,
164    {
165        self.collect_sorted(hcx, true)
166    }
167
168    #[inline]
169    pub fn into_sorted_stable_ord(self) -> Vec<T>
170    where
171        T: StableCompare,
172    {
173        self.collect_stable_ord_by_key(|x| x)
174    }
175
176    #[inline]
177    pub fn into_sorted_stable_ord_by_key<K, C>(self, project_to_key: C) -> Vec<T>
178    where
179        K: StableCompare,
180        C: for<'a> Fn(&'a T) -> &'a K,
181    {
182        self.collect_stable_ord_by_key(project_to_key)
183    }
184
185    #[inline]
186    pub fn collect_sorted<Hcx, C>(self, hcx: &mut Hcx, cache_sort_key: bool) -> C
187    where
188        Hcx: StableHashCtxt,
189        T: ToStableHashKey,
190        C: FromIterator<T> + BorrowMut<[T]>,
191    {
192        let mut items: C = self.0.collect();
193
194        let slice = items.borrow_mut();
195        if slice.len() > 1 {
196            if cache_sort_key {
197                slice.sort_by_cached_key(|x| x.to_stable_hash_key(hcx));
198            } else {
199                slice.sort_by_key(|x| x.to_stable_hash_key(hcx));
200            }
201        }
202
203        items
204    }
205
206    #[inline]
207    pub fn collect_stable_ord_by_key<K, C, P>(self, project_to_key: P) -> C
208    where
209        K: StableCompare,
210        P: for<'a> Fn(&'a T) -> &'a K,
211        C: FromIterator<T> + BorrowMut<[T]>,
212    {
213        let mut items: C = self.0.collect();
214
215        let slice = items.borrow_mut();
216        if slice.len() > 1 {
217            if !K::CAN_USE_UNSTABLE_SORT {
218                slice.sort_by(|a, b| {
219                    let a_key = project_to_key(a);
220                    let b_key = project_to_key(b);
221                    a_key.stable_cmp(b_key)
222                });
223            } else {
224                slice.sort_unstable_by(|a, b| {
225                    let a_key = project_to_key(a);
226                    let b_key = project_to_key(b);
227                    a_key.stable_cmp(b_key)
228                });
229            }
230        }
231
232        items
233    }
234}
235
236/// A marker trait specifying that `Self` can consume `UnordItems<_>` without
237/// exposing any internal ordering.
238///
239/// Note: right now this is just a marker trait. It could be extended to contain
240/// some useful, common methods though, like `len`, `clear`, or the various
241/// kinds of `to_sorted`.
242trait UnordCollection {}
243
244/// This is a set collection type that tries very hard to not expose
245/// any internal iteration. This is a useful property when trying to
246/// uphold the determinism invariants imposed by the query system.
247///
248/// This collection type is a good choice for set-like collections the
249/// keys of which don't have a semantic ordering.
250///
251/// See [MCP 533](https://github.com/rust-lang/compiler-team/issues/533)
252/// for more information.
253#[derive(#[automatically_derived]
impl<V: ::core::fmt::Debug + Eq + Hash> ::core::fmt::Debug for UnordSet<V> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field1_finish(f, "UnordSet",
            "inner", &&self.inner)
    }
}Debug, #[automatically_derived]
impl<V: ::core::cmp::Eq + Eq + Hash> ::core::cmp::Eq for UnordSet<V> {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<FxHashSet<V>>;
    }
}Eq, #[automatically_derived]
impl<V: ::core::cmp::PartialEq + Eq + Hash> ::core::cmp::PartialEq for
    UnordSet<V> {
    #[inline]
    fn eq(&self, other: &UnordSet<V>) -> bool { self.inner == other.inner }
}PartialEq, #[automatically_derived]
impl<V: ::core::clone::Clone + Eq + Hash> ::core::clone::Clone for UnordSet<V>
    {
    #[inline]
    fn clone(&self) -> UnordSet<V> {
        UnordSet { inner: ::core::clone::Clone::clone(&self.inner) }
    }
}Clone, const _: () =
    {
        impl<V: Eq + Hash, __E: ::rustc_serialize::Encoder>
            ::rustc_serialize::Encodable<__E> for UnordSet<V> where
            FxHashSet<V>: ::rustc_serialize::Encodable<__E> {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    UnordSet { inner: ref __binding_0 } => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                }
            }
        }
    };Encodable_NoContext, const _: () =
    {
        impl<V: Eq + Hash, __D: ::rustc_serialize::Decoder>
            ::rustc_serialize::Decodable<__D> for UnordSet<V> where
            FxHashSet<V>: ::rustc_serialize::Decodable<__D> {
            fn decode(__decoder: &mut __D) -> Self {
                UnordSet {
                    inner: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };Decodable_NoContext)]
254pub struct UnordSet<V: Eq + Hash> {
255    inner: FxHashSet<V>,
256}
257
258impl<V: Eq + Hash> UnordCollection for UnordSet<V> {}
259
260impl<V: Eq + Hash> const Default for UnordSet<V> {
261    #[inline]
262    fn default() -> Self {
263        Self { inner: FxHashSet::with_hasher(FxBuildHasher) }
264    }
265}
266
267impl<V: Eq + Hash> UnordSet<V> {
268    #[inline]
269    pub fn new() -> Self {
270        Self { inner: Default::default() }
271    }
272
273    #[inline]
274    pub fn with_capacity(capacity: usize) -> Self {
275        Self { inner: FxHashSet::with_capacity_and_hasher(capacity, Default::default()) }
276    }
277
278    #[inline]
279    pub fn len(&self) -> usize {
280        self.inner.len()
281    }
282
283    #[inline]
284    pub fn is_empty(&self) -> bool {
285        self.inner.is_empty()
286    }
287
288    /// If the set has only one element, returns it, otherwise returns `None`.
289    #[inline]
290    pub fn get_only(&self) -> Option<&V> {
291        if self.inner.len() == 1 { self.inner.iter().next() } else { None }
292    }
293
294    #[inline]
295    pub fn insert(&mut self, v: V) -> bool {
296        self.inner.insert(v)
297    }
298
299    #[inline]
300    pub fn contains<Q: ?Sized>(&self, v: &Q) -> bool
301    where
302        V: Borrow<Q>,
303        Q: Hash + Eq,
304    {
305        self.inner.contains(v)
306    }
307
308    #[inline]
309    pub fn remove<Q: ?Sized>(&mut self, k: &Q) -> bool
310    where
311        V: Borrow<Q>,
312        Q: Hash + Eq,
313    {
314        self.inner.remove(k)
315    }
316
317    #[inline]
318    pub fn items(&self) -> UnordItems<&V, impl Iterator<Item = &V>> {
319        UnordItems(self.inner.iter())
320    }
321
322    #[inline]
323    pub fn into_items(self) -> UnordItems<V, impl Iterator<Item = V>> {
324        UnordItems(self.inner.into_iter())
325    }
326
327    /// Returns the items of this set in stable sort order (as defined by `ToStableHashKey`).
328    ///
329    /// The `cache_sort_key` parameter controls if [slice::sort_by_cached_key] or
330    /// [slice::sort_unstable_by_key] will be used for sorting the vec. Use
331    /// `cache_sort_key` when the [ToStableHashKey::to_stable_hash_key] implementation
332    /// for `V` is expensive (e.g. a `DefId -> DefPathHash` lookup).
333    #[inline]
334    pub fn to_sorted<Hcx>(&self, hcx: &mut Hcx, cache_sort_key: bool) -> Vec<&V>
335    where
336        Hcx: StableHashCtxt,
337        V: ToStableHashKey,
338    {
339        to_sorted_vec(hcx, self.inner.iter(), cache_sort_key, |&x| x)
340    }
341
342    /// Returns the items of this set in stable sort order (as defined by
343    /// `StableCompare`). This method is much more efficient than
344    /// `into_sorted` because it does not need to transform keys to their
345    /// `ToStableHashKey` equivalent.
346    #[inline]
347    pub fn to_sorted_stable_ord(&self) -> Vec<&V>
348    where
349        V: StableCompare,
350    {
351        let mut items: Vec<&V> = self.inner.iter().collect();
352        items.sort_unstable_by(|a, b| a.stable_cmp(*b));
353        items
354    }
355
356    /// Returns the items of this set in stable sort order (as defined by
357    /// `StableCompare`). This method is much more efficient than
358    /// `into_sorted` because it does not need to transform keys to their
359    /// `ToStableHashKey` equivalent.
360    #[inline]
361    pub fn into_sorted_stable_ord(self) -> Vec<V>
362    where
363        V: StableCompare,
364    {
365        let mut items: Vec<V> = self.inner.into_iter().collect();
366        items.sort_unstable_by(V::stable_cmp);
367        items
368    }
369
370    /// Returns the items of this set in stable sort order (as defined by `ToStableHashKey`).
371    ///
372    /// The `cache_sort_key` parameter controls if [slice::sort_by_cached_key] or
373    /// [slice::sort_unstable_by_key] will be used for sorting the vec. Use
374    /// `cache_sort_key` when the [ToStableHashKey::to_stable_hash_key] implementation
375    /// for `V` is expensive (e.g. a `DefId -> DefPathHash` lookup).
376    #[inline]
377    pub fn into_sorted<Hcx>(self, hcx: &mut Hcx, cache_sort_key: bool) -> Vec<V>
378    where
379        Hcx: StableHashCtxt,
380        V: ToStableHashKey,
381    {
382        to_sorted_vec(hcx, self.inner.into_iter(), cache_sort_key, |x| x)
383    }
384
385    #[inline]
386    pub fn clear(&mut self) {
387        self.inner.clear();
388    }
389}
390
391pub trait ExtendUnord<T> {
392    /// Extend this unord collection with the given `UnordItems`.
393    /// This method is called `extend_unord` instead of just `extend` so it
394    /// does not conflict with `Extend::extend`. Otherwise there would be many
395    /// places where the two methods would have to be explicitly disambiguated
396    /// via UFCS.
397    fn extend_unord<I: Iterator<Item = T>>(&mut self, items: UnordItems<T, I>);
398}
399
400// Note: it is important that `C` implements `UnordCollection` in addition to
401// `Extend`, otherwise this impl would leak the internal iteration order of
402// `items`, e.g. when calling `some_vec.extend_unord(some_unord_items)`.
403impl<C: Extend<T> + UnordCollection, T> ExtendUnord<T> for C {
404    #[inline]
405    fn extend_unord<I: Iterator<Item = T>>(&mut self, items: UnordItems<T, I>) {
406        self.extend(items.0)
407    }
408}
409
410impl<V: Hash + Eq> Extend<V> for UnordSet<V> {
411    #[inline]
412    fn extend<T: IntoIterator<Item = V>>(&mut self, iter: T) {
413        self.inner.extend(iter)
414    }
415}
416
417impl<V: Hash + Eq> FromIterator<V> for UnordSet<V> {
418    #[inline]
419    fn from_iter<T: IntoIterator<Item = V>>(iter: T) -> Self {
420        UnordSet { inner: FxHashSet::from_iter(iter) }
421    }
422}
423
424impl<V: Hash + Eq> From<FxHashSet<V>> for UnordSet<V> {
425    fn from(value: FxHashSet<V>) -> Self {
426        UnordSet { inner: value }
427    }
428}
429
430impl<V: Hash + Eq, I: Iterator<Item = V>> From<UnordItems<V, I>> for UnordSet<V> {
431    fn from(value: UnordItems<V, I>) -> Self {
432        UnordSet { inner: FxHashSet::from_iter(value.0) }
433    }
434}
435
436impl<V: Hash + Eq + StableHash> StableHash for UnordSet<V> {
437    #[inline]
438    fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
439        hash_iter_order_independent(self.inner.iter(), hcx, hasher);
440    }
441}
442
443/// This is a map collection type that tries very hard to not expose
444/// any internal iteration. This is a useful property when trying to
445/// uphold the determinism invariants imposed by the query system.
446///
447/// This collection type is a good choice for map-like collections the
448/// keys of which don't have a semantic ordering.
449///
450/// See [MCP 533](https://github.com/rust-lang/compiler-team/issues/533)
451/// for more information.
452#[derive(#[automatically_derived]
impl<K: ::core::fmt::Debug + Eq + Hash, V: ::core::fmt::Debug>
    ::core::fmt::Debug for UnordMap<K, V> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field1_finish(f, "UnordMap",
            "inner", &&self.inner)
    }
}Debug, #[automatically_derived]
impl<K: ::core::cmp::Eq + Eq + Hash, V: ::core::cmp::Eq> ::core::cmp::Eq for
    UnordMap<K, V> {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<FxHashMap<K, V>>;
    }
}Eq, #[automatically_derived]
impl<K: ::core::cmp::PartialEq + Eq + Hash, V: ::core::cmp::PartialEq>
    ::core::cmp::PartialEq for UnordMap<K, V> {
    #[inline]
    fn eq(&self, other: &UnordMap<K, V>) -> bool { self.inner == other.inner }
}PartialEq, #[automatically_derived]
impl<K: ::core::clone::Clone + Eq + Hash, V: ::core::clone::Clone>
    ::core::clone::Clone for UnordMap<K, V> {
    #[inline]
    fn clone(&self) -> UnordMap<K, V> {
        UnordMap { inner: ::core::clone::Clone::clone(&self.inner) }
    }
}Clone, const _: () =
    {
        impl<K: Eq + Hash, V, __E: ::rustc_serialize::Encoder>
            ::rustc_serialize::Encodable<__E> for UnordMap<K, V> where
            FxHashMap<K, V>: ::rustc_serialize::Encodable<__E> {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    UnordMap { inner: ref __binding_0 } => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                }
            }
        }
    };Encodable_NoContext, const _: () =
    {
        impl<K: Eq + Hash, V, __D: ::rustc_serialize::Decoder>
            ::rustc_serialize::Decodable<__D> for UnordMap<K, V> where
            FxHashMap<K, V>: ::rustc_serialize::Decodable<__D> {
            fn decode(__decoder: &mut __D) -> Self {
                UnordMap {
                    inner: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };Decodable_NoContext)]
453pub struct UnordMap<K: Eq + Hash, V> {
454    inner: FxHashMap<K, V>,
455}
456
457impl<K: Eq + Hash, V> UnordCollection for UnordMap<K, V> {}
458
459impl<K: Eq + Hash, V> const Default for UnordMap<K, V> {
460    #[inline]
461    fn default() -> Self {
462        Self { inner: FxHashMap::with_hasher(FxBuildHasher) }
463    }
464}
465
466impl<K: Hash + Eq, V> Extend<(K, V)> for UnordMap<K, V> {
467    #[inline]
468    fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
469        self.inner.extend(iter)
470    }
471}
472
473impl<K: Hash + Eq, V> FromIterator<(K, V)> for UnordMap<K, V> {
474    #[inline]
475    fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
476        UnordMap { inner: FxHashMap::from_iter(iter) }
477    }
478}
479
480impl<K: Hash + Eq, V, I: Iterator<Item = (K, V)>> From<UnordItems<(K, V), I>> for UnordMap<K, V> {
481    #[inline]
482    fn from(items: UnordItems<(K, V), I>) -> Self {
483        UnordMap { inner: FxHashMap::from_iter(items.0) }
484    }
485}
486
487impl<K: Eq + Hash, V> UnordMap<K, V> {
488    #[inline]
489    pub fn with_capacity(capacity: usize) -> Self {
490        Self { inner: FxHashMap::with_capacity_and_hasher(capacity, Default::default()) }
491    }
492
493    #[inline]
494    pub fn len(&self) -> usize {
495        self.inner.len()
496    }
497
498    #[inline]
499    pub fn insert(&mut self, k: K, v: V) -> Option<V> {
500        self.inner.insert(k, v)
501    }
502
503    #[inline]
504    pub fn try_insert(&mut self, k: K, v: V) -> Result<&mut V, OccupiedError<'_, K, V>> {
505        self.inner.try_insert(k, v)
506    }
507
508    #[inline]
509    pub fn contains_key<Q: ?Sized>(&self, k: &Q) -> bool
510    where
511        K: Borrow<Q>,
512        Q: Hash + Eq,
513    {
514        self.inner.contains_key(k)
515    }
516
517    #[inline]
518    pub fn is_empty(&self) -> bool {
519        self.inner.is_empty()
520    }
521
522    #[inline]
523    pub fn entry(&mut self, key: K) -> Entry<'_, K, V> {
524        self.inner.entry(key)
525    }
526
527    #[inline]
528    pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V>
529    where
530        K: Borrow<Q>,
531        Q: Hash + Eq,
532    {
533        self.inner.get(k)
534    }
535
536    #[inline]
537    pub fn get_mut<Q: ?Sized>(&mut self, k: &Q) -> Option<&mut V>
538    where
539        K: Borrow<Q>,
540        Q: Hash + Eq,
541    {
542        self.inner.get_mut(k)
543    }
544
545    #[inline]
546    pub fn remove<Q: ?Sized>(&mut self, k: &Q) -> Option<V>
547    where
548        K: Borrow<Q>,
549        Q: Hash + Eq,
550    {
551        self.inner.remove(k)
552    }
553
554    #[inline]
555    pub fn items(&self) -> UnordItems<(&K, &V), impl Iterator<Item = (&K, &V)>> {
556        UnordItems(self.inner.iter())
557    }
558
559    #[inline]
560    pub fn into_items(self) -> UnordItems<(K, V), impl Iterator<Item = (K, V)>> {
561        UnordItems(self.inner.into_iter())
562    }
563
564    #[inline]
565    pub fn keys(&self) -> UnordItems<&K, impl Iterator<Item = &K>> {
566        UnordItems(self.inner.keys())
567    }
568
569    /// Returns the entries of this map in stable sort order (as defined by `ToStableHashKey`).
570    ///
571    /// The `cache_sort_key` parameter controls if [slice::sort_by_cached_key] or
572    /// [slice::sort_unstable_by_key] will be used for sorting the vec. Use
573    /// `cache_sort_key` when the [ToStableHashKey::to_stable_hash_key] implementation
574    /// for `K` is expensive (e.g. a `DefId -> DefPathHash` lookup).
575    #[inline]
576    pub fn to_sorted<Hcx>(&self, hcx: &mut Hcx, cache_sort_key: bool) -> Vec<(&K, &V)>
577    where
578        Hcx: StableHashCtxt,
579        K: ToStableHashKey,
580    {
581        to_sorted_vec(hcx, self.inner.iter(), cache_sort_key, |&(k, _)| k)
582    }
583
584    /// Returns the entries of this map in stable sort order (as defined by `StableCompare`).
585    /// This method can be much more efficient than `into_sorted` because it does not need
586    /// to transform keys to their `ToStableHashKey` equivalent.
587    #[inline]
588    pub fn to_sorted_stable_ord(&self) -> Vec<(&K, &V)>
589    where
590        K: StableCompare,
591    {
592        let mut items: Vec<_> = self.inner.iter().collect();
593        items.sort_unstable_by(|(a, _), (b, _)| a.stable_cmp(*b));
594        items
595    }
596
597    /// Returns the entries of this map in stable sort order (as defined by `ToStableHashKey`).
598    ///
599    /// The `cache_sort_key` parameter controls if [slice::sort_by_cached_key] or
600    /// [slice::sort_unstable_by_key] will be used for sorting the vec. Use
601    /// `cache_sort_key` when the [ToStableHashKey::to_stable_hash_key] implementation
602    /// for `K` is expensive (e.g. a `DefId -> DefPathHash` lookup).
603    #[inline]
604    pub fn into_sorted<Hcx>(self, hcx: &mut Hcx, cache_sort_key: bool) -> Vec<(K, V)>
605    where
606        Hcx: StableHashCtxt,
607        K: ToStableHashKey,
608    {
609        to_sorted_vec(hcx, self.inner.into_iter(), cache_sort_key, |(k, _)| k)
610    }
611
612    /// Returns the entries of this map in stable sort order (as defined by `StableCompare`).
613    /// This method can be much more efficient than `into_sorted` because it does not need
614    /// to transform keys to their `ToStableHashKey` equivalent.
615    #[inline]
616    pub fn into_sorted_stable_ord(self) -> Vec<(K, V)>
617    where
618        K: StableCompare,
619    {
620        let mut items: Vec<(K, V)> = self.inner.into_iter().collect();
621        items.sort_unstable_by(|a, b| a.0.stable_cmp(&b.0));
622        items
623    }
624
625    /// Returns the values of this map in stable sort order (as defined by K's
626    /// `ToStableHashKey` implementation).
627    ///
628    /// The `cache_sort_key` parameter controls if [slice::sort_by_cached_key] or
629    /// [slice::sort_unstable_by_key] will be used for sorting the vec. Use
630    /// `cache_sort_key` when the [ToStableHashKey::to_stable_hash_key] implementation
631    /// for `K` is expensive (e.g. a `DefId -> DefPathHash` lookup).
632    #[inline]
633    pub fn values_sorted<Hcx>(
634        &self,
635        hcx: &mut Hcx,
636        cache_sort_key: bool,
637    ) -> impl Iterator<Item = &V>
638    where
639        Hcx: StableHashCtxt,
640        K: ToStableHashKey,
641    {
642        to_sorted_vec(hcx, self.inner.iter(), cache_sort_key, |&(k, _)| k)
643            .into_iter()
644            .map(|(_, v)| v)
645    }
646
647    #[inline]
648    pub fn clear(&mut self) {
649        self.inner.clear()
650    }
651}
652
653impl<K, Q: ?Sized, V> Index<&Q> for UnordMap<K, V>
654where
655    K: Eq + Hash + Borrow<Q>,
656    Q: Eq + Hash,
657{
658    type Output = V;
659
660    #[inline]
661    fn index(&self, key: &Q) -> &V {
662        &self.inner[key]
663    }
664}
665
666impl<K: Hash + Eq + StableHash, V: StableHash> StableHash for UnordMap<K, V> {
667    #[inline]
668    fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
669        hash_iter_order_independent(self.inner.iter(), hcx, hasher);
670    }
671}
672
673/// This is a collection type that tries very hard to not expose
674/// any internal iteration. This is a useful property when trying to
675/// uphold the determinism invariants imposed by the query system.
676///
677/// This collection type is a good choice for collections the
678/// keys of which don't have a semantic ordering and don't implement
679/// `Hash` or `Eq`.
680///
681/// See [MCP 533](https://github.com/rust-lang/compiler-team/issues/533)
682/// for more information.
683#[derive(#[automatically_derived]
impl<V: ::core::default::Default> ::core::default::Default for UnordBag<V> {
    #[inline]
    fn default() -> UnordBag<V> {
        UnordBag { inner: ::core::default::Default::default() }
    }
}Default, #[automatically_derived]
impl<V: ::core::fmt::Debug> ::core::fmt::Debug for UnordBag<V> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field1_finish(f, "UnordBag",
            "inner", &&self.inner)
    }
}Debug, #[automatically_derived]
impl<V: ::core::cmp::Eq> ::core::cmp::Eq for UnordBag<V> {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<Vec<V>>;
    }
}Eq, #[automatically_derived]
impl<V: ::core::cmp::PartialEq> ::core::cmp::PartialEq for UnordBag<V> {
    #[inline]
    fn eq(&self, other: &UnordBag<V>) -> bool { self.inner == other.inner }
}PartialEq, #[automatically_derived]
impl<V: ::core::clone::Clone> ::core::clone::Clone for UnordBag<V> {
    #[inline]
    fn clone(&self) -> UnordBag<V> {
        UnordBag { inner: ::core::clone::Clone::clone(&self.inner) }
    }
}Clone, const _: () =
    {
        impl<V, __E: ::rustc_serialize::Encoder>
            ::rustc_serialize::Encodable<__E> for UnordBag<V> where
            Vec<V>: ::rustc_serialize::Encodable<__E> {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    UnordBag { inner: ref __binding_0 } => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                }
            }
        }
    };Encodable_NoContext, const _: () =
    {
        impl<V, __D: ::rustc_serialize::Decoder>
            ::rustc_serialize::Decodable<__D> for UnordBag<V> where
            Vec<V>: ::rustc_serialize::Decodable<__D> {
            fn decode(__decoder: &mut __D) -> Self {
                UnordBag {
                    inner: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };Decodable_NoContext)]
684pub struct UnordBag<V> {
685    inner: Vec<V>,
686}
687
688impl<V> UnordBag<V> {
689    #[inline]
690    pub fn new() -> Self {
691        Self { inner: Default::default() }
692    }
693
694    #[inline]
695    pub fn len(&self) -> usize {
696        self.inner.len()
697    }
698
699    #[inline]
700    pub fn push(&mut self, v: V) {
701        self.inner.push(v);
702    }
703
704    #[inline]
705    pub fn items(&self) -> UnordItems<&V, impl Iterator<Item = &V>> {
706        UnordItems(self.inner.iter())
707    }
708
709    #[inline]
710    pub fn into_items(self) -> UnordItems<V, impl Iterator<Item = V>> {
711        UnordItems(self.inner.into_iter())
712    }
713}
714
715impl<T> UnordCollection for UnordBag<T> {}
716
717impl<T> Extend<T> for UnordBag<T> {
718    fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
719        self.inner.extend(iter)
720    }
721}
722
723impl<T, I: Iterator<Item = T>> From<UnordItems<T, I>> for UnordBag<T> {
724    fn from(value: UnordItems<T, I>) -> Self {
725        UnordBag { inner: Vec::from_iter(value.0) }
726    }
727}
728
729impl<V: Hash + Eq + StableHash> StableHash for UnordBag<V> {
730    #[inline]
731    fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
732        hash_iter_order_independent(self.inner.iter(), hcx, hasher);
733    }
734}
735
736#[inline]
737fn to_sorted_vec<Hcx, T, K, I>(
738    hcx: &mut Hcx,
739    iter: I,
740    cache_sort_key: bool,
741    extract_key: fn(&T) -> &K,
742) -> Vec<T>
743where
744    Hcx: StableHashCtxt,
745    I: Iterator<Item = T>,
746    K: ToStableHashKey,
747{
748    let mut items: Vec<T> = iter.collect();
749    if cache_sort_key {
750        items.sort_by_cached_key(|x| extract_key(x).to_stable_hash_key(hcx));
751    } else {
752        items.sort_unstable_by_key(|x| extract_key(x).to_stable_hash_key(hcx));
753    }
754
755    items
756}
757
758fn hash_iter_order_independent<
759    Hcx: StableHashCtxt,
760    T: StableHash,
761    I: Iterator<Item = T> + ExactSizeIterator,
762>(
763    mut it: I,
764    hcx: &mut Hcx,
765    hasher: &mut StableHasher,
766) {
767    let len = it.len();
768    len.stable_hash(hcx, hasher);
769
770    match len {
771        0 => {
772            // We're done
773        }
774        1 => {
775            // No need to instantiate a hasher
776            it.next().unwrap().stable_hash(hcx, hasher);
777        }
778        _ => {
779            let mut accumulator = Fingerprint::ZERO;
780            for item in it {
781                let mut item_hasher = StableHasher::new();
782                item.stable_hash(hcx, &mut item_hasher);
783                let item_fingerprint: Fingerprint = item_hasher.finish();
784                accumulator = accumulator.combine_commutative(item_fingerprint);
785            }
786            accumulator.stable_hash(hcx, hasher);
787        }
788    }
789}
790
791// Do not implement IntoIterator for the collections in this module.
792// They only exist to hide iteration order in the first place.
793impl<T> !IntoIterator for UnordBag<T> {}
794impl<V> !IntoIterator for UnordSet<V> {}
795impl<K, V> !IntoIterator for UnordMap<K, V> {}
796impl<T, I> !IntoIterator for UnordItems<T, I> {}