Skip to content

Commit ada80a1

Browse files
committed
Auto merge of rust-lang#99725 - lcnr:dedup-region_bound_pairs, r=compiler-errors
use `FxIndexSet` for `region_bound_pairs` should help with rust-lang#99217 and might generally be a perf improvement. r? types
2 parents 2643b16 + 2e796ac commit ada80a1

File tree

5 files changed

+37
-35
lines changed

5 files changed

+37
-35
lines changed

compiler/rustc_borrowck/src/type_check/constraint_conversion.rs

+10
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,16 @@ pub(crate) struct ConstraintConversion<'a, 'tcx> {
2222
infcx: &'a InferCtxt<'a, 'tcx>,
2323
tcx: TyCtxt<'tcx>,
2424
universal_regions: &'a UniversalRegions<'tcx>,
25+
/// Each RBP `GK: 'a` is assumed to be true. These encode
26+
/// relationships like `T: 'a` that are added via implicit bounds
27+
/// or the `param_env`.
28+
///
29+
/// Each region here is guaranteed to be a key in the `indices`
30+
/// map. We use the "original" regions (i.e., the keys from the
31+
/// map, and not the values) because the code in
32+
/// `process_registered_region_obligations` has some special-cased
33+
/// logic expecting to see (e.g.) `ReStatic`, and if we supplied
34+
/// our special inference variable there, we would mess that up.
2535
region_bound_pairs: &'a RegionBoundPairs<'tcx>,
2636
implicit_region_bound: ty::Region<'tcx>,
2737
param_env: ty::ParamEnv<'tcx>,

compiler/rustc_borrowck/src/type_check/free_region_relations.rs

+6-15
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use rustc_data_structures::frozen::Frozen;
22
use rustc_data_structures::transitive_relation::TransitiveRelation;
33
use rustc_infer::infer::canonical::QueryRegionConstraints;
44
use rustc_infer::infer::outlives;
5+
use rustc_infer::infer::outlives::env::RegionBoundPairs;
56
use rustc_infer::infer::region_constraints::GenericKind;
67
use rustc_infer::infer::InferCtxt;
78
use rustc_middle::mir::ConstraintCategory;
@@ -34,18 +35,6 @@ pub(crate) struct UniversalRegionRelations<'tcx> {
3435
inverse_outlives: TransitiveRelation<RegionVid>,
3536
}
3637

37-
/// Each RBP `('a, GK)` indicates that `GK: 'a` can be assumed to
38-
/// be true. These encode relationships like `T: 'a` that are
39-
/// added via implicit bounds.
40-
///
41-
/// Each region here is guaranteed to be a key in the `indices`
42-
/// map. We use the "original" regions (i.e., the keys from the
43-
/// map, and not the values) because the code in
44-
/// `process_registered_region_obligations` has some special-cased
45-
/// logic expecting to see (e.g.) `ReStatic`, and if we supplied
46-
/// our special inference variable there, we would mess that up.
47-
type RegionBoundPairs<'tcx> = Vec<(ty::Region<'tcx>, GenericKind<'tcx>)>;
48-
4938
/// As part of computing the free region relations, we also have to
5039
/// normalize the input-output types, which we then need later. So we
5140
/// return those. This vector consists of first the input types and
@@ -71,7 +60,7 @@ pub(crate) fn create<'tcx>(
7160
implicit_region_bound,
7261
constraints,
7362
universal_regions: universal_regions.clone(),
74-
region_bound_pairs: Vec::new(),
63+
region_bound_pairs: Default::default(),
7564
relations: UniversalRegionRelations {
7665
universal_regions: universal_regions.clone(),
7766
outlives: Default::default(),
@@ -371,11 +360,13 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
371360
}
372361

373362
OutlivesBound::RegionSubParam(r_a, param_b) => {
374-
self.region_bound_pairs.push((r_a, GenericKind::Param(param_b)));
363+
self.region_bound_pairs
364+
.insert(ty::OutlivesPredicate(GenericKind::Param(param_b), r_a));
375365
}
376366

377367
OutlivesBound::RegionSubProjection(r_a, projection_b) => {
378-
self.region_bound_pairs.push((r_a, GenericKind::Projection(projection_b)));
368+
self.region_bound_pairs
369+
.insert(ty::OutlivesPredicate(GenericKind::Projection(projection_b), r_a));
379370
}
380371
}
381372
}

compiler/rustc_infer/src/infer/outlives/env.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::infer::free_regions::FreeRegionMap;
22
use crate::infer::{GenericKind, InferCtxt};
33
use crate::traits::query::OutlivesBound;
4+
use rustc_data_structures::fx::FxIndexSet;
45
use rustc_middle::ty::{self, ReEarlyBound, ReFree, ReVar, Region};
56

67
use super::explicit_outlives_bounds;
@@ -53,7 +54,8 @@ pub struct OutlivesEnvironment<'tcx> {
5354
/// "Region-bound pairs" tracks outlives relations that are known to
5455
/// be true, either because of explicit where-clauses like `T: 'a` or
5556
/// because of implied bounds.
56-
pub type RegionBoundPairs<'tcx> = Vec<(Region<'tcx>, GenericKind<'tcx>)>;
57+
pub type RegionBoundPairs<'tcx> =
58+
FxIndexSet<ty::OutlivesPredicate<GenericKind<'tcx>, Region<'tcx>>>;
5759

