Auto merge of #99725 - lcnr:dedup-region_bound_pairs, r=compiler-errors
use `FxIndexSet` for `region_bound_pairs` should help with #99217 and might generally be a perf improvement. r? types
This commit is contained in:
commit
ada80a13b9
5 changed files with 37 additions and 35 deletions
|
@ -1,6 +1,7 @@
|
|||
use crate::infer::free_regions::FreeRegionMap;
|
||||
use crate::infer::{GenericKind, InferCtxt};
|
||||
use crate::traits::query::OutlivesBound;
|
||||
use rustc_data_structures::fx::FxIndexSet;
|
||||
use rustc_middle::ty::{self, ReEarlyBound, ReFree, ReVar, Region};
|
||||
|
||||
use super::explicit_outlives_bounds;
|
||||
|
@ -53,7 +54,8 @@ pub struct OutlivesEnvironment<'tcx> {
|
|||
/// "Region-bound pairs" tracks outlives relations that are known to
|
||||
/// be true, either because of explicit where-clauses like `T: 'a` or
|
||||
/// because of implied bounds.
|
||||
pub type RegionBoundPairs<'tcx> = Vec<(Region<'tcx>, GenericKind<'tcx>)>;
|
||||
pub type RegionBoundPairs<'tcx> =
|
||||
FxIndexSet<ty::OutlivesPredicate<GenericKind<'tcx>, Region<'tcx>>>;
|
||||
|
||||
impl<'a, 'tcx> OutlivesEnvironment<'tcx> {
|
||||
pub fn new(param_env: ty::ParamEnv<'tcx>) -> Self {
|
||||
|
@ -97,10 +99,12 @@ impl<'a, 'tcx> OutlivesEnvironment<'tcx> {
|
|||
debug!("add_outlives_bounds: outlives_bound={:?}", outlives_bound);
|
||||
match outlives_bound {
|
||||
OutlivesBound::RegionSubParam(r_a, param_b) => {
|
||||
self.region_bound_pairs.push((r_a, GenericKind::Param(param_b)));
|
||||
self.region_bound_pairs
|
||||
.insert(ty::OutlivesPredicate(GenericKind::Param(param_b), r_a));
|
||||
}
|
||||
OutlivesBound::RegionSubProjection(r_a, projection_b) => {
|
||||
self.region_bound_pairs.push((r_a, GenericKind::Projection(projection_b)));
|
||||
self.region_bound_pairs
|
||||
.insert(ty::OutlivesPredicate(GenericKind::Projection(projection_b), r_a));
|
||||
}
|
||||
OutlivesBound::RegionSubRegion(r_a, r_b) => {
|
||||
if let (ReEarlyBound(_) | ReFree(_), ReVar(vid_b)) = (r_a.kind(), r_b.kind()) {
|
||||
|
|
|
@ -6,7 +6,7 @@ use rustc_data_structures::captures::Captures;
|
|||
use rustc_data_structures::sso::SsoHashSet;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_middle::ty::subst::{GenericArg, Subst};
|
||||
use rustc_middle::ty::{self, EarlyBinder, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{self, EarlyBinder, OutlivesPredicate, Ty, TyCtxt};
|
||||
|
||||
use smallvec::smallvec;
|
||||
|
||||
|
@ -259,16 +259,17 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
|
|||
// The problem is that the type of `x` is `&'a A`. To be
|
||||
// well-formed, then, A must outlive `'a`, but we don't know that
|
||||
// this holds from first principles.
|
||||
let from_region_bound_pairs = self.region_bound_pairs.iter().filter_map(|&(r, p)| {
|
||||
debug!(
|
||||
"declared_generic_bounds_from_env_for_erased_ty: region_bound_pair = {:?}",
|
||||
(r, p)
|
||||
);
|
||||
let p_ty = p.to_ty(tcx);
|
||||
let erased_p_ty = self.tcx.erase_regions(p_ty);
|
||||
(erased_p_ty == erased_ty)
|
||||
.then_some(ty::Binder::dummy(ty::OutlivesPredicate(p.to_ty(tcx), r)))
|
||||
});
|
||||
let from_region_bound_pairs =
|
||||
self.region_bound_pairs.iter().filter_map(|&OutlivesPredicate(p, r)| {
|
||||
debug!(
|
||||
"declared_generic_bounds_from_env_for_erased_ty: region_bound_pair = {:?}",
|
||||
(r, p)
|
||||
);
|
||||
let p_ty = p.to_ty(tcx);
|
||||
let erased_p_ty = self.tcx.erase_regions(p_ty);
|
||||
(erased_p_ty == erased_ty)
|
||||
.then_some(ty::Binder::dummy(ty::OutlivesPredicate(p.to_ty(tcx), r)))
|
||||
});
|
||||
|
||||
param_bounds
|
||||
.chain(from_region_bound_pairs)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue