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