5860
impl<'a, 'tcx> OutlivesEnvironment<'tcx> {
5961
pub fn new(param_env: ty::ParamEnv<'tcx>) -> Self {
@@ -97,10 +99,12 @@ impl<'a, 'tcx> OutlivesEnvironment<'tcx> {
9799
debug!("add_outlives_bounds: outlives_bound={:?}", outlives_bound);
98100
match outlives_bound {
99101
OutlivesBound::RegionSubParam(r_a, param_b) => {
100-
self.region_bound_pairs.push((r_a, GenericKind::Param(param_b)));
102+
self.region_bound_pairs
103+
.insert(ty::OutlivesPredicate(GenericKind::Param(param_b), r_a));
101104
}
102105
OutlivesBound::RegionSubProjection(r_a, projection_b) => {
103-
self.region_bound_pairs.push((r_a, GenericKind::Projection(projection_b)));
106+
self.region_bound_pairs
107+
.insert(ty::OutlivesPredicate(GenericKind::Projection(projection_b), r_a));
104108
}
105109
OutlivesBound::RegionSubRegion(r_a, r_b) => {
106110
if let (ReEarlyBound(_) | ReFree(_), ReVar(vid_b)) = (r_a.kind(), r_b.kind()) {

compiler/rustc_infer/src/infer/outlives/verify.rs

+12-11
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use rustc_data_structures::captures::Captures;
66
use rustc_data_structures::sso::SsoHashSet;
77
use rustc_hir::def_id::DefId;
88
use rustc_middle::ty::subst::{GenericArg, Subst};
9-
use rustc_middle::ty::{self, EarlyBinder, Ty, TyCtxt};
9+
use rustc_middle::ty::{self, EarlyBinder, OutlivesPredicate, Ty, TyCtxt};
1010

1111
use smallvec::smallvec;
1212

@@ -259,16 +259,17 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
259259
// The problem is that the type of `x` is `&'a A`. To be
260260
// well-formed, then, A must outlive `'a`, but we don't know that
261261
// this holds from first principles.
262-
let from_region_bound_pairs = self.region_bound_pairs.iter().filter_map(|&(r, p)| {
263-
debug!(
264-
"declared_generic_bounds_from_env_for_erased_ty: region_bound_pair = {:?}",
265-
(r, p)
266-
);
267-
let p_ty = p.to_ty(tcx);
268-
let erased_p_ty = self.tcx.erase_regions(p_ty);
269-
(erased_p_ty == erased_ty)
270-
.then_some(ty::Binder::dummy(ty::OutlivesPredicate(p.to_ty(tcx), r)))
271-
});
262+
let from_region_bound_pairs =
263+
self.region_bound_pairs.iter().filter_map(|&OutlivesPredicate(p, r)| {
264+
debug!(
265+
"declared_generic_bounds_from_env_for_erased_ty: region_bound_pair = {:?}",
266+
(r, p)
267+
);
268+
let p_ty = p.to_ty(tcx);
269+
let erased_p_ty = self.tcx.erase_regions(p_ty);
270+
(erased_p_ty == erased_ty)
271+
.then_some(ty::Binder::dummy(ty::OutlivesPredicate(p.to_ty(tcx), r)))
272+
});
272273

273274
param_bounds
274275
.chain(from_region_bound_pairs)

compiler/rustc_typeck/src/check/wfcheck.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,8 @@ use rustc_hir as hir;
77
use rustc_hir::def_id::{DefId, LocalDefId};
88
use rustc_hir::lang_items::LangItem;
99
use rustc_hir::ItemKind;
10-
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
10+
use rustc_infer::infer::outlives::env::{OutlivesEnvironment, RegionBoundPairs};
1111
use rustc_infer::infer::outlives::obligations::TypeOutlives;
12-
use rustc_infer::infer::region_constraints::GenericKind;
1312
use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt};
1413
use rustc_infer::traits::Normalized;
1514
use rustc_middle::ty::query::Providers;
@@ -689,10 +688,7 @@ fn resolve_regions_with_wf_tys<'tcx>(
689688
id: hir::HirId,
690689
param_env: ty::ParamEnv<'tcx>,
691690
wf_tys: &FxHashSet<Ty<'tcx>>,
692-
add_constraints: impl for<'a> FnOnce(
693-
&'a InferCtxt<'a, 'tcx>,
694-
&'a Vec<(ty::Region<'tcx>, GenericKind<'tcx>)>,
695-
),
691+
add_constraints: impl for<'a> FnOnce(&'a InferCtxt<'a, 'tcx>, &'a RegionBoundPairs<'tcx>),
696692
) -> bool {
697693
// Unfortunately, we have to use a new `InferCtxt` each call, because
698694
// region constraints get added and solved there and we need to test each

0 commit comments

Comments
 (0)