Introduce ExtentUnord trait for collections that can safely consume UnordItems.
This commit is contained in:
parent
cfb310939b
commit
457b787a52
@ -168,6 +168,14 @@ pub fn into_sorted_stable_ord(self) -> Vec<T>
|
||||
}
|
||||
}
|
||||
|
||||
/// 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,19 +295,31 @@ pub fn into_sorted<HCX>(self, hcx: &HCX, cache_sort_key: bool) -> Vec<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)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
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]
|
||||
fn extend_unord<I: Iterator<Item = T>>(&mut self, items: UnordItems<T, I>) {
|
||||
self.extend(items.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: Hash + Eq> Extend<V> for UnordSet<V> {
|
||||
#[inline]
|
||||
fn extend<T: IntoIterator<Item = V>>(&mut self, iter: T) {
|
||||
@ -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 @@ pub fn into_items(self) -> UnordItems<(K, V), impl Iterator<Item = (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 @@ pub fn items(&self) -> UnordItems<&V, impl Iterator<Item = &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)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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 @@ fn visit_user_provided_sigs(&mut self) {
|
||||
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!(
|
||||
|
@ -9,7 +9,7 @@
|
||||
};
|
||||
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 @@ pub fn extend(
|
||||
&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)
|
||||
}))
|
||||
|
@ -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};
|
||||
|
Loading…
Reference in New Issue
Block a user