get rid of RefCell
in TransitiveRelation
This commit is contained in:
parent
a9bb589cd6
commit
5d9e4d07fc
9 changed files with 179 additions and 118 deletions
|
@ -27,13 +27,13 @@ impl<'a, 'tcx> RegionRelations<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct FreeRegionMap<'tcx> {
|
||||
// Stores the relation `a < b`, where `a` and `b` are regions.
|
||||
//
|
||||
// Invariant: only free regions like `'x` or `'static` are stored
|
||||
// in this relation, not scopes.
|
||||
relation: TransitiveRelation<Region<'tcx>>,
|
||||
pub(crate) relation: TransitiveRelation<Region<'tcx>>,
|
||||
}
|
||||
|
||||
impl<'tcx> FreeRegionMap<'tcx> {
|
||||
|
@ -45,15 +45,6 @@ impl<'tcx> FreeRegionMap<'tcx> {
|
|||
self.relation.is_empty()
|
||||
}
|
||||
|
||||
// Record that `'sup:'sub`. Or, put another way, `'sub <= 'sup`.
|
||||
// (with the exception that `'static: 'x` is not notable)
|
||||
pub fn relate_regions(&mut self, sub: Region<'tcx>, sup: Region<'tcx>) {
|
||||
debug!("relate_regions(sub={:?}, sup={:?})", sub, sup);
|
||||
if sub.is_free_or_static() && sup.is_free() {
|
||||
self.relation.add(sub, sup)
|
||||
}
|
||||
}
|
||||
|
||||
/// Tests whether `r_a <= r_b`.
|
||||
///
|
||||
/// Both regions must meet `is_free_or_static`.
|
||||
|
|
|
@ -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,39 @@ pub struct OutlivesEnvironment<'tcx> {
|
|||
region_bound_pairs: RegionBoundPairs<'tcx>,
|
||||
}
|
||||
|
||||
/// Builder of OutlivesEnvironment. Use this structure if you need to add more outlives
|
||||
/// bounds than `explicit_outlives_bounds(param_env)`.
|
||||
pub struct OutlivesEnvironmentBuilder<'tcx> {
|
||||
pub 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.
|
||||
pub 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()
|
||||
}
|
||||
|
||||
/// Borrows current value of the `free_region_map`.
|
||||
|
@ -79,6 +96,26 @@ impl<'a, 'tcx> OutlivesEnvironment<'tcx> {
|
|||
pub fn region_bound_pairs(&self) -> &RegionBoundPairs<'tcx> {
|
||||
&self.region_bound_pairs
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> OutlivesEnvironmentBuilder<'tcx> {
|
||||
#[inline]
|
||||
pub 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,
|
||||
}
|
||||
}
|
||||
|
||||
// Record that `'sup:'sub`. Or, put another way, `'sub <= 'sup`.
|
||||
// (with the exception that `'static: 'x` is not notable)
|
||||
fn relate_regions(&mut self, sub: Region<'tcx>, sup: Region<'tcx>) {
|
||||
debug!("relate_regions(sub={:?}, sup={:?})", sub, sup);
|
||||
if sub.is_free_or_static() && sup.is_free() {
|
||||
self.region_relation.add(sub, sup)
|
||||
}
|
||||
}
|
||||
|
||||
/// Processes outlives bounds that are known to hold, whether from implied or other sources.
|
||||
///
|
||||
|
@ -122,7 +159,7 @@ 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);
|
||||
self.relate_regions(r_a, r_b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue