mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
Shift both late bound regions and bound types
This commit is contained in:
parent
1003b7f85e
commit
d0447550da
@ -305,7 +305,7 @@ where
|
||||
ty, region, origin
|
||||
);
|
||||
|
||||
assert!(!ty.has_escaping_regions());
|
||||
assert!(!ty.has_escaping_bound_vars());
|
||||
|
||||
let components = self.tcx.outlives_components(ty);
|
||||
self.components_must_outlive(origin, components, region);
|
||||
|
@ -84,8 +84,8 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
|
||||
// Shouldn't have any LBR here, so we can safely put
|
||||
// this under a binder below without fear of accidental
|
||||
// capture.
|
||||
assert!(!a.has_escaping_regions());
|
||||
assert!(!b.has_escaping_regions());
|
||||
assert!(!a.has_escaping_bound_vars());
|
||||
assert!(!b.has_escaping_bound_vars());
|
||||
|
||||
// can't make progress on `A <: B` if both A and B are
|
||||
// type variables, so record an obligation. We also
|
||||
|
@ -143,7 +143,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> {
|
||||
debug!("normalize_projection_type(projection_ty={:?})",
|
||||
projection_ty);
|
||||
|
||||
debug_assert!(!projection_ty.has_escaping_regions());
|
||||
debug_assert!(!projection_ty.has_escaping_bound_vars());
|
||||
|
||||
// FIXME(#20304) -- cache
|
||||
|
||||
|
@ -366,7 +366,7 @@ impl<'a, 'b, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for AssociatedTypeNormalizer<'a,
|
||||
|
||||
let ty = ty.super_fold_with(self);
|
||||
match ty.sty {
|
||||
ty::Opaque(def_id, substs) if !substs.has_escaping_regions() => { // (*)
|
||||
ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => { // (*)
|
||||
// Only normalize `impl Trait` after type-checking, usually in codegen.
|
||||
match self.param_env.reveal {
|
||||
Reveal::UserFacing => ty,
|
||||
@ -393,7 +393,7 @@ impl<'a, 'b, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for AssociatedTypeNormalizer<'a,
|
||||
}
|
||||
}
|
||||
|
||||
ty::Projection(ref data) if !data.has_escaping_regions() => { // (*)
|
||||
ty::Projection(ref data) if !data.has_escaping_bound_vars() => { // (*)
|
||||
|
||||
// (*) This is kind of hacky -- we need to be able to
|
||||
// handle normalization within binders because
|
||||
|
@ -100,7 +100,7 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for QueryNormalizer<'cx, 'gcx, 'tcx
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
let ty = ty.super_fold_with(self);
|
||||
match ty.sty {
|
||||
ty::Opaque(def_id, substs) if !substs.has_escaping_regions() => {
|
||||
ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => {
|
||||
// (*)
|
||||
// Only normalize `impl Trait` after type-checking, usually in codegen.
|
||||
match self.param_env.reveal {
|
||||
@ -138,7 +138,7 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for QueryNormalizer<'cx, 'gcx, 'tcx
|
||||
}
|
||||
}
|
||||
|
||||
ty::Projection(ref data) if !data.has_escaping_regions() => {
|
||||
ty::Projection(ref data) if !data.has_escaping_bound_vars() => {
|
||||
// (*)
|
||||
// (*) This is kind of hacky -- we need to be able to
|
||||
// handle normalization within binders because
|
||||
|
@ -587,7 +587,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||
obligation: &TraitObligation<'tcx>,
|
||||
) -> SelectionResult<'tcx, Selection<'tcx>> {
|
||||
debug!("select({:?})", obligation);
|
||||
debug_assert!(!obligation.predicate.has_escaping_regions());
|
||||
debug_assert!(!obligation.predicate.has_escaping_bound_vars());
|
||||
|
||||
let stack = self.push_stack(TraitObligationStackList::empty(), obligation);
|
||||
|
||||
@ -690,7 +690,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||
|
||||
match obligation.predicate {
|
||||
ty::Predicate::Trait(ref t) => {
|
||||
debug_assert!(!t.has_escaping_regions());
|
||||
debug_assert!(!t.has_escaping_bound_vars());
|
||||
let obligation = obligation.with(t.clone());
|
||||
self.evaluate_trait_predicate_recursively(previous_stack, obligation)
|
||||
}
|
||||
@ -722,9 +722,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||
},
|
||||
|
||||
ty::Predicate::TypeOutlives(ref binder) => {
|
||||
assert!(!binder.has_escaping_regions());
|
||||
// Check if the type has higher-ranked regions.
|
||||
if binder.skip_binder().0.has_escaping_regions() {
|
||||
assert!(!binder.has_escaping_bound_vars());
|
||||
// Check if the type has higher-ranked vars.
|
||||
if binder.skip_binder().0.has_escaping_bound_vars() {
|
||||
// If so, this obligation is an error (for now). Eventually we should be
|
||||
// able to support additional cases here, like `for<'a> &'a str: 'a`.
|
||||
|
||||
@ -740,7 +740,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||
Ok(EvaluatedToErr)
|
||||
}
|
||||
} else {
|
||||
// If the type has no late bound regions, then if we assign all
|
||||
// If the type has no late bound vars, then if we assign all
|
||||
// the inference variables in it to be 'static, then the type
|
||||
// will be 'static itself.
|
||||
//
|
||||
@ -1199,7 +1199,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||
"candidate_from_obligation(cache_fresh_trait_pred={:?}, obligation={:?})",
|
||||
cache_fresh_trait_pred, stack
|
||||
);
|
||||
debug_assert!(!stack.obligation.predicate.has_escaping_regions());
|
||||
debug_assert!(!stack.obligation.predicate.has_escaping_bound_vars());
|
||||
|
||||
if let Some(c) =
|
||||
self.check_candidate_cache(stack.obligation.param_env, &cache_fresh_trait_pred)
|
||||
@ -1801,7 +1801,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||
placeholder_map: &infer::PlaceholderMap<'tcx>,
|
||||
snapshot: &infer::CombinedSnapshot<'cx, 'tcx>,
|
||||
) -> bool {
|
||||
debug_assert!(!skol_trait_ref.has_escaping_regions());
|
||||
debug_assert!(!skol_trait_ref.has_escaping_bound_vars());
|
||||
if self.infcx
|
||||
.at(&obligation.cause, obligation.param_env)
|
||||
.sup(ty::Binder::dummy(skol_trait_ref), trait_bound)
|
||||
|
@ -115,7 +115,10 @@ impl FlagComputation {
|
||||
self.add_substs(&substs.substs);
|
||||
}
|
||||
|
||||
&ty::Bound(_) => self.add_flags(TypeFlags::HAS_CANONICAL_VARS),
|
||||
&ty::Bound(bound_ty) => {
|
||||
self.add_flags(TypeFlags::HAS_CANONICAL_VARS);
|
||||
self.add_binder(bound_ty.level);
|
||||
}
|
||||
|
||||
&ty::Infer(infer) => {
|
||||
self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES); // it might, right?
|
||||
@ -142,7 +145,7 @@ impl FlagComputation {
|
||||
&ty::Projection(ref data) => {
|
||||
// currently we can't normalize projections that
|
||||
// include bound regions, so track those separately.
|
||||
if !data.has_escaping_regions() {
|
||||
if !data.has_escaping_bound_vars() {
|
||||
self.add_flags(TypeFlags::HAS_NORMALIZABLE_PROJECTION);
|
||||
}
|
||||
self.add_flags(TypeFlags::HAS_PROJECTION);
|
||||
|
@ -67,18 +67,18 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
|
||||
/// bound by `binder` or bound by some binder outside of `binder`.
|
||||
/// If `binder` is `ty::INNERMOST`, this indicates whether
|
||||
/// there are any late-bound regions that appear free.
|
||||
fn has_regions_bound_at_or_above(&self, binder: ty::DebruijnIndex) -> bool {
|
||||
self.visit_with(&mut HasEscapingRegionsVisitor { outer_index: binder })
|
||||
fn has_vars_bound_at_or_above(&self, binder: ty::DebruijnIndex) -> bool {
|
||||
self.visit_with(&mut HasEscapingVarsVisitor { outer_index: binder })
|
||||
}
|
||||
|
||||
/// True if this `self` has any regions that escape `binder` (and
|
||||
/// hence are not bound by it).
|
||||
fn has_regions_bound_above(&self, binder: ty::DebruijnIndex) -> bool {
|
||||
self.has_regions_bound_at_or_above(binder.shifted_in(1))
|
||||
fn has_vars_bound_above(&self, binder: ty::DebruijnIndex) -> bool {
|
||||
self.has_vars_bound_at_or_above(binder.shifted_in(1))
|
||||
}
|
||||
|
||||
fn has_escaping_regions(&self) -> bool {
|
||||
self.has_regions_bound_at_or_above(ty::INNERMOST)
|
||||
fn has_escaping_bound_vars(&self) -> bool {
|
||||
self.has_vars_bound_at_or_above(ty::INNERMOST)
|
||||
}
|
||||
|
||||
fn has_type_flags(&self, flags: TypeFlags) -> bool {
|
||||
@ -574,7 +574,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for RegionReplacer<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||
if !t.has_regions_bound_at_or_above(self.current_index) {
|
||||
if !t.has_vars_bound_at_or_above(self.current_index) {
|
||||
return t;
|
||||
}
|
||||
|
||||
@ -603,14 +603,75 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for RegionReplacer<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Region shifter
|
||||
// Shifter
|
||||
//
|
||||
// Shifts the De Bruijn indices on all escaping bound regions by a
|
||||
// Shifts the De Bruijn indices on all escaping bound vars by a
|
||||
// fixed amount. Useful in substitution or when otherwise introducing
|
||||
// a binding level that is not intended to capture the existing bound
|
||||
// regions. See comment on `shift_regions_through_binders` method in
|
||||
// vars. See comment on `shift_vars_through_binders` method in
|
||||
// `subst.rs` for more details.
|
||||
|
||||
struct Shifter<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
|
||||
current_index: ty::DebruijnIndex,
|
||||
amount: u32,
|
||||
}
|
||||
|
||||
impl Shifter<'a, 'gcx, 'tcx> {
|
||||
pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>, amount: u32) -> Self {
|
||||
Shifter {
|
||||
tcx,
|
||||
current_index: ty::INNERMOST,
|
||||
amount,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Shifter<'a, 'gcx, 'tcx> {
|
||||
fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> { self.tcx }
|
||||
|
||||
fn fold_binder<T: TypeFoldable<'tcx>>(&mut self, t: &ty::Binder<T>) -> ty::Binder<T> {
|
||||
self.current_index.shift_in(1);
|
||||
let t = t.super_fold_with(self);
|
||||
self.current_index.shift_out(1);
|
||||
t
|
||||
}
|
||||
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
match *r {
|
||||
ty::ReLateBound(debruijn, br) => {
|
||||
if self.amount == 0 || debruijn < self.current_index {
|
||||
r
|
||||
} else {
|
||||
let shifted = ty::ReLateBound(debruijn.shifted_in(self.amount), br);
|
||||
self.tcx.mk_region(shifted)
|
||||
}
|
||||
}
|
||||
_ => r
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, ty: ty::Ty<'tcx>) -> ty::Ty<'tcx> {
|
||||
match ty.sty {
|
||||
ty::Bound(bound_ty) => {
|
||||
if self.amount == 0 || bound_ty.level < self.current_index {
|
||||
ty
|
||||
} else {
|
||||
let shifted = ty::BoundTy {
|
||||
level: bound_ty.level.shifted_in(self.amount),
|
||||
var: bound_ty.var,
|
||||
kind: bound_ty.kind,
|
||||
};
|
||||
self.tcx.mk_ty(ty::Bound(shifted))
|
||||
}
|
||||
}
|
||||
|
||||
_ => ty.super_fold_with(self),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn shift_region(region: ty::RegionKind, amount: u32) -> ty::RegionKind {
|
||||
match region {
|
||||
ty::ReLateBound(debruijn, br) => {
|
||||
@ -622,36 +683,19 @@ pub fn shift_region(region: ty::RegionKind, amount: u32) -> ty::RegionKind {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn shift_region_ref<'a, 'gcx, 'tcx>(
|
||||
pub fn shift_vars<'a, 'gcx, 'tcx, T>(
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
region: ty::Region<'tcx>,
|
||||
amount: u32)
|
||||
-> ty::Region<'tcx>
|
||||
{
|
||||
match region {
|
||||
&ty::ReLateBound(debruijn, br) if amount > 0 => {
|
||||
tcx.mk_region(ty::ReLateBound(debruijn.shifted_in(amount), br))
|
||||
}
|
||||
_ => {
|
||||
region
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn shift_regions<'a, 'gcx, 'tcx, T>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
amount: u32,
|
||||
value: &T) -> T
|
||||
where T: TypeFoldable<'tcx>
|
||||
{
|
||||
debug!("shift_regions(value={:?}, amount={})",
|
||||
amount: u32,
|
||||
value: &T
|
||||
) -> T where T: TypeFoldable<'tcx> {
|
||||
debug!("shift_vars(value={:?}, amount={})",
|
||||
value, amount);
|
||||
|
||||
value.fold_with(&mut RegionFolder::new(tcx, &mut false, &mut |region, _current_depth| {
|
||||
shift_region_ref(tcx, region, amount)
|
||||
}))
|
||||
value.fold_with(&mut Shifter::new(tcx, amount))
|
||||
}
|
||||
|
||||
/// An "escaping region" is a bound region whose binder is not part of `t`.
|
||||
/// An "escaping var" is a bound var whose binder is not part of `t`. A bound var can be a
|
||||
/// bound region or a bound type.
|
||||
///
|
||||
/// So, for example, consider a type like the following, which has two binders:
|
||||
///
|
||||
@ -663,24 +707,24 @@ pub fn shift_regions<'a, 'gcx, 'tcx, T>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
/// binders of both `'a` and `'b` are part of the type itself. However, if we consider the *inner
|
||||
/// fn type*, that type has an escaping region: `'a`.
|
||||
///
|
||||
/// Note that what I'm calling an "escaping region" is often just called a "free region". However,
|
||||
/// we already use the term "free region". It refers to the regions that we use to represent bound
|
||||
/// regions on a fn definition while we are typechecking its body.
|
||||
/// Note that what I'm calling an "escaping var" is often just called a "free var". However,
|
||||
/// we already use the term "free var". It refers to the regions or types that we use to represent
|
||||
/// bound regions or type params on a fn definition while we are typechecking its body.
|
||||
///
|
||||
/// To clarify, conceptually there is no particular difference between
|
||||
/// an "escaping" region and a "free" region. However, there is a big
|
||||
/// an "escaping" var and a "free" var. However, there is a big
|
||||
/// difference in practice. Basically, when "entering" a binding
|
||||
/// level, one is generally required to do some sort of processing to
|
||||
/// a bound region, such as replacing it with a fresh/placeholder
|
||||
/// region, or making an entry in the environment to represent the
|
||||
/// scope to which it is attached, etc. An escaping region represents
|
||||
/// a bound region for which this processing has not yet been done.
|
||||
struct HasEscapingRegionsVisitor {
|
||||
/// a bound var, such as replacing it with a fresh/placeholder
|
||||
/// var, or making an entry in the environment to represent the
|
||||
/// scope to which it is attached, etc. An escaping var represents
|
||||
/// a bound var for which this processing has not yet been done.
|
||||
struct HasEscapingVarsVisitor {
|
||||
/// Anything bound by `outer_index` or "above" is escaping
|
||||
outer_index: ty::DebruijnIndex,
|
||||
}
|
||||
|
||||
impl<'tcx> TypeVisitor<'tcx> for HasEscapingRegionsVisitor {
|
||||
impl<'tcx> TypeVisitor<'tcx> for HasEscapingVarsVisitor {
|
||||
fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, t: &Binder<T>) -> bool {
|
||||
self.outer_index.shift_in(1);
|
||||
let result = t.super_visit_with(self);
|
||||
@ -693,7 +737,7 @@ impl<'tcx> TypeVisitor<'tcx> for HasEscapingRegionsVisitor {
|
||||
// `outer_index`, that means that `t` contains some content
|
||||
// bound at `outer_index` or above (because
|
||||
// `outer_exclusive_binder` is always 1 higher than the
|
||||
// content in `t`). Therefore, `t` has some escaping regions.
|
||||
// content in `t`). Therefore, `t` has some escaping vars.
|
||||
t.outer_exclusive_binder > self.outer_index
|
||||
}
|
||||
|
||||
|
@ -213,7 +213,7 @@ impl<'tcx> fmt::Display for Instance<'tcx> {
|
||||
impl<'a, 'b, 'tcx> Instance<'tcx> {
|
||||
pub fn new(def_id: DefId, substs: &'tcx Substs<'tcx>)
|
||||
-> Instance<'tcx> {
|
||||
assert!(!substs.has_escaping_regions(),
|
||||
assert!(!substs.has_escaping_bound_vars(),
|
||||
"substs of instance {:?} not normalized for codegen: {:?}",
|
||||
def_id, substs);
|
||||
Instance { def: InstanceDef::Item(def_id), substs: substs }
|
||||
|
@ -106,7 +106,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
// we simply fallback to the most restrictive rule, which
|
||||
// requires that `Pi: 'a` for all `i`.
|
||||
ty::Projection(ref data) => {
|
||||
if !data.has_escaping_regions() {
|
||||
if !data.has_escaping_bound_vars() {
|
||||
// best case: no escaping regions, so push the
|
||||
// projection and skip the subtree (thus generating no
|
||||
// constraints for Pi). This defers the choice between
|
||||
|
@ -730,8 +730,8 @@ impl<'a, 'gcx, 'tcx> ExistentialTraitRef<'tcx> {
|
||||
/// or some placeholder type.
|
||||
pub fn with_self_ty(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, self_ty: Ty<'tcx>)
|
||||
-> ty::TraitRef<'tcx> {
|
||||
// otherwise the escaping regions would be captured by the binder
|
||||
// debug_assert!(!self_ty.has_escaping_regions());
|
||||
// otherwise the escaping vars would be captured by the binder
|
||||
// debug_assert!(!self_ty.has_escaping_bound_vars());
|
||||
|
||||
ty::TraitRef {
|
||||
def_id: self.def_id,
|
||||
@ -776,7 +776,7 @@ impl<T> Binder<T> {
|
||||
pub fn dummy<'tcx>(value: T) -> Binder<T>
|
||||
where T: TypeFoldable<'tcx>
|
||||
{
|
||||
debug_assert!(!value.has_escaping_regions());
|
||||
debug_assert!(!value.has_escaping_bound_vars());
|
||||
Binder(value)
|
||||
}
|
||||
|
||||
@ -835,7 +835,7 @@ impl<T> Binder<T> {
|
||||
pub fn no_late_bound_regions<'tcx>(self) -> Option<T>
|
||||
where T : TypeFoldable<'tcx>
|
||||
{
|
||||
if self.skip_binder().has_escaping_regions() {
|
||||
if self.skip_binder().has_escaping_bound_vars() {
|
||||
None
|
||||
} else {
|
||||
Some(self.skip_binder().clone())
|
||||
@ -1246,7 +1246,6 @@ impl_stable_hash_for!(enum self::BoundTyKind { Anon, Param(a) });
|
||||
|
||||
impl BoundTy {
|
||||
pub fn new(level: DebruijnIndex, var: BoundTyIndex) -> Self {
|
||||
debug_assert_eq!(ty::INNERMOST, level);
|
||||
BoundTy {
|
||||
level,
|
||||
var,
|
||||
@ -1283,7 +1282,7 @@ impl<'a, 'tcx, 'gcx> ExistentialProjection<'tcx> {
|
||||
-> ty::ProjectionPredicate<'tcx>
|
||||
{
|
||||
// otherwise the escaping regions would be captured by the binders
|
||||
debug_assert!(!self_ty.has_escaping_regions());
|
||||
debug_assert!(!self_ty.has_escaping_bound_vars());
|
||||
|
||||
ty::ProjectionPredicate {
|
||||
projection_ty: ty::ProjectionTy {
|
||||
|
@ -355,7 +355,7 @@ impl<'tcx, T:TypeFoldable<'tcx>> Subst<'tcx> for T {
|
||||
span,
|
||||
root_ty: None,
|
||||
ty_stack_depth: 0,
|
||||
region_binders_passed: 0 };
|
||||
binders_passed: 0 };
|
||||
(*self).fold_with(&mut folder)
|
||||
}
|
||||
}
|
||||
@ -377,16 +377,16 @@ struct SubstFolder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
||||
ty_stack_depth: usize,
|
||||
|
||||
// Number of region binders we have passed through while doing the substitution
|
||||
region_binders_passed: u32,
|
||||
binders_passed: u32,
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for SubstFolder<'a, 'gcx, 'tcx> {
|
||||
fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> { self.tcx }
|
||||
|
||||
fn fold_binder<T: TypeFoldable<'tcx>>(&mut self, t: &ty::Binder<T>) -> ty::Binder<T> {
|
||||
self.region_binders_passed += 1;
|
||||
self.binders_passed += 1;
|
||||
let t = t.super_fold_with(self);
|
||||
self.region_binders_passed -= 1;
|
||||
self.binders_passed -= 1;
|
||||
t
|
||||
}
|
||||
|
||||
@ -471,7 +471,7 @@ impl<'a, 'gcx, 'tcx> SubstFolder<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
};
|
||||
|
||||
self.shift_regions_through_binders(ty)
|
||||
self.shift_vars_through_binders(ty)
|
||||
}
|
||||
|
||||
/// It is sometimes necessary to adjust the debruijn indices during substitution. This occurs
|
||||
@ -516,25 +516,25 @@ impl<'a, 'gcx, 'tcx> SubstFolder<'a, 'gcx, 'tcx> {
|
||||
/// As indicated in the diagram, here the same type `&'a int` is substituted once, but in the
|
||||
/// first case we do not increase the Debruijn index and in the second case we do. The reason
|
||||
/// is that only in the second case have we passed through a fn binder.
|
||||
fn shift_regions_through_binders(&self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
debug!("shift_regions(ty={:?}, region_binders_passed={:?}, has_escaping_regions={:?})",
|
||||
ty, self.region_binders_passed, ty.has_escaping_regions());
|
||||
fn shift_vars_through_binders(&self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
debug!("shift_vars(ty={:?}, binders_passed={:?}, has_escaping_bound_vars={:?})",
|
||||
ty, self.binders_passed, ty.has_escaping_bound_vars());
|
||||
|
||||
if self.region_binders_passed == 0 || !ty.has_escaping_regions() {
|
||||
if self.binders_passed == 0 || !ty.has_escaping_bound_vars() {
|
||||
return ty;
|
||||
}
|
||||
|
||||
let result = ty::fold::shift_regions(self.tcx(), self.region_binders_passed, &ty);
|
||||
debug!("shift_regions: shifted result = {:?}", result);
|
||||
let result = ty::fold::shift_vars(self.tcx(), self.binders_passed, &ty);
|
||||
debug!("shift_vars: shifted result = {:?}", result);
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
fn shift_region_through_binders(&self, region: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
if self.region_binders_passed == 0 || !region.has_escaping_regions() {
|
||||
if self.binders_passed == 0 || !region.has_escaping_bound_vars() {
|
||||
return region;
|
||||
}
|
||||
self.tcx().mk_region(ty::fold::shift_region(*region, self.region_binders_passed))
|
||||
self.tcx().mk_region(ty::fold::shift_region(*region, self.binders_passed))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -363,7 +363,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
erased_self_ty,
|
||||
predicates);
|
||||
|
||||
assert!(!erased_self_ty.has_escaping_regions());
|
||||
assert!(!erased_self_ty.has_escaping_bound_vars());
|
||||
|
||||
traits::elaborate_predicates(self, predicates)
|
||||
.filter_map(|predicate| {
|
||||
@ -389,7 +389,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
// construct such an object, but this seems
|
||||
// correct even if that code changes).
|
||||
let ty::OutlivesPredicate(ref t, ref r) = predicate.skip_binder();
|
||||
if t == &erased_self_ty && !r.has_escaping_regions() {
|
||||
if t == &erased_self_ty && !r.has_escaping_bound_vars() {
|
||||
Some(*r)
|
||||
} else {
|
||||
None
|
||||
|
@ -158,7 +158,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
|
||||
let infcx = &mut self.infcx;
|
||||
let param_env = self.param_env;
|
||||
self.out.iter()
|
||||
.inspect(|pred| assert!(!pred.has_escaping_regions()))
|
||||
.inspect(|pred| assert!(!pred.has_escaping_bound_vars()))
|
||||
.flat_map(|pred| {
|
||||
let mut selcx = traits::SelectionContext::new(infcx);
|
||||
let pred = traits::normalize(&mut selcx, param_env, cause.clone(), pred);
|
||||
@ -190,7 +190,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
|
||||
|
||||
self.out.extend(
|
||||
trait_ref.substs.types()
|
||||
.filter(|ty| !ty.has_escaping_regions())
|
||||
.filter(|ty| !ty.has_escaping_bound_vars())
|
||||
.map(|ty| traits::Obligation::new(cause.clone(),
|
||||
param_env,
|
||||
ty::Predicate::WellFormed(ty))));
|
||||
@ -205,7 +205,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
|
||||
let trait_ref = data.trait_ref(self.infcx.tcx);
|
||||
self.compute_trait_ref(&trait_ref, Elaborate::None);
|
||||
|
||||
if !data.has_escaping_regions() {
|
||||
if !data.has_escaping_bound_vars() {
|
||||
let predicate = trait_ref.to_predicate();
|
||||
let cause = self.cause(traits::ProjectionWf(data));
|
||||
self.out.push(traits::Obligation::new(cause, self.param_env, predicate));
|
||||
@ -229,7 +229,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
fn require_sized(&mut self, subty: Ty<'tcx>, cause: traits::ObligationCauseCode<'tcx>) {
|
||||
if !subty.has_escaping_regions() {
|
||||
if !subty.has_escaping_bound_vars() {
|
||||
let cause = self.cause(cause);
|
||||
let trait_ref = ty::TraitRef {
|
||||
def_id: self.infcx.tcx.require_lang_item(lang_items::SizedTraitLangItem),
|
||||
@ -300,7 +300,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
|
||||
|
||||
ty::Ref(r, rty, _) => {
|
||||
// WfReference
|
||||
if !r.has_escaping_regions() && !rty.has_escaping_regions() {
|
||||
if !r.has_escaping_bound_vars() && !rty.has_escaping_bound_vars() {
|
||||
let cause = self.cause(traits::ReferenceOutlivesReferent(ty));
|
||||
self.out.push(
|
||||
traits::Obligation::new(
|
||||
@ -451,7 +451,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
|
||||
.map(|pred| traits::Obligation::new(cause.clone(),
|
||||
self.param_env,
|
||||
pred))
|
||||
.filter(|pred| !pred.has_escaping_regions())
|
||||
.filter(|pred| !pred.has_escaping_bound_vars())
|
||||
.collect()
|
||||
}
|
||||
|
||||
@ -490,7 +490,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
|
||||
// Note: in fact we only permit builtin traits, not `Bar<'d>`, I
|
||||
// am looking forward to the future here.
|
||||
|
||||
if !data.has_escaping_regions() {
|
||||
if !data.has_escaping_bound_vars() {
|
||||
let implicit_bounds =
|
||||
object_region_bounds(self.infcx.tcx, data);
|
||||
|
||||
|
@ -44,7 +44,7 @@ pub fn get_fn(
|
||||
debug!("get_fn(instance={:?})", instance);
|
||||
|
||||
assert!(!instance.substs.needs_infer());
|
||||
assert!(!instance.substs.has_escaping_regions());
|
||||
assert!(!instance.substs.has_escaping_bound_vars());
|
||||
assert!(!instance.substs.has_param_types());
|
||||
|
||||
let sig = instance.fn_sig(cx.tcx);
|
||||
|
@ -285,7 +285,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> {
|
||||
|
||||
debug!("llvm_type({:#?})", self);
|
||||
|
||||
assert!(!self.ty.has_escaping_regions(), "{:?} has escaping regions", self.ty);
|
||||
assert!(!self.ty.has_escaping_bound_vars(), "{:?} has escaping bound vars", self.ty);
|
||||
|
||||
// Make sure lifetimes are erased, to avoid generating distinct LLVM
|
||||
// types for Rust types that only differ in the choice of lifetimes.
|
||||
|
@ -616,22 +616,22 @@ fn escaping() {
|
||||
// Theta = [A -> &'a foo]
|
||||
env.create_simple_region_hierarchy();
|
||||
|
||||
assert!(!env.t_nil().has_escaping_regions());
|
||||
assert!(!env.t_nil().has_escaping_bound_vars());
|
||||
|
||||
let t_rptr_free1 = env.t_rptr_free(1);
|
||||
assert!(!t_rptr_free1.has_escaping_regions());
|
||||
assert!(!t_rptr_free1.has_escaping_bound_vars());
|
||||
|
||||
let t_rptr_bound1 = env.t_rptr_late_bound_with_debruijn(1, d1());
|
||||
assert!(t_rptr_bound1.has_escaping_regions());
|
||||
assert!(t_rptr_bound1.has_escaping_bound_vars());
|
||||
|
||||
let t_rptr_bound2 = env.t_rptr_late_bound_with_debruijn(1, d2());
|
||||
assert!(t_rptr_bound2.has_escaping_regions());
|
||||
assert!(t_rptr_bound2.has_escaping_bound_vars());
|
||||
|
||||
// t_fn = fn(A)
|
||||
let t_param = env.t_param(0);
|
||||
assert!(!t_param.has_escaping_regions());
|
||||
assert!(!t_param.has_escaping_bound_vars());
|
||||
let t_fn = env.t_fn(&[t_param], env.t_nil());
|
||||
assert!(!t_fn.has_escaping_regions());
|
||||
assert!(!t_fn.has_escaping_bound_vars());
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -359,7 +359,7 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
fn sanitize_type(&mut self, parent: &dyn fmt::Debug, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
if ty.has_escaping_regions() || ty.references_error() {
|
||||
if ty.has_escaping_bound_vars() || ty.references_error() {
|
||||
span_mirbug_and_err!(self, parent, "bad type {:?}", ty)
|
||||
} else {
|
||||
ty
|
||||
|
@ -905,12 +905,12 @@ fn create_mono_items_for_vtable_methods<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
trait_ty: Ty<'tcx>,
|
||||
impl_ty: Ty<'tcx>,
|
||||
output: &mut Vec<MonoItem<'tcx>>) {
|
||||
assert!(!trait_ty.needs_subst() && !trait_ty.has_escaping_regions() &&
|
||||
!impl_ty.needs_subst() && !impl_ty.has_escaping_regions());
|
||||
assert!(!trait_ty.needs_subst() && !trait_ty.has_escaping_bound_vars() &&
|
||||
!impl_ty.needs_subst() && !impl_ty.has_escaping_bound_vars());
|
||||
|
||||
if let ty::Dynamic(ref trait_ty, ..) = trait_ty.sty {
|
||||
let poly_trait_ref = trait_ty.principal().with_self_ty(tcx, impl_ty);
|
||||
assert!(!poly_trait_ref.has_escaping_regions());
|
||||
assert!(!poly_trait_ref.has_escaping_bound_vars());
|
||||
|
||||
// Walk all methods of the trait, including those of its supertraits
|
||||
let methods = tcx.vtable_methods(poly_trait_ref);
|
||||
|
@ -108,7 +108,7 @@ fn compute_implied_outlives_bounds<'tcx>(
|
||||
// From the full set of obligations, just filter down to the
|
||||
// region relationships.
|
||||
implied_bounds.extend(obligations.into_iter().flat_map(|obligation| {
|
||||
assert!(!obligation.has_escaping_regions());
|
||||
assert!(!obligation.has_escaping_bound_vars());
|
||||
match obligation.predicate {
|
||||
ty::Predicate::Trait(..) |
|
||||
ty::Predicate::Subtype(..) |
|
||||
|
@ -460,7 +460,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
// Create a `PolyFnSig`. Note the oddity that late bound
|
||||
// regions appearing free in `expected_sig` are now bound up
|
||||
// in this binder we are creating.
|
||||
assert!(!expected_sig.sig.has_regions_bound_above(ty::INNERMOST));
|
||||
assert!(!expected_sig.sig.has_vars_bound_above(ty::INNERMOST));
|
||||
let bound_sig = ty::Binder::bind(self.tcx.mk_fn_sig(
|
||||
expected_sig.sig.inputs().iter().cloned(),
|
||||
expected_sig.sig.output(),
|
||||
|
@ -331,7 +331,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
value
|
||||
}
|
||||
};
|
||||
assert!(!bounds.has_escaping_regions());
|
||||
assert!(!bounds.has_escaping_bound_vars());
|
||||
|
||||
let cause = traits::ObligationCause::misc(span, self.body_id);
|
||||
obligations.extend(traits::predicates_for_generics(cause.clone(),
|
||||
|
@ -1374,7 +1374,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
|
||||
fn_sig,
|
||||
substs);
|
||||
|
||||
assert!(!substs.has_escaping_regions());
|
||||
assert!(!substs.has_escaping_bound_vars());
|
||||
|
||||
// It is possible for type parameters or early-bound lifetimes
|
||||
// to appear in the signature of `self`. The substitutions we
|
||||
|
@ -653,8 +653,8 @@ impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> {
|
||||
|
||||
fn register_predicate(&self, obligation: traits::PredicateObligation<'tcx>) {
|
||||
debug!("register_predicate({:?})", obligation);
|
||||
if obligation.has_escaping_regions() {
|
||||
span_bug!(obligation.cause.span, "escaping regions in predicate {:?}",
|
||||
if obligation.has_escaping_bound_vars() {
|
||||
span_bug!(obligation.cause.span, "escaping bound vars in predicate {:?}",
|
||||
obligation);
|
||||
}
|
||||
self.fulfillment_cx
|
||||
@ -1928,7 +1928,7 @@ impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
|
||||
fn normalize_ty(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
if ty.has_escaping_regions() {
|
||||
if ty.has_escaping_bound_vars() {
|
||||
ty // FIXME: normalization and escaping regions
|
||||
} else {
|
||||
self.normalize_associated_types_in(span, &ty)
|
||||
@ -2431,7 +2431,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
cause: traits::ObligationCause<'tcx>,
|
||||
predicates: &ty::InstantiatedPredicates<'tcx>)
|
||||
{
|
||||
assert!(!predicates.has_escaping_regions());
|
||||
assert!(!predicates.has_escaping_bound_vars());
|
||||
|
||||
debug!("add_obligations_for_parameters(predicates={:?})",
|
||||
predicates);
|
||||
@ -5188,8 +5188,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
},
|
||||
);
|
||||
assert!(!substs.has_escaping_regions());
|
||||
assert!(!ty.has_escaping_regions());
|
||||
assert!(!substs.has_escaping_bound_vars());
|
||||
assert!(!ty.has_escaping_bound_vars());
|
||||
|
||||
// Write the "user substs" down first thing for later.
|
||||
let hir_id = self.tcx.hir.node_to_hir_id(node_id);
|
||||
|
@ -99,7 +99,7 @@ fn visit_implementation_of_copy<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impl_did:
|
||||
|
||||
let span = tcx.hir.span(impl_node_id);
|
||||
let param_env = tcx.param_env(impl_did);
|
||||
assert!(!self_type.has_escaping_regions());
|
||||
assert!(!self_type.has_escaping_bound_vars());
|
||||
|
||||
debug!("visit_implementation_of_copy: self_type={:?} (free)",
|
||||
self_type);
|
||||
@ -176,7 +176,7 @@ fn visit_implementation_of_dispatch_from_dyn<'a, 'tcx>(
|
||||
let span = tcx.hir.span(impl_node_id);
|
||||
|
||||
let source = tcx.type_of(impl_did);
|
||||
assert!(!source.has_escaping_regions());
|
||||
assert!(!source.has_escaping_bound_vars());
|
||||
let target = {
|
||||
let trait_ref = tcx.impl_trait_ref(impl_did).unwrap();
|
||||
assert_eq!(trait_ref.def_id, dispatch_from_dyn_trait);
|
||||
@ -356,7 +356,7 @@ pub fn coerce_unsized_info<'a, 'gcx>(gcx: TyCtxt<'a, 'gcx, 'gcx>,
|
||||
|
||||
let span = gcx.hir.span(impl_node_id);
|
||||
let param_env = gcx.param_env(impl_did);
|
||||
assert!(!source.has_escaping_regions());
|
||||
assert!(!source.has_escaping_bound_vars());
|
||||
|
||||
let err_info = CoerceUnsizedInfo { custom_kind: None };
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user