Allow for more efficient sorting when exporting Unord collections.
This commit is contained in:
parent
c3d2573120
commit
72ee14ce39
@ -177,7 +177,7 @@ fn exported_symbols_provider_local(
|
|||||||
// Can we skip the later sorting?
|
// Can we skip the later sorting?
|
||||||
let mut symbols: Vec<_> = tcx.with_stable_hashing_context(|hcx| {
|
let mut symbols: Vec<_> = tcx.with_stable_hashing_context(|hcx| {
|
||||||
tcx.reachable_non_generics(LOCAL_CRATE)
|
tcx.reachable_non_generics(LOCAL_CRATE)
|
||||||
.to_sorted(&hcx)
|
.to_sorted(&hcx, true)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(&def_id, &info)| (ExportedSymbol::NonGeneric(def_id), info))
|
.map(|(&def_id, &info)| (ExportedSymbol::NonGeneric(def_id), info))
|
||||||
.collect()
|
.collect()
|
||||||
|
@ -14,7 +14,7 @@ use std::{
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
fingerprint::Fingerprint,
|
fingerprint::Fingerprint,
|
||||||
stable_hasher::{HashStable, StableHasher, ToStableHashKey},
|
stable_hasher::{HashStable, StableHasher, StableOrd, ToStableHashKey},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// `UnordItems` is the order-less version of `Iterator`. It only contains methods
|
/// `UnordItems` is the order-less version of `Iterator`. It only contains methods
|
||||||
@ -158,6 +158,7 @@ pub struct UnordSet<V: Eq + Hash> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<V: Eq + Hash> Default for UnordSet<V> {
|
impl<V: Eq + Hash> Default for UnordSet<V> {
|
||||||
|
#[inline]
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self { inner: FxHashSet::default() }
|
Self { inner: FxHashSet::default() }
|
||||||
}
|
}
|
||||||
@ -207,6 +208,46 @@ impl<V: Eq + Hash> UnordSet<V> {
|
|||||||
UnordItems(self.inner.into_iter())
|
UnordItems(self.inner.into_iter())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn to_sorted<HCX>(&self, hcx: &HCX, cache_sort_key: bool) -> Vec<&V>
|
||||||
|
where
|
||||||
|
V: ToStableHashKey<HCX>,
|
||||||
|
{
|
||||||
|
let mut items: Vec<&V> = self.inner.iter().collect();
|
||||||
|
if cache_sort_key {
|
||||||
|
items.sort_by_cached_key(|k| k.to_stable_hash_key(hcx));
|
||||||
|
} else {
|
||||||
|
items.sort_unstable_by_key(|k| k.to_stable_hash_key(hcx));
|
||||||
|
}
|
||||||
|
|
||||||
|
items
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn to_sorted_stable_ord(&self) -> Vec<V>
|
||||||
|
where
|
||||||
|
V: Ord + StableOrd + Copy,
|
||||||
|
{
|
||||||
|
let mut items: Vec<V> = self.inner.iter().copied().collect();
|
||||||
|
items.sort_unstable();
|
||||||
|
items
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn into_sorted<HCX>(self, hcx: &HCX, cache_sort_key: bool) -> Vec<V>
|
||||||
|
where
|
||||||
|
V: ToStableHashKey<HCX>,
|
||||||
|
{
|
||||||
|
let mut items: Vec<V> = self.inner.into_iter().collect();
|
||||||
|
if cache_sort_key {
|
||||||
|
items.sort_by_cached_key(|k| k.to_stable_hash_key(hcx));
|
||||||
|
} else {
|
||||||
|
items.sort_unstable_by_key(|k| k.to_stable_hash_key(hcx));
|
||||||
|
}
|
||||||
|
|
||||||
|
items
|
||||||
|
}
|
||||||
|
|
||||||
// We can safely extend this UnordSet from a set of unordered values because that
|
// We can safely extend this UnordSet from a set of unordered values because that
|
||||||
// won't expose the internal ordering anywhere.
|
// won't expose the internal ordering anywhere.
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -221,12 +262,14 @@ impl<V: Eq + Hash> UnordSet<V> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<V: Hash + Eq> Extend<V> for UnordSet<V> {
|
impl<V: Hash + Eq> Extend<V> for UnordSet<V> {
|
||||||
|
#[inline]
|
||||||
fn extend<T: IntoIterator<Item = V>>(&mut self, iter: T) {
|
fn extend<T: IntoIterator<Item = V>>(&mut self, iter: T) {
|
||||||
self.inner.extend(iter)
|
self.inner.extend(iter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<V: Hash + Eq> FromIterator<V> for UnordSet<V> {
|
impl<V: Hash + Eq> FromIterator<V> for UnordSet<V> {
|
||||||
|
#[inline]
|
||||||
fn from_iter<T: IntoIterator<Item = V>>(iter: T) -> Self {
|
fn from_iter<T: IntoIterator<Item = V>>(iter: T) -> Self {
|
||||||
UnordSet { inner: FxHashSet::from_iter(iter) }
|
UnordSet { inner: FxHashSet::from_iter(iter) }
|
||||||
}
|
}
|
||||||
@ -254,24 +297,28 @@ pub struct UnordMap<K: Eq + Hash, V> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<K: Eq + Hash, V> Default for UnordMap<K, V> {
|
impl<K: Eq + Hash, V> Default for UnordMap<K, V> {
|
||||||
|
#[inline]
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self { inner: FxHashMap::default() }
|
Self { inner: FxHashMap::default() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<K: Hash + Eq, V> Extend<(K, V)> for UnordMap<K, V> {
|
impl<K: Hash + Eq, V> Extend<(K, V)> for UnordMap<K, V> {
|
||||||
|
#[inline]
|
||||||
fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
|
fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
|
||||||
self.inner.extend(iter)
|
self.inner.extend(iter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<K: Hash + Eq, V> FromIterator<(K, V)> for UnordMap<K, V> {
|
impl<K: Hash + Eq, V> FromIterator<(K, V)> for UnordMap<K, V> {
|
||||||
|
#[inline]
|
||||||
fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
|
fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
|
||||||
UnordMap { inner: FxHashMap::from_iter(iter) }
|
UnordMap { inner: FxHashMap::from_iter(iter) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<K: Hash + Eq, V, I: Iterator<Item = (K, V)>> From<UnordItems<(K, V), I>> for UnordMap<K, V> {
|
impl<K: Hash + Eq, V, I: Iterator<Item = (K, V)>> From<UnordItems<(K, V), I>> for UnordMap<K, V> {
|
||||||
|
#[inline]
|
||||||
fn from(items: UnordItems<(K, V), I>) -> Self {
|
fn from(items: UnordItems<(K, V), I>) -> Self {
|
||||||
UnordMap { inner: FxHashMap::from_iter(items.0) }
|
UnordMap { inner: FxHashMap::from_iter(items.0) }
|
||||||
}
|
}
|
||||||
@ -351,30 +398,56 @@ impl<K: Eq + Hash, V> UnordMap<K, V> {
|
|||||||
self.inner.extend(items.0)
|
self.inner.extend(items.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_sorted<HCX>(&self, hcx: &HCX) -> Vec<(&K, &V)>
|
#[inline]
|
||||||
|
pub fn to_sorted<HCX>(&self, hcx: &HCX, cache_sort_key: bool) -> Vec<(&K, &V)>
|
||||||
where
|
where
|
||||||
K: ToStableHashKey<HCX>,
|
K: ToStableHashKey<HCX>,
|
||||||
{
|
{
|
||||||
let mut items: Vec<(&K, &V)> = self.inner.iter().collect();
|
let mut items: Vec<(&K, &V)> = self.inner.iter().collect();
|
||||||
items.sort_by_cached_key(|(k, _)| k.to_stable_hash_key(hcx));
|
if cache_sort_key {
|
||||||
|
items.sort_by_cached_key(|(k, _)| k.to_stable_hash_key(hcx));
|
||||||
|
} else {
|
||||||
|
items.sort_unstable_by_key(|(k, _)| k.to_stable_hash_key(hcx));
|
||||||
|
}
|
||||||
|
|
||||||
items
|
items
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn into_sorted<HCX>(self, hcx: &HCX) -> Vec<(K, V)>
|
#[inline]
|
||||||
|
pub fn to_sorted_stable_ord(&self) -> Vec<(K, &V)>
|
||||||
|
where
|
||||||
|
K: Ord + StableOrd + Copy,
|
||||||
|
{
|
||||||
|
let mut items: Vec<(K, &V)> = self.inner.iter().map(|(&k, v)| (k, v)).collect();
|
||||||
|
items.sort_unstable_by_key(|&(k, _)| k);
|
||||||
|
items
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn into_sorted<HCX>(self, hcx: &HCX, cache_sort_key: bool) -> Vec<(K, V)>
|
||||||
where
|
where
|
||||||
K: ToStableHashKey<HCX>,
|
K: ToStableHashKey<HCX>,
|
||||||
{
|
{
|
||||||
let mut items: Vec<(K, V)> = self.inner.into_iter().collect();
|
let mut items: Vec<(K, V)> = self.inner.into_iter().collect();
|
||||||
items.sort_by_cached_key(|(k, _)| k.to_stable_hash_key(hcx));
|
if cache_sort_key {
|
||||||
|
items.sort_by_cached_key(|(k, _)| k.to_stable_hash_key(hcx));
|
||||||
|
} else {
|
||||||
|
items.sort_unstable_by_key(|(k, _)| k.to_stable_hash_key(hcx));
|
||||||
|
}
|
||||||
items
|
items
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn values_sorted<HCX>(&self, hcx: &HCX) -> impl Iterator<Item = &V>
|
#[inline]
|
||||||
|
pub fn values_sorted<HCX>(&self, hcx: &HCX, cache_sort_key: bool) -> impl Iterator<Item = &V>
|
||||||
where
|
where
|
||||||
K: ToStableHashKey<HCX>,
|
K: ToStableHashKey<HCX>,
|
||||||
{
|
{
|
||||||
let mut items: Vec<(&K, &V)> = self.inner.iter().collect();
|
let mut items: Vec<(&K, &V)> = self.inner.iter().collect();
|
||||||
items.sort_by_cached_key(|(k, _)| k.to_stable_hash_key(hcx));
|
if cache_sort_key {
|
||||||
|
items.sort_by_cached_key(|(k, _)| k.to_stable_hash_key(hcx));
|
||||||
|
} else {
|
||||||
|
items.sort_unstable_by_key(|(k, _)| k.to_stable_hash_key(hcx));
|
||||||
|
}
|
||||||
items.into_iter().map(|(_, v)| v)
|
items.into_iter().map(|(_, v)| v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,6 @@ use rustc_middle::ty::TypeckResults;
|
|||||||
use rustc_middle::ty::{self, ClosureSizeProfileData, Ty, TyCtxt};
|
use rustc_middle::ty::{self, ClosureSizeProfileData, Ty, TyCtxt};
|
||||||
use rustc_span::symbol::sym;
|
use rustc_span::symbol::sym;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use smallvec::SmallVec;
|
|
||||||
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ops::ControlFlow;
|
use std::ops::ControlFlow;
|
||||||
@ -450,9 +449,9 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
|||||||
let common_hir_owner = fcx_typeck_results.hir_owner;
|
let common_hir_owner = fcx_typeck_results.hir_owner;
|
||||||
|
|
||||||
let fcx_closure_kind_origins =
|
let fcx_closure_kind_origins =
|
||||||
fcx_typeck_results.closure_kind_origins().items_in_stable_order(self.tcx());
|
fcx_typeck_results.closure_kind_origins().items_in_stable_order();
|
||||||
|
|
||||||
for (&local_id, origin) in fcx_closure_kind_origins {
|
for (local_id, origin) in fcx_closure_kind_origins {
|
||||||
let hir_id = hir::HirId { owner: common_hir_owner, local_id };
|
let hir_id = hir::HirId { owner: common_hir_owner, local_id };
|
||||||
let place_span = origin.0;
|
let place_span = origin.0;
|
||||||
let place = self.resolve(origin.1.clone(), &place_span);
|
let place = self.resolve(origin.1.clone(), &place_span);
|
||||||
@ -465,14 +464,10 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
|||||||
|
|
||||||
assert_eq!(fcx_typeck_results.hir_owner, self.typeck_results.hir_owner);
|
assert_eq!(fcx_typeck_results.hir_owner, self.typeck_results.hir_owner);
|
||||||
|
|
||||||
self.tcx().with_stable_hashing_context(|hcx| {
|
let fcx_coercion_casts = fcx_typeck_results.coercion_casts().to_sorted_stable_ord();
|
||||||
let fcx_coercion_casts: SmallVec<[_; 32]> =
|
for local_id in fcx_coercion_casts {
|
||||||
fcx_typeck_results.coercion_casts().items().cloned().into_sorted_small_vec(&hcx);
|
self.typeck_results.set_coercion_cast(local_id);
|
||||||
|
}
|
||||||
for local_id in fcx_coercion_casts {
|
|
||||||
self.typeck_results.set_coercion_cast(local_id);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_user_provided_tys(&mut self) {
|
fn visit_user_provided_tys(&mut self) {
|
||||||
@ -482,10 +477,10 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
|||||||
|
|
||||||
if self.rustc_dump_user_substs {
|
if self.rustc_dump_user_substs {
|
||||||
let sorted_user_provided_types =
|
let sorted_user_provided_types =
|
||||||
fcx_typeck_results.user_provided_types().items_in_stable_order(self.tcx());
|
fcx_typeck_results.user_provided_types().items_in_stable_order();
|
||||||
|
|
||||||
let mut errors_buffer = Vec::new();
|
let mut errors_buffer = Vec::new();
|
||||||
for (&local_id, c_ty) in sorted_user_provided_types {
|
for (local_id, c_ty) in sorted_user_provided_types {
|
||||||
let hir_id = hir::HirId { owner: common_hir_owner, local_id };
|
let hir_id = hir::HirId { owner: common_hir_owner, local_id };
|
||||||
|
|
||||||
if let ty::UserType::TypeOf(_, user_substs) = c_ty.value {
|
if let ty::UserType::TypeOf(_, user_substs) = c_ty.value {
|
||||||
@ -661,10 +656,9 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
|||||||
assert_eq!(fcx_typeck_results.hir_owner, self.typeck_results.hir_owner);
|
assert_eq!(fcx_typeck_results.hir_owner, self.typeck_results.hir_owner);
|
||||||
let common_hir_owner = fcx_typeck_results.hir_owner;
|
let common_hir_owner = fcx_typeck_results.hir_owner;
|
||||||
|
|
||||||
let fcx_liberated_fn_sigs =
|
let fcx_liberated_fn_sigs = fcx_typeck_results.liberated_fn_sigs().items_in_stable_order();
|
||||||
fcx_typeck_results.liberated_fn_sigs().items_in_stable_order(self.tcx());
|
|
||||||
|
|
||||||
for (&local_id, &fn_sig) in fcx_liberated_fn_sigs {
|
for (local_id, &fn_sig) in fcx_liberated_fn_sigs {
|
||||||
let hir_id = hir::HirId { owner: common_hir_owner, local_id };
|
let hir_id = hir::HirId { owner: common_hir_owner, local_id };
|
||||||
let fn_sig = self.resolve(fn_sig, &hir_id);
|
let fn_sig = self.resolve(fn_sig, &hir_id);
|
||||||
self.typeck_results.liberated_fn_sigs_mut().insert(hir_id, fn_sig);
|
self.typeck_results.liberated_fn_sigs_mut().insert(hir_id, fn_sig);
|
||||||
@ -676,10 +670,9 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
|||||||
assert_eq!(fcx_typeck_results.hir_owner, self.typeck_results.hir_owner);
|
assert_eq!(fcx_typeck_results.hir_owner, self.typeck_results.hir_owner);
|
||||||
let common_hir_owner = fcx_typeck_results.hir_owner;
|
let common_hir_owner = fcx_typeck_results.hir_owner;
|
||||||
|
|
||||||
let fcx_fru_field_types =
|
let fcx_fru_field_types = fcx_typeck_results.fru_field_types().items_in_stable_order();
|
||||||
fcx_typeck_results.fru_field_types().items_in_stable_order(self.tcx());
|
|
||||||
|
|
||||||
for (&local_id, ftys) in fcx_fru_field_types {
|
for (local_id, ftys) in fcx_fru_field_types {
|
||||||
let hir_id = hir::HirId { owner: common_hir_owner, local_id };
|
let hir_id = hir::HirId { owner: common_hir_owner, local_id };
|
||||||
let ftys = self.resolve(ftys.clone(), &hir_id);
|
let ftys = self.resolve(ftys.clone(), &hir_id);
|
||||||
self.typeck_results.fru_field_types_mut().insert(hir_id, ftys);
|
self.typeck_results.fru_field_types_mut().insert(hir_id, ftys);
|
||||||
|
@ -1188,7 +1188,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
let inherent_impls = tcx.with_stable_hashing_context(|hcx| {
|
let inherent_impls = tcx.with_stable_hashing_context(|hcx| {
|
||||||
tcx.crate_inherent_impls(()).inherent_impls.to_sorted(&hcx)
|
tcx.crate_inherent_impls(()).inherent_impls.to_sorted(&hcx, true)
|
||||||
});
|
});
|
||||||
|
|
||||||
for (def_id, implementations) in inherent_impls {
|
for (def_id, implementations) in inherent_impls {
|
||||||
|
@ -27,7 +27,7 @@ use rustc_session::Session;
|
|||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use std::{collections::hash_map::Entry, hash::Hash, iter};
|
use std::{collections::hash_map::Entry, hash::Hash, iter};
|
||||||
|
|
||||||
use super::{RvalueScopes, TyCtxt};
|
use super::RvalueScopes;
|
||||||
|
|
||||||
#[derive(TyEncodable, TyDecodable, Debug, HashStable)]
|
#[derive(TyEncodable, TyDecodable, Debug, HashStable)]
|
||||||
pub struct TypeckResults<'tcx> {
|
pub struct TypeckResults<'tcx> {
|
||||||
@ -575,9 +575,8 @@ impl<'a, V> LocalTableInContext<'a, V> {
|
|||||||
self.data.items().map(|(id, value)| (*id, value))
|
self.data.items().map(|(id, value)| (*id, value))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(rustc::pass_by_value)]
|
pub fn items_in_stable_order(&self) -> Vec<(ItemLocalId, &'a V)> {
|
||||||
pub fn items_in_stable_order(&self, tcx: TyCtxt<'_>) -> Vec<(&'a ItemLocalId, &'a V)> {
|
self.data.to_sorted_stable_ord()
|
||||||
tcx.with_stable_hashing_context(|hcx| self.data.to_sorted(&hcx))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ impl<'tcx> LateLintPass<'tcx> for MultipleInherentImpl {
|
|||||||
|
|
||||||
let inherent_impls = cx
|
let inherent_impls = cx
|
||||||
.tcx
|
.tcx
|
||||||
.with_stable_hashing_context(|hcx| cx.tcx.crate_inherent_impls(()).inherent_impls.to_sorted(&hcx));
|
.with_stable_hashing_context(|hcx| cx.tcx.crate_inherent_impls(()).inherent_impls.to_sorted(&hcx, true));
|
||||||
|
|
||||||
for (_, impl_ids) in inherent_impls.into_iter().filter(|(&id, impls)| {
|
for (_, impl_ids) in inherent_impls.into_iter().filter(|(&id, impls)| {
|
||||||
impls.len() > 1
|
impls.len() > 1
|
||||||
|
@ -81,7 +81,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingTraitMethods {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cx.tcx.with_stable_hashing_context(|hcx| {
|
cx.tcx.with_stable_hashing_context(|hcx| {
|
||||||
for assoc in provided.values_sorted(&hcx) {
|
for assoc in provided.values_sorted(&hcx, true) {
|
||||||
let source_map = cx.tcx.sess.source_map();
|
let source_map = cx.tcx.sess.source_map();
|
||||||
let definition_span = source_map.guess_head_span(cx.tcx.def_span(assoc.def_id));
|
let definition_span = source_map.guess_head_span(cx.tcx.def_span(assoc.def_id));
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user