Remove ReCanonical
in favor of ReLateBound
This commit is contained in:
parent
1f8de94f3b
commit
45be1ac0fc
23 changed files with 98 additions and 101 deletions
|
@ -100,9 +100,6 @@ for ty::RegionKind {
|
||||||
ty::ReEmpty => {
|
ty::ReEmpty => {
|
||||||
// No variant fields to hash for these ...
|
// No variant fields to hash for these ...
|
||||||
}
|
}
|
||||||
ty::ReCanonical(c) => {
|
|
||||||
c.hash_stable(hcx, hasher);
|
|
||||||
}
|
|
||||||
ty::ReLateBound(db, ty::BrAnon(i)) => {
|
ty::ReLateBound(db, ty::BrAnon(i)) => {
|
||||||
db.hash_stable(hcx, hasher);
|
db.hash_stable(hcx, hasher);
|
||||||
i.hash_stable(hcx, hasher);
|
i.hash_stable(hcx, hasher);
|
||||||
|
|
|
@ -331,8 +331,8 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx>
|
||||||
| ty::ReErased => self.canonicalize_region_mode
|
| ty::ReErased => self.canonicalize_region_mode
|
||||||
.canonicalize_free_region(self, r),
|
.canonicalize_free_region(self, r),
|
||||||
|
|
||||||
ty::ReClosureBound(..) | ty::ReCanonical(_) => {
|
ty::ReClosureBound(..) => {
|
||||||
bug!("canonical region encountered during canonicalization")
|
bug!("closure bound region encountered during canonicalization")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -407,12 +407,6 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
|
||||||
where
|
where
|
||||||
V: TypeFoldable<'tcx> + Lift<'gcx>,
|
V: TypeFoldable<'tcx> + Lift<'gcx>,
|
||||||
{
|
{
|
||||||
debug_assert!(
|
|
||||||
!value.has_type_flags(TypeFlags::HAS_CANONICAL_VARS),
|
|
||||||
"canonicalizing a canonical value: {:?}",
|
|
||||||
value,
|
|
||||||
);
|
|
||||||
|
|
||||||
let needs_canonical_flags = if canonicalize_region_mode.any() {
|
let needs_canonical_flags = if canonicalize_region_mode.any() {
|
||||||
TypeFlags::HAS_FREE_REGIONS | TypeFlags::KEEP_IN_LOCAL_TCX
|
TypeFlags::HAS_FREE_REGIONS | TypeFlags::KEEP_IN_LOCAL_TCX
|
||||||
} else {
|
} else {
|
||||||
|
@ -569,7 +563,11 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
|
||||||
r: ty::Region<'tcx>,
|
r: ty::Region<'tcx>,
|
||||||
) -> ty::Region<'tcx> {
|
) -> ty::Region<'tcx> {
|
||||||
let var = self.canonical_var(info, r.into());
|
let var = self.canonical_var(info, r.into());
|
||||||
self.tcx().mk_region(ty::ReCanonical(var))
|
let region = ty::ReLateBound(
|
||||||
|
self.binder_index,
|
||||||
|
ty::BoundRegion::BrAnon(var.index() as u32)
|
||||||
|
);
|
||||||
|
self.tcx().mk_region(region)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Given a type variable `ty_var` of the given kind, first check
|
/// Given a type variable `ty_var` of the given kind, first check
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
//! - a map M (of type `CanonicalVarValues`) from those canonical
|
//! - a map M (of type `CanonicalVarValues`) from those canonical
|
||||||
//! variables back to the original.
|
//! variables back to the original.
|
||||||
//!
|
//!
|
||||||
//! We can then do queries using T2. These will give back constriants
|
//! We can then do queries using T2. These will give back constraints
|
||||||
//! on the canonical variables which can be translated, using the map
|
//! on the canonical variables which can be translated, using the map
|
||||||
//! M, into constraints in our source context. This process of
|
//! M, into constraints in our source context. This process of
|
||||||
//! translating the results back is done by the
|
//! translating the results back is done by the
|
||||||
|
|
|
@ -308,11 +308,12 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
||||||
// ...also include the other query region constraints from the query.
|
// ...also include the other query region constraints from the query.
|
||||||
output_query_region_constraints.extend(
|
output_query_region_constraints.extend(
|
||||||
query_response.value.region_constraints.iter().filter_map(|r_c| {
|
query_response.value.region_constraints.iter().filter_map(|r_c| {
|
||||||
let &ty::OutlivesPredicate(k1, r2) = r_c.skip_binder(); // reconstructed below
|
let ty::OutlivesPredicate(k1, r2) = r_c.skip_binder(); // reconstructed below
|
||||||
let k1 = substitute_value(self.tcx, &result_subst, &k1);
|
let k1 = substitute_value(self.tcx, &result_subst, &ty::Binder::bind(*k1));
|
||||||
let r2 = substitute_value(self.tcx, &result_subst, &r2);
|
let r2 = substitute_value(self.tcx, &result_subst, &ty::Binder::bind(*r2));
|
||||||
if k1 != r2.into() {
|
if k1 != r2.map_bound(|bound| bound.into()) {
|
||||||
Some(ty::Binder::bind(ty::OutlivesPredicate(k1, r2)))
|
let predicate = ty::OutlivesPredicate(*k1.skip_binder(), *r2.skip_binder());
|
||||||
|
Some(ty::Binder::bind(predicate))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -433,16 +434,21 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
||||||
UnpackedKind::Type(result_value) => {
|
UnpackedKind::Type(result_value) => {
|
||||||
// e.g., here `result_value` might be `?0` in the example above...
|
// e.g., here `result_value` might be `?0` in the example above...
|
||||||
if let ty::Bound(b) = result_value.sty {
|
if let ty::Bound(b) = result_value.sty {
|
||||||
|
// ...in which case we would set `canonical_vars[0]` to `Some(?U)`.
|
||||||
|
|
||||||
|
// We only allow a `ty::INNERMOST` index in substitutions.
|
||||||
assert_eq!(b.index, ty::INNERMOST);
|
assert_eq!(b.index, ty::INNERMOST);
|
||||||
// in which case we would set `canonical_vars[0]` to `Some(?U)`.
|
|
||||||
opt_values[b.var] = Some(*original_value);
|
opt_values[b.var] = Some(*original_value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UnpackedKind::Lifetime(result_value) => {
|
UnpackedKind::Lifetime(result_value) => {
|
||||||
// e.g., here `result_value` might be `'?1` in the example above...
|
// e.g., here `result_value` might be `'?1` in the example above...
|
||||||
if let &ty::RegionKind::ReCanonical(index) = result_value {
|
if let &ty::RegionKind::ReLateBound(index, br) = result_value {
|
||||||
// in which case we would set `canonical_vars[0]` to `Some('static)`.
|
// ... in which case we would set `canonical_vars[0]` to `Some('static)`.
|
||||||
opt_values[index] = Some(*original_value);
|
|
||||||
|
// We only allow a `ty::INNERMOST` index in substitutions.
|
||||||
|
assert_eq!(index, ty::INNERMOST);
|
||||||
|
opt_values[br.as_bound_var()] = Some(*original_value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -525,21 +531,23 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
||||||
.iter()
|
.iter()
|
||||||
.map(move |constraint| {
|
.map(move |constraint| {
|
||||||
let ty::OutlivesPredicate(k1, r2) = constraint.skip_binder(); // restored below
|
let ty::OutlivesPredicate(k1, r2) = constraint.skip_binder(); // restored below
|
||||||
let k1 = substitute_value(self.tcx, result_subst, k1);
|
let k1 = substitute_value(self.tcx, result_subst, &ty::Binder::bind(*k1));
|
||||||
let r2 = substitute_value(self.tcx, result_subst, r2);
|
let r2 = substitute_value(self.tcx, result_subst, &ty::Binder::bind(*r2));
|
||||||
|
|
||||||
Obligation::new(
|
Obligation::new(
|
||||||
cause.clone(),
|
cause.clone(),
|
||||||
param_env,
|
param_env,
|
||||||
match k1.unpack() {
|
match k1.skip_binder().unpack() {
|
||||||
UnpackedKind::Lifetime(r1) => ty::Predicate::RegionOutlives(
|
UnpackedKind::Lifetime(r1) => ty::Predicate::RegionOutlives(
|
||||||
ty::Binder::dummy(
|
ty::Binder::bind(
|
||||||
ty::OutlivesPredicate(r1, r2)
|
ty::OutlivesPredicate(r1, r2.skip_binder())
|
||||||
)),
|
)
|
||||||
|
),
|
||||||
UnpackedKind::Type(t1) => ty::Predicate::TypeOutlives(
|
UnpackedKind::Type(t1) => ty::Predicate::TypeOutlives(
|
||||||
ty::Binder::dummy(ty::OutlivesPredicate(
|
ty::Binder::bind(
|
||||||
t1, r2
|
ty::OutlivesPredicate(t1, r2.skip_binder())
|
||||||
)))
|
)
|
||||||
|
),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@ -621,11 +629,11 @@ pub fn make_query_outlives<'tcx>(
|
||||||
}
|
}
|
||||||
Constraint::RegSubReg(r1, r2) => ty::OutlivesPredicate(r2.into(), r1),
|
Constraint::RegSubReg(r1, r2) => ty::OutlivesPredicate(r2.into(), r1),
|
||||||
})
|
})
|
||||||
.map(ty::Binder::dummy) // no bound regions in the code above
|
.map(ty::Binder::dummy) // no bound vars in the code above
|
||||||
.chain(
|
.chain(
|
||||||
outlives_obligations
|
outlives_obligations
|
||||||
.map(|(ty, r)| ty::OutlivesPredicate(ty.into(), r))
|
.map(|(ty, r)| ty::OutlivesPredicate(ty.into(), r))
|
||||||
.map(ty::Binder::dummy), // no bound regions in the code above
|
.map(ty::Binder::dummy) // no bound vars in the code above
|
||||||
)
|
)
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
use infer::canonical::{Canonical, CanonicalVarValues};
|
use infer::canonical::{Canonical, CanonicalVarValues};
|
||||||
use ty::fold::{TypeFoldable, TypeFolder};
|
use ty::fold::{TypeFoldable, TypeFolder};
|
||||||
use ty::subst::UnpackedKind;
|
use ty::subst::UnpackedKind;
|
||||||
use ty::{self, Ty, TyCtxt, TypeFlags};
|
use ty::{self, Ty, TyCtxt};
|
||||||
|
|
||||||
impl<'tcx, V> Canonical<'tcx, V> {
|
impl<'tcx, V> Canonical<'tcx, V> {
|
||||||
/// Instantiate the wrapped value, replacing each canonical value
|
/// Instantiate the wrapped value, replacing each canonical value
|
||||||
|
@ -64,9 +64,9 @@ where
|
||||||
T: TypeFoldable<'tcx>,
|
T: TypeFoldable<'tcx>,
|
||||||
{
|
{
|
||||||
if var_values.var_values.is_empty() {
|
if var_values.var_values.is_empty() {
|
||||||
debug_assert!(!value.has_type_flags(TypeFlags::HAS_CANONICAL_VARS));
|
|
||||||
value.clone()
|
value.clone()
|
||||||
} else if !value.has_type_flags(TypeFlags::HAS_CANONICAL_VARS) {
|
} else if !value.has_escaping_bound_vars() {
|
||||||
|
// There are no bound vars to substitute.
|
||||||
value.clone()
|
value.clone()
|
||||||
} else {
|
} else {
|
||||||
value.fold_with(&mut CanonicalVarValuesSubst {
|
value.fold_with(&mut CanonicalVarValuesSubst {
|
||||||
|
@ -104,8 +104,8 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for CanonicalVarValuesSubst<'cx, 'g
|
||||||
match self.var_values.var_values[b.var].unpack() {
|
match self.var_values.var_values[b.var].unpack() {
|
||||||
UnpackedKind::Type(ty) => ty::fold::shift_vars(
|
UnpackedKind::Type(ty) => ty::fold::shift_vars(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
self.binder_index.index() as u32,
|
&ty,
|
||||||
&ty
|
self.binder_index.index() as u32
|
||||||
),
|
),
|
||||||
r => bug!("{:?} is a type but value is {:?}", b, r),
|
r => bug!("{:?} is a type but value is {:?}", b, r),
|
||||||
}
|
}
|
||||||
|
@ -114,7 +114,8 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for CanonicalVarValuesSubst<'cx, 'g
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
if !t.has_type_flags(TypeFlags::HAS_CANONICAL_VARS) {
|
if !t.has_vars_bound_at_or_above(self.binder_index) {
|
||||||
|
// Nothing more to substitute.
|
||||||
t
|
t
|
||||||
} else {
|
} else {
|
||||||
t.super_fold_with(self)
|
t.super_fold_with(self)
|
||||||
|
@ -125,10 +126,20 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for CanonicalVarValuesSubst<'cx, 'g
|
||||||
|
|
||||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||||
match r {
|
match r {
|
||||||
ty::RegionKind::ReCanonical(c) => match self.var_values.var_values[*c].unpack() {
|
ty::RegionKind::ReLateBound(index, br) => {
|
||||||
UnpackedKind::Lifetime(l) => l,
|
if *index == self.binder_index {
|
||||||
r => bug!("{:?} is a region but value is {:?}", c, r),
|
match self.var_values.var_values[br.as_bound_var()].unpack() {
|
||||||
},
|
UnpackedKind::Lifetime(l) => ty::fold::shift_region(
|
||||||
|
self.tcx,
|
||||||
|
l,
|
||||||
|
self.binder_index.index() as u32,
|
||||||
|
),
|
||||||
|
r => bug!("{:?} is a region but value is {:?}", br, r),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
r
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => r.super_fold_with(self),
|
_ => r.super_fold_with(self),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -485,7 +485,6 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, '
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::ReCanonical(..) |
|
|
||||||
ty::ReClosureBound(..) => {
|
ty::ReClosureBound(..) => {
|
||||||
span_bug!(
|
span_bug!(
|
||||||
self.span,
|
self.span,
|
||||||
|
|
|
@ -152,7 +152,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// We shouldn't encounter an error message with ReClosureBound.
|
// We shouldn't encounter an error message with ReClosureBound.
|
||||||
ty::ReCanonical(..) | ty::ReClosureBound(..) => {
|
ty::ReClosureBound(..) => {
|
||||||
bug!("encountered unexpected ReClosureBound: {:?}", region,);
|
bug!("encountered unexpected ReClosureBound: {:?}", region,);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -114,7 +114,6 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> {
|
||||||
self.tcx().types.re_erased
|
self.tcx().types.re_erased
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::ReCanonical(..) |
|
|
||||||
ty::ReClosureBound(..) => {
|
ty::ReClosureBound(..) => {
|
||||||
bug!(
|
bug!(
|
||||||
"encountered unexpected region: {:?}",
|
"encountered unexpected region: {:?}",
|
||||||
|
|
|
@ -260,9 +260,7 @@ impl<'cx, 'gcx, 'tcx> LexicalResolver<'cx, 'gcx, 'tcx> {
|
||||||
fn lub_concrete_regions(&self, a: Region<'tcx>, b: Region<'tcx>) -> Region<'tcx> {
|
fn lub_concrete_regions(&self, a: Region<'tcx>, b: Region<'tcx>) -> Region<'tcx> {
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
match (a, b) {
|
match (a, b) {
|
||||||
(&ty::ReCanonical(..), _)
|
(&ty::ReClosureBound(..), _)
|
||||||
| (_, &ty::ReCanonical(..))
|
|
||||||
| (&ty::ReClosureBound(..), _)
|
|
||||||
| (_, &ty::ReClosureBound(..))
|
| (_, &ty::ReClosureBound(..))
|
||||||
| (&ReLateBound(..), _)
|
| (&ReLateBound(..), _)
|
||||||
| (_, &ReLateBound(..))
|
| (_, &ReLateBound(..))
|
||||||
|
|
|
@ -833,10 +833,6 @@ impl<'tcx> RegionConstraintCollector<'tcx> {
|
||||||
ty::RePlaceholder(placeholder) => placeholder.universe,
|
ty::RePlaceholder(placeholder) => placeholder.universe,
|
||||||
ty::ReClosureBound(vid) | ty::ReVar(vid) => self.var_universe(vid),
|
ty::ReClosureBound(vid) | ty::ReVar(vid) => self.var_universe(vid),
|
||||||
ty::ReLateBound(..) => bug!("universe(): encountered bound region {:?}", region),
|
ty::ReLateBound(..) => bug!("universe(): encountered bound region {:?}", region),
|
||||||
ty::ReCanonical(..) => bug!(
|
|
||||||
"region_universe(): encountered canonical region {:?}",
|
|
||||||
region
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -116,7 +116,6 @@ impl FlagComputation {
|
||||||
}
|
}
|
||||||
|
|
||||||
&ty::Bound(bound_ty) => {
|
&ty::Bound(bound_ty) => {
|
||||||
self.add_flags(TypeFlags::HAS_CANONICAL_VARS);
|
|
||||||
self.add_binder(bound_ty.index);
|
self.add_binder(bound_ty.index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,7 +126,6 @@ impl FlagComputation {
|
||||||
ty::FreshTy(_) |
|
ty::FreshTy(_) |
|
||||||
ty::FreshIntTy(_) |
|
ty::FreshIntTy(_) |
|
||||||
ty::FreshFloatTy(_) => {
|
ty::FreshFloatTy(_) => {
|
||||||
self.add_flags(TypeFlags::HAS_CANONICAL_VARS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::TyVar(_) |
|
ty::TyVar(_) |
|
||||||
|
|
|
@ -672,10 +672,14 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Shifter<'a, 'gcx, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn shift_region(region: ty::RegionKind, amount: u32) -> ty::RegionKind {
|
pub fn shift_region<'a, 'gcx, 'tcx>(
|
||||||
|
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||||
|
region: ty::Region<'tcx>,
|
||||||
|
amount: u32
|
||||||
|
) -> ty::Region<'tcx> {
|
||||||
match region {
|
match region {
|
||||||
ty::ReLateBound(debruijn, br) => {
|
ty::ReLateBound(debruijn, br) if amount > 0 => {
|
||||||
ty::ReLateBound(debruijn.shifted_in(amount), br)
|
tcx.mk_region(ty::ReLateBound(debruijn.shifted_in(amount), *br))
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
region
|
region
|
||||||
|
@ -685,8 +689,8 @@ pub fn shift_region(region: ty::RegionKind, amount: u32) -> ty::RegionKind {
|
||||||
|
|
||||||
pub fn shift_vars<'a, 'gcx, 'tcx, T>(
|
pub fn shift_vars<'a, 'gcx, 'tcx, T>(
|
||||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||||
amount: u32,
|
value: &T,
|
||||||
value: &T
|
amount: u32
|
||||||
) -> T where T: TypeFoldable<'tcx> {
|
) -> T where T: TypeFoldable<'tcx> {
|
||||||
debug!("shift_vars(value={:?}, amount={})",
|
debug!("shift_vars(value={:?}, amount={})",
|
||||||
value, amount);
|
value, amount);
|
||||||
|
|
|
@ -463,13 +463,9 @@ bitflags! {
|
||||||
// Currently we can't normalize projections w/ bound regions.
|
// Currently we can't normalize projections w/ bound regions.
|
||||||
const HAS_NORMALIZABLE_PROJECTION = 1 << 12;
|
const HAS_NORMALIZABLE_PROJECTION = 1 << 12;
|
||||||
|
|
||||||
// Set if this includes a "canonical" type or region var --
|
|
||||||
// ought to be true only for the results of canonicalization.
|
|
||||||
const HAS_CANONICAL_VARS = 1 << 13;
|
|
||||||
|
|
||||||
/// Does this have any `ReLateBound` regions? Used to check
|
/// Does this have any `ReLateBound` regions? Used to check
|
||||||
/// if a global bound is safe to evaluate.
|
/// if a global bound is safe to evaluate.
|
||||||
const HAS_RE_LATE_BOUND = 1 << 14;
|
const HAS_RE_LATE_BOUND = 1 << 13;
|
||||||
|
|
||||||
const NEEDS_SUBST = TypeFlags::HAS_PARAMS.bits |
|
const NEEDS_SUBST = TypeFlags::HAS_PARAMS.bits |
|
||||||
TypeFlags::HAS_SELF.bits |
|
TypeFlags::HAS_SELF.bits |
|
||||||
|
@ -490,7 +486,6 @@ bitflags! {
|
||||||
TypeFlags::HAS_TY_CLOSURE.bits |
|
TypeFlags::HAS_TY_CLOSURE.bits |
|
||||||
TypeFlags::HAS_FREE_LOCAL_NAMES.bits |
|
TypeFlags::HAS_FREE_LOCAL_NAMES.bits |
|
||||||
TypeFlags::KEEP_IN_LOCAL_TCX.bits |
|
TypeFlags::KEEP_IN_LOCAL_TCX.bits |
|
||||||
TypeFlags::HAS_CANONICAL_VARS.bits |
|
|
||||||
TypeFlags::HAS_RE_LATE_BOUND.bits;
|
TypeFlags::HAS_RE_LATE_BOUND.bits;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,6 +77,17 @@ impl BoundRegion {
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// When canonicalizing, we replace unbound inference variables and free
|
||||||
|
/// regions with anonymous late bound regions. This method asserts that
|
||||||
|
/// we have an anonymous late bound region, which hence may refer to
|
||||||
|
/// a canonical variable.
|
||||||
|
pub fn as_bound_var(&self) -> BoundVar {
|
||||||
|
match *self {
|
||||||
|
BoundRegion::BrAnon(var) => BoundVar::from_u32(var),
|
||||||
|
_ => bug!("bound region is not anonymous"),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// N.B., If you change this, you'll probably want to change the corresponding
|
/// N.B., If you change this, you'll probably want to change the corresponding
|
||||||
|
@ -758,11 +769,11 @@ impl<'tcx> PolyExistentialTraitRef<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Binder is a binder for higher-ranked lifetimes. It is part of the
|
/// Binder is a binder for higher-ranked lifetimes or types. It is part of the
|
||||||
/// compiler's representation for things like `for<'a> Fn(&'a isize)`
|
/// compiler's representation for things like `for<'a> Fn(&'a isize)`
|
||||||
/// (which would be represented by the type `PolyTraitRef ==
|
/// (which would be represented by the type `PolyTraitRef ==
|
||||||
/// Binder<TraitRef>`). Note that when we instantiate,
|
/// Binder<TraitRef>`). Note that when we instantiate,
|
||||||
/// erase, or otherwise "discharge" these bound regions, we change the
|
/// erase, or otherwise "discharge" these bound vars, we change the
|
||||||
/// type from `Binder<T>` to just `T` (see
|
/// type from `Binder<T>` to just `T` (see
|
||||||
/// e.g. `liberate_late_bound_regions`).
|
/// e.g. `liberate_late_bound_regions`).
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
|
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
|
||||||
|
@ -770,7 +781,7 @@ pub struct Binder<T>(T);
|
||||||
|
|
||||||
impl<T> Binder<T> {
|
impl<T> Binder<T> {
|
||||||
/// Wraps `value` in a binder, asserting that `value` does not
|
/// Wraps `value` in a binder, asserting that `value` does not
|
||||||
/// contain any bound regions that would be bound by the
|
/// contain any bound vars that would be bound by the
|
||||||
/// binder. This is commonly used to 'inject' a value T into a
|
/// binder. This is commonly used to 'inject' a value T into a
|
||||||
/// different binding level.
|
/// different binding level.
|
||||||
pub fn dummy<'tcx>(value: T) -> Binder<T>
|
pub fn dummy<'tcx>(value: T) -> Binder<T>
|
||||||
|
@ -780,9 +791,8 @@ impl<T> Binder<T> {
|
||||||
Binder(value)
|
Binder(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Wraps `value` in a binder, binding late-bound regions (if any).
|
/// Wraps `value` in a binder, binding higher-ranked vars (if any).
|
||||||
pub fn bind<'tcx>(value: T) -> Binder<T>
|
pub fn bind<'tcx>(value: T) -> Binder<T> {
|
||||||
{
|
|
||||||
Binder(value)
|
Binder(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1169,9 +1179,6 @@ pub enum RegionKind {
|
||||||
/// `ClosureRegionRequirements` that are produced by MIR borrowck.
|
/// `ClosureRegionRequirements` that are produced by MIR borrowck.
|
||||||
/// See `ClosureRegionRequirements` for more details.
|
/// See `ClosureRegionRequirements` for more details.
|
||||||
ReClosureBound(RegionVid),
|
ReClosureBound(RegionVid),
|
||||||
|
|
||||||
/// Canonicalized region, used only when preparing a trait query.
|
|
||||||
ReCanonical(BoundVar),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> serialize::UseSpecializedDecodable for Region<'tcx> {}
|
impl<'tcx> serialize::UseSpecializedDecodable for Region<'tcx> {}
|
||||||
|
@ -1381,7 +1388,6 @@ impl RegionKind {
|
||||||
RegionKind::ReEmpty => false,
|
RegionKind::ReEmpty => false,
|
||||||
RegionKind::ReErased => false,
|
RegionKind::ReErased => false,
|
||||||
RegionKind::ReClosureBound(..) => false,
|
RegionKind::ReClosureBound(..) => false,
|
||||||
RegionKind::ReCanonical(..) => false,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1468,10 +1474,6 @@ impl RegionKind {
|
||||||
}
|
}
|
||||||
ty::ReErased => {
|
ty::ReErased => {
|
||||||
}
|
}
|
||||||
ty::ReCanonical(..) => {
|
|
||||||
flags = flags | TypeFlags::HAS_FREE_REGIONS;
|
|
||||||
flags = flags | TypeFlags::HAS_CANONICAL_VARS;
|
|
||||||
}
|
|
||||||
ty::ReClosureBound(..) => {
|
ty::ReClosureBound(..) => {
|
||||||
flags = flags | TypeFlags::HAS_FREE_REGIONS;
|
flags = flags | TypeFlags::HAS_FREE_REGIONS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -475,8 +475,8 @@ impl<'a, 'gcx, 'tcx> SubstFolder<'a, 'gcx, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// It is sometimes necessary to adjust the debruijn indices during substitution. This occurs
|
/// It is sometimes necessary to adjust the debruijn indices during substitution. This occurs
|
||||||
/// when we are substituting a type with escaping regions into a context where we have passed
|
/// when we are substituting a type with escaping bound vars into a context where we have
|
||||||
/// through region binders. That's quite a mouthful. Let's see an example:
|
/// passed through binders. That's quite a mouthful. Let's see an example:
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// type Func<A> = fn(A);
|
/// type Func<A> = fn(A);
|
||||||
|
@ -524,7 +524,7 @@ impl<'a, 'gcx, 'tcx> SubstFolder<'a, 'gcx, 'tcx> {
|
||||||
return ty;
|
return ty;
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = ty::fold::shift_vars(self.tcx(), self.binders_passed, &ty);
|
let result = ty::fold::shift_vars(self.tcx(), &ty, self.binders_passed);
|
||||||
debug!("shift_vars: shifted result = {:?}", result);
|
debug!("shift_vars: shifted result = {:?}", result);
|
||||||
|
|
||||||
result
|
result
|
||||||
|
@ -534,7 +534,7 @@ impl<'a, 'gcx, 'tcx> SubstFolder<'a, 'gcx, 'tcx> {
|
||||||
if self.binders_passed == 0 || !region.has_escaping_bound_vars() {
|
if self.binders_passed == 0 || !region.has_escaping_bound_vars() {
|
||||||
return region;
|
return region;
|
||||||
}
|
}
|
||||||
self.tcx().mk_region(ty::fold::shift_region(*region, self.binders_passed))
|
ty::fold::shift_region(self.tcx, region, self.binders_passed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -556,7 +556,8 @@ impl CanonicalUserSubsts<'tcx> {
|
||||||
self.value.substs.iter().zip(BoundVar::new(0)..).all(|(kind, cvar)| {
|
self.value.substs.iter().zip(BoundVar::new(0)..).all(|(kind, cvar)| {
|
||||||
match kind.unpack() {
|
match kind.unpack() {
|
||||||
UnpackedKind::Type(ty) => match ty.sty {
|
UnpackedKind::Type(ty) => match ty.sty {
|
||||||
ty::Bound(ref b) => {
|
ty::Bound(b) => {
|
||||||
|
// We only allow a `ty::INNERMOST` index in substitutions.
|
||||||
assert_eq!(b.index, ty::INNERMOST);
|
assert_eq!(b.index, ty::INNERMOST);
|
||||||
cvar == b.var
|
cvar == b.var
|
||||||
}
|
}
|
||||||
|
@ -564,7 +565,11 @@ impl CanonicalUserSubsts<'tcx> {
|
||||||
},
|
},
|
||||||
|
|
||||||
UnpackedKind::Lifetime(r) => match r {
|
UnpackedKind::Lifetime(r) => match r {
|
||||||
ty::ReCanonical(cvar1) => cvar == *cvar1,
|
ty::ReLateBound(index, br) => {
|
||||||
|
// We only allow a `ty::INNERMOST` index in substitutions.
|
||||||
|
assert_eq!(*index, ty::INNERMOST);
|
||||||
|
cvar == br.as_bound_var()
|
||||||
|
}
|
||||||
_ => false,
|
_ => false,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -790,9 +790,6 @@ define_print! {
|
||||||
ty::ReEarlyBound(ref data) => {
|
ty::ReEarlyBound(ref data) => {
|
||||||
write!(f, "{}", data.name)
|
write!(f, "{}", data.name)
|
||||||
}
|
}
|
||||||
ty::ReCanonical(_) => {
|
|
||||||
write!(f, "'_")
|
|
||||||
}
|
|
||||||
ty::ReLateBound(_, br) |
|
ty::ReLateBound(_, br) |
|
||||||
ty::ReFree(ty::FreeRegion { bound_region: br, .. }) |
|
ty::ReFree(ty::FreeRegion { bound_region: br, .. }) |
|
||||||
ty::RePlaceholder(ty::Placeholder { name: br, .. }) => {
|
ty::RePlaceholder(ty::Placeholder { name: br, .. }) => {
|
||||||
|
@ -860,10 +857,6 @@ define_print! {
|
||||||
write!(f, "{:?}", vid)
|
write!(f, "{:?}", vid)
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::ReCanonical(c) => {
|
|
||||||
write!(f, "'?{}", c.index())
|
|
||||||
}
|
|
||||||
|
|
||||||
ty::RePlaceholder(placeholder) => {
|
ty::RePlaceholder(placeholder) => {
|
||||||
write!(f, "RePlaceholder({:?})", placeholder)
|
write!(f, "RePlaceholder({:?})", placeholder)
|
||||||
}
|
}
|
||||||
|
|
|
@ -426,7 +426,6 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
// These cannot exist in borrowck
|
// These cannot exist in borrowck
|
||||||
RegionKind::ReVar(..) |
|
RegionKind::ReVar(..) |
|
||||||
RegionKind::ReCanonical(..) |
|
|
||||||
RegionKind::RePlaceholder(..) |
|
RegionKind::RePlaceholder(..) |
|
||||||
RegionKind::ReClosureBound(..) |
|
RegionKind::ReClosureBound(..) |
|
||||||
RegionKind::ReErased => span_bug!(borrow_span,
|
RegionKind::ReErased => span_bug!(borrow_span,
|
||||||
|
|
|
@ -363,7 +363,6 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
ty::ReStatic => self.item_ub,
|
ty::ReStatic => self.item_ub,
|
||||||
|
|
||||||
ty::ReCanonical(_) |
|
|
||||||
ty::ReEmpty |
|
ty::ReEmpty |
|
||||||
ty::ReClosureBound(..) |
|
ty::ReClosureBound(..) |
|
||||||
ty::ReLateBound(..) |
|
ty::ReLateBound(..) |
|
||||||
|
|
|
@ -277,8 +277,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||||
| ty::RePlaceholder(..)
|
| ty::RePlaceholder(..)
|
||||||
| ty::ReEmpty
|
| ty::ReEmpty
|
||||||
| ty::ReErased
|
| ty::ReErased
|
||||||
| ty::ReClosureBound(..)
|
| ty::ReClosureBound(..) => None,
|
||||||
| ty::ReCanonical(..) => None,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1748,7 +1748,7 @@ impl<'a, 'gcx, 'tcx> Bounds<'tcx> {
|
||||||
self.region_bounds.iter().map(|&(region_bound, span)| {
|
self.region_bounds.iter().map(|&(region_bound, span)| {
|
||||||
// account for the binder being introduced below; no need to shift `param_ty`
|
// account for the binder being introduced below; no need to shift `param_ty`
|
||||||
// because, at present at least, it can only refer to early-bound regions
|
// because, at present at least, it can only refer to early-bound regions
|
||||||
let region_bound = tcx.mk_region(ty::fold::shift_region(*region_bound, 1));
|
let region_bound = ty::fold::shift_region(tcx, region_bound, 1);
|
||||||
let outlives = ty::OutlivesPredicate(param_ty, region_bound);
|
let outlives = ty::OutlivesPredicate(param_ty, region_bound);
|
||||||
(ty::Binder::dummy(outlives).to_predicate(), span)
|
(ty::Binder::dummy(outlives).to_predicate(), span)
|
||||||
}).chain(
|
}).chain(
|
||||||
|
|
|
@ -167,7 +167,6 @@ fn is_free_region<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, region: Region<'_>) -> bool
|
||||||
RegionKind::ReEmpty
|
RegionKind::ReEmpty
|
||||||
| RegionKind::ReErased
|
| RegionKind::ReErased
|
||||||
| RegionKind::ReClosureBound(..)
|
| RegionKind::ReClosureBound(..)
|
||||||
| RegionKind::ReCanonical(..)
|
|
||||||
| RegionKind::ReScope(..)
|
| RegionKind::ReScope(..)
|
||||||
| RegionKind::ReVar(..)
|
| RegionKind::ReVar(..)
|
||||||
| RegionKind::RePlaceholder(..)
|
| RegionKind::RePlaceholder(..)
|
||||||
|
|
|
@ -427,7 +427,6 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
||||||
// way early-bound regions do, so we skip them here.
|
// way early-bound regions do, so we skip them here.
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::ReCanonical(_) |
|
|
||||||
ty::ReFree(..) |
|
ty::ReFree(..) |
|
||||||
ty::ReClosureBound(..) |
|
ty::ReClosureBound(..) |
|
||||||
ty::ReScope(..) |
|
ty::ReScope(..) |
|
||||||
|
|
|
@ -1260,7 +1260,6 @@ impl Clean<Option<Lifetime>> for ty::RegionKind {
|
||||||
ty::RePlaceholder(..) |
|
ty::RePlaceholder(..) |
|
||||||
ty::ReEmpty |
|
ty::ReEmpty |
|
||||||
ty::ReClosureBound(_) |
|
ty::ReClosureBound(_) |
|
||||||
ty::ReCanonical(_) |
|
|
||||||
ty::ReErased => None
|
ty::ReErased => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue