mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-02 15:32:06 +00:00
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:
parent
fe03b46ee4
commit
cfb310939b
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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| {
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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> {
|
||||
|
@ -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]
|
||||
|
@ -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())
|
||||
|
@ -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,
|
||||
|
@ -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")]
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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 {
|
||||
|
@ -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>)>,
|
||||
|
Loading…
Reference in New Issue
Block a user