1
Fork 0

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, /// 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. /// but the chance of doing it accidentally is reduced.
#[derive(Clone)]
pub struct UnordItems<T, I: Iterator<Item = T>>(I); pub struct UnordItems<T, I: Iterator<Item = T>>(I);
impl<T, I: Iterator<Item = T>> UnordItems<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() } Self { inner: Default::default() }
} }
#[inline]
pub fn with_capacity(capacity: usize) -> Self {
Self { inner: FxHashSet::with_capacity_and_hasher(capacity, Default::default()) }
}
#[inline] #[inline]
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
self.inner.len() self.inner.len()
@ -258,9 +264,9 @@ impl<V: Eq + Hash> UnordSet<V> {
#[inline] #[inline]
pub fn to_sorted_stable_ord(&self) -> Vec<V> pub fn to_sorted_stable_ord(&self) -> Vec<V>
where 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.sort_unstable();
items 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> { impl<HCX, V: Hash + Eq + HashStable<HCX>> HashStable<HCX> for UnordSet<V> {
#[inline] #[inline]
fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) { 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> { 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] #[inline]
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
self.inner.len() self.inner.len()

View file

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

View file

@ -6,7 +6,7 @@ use hir::{
intravisit::{self, Visitor}, intravisit::{self, Visitor},
Body, Expr, ExprKind, Guard, HirId, LoopIdError, 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_hir as hir;
use rustc_index::IndexVec; use rustc_index::IndexVec;
use rustc_infer::infer::InferCtxt; use rustc_infer::infer::InferCtxt;
@ -28,7 +28,7 @@ pub(super) fn build_control_flow_graph<'tcx>(
consumed_borrowed_places: ConsumedAndBorrowedPlaces, consumed_borrowed_places: ConsumedAndBorrowedPlaces,
body: &'tcx Body<'tcx>, body: &'tcx Body<'tcx>,
num_exprs: usize, num_exprs: usize,
) -> (DropRangesBuilder, FxHashSet<HirId>) { ) -> (DropRangesBuilder, UnordSet<HirId>) {
let mut drop_range_visitor = DropRangeVisitor::new( let mut drop_range_visitor = DropRangeVisitor::new(
infcx, infcx,
typeck_results, typeck_results,
@ -528,7 +528,7 @@ impl DropRangesBuilder {
hir: Map<'_>, hir: Map<'_>,
num_exprs: usize, num_exprs: usize,
) -> Self { ) -> Self {
let mut tracked_value_map = FxHashMap::<_, TrackedValueIndex>::default(); let mut tracked_value_map = UnordMap::<_, TrackedValueIndex>::default();
let mut next = <_>::from(0u32); let mut next = <_>::from(0u32);
for value in tracked_values { for value in tracked_values {
for_each_consumable(hir, value, |value| { 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 crate::FnCtxt;
use hir::def_id::DefId; use hir::def_id::DefId;
use hir::{Body, HirId, HirIdMap, Node}; 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_hir as hir;
use rustc_index::bit_set::BitSet; use rustc_index::bit_set::BitSet;
use rustc_index::IndexVec; 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 // If drop range tracking is not enabled, skip all the analysis and produce an
// empty set of DropRanges. // empty set of DropRanges.
DropRanges { DropRanges {
tracked_value_map: FxHashMap::default(), tracked_value_map: UnordMap::default(),
nodes: IndexVec::new(), nodes: IndexVec::new(),
borrowed_temporaries: None, borrowed_temporaries: None,
} }
@ -182,9 +182,9 @@ impl TryFrom<&PlaceWithHirId<'_>> for TrackedValue {
} }
pub struct DropRanges { pub struct DropRanges {
tracked_value_map: FxHashMap<TrackedValue, TrackedValueIndex>, tracked_value_map: UnordMap<TrackedValue, TrackedValueIndex>,
nodes: IndexVec<PostOrderId, NodeInfo>, nodes: IndexVec<PostOrderId, NodeInfo>,
borrowed_temporaries: Option<FxHashSet<HirId>>, borrowed_temporaries: Option<UnordSet<HirId>>,
} }
impl DropRanges { impl DropRanges {
@ -227,7 +227,7 @@ struct DropRangesBuilder {
/// (see NodeInfo::drop_state). The hir_id_map field stores the mapping /// (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 /// from HirIds to the HirIdIndex that is used to represent that value in
/// bitvector. /// 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 /// 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. /// post-order index of the target node at the point we encounter it.

View file

@ -4,7 +4,7 @@ use crate::{
FnCtxt, FnCtxt,
}; };
use hir::{def_id::DefId, Body, HirId, HirIdMap}; 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_hir as hir;
use rustc_middle::ty::{ParamEnv, TyCtxt}; use rustc_middle::ty::{ParamEnv, TyCtxt};
use rustc_middle::{ 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 /// 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`. /// 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. /// 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. /// 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. /// Works with ExprUseVisitor to find interesting values for the drop range analysis.

View file

@ -1,6 +1,6 @@
use super::callee::DeferredCallResolution; 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 as hir;
use rustc_hir::def_id::LocalDefId; use rustc_hir::def_id::LocalDefId;
use rustc_hir::HirIdMap; use rustc_hir::HirIdMap;
@ -61,9 +61,9 @@ pub struct Inherited<'tcx> {
/// Whenever we introduce an adjustment from `!` into a type variable, /// Whenever we introduce an adjustment from `!` into a type variable,
/// we record that type variable here. This is later used to inform /// we record that type variable here. This is later used to inform
/// fallback. See the `fallback` module for details. /// 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> { impl<'tcx> Deref for Inherited<'tcx> {

View file

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

View file

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

View file

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

View file

@ -4,17 +4,14 @@
use crate::FnCtxt; use crate::FnCtxt;
use hir::def_id::LocalDefId; use hir::def_id::LocalDefId;
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::{ErrorGuaranteed, StashKey}; use rustc_errors::{ErrorGuaranteed, StashKey};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::intravisit::{self, Visitor};
use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282; 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::adjustment::{Adjust, Adjustment, PointerCoercion};
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt}; 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::symbol::sym;
use rustc_span::Span; use rustc_span::Span;
@ -376,66 +373,75 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> {
impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
fn eval_closure_size(&mut self) { fn eval_closure_size(&mut self) {
let mut res: FxHashMap<LocalDefId, ClosureSizeProfileData<'tcx>> = Default::default(); self.tcx().with_stable_hashing_context(|ref hcx| {
for (&closure_def_id, data) in self.fcx.typeck_results.borrow().closure_size_eval.iter() { let fcx_typeck_results = self.fcx.typeck_results.borrow();
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 closure_hir_id = self.tcx().hir().local_def_id_to_hir_id(closure_def_id);
let data = self.resolve(*data, &closure_hir_id); let data = self.resolve(*data, &closure_hir_id);
(closure_def_id, data)
res.insert(closure_def_id, data); })
.collect();
})
} }
self.typeck_results.closure_size_eval = res;
}
fn visit_min_capture_map(&mut self) { fn visit_min_capture_map(&mut self) {
let mut min_captures_wb = ty::MinCaptureInformationMap::with_capacity_and_hasher( self.tcx().with_stable_hashing_context(|ref hcx| {
self.fcx.typeck_results.borrow().closure_min_captures.len(), let fcx_typeck_results = self.fcx.typeck_results.borrow();
Default::default(),
); self.typeck_results.closure_min_captures = fcx_typeck_results
for (&closure_def_id, root_min_captures) in .closure_min_captures
self.fcx.typeck_results.borrow().closure_min_captures.iter() .to_sorted(hcx, false)
{ .into_iter()
let mut root_var_map_wb = ty::RootVariableMinCaptureList::with_capacity_and_hasher( .map(|(&closure_def_id, root_min_captures)| {
root_min_captures.len(), let root_var_map_wb = root_min_captures
Default::default(), .iter()
); .map(|(var_hir_id, min_list)| {
for (var_hir_id, min_list) in root_min_captures.iter() {
let min_list_wb = min_list let min_list_wb = min_list
.iter() .iter()
.map(|captured_place| { .map(|captured_place| {
let locatable = captured_place.info.path_expr_id.unwrap_or_else(|| { 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().hir().local_def_id_to_hir_id(closure_def_id)
}); });
self.resolve(captured_place.clone(), &locatable) self.resolve(captured_place.clone(), &locatable)
}) })
.collect(); .collect();
root_var_map_wb.insert(*var_hir_id, min_list_wb); (*var_hir_id, min_list_wb)
} })
min_captures_wb.insert(closure_def_id, root_var_map_wb); .collect();
} (closure_def_id, root_var_map_wb)
})
self.typeck_results.closure_min_captures = min_captures_wb; .collect();
})
} }
fn visit_fake_reads_map(&mut self) { fn visit_fake_reads_map(&mut self) {
let mut resolved_closure_fake_reads: FxHashMap< self.tcx().with_stable_hashing_context(move |ref hcx| {
LocalDefId, let fcx_typeck_results = self.fcx.typeck_results.borrow();
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.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); let resolved_fake_read = self.resolve(place.clone(), &locatable);
resolved_fake_reads.push((resolved_fake_read, *cause, *hir_id)); (resolved_fake_read, *cause, *hir_id)
} })
resolved_closure_fake_reads.insert(closure_def_id, resolved_fake_reads); .collect();
}
self.typeck_results.closure_fake_reads = resolved_closure_fake_reads; (closure_def_id, resolved_fake_reads)
})
.collect();
});
} }
fn visit_closures(&mut self) { 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); assert_eq!(fcx_typeck_results.hir_owner, self.typeck_results.hir_owner);
self.typeck_results.generator_interior_types = self.typeck_results.generator_interior_types =
fcx_typeck_results.generator_interior_types.clone(); fcx_typeck_results.generator_interior_types.clone();
for (&expr_def_id, predicates) in fcx_typeck_results.generator_interior_predicates.iter() { self.tcx().with_stable_hashing_context(move |ref hcx| {
let predicates = self.resolve(predicates.clone(), &self.fcx.tcx.def_span(expr_def_id)); 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); self.typeck_results.generator_interior_predicates.insert(expr_def_id, predicates);
} }
})
} }
#[instrument(skip(self), level = "debug")] #[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::fx::{FxHashMap, FxIndexMap};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::Node; use rustc_hir::{HirIdMap, Node};
use rustc_macros::HashStable; use rustc_macros::HashStable;
use rustc_query_system::ich::StableHashingContext; use rustc_query_system::ich::StableHashingContext;
use rustc_span::{Span, DUMMY_SP}; 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 /// and not the enclosing *statement*. Expressions that are not present in this
/// table are not rvalue candidates. The set of rvalue candidates is computed /// table are not rvalue candidates. The set of rvalue candidates is computed
/// during type check based on a traversal of the AST. /// 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 /// If there are any `yield` nested within a scope, this map
/// stores the `Span` of the last one and its index in the /// 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 std::fmt::Write;
use crate::query::Providers; 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::def_id::{DefId, LocalDefId};
use rustc_hir::{self as hir, LangItem}; use rustc_hir::{self as hir, LangItem};
use rustc_span::def_id::LocalDefIdMap;
use rustc_span::symbol::Ident; use rustc_span::symbol::Ident;
use rustc_span::{Span, Symbol}; use rustc_span::{Span, Symbol};
@ -56,12 +57,9 @@ pub enum UpvarCapture {
ByRef(BorrowKind), 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 /// 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. /// 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`. /// 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 /// 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::{ pub use self::closure::{
is_ancestor_or_same_capture, place_to_string_for_capture, BorrowKind, CaptureInfo, is_ancestor_or_same_capture, place_to_string_for_capture, BorrowKind, CaptureInfo,
CapturedPlace, ClosureKind, ClosureTypeInfo, MinCaptureInformationMap, MinCaptureList, CapturedPlace, ClosureKind, ClosureTypeInfo, MinCaptureInformationMap, MinCaptureList,
RootVariableMinCaptureList, UpvarCapture, UpvarCaptureMap, UpvarId, UpvarListMap, UpvarPath, RootVariableMinCaptureList, UpvarCapture, UpvarId, UpvarPath, CAPTURE_STRUCT_LOCAL,
CAPTURE_STRUCT_LOCAL,
}; };
pub use self::consts::{ pub use self::consts::{
Const, ConstData, ConstInt, Expr, InferConst, ScalarInt, UnevaluatedConst, ValTree, Const, ConstData, ConstInt, Expr, InferConst, ScalarInt, UnevaluatedConst, ValTree,

View file

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

View file

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