Remove OutlivesEnvironmentBuilder
.
`OutlivesEnvironment::new` can call `OutlivesEnvironment::with_bounds` with an empty `extra_bounds`. And once that's done, `OutlivesEnvironmentBuilder` has a single use and can be inlined and removed into `OutlivesEnvironment::with_bounds`.
This commit is contained in:
parent
b8495e5dd2
commit
abf212c16c
@ -1,8 +1,7 @@
|
|||||||
use rustc_data_structures::fx::FxIndexSet;
|
use rustc_data_structures::fx::FxIndexSet;
|
||||||
use rustc_data_structures::transitive_relation::TransitiveRelationBuilder;
|
use rustc_data_structures::transitive_relation::TransitiveRelationBuilder;
|
||||||
use rustc_middle::bug;
|
use rustc_middle::{bug, ty};
|
||||||
use rustc_middle::ty::{self, Region};
|
use tracing::debug;
|
||||||
use tracing::{debug, instrument};
|
|
||||||
|
|
||||||
use super::explicit_outlives_bounds;
|
use super::explicit_outlives_bounds;
|
||||||
use crate::infer::GenericKind;
|
use crate::infer::GenericKind;
|
||||||
@ -54,37 +53,16 @@ pub struct OutlivesEnvironment<'tcx> {
|
|||||||
region_bound_pairs: RegionBoundPairs<'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
|
/// "Region-bound pairs" tracks outlives relations that are known to
|
||||||
/// be true, either because of explicit where-clauses like `T: 'a` or
|
/// be true, either because of explicit where-clauses like `T: 'a` or
|
||||||
/// because of implied bounds.
|
/// because of implied bounds.
|
||||||
pub type RegionBoundPairs<'tcx> = FxIndexSet<ty::OutlivesPredicate<'tcx, GenericKind<'tcx>>>;
|
pub type RegionBoundPairs<'tcx> = FxIndexSet<ty::OutlivesPredicate<'tcx, GenericKind<'tcx>>>;
|
||||||
|
|
||||||
impl<'tcx> OutlivesEnvironment<'tcx> {
|
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,
|
|
||||||
region_relation: Default::default(),
|
|
||||||
region_bound_pairs: Default::default(),
|
|
||||||
};
|
|
||||||
|
|
||||||
builder.add_outlives_bounds(explicit_outlives_bounds(param_env));
|
|
||||||
|
|
||||||
builder
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
/// Create a new `OutlivesEnvironment` without extra outlives bounds.
|
/// Create a new `OutlivesEnvironment` without extra outlives bounds.
|
||||||
|
#[inline]
|
||||||
pub fn new(param_env: ty::ParamEnv<'tcx>) -> Self {
|
pub fn new(param_env: ty::ParamEnv<'tcx>) -> Self {
|
||||||
Self::builder(param_env).build()
|
Self::with_bounds(param_env, vec![])
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new `OutlivesEnvironment` with extra outlives bounds.
|
/// Create a new `OutlivesEnvironment` with extra outlives bounds.
|
||||||
@ -92,9 +70,41 @@ pub fn with_bounds(
|
|||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
extra_bounds: impl IntoIterator<Item = OutlivesBound<'tcx>>,
|
extra_bounds: impl IntoIterator<Item = OutlivesBound<'tcx>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut builder = Self::builder(param_env);
|
let mut region_relation = TransitiveRelationBuilder::default();
|
||||||
builder.add_outlives_bounds(extra_bounds);
|
let mut region_bound_pairs = RegionBoundPairs::default();
|
||||||
builder.build()
|
|
||||||
|
// Record relationships such as `T:'x` that don't go into the
|
||||||
|
// free-region-map but which we use here.
|
||||||
|
for outlives_bound in explicit_outlives_bounds(param_env).chain(extra_bounds) {
|
||||||
|
debug!("add_outlives_bounds: outlives_bound={:?}", outlives_bound);
|
||||||
|
match outlives_bound {
|
||||||
|
OutlivesBound::RegionSubParam(r_a, param_b) => {
|
||||||
|
region_bound_pairs
|
||||||
|
.insert(ty::OutlivesPredicate(GenericKind::Param(param_b), r_a));
|
||||||
|
}
|
||||||
|
OutlivesBound::RegionSubAlias(r_a, alias_b) => {
|
||||||
|
region_bound_pairs
|
||||||
|
.insert(ty::OutlivesPredicate(GenericKind::Alias(alias_b), r_a));
|
||||||
|
}
|
||||||
|
OutlivesBound::RegionSubRegion(r_a, r_b) => match (*r_a, *r_b) {
|
||||||
|
(
|
||||||
|
ty::ReStatic | ty::ReEarlyParam(_) | ty::ReLateParam(_),
|
||||||
|
ty::ReStatic | ty::ReEarlyParam(_) | ty::ReLateParam(_),
|
||||||
|
) => region_relation.add(r_a, r_b),
|
||||||
|
(ty::ReError(_), _) | (_, ty::ReError(_)) => {}
|
||||||
|
// FIXME(#109628): We shouldn't have existential variables in implied bounds.
|
||||||
|
// Panic here once the linked issue is resolved!
|
||||||
|
(ty::ReVar(_), _) | (_, ty::ReVar(_)) => {}
|
||||||
|
_ => bug!("add_outlives_bounds: unexpected regions: ({r_a:?}, {r_b:?})"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OutlivesEnvironment {
|
||||||
|
param_env,
|
||||||
|
free_region_map: FreeRegionMap { relation: region_relation.freeze() },
|
||||||
|
region_bound_pairs,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Borrows current value of the `free_region_map`.
|
/// Borrows current value of the `free_region_map`.
|
||||||
@ -107,48 +117,3 @@ pub fn region_bound_pairs(&self) -> &RegionBoundPairs<'tcx> {
|
|||||||
&self.region_bound_pairs
|
&self.region_bound_pairs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'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.
|
|
||||||
fn add_outlives_bounds<I>(&mut self, outlives_bounds: I)
|
|
||||||
where
|
|
||||||
I: IntoIterator<Item = OutlivesBound<'tcx>>,
|
|
||||||
{
|
|
||||||
// Record relationships such as `T:'x` that don't go into the
|
|
||||||
// free-region-map but which we use here.
|
|
||||||
for outlives_bound in outlives_bounds {
|
|
||||||
debug!("add_outlives_bounds: outlives_bound={:?}", outlives_bound);
|
|
||||||
match outlives_bound {
|
|
||||||
OutlivesBound::RegionSubParam(r_a, param_b) => {
|
|
||||||
self.region_bound_pairs
|
|
||||||
.insert(ty::OutlivesPredicate(GenericKind::Param(param_b), r_a));
|
|
||||||
}
|
|
||||||
OutlivesBound::RegionSubAlias(r_a, alias_b) => {
|
|
||||||
self.region_bound_pairs
|
|
||||||
.insert(ty::OutlivesPredicate(GenericKind::Alias(alias_b), r_a));
|
|
||||||
}
|
|
||||||
OutlivesBound::RegionSubRegion(r_a, r_b) => match (*r_a, *r_b) {
|
|
||||||
(
|
|
||||||
ty::ReStatic | ty::ReEarlyParam(_) | ty::ReLateParam(_),
|
|
||||||
ty::ReStatic | ty::ReEarlyParam(_) | ty::ReLateParam(_),
|
|
||||||
) => self.region_relation.add(r_a, r_b),
|
|
||||||
(ty::ReError(_), _) | (_, ty::ReError(_)) => {}
|
|
||||||
// FIXME(#109628): We shouldn't have existential variables in implied bounds.
|
|
||||||
// Panic here once the linked issue is resolved!
|
|
||||||
(ty::ReVar(_), _) | (_, ty::ReVar(_)) => {}
|
|
||||||
_ => bug!("add_outlives_bounds: unexpected regions: ({r_a:?}, {r_b:?})"),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user