Enable potential_query_instability lint in rustc_hir_typeck.

Fix linting errors by using FxIndex(Map|Set) and Unord(Map|Set) as appropriate.
This commit is contained in:
Michael Woerister 2023-07-04 16:22:01 +02:00
parent fe03b46ee4
commit cfb310939b
15 changed files with 172 additions and 145 deletions

View File

@ -31,6 +31,7 @@ use crate::{
///
/// It's still possible to do the same thing with an `Fn` by using interior mutability,
/// but the chance of doing it accidentally is reduced.
#[derive(Clone)]
pub struct UnordItems<T, I: Iterator<Item = T>>(I);
impl<T, I: Iterator<Item = T>> UnordItems<T, I> {
@ -194,6 +195,11 @@ impl<V: Eq + Hash> UnordSet<V> {
Self { inner: Default::default() }
}
#[inline]
pub fn with_capacity(capacity: usize) -> Self {
Self { inner: FxHashSet::with_capacity_and_hasher(capacity, Default::default()) }
}
#[inline]
pub fn len(&self) -> usize {
self.inner.len()
@ -258,9 +264,9 @@ impl<V: Eq + Hash> UnordSet<V> {
#[inline]
pub fn to_sorted_stable_ord(&self) -> Vec<V>
where
V: Ord + StableOrd + Copy,
V: Ord + StableOrd + Clone,
{
let mut items: Vec<V> = self.inner.iter().copied().collect();
let mut items: Vec<V> = self.inner.iter().cloned().collect();
items.sort_unstable();
items
}
@ -312,6 +318,12 @@ impl<V: Hash + Eq> From<FxHashSet<V>> for UnordSet<V> {
}
}
impl<V: Hash + Eq, I: Iterator<Item = V>> From<UnordItems<V, I>> for UnordSet<V> {
fn from(value: UnordItems<V, I>) -> Self {
UnordSet { inner: FxHashSet::from_iter(value.0) }
}
}
impl<HCX, V: Hash + Eq + HashStable<HCX>> HashStable<HCX> for UnordSet<V> {
#[inline]
fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) {
@ -362,6 +374,11 @@ impl<K: Hash + Eq, V, I: Iterator<Item = (K, V)>> From<UnordItems<(K, V), I>> fo
}
impl<K: Eq + Hash, V> UnordMap<K, V> {
#[inline]
pub fn with_capacity(capacity: usize) -> Self {
Self { inner: FxHashMap::with_capacity_and_hasher(capacity, Default::default()) }
}
#[inline]
pub fn len(&self) -> usize {
self.inner.len()

View File

@ -1,8 +1,8 @@
use crate::FnCtxt;
use rustc_data_structures::{
fx::{FxHashMap, FxHashSet},
graph::WithSuccessors,
graph::{iterate::DepthFirstSearch, vec_graph::VecGraph},
unord::{UnordBag, UnordMap, UnordSet},
};
use rustc_middle::ty::{self, Ty};
@ -83,7 +83,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
fn fallback_if_possible(
&self,
ty: Ty<'tcx>,
diverging_fallback: &FxHashMap<Ty<'tcx>, Ty<'tcx>>,
diverging_fallback: &UnordMap<Ty<'tcx>, Ty<'tcx>>,
) {
// Careful: we do NOT shallow-resolve `ty`. We know that `ty`
// is an unsolved variable, and we determine its fallback
@ -193,7 +193,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
fn calculate_diverging_fallback(
&self,
unsolved_variables: &[Ty<'tcx>],
) -> FxHashMap<Ty<'tcx>, Ty<'tcx>> {
) -> UnordMap<Ty<'tcx>, Ty<'tcx>> {
debug!("calculate_diverging_fallback({:?})", unsolved_variables);
// Construct a coercion graph where an edge `A -> B` indicates
@ -210,10 +210,10 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
//
// These variables are the ones that are targets for fallback to
// either `!` or `()`.
let diverging_roots: FxHashSet<ty::TyVid> = self
let diverging_roots: UnordSet<ty::TyVid> = self
.diverging_type_vars
.borrow()
.iter()
.items()
.map(|&ty| self.shallow_resolve(ty))
.filter_map(|ty| ty.ty_vid())
.map(|vid| self.root_var(vid))
@ -284,8 +284,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
// For each diverging variable, figure out whether it can
// reach a member of N. If so, it falls back to `()`. Else
// `!`.
let mut diverging_fallback = FxHashMap::default();
diverging_fallback.reserve(diverging_vids.len());
let mut diverging_fallback = UnordMap::with_capacity(diverging_vids.len());
for &diverging_vid in &diverging_vids {
let diverging_ty = Ty::new_var(self.tcx, diverging_vid);
let root_vid = self.root_var(diverging_vid);
@ -293,14 +292,19 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
.depth_first_search(root_vid)
.any(|n| roots_reachable_from_non_diverging.visited(n));
let mut found_infer_var_info = ty::InferVarInfo { self_in_trait: false, output: false };
let infer_var_infos: UnordBag<_> = self
.inh
.infer_var_info
.borrow()
.items()
.filter(|&(vid, _)| self.infcx.root_var(*vid) == root_vid)
.map(|(_, info)| *info)
.collect();
for (vid, info) in self.inh.infer_var_info.borrow().iter() {
if self.infcx.root_var(*vid) == root_vid {
found_infer_var_info.self_in_trait |= info.self_in_trait;
found_infer_var_info.output |= info.output;
}
}
let found_infer_var_info = ty::InferVarInfo {
self_in_trait: infer_var_infos.items().any(|info| info.self_in_trait),
output: infer_var_infos.items().any(|info| info.output),
};
if found_infer_var_info.self_in_trait && found_infer_var_info.output {
// This case falls back to () to ensure that the code pattern in

View File

@ -6,7 +6,7 @@ use hir::{
intravisit::{self, Visitor},
Body, Expr, ExprKind, Guard, HirId, LoopIdError,
};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::unord::{UnordMap, UnordSet};
use rustc_hir as hir;
use rustc_index::IndexVec;
use rustc_infer::infer::InferCtxt;
@ -28,7 +28,7 @@ pub(super) fn build_control_flow_graph<'tcx>(
consumed_borrowed_places: ConsumedAndBorrowedPlaces,
body: &'tcx Body<'tcx>,
num_exprs: usize,
) -> (DropRangesBuilder, FxHashSet<HirId>) {
) -> (DropRangesBuilder, UnordSet<HirId>) {
let mut drop_range_visitor = DropRangeVisitor::new(
infcx,
typeck_results,
@ -528,7 +528,7 @@ impl DropRangesBuilder {
hir: Map<'_>,
num_exprs: usize,
) -> Self {
let mut tracked_value_map = FxHashMap::<_, TrackedValueIndex>::default();
let mut tracked_value_map = UnordMap::<_, TrackedValueIndex>::default();
let mut next = <_>::from(0u32);
for value in tracked_values {
for_each_consumable(hir, value, |value| {

View File

@ -17,7 +17,7 @@ use self::record_consumed_borrow::find_consumed_and_borrowed;
use crate::FnCtxt;
use hir::def_id::DefId;
use hir::{Body, HirId, HirIdMap, Node};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::unord::{UnordMap, UnordSet};
use rustc_hir as hir;
use rustc_index::bit_set::BitSet;
use rustc_index::IndexVec;
@ -63,7 +63,7 @@ pub fn compute_drop_ranges<'a, 'tcx>(
// If drop range tracking is not enabled, skip all the analysis and produce an
// empty set of DropRanges.
DropRanges {
tracked_value_map: FxHashMap::default(),
tracked_value_map: UnordMap::default(),
nodes: IndexVec::new(),
borrowed_temporaries: None,
}
@ -182,9 +182,9 @@ impl TryFrom<&PlaceWithHirId<'_>> for TrackedValue {
}
pub struct DropRanges {
tracked_value_map: FxHashMap<TrackedValue, TrackedValueIndex>,
tracked_value_map: UnordMap<TrackedValue, TrackedValueIndex>,
nodes: IndexVec<PostOrderId, NodeInfo>,
borrowed_temporaries: Option<FxHashSet<HirId>>,
borrowed_temporaries: Option<UnordSet<HirId>>,
}
impl DropRanges {
@ -227,7 +227,7 @@ struct DropRangesBuilder {
/// (see NodeInfo::drop_state). The hir_id_map field stores the mapping
/// from HirIds to the HirIdIndex that is used to represent that value in
/// bitvector.
tracked_value_map: FxHashMap<TrackedValue, TrackedValueIndex>,
tracked_value_map: UnordMap<TrackedValue, TrackedValueIndex>,
/// When building the control flow graph, we don't always know the
/// post-order index of the target node at the point we encounter it.

View File

@ -4,7 +4,7 @@ use crate::{
FnCtxt,
};
use hir::{def_id::DefId, Body, HirId, HirIdMap};
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::{fx::FxIndexSet, unord::UnordSet};
use rustc_hir as hir;
use rustc_middle::ty::{ParamEnv, TyCtxt};
use rustc_middle::{
@ -30,13 +30,13 @@ pub(super) struct ConsumedAndBorrowedPlaces {
///
/// Note that this set excludes "partial drops" -- for example, a statement like `drop(x.y)` is
/// not considered a drop of `x`, although it would be a drop of `x.y`.
pub(super) consumed: HirIdMap<FxHashSet<TrackedValue>>,
pub(super) consumed: HirIdMap<FxIndexSet<TrackedValue>>,
/// A set of hir-ids of values or variables that are borrowed at some point within the body.
pub(super) borrowed: FxHashSet<TrackedValue>,
pub(super) borrowed: UnordSet<TrackedValue>,
/// A set of hir-ids of values or variables that are borrowed at some point within the body.
pub(super) borrowed_temporaries: FxHashSet<HirId>,
pub(super) borrowed_temporaries: UnordSet<HirId>,
}
/// Works with ExprUseVisitor to find interesting values for the drop range analysis.

View File

@ -1,6 +1,6 @@
use super::callee::DeferredCallResolution;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::unord::{UnordMap, UnordSet};
use rustc_hir as hir;
use rustc_hir::def_id::LocalDefId;
use rustc_hir::HirIdMap;
@ -61,9 +61,9 @@ pub struct Inherited<'tcx> {
/// Whenever we introduce an adjustment from `!` into a type variable,
/// we record that type variable here. This is later used to inform
/// fallback. See the `fallback` module for details.
pub(super) diverging_type_vars: RefCell<FxHashSet<Ty<'tcx>>>,
pub(super) diverging_type_vars: RefCell<UnordSet<Ty<'tcx>>>,
pub(super) infer_var_info: RefCell<FxHashMap<ty::TyVid, ty::InferVarInfo>>,
pub(super) infer_var_info: RefCell<UnordMap<ty::TyVid, ty::InferVarInfo>>,
}
impl<'tcx> Deref for Inherited<'tcx> {

View File

@ -6,7 +6,6 @@
#![feature(min_specialization)]
#![feature(control_flow_enum)]
#![feature(option_as_slice)]
#![allow(rustc::potential_query_instability)]
#![recursion_limit = "256"]
#[macro_use]

View File

@ -7,7 +7,9 @@ use crate::errors::NoAssociatedItem;
use crate::Expectation;
use crate::FnCtxt;
use rustc_ast::ast::Mutability;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::fx::FxIndexSet;
use rustc_data_structures::unord::UnordSet;
use rustc_errors::StashKey;
use rustc_errors::{
pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed,
@ -31,6 +33,7 @@ use rustc_middle::ty::fast_reject::{simplify_type, TreatParams};
use rustc_middle::ty::print::{with_crate_prefix, with_forced_trimmed_paths};
use rustc_middle::ty::IsSuggestable;
use rustc_middle::ty::{self, GenericArgKind, Ty, TyCtxt, TypeVisitableExt};
use rustc_span::def_id::DefIdSet;
use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::Symbol;
use rustc_span::{edit_distance, source_map, ExpnKind, FileName, MacroKind, Span};
@ -536,11 +539,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
));
}
} else if !unsatisfied_predicates.is_empty() {
let mut type_params = FxHashMap::default();
let mut type_params = FxIndexMap::default();
// Pick out the list of unimplemented traits on the receiver.
// This is used for custom error messages with the `#[rustc_on_unimplemented]` attribute.
let mut unimplemented_traits = FxHashMap::default();
let mut unimplemented_traits = FxIndexMap::default();
let mut unimplemented_traits_only = true;
for (predicate, _parent_pred, cause) in unsatisfied_predicates {
if let (ty::PredicateKind::Clause(ty::ClauseKind::Trait(p)), Some(cause)) =
@ -606,7 +609,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
);
type_params
.entry(key)
.or_insert_with(FxHashSet::default)
.or_insert_with(UnordSet::default)
.insert(obligation.to_owned());
return true;
}
@ -680,8 +683,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
};
// Find all the requirements that come from a local `impl` block.
let mut skip_list: FxHashSet<_> = Default::default();
let mut spanned_predicates = FxHashMap::default();
let mut skip_list: UnordSet<_> = Default::default();
let mut spanned_predicates = FxIndexMap::default();
for (p, parent_p, cause) in unsatisfied_predicates {
// Extract the predicate span and parent def id of the cause,
// if we have one.
@ -723,7 +726,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let span = self_ty.span.ctxt().outer_expn_data().call_site;
let entry = spanned_predicates.entry(span);
let entry = entry.or_insert_with(|| {
(FxHashSet::default(), FxHashSet::default(), Vec::new())
(FxIndexSet::default(), FxIndexSet::default(), Vec::new())
});
entry.0.insert(span);
entry.1.insert((
@ -771,7 +774,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
skip_list.insert(p);
let entry = spanned_predicates.entry(self_ty.span);
let entry = entry.or_insert_with(|| {
(FxHashSet::default(), FxHashSet::default(), Vec::new())
(FxIndexSet::default(), FxIndexSet::default(), Vec::new())
});
entry.2.push(p);
if cause_span != *item_span {
@ -806,7 +809,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
skip_list.insert(p);
let entry = spanned_predicates.entry(ident.span);
let entry = entry.or_insert_with(|| {
(FxHashSet::default(), FxHashSet::default(), Vec::new())
(FxIndexSet::default(), FxIndexSet::default(), Vec::new())
});
entry.0.insert(cause_span);
entry.1.insert((ident.span, ""));
@ -840,7 +843,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
unsatisfied_bounds = true;
}
let mut suggested_bounds = FxHashSet::default();
let mut suggested_bounds = UnordSet::default();
// The requirements that didn't have an `impl` span to show.
let mut bound_list = unsatisfied_predicates
.iter()
@ -889,8 +892,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
for ((span, add_where_or_comma), obligations) in type_params.into_iter() {
restrict_type_params = true;
// #74886: Sort here so that the output is always the same.
let mut obligations = obligations.into_iter().collect::<Vec<_>>();
obligations.sort();
let obligations = obligations.to_sorted_stable_ord();
err.span_suggestion_verbose(
span,
format!(
@ -2053,7 +2055,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ty::Adt(def, _) => Some(def.did()),
_ => None,
})
.collect::<FxHashSet<_>>();
.collect::<FxIndexSet<_>>();
let mut spans: MultiSpan = def_ids
.iter()
.filter_map(|def_id| {
@ -2669,7 +2671,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
Nothing,
}
let ast_generics = hir.get_generics(id.owner.def_id).unwrap();
let trait_def_ids: FxHashSet<DefId> = ast_generics
let trait_def_ids: DefIdSet = ast_generics
.bounds_for_param(def_id)
.flat_map(|bp| bp.bounds.iter())
.filter_map(|bound| bound.trait_ref()?.trait_def_id())

View File

@ -33,6 +33,7 @@
use super::FnCtxt;
use crate::expr_use_visitor as euv;
use rustc_data_structures::unord::UnordSet;
use rustc_errors::{Applicability, MultiSpan};
use rustc_hir as hir;
use rustc_hir::def_id::LocalDefId;
@ -48,7 +49,7 @@ use rustc_span::sym;
use rustc_span::{BytePos, Pos, Span, Symbol};
use rustc_trait_selection::infer::InferCtxtExt;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_target::abi::FIRST_VARIANT;
use std::iter;
@ -910,19 +911,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// Combines all the reasons for 2229 migrations
fn compute_2229_migrations_reasons(
&self,
auto_trait_reasons: FxHashSet<&'static str>,
auto_trait_reasons: UnordSet<&'static str>,
drop_order: bool,
) -> MigrationWarningReason {
let mut reasons = MigrationWarningReason::default();
reasons.auto_traits.extend(auto_trait_reasons);
reasons.drop_order = drop_order;
// `auto_trait_reasons` are in hashset order, so sort them to put the
// diagnostics we emit later in a cross-platform-consistent order.
reasons.auto_traits.sort_unstable();
reasons
MigrationWarningReason {
auto_traits: auto_trait_reasons.to_sorted_stable_ord(),
drop_order,
}
}
/// Figures out the list of root variables (and their types) that aren't completely
@ -936,7 +931,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
min_captures: Option<&ty::RootVariableMinCaptureList<'tcx>>,
var_hir_id: hir::HirId,
closure_clause: hir::CaptureBy,
) -> Option<FxHashMap<UpvarMigrationInfo, FxHashSet<&'static str>>> {
) -> Option<FxIndexMap<UpvarMigrationInfo, UnordSet<&'static str>>> {
let auto_traits_def_id = vec![
self.tcx.lang_items().clone_trait(),
self.tcx.lang_items().sync_trait(),
@ -981,7 +976,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}));
}
let mut problematic_captures = FxHashMap::default();
let mut problematic_captures = FxIndexMap::default();
// Check whether captured fields also implement the trait
for capture in root_var_min_capture_list.iter() {
let ty = apply_capture_kind_on_capture_ty(
@ -1001,7 +996,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}));
}
let mut capture_problems = FxHashSet::default();
let mut capture_problems = UnordSet::default();
// Checks if for any of the auto traits, one or more trait is implemented
// by the root variable but not by the capture
@ -1047,7 +1042,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
min_captures: Option<&ty::RootVariableMinCaptureList<'tcx>>,
closure_clause: hir::CaptureBy,
var_hir_id: hir::HirId,
) -> Option<FxHashSet<UpvarMigrationInfo>> {
) -> Option<FxIndexSet<UpvarMigrationInfo>> {
let ty = self.resolve_vars_if_possible(self.node_ty(var_hir_id));
if !ty.has_significant_drop(self.tcx, self.tcx.param_env(closure_def_id)) {
@ -1069,7 +1064,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
match closure_clause {
// Only migrate if closure is a move closure
hir::CaptureBy::Value => {
let mut diagnostics_info = FxHashSet::default();
let mut diagnostics_info = FxIndexSet::default();
let upvars =
self.tcx.upvars_mentioned(closure_def_id).expect("must be an upvar");
let upvar = upvars[&var_hir_id];
@ -1085,7 +1080,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
debug!(?root_var_min_capture_list);
let mut projections_list = Vec::new();
let mut diagnostics_info = FxHashSet::default();
let mut diagnostics_info = FxIndexSet::default();
for captured_place in root_var_min_capture_list.iter() {
match captured_place.info.capture_kind {
@ -1155,7 +1150,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
};
let mut need_migrations = Vec::new();
let mut auto_trait_migration_reasons = FxHashSet::default();
let mut auto_trait_migration_reasons = UnordSet::default();
let mut drop_migration_needed = false;
// Perform auto-trait analysis
@ -1167,7 +1162,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
{
diagnostics_info
} else {
FxHashMap::default()
FxIndexMap::default()
};
let drop_reorder_diagnostic = if let Some(diagnostics_info) = self
@ -1181,7 +1176,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
drop_migration_needed = true;
diagnostics_info
} else {
FxHashSet::default()
FxIndexSet::default()
};
// Combine all the captures responsible for needing migrations into one HashSet
@ -1198,7 +1193,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if let Some(reasons) = auto_trait_diagnostic.get(&captures_info) {
reasons.clone()
} else {
FxHashSet::default()
UnordSet::default()
};
// Check if migration is needed because of drop reorder as a result of that capture
@ -1206,7 +1201,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Combine all the reasons of why the root variable should be captured as a result of
// auto trait implementation issues
auto_trait_migration_reasons.extend(capture_trait_reasons.iter().copied());
auto_trait_migration_reasons.extend_unord(capture_trait_reasons.items().copied());
diagnostics_info.push(MigrationLintNote {
captures_info,

View File

@ -4,17 +4,14 @@
use crate::FnCtxt;
use hir::def_id::LocalDefId;
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::{ErrorGuaranteed, StashKey};
use rustc_hir as hir;
use rustc_hir::intravisit::{self, Visitor};
use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
use rustc_middle::hir::place::Place as HirPlace;
use rustc_middle::mir::FakeReadCause;
use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion};
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt};
use rustc_middle::ty::{self, ClosureSizeProfileData, Ty, TyCtxt};
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_span::symbol::sym;
use rustc_span::Span;
@ -376,66 +373,75 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> {
impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
fn eval_closure_size(&mut self) {
let mut res: FxHashMap<LocalDefId, ClosureSizeProfileData<'tcx>> = Default::default();
for (&closure_def_id, data) in self.fcx.typeck_results.borrow().closure_size_eval.iter() {
let closure_hir_id = self.tcx().hir().local_def_id_to_hir_id(closure_def_id);
self.tcx().with_stable_hashing_context(|ref hcx| {
let fcx_typeck_results = self.fcx.typeck_results.borrow();
let data = self.resolve(*data, &closure_hir_id);
res.insert(closure_def_id, data);
}
self.typeck_results.closure_size_eval = res;
self.typeck_results.closure_size_eval = fcx_typeck_results
.closure_size_eval
.to_sorted(hcx, false)
.into_iter()
.map(|(&closure_def_id, data)| {
let closure_hir_id = self.tcx().hir().local_def_id_to_hir_id(closure_def_id);
let data = self.resolve(*data, &closure_hir_id);
(closure_def_id, data)
})
.collect();
})
}
fn visit_min_capture_map(&mut self) {
let mut min_captures_wb = ty::MinCaptureInformationMap::with_capacity_and_hasher(
self.fcx.typeck_results.borrow().closure_min_captures.len(),
Default::default(),
);
for (&closure_def_id, root_min_captures) in
self.fcx.typeck_results.borrow().closure_min_captures.iter()
{
let mut root_var_map_wb = ty::RootVariableMinCaptureList::with_capacity_and_hasher(
root_min_captures.len(),
Default::default(),
);
for (var_hir_id, min_list) in root_min_captures.iter() {
let min_list_wb = min_list
.iter()
.map(|captured_place| {
let locatable = captured_place.info.path_expr_id.unwrap_or_else(|| {
self.tcx().hir().local_def_id_to_hir_id(closure_def_id)
});
self.tcx().with_stable_hashing_context(|ref hcx| {
let fcx_typeck_results = self.fcx.typeck_results.borrow();
self.resolve(captured_place.clone(), &locatable)
})
.collect();
root_var_map_wb.insert(*var_hir_id, min_list_wb);
}
min_captures_wb.insert(closure_def_id, root_var_map_wb);
}
self.typeck_results.closure_min_captures = min_captures_wb;
self.typeck_results.closure_min_captures = fcx_typeck_results
.closure_min_captures
.to_sorted(hcx, false)
.into_iter()
.map(|(&closure_def_id, root_min_captures)| {
let root_var_map_wb = root_min_captures
.iter()
.map(|(var_hir_id, min_list)| {
let min_list_wb = min_list
.iter()
.map(|captured_place| {
let locatable =
captured_place.info.path_expr_id.unwrap_or_else(|| {
self.tcx().hir().local_def_id_to_hir_id(closure_def_id)
});
self.resolve(captured_place.clone(), &locatable)
})
.collect();
(*var_hir_id, min_list_wb)
})
.collect();
(closure_def_id, root_var_map_wb)
})
.collect();
})
}
fn visit_fake_reads_map(&mut self) {
let mut resolved_closure_fake_reads: FxHashMap<
LocalDefId,
Vec<(HirPlace<'tcx>, FakeReadCause, hir::HirId)>,
> = Default::default();
for (&closure_def_id, fake_reads) in
self.fcx.typeck_results.borrow().closure_fake_reads.iter()
{
let mut resolved_fake_reads = Vec::<(HirPlace<'tcx>, FakeReadCause, hir::HirId)>::new();
for (place, cause, hir_id) in fake_reads.iter() {
let locatable = self.tcx().hir().local_def_id_to_hir_id(closure_def_id);
self.tcx().with_stable_hashing_context(move |ref hcx| {
let fcx_typeck_results = self.fcx.typeck_results.borrow();
let resolved_fake_read = self.resolve(place.clone(), &locatable);
resolved_fake_reads.push((resolved_fake_read, *cause, *hir_id));
}
resolved_closure_fake_reads.insert(closure_def_id, resolved_fake_reads);
}
self.typeck_results.closure_fake_reads = resolved_closure_fake_reads;
self.typeck_results.closure_fake_reads = fcx_typeck_results
.closure_fake_reads
.to_sorted(hcx, true)
.into_iter()
.map(|(&closure_def_id, fake_reads)| {
let resolved_fake_reads = fake_reads
.iter()
.map(|(place, cause, hir_id)| {
let locatable = self.tcx().hir().local_def_id_to_hir_id(closure_def_id);
let resolved_fake_read = self.resolve(place.clone(), &locatable);
(resolved_fake_read, *cause, *hir_id)
})
.collect();
(closure_def_id, resolved_fake_reads)
})
.collect();
});
}
fn visit_closures(&mut self) {
@ -540,10 +546,15 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
assert_eq!(fcx_typeck_results.hir_owner, self.typeck_results.hir_owner);
self.typeck_results.generator_interior_types =
fcx_typeck_results.generator_interior_types.clone();
for (&expr_def_id, predicates) in fcx_typeck_results.generator_interior_predicates.iter() {
let predicates = self.resolve(predicates.clone(), &self.fcx.tcx.def_span(expr_def_id));
self.typeck_results.generator_interior_predicates.insert(expr_def_id, predicates);
}
self.tcx().with_stable_hashing_context(move |ref hcx| {
for (&expr_def_id, predicates) in
fcx_typeck_results.generator_interior_predicates.to_sorted(hcx, false).into_iter()
{
let predicates =
self.resolve(predicates.clone(), &self.fcx.tcx.def_span(expr_def_id));
self.typeck_results.generator_interior_predicates.insert(expr_def_id, predicates);
}
})
}
#[instrument(skip(self), level = "debug")]

View File

@ -10,7 +10,7 @@ use crate::ty::TyCtxt;
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_hir as hir;
use rustc_hir::Node;
use rustc_hir::{HirIdMap, Node};
use rustc_macros::HashStable;
use rustc_query_system::ich::StableHashingContext;
use rustc_span::{Span, DUMMY_SP};
@ -228,7 +228,7 @@ pub struct ScopeTree {
/// and not the enclosing *statement*. Expressions that are not present in this
/// table are not rvalue candidates. The set of rvalue candidates is computed
/// during type check based on a traversal of the AST.
pub rvalue_candidates: FxHashMap<hir::HirId, RvalueCandidateType>,
pub rvalue_candidates: HirIdMap<RvalueCandidateType>,
/// If there are any `yield` nested within a scope, this map
/// stores the `Span` of the last one and its index in the

View File

@ -6,9 +6,10 @@ use crate::{mir, ty};
use std::fmt::Write;
use crate::query::Providers;
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
use rustc_data_structures::fx::FxIndexMap;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::{self as hir, LangItem};
use rustc_span::def_id::LocalDefIdMap;
use rustc_span::symbol::Ident;
use rustc_span::{Span, Symbol};
@ -56,12 +57,9 @@ pub enum UpvarCapture {
ByRef(BorrowKind),
}
pub type UpvarListMap = FxHashMap<DefId, FxIndexMap<hir::HirId, UpvarId>>;
pub type UpvarCaptureMap = FxHashMap<UpvarId, UpvarCapture>;
/// Given the closure DefId this map provides a map of root variables to minimum
/// set of `CapturedPlace`s that need to be tracked to support all captures of that closure.
pub type MinCaptureInformationMap<'tcx> = FxHashMap<LocalDefId, RootVariableMinCaptureList<'tcx>>;
pub type MinCaptureInformationMap<'tcx> = LocalDefIdMap<RootVariableMinCaptureList<'tcx>>;
/// Part of `MinCaptureInformationMap`; Maps a root variable to the list of `CapturedPlace`.
/// Used to track the minimum set of `Place`s that need to be captured to support all

View File

@ -82,8 +82,7 @@ pub use self::binding::BindingMode::*;
pub use self::closure::{
is_ancestor_or_same_capture, place_to_string_for_capture, BorrowKind, CaptureInfo,
CapturedPlace, ClosureKind, ClosureTypeInfo, MinCaptureInformationMap, MinCaptureList,
RootVariableMinCaptureList, UpvarCapture, UpvarCaptureMap, UpvarId, UpvarListMap, UpvarPath,
CAPTURE_STRUCT_LOCAL,
RootVariableMinCaptureList, UpvarCapture, UpvarId, UpvarPath, CAPTURE_STRUCT_LOCAL,
};
pub use self::consts::{
Const, ConstData, ConstInt, Expr, InferConst, ScalarInt, UnevaluatedConst, ValTree,

View File

@ -1,12 +1,12 @@
use crate::middle::region::{Scope, ScopeData, ScopeTree};
use rustc_data_structures::fx::FxHashMap;
use rustc_hir as hir;
use rustc_hir::ItemLocalMap;
/// `RvalueScopes` is a mapping from sub-expressions to _extended_ lifetime as determined by
/// rules laid out in `rustc_hir_analysis::check::rvalue_scopes`.
#[derive(TyEncodable, TyDecodable, Clone, Debug, Default, Eq, PartialEq, HashStable)]
pub struct RvalueScopes {
map: FxHashMap<hir::ItemLocalId, Option<Scope>>,
map: ItemLocalMap<Option<Scope>>,
}
impl RvalueScopes {

View File

@ -7,8 +7,10 @@ use crate::{
GenericArgKind, InternalSubsts, SubstsRef, Ty, UserSubsts,
},
};
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
use rustc_data_structures::unord::{UnordItems, UnordSet};
use rustc_data_structures::{
fx::FxIndexMap,
unord::{UnordItems, UnordSet},
};
use rustc_errors::ErrorGuaranteed;
use rustc_hir as hir;
use rustc_hir::{
@ -180,7 +182,7 @@ pub struct TypeckResults<'tcx> {
/// we never capture `t`. This becomes an issue when we build MIR as we require
/// information on `t` in order to create place `t.0` and `t.1`. We can solve this
/// issue by fake reading `t`.
pub closure_fake_reads: FxHashMap<LocalDefId, Vec<(HirPlace<'tcx>, FakeReadCause, hir::HirId)>>,
pub closure_fake_reads: LocalDefIdMap<Vec<(HirPlace<'tcx>, FakeReadCause, hir::HirId)>>,
/// Tracks the rvalue scoping rules which defines finer scoping for rvalue expressions
/// by applying extended parameter rules.
@ -194,7 +196,7 @@ pub struct TypeckResults<'tcx> {
/// Stores the predicates that apply on generator witness types.
/// formatting modified file tests/ui/generator/retain-resume-ref.rs
pub generator_interior_predicates:
FxHashMap<LocalDefId, Vec<(ty::Predicate<'tcx>, ObligationCause<'tcx>)>>,
LocalDefIdMap<Vec<(ty::Predicate<'tcx>, ObligationCause<'tcx>)>>,
/// We sometimes treat byte string literals (which are of type `&[u8; N]`)
/// as `&[u8]`, depending on the pattern in which they are used.
@ -204,7 +206,7 @@ pub struct TypeckResults<'tcx> {
/// Contains the data for evaluating the effect of feature `capture_disjoint_fields`
/// on closure size.
pub closure_size_eval: FxHashMap<LocalDefId, ClosureSizeProfileData<'tcx>>,
pub closure_size_eval: LocalDefIdMap<ClosureSizeProfileData<'tcx>>,
/// Container types and field indices of `offset_of!` expressions
offset_of_data: ItemLocalMap<(Ty<'tcx>, Vec<FieldIdx>)>,