Auto merge of #125284 - compiler-errors:uplift-misc, r=lcnr
Uplift `RegionVid`, `TermKind` to `rustc_type_ir`, and `EagerResolver` to `rustc_next_trait_solver`
- Uplift `RegionVid`. This was complicated due to the fact that we implement `polonius_engine::Atom` for `RegionVid` -- but I just separated that into `PoloniusRegionVid`, and added `From`/`Into` impls so it can be defined in `rustc_borrowck` separately. Coherence 😵
- Change `InferCtxtLike` to expose `opportunistically_resolve_{ty,ct,lt,int,float}_var` so that we can uplift `EagerResolver` for use in the canonicalization methods.
- Uplift `TermKind` much like `GenericArgKind`
All of this is miscellaneous dependencies for making more `EvalCtxt` methods generic.
This commit is contained in:
commit
9cb6bb8599
@ -15,8 +15,31 @@
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct RustcFacts;
|
||||
|
||||
rustc_index::newtype_index! {
|
||||
/// A (kinda) newtype of `RegionVid` so we can implement `Atom` on it.
|
||||
#[orderable]
|
||||
#[debug_format = "'?{}"]
|
||||
pub struct PoloniusRegionVid {}
|
||||
}
|
||||
|
||||
impl polonius_engine::Atom for PoloniusRegionVid {
|
||||
fn index(self) -> usize {
|
||||
self.as_usize()
|
||||
}
|
||||
}
|
||||
impl From<RegionVid> for PoloniusRegionVid {
|
||||
fn from(value: RegionVid) -> Self {
|
||||
Self::from_usize(value.as_usize())
|
||||
}
|
||||
}
|
||||
impl From<PoloniusRegionVid> for RegionVid {
|
||||
fn from(value: PoloniusRegionVid) -> Self {
|
||||
Self::from_usize(value.as_usize())
|
||||
}
|
||||
}
|
||||
|
||||
impl polonius_engine::FactTypes for RustcFacts {
|
||||
type Origin = RegionVid;
|
||||
type Origin = PoloniusRegionVid;
|
||||
type Loan = BorrowIndex;
|
||||
type Point = LocationIndex;
|
||||
type Variable = Local;
|
||||
@ -119,7 +142,7 @@ fn write(
|
||||
) -> Result<(), Box<dyn Error>>;
|
||||
}
|
||||
|
||||
impl FactRow for RegionVid {
|
||||
impl FactRow for PoloniusRegionVid {
|
||||
fn write(
|
||||
&self,
|
||||
out: &mut dyn Write,
|
||||
|
@ -8,7 +8,7 @@
|
||||
use rustc_mir_dataflow::move_paths::{InitKind, InitLocation, MoveData};
|
||||
|
||||
use crate::borrow_set::BorrowSet;
|
||||
use crate::facts::AllFacts;
|
||||
use crate::facts::{AllFacts, PoloniusRegionVid};
|
||||
use crate::location::LocationTable;
|
||||
use crate::type_check::free_region_relations::UniversalRegionRelations;
|
||||
use crate::universal_regions::UniversalRegions;
|
||||
@ -137,7 +137,9 @@ fn emit_universal_region_facts(
|
||||
// the `borrow_set`, their `BorrowIndex` are synthesized as the universal region index
|
||||
// added to the existing number of loans, as if they succeeded them in the set.
|
||||
//
|
||||
all_facts.universal_region.extend(universal_regions.universal_regions());
|
||||
all_facts
|
||||
.universal_region
|
||||
.extend(universal_regions.universal_regions().map(PoloniusRegionVid::from));
|
||||
let borrow_count = borrow_set.len();
|
||||
debug!(
|
||||
"emit_universal_region_facts: polonius placeholders, num_universals={}, borrow_count={}",
|
||||
@ -148,7 +150,7 @@ fn emit_universal_region_facts(
|
||||
for universal_region in universal_regions.universal_regions() {
|
||||
let universal_region_idx = universal_region.index();
|
||||
let placeholder_loan_idx = borrow_count + universal_region_idx;
|
||||
all_facts.placeholder.push((universal_region, placeholder_loan_idx.into()));
|
||||
all_facts.placeholder.push((universal_region.into(), placeholder_loan_idx.into()));
|
||||
}
|
||||
|
||||
// 2: the universal region relations `outlives` constraints are emitted as
|
||||
@ -160,7 +162,7 @@ fn emit_universal_region_facts(
|
||||
fr1={:?}, fr2={:?}",
|
||||
fr1, fr2
|
||||
);
|
||||
all_facts.known_placeholder_subset.push((fr1, fr2));
|
||||
all_facts.known_placeholder_subset.push((fr1.into(), fr2.into()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1506,7 +1506,7 @@ fn check_polonius_subset_errors(
|
||||
subset_errors.sort();
|
||||
subset_errors.dedup();
|
||||
|
||||
for (longer_fr, shorter_fr) in subset_errors.into_iter() {
|
||||
for &(longer_fr, shorter_fr) in subset_errors.into_iter() {
|
||||
debug!(
|
||||
"check_polonius_subset_errors: subset_error longer_fr={:?},\
|
||||
shorter_fr={:?}",
|
||||
@ -1514,14 +1514,14 @@ fn check_polonius_subset_errors(
|
||||
);
|
||||
|
||||
let propagated = self.try_propagate_universal_region_error(
|
||||
*longer_fr,
|
||||
*shorter_fr,
|
||||
longer_fr.into(),
|
||||
shorter_fr.into(),
|
||||
&mut propagated_outlives_requirements,
|
||||
);
|
||||
if propagated == RegionRelationCheckResult::Error {
|
||||
errors_buffer.push(RegionErrorKind::RegionError {
|
||||
longer_fr: *longer_fr,
|
||||
shorter_fr: *shorter_fr,
|
||||
longer_fr: longer_fr.into(),
|
||||
shorter_fr: shorter_fr.into(),
|
||||
fr_origin: NllRegionVariableOrigin::FreeRegion,
|
||||
is_reported: true,
|
||||
});
|
||||
|
@ -117,7 +117,7 @@ pub(super) fn populate_access_facts<'a, 'tcx>(
|
||||
let universal_regions = &typeck.borrowck_context.universal_regions;
|
||||
typeck.infcx.tcx.for_each_free_region(&local_decl.ty, |region| {
|
||||
let region_vid = universal_regions.to_region_vid(region);
|
||||
facts.use_of_var_derefs_origin.push((local, region_vid));
|
||||
facts.use_of_var_derefs_origin.push((local, region_vid.into()));
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -136,7 +136,7 @@ pub(super) fn add_drop_of_var_derefs_origin<'tcx>(
|
||||
let universal_regions = &typeck.borrowck_context.universal_regions;
|
||||
typeck.infcx.tcx.for_each_free_region(kind, |drop_live_region| {
|
||||
let region_vid = universal_regions.to_region_vid(drop_live_region);
|
||||
facts.drop_of_var_derefs_origin.push((local, region_vid));
|
||||
facts.drop_of_var_derefs_origin.push((local, region_vid.into()));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -260,16 +260,14 @@ fn translate_outlives_facts(typeck: &mut TypeChecker<'_, '_>) {
|
||||
|constraint: &OutlivesConstraint<'_>| {
|
||||
if let Some(from_location) = constraint.locations.from_location() {
|
||||
Either::Left(iter::once((
|
||||
constraint.sup,
|
||||
constraint.sub,
|
||||
constraint.sup.into(),
|
||||
constraint.sub.into(),
|
||||
location_table.mid_index(from_location),
|
||||
)))
|
||||
} else {
|
||||
Either::Right(
|
||||
location_table
|
||||
.all_points()
|
||||
.map(move |location| (constraint.sup, constraint.sub, location)),
|
||||
)
|
||||
Either::Right(location_table.all_points().map(move |location| {
|
||||
(constraint.sup.into(), constraint.sub.into(), location)
|
||||
}))
|
||||
}
|
||||
},
|
||||
));
|
||||
@ -2545,7 +2543,7 @@ fn add_reborrow_constraint(
|
||||
if let Some(borrow_index) = borrow_set.get_index_of(&location) {
|
||||
let region_vid = borrow_region.as_var();
|
||||
all_facts.loan_issued_at.push((
|
||||
region_vid,
|
||||
region_vid.into(),
|
||||
borrow_index,
|
||||
location_table.mid_index(location),
|
||||
));
|
||||
|
@ -369,34 +369,44 @@ fn universe_of_lt(&self, lt: ty::RegionVid) -> Option<ty::UniverseIndex> {
|
||||
}
|
||||
}
|
||||
|
||||
fn root_ty_var(&self, vid: TyVid) -> TyVid {
|
||||
self.root_var(vid)
|
||||
}
|
||||
|
||||
fn probe_ty_var(&self, vid: TyVid) -> Option<Ty<'tcx>> {
|
||||
self.probe_ty_var(vid).ok()
|
||||
}
|
||||
|
||||
fn opportunistic_resolve_lt_var(&self, vid: ty::RegionVid) -> Option<ty::Region<'tcx>> {
|
||||
let re = self
|
||||
.inner
|
||||
.borrow_mut()
|
||||
.unwrap_region_constraints()
|
||||
.opportunistic_resolve_var(self.tcx, vid);
|
||||
if *re == ty::ReVar(vid) { None } else { Some(re) }
|
||||
}
|
||||
|
||||
fn root_ct_var(&self, vid: ConstVid) -> ConstVid {
|
||||
self.root_const_var(vid)
|
||||
}
|
||||
|
||||
fn probe_ct_var(&self, vid: ConstVid) -> Option<ty::Const<'tcx>> {
|
||||
self.probe_const_var(vid).ok()
|
||||
fn opportunistic_resolve_lt_var(&self, vid: ty::RegionVid) -> ty::Region<'tcx> {
|
||||
self.inner.borrow_mut().unwrap_region_constraints().opportunistic_resolve_var(self.tcx, vid)
|
||||
}
|
||||
|
||||
fn defining_opaque_types(&self) -> &'tcx ty::List<LocalDefId> {
|
||||
self.defining_opaque_types
|
||||
}
|
||||
|
||||
fn opportunistic_resolve_ty_var(&self, vid: TyVid) -> Ty<'tcx> {
|
||||
match self.probe_ty_var(vid) {
|
||||
Ok(ty) => ty,
|
||||
Err(_) => Ty::new_var(self.tcx, self.root_var(vid)),
|
||||
}
|
||||
}
|
||||
|
||||
fn opportunistic_resolve_int_var(&self, vid: IntVid) -> Ty<'tcx> {
|
||||
self.opportunistic_resolve_int_var(vid)
|
||||
}
|
||||
|
||||
fn opportunistic_resolve_float_var(&self, vid: FloatVid) -> Ty<'tcx> {
|
||||
self.opportunistic_resolve_float_var(vid)
|
||||
}
|
||||
|
||||
fn opportunistic_resolve_ct_var(&self, vid: ConstVid, ty: Ty<'tcx>) -> ty::Const<'tcx> {
|
||||
match self.probe_const_var(vid) {
|
||||
Ok(ct) => ct,
|
||||
Err(_) => ty::Const::new_var(self.tcx, self.root_const_var(vid), ty),
|
||||
}
|
||||
}
|
||||
|
||||
fn opportunistic_resolve_effect_var(&self, vid: EffectVid, ty: Ty<'tcx>) -> ty::Const<'tcx> {
|
||||
match self.probe_effect_var(vid) {
|
||||
Some(ct) => ct,
|
||||
None => {
|
||||
ty::Const::new_infer(self.tcx, InferConst::EffectVar(self.root_effect_var(vid)), ty)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// See the `error_reporting` module for more details.
|
||||
|
@ -173,84 +173,3 @@ fn try_fold_const(&mut self, c: ty::Const<'tcx>) -> Result<ty::Const<'tcx>, Self
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// EAGER RESOLUTION
|
||||
|
||||
/// Resolves ty, region, and const vars to their inferred values or their root vars.
|
||||
pub struct EagerResolver<'a, 'tcx> {
|
||||
infcx: &'a InferCtxt<'tcx>,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> EagerResolver<'a, 'tcx> {
|
||||
pub fn new(infcx: &'a InferCtxt<'tcx>) -> Self {
|
||||
EagerResolver { infcx }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for EagerResolver<'_, 'tcx> {
|
||||
fn interner(&self) -> TyCtxt<'tcx> {
|
||||
self.infcx.tcx
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||
match *t.kind() {
|
||||
ty::Infer(ty::TyVar(vid)) => match self.infcx.probe_ty_var(vid) {
|
||||
Ok(t) => t.fold_with(self),
|
||||
Err(_) => Ty::new_var(self.infcx.tcx, self.infcx.root_var(vid)),
|
||||
},
|
||||
ty::Infer(ty::IntVar(vid)) => self.infcx.opportunistic_resolve_int_var(vid),
|
||||
ty::Infer(ty::FloatVar(vid)) => self.infcx.opportunistic_resolve_float_var(vid),
|
||||
_ => {
|
||||
if t.has_infer() {
|
||||
t.super_fold_with(self)
|
||||
} else {
|
||||
t
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
match *r {
|
||||
ty::ReVar(vid) => self
|
||||
.infcx
|
||||
.inner
|
||||
.borrow_mut()
|
||||
.unwrap_region_constraints()
|
||||
.opportunistic_resolve_var(self.infcx.tcx, vid),
|
||||
_ => r,
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_const(&mut self, c: ty::Const<'tcx>) -> ty::Const<'tcx> {
|
||||
match c.kind() {
|
||||
ty::ConstKind::Infer(ty::InferConst::Var(vid)) => {
|
||||
// FIXME: we need to fold the ty too, I think.
|
||||
match self.infcx.probe_const_var(vid) {
|
||||
Ok(c) => c.fold_with(self),
|
||||
Err(_) => {
|
||||
ty::Const::new_var(self.infcx.tcx, self.infcx.root_const_var(vid), c.ty())
|
||||
}
|
||||
}
|
||||
}
|
||||
ty::ConstKind::Infer(ty::InferConst::EffectVar(vid)) => {
|
||||
debug_assert_eq!(c.ty(), self.infcx.tcx.types.bool);
|
||||
self.infcx.probe_effect_var(vid).unwrap_or_else(|| {
|
||||
ty::Const::new_infer(
|
||||
self.infcx.tcx,
|
||||
ty::InferConst::EffectVar(self.infcx.root_effect_var(vid)),
|
||||
self.infcx.tcx.types.bool,
|
||||
)
|
||||
})
|
||||
}
|
||||
_ => {
|
||||
if c.has_infer() {
|
||||
c.super_fold_with(self)
|
||||
} else {
|
||||
c
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -175,6 +175,14 @@ pub fn new_error_with_message<S: Into<MultiSpan>>(
|
||||
}
|
||||
|
||||
impl<'tcx> rustc_type_ir::inherent::Const<TyCtxt<'tcx>> for Const<'tcx> {
|
||||
fn new_infer(tcx: TyCtxt<'tcx>, infer: ty::InferConst, ty: Ty<'tcx>) -> Self {
|
||||
Const::new_infer(tcx, infer, ty)
|
||||
}
|
||||
|
||||
fn new_var(tcx: TyCtxt<'tcx>, vid: ty::ConstVid, ty: Ty<'tcx>) -> Self {
|
||||
Const::new_var(tcx, vid, ty)
|
||||
}
|
||||
|
||||
fn new_anon_bound(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
debruijn: ty::DebruijnIndex,
|
||||
|
@ -134,7 +134,6 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
||||
type EarlyParamRegion = ty::EarlyParamRegion;
|
||||
type LateParamRegion = ty::LateParamRegion;
|
||||
type BoundRegion = ty::BoundRegion;
|
||||
type InferRegion = ty::RegionVid;
|
||||
type PlaceholderRegion = ty::PlaceholderRegion;
|
||||
|
||||
type ParamEnv = ty::ParamEnv<'tcx>;
|
||||
|
@ -27,6 +27,7 @@
|
||||
use std::ptr::NonNull;
|
||||
|
||||
pub type GenericArgKind<'tcx> = rustc_type_ir::GenericArgKind<TyCtxt<'tcx>>;
|
||||
pub type TermKind<'tcx> = rustc_type_ir::TermKind<TyCtxt<'tcx>>;
|
||||
|
||||
/// An entity in the Rust type system, which can be one of
|
||||
/// several kinds (types, lifetimes, and consts).
|
||||
|
@ -28,7 +28,7 @@
|
||||
use crate::ty::util::Discr;
|
||||
pub use adt::*;
|
||||
pub use assoc::*;
|
||||
pub use generic_args::{GenericArgKind, *};
|
||||
pub use generic_args::{GenericArgKind, TermKind, *};
|
||||
pub use generics::*;
|
||||
pub use intrinsic::IntrinsicDef;
|
||||
use rustc_ast as ast;
|
||||
@ -48,7 +48,8 @@
|
||||
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap};
|
||||
use rustc_index::IndexVec;
|
||||
use rustc_macros::{
|
||||
Decodable, Encodable, HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable,
|
||||
extension, Decodable, Encodable, HashStable, TyDecodable, TyEncodable, TypeFoldable,
|
||||
TypeVisitable,
|
||||
};
|
||||
use rustc_query_system::ich::StableHashingContext;
|
||||
use rustc_serialize::{Decodable, Encodable};
|
||||
@ -521,6 +522,14 @@ pub struct Term<'tcx> {
|
||||
marker: PhantomData<(Ty<'tcx>, Const<'tcx>)>,
|
||||
}
|
||||
|
||||
impl<'tcx> rustc_type_ir::inherent::IntoKind for Term<'tcx> {
|
||||
type Kind = TermKind<'tcx>;
|
||||
|
||||
fn kind(self) -> Self::Kind {
|
||||
self.unpack()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(parallel_compiler)]
|
||||
unsafe impl<'tcx> rustc_data_structures::sync::DynSend for Term<'tcx> where
|
||||
&'tcx (Ty<'tcx>, Const<'tcx>): rustc_data_structures::sync::DynSend
|
||||
@ -566,13 +575,19 @@ fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>(
|
||||
self,
|
||||
folder: &mut F,
|
||||
) -> Result<Self, F::Error> {
|
||||
Ok(self.unpack().try_fold_with(folder)?.pack())
|
||||
match self.unpack() {
|
||||
ty::TermKind::Ty(ty) => ty.try_fold_with(folder).map(Into::into),
|
||||
ty::TermKind::Const(ct) => ct.try_fold_with(folder).map(Into::into),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for Term<'tcx> {
|
||||
fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
|
||||
self.unpack().visit_with(visitor)
|
||||
match self.unpack() {
|
||||
ty::TermKind::Ty(ty) => ty.visit_with(visitor),
|
||||
ty::TermKind::Const(ct) => ct.visit_with(visitor),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -650,13 +665,7 @@ pub fn is_infer(&self) -> bool {
|
||||
const TYPE_TAG: usize = 0b00;
|
||||
const CONST_TAG: usize = 0b01;
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
|
||||
#[derive(HashStable, TypeFoldable, TypeVisitable)]
|
||||
pub enum TermKind<'tcx> {
|
||||
Ty(Ty<'tcx>),
|
||||
Const(Const<'tcx>),
|
||||
}
|
||||
|
||||
#[extension(pub trait TermKindPackExt<'tcx>)]
|
||||
impl<'tcx> TermKind<'tcx> {
|
||||
#[inline]
|
||||
fn pack(self) -> Term<'tcx> {
|
||||
|
@ -1,13 +1,12 @@
|
||||
use polonius_engine::Atom;
|
||||
use rustc_data_structures::intern::Interned;
|
||||
use rustc_errors::MultiSpan;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_index::Idx;
|
||||
use rustc_macros::{HashStable, TyDecodable, TyEncodable};
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_span::symbol::{kw, Symbol};
|
||||
use rustc_span::{ErrorGuaranteed, DUMMY_SP};
|
||||
use rustc_type_ir::RegionKind as IrRegionKind;
|
||||
pub use rustc_type_ir::RegionVid;
|
||||
use std::ops::Deref;
|
||||
|
||||
use crate::ty::{self, BoundVar, TyCtxt, TypeFlags};
|
||||
@ -348,21 +347,6 @@ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
}
|
||||
}
|
||||
|
||||
rustc_index::newtype_index! {
|
||||
/// A **region** (lifetime) **v**ariable **ID**.
|
||||
#[derive(HashStable)]
|
||||
#[encodable]
|
||||
#[orderable]
|
||||
#[debug_format = "'?{}"]
|
||||
pub struct RegionVid {}
|
||||
}
|
||||
|
||||
impl Atom for RegionVid {
|
||||
fn index(self) -> usize {
|
||||
Idx::index(self)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, Copy)]
|
||||
#[derive(HashStable)]
|
||||
/// The parameter representation of late-bound function parameters, "some region
|
||||
|
@ -259,18 +259,6 @@ fn fmt<Infcx: InferCtxtLike<Interner = TyCtxt<'tcx>>>(
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> DebugWithInfcx<TyCtxt<'tcx>> for ty::RegionVid {
|
||||
fn fmt<Infcx: InferCtxtLike<Interner = TyCtxt<'tcx>>>(
|
||||
this: WithInfcx<'_, Infcx, &Self>,
|
||||
f: &mut core::fmt::Formatter<'_>,
|
||||
) -> core::fmt::Result {
|
||||
match this.infcx.universe_of_lt(*this.data) {
|
||||
Some(universe) => write!(f, "'?{}_{}", this.data.index(), universe.index()),
|
||||
None => write!(f, "{:?}", this.data),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T: DebugWithInfcx<TyCtxt<'tcx>>> DebugWithInfcx<TyCtxt<'tcx>> for ty::Binder<'tcx, T> {
|
||||
fn fmt<Infcx: InferCtxtLike<Interner = TyCtxt<'tcx>>>(
|
||||
this: WithInfcx<'_, Infcx, &Self>,
|
||||
@ -383,13 +371,10 @@ fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
|
||||
impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Term<'a> {
|
||||
type Lifted = ty::Term<'tcx>;
|
||||
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
|
||||
Some(
|
||||
match self.unpack() {
|
||||
TermKind::Ty(ty) => TermKind::Ty(tcx.lift(ty)?),
|
||||
TermKind::Const(c) => TermKind::Const(tcx.lift(c)?),
|
||||
}
|
||||
.pack(),
|
||||
)
|
||||
match self.unpack() {
|
||||
TermKind::Ty(ty) => tcx.lift(ty).map(Into::into),
|
||||
TermKind::Const(c) => tcx.lift(c).map(Into::into),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1611,6 +1611,14 @@ fn new_bool(tcx: TyCtxt<'tcx>) -> Self {
|
||||
tcx.types.bool
|
||||
}
|
||||
|
||||
fn new_infer(tcx: TyCtxt<'tcx>, infer: ty::InferTy) -> Self {
|
||||
Ty::new_infer(tcx, infer)
|
||||
}
|
||||
|
||||
fn new_var(tcx: TyCtxt<'tcx>, vid: ty::TyVid) -> Self {
|
||||
Ty::new_var(tcx, vid)
|
||||
}
|
||||
|
||||
fn new_anon_bound(tcx: TyCtxt<'tcx>, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self {
|
||||
Ty::new_bound(tcx, debruijn, ty::BoundTy { var, kind: ty::BoundTyKind::Anon })
|
||||
}
|
||||
|
@ -268,7 +268,7 @@ fn fold_region(&mut self, r: I::Region) -> I::Region {
|
||||
ty::ReVar(vid) => {
|
||||
assert_eq!(
|
||||
self.infcx.opportunistic_resolve_lt_var(vid),
|
||||
None,
|
||||
r,
|
||||
"region vid should have been resolved fully before canonicalization"
|
||||
);
|
||||
match self.canonicalize_mode {
|
||||
@ -302,13 +302,8 @@ fn fold_ty(&mut self, t: I::Ty) -> I::Ty {
|
||||
ty::Infer(i) => match i {
|
||||
ty::TyVar(vid) => {
|
||||
assert_eq!(
|
||||
self.infcx.root_ty_var(vid),
|
||||
vid,
|
||||
"ty vid should have been resolved fully before canonicalization"
|
||||
);
|
||||
assert_eq!(
|
||||
self.infcx.probe_ty_var(vid),
|
||||
None,
|
||||
self.infcx.opportunistic_resolve_ty_var(vid),
|
||||
t,
|
||||
"ty vid should have been resolved fully before canonicalization"
|
||||
);
|
||||
|
||||
@ -318,10 +313,24 @@ fn fold_ty(&mut self, t: I::Ty) -> I::Ty {
|
||||
.unwrap_or_else(|| panic!("ty var should have been resolved: {t:?}")),
|
||||
))
|
||||
}
|
||||
ty::IntVar(_) => CanonicalVarKind::Ty(CanonicalTyVarKind::Int),
|
||||
ty::FloatVar(_) => CanonicalVarKind::Ty(CanonicalTyVarKind::Float),
|
||||
ty::IntVar(vid) => {
|
||||
assert_eq!(
|
||||
self.infcx.opportunistic_resolve_int_var(vid),
|
||||
t,
|
||||
"ty vid should have been resolved fully before canonicalization"
|
||||
);
|
||||
CanonicalVarKind::Ty(CanonicalTyVarKind::Int)
|
||||
}
|
||||
ty::FloatVar(vid) => {
|
||||
assert_eq!(
|
||||
self.infcx.opportunistic_resolve_float_var(vid),
|
||||
t,
|
||||
"ty vid should have been resolved fully before canonicalization"
|
||||
);
|
||||
CanonicalVarKind::Ty(CanonicalTyVarKind::Float)
|
||||
}
|
||||
ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) => {
|
||||
todo!()
|
||||
panic!("fresh vars not expected in canonicalization")
|
||||
}
|
||||
},
|
||||
ty::Placeholder(placeholder) => match self.canonicalize_mode {
|
||||
@ -387,14 +396,11 @@ fn fold_const(&mut self, c: I::Const) -> I::Const {
|
||||
let kind = match c.kind() {
|
||||
ty::ConstKind::Infer(i) => match i {
|
||||
ty::InferConst::Var(vid) => {
|
||||
// We compare `kind`s here because we've folded the `ty` with `RegionsToStatic`
|
||||
// so we'll get a mismatch in types if it actually changed any regions.
|
||||
assert_eq!(
|
||||
self.infcx.root_ct_var(vid),
|
||||
vid,
|
||||
"region vid should have been resolved fully before canonicalization"
|
||||
);
|
||||
assert_eq!(
|
||||
self.infcx.probe_ct_var(vid),
|
||||
None,
|
||||
self.infcx.opportunistic_resolve_ct_var(vid, ty).kind(),
|
||||
c.kind(),
|
||||
"region vid should have been resolved fully before canonicalization"
|
||||
);
|
||||
CanonicalVarKind::Const(self.infcx.universe_of_ct(vid).unwrap(), ty)
|
||||
|
@ -1,2 +1,3 @@
|
||||
pub mod canonicalizer;
|
||||
pub mod resolve;
|
||||
pub mod solve;
|
||||
|
83
compiler/rustc_next_trait_solver/src/resolve.rs
Normal file
83
compiler/rustc_next_trait_solver/src/resolve.rs
Normal file
@ -0,0 +1,83 @@
|
||||
use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
|
||||
use rustc_type_ir::inherent::*;
|
||||
use rustc_type_ir::visit::TypeVisitableExt;
|
||||
use rustc_type_ir::{self as ty, InferCtxtLike, Interner};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// EAGER RESOLUTION
|
||||
|
||||
/// Resolves ty, region, and const vars to their inferred values or their root vars.
|
||||
pub struct EagerResolver<
|
||||
'a,
|
||||
Infcx: InferCtxtLike<Interner = I>,
|
||||
I: Interner = <Infcx as InferCtxtLike>::Interner,
|
||||
> {
|
||||
infcx: &'a Infcx,
|
||||
}
|
||||
|
||||
impl<'a, Infcx: InferCtxtLike> EagerResolver<'a, Infcx> {
|
||||
pub fn new(infcx: &'a Infcx) -> Self {
|
||||
EagerResolver { infcx }
|
||||
}
|
||||
}
|
||||
|
||||
impl<Infcx: InferCtxtLike<Interner = I>, I: Interner> TypeFolder<I> for EagerResolver<'_, Infcx> {
|
||||
fn interner(&self) -> I {
|
||||
self.infcx.interner()
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, t: I::Ty) -> I::Ty {
|
||||
match t.kind() {
|
||||
ty::Infer(ty::TyVar(vid)) => {
|
||||
let resolved = self.infcx.opportunistic_resolve_ty_var(vid);
|
||||
if t != resolved && resolved.has_infer() {
|
||||
resolved.fold_with(self)
|
||||
} else {
|
||||
resolved
|
||||
}
|
||||
}
|
||||
ty::Infer(ty::IntVar(vid)) => self.infcx.opportunistic_resolve_int_var(vid),
|
||||
ty::Infer(ty::FloatVar(vid)) => self.infcx.opportunistic_resolve_float_var(vid),
|
||||
_ => {
|
||||
if t.has_infer() {
|
||||
t.super_fold_with(self)
|
||||
} else {
|
||||
t
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_region(&mut self, r: I::Region) -> I::Region {
|
||||
match r.kind() {
|
||||
ty::ReVar(vid) => self.infcx.opportunistic_resolve_lt_var(vid),
|
||||
_ => r,
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_const(&mut self, c: I::Const) -> I::Const {
|
||||
match c.kind() {
|
||||
ty::ConstKind::Infer(ty::InferConst::Var(vid)) => {
|
||||
let ty = c.ty().fold_with(self);
|
||||
let resolved = self.infcx.opportunistic_resolve_ct_var(vid, ty);
|
||||
if c != resolved && resolved.has_infer() {
|
||||
resolved.fold_with(self)
|
||||
} else {
|
||||
resolved
|
||||
}
|
||||
}
|
||||
ty::ConstKind::Infer(ty::InferConst::EffectVar(vid)) => {
|
||||
let bool = Ty::new_bool(self.infcx.interner());
|
||||
debug_assert_eq!(c.ty(), bool);
|
||||
self.infcx.opportunistic_resolve_effect_var(vid, bool)
|
||||
}
|
||||
_ => {
|
||||
if c.has_infer() {
|
||||
c.super_fold_with(self)
|
||||
} else {
|
||||
c
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -18,7 +18,6 @@
|
||||
use rustc_infer::infer::canonical::query_response::make_query_region_constraints;
|
||||
use rustc_infer::infer::canonical::CanonicalVarValues;
|
||||
use rustc_infer::infer::canonical::{CanonicalExt, QueryRegionConstraints};
|
||||
use rustc_infer::infer::resolve::EagerResolver;
|
||||
use rustc_infer::infer::RegionVariableOrigin;
|
||||
use rustc_infer::infer::{InferCtxt, InferOk};
|
||||
use rustc_infer::traits::solve::NestedNormalizationGoals;
|
||||
@ -31,6 +30,7 @@
|
||||
use rustc_middle::traits::ObligationCause;
|
||||
use rustc_middle::ty::{self, BoundVar, GenericArgKind, Ty, TyCtxt, TypeFoldable};
|
||||
use rustc_next_trait_solver::canonicalizer::{CanonicalizeMode, Canonicalizer};
|
||||
use rustc_next_trait_solver::resolve::EagerResolver;
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
use std::assert_matches::assert_matches;
|
||||
use std::iter;
|
||||
|
@ -11,7 +11,6 @@
|
||||
|
||||
use rustc_ast_ir::try_visit;
|
||||
use rustc_ast_ir::visit::VisitorResult;
|
||||
use rustc_infer::infer::resolve::EagerResolver;
|
||||
use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk};
|
||||
use rustc_macros::extension;
|
||||
use rustc_middle::traits::query::NoSolution;
|
||||
@ -20,6 +19,7 @@
|
||||
use rustc_middle::traits::ObligationCause;
|
||||
use rustc_middle::ty::{TyCtxt, TypeFoldable};
|
||||
use rustc_middle::{bug, ty};
|
||||
use rustc_next_trait_solver::resolve::EagerResolver;
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
|
||||
use crate::solve::eval_ctxt::canonical;
|
||||
|
@ -1,4 +1,6 @@
|
||||
use crate::{ConstVid, InferCtxtLike, Interner, TyVid, UniverseIndex};
|
||||
use crate::{
|
||||
ConstVid, EffectVid, FloatVid, InferCtxtLike, IntVid, Interner, RegionVid, TyVid, UniverseIndex,
|
||||
};
|
||||
|
||||
use core::fmt;
|
||||
use std::marker::PhantomData;
|
||||
@ -16,7 +18,7 @@ fn universe_of_ty(&self, _ty: TyVid) -> Option<UniverseIndex> {
|
||||
None
|
||||
}
|
||||
|
||||
fn universe_of_lt(&self, _lt: I::InferRegion) -> Option<UniverseIndex> {
|
||||
fn universe_of_lt(&self, _lt: RegionVid) -> Option<UniverseIndex> {
|
||||
None
|
||||
}
|
||||
|
||||
@ -24,27 +26,31 @@ fn universe_of_ct(&self, _ct: ConstVid) -> Option<UniverseIndex> {
|
||||
None
|
||||
}
|
||||
|
||||
fn root_ty_var(&self, vid: TyVid) -> TyVid {
|
||||
vid
|
||||
fn opportunistic_resolve_ty_var(&self, vid: TyVid) -> I::Ty {
|
||||
panic!("cannot resolve {vid:?}")
|
||||
}
|
||||
|
||||
fn probe_ty_var(&self, _vid: TyVid) -> Option<I::Ty> {
|
||||
None
|
||||
fn opportunistic_resolve_int_var(&self, vid: IntVid) -> I::Ty {
|
||||
panic!("cannot resolve {vid:?}")
|
||||
}
|
||||
|
||||
fn opportunistic_resolve_lt_var(&self, _vid: I::InferRegion) -> Option<I::Region> {
|
||||
None
|
||||
fn opportunistic_resolve_float_var(&self, vid: FloatVid) -> I::Ty {
|
||||
panic!("cannot resolve {vid:?}")
|
||||
}
|
||||
|
||||
fn root_ct_var(&self, vid: ConstVid) -> ConstVid {
|
||||
vid
|
||||
fn opportunistic_resolve_ct_var(&self, vid: ConstVid, _: I::Ty) -> I::Const {
|
||||
panic!("cannot resolve {vid:?}")
|
||||
}
|
||||
|
||||
fn probe_ct_var(&self, _vid: ConstVid) -> Option<I::Const> {
|
||||
None
|
||||
fn opportunistic_resolve_effect_var(&self, vid: EffectVid, _: I::Ty) -> I::Const {
|
||||
panic!("cannot resolve {vid:?}")
|
||||
}
|
||||
|
||||
fn defining_opaque_types(&self) -> <Self::Interner as Interner>::DefiningOpaqueTypes {
|
||||
fn opportunistic_resolve_lt_var(&self, vid: crate::RegionVid) -> I::Region {
|
||||
panic!("cannot resolve {vid:?}")
|
||||
}
|
||||
|
||||
fn defining_opaque_types(&self) -> I::DefiningOpaqueTypes {
|
||||
Default::default()
|
||||
}
|
||||
}
|
||||
|
@ -16,3 +16,17 @@ pub enum GenericArgKind<I: Interner> {
|
||||
Type(I::Ty),
|
||||
Const(I::Const),
|
||||
}
|
||||
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
Clone(bound = ""),
|
||||
Copy(bound = ""),
|
||||
Debug(bound = ""),
|
||||
Eq(bound = ""),
|
||||
PartialEq(bound = "")
|
||||
)]
|
||||
#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
|
||||
pub enum TermKind<I: Interner> {
|
||||
Ty(I::Ty),
|
||||
Const(I::Const),
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::{ConstVid, Interner, TyVid, UniverseIndex};
|
||||
use crate::{ConstVid, EffectVid, FloatVid, IntVid, Interner, RegionVid, TyVid, UniverseIndex};
|
||||
|
||||
pub trait InferCtxtLike {
|
||||
type Interner: Interner;
|
||||
@ -6,37 +6,23 @@ pub trait InferCtxtLike {
|
||||
fn interner(&self) -> Self::Interner;
|
||||
|
||||
fn universe_of_ty(&self, ty: TyVid) -> Option<UniverseIndex>;
|
||||
|
||||
/// Resolve `TyVid` to its root `TyVid`.
|
||||
fn root_ty_var(&self, vid: TyVid) -> TyVid;
|
||||
|
||||
/// Resolve `TyVid` to its inferred type, if it has been equated with a non-infer type.
|
||||
fn probe_ty_var(&self, vid: TyVid) -> Option<<Self::Interner as Interner>::Ty>;
|
||||
|
||||
fn universe_of_lt(
|
||||
&self,
|
||||
lt: <Self::Interner as Interner>::InferRegion,
|
||||
) -> Option<UniverseIndex>;
|
||||
|
||||
/// Resolve `InferRegion` to its inferred region, if it has been equated with
|
||||
/// a non-infer region.
|
||||
///
|
||||
/// FIXME: This has slightly different semantics than `{probe,resolve}_{ty,ct}_var`,
|
||||
/// that has to do with the fact unlike `Ty` or `Const` vars, in rustc, we may
|
||||
/// not always be able to *name* the root region var from the universe of the
|
||||
/// var we're trying to resolve. That's why it's called *opportunistic*.
|
||||
fn opportunistic_resolve_lt_var(
|
||||
&self,
|
||||
vid: <Self::Interner as Interner>::InferRegion,
|
||||
) -> Option<<Self::Interner as Interner>::Region>;
|
||||
|
||||
fn universe_of_lt(&self, lt: RegionVid) -> Option<UniverseIndex>;
|
||||
fn universe_of_ct(&self, ct: ConstVid) -> Option<UniverseIndex>;
|
||||
|
||||
/// Resolve `ConstVid` to its root `ConstVid`.
|
||||
fn root_ct_var(&self, vid: ConstVid) -> ConstVid;
|
||||
|
||||
/// Resolve `ConstVid` to its inferred type, if it has been equated with a non-infer type.
|
||||
fn probe_ct_var(&self, vid: ConstVid) -> Option<<Self::Interner as Interner>::Const>;
|
||||
fn opportunistic_resolve_ty_var(&self, vid: TyVid) -> <Self::Interner as Interner>::Ty;
|
||||
fn opportunistic_resolve_int_var(&self, vid: IntVid) -> <Self::Interner as Interner>::Ty;
|
||||
fn opportunistic_resolve_float_var(&self, vid: FloatVid) -> <Self::Interner as Interner>::Ty;
|
||||
fn opportunistic_resolve_ct_var(
|
||||
&self,
|
||||
vid: ConstVid,
|
||||
ty: <Self::Interner as Interner>::Ty,
|
||||
) -> <Self::Interner as Interner>::Const;
|
||||
fn opportunistic_resolve_effect_var(
|
||||
&self,
|
||||
vid: EffectVid,
|
||||
ty: <Self::Interner as Interner>::Ty,
|
||||
) -> <Self::Interner as Interner>::Const;
|
||||
fn opportunistic_resolve_lt_var(&self, vid: RegionVid) -> <Self::Interner as Interner>::Region;
|
||||
|
||||
fn defining_opaque_types(&self) -> <Self::Interner as Interner>::DefiningOpaqueTypes;
|
||||
}
|
||||
|
@ -7,11 +7,11 @@
|
||||
use std::hash::Hash;
|
||||
use std::ops::Deref;
|
||||
|
||||
use crate::fold::TypeSuperFoldable;
|
||||
use crate::fold::{TypeFoldable, TypeSuperFoldable};
|
||||
use crate::visit::{Flags, TypeSuperVisitable};
|
||||
use crate::{
|
||||
AliasTy, AliasTyKind, BoundVar, ConstKind, DebruijnIndex, DebugWithInfcx, Interner, RegionKind,
|
||||
TyKind, UnevaluatedConst, UniverseIndex,
|
||||
AliasTy, AliasTyKind, BoundVar, ConstKind, ConstVid, DebruijnIndex, DebugWithInfcx, InferConst,
|
||||
InferTy, Interner, RegionKind, TyKind, TyVid, UnevaluatedConst, UniverseIndex,
|
||||
};
|
||||
|
||||
pub trait Ty<I: Interner<Ty = Self>>:
|
||||
@ -28,6 +28,10 @@ pub trait Ty<I: Interner<Ty = Self>>:
|
||||
{
|
||||
fn new_bool(interner: I) -> Self;
|
||||
|
||||
fn new_infer(interner: I, var: InferTy) -> Self;
|
||||
|
||||
fn new_var(interner: I, var: TyVid) -> Self;
|
||||
|
||||
fn new_anon_bound(interner: I, debruijn: DebruijnIndex, var: BoundVar) -> Self;
|
||||
|
||||
fn new_alias(interner: I, kind: AliasTyKind, alias_ty: AliasTy<I>) -> Self;
|
||||
@ -68,6 +72,10 @@ pub trait Const<I: Interner<Const = Self>>:
|
||||
+ TypeSuperFoldable<I>
|
||||
+ Flags
|
||||
{
|
||||
fn new_infer(interner: I, var: InferConst, ty: I::Ty) -> Self;
|
||||
|
||||
fn new_var(interner: I, var: ConstVid, ty: I::Ty) -> Self;
|
||||
|
||||
fn new_anon_bound(interner: I, debruijn: DebruijnIndex, var: BoundVar, ty: I::Ty) -> Self;
|
||||
|
||||
fn new_unevaluated(interner: I, uv: UnevaluatedConst<I>, ty: I::Ty) -> Self;
|
||||
@ -87,6 +95,7 @@ pub trait GenericArgs<I: Interner<GenericArgs = Self>>:
|
||||
+ IntoIterator<Item = I::GenericArg>
|
||||
+ Deref<Target: Deref<Target = [I::GenericArg]>>
|
||||
+ Default
|
||||
+ TypeFoldable<I>
|
||||
{
|
||||
fn type_at(self, i: usize) -> I::Ty;
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
use crate::{
|
||||
AliasTerm, AliasTermKind, AliasTy, AliasTyKind, CanonicalVarInfo, CoercePredicate,
|
||||
DebugWithInfcx, ExistentialProjection, ExistentialTraitRef, FnSig, GenericArgKind,
|
||||
NormalizesTo, ProjectionPredicate, SubtypePredicate, TraitPredicate, TraitRef,
|
||||
NormalizesTo, ProjectionPredicate, SubtypePredicate, TermKind, TraitPredicate, TraitRef,
|
||||
};
|
||||
|
||||
pub trait Interner:
|
||||
@ -36,7 +36,7 @@ pub trait Interner:
|
||||
/// not including the args from the parent item (trait or impl).
|
||||
type OwnItemArgs: Copy + Debug + Hash + Eq;
|
||||
type GenericArg: Copy + DebugWithInfcx<Self> + Hash + Eq + IntoKind<Kind = GenericArgKind<Self>>;
|
||||
type Term: Copy + Debug + Hash + Eq;
|
||||
type Term: Copy + Debug + Hash + Eq + IntoKind<Kind = TermKind<Self>>;
|
||||
|
||||
type Binder<T: TypeVisitable<Self>>: BoundVars<Self> + TypeSuperVisitable<Self>;
|
||||
type BoundVars: IntoIterator<Item = Self::BoundVar>;
|
||||
@ -79,7 +79,6 @@ pub trait Interner:
|
||||
type EarlyParamRegion: Copy + Debug + Hash + Eq;
|
||||
type LateParamRegion: Copy + Debug + Hash + Eq;
|
||||
type BoundRegion: Copy + Debug + Hash + Eq + BoundVarLike<Self>;
|
||||
type InferRegion: Copy + DebugWithInfcx<Self> + Hash + Eq;
|
||||
type PlaceholderRegion: PlaceholderLike;
|
||||
|
||||
// Predicates
|
||||
|
@ -1,13 +1,35 @@
|
||||
#[cfg(feature = "nightly")]
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
#[cfg(feature = "nightly")]
|
||||
use rustc_macros::{TyDecodable, TyEncodable};
|
||||
use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable};
|
||||
use std::fmt;
|
||||
|
||||
use crate::{DebruijnIndex, DebugWithInfcx, InferCtxtLike, Interner, WithInfcx};
|
||||
|
||||
use self::RegionKind::*;
|
||||
|
||||
rustc_index::newtype_index! {
|
||||
/// A **region** **v**ariable **ID**.
|
||||
#[encodable]
|
||||
#[orderable]
|
||||
#[debug_format = "'?{}"]
|
||||
#[gate_rustc_only]
|
||||
#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
|
||||
pub struct RegionVid {}
|
||||
}
|
||||
|
||||
impl<I: Interner> DebugWithInfcx<I> for RegionVid {
|
||||
fn fmt<Infcx: InferCtxtLike<Interner = I>>(
|
||||
this: WithInfcx<'_, Infcx, &Self>,
|
||||
f: &mut core::fmt::Formatter<'_>,
|
||||
) -> core::fmt::Result {
|
||||
match this.infcx.universe_of_lt(*this.data) {
|
||||
Some(universe) => write!(f, "'?{}_{}", this.data.index(), universe.index()),
|
||||
None => write!(f, "{:?}", this.data),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Representation of regions. Note that the NLL checker uses a distinct
|
||||
/// representation of regions. For this reason, it internally replaces all the
|
||||
/// regions with inference variables -- the index of the variable is then used
|
||||
@ -152,7 +174,7 @@ pub enum RegionKind<I: Interner> {
|
||||
ReStatic,
|
||||
|
||||
/// A region variable. Should not exist outside of type inference.
|
||||
ReVar(I::InferRegion),
|
||||
ReVar(RegionVid),
|
||||
|
||||
/// A placeholder region -- the higher-ranked version of `ReLateParam`.
|
||||
/// Should not exist outside of type inference.
|
||||
@ -251,7 +273,6 @@ impl<CTX, I: Interner> HashStable<CTX> for RegionKind<I>
|
||||
I::EarlyParamRegion: HashStable<CTX>,
|
||||
I::BoundRegion: HashStable<CTX>,
|
||||
I::LateParamRegion: HashStable<CTX>,
|
||||
I::InferRegion: HashStable<CTX>,
|
||||
I::PlaceholderRegion: HashStable<CTX>,
|
||||
{
|
||||
#[inline]
|
||||
|
Loading…
Reference in New Issue
Block a user