Overhaul RegionKind and Region.

Specifically, change `Region` from this:
```
pub type Region<'tcx> = &'tcx RegionKind;
```
to this:
```
pub struct Region<'tcx>(&'tcx Interned<RegionKind>);
```

This now matches `Ty` and `Predicate` more closely.

Things to note
- Regions have always been interned, but we haven't been using pointer-based
  `Eq` and `Hash`. This is now happening.
- I chose to impl `Deref` for `Region` because it makes pattern matching a lot
  nicer, and `Region` can be viewed as just a smart wrapper for `RegionKind`.
- Various methods are moved from `RegionKind` to `Region`.
- There is a lot of tedious sigil changes.
- A couple of types like `HighlightBuilder`, `RegionHighlightMode` now have a
  `'tcx` lifetime because they hold a `Ty<'tcx>`, so they can call `mk_region`.
- A couple of test outputs change slightly, I'm not sure why, but the new
  outputs are a little better.
This commit is contained in:
Nicholas Nethercote
2022-01-28 11:25:15 +11:00
parent 925ec0d3c7
commit 7024dc523a
80 changed files with 443 additions and 346 deletions

View File

@@ -60,8 +60,8 @@ impl<'cg, 'cx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'tcx> {
/// We sometimes have `region` within an rvalue, or within a
/// call. Make them live at the location where they appear.
fn visit_region(&mut self, region: &ty::Region<'tcx>, location: Location) {
self.add_regular_live_constraint(*region, location);
fn visit_region(&mut self, region: ty::Region<'tcx>, location: Location) {
self.add_regular_live_constraint(region, location);
self.super_region(region);
}

View File

@@ -356,8 +356,8 @@ fn try_extract_error_from_fulfill_cx<'tcx>(
})?;
debug!(?sub_region, "cause = {:#?}", cause);
let nice_error = match (error_region, sub_region) {
(Some(error_region), &ty::ReVar(vid)) => NiceRegionError::new(
let nice_error = match (error_region, *sub_region) {
(Some(error_region), ty::ReVar(vid)) => NiceRegionError::new(
infcx,
RegionResolutionError::SubSupConflict(
vid,
@@ -374,7 +374,7 @@ fn try_extract_error_from_fulfill_cx<'tcx>(
RegionResolutionError::ConcreteFailure(cause.clone(), error_region, placeholder_region),
),
// Note universe here is wrong...
(None, &ty::ReVar(vid)) => NiceRegionError::new(
(None, ty::ReVar(vid)) => NiceRegionError::new(
infcx,
RegionResolutionError::UpperBoundUniverseConflict(
vid,

View File

@@ -497,14 +497,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
// We need to add synthesized lifetimes where appropriate. We do
// this by hooking into the pretty printer and telling it to label the
// lifetimes without names with the value `'0`.
match ty.kind() {
ty::Ref(
ty::RegionKind::ReLateBound(_, ty::BoundRegion { kind: br, .. })
| ty::RegionKind::RePlaceholder(ty::PlaceholderRegion { name: br, .. }),
_,
_,
) => printer.region_highlight_mode.highlighting_bound_region(*br, counter),
_ => {}
if let ty::Ref(region, ..) = ty.kind() {
match **region {
ty::ReLateBound(_, ty::BoundRegion { kind: br, .. })
| ty::RePlaceholder(ty::PlaceholderRegion { name: br, .. }) => {
printer.region_highlight_mode.highlighting_bound_region(br, counter)
}
_ => {}
}
}
let _ = ty.print(printer);
@@ -517,19 +517,17 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let mut s = String::new();
let mut printer = ty::print::FmtPrinter::new(self.infcx.tcx, &mut s, Namespace::TypeNS);
let region = match ty.kind() {
ty::Ref(region, _, _) => {
match region {
ty::RegionKind::ReLateBound(_, ty::BoundRegion { kind: br, .. })
| ty::RegionKind::RePlaceholder(ty::PlaceholderRegion { name: br, .. }) => {
printer.region_highlight_mode.highlighting_bound_region(*br, counter)
}
_ => {}
let region = if let ty::Ref(region, ..) = ty.kind() {
match **region {
ty::ReLateBound(_, ty::BoundRegion { kind: br, .. })
| ty::RePlaceholder(ty::PlaceholderRegion { name: br, .. }) => {
printer.region_highlight_mode.highlighting_bound_region(br, counter)
}
region
_ => {}
}
_ => bug!("ty for annotation of borrow region is not a reference"),
region
} else {
bug!("ty for annotation of borrow region is not a reference");
};
let _ = region.print(printer);

View File

@@ -139,7 +139,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
/// Returns `true` if a closure is inferred to be an `FnMut` closure.
fn is_closure_fn_mut(&self, fr: RegionVid) -> bool {
if let Some(ty::ReFree(free_region)) = self.to_error_region(fr) {
if let Some(ty::ReFree(free_region)) = self.to_error_region(fr).as_deref() {
if let ty::BoundRegionKind::BrEnv = free_region.bound_region {
if let DefiningTy::Closure(_, substs) =
self.regioncx.universal_regions().defining_ty
@@ -628,8 +628,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
fr_name: RegionName,
outlived_fr: RegionVid,
) {
if let (Some(f), Some(ty::RegionKind::ReStatic)) =
(self.to_error_region(fr), self.to_error_region(outlived_fr))
if let (Some(f), Some(ty::ReStatic)) =
(self.to_error_region(fr), self.to_error_region(outlived_fr).as_deref())
{
if let Some(&ty::Opaque(did, substs)) = self
.infcx
@@ -652,7 +652,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
bound.kind().skip_binder()
{
let r = r.subst(self.infcx.tcx, substs);
if let ty::RegionKind::ReStatic = r {
if r.is_static() {
found = true;
break;
} else {

View File

@@ -264,7 +264,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
let tcx = self.infcx.tcx;
debug!("give_region_a_name: error_region = {:?}", error_region);
match error_region {
match *error_region {
ty::ReEarlyBound(ebr) => {
if ebr.has_name() {
let span = tcx.hir().span_if_local(ebr.def_id).unwrap_or(DUMMY_SP);
@@ -433,7 +433,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
span: Span,
counter: usize,
) -> RegionNameHighlight {
let mut highlight = RegionHighlightMode::default();
let mut highlight = RegionHighlightMode::new(self.infcx.tcx);
highlight.highlighting_region_vid(needle_fr, counter);
let type_name =
self.infcx.extract_inference_diagnostics_data(ty.into(), Some(highlight)).name;
@@ -818,7 +818,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
return None;
}
let mut highlight = RegionHighlightMode::default();
let mut highlight = RegionHighlightMode::new(tcx);
highlight.highlighting_region_vid(fr, *self.next_region_name.try_borrow().unwrap());
let type_name =
self.infcx.extract_inference_diagnostics_data(yield_ty.into(), Some(highlight)).name;

View File

@@ -8,7 +8,7 @@ use rustc_middle::mir::{
BasicBlock, Body, ClosureOutlivesSubject, ClosureRegionRequirements, LocalKind, Location,
Promoted,
};
use rustc_middle::ty::{self, OpaqueTypeKey, RegionKind, RegionVid, Ty};
use rustc_middle::ty::{self, OpaqueTypeKey, Region, RegionVid, Ty};
use rustc_span::symbol::sym;
use std::env;
use std::fmt::Debug;
@@ -443,9 +443,9 @@ pub trait ToRegionVid {
fn to_region_vid(self) -> RegionVid;
}
impl<'tcx> ToRegionVid for &'tcx RegionKind {
impl<'tcx> ToRegionVid for Region<'tcx> {
fn to_region_vid(self) -> RegionVid {
if let ty::ReVar(vid) = self { *vid } else { bug!("region is not an ReVar: {:?}", self) }
if let ty::ReVar(vid) = *self { vid } else { bug!("region is not an ReVar: {:?}", self) }
}
}

View File

@@ -1178,7 +1178,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
}
VerifyBound::OutlivedBy(r) => {
let r_vid = self.to_region_vid(r);
let r_vid = self.to_region_vid(*r);
self.eval_outlives(r_vid, lower_bound)
}

View File

@@ -133,7 +133,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
for vid in self.rev_scc_graph.as_ref().unwrap().upper_bounds(scc) {
match self.definitions[vid].external_name {
None => {}
Some(&ty::ReStatic) => {}
Some(region) if region.is_static() => {}
Some(region) => return region,
}
}
@@ -183,7 +183,7 @@ fn check_opaque_type_parameter_valid(
for (i, arg) in opaque_type_key.substs.iter().enumerate() {
let arg_is_param = match arg.unpack() {
GenericArgKind::Type(ty) => matches!(ty.kind(), ty::Param(_)),
GenericArgKind::Lifetime(ty::ReStatic) => {
GenericArgKind::Lifetime(lt) if lt.is_static() => {
tcx.sess
.struct_span_err(span, "non-defining opaque type use in defining scope")
.span_label(
@@ -196,7 +196,7 @@ fn check_opaque_type_parameter_valid(
return false;
}
GenericArgKind::Lifetime(lt) => {
matches!(lt, ty::ReEarlyBound(_) | ty::ReFree(_))
matches!(*lt, ty::ReEarlyBound(_) | ty::ReFree(_))
}
GenericArgKind::Const(ct) => matches!(ct.val, ty::ConstKind::Param(_)),
};

View File

@@ -72,7 +72,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for NllVisitor<'a, 'tcx> {
#[instrument(skip(self), level = "debug")]
fn visit_region(&mut self, region: &mut ty::Region<'tcx>, location: Location) {
let old_region = *region;
*region = self.renumber_regions(&old_region);
*region = self.renumber_regions(old_region);
debug!(?region);
}

View File

@@ -142,8 +142,8 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
}
fn to_region_vid(&mut self, r: ty::Region<'tcx>) -> ty::RegionVid {
if let ty::RePlaceholder(placeholder) = r {
self.constraints.placeholder_region(self.infcx, *placeholder).to_region_vid()
if let ty::RePlaceholder(placeholder) = *r {
self.constraints.placeholder_region(self.infcx, placeholder).to_region_vid()
} else {
self.universal_regions.to_region_vid(r)
}

View File

@@ -358,7 +358,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
// `where Type:` is lowered to `where Type: 'empty` so that
// we check `Type` is well formed, but there's no use for
// this bound here.
if let ty::ReEmpty(_) = r1 {
if r1.is_empty() {
return;
}

View File

@@ -2318,7 +2318,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
}
Rvalue::Ref(region, _borrow_kind, borrowed_place) => {
self.add_reborrow_constraint(&body, location, region, borrowed_place);
self.add_reborrow_constraint(&body, location, *region, borrowed_place);
}
Rvalue::BinaryOp(

View File

@@ -323,7 +323,7 @@ impl<'tcx> UniversalRegions<'tcx> {
/// See `UniversalRegionIndices::to_region_vid`.
pub fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid {
if let ty::ReEmpty(ty::UniverseIndex::ROOT) = r {
if let ty::ReEmpty(ty::UniverseIndex::ROOT) = *r {
self.root_empty
} else {
self.indices.to_region_vid(r)
@@ -805,7 +805,7 @@ impl<'tcx> UniversalRegionIndices<'tcx> {
/// during initialization. Relies on the `indices` map having been
/// fully initialized.
pub fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid {
if let ty::ReVar(..) = r {
if let ty::ReVar(..) = *r {
r.to_region_vid()
} else {
*self