Move is_free and is_free_or_static to Region, change resolve_var to resolve_region, and remove RootEmptyRegion
This commit is contained in:
parent
1517f5de01
commit
2471431017
compiler
rustc_borrowck/src
rustc_infer/src/infer
rustc_middle/src/ty
@ -495,8 +495,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
NllRegionVariableOrigin::RootEmptyRegion
|
||||
| NllRegionVariableOrigin::Existential { .. } => {
|
||||
NllRegionVariableOrigin::Existential { .. } => {
|
||||
// For existential, regions, nothing to do.
|
||||
}
|
||||
}
|
||||
@ -1410,8 +1409,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
self.check_bound_universal_region(fr, placeholder, errors_buffer);
|
||||
}
|
||||
|
||||
NllRegionVariableOrigin::RootEmptyRegion
|
||||
| NllRegionVariableOrigin::Existential { .. } => {
|
||||
NllRegionVariableOrigin::Existential { .. } => {
|
||||
// nothing to check here
|
||||
}
|
||||
}
|
||||
@ -1513,8 +1511,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
self.check_bound_universal_region(fr, placeholder, errors_buffer);
|
||||
}
|
||||
|
||||
NllRegionVariableOrigin::RootEmptyRegion
|
||||
| NllRegionVariableOrigin::Existential { .. } => {
|
||||
NllRegionVariableOrigin::Existential { .. } => {
|
||||
// nothing to check here
|
||||
}
|
||||
}
|
||||
@ -1788,9 +1785,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
universe1.cannot_name(placeholder.universe)
|
||||
}
|
||||
|
||||
NllRegionVariableOrigin::RootEmptyRegion
|
||||
| NllRegionVariableOrigin::FreeRegion
|
||||
| NllRegionVariableOrigin::Existential { .. } => false,
|
||||
NllRegionVariableOrigin::FreeRegion | NllRegionVariableOrigin::Existential { .. } => {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2152,8 +2149,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
let blame_source = match from_region_origin {
|
||||
NllRegionVariableOrigin::FreeRegion
|
||||
| NllRegionVariableOrigin::Existential { from_forall: false } => true,
|
||||
NllRegionVariableOrigin::RootEmptyRegion
|
||||
| NllRegionVariableOrigin::Placeholder(_)
|
||||
NllRegionVariableOrigin::Placeholder(_)
|
||||
| NllRegionVariableOrigin::Existential { from_forall: true } => false,
|
||||
};
|
||||
|
||||
|
@ -503,7 +503,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
||||
|
||||
let root_empty = self
|
||||
.infcx
|
||||
.next_nll_region_var(NllRegionVariableOrigin::RootEmptyRegion)
|
||||
.next_nll_region_var(NllRegionVariableOrigin::Existential { from_forall: true })
|
||||
.to_region_vid();
|
||||
|
||||
UniversalRegions {
|
||||
|
@ -4,7 +4,7 @@
|
||||
//! and use that to decide when one free region outlives another, and so forth.
|
||||
|
||||
use rustc_data_structures::transitive_relation::TransitiveRelation;
|
||||
use rustc_middle::ty::{self, Lift, Region, TyCtxt};
|
||||
use rustc_middle::ty::{Lift, Region, TyCtxt};
|
||||
|
||||
/// Combines a `FreeRegionMap` and a `TyCtxt`.
|
||||
///
|
||||
@ -49,7 +49,7 @@ impl<'tcx> FreeRegionMap<'tcx> {
|
||||
// (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 self.is_free_or_static(sub) && self.is_free(sup) {
|
||||
if sub.is_free_or_static() && sup.is_free() {
|
||||
self.relation.add(sub, sup)
|
||||
}
|
||||
}
|
||||
@ -68,7 +68,7 @@ impl<'tcx> FreeRegionMap<'tcx> {
|
||||
r_a: Region<'tcx>,
|
||||
r_b: Region<'tcx>,
|
||||
) -> bool {
|
||||
assert!(self.is_free_or_static(r_a) && self.is_free_or_static(r_b));
|
||||
assert!(r_a.is_free_or_static() && r_b.is_free_or_static());
|
||||
let re_static = tcx.lifetimes.re_static;
|
||||
if self.check_relation(re_static, r_b) {
|
||||
// `'a <= 'static` is always true, and not stored in the
|
||||
@ -85,20 +85,6 @@ impl<'tcx> FreeRegionMap<'tcx> {
|
||||
r_a == r_b || self.relation.contains(r_a, r_b)
|
||||
}
|
||||
|
||||
/// True for free regions other than `'static`.
|
||||
pub fn is_free(&self, r: Region<'_>) -> bool {
|
||||
matches!(*r, ty::ReEarlyBound(_) | ty::ReFree(_))
|
||||
}
|
||||
|
||||
/// True if `r` is a free region or static of the sort that this
|
||||
/// free region map can be used with.
|
||||
pub fn is_free_or_static(&self, r: Region<'_>) -> bool {
|
||||
match *r {
|
||||
ty::ReStatic => true,
|
||||
_ => self.is_free(r),
|
||||
}
|
||||
}
|
||||
|
||||
/// Computes the least-upper-bound of two free regions. In some
|
||||
/// cases, this is more conservative than necessary, in order to
|
||||
/// avoid making arbitrary choices. See
|
||||
@ -110,8 +96,8 @@ impl<'tcx> FreeRegionMap<'tcx> {
|
||||
r_b: Region<'tcx>,
|
||||
) -> Region<'tcx> {
|
||||
debug!("lub_free_regions(r_a={:?}, r_b={:?})", r_a, r_b);
|
||||
assert!(self.is_free(r_a));
|
||||
assert!(self.is_free(r_b));
|
||||
assert!(r_a.is_free());
|
||||
assert!(r_b.is_free());
|
||||
let result = if r_a == r_b {
|
||||
r_a
|
||||
} else {
|
||||
|
@ -47,7 +47,6 @@ pub(crate) fn resolve<'tcx>(
|
||||
#[derive(Clone)]
|
||||
pub struct LexicalRegionResolutions<'tcx> {
|
||||
pub(crate) values: IndexVec<RegionVid, VarValue<'tcx>>,
|
||||
pub(crate) error_region: ty::Region<'tcx>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
@ -140,7 +139,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
|
||||
/// empty region. The `expansion` phase will grow this larger.
|
||||
fn construct_var_data(&self, tcx: TyCtxt<'tcx>) -> LexicalRegionResolutions<'tcx> {
|
||||
LexicalRegionResolutions {
|
||||
error_region: tcx.lifetimes.re_static,
|
||||
values: IndexVec::from_fn_n(
|
||||
|vid| {
|
||||
let vid_universe = self.var_infos[vid].universe;
|
||||
@ -310,7 +308,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
|
||||
|
||||
// Check for the case where we know that `'b: 'static` -- in that case,
|
||||
// `a <= b` for all `a`.
|
||||
let b_free_or_static = self.region_rels.free_regions.is_free_or_static(b);
|
||||
let b_free_or_static = b.is_free_or_static();
|
||||
if b_free_or_static && sub_free_regions(tcx.lifetimes.re_static, b) {
|
||||
return true;
|
||||
}
|
||||
@ -320,7 +318,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
|
||||
// `lub` relationship defined below, since sometimes the "lub"
|
||||
// is actually the `postdom_upper_bound` (see
|
||||
// `TransitiveRelation` for more details).
|
||||
let a_free_or_static = self.region_rels.free_regions.is_free_or_static(a);
|
||||
let a_free_or_static = a.is_free_or_static();
|
||||
if a_free_or_static && b_free_or_static {
|
||||
return sub_free_regions(a, b);
|
||||
}
|
||||
@ -864,10 +862,7 @@ impl<'tcx> LexicalRegionResolutions<'tcx> {
|
||||
where
|
||||
T: TypeFoldable<'tcx>,
|
||||
{
|
||||
tcx.fold_regions(value, |r, _db| match *r {
|
||||
ty::ReVar(rid) => self.resolve_var(rid),
|
||||
_ => r,
|
||||
})
|
||||
tcx.fold_regions(value, |r, _db| self.resolve_region(tcx, r))
|
||||
}
|
||||
|
||||
fn value(&self, rid: RegionVid) -> &VarValue<'tcx> {
|
||||
@ -878,12 +873,19 @@ impl<'tcx> LexicalRegionResolutions<'tcx> {
|
||||
&mut self.values[rid]
|
||||
}
|
||||
|
||||
pub fn resolve_var(&self, rid: RegionVid) -> ty::Region<'tcx> {
|
||||
let result = match self.values[rid] {
|
||||
VarValue::Value(r) => r,
|
||||
VarValue::ErrorValue => self.error_region,
|
||||
pub(crate) fn resolve_region(
|
||||
&self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
r: ty::Region<'tcx>,
|
||||
) -> ty::Region<'tcx> {
|
||||
let result = match *r {
|
||||
ty::ReVar(rid) => match self.values[rid] {
|
||||
VarValue::Value(r) => r,
|
||||
VarValue::ErrorValue => tcx.lifetimes.re_static,
|
||||
},
|
||||
_ => r,
|
||||
};
|
||||
debug!("resolve_var({:?}) = {:?}", rid, result);
|
||||
debug!("resolve_region({:?}) = {:?}", r, result);
|
||||
result
|
||||
}
|
||||
}
|
||||
|
@ -466,9 +466,6 @@ pub enum NllRegionVariableOrigin {
|
||||
/// from a `for<'a> T` binder). Meant to represent "any region".
|
||||
Placeholder(ty::PlaceholderRegion),
|
||||
|
||||
/// The variable we create to represent `'empty(U0)`.
|
||||
RootEmptyRegion,
|
||||
|
||||
Existential {
|
||||
/// If this is true, then this variable was created to represent a lifetime
|
||||
/// bound in a `for` binder. For example, it might have been created to
|
||||
@ -1250,7 +1247,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
};
|
||||
|
||||
let lexical_region_resolutions = LexicalRegionResolutions {
|
||||
error_region: self.tcx.lifetimes.re_static,
|
||||
values: rustc_index::vec::IndexVec::from_elem_n(
|
||||
crate::infer::lexical_region_resolve::VarValue::Value(self.tcx.lifetimes.re_erased),
|
||||
var_infos.len(),
|
||||
|
@ -206,13 +206,13 @@ impl<'a, 'tcx> FallibleTypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> {
|
||||
|
||||
fn try_fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
||||
match *r {
|
||||
ty::ReVar(rid) => Ok(self
|
||||
ty::ReVar(_) => Ok(self
|
||||
.infcx
|
||||
.lexical_region_resolutions
|
||||
.borrow()
|
||||
.as_ref()
|
||||
.expect("region resolution not performed")
|
||||
.resolve_var(rid)),
|
||||
.resolve_region(self.infcx.tcx, r)),
|
||||
_ => Ok(r),
|
||||
}
|
||||
}
|
||||
|
@ -1570,6 +1570,19 @@ impl<'tcx> Region<'tcx> {
|
||||
_ => bug!("free_region_binding_scope invoked on inappropriate region: {:?}", self),
|
||||
}
|
||||
}
|
||||
|
||||
/// True for free regions other than `'static`.
|
||||
pub fn is_free(self) -> bool {
|
||||
matches!(*self, ty::ReEarlyBound(_) | ty::ReFree(_))
|
||||
}
|
||||
|
||||
/// True if `self` is a free region or static.
|
||||
pub fn is_free_or_static(self) -> bool {
|
||||
match *self {
|
||||
ty::ReStatic => true,
|
||||
_ => self.is_free(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Type utilities
|
||||
|
Loading…
x
Reference in New Issue
Block a user