From 24714310170f0d0214ceafe114c24b8d5b6746f0 Mon Sep 17 00:00:00 2001 From: Jack Huey <31162821+jackh726@users.noreply.github.com> Date: Tue, 28 Jun 2022 00:08:35 -0400 Subject: [PATCH] Move is_free and is_free_or_static to Region, change resolve_var to resolve_region, and remove RootEmptyRegion --- .../rustc_borrowck/src/region_infer/mod.rs | 18 +++++------- .../rustc_borrowck/src/universal_regions.rs | 2 +- .../rustc_infer/src/infer/free_regions.rs | 24 ++++------------ .../src/infer/lexical_region_resolve/mod.rs | 28 ++++++++++--------- compiler/rustc_infer/src/infer/mod.rs | 4 --- compiler/rustc_infer/src/infer/resolve.rs | 4 +-- compiler/rustc_middle/src/ty/sty.rs | 13 +++++++++ 7 files changed, 43 insertions(+), 50 deletions(-) diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index d0e0203bf8c..ea3602e8a05 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -495,8 +495,7 @@ fn init_free_and_bound_regions(&mut self) { } } - NllRegionVariableOrigin::RootEmptyRegion - | NllRegionVariableOrigin::Existential { .. } => { + NllRegionVariableOrigin::Existential { .. } => { // For existential, regions, nothing to do. } } @@ -1410,8 +1409,7 @@ fn check_universal_regions( self.check_bound_universal_region(fr, placeholder, errors_buffer); } - NllRegionVariableOrigin::RootEmptyRegion - | NllRegionVariableOrigin::Existential { .. } => { + NllRegionVariableOrigin::Existential { .. } => { // nothing to check here } } @@ -1513,8 +1511,7 @@ fn check_polonius_subset_errors( self.check_bound_universal_region(fr, placeholder, errors_buffer); } - NllRegionVariableOrigin::RootEmptyRegion - | NllRegionVariableOrigin::Existential { .. } => { + NllRegionVariableOrigin::Existential { .. } => { // nothing to check here } } @@ -1788,9 +1785,9 @@ pub(crate) fn cannot_name_placeholder(&self, r1: RegionVid, r2: RegionVid) -> bo universe1.cannot_name(placeholder.universe) } - NllRegionVariableOrigin::RootEmptyRegion - | NllRegionVariableOrigin::FreeRegion - | NllRegionVariableOrigin::Existential { .. } => false, + NllRegionVariableOrigin::FreeRegion | NllRegionVariableOrigin::Existential { .. } => { + false + } } } @@ -2152,8 +2149,7 @@ pub(crate) fn best_blame_constraint( 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, }; diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index 89d84fcf09c..2a7713bc4df 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -503,7 +503,7 @@ fn build(self) -> UniversalRegions<'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 { diff --git a/compiler/rustc_infer/src/infer/free_regions.rs b/compiler/rustc_infer/src/infer/free_regions.rs index fad949a3bc6..d566634a492 100644 --- a/compiler/rustc_infer/src/infer/free_regions.rs +++ b/compiler/rustc_infer/src/infer/free_regions.rs @@ -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 @@ pub fn is_empty(&self) -> bool { // (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 @@ pub fn sub_free_regions( 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 @@ fn check_relation(&self, r_a: Region<'tcx>, r_b: Region<'tcx>) -> bool { 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 @@ pub fn lub_free_regions( 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 { diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs index 87fa22b3835..3783cfb4cc5 100644 --- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs +++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs @@ -47,7 +47,6 @@ pub(crate) fn resolve<'tcx>( #[derive(Clone)] pub struct LexicalRegionResolutions<'tcx> { pub(crate) values: IndexVec>, - pub(crate) error_region: ty::Region<'tcx>, } #[derive(Copy, Clone, Debug)] @@ -140,7 +139,6 @@ fn num_vars(&self) -> usize { /// 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 @@ fn sub_concrete_regions(&self, a: Region<'tcx>, b: Region<'tcx>) -> bool { // 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 @@ fn sub_concrete_regions(&self, a: Region<'tcx>, b: Region<'tcx>) -> bool { // `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 @@ fn normalize(&self, tcx: TyCtxt<'tcx>, value: T) -> T 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 @@ fn value_mut(&mut self, rid: RegionVid) -> &mut VarValue<'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 } } diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 991fd23ab43..6e0f2d68743 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -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 @@ pub fn skip_region_resolution(&self) { }; 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(), diff --git a/compiler/rustc_infer/src/infer/resolve.rs b/compiler/rustc_infer/src/infer/resolve.rs index a6145687429..3d99f0958f7 100644 --- a/compiler/rustc_infer/src/infer/resolve.rs +++ b/compiler/rustc_infer/src/infer/resolve.rs @@ -206,13 +206,13 @@ fn try_fold_ty(&mut self, t: Ty<'tcx>) -> Result, Self::Error> { fn try_fold_region(&mut self, r: ty::Region<'tcx>) -> Result, 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), } } diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 815e39aab57..03e4319bbf1 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1570,6 +1570,19 @@ pub fn free_region_binding_scope(self, tcx: TyCtxt<'_>) -> DefId { _ => 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 -- GitLab