about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-07-27 22:02:14 +0000
committerbors <bors@rust-lang.org>2022-07-27 22:02:14 +0000
commitada80a13b97a01176a1660453060e296a72cf1bb (patch)
treeebc2c1ec769748be6dd4ab627979abc6b9468d82 /compiler
parent2643b16468fda787470340890212591d8bc832b7 (diff)
parent2e796acf33ba247acfb9327a398e15c1ea8710e8 (diff)
downloadrust-ada80a13b97a01176a1660453060e296a72cf1bb.tar.gz
rust-ada80a13b97a01176a1660453060e296a72cf1bb.zip
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
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_borrowck/src/type_check/constraint_conversion.rs10
-rw-r--r--compiler/rustc_borrowck/src/type_check/free_region_relations.rs21
-rw-r--r--compiler/rustc_infer/src/infer/outlives/env.rs10
-rw-r--r--compiler/rustc_infer/src/infer/outlives/verify.rs23
-rw-r--r--compiler/rustc_typeck/src/check/wfcheck.rs8
5 files changed, 37 insertions, 35 deletions
diff --git a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
index 3f9c0cecccc..16796091830 100644
--- a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
+++ b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
@@ -22,6 +22,16 @@ pub(crate) struct ConstraintConversion<'a, 'tcx> {
     infcx: &'a InferCtxt<'a, 'tcx>,
     tcx: TyCtxt<'tcx>,
     universal_regions: &'a UniversalRegions<'tcx>,
+    /// Each RBP `GK: 'a` is assumed to be true. These encode
+    /// relationships like `T: 'a` that are added via implicit bounds
+    /// or the `param_env`.
+    ///
+    /// Each region here is guaranteed to be a key in the `indices`
+    /// map. We use the "original" regions (i.e., the keys from the
+    /// map, and not the values) because the code in
+    /// `process_registered_region_obligations` has some special-cased
+    /// logic expecting to see (e.g.) `ReStatic`, and if we supplied
+    /// our special inference variable there, we would mess that up.
     region_bound_pairs: &'a RegionBoundPairs<'tcx>,
     implicit_region_bound: ty::Region<'tcx>,
     param_env: ty::ParamEnv<'tcx>,
diff --git a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs
index fe66821ad75..cc0318ede54 100644
--- a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs
+++ b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs
@@ -2,6 +2,7 @@ use rustc_data_structures::frozen::Frozen;
 use rustc_data_structures::transitive_relation::TransitiveRelation;
 use rustc_infer::infer::canonical::QueryRegionConstraints;
 use rustc_infer::infer::outlives;
+use rustc_infer::infer::outlives::env::RegionBoundPairs;
 use rustc_infer::infer::region_constraints::GenericKind;
 use rustc_infer::infer::InferCtxt;
 use rustc_middle::mir::ConstraintCategory;
@@ -34,18 +35,6 @@ pub(crate) struct UniversalRegionRelations<'tcx> {
     inverse_outlives: TransitiveRelation<RegionVid>,
 }
 
-/// Each RBP `('a, GK)` indicates that `GK: 'a` can be assumed to
-/// be true. These encode relationships like `T: 'a` that are
-/// added via implicit bounds.
-///
-/// Each region here is guaranteed to be a key in the `indices`
-/// map. We use the "original" regions (i.e., the keys from the
-/// map, and not the values) because the code in
-/// `process_registered_region_obligations` has some special-cased
-/// logic expecting to see (e.g.) `ReStatic`, and if we supplied
-/// our special inference variable there, we would mess that up.
-type RegionBoundPairs<'tcx> = Vec<(ty::Region<'tcx>, GenericKind<'tcx>)>;
-
 /// As part of computing the free region relations, we also have to
 /// normalize the input-output types, which we then need later. So we
 /// return those. This vector consists of first the input types and
@@ -71,7 +60,7 @@ pub(crate) fn create<'tcx>(
         implicit_region_bound,
         constraints,
         universal_regions: universal_regions.clone(),
-        region_bound_pairs: Vec::new(),
+        region_bound_pairs: Default::default(),
         relations: UniversalRegionRelations {
             universal_regions: universal_regions.clone(),
             outlives: Default::default(),
@@ -371,11 +360,13 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
                 }
 
                 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));
                 }
             }
         }
diff --git a/compiler/rustc_infer/src/infer/outlives/env.rs b/compiler/rustc_infer/src/infer/outlives/env.rs
index b897de7315a..b2decd64f0f 100644
--- a/compiler/rustc_infer/src/infer/outlives/env.rs
+++ b/compiler/rustc_infer/src/infer/outlives/env.rs
@@ -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()) {
diff --git a/compiler/rustc_infer/src/infer/outlives/verify.rs b/compiler/rustc_infer/src/infer/outlives/verify.rs
index faa0a18f93d..c7d7ef40d9d 100644
--- a/compiler/rustc_infer/src/infer/outlives/verify.rs
+++ b/compiler/rustc_infer/src/infer/outlives/verify.rs
@@ -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)
diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs
index bae986de9a2..faab862cc3c 100644
--- a/compiler/rustc_typeck/src/check/wfcheck.rs
+++ b/compiler/rustc_typeck/src/check/wfcheck.rs
@@ -7,9 +7,8 @@ use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::lang_items::LangItem;
 use rustc_hir::ItemKind;
-use rustc_infer::infer::outlives::env::OutlivesEnvironment;
+use rustc_infer::infer::outlives::env::{OutlivesEnvironment, RegionBoundPairs};
 use rustc_infer::infer::outlives::obligations::TypeOutlives;
-use rustc_infer::infer::region_constraints::GenericKind;
 use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt};
 use rustc_infer::traits::Normalized;
 use rustc_middle::ty::query::Providers;
@@ -689,10 +688,7 @@ fn resolve_regions_with_wf_tys<'tcx>(
     id: hir::HirId,
     param_env: ty::ParamEnv<'tcx>,
     wf_tys: &FxHashSet<Ty<'tcx>>,
-    add_constraints: impl for<'a> FnOnce(
-        &'a InferCtxt<'a, 'tcx>,
-        &'a Vec<(ty::Region<'tcx>, GenericKind<'tcx>)>,
-    ),
+    add_constraints: impl for<'a> FnOnce(&'a InferCtxt<'a, 'tcx>, &'a RegionBoundPairs<'tcx>),
 ) -> bool {
     // Unfortunately, we have to use a new `InferCtxt` each call, because
     // region constraints get added and solved there and we need to test each