Auto merge of #118824 - aliemjay:perf-region-cons, r=compiler-errors
use Vec for region constraints instead of BTreeMap ~1% perf gain Diagnostic regressions need more investigation. r? `@ghost`
This commit is contained in:
commit
d6d7a93866
@ -408,13 +408,18 @@ fn try_extract_error_from_region_constraints<'tcx>(
|
|||||||
mut region_var_origin: impl FnMut(RegionVid) -> RegionVariableOrigin,
|
mut region_var_origin: impl FnMut(RegionVid) -> RegionVariableOrigin,
|
||||||
mut universe_of_region: impl FnMut(RegionVid) -> UniverseIndex,
|
mut universe_of_region: impl FnMut(RegionVid) -> UniverseIndex,
|
||||||
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
|
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
|
||||||
|
let placeholder_universe = match placeholder_region.kind() {
|
||||||
|
ty::RePlaceholder(p) => p.universe,
|
||||||
|
ty::ReVar(vid) => universe_of_region(vid),
|
||||||
|
_ => ty::UniverseIndex::ROOT,
|
||||||
|
};
|
||||||
let matches =
|
let matches =
|
||||||
|a_region: Region<'tcx>, b_region: Region<'tcx>| match (a_region.kind(), b_region.kind()) {
|
|a_region: Region<'tcx>, b_region: Region<'tcx>| match (a_region.kind(), b_region.kind()) {
|
||||||
(RePlaceholder(a_p), RePlaceholder(b_p)) => a_p.bound == b_p.bound,
|
(RePlaceholder(a_p), RePlaceholder(b_p)) => a_p.bound == b_p.bound,
|
||||||
_ => a_region == b_region,
|
_ => a_region == b_region,
|
||||||
};
|
};
|
||||||
let check = |constraint: &Constraint<'tcx>, cause: &SubregionOrigin<'tcx>, exact| {
|
let mut check =
|
||||||
match *constraint {
|
|constraint: &Constraint<'tcx>, cause: &SubregionOrigin<'tcx>, exact| match *constraint {
|
||||||
Constraint::RegSubReg(sub, sup)
|
Constraint::RegSubReg(sub, sup)
|
||||||
if ((exact && sup == placeholder_region)
|
if ((exact && sup == placeholder_region)
|
||||||
|| (!exact && matches(sup, placeholder_region)))
|
|| (!exact && matches(sup, placeholder_region)))
|
||||||
@ -422,15 +427,15 @@ fn try_extract_error_from_region_constraints<'tcx>(
|
|||||||
{
|
{
|
||||||
Some((sub, cause.clone()))
|
Some((sub, cause.clone()))
|
||||||
}
|
}
|
||||||
// FIXME: Should this check the universe of the var?
|
|
||||||
Constraint::VarSubReg(vid, sup)
|
Constraint::VarSubReg(vid, sup)
|
||||||
if ((exact && sup == placeholder_region)
|
if (exact
|
||||||
|| (!exact && matches(sup, placeholder_region))) =>
|
&& sup == placeholder_region
|
||||||
|
&& !universe_of_region(vid).can_name(placeholder_universe))
|
||||||
|
|| (!exact && matches(sup, placeholder_region)) =>
|
||||||
{
|
{
|
||||||
Some((ty::Region::new_var(infcx.tcx, vid), cause.clone()))
|
Some((ty::Region::new_var(infcx.tcx, vid), cause.clone()))
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
|
||||||
};
|
};
|
||||||
let mut info = region_constraints
|
let mut info = region_constraints
|
||||||
.constraints
|
.constraints
|
||||||
|
@ -135,6 +135,10 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
|
|||||||
) -> LexicalRegionResolutions<'tcx> {
|
) -> LexicalRegionResolutions<'tcx> {
|
||||||
let mut var_data = self.construct_var_data();
|
let mut var_data = self.construct_var_data();
|
||||||
|
|
||||||
|
// Deduplicating constraints is shown to have a positive perf impact.
|
||||||
|
self.data.constraints.sort_by_key(|(constraint, _)| *constraint);
|
||||||
|
self.data.constraints.dedup_by_key(|(constraint, _)| *constraint);
|
||||||
|
|
||||||
if cfg!(debug_assertions) {
|
if cfg!(debug_assertions) {
|
||||||
self.dump_constraints();
|
self.dump_constraints();
|
||||||
}
|
}
|
||||||
@ -181,7 +185,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
|
|||||||
let mut constraints = IndexVec::from_elem(Vec::new(), &var_values.values);
|
let mut constraints = IndexVec::from_elem(Vec::new(), &var_values.values);
|
||||||
// Tracks the changed region vids.
|
// Tracks the changed region vids.
|
||||||
let mut changes = Vec::new();
|
let mut changes = Vec::new();
|
||||||
for constraint in self.data.constraints.keys() {
|
for (constraint, _) in &self.data.constraints {
|
||||||
match *constraint {
|
match *constraint {
|
||||||
Constraint::RegSubVar(a_region, b_vid) => {
|
Constraint::RegSubVar(a_region, b_vid) => {
|
||||||
let b_data = var_values.value_mut(b_vid);
|
let b_data = var_values.value_mut(b_vid);
|
||||||
@ -676,7 +680,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
|
|||||||
let dummy_source = graph.add_node(());
|
let dummy_source = graph.add_node(());
|
||||||
let dummy_sink = graph.add_node(());
|
let dummy_sink = graph.add_node(());
|
||||||
|
|
||||||
for constraint in self.data.constraints.keys() {
|
for (constraint, _) in &self.data.constraints {
|
||||||
match *constraint {
|
match *constraint {
|
||||||
Constraint::VarSubVar(a_id, b_id) => {
|
Constraint::VarSubVar(a_id, b_id) => {
|
||||||
graph.add_edge(NodeIndex(a_id.index()), NodeIndex(b_id.index()), *constraint);
|
graph.add_edge(NodeIndex(a_id.index()), NodeIndex(b_id.index()), *constraint);
|
||||||
@ -883,9 +887,11 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Constraint::RegSubVar(region, _) | Constraint::VarSubReg(_, region) => {
|
Constraint::RegSubVar(region, _) | Constraint::VarSubReg(_, region) => {
|
||||||
|
let constraint_idx =
|
||||||
|
this.constraints.binary_search_by(|(c, _)| c.cmp(&edge.data)).unwrap();
|
||||||
state.result.push(RegionAndOrigin {
|
state.result.push(RegionAndOrigin {
|
||||||
region,
|
region,
|
||||||
origin: this.constraints.get(&edge.data).unwrap().clone(),
|
origin: this.constraints[constraint_idx].1.clone(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -416,8 +416,8 @@ impl<'tcx> MiniGraph<'tcx> {
|
|||||||
region_constraints.undo_log.region_constraints_in_snapshot(&snapshot.undo_snapshot)
|
region_constraints.undo_log.region_constraints_in_snapshot(&snapshot.undo_snapshot)
|
||||||
{
|
{
|
||||||
match undo_entry {
|
match undo_entry {
|
||||||
AddConstraint(constraint) => {
|
&AddConstraint(i) => {
|
||||||
each_constraint(constraint);
|
each_constraint(®ion_constraints.data().constraints[i].0);
|
||||||
}
|
}
|
||||||
&AddVerify(i) => span_bug!(
|
&AddVerify(i) => span_bug!(
|
||||||
region_constraints.data().verifys[i].origin.span(),
|
region_constraints.data().verifys[i].origin.span(),
|
||||||
@ -430,8 +430,8 @@ impl<'tcx> MiniGraph<'tcx> {
|
|||||||
region_constraints
|
region_constraints
|
||||||
.data()
|
.data()
|
||||||
.constraints
|
.constraints
|
||||||
.keys()
|
.iter()
|
||||||
.for_each(|constraint| each_constraint(constraint));
|
.for_each(|(constraint, _)| each_constraint(constraint));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +20,6 @@ use rustc_middle::ty::{ReBound, ReVar};
|
|||||||
use rustc_middle::ty::{Region, RegionVid};
|
use rustc_middle::ty::{Region, RegionVid};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
use std::collections::BTreeMap;
|
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
use std::{cmp, fmt, mem};
|
use std::{cmp, fmt, mem};
|
||||||
|
|
||||||
@ -90,7 +89,7 @@ pub type VarInfos = IndexVec<RegionVid, RegionVariableInfo>;
|
|||||||
pub struct RegionConstraintData<'tcx> {
|
pub struct RegionConstraintData<'tcx> {
|
||||||
/// Constraints of the form `A <= B`, where either `A` or `B` can
|
/// Constraints of the form `A <= B`, where either `A` or `B` can
|
||||||
/// be a region variable (or neither, as it happens).
|
/// be a region variable (or neither, as it happens).
|
||||||
pub constraints: BTreeMap<Constraint<'tcx>, SubregionOrigin<'tcx>>,
|
pub constraints: Vec<(Constraint<'tcx>, SubregionOrigin<'tcx>)>,
|
||||||
|
|
||||||
/// Constraints of the form `R0 member of [R1, ..., Rn]`, meaning that
|
/// Constraints of the form `R0 member of [R1, ..., Rn]`, meaning that
|
||||||
/// `R0` must be equal to one of the regions `R1..Rn`. These occur
|
/// `R0` must be equal to one of the regions `R1..Rn`. These occur
|
||||||
@ -273,7 +272,7 @@ pub(crate) enum UndoLog<'tcx> {
|
|||||||
AddVar(RegionVid),
|
AddVar(RegionVid),
|
||||||
|
|
||||||
/// We added the given `constraint`.
|
/// We added the given `constraint`.
|
||||||
AddConstraint(Constraint<'tcx>),
|
AddConstraint(usize),
|
||||||
|
|
||||||
/// We added the given `verify`.
|
/// We added the given `verify`.
|
||||||
AddVerify(usize),
|
AddVerify(usize),
|
||||||
@ -319,8 +318,9 @@ impl<'tcx> RegionConstraintStorage<'tcx> {
|
|||||||
self.var_infos.pop().unwrap();
|
self.var_infos.pop().unwrap();
|
||||||
assert_eq!(self.var_infos.len(), vid.index());
|
assert_eq!(self.var_infos.len(), vid.index());
|
||||||
}
|
}
|
||||||
AddConstraint(ref constraint) => {
|
AddConstraint(index) => {
|
||||||
self.data.constraints.remove(constraint);
|
self.data.constraints.pop().unwrap();
|
||||||
|
assert_eq!(self.data.constraints.len(), index);
|
||||||
}
|
}
|
||||||
AddVerify(index) => {
|
AddVerify(index) => {
|
||||||
self.data.verifys.pop();
|
self.data.verifys.pop();
|
||||||
@ -443,14 +443,9 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
|
|||||||
// cannot add constraints once regions are resolved
|
// cannot add constraints once regions are resolved
|
||||||
debug!("RegionConstraintCollector: add_constraint({:?})", constraint);
|
debug!("RegionConstraintCollector: add_constraint({:?})", constraint);
|
||||||
|
|
||||||
// never overwrite an existing (constraint, origin) - only insert one if it isn't
|
let index = self.storage.data.constraints.len();
|
||||||
// present in the map yet. This prevents origins from outside the snapshot being
|
self.storage.data.constraints.push((constraint, origin));
|
||||||
// replaced with "less informative" origins e.g., during calls to `can_eq`
|
self.undo_log.push(AddConstraint(index));
|
||||||
let undo_log = &mut self.undo_log;
|
|
||||||
self.storage.data.constraints.entry(constraint).or_insert_with(|| {
|
|
||||||
undo_log.push(AddConstraint(constraint));
|
|
||||||
origin
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_verify(&mut self, verify: Verify<'tcx>) {
|
fn add_verify(&mut self, verify: Verify<'tcx>) {
|
||||||
|
@ -477,7 +477,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
|
|||||||
let mut vid_map: FxHashMap<RegionTarget<'cx>, RegionDeps<'cx>> = FxHashMap::default();
|
let mut vid_map: FxHashMap<RegionTarget<'cx>, RegionDeps<'cx>> = FxHashMap::default();
|
||||||
let mut finished_map = FxHashMap::default();
|
let mut finished_map = FxHashMap::default();
|
||||||
|
|
||||||
for constraint in regions.constraints.keys() {
|
for (constraint, _) in ®ions.constraints {
|
||||||
match constraint {
|
match constraint {
|
||||||
&Constraint::VarSubVar(r1, r2) => {
|
&Constraint::VarSubVar(r1, r2) => {
|
||||||
{
|
{
|
||||||
|
@ -195,7 +195,7 @@ where
|
|||||||
// into a map. Each RegionTarget (either a RegionVid or a Region) maps
|
// into a map. Each RegionTarget (either a RegionVid or a Region) maps
|
||||||
// to its smaller and larger regions. Note that 'larger' regions correspond
|
// to its smaller and larger regions. Note that 'larger' regions correspond
|
||||||
// to sub-regions in Rust code (e.g., in 'a: 'b, 'a is the larger region).
|
// to sub-regions in Rust code (e.g., in 'a: 'b, 'a is the larger region).
|
||||||
for constraint in regions.constraints.keys() {
|
for (constraint, _) in ®ions.constraints {
|
||||||
match *constraint {
|
match *constraint {
|
||||||
Constraint::VarSubVar(r1, r2) => {
|
Constraint::VarSubVar(r1, r2) => {
|
||||||
{
|
{
|
||||||
|
@ -4,8 +4,8 @@ error[E0308]: mismatched types
|
|||||||
LL | assert_all::<_, &String>(id);
|
LL | assert_all::<_, &String>(id);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
|
| ^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
|
||||||
|
|
|
|
||||||
= note: expected reference `&String`
|
= note: expected trait `for<'a> <for<'a> fn(&'a String) -> &'a String {id} as FnMut<(&'a String,)>>`
|
||||||
found reference `&String`
|
found trait `for<'a> <for<'a> fn(&'a String) -> &'a String {id} as FnMut<(&'a String,)>>`
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user