diff options
| -rw-r--r-- | compiler/rustc_data_structures/src/unord.rs | 52 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/check_unused.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_hir_typeck/src/upvar.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_hir_typeck/src/writeback.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/typeck_results.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_mir_transform/src/check_unsafety.rs | 2 | 
6 files changed, 39 insertions, 26 deletions
| diff --git a/compiler/rustc_data_structures/src/unord.rs b/compiler/rustc_data_structures/src/unord.rs index ec779854f36..47c56eba7ad 100644 --- a/compiler/rustc_data_structures/src/unord.rs +++ b/compiler/rustc_data_structures/src/unord.rs @@ -168,6 +168,14 @@ impl<T: Ord, I: Iterator<Item = T>> UnordItems<T, I> { } } +/// A marker trait specifying that `Self` can consume `UnordItems<_>` without +/// exposing any internal ordering. +/// +/// Note: right now this is just a marker trait. It could be extended to contain +/// some useful, common methods though, like `len`, `clear`, or the various +/// kinds of `to_sorted`. +trait UnordCollection {} + /// This is a set collection type that tries very hard to not expose /// any internal iteration. This is a useful property when trying to /// uphold the determinism invariants imposed by the query system. @@ -182,6 +190,8 @@ pub struct UnordSet<V: Eq + Hash> { inner: FxHashSet<V>, } +impl<V: Eq + Hash> UnordCollection for UnordSet<V> {} + impl<V: Eq + Hash> Default for UnordSet<V> { #[inline] fn default() -> Self { @@ -285,16 +295,28 @@ impl<V: Eq + Hash> UnordSet<V> { to_sorted_vec(hcx, self.inner.into_iter(), cache_sort_key, |x| x) } - // We can safely extend this UnordSet from a set of unordered values because that - // won't expose the internal ordering anywhere. #[inline] - pub fn extend_unord<I: Iterator<Item = V>>(&mut self, items: UnordItems<V, I>) { - self.inner.extend(items.0) + pub fn clear(&mut self) { + self.inner.clear(); } +} + +pub trait ExtendUnord<T> { + /// Extend this unord collection with the given `UnordItems`. + /// This method is called `extend_unord` instead of just `extend` so it + /// does not conflict with `Extend::extend`. Otherwise there would be many + /// places where the two methods would have to be explicitly disambiguated + /// via UFCS. + fn extend_unord<I: Iterator<Item = T>>(&mut self, items: UnordItems<T, I>); +} +// Note: it is important that `C` implements `UnordCollection` in addition to +// `Extend`, otherwise this impl would leak the internal iteration order of +// `items`, e.g. when calling `some_vec.extend_unord(some_unord_items)`. +impl<C: Extend<T> + UnordCollection, T> ExtendUnord<T> for C { #[inline] - pub fn clear(&mut self) { - self.inner.clear(); + fn extend_unord<I: Iterator<Item = T>>(&mut self, items: UnordItems<T, I>) { + self.extend(items.0) } } @@ -345,6 +367,8 @@ pub struct UnordMap<K: Eq + Hash, V> { inner: FxHashMap<K, V>, } +impl<K: Eq + Hash, V> UnordCollection for UnordMap<K, V> {} + impl<K: Eq + Hash, V> Default for UnordMap<K, V> { #[inline] fn default() -> Self { @@ -445,13 +469,6 @@ impl<K: Eq + Hash, V> UnordMap<K, V> { UnordItems(self.inner.into_iter()) } - // We can safely extend this UnordMap from a set of unordered values because that - // won't expose the internal ordering anywhere. - #[inline] - pub fn extend<I: Iterator<Item = (K, V)>>(&mut self, items: UnordItems<(K, V), I>) { - self.inner.extend(items.0) - } - /// Returns the entries of this map in stable sort order (as defined by `ToStableHashKey`). /// /// The `cache_sort_key` parameter controls if [slice::sort_by_cached_key] or @@ -571,15 +588,10 @@ impl<V> UnordBag<V> { pub fn into_items(self) -> UnordItems<V, impl Iterator<Item = V>> { UnordItems(self.inner.into_iter()) } - - // We can safely extend this UnordSet from a set of unordered values because that - // won't expose the internal ordering anywhere. - #[inline] - pub fn extend<I: Iterator<Item = V>>(&mut self, items: UnordItems<V, I>) { - self.inner.extend(items.0) - } } +impl<T> UnordCollection for UnordBag<T> {} + impl<T> Extend<T> for UnordBag<T> { fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) { self.inner.extend(iter) diff --git a/compiler/rustc_hir_analysis/src/check_unused.rs b/compiler/rustc_hir_analysis/src/check_unused.rs index 3471d5f1e77..5318e637fc7 100644 --- a/compiler/rustc_hir_analysis/src/check_unused.rs +++ b/compiler/rustc_hir_analysis/src/check_unused.rs @@ -1,4 +1,4 @@ -use rustc_data_structures::unord::UnordSet; +use rustc_data_structures::unord::{ExtendUnord, UnordSet}; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; use rustc_middle::ty::TyCtxt; diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index 14c073707e6..a3838275dc5 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -33,7 +33,7 @@ use super::FnCtxt; use crate::expr_use_visitor as euv; -use rustc_data_structures::unord::UnordSet; +use rustc_data_structures::unord::{ExtendUnord, UnordSet}; use rustc_errors::{Applicability, MultiSpan}; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index eef2b835cbb..fab6090ff19 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -4,6 +4,7 @@ use crate::FnCtxt; use hir::def_id::LocalDefId; +use rustc_data_structures::unord::ExtendUnord; use rustc_errors::{ErrorGuaranteed, StashKey}; use rustc_hir as hir; use rustc_hir::intravisit::{self, Visitor}; @@ -526,7 +527,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { let fcx_typeck_results = self.fcx.typeck_results.borrow(); assert_eq!(fcx_typeck_results.hir_owner, self.typeck_results.hir_owner); - self.typeck_results.user_provided_sigs.extend( + self.typeck_results.user_provided_sigs.extend_unord( fcx_typeck_results.user_provided_sigs.items().map(|(&def_id, c_sig)| { if cfg!(debug_assertions) && c_sig.has_infer() { span_bug!( diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index 3a63e28d97e..9c25c01b056 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -9,7 +9,7 @@ use crate::{ }; use rustc_data_structures::{ fx::FxIndexMap, - unord::{UnordItems, UnordSet}, + unord::{ExtendUnord, UnordItems, UnordSet}, }; use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; @@ -635,7 +635,7 @@ impl<'a, V> LocalTableInContextMut<'a, V> { &mut self, items: UnordItems<(hir::HirId, V), impl Iterator<Item = (hir::HirId, V)>>, ) { - self.data.extend(items.map(|(id, value)| { + self.data.extend_unord(items.map(|(id, value)| { validate_hir_id_for_typeck_results(self.hir_owner, id); (id.local_id, value) })) diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs index 70812761e88..58e9786ec1a 100644 --- a/compiler/rustc_mir_transform/src/check_unsafety.rs +++ b/compiler/rustc_mir_transform/src/check_unsafety.rs @@ -1,4 +1,4 @@ -use rustc_data_structures::unord::{UnordItems, UnordSet}; +use rustc_data_structures::unord::{ExtendUnord, UnordItems, UnordSet}; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; | 
