summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_infer/src/infer/outlives/env.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:03:36 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:03:36 +0000
commit17d40c6057c88f4c432b0d7bac88e1b84cb7e67f (patch)
tree3f66c4a5918660bb8a758ab6cda5ff8ee4f6cdcd /compiler/rustc_infer/src/infer/outlives/env.rs
parentAdding upstream version 1.64.0+dfsg1. (diff)
downloadrustc-f7f0cc2a5d72e2c61c1f6900e70eec992bea4273.tar.xz
rustc-f7f0cc2a5d72e2c61c1f6900e70eec992bea4273.zip
Adding upstream version 1.65.0+dfsg1.upstream/1.65.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_infer/src/infer/outlives/env.rs')
-rw-r--r--compiler/rustc_infer/src/infer/outlives/env.rs62
1 files changed, 50 insertions, 12 deletions
diff --git a/compiler/rustc_infer/src/infer/outlives/env.rs b/compiler/rustc_infer/src/infer/outlives/env.rs
index b2decd64f..9922b156e 100644
--- a/compiler/rustc_infer/src/infer/outlives/env.rs
+++ b/compiler/rustc_infer/src/infer/outlives/env.rs
@@ -2,6 +2,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_data_structures::transitive_relation::TransitiveRelationBuilder;
use rustc_middle::ty::{self, ReEarlyBound, ReFree, ReVar, Region};
use super::explicit_outlives_bounds;
@@ -51,23 +52,49 @@ pub struct OutlivesEnvironment<'tcx> {
region_bound_pairs: RegionBoundPairs<'tcx>,
}
+/// Builder of OutlivesEnvironment.
+#[derive(Debug)]
+struct OutlivesEnvironmentBuilder<'tcx> {
+ param_env: ty::ParamEnv<'tcx>,
+ region_relation: TransitiveRelationBuilder<Region<'tcx>>,
+ region_bound_pairs: RegionBoundPairs<'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> =
FxIndexSet<ty::OutlivesPredicate<GenericKind<'tcx>, Region<'tcx>>>;
-impl<'a, 'tcx> OutlivesEnvironment<'tcx> {
- pub fn new(param_env: ty::ParamEnv<'tcx>) -> Self {
- let mut env = OutlivesEnvironment {
+impl<'tcx> OutlivesEnvironment<'tcx> {
+ /// Create a builder using `ParamEnv` and add explicit outlives bounds into it.
+ fn builder(param_env: ty::ParamEnv<'tcx>) -> OutlivesEnvironmentBuilder<'tcx> {
+ let mut builder = OutlivesEnvironmentBuilder {
param_env,
- free_region_map: Default::default(),
+ region_relation: Default::default(),
region_bound_pairs: Default::default(),
};
- env.add_outlives_bounds(None, explicit_outlives_bounds(param_env));
+ builder.add_outlives_bounds(None, explicit_outlives_bounds(param_env));
- env
+ builder
+ }
+
+ #[inline]
+ /// Create a new `OutlivesEnvironment` without extra outlives bounds.
+ pub fn new(param_env: ty::ParamEnv<'tcx>) -> Self {
+ Self::builder(param_env).build()
+ }
+
+ /// Create a new `OutlivesEnvironment` with extra outlives bounds.
+ pub fn with_bounds<'a>(
+ param_env: ty::ParamEnv<'tcx>,
+ infcx: Option<&InferCtxt<'a, 'tcx>>,
+ extra_bounds: impl IntoIterator<Item = OutlivesBound<'tcx>>,
+ ) -> Self {
+ let mut builder = Self::builder(param_env);
+ builder.add_outlives_bounds(infcx, extra_bounds);
+ builder.build()
}
/// Borrows current value of the `free_region_map`.
@@ -79,6 +106,18 @@ impl<'a, 'tcx> OutlivesEnvironment<'tcx> {
pub fn region_bound_pairs(&self) -> &RegionBoundPairs<'tcx> {
&self.region_bound_pairs
}
+}
+
+impl<'a, 'tcx> OutlivesEnvironmentBuilder<'tcx> {
+ #[inline]
+ #[instrument(level = "debug")]
+ fn build(self) -> OutlivesEnvironment<'tcx> {
+ OutlivesEnvironment {
+ param_env: self.param_env,
+ free_region_map: FreeRegionMap { relation: self.region_relation.freeze() },
+ region_bound_pairs: self.region_bound_pairs,
+ }
+ }
/// Processes outlives bounds that are known to hold, whether from implied or other sources.
///
@@ -86,11 +125,8 @@ impl<'a, 'tcx> OutlivesEnvironment<'tcx> {
/// contain inference variables, it must be supplied, in which
/// case we will register "givens" on the inference context. (See
/// `RegionConstraintData`.)
- pub fn add_outlives_bounds<I>(
- &mut self,
- infcx: Option<&InferCtxt<'a, 'tcx>>,
- outlives_bounds: I,
- ) where
+ fn add_outlives_bounds<I>(&mut self, infcx: Option<&InferCtxt<'a, 'tcx>>, outlives_bounds: I)
+ where
I: IntoIterator<Item = OutlivesBound<'tcx>>,
{
// Record relationships such as `T:'x` that don't go into the
@@ -122,7 +158,9 @@ impl<'a, 'tcx> OutlivesEnvironment<'tcx> {
// system to be more general and to make use
// of *every* relationship that arises here,
// but presently we do not.)
- self.free_region_map.relate_regions(r_a, r_b);
+ if r_a.is_free_or_static() && r_b.is_free() {
+ self.region_relation.add(r_a, r_b)
+ }
}
}
}