Auto merge of #91318 - eggyal:reduce-boilerplate-around-infallible-folders, r=jackh726
Reduce boilerplate around infallible folders Further to https://github.com/rust-lang/rust/pull/91230#issuecomment-981059666 r? `@jackh726`
This commit is contained in:
commit
acbe4443cc
43 changed files with 900 additions and 736 deletions
|
@ -23,7 +23,6 @@ Rust MIR: a lowered representation of Rust.
|
||||||
#![feature(trusted_len)]
|
#![feature(trusted_len)]
|
||||||
#![feature(trusted_step)]
|
#![feature(trusted_step)]
|
||||||
#![feature(try_blocks)]
|
#![feature(try_blocks)]
|
||||||
#![feature(unwrap_infallible)]
|
|
||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
|
|
@ -94,8 +94,7 @@ pub fn equal_up_to_regions(
|
||||||
// Leave consts and types unchanged.
|
// Leave consts and types unchanged.
|
||||||
ct_op: |ct| ct,
|
ct_op: |ct| ct,
|
||||||
ty_op: |ty| ty,
|
ty_op: |ty| ty,
|
||||||
})
|
}),
|
||||||
.into_ok(),
|
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
tcx.infer_ctxt().enter(|infcx| infcx.can_eq(param_env, normalize(src), normalize(dest)).is_ok())
|
tcx.infer_ctxt().enter(|infcx| infcx.can_eq(param_env, normalize(src), normalize(dest)).is_ok())
|
||||||
|
|
|
@ -4,14 +4,6 @@ use std::mem;
|
||||||
pub trait IdFunctor: Sized {
|
pub trait IdFunctor: Sized {
|
||||||
type Inner;
|
type Inner;
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn map_id<F>(self, mut f: F) -> Self
|
|
||||||
where
|
|
||||||
F: FnMut(Self::Inner) -> Self::Inner,
|
|
||||||
{
|
|
||||||
self.try_map_id::<_, !>(|value| Ok(f(value))).into_ok()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn try_map_id<F, E>(self, f: F) -> Result<Self, E>
|
fn try_map_id<F, E>(self, f: F) -> Result<Self, E>
|
||||||
where
|
where
|
||||||
F: FnMut(Self::Inner) -> Result<Self::Inner, E>;
|
F: FnMut(Self::Inner) -> Result<Self::Inner, E>;
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
#![feature(once_cell)]
|
#![feature(once_cell)]
|
||||||
#![feature(test)]
|
#![feature(test)]
|
||||||
#![feature(thread_id_value)]
|
#![feature(thread_id_value)]
|
||||||
#![feature(unwrap_infallible)]
|
|
||||||
#![allow(rustc::default_hash_types)]
|
#![allow(rustc::default_hash_types)]
|
||||||
#![deny(unaligned_references)]
|
#![deny(unaligned_references)]
|
||||||
|
|
||||||
|
|
|
@ -278,7 +278,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
|
||||||
self.tcx
|
self.tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_binder<T>(&mut self, t: ty::Binder<'tcx, T>) -> Result<ty::Binder<'tcx, T>, Self::Error>
|
fn fold_binder<T>(&mut self, t: ty::Binder<'tcx, T>) -> ty::Binder<'tcx, T>
|
||||||
where
|
where
|
||||||
T: TypeFoldable<'tcx>,
|
T: TypeFoldable<'tcx>,
|
||||||
{
|
{
|
||||||
|
@ -288,13 +288,13 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
|
||||||
t
|
t
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||||
match *r {
|
match *r {
|
||||||
ty::ReLateBound(index, ..) => {
|
ty::ReLateBound(index, ..) => {
|
||||||
if index >= self.binder_index {
|
if index >= self.binder_index {
|
||||||
bug!("escaping late-bound region during canonicalization");
|
bug!("escaping late-bound region during canonicalization");
|
||||||
} else {
|
} else {
|
||||||
Ok(r)
|
r
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,7 +311,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
|
||||||
vid, r
|
vid, r
|
||||||
);
|
);
|
||||||
let r = self.tcx.reuse_or_mk_region(r, ty::ReVar(resolved_vid));
|
let r = self.tcx.reuse_or_mk_region(r, ty::ReVar(resolved_vid));
|
||||||
Ok(self.canonicalize_region_mode.canonicalize_free_region(self, r))
|
self.canonicalize_region_mode.canonicalize_free_region(self, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::ReStatic
|
ty::ReStatic
|
||||||
|
@ -319,11 +319,11 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
|
||||||
| ty::ReFree(_)
|
| ty::ReFree(_)
|
||||||
| ty::ReEmpty(_)
|
| ty::ReEmpty(_)
|
||||||
| ty::RePlaceholder(..)
|
| ty::RePlaceholder(..)
|
||||||
| ty::ReErased => Ok(self.canonicalize_region_mode.canonicalize_free_region(self, r)),
|
| ty::ReErased => self.canonicalize_region_mode.canonicalize_free_region(self, r),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
match *t.kind() {
|
match *t.kind() {
|
||||||
ty::Infer(ty::TyVar(vid)) => {
|
ty::Infer(ty::TyVar(vid)) => {
|
||||||
debug!("canonical: type var found with vid {:?}", vid);
|
debug!("canonical: type var found with vid {:?}", vid);
|
||||||
|
@ -339,40 +339,40 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
|
||||||
Err(mut ui) => {
|
Err(mut ui) => {
|
||||||
// FIXME: perf problem described in #55921.
|
// FIXME: perf problem described in #55921.
|
||||||
ui = ty::UniverseIndex::ROOT;
|
ui = ty::UniverseIndex::ROOT;
|
||||||
Ok(self.canonicalize_ty_var(
|
self.canonicalize_ty_var(
|
||||||
CanonicalVarInfo {
|
CanonicalVarInfo {
|
||||||
kind: CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui)),
|
kind: CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui)),
|
||||||
},
|
},
|
||||||
t,
|
t,
|
||||||
))
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::Infer(ty::IntVar(_)) => Ok(self.canonicalize_ty_var(
|
ty::Infer(ty::IntVar(_)) => self.canonicalize_ty_var(
|
||||||
CanonicalVarInfo { kind: CanonicalVarKind::Ty(CanonicalTyVarKind::Int) },
|
CanonicalVarInfo { kind: CanonicalVarKind::Ty(CanonicalTyVarKind::Int) },
|
||||||
t,
|
t,
|
||||||
)),
|
),
|
||||||
|
|
||||||
ty::Infer(ty::FloatVar(_)) => Ok(self.canonicalize_ty_var(
|
ty::Infer(ty::FloatVar(_)) => self.canonicalize_ty_var(
|
||||||
CanonicalVarInfo { kind: CanonicalVarKind::Ty(CanonicalTyVarKind::Float) },
|
CanonicalVarInfo { kind: CanonicalVarKind::Ty(CanonicalTyVarKind::Float) },
|
||||||
t,
|
t,
|
||||||
)),
|
),
|
||||||
|
|
||||||
ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
|
ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
|
||||||
bug!("encountered a fresh type during canonicalization")
|
bug!("encountered a fresh type during canonicalization")
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::Placeholder(placeholder) => Ok(self.canonicalize_ty_var(
|
ty::Placeholder(placeholder) => self.canonicalize_ty_var(
|
||||||
CanonicalVarInfo { kind: CanonicalVarKind::PlaceholderTy(placeholder) },
|
CanonicalVarInfo { kind: CanonicalVarKind::PlaceholderTy(placeholder) },
|
||||||
t,
|
t,
|
||||||
)),
|
),
|
||||||
|
|
||||||
ty::Bound(debruijn, _) => {
|
ty::Bound(debruijn, _) => {
|
||||||
if debruijn >= self.binder_index {
|
if debruijn >= self.binder_index {
|
||||||
bug!("escaping bound type during canonicalization")
|
bug!("escaping bound type during canonicalization")
|
||||||
} else {
|
} else {
|
||||||
Ok(t)
|
t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -403,16 +403,13 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
|
||||||
if t.flags().intersects(self.needs_canonical_flags) {
|
if t.flags().intersects(self.needs_canonical_flags) {
|
||||||
t.super_fold_with(self)
|
t.super_fold_with(self)
|
||||||
} else {
|
} else {
|
||||||
Ok(t)
|
t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_const(
|
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||||
&mut self,
|
|
||||||
ct: &'tcx ty::Const<'tcx>,
|
|
||||||
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
|
|
||||||
match ct.val {
|
match ct.val {
|
||||||
ty::ConstKind::Infer(InferConst::Var(vid)) => {
|
ty::ConstKind::Infer(InferConst::Var(vid)) => {
|
||||||
debug!("canonical: const var found with vid {:?}", vid);
|
debug!("canonical: const var found with vid {:?}", vid);
|
||||||
|
@ -427,10 +424,10 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
|
||||||
Err(mut ui) => {
|
Err(mut ui) => {
|
||||||
// FIXME: perf problem described in #55921.
|
// FIXME: perf problem described in #55921.
|
||||||
ui = ty::UniverseIndex::ROOT;
|
ui = ty::UniverseIndex::ROOT;
|
||||||
return Ok(self.canonicalize_const_var(
|
return self.canonicalize_const_var(
|
||||||
CanonicalVarInfo { kind: CanonicalVarKind::Const(ui) },
|
CanonicalVarInfo { kind: CanonicalVarKind::Const(ui) },
|
||||||
ct,
|
ct,
|
||||||
));
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -441,20 +438,20 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
|
||||||
if debruijn >= self.binder_index {
|
if debruijn >= self.binder_index {
|
||||||
bug!("escaping bound type during canonicalization")
|
bug!("escaping bound type during canonicalization")
|
||||||
} else {
|
} else {
|
||||||
return Ok(ct);
|
return ct;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::ConstKind::Placeholder(placeholder) => {
|
ty::ConstKind::Placeholder(placeholder) => {
|
||||||
return Ok(self.canonicalize_const_var(
|
return self.canonicalize_const_var(
|
||||||
CanonicalVarInfo { kind: CanonicalVarKind::PlaceholderConst(placeholder) },
|
CanonicalVarInfo { kind: CanonicalVarKind::PlaceholderConst(placeholder) },
|
||||||
ct,
|
ct,
|
||||||
));
|
);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
let flags = FlagComputation::for_const(ct);
|
let flags = FlagComputation::for_const(ct);
|
||||||
if flags.intersects(self.needs_canonical_flags) { ct.super_fold_with(self) } else { Ok(ct) }
|
if flags.intersects(self.needs_canonical_flags) { ct.super_fold_with(self) } else { ct }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -503,7 +500,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
|
||||||
indices: FxHashMap::default(),
|
indices: FxHashMap::default(),
|
||||||
binder_index: ty::INNERMOST,
|
binder_index: ty::INNERMOST,
|
||||||
};
|
};
|
||||||
let out_value = value.fold_with(&mut canonicalizer).into_ok();
|
let out_value = value.fold_with(&mut canonicalizer);
|
||||||
|
|
||||||
// Once we have canonicalized `out_value`, it should not
|
// Once we have canonicalized `out_value`, it should not
|
||||||
// contain anything that ties it to this inference context
|
// contain anything that ties it to this inference context
|
||||||
|
@ -621,7 +618,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
|
||||||
let infcx = self.infcx;
|
let infcx = self.infcx;
|
||||||
let bound_to = infcx.shallow_resolve(ty_var);
|
let bound_to = infcx.shallow_resolve(ty_var);
|
||||||
if bound_to != ty_var {
|
if bound_to != ty_var {
|
||||||
self.fold_ty(bound_to).into_ok()
|
self.fold_ty(bound_to)
|
||||||
} else {
|
} else {
|
||||||
let var = self.canonical_var(info, ty_var.into());
|
let var = self.canonical_var(info, ty_var.into());
|
||||||
self.tcx().mk_ty(ty::Bound(self.binder_index, var.into()))
|
self.tcx().mk_ty(ty::Bound(self.binder_index, var.into()))
|
||||||
|
@ -640,12 +637,12 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
|
||||||
let infcx = self.infcx;
|
let infcx = self.infcx;
|
||||||
let bound_to = infcx.shallow_resolve(const_var);
|
let bound_to = infcx.shallow_resolve(const_var);
|
||||||
if bound_to != const_var {
|
if bound_to != const_var {
|
||||||
self.fold_const(bound_to).into_ok()
|
self.fold_const(bound_to)
|
||||||
} else {
|
} else {
|
||||||
let var = self.canonical_var(info, const_var.into());
|
let var = self.canonical_var(info, const_var.into());
|
||||||
self.tcx().mk_const(ty::Const {
|
self.tcx().mk_const(ty::Const {
|
||||||
val: ty::ConstKind::Bound(self.binder_index, var),
|
val: ty::ConstKind::Bound(self.binder_index, var),
|
||||||
ty: self.fold_ty(const_var.ty).into_ok(),
|
ty: self.fold_ty(const_var.ty),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,7 +72,7 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> {
|
||||||
F: FnOnce(u32) -> ty::InferTy,
|
F: FnOnce(u32) -> ty::InferTy,
|
||||||
{
|
{
|
||||||
if let Some(ty) = opt_ty {
|
if let Some(ty) = opt_ty {
|
||||||
return ty.fold_with(self).into_ok();
|
return ty.fold_with(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.ty_freshen_map.entry(key) {
|
match self.ty_freshen_map.entry(key) {
|
||||||
|
@ -98,7 +98,7 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> {
|
||||||
F: FnOnce(u32) -> ty::InferConst<'tcx>,
|
F: FnOnce(u32) -> ty::InferConst<'tcx>,
|
||||||
{
|
{
|
||||||
if let Some(ct) = opt_ct {
|
if let Some(ct) = opt_ct {
|
||||||
return ct.fold_with(self).into_ok();
|
return ct.fold_with(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.const_freshen_map.entry(key) {
|
match self.const_freshen_map.entry(key) {
|
||||||
|
@ -119,11 +119,11 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
|
||||||
self.infcx.tcx
|
self.infcx.tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||||
match *r {
|
match *r {
|
||||||
ty::ReLateBound(..) => {
|
ty::ReLateBound(..) => {
|
||||||
// leave bound regions alone
|
// leave bound regions alone
|
||||||
Ok(r)
|
r
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::ReEarlyBound(..)
|
ty::ReEarlyBound(..)
|
||||||
|
@ -133,21 +133,21 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
|
||||||
| ty::ReEmpty(_)
|
| ty::ReEmpty(_)
|
||||||
| ty::ReErased => {
|
| ty::ReErased => {
|
||||||
// replace all free regions with 'erased
|
// replace all free regions with 'erased
|
||||||
Ok(self.tcx().lifetimes.re_erased)
|
self.tcx().lifetimes.re_erased
|
||||||
}
|
}
|
||||||
ty::ReStatic => {
|
ty::ReStatic => {
|
||||||
if self.keep_static {
|
if self.keep_static {
|
||||||
Ok(r)
|
r
|
||||||
} else {
|
} else {
|
||||||
Ok(self.tcx().lifetimes.re_erased)
|
self.tcx().lifetimes.re_erased
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
if !t.needs_infer() && !t.has_erasable_regions(self.tcx()) {
|
if !t.needs_infer() && !t.has_erasable_regions(self.tcx()) {
|
||||||
return Ok(t);
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
let tcx = self.infcx.tcx;
|
let tcx = self.infcx.tcx;
|
||||||
|
@ -155,10 +155,10 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
|
||||||
match *t.kind() {
|
match *t.kind() {
|
||||||
ty::Infer(ty::TyVar(v)) => {
|
ty::Infer(ty::TyVar(v)) => {
|
||||||
let opt_ty = self.infcx.inner.borrow_mut().type_variables().probe(v).known();
|
let opt_ty = self.infcx.inner.borrow_mut().type_variables().probe(v).known();
|
||||||
Ok(self.freshen_ty(opt_ty, ty::TyVar(v), ty::FreshTy))
|
self.freshen_ty(opt_ty, ty::TyVar(v), ty::FreshTy)
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::Infer(ty::IntVar(v)) => Ok(self.freshen_ty(
|
ty::Infer(ty::IntVar(v)) => self.freshen_ty(
|
||||||
self.infcx
|
self.infcx
|
||||||
.inner
|
.inner
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
|
@ -167,9 +167,9 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
|
||||||
.map(|v| v.to_type(tcx)),
|
.map(|v| v.to_type(tcx)),
|
||||||
ty::IntVar(v),
|
ty::IntVar(v),
|
||||||
ty::FreshIntTy,
|
ty::FreshIntTy,
|
||||||
)),
|
),
|
||||||
|
|
||||||
ty::Infer(ty::FloatVar(v)) => Ok(self.freshen_ty(
|
ty::Infer(ty::FloatVar(v)) => self.freshen_ty(
|
||||||
self.infcx
|
self.infcx
|
||||||
.inner
|
.inner
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
|
@ -178,7 +178,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
|
||||||
.map(|v| v.to_type(tcx)),
|
.map(|v| v.to_type(tcx)),
|
||||||
ty::FloatVar(v),
|
ty::FloatVar(v),
|
||||||
ty::FreshFloatTy,
|
ty::FreshFloatTy,
|
||||||
)),
|
),
|
||||||
|
|
||||||
ty::Infer(ty::FreshTy(ct) | ty::FreshIntTy(ct) | ty::FreshFloatTy(ct)) => {
|
ty::Infer(ty::FreshTy(ct) | ty::FreshIntTy(ct) | ty::FreshFloatTy(ct)) => {
|
||||||
if ct >= self.ty_freshen_count {
|
if ct >= self.ty_freshen_count {
|
||||||
|
@ -189,7 +189,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
|
||||||
self.ty_freshen_count
|
self.ty_freshen_count
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Ok(t)
|
t
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::Generator(..)
|
ty::Generator(..)
|
||||||
|
@ -221,10 +221,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_const(
|
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||||
&mut self,
|
|
||||||
ct: &'tcx ty::Const<'tcx>,
|
|
||||||
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
|
|
||||||
match ct.val {
|
match ct.val {
|
||||||
ty::ConstKind::Infer(ty::InferConst::Var(v)) => {
|
ty::ConstKind::Infer(ty::InferConst::Var(v)) => {
|
||||||
let opt_ct = self
|
let opt_ct = self
|
||||||
|
@ -235,12 +232,12 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
|
||||||
.probe_value(v)
|
.probe_value(v)
|
||||||
.val
|
.val
|
||||||
.known();
|
.known();
|
||||||
return Ok(self.freshen_const(
|
return self.freshen_const(
|
||||||
opt_ct,
|
opt_ct,
|
||||||
ty::InferConst::Var(v),
|
ty::InferConst::Var(v),
|
||||||
ty::InferConst::Fresh,
|
ty::InferConst::Fresh,
|
||||||
ct.ty,
|
ct.ty,
|
||||||
));
|
);
|
||||||
}
|
}
|
||||||
ty::ConstKind::Infer(ty::InferConst::Fresh(i)) => {
|
ty::ConstKind::Infer(ty::InferConst::Fresh(i)) => {
|
||||||
if i >= self.const_freshen_count {
|
if i >= self.const_freshen_count {
|
||||||
|
@ -251,7 +248,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
|
||||||
self.const_freshen_count,
|
self.const_freshen_count,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return Ok(ct);
|
return ct;
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(_) => {
|
ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(_) => {
|
||||||
|
|
|
@ -161,7 +161,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
{
|
{
|
||||||
Ok(value)
|
Ok(value)
|
||||||
} else {
|
} else {
|
||||||
Ok(value.fold_with(&mut fudger).into_ok())
|
Ok(value.fold_with(&mut fudger))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -180,7 +180,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for InferenceFudger<'a, 'tcx> {
|
||||||
self.infcx.tcx
|
self.infcx.tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
match *ty.kind() {
|
match *ty.kind() {
|
||||||
ty::Infer(ty::InferTy::TyVar(vid)) => {
|
ty::Infer(ty::InferTy::TyVar(vid)) => {
|
||||||
if self.type_vars.0.contains(&vid) {
|
if self.type_vars.0.contains(&vid) {
|
||||||
|
@ -188,7 +188,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for InferenceFudger<'a, 'tcx> {
|
||||||
// Recreate it with a fresh variable here.
|
// Recreate it with a fresh variable here.
|
||||||
let idx = (vid.as_usize() - self.type_vars.0.start.as_usize()) as usize;
|
let idx = (vid.as_usize() - self.type_vars.0.start.as_usize()) as usize;
|
||||||
let origin = self.type_vars.1[idx];
|
let origin = self.type_vars.1[idx];
|
||||||
Ok(self.infcx.next_ty_var(origin))
|
self.infcx.next_ty_var(origin)
|
||||||
} else {
|
} else {
|
||||||
// This variable was created before the
|
// This variable was created before the
|
||||||
// "fudging". Since we refresh all type
|
// "fudging". Since we refresh all type
|
||||||
|
@ -198,43 +198,48 @@ impl<'a, 'tcx> TypeFolder<'tcx> for InferenceFudger<'a, 'tcx> {
|
||||||
debug_assert!(
|
debug_assert!(
|
||||||
self.infcx.inner.borrow_mut().type_variables().probe(vid).is_unknown()
|
self.infcx.inner.borrow_mut().type_variables().probe(vid).is_unknown()
|
||||||
);
|
);
|
||||||
Ok(ty)
|
ty
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::Infer(ty::InferTy::IntVar(vid)) => {
|
ty::Infer(ty::InferTy::IntVar(vid)) => {
|
||||||
Ok(if self.int_vars.contains(&vid) { self.infcx.next_int_var() } else { ty })
|
if self.int_vars.contains(&vid) {
|
||||||
|
self.infcx.next_int_var()
|
||||||
|
} else {
|
||||||
|
ty
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ty::Infer(ty::InferTy::FloatVar(vid)) => {
|
ty::Infer(ty::InferTy::FloatVar(vid)) => {
|
||||||
Ok(if self.float_vars.contains(&vid) { self.infcx.next_float_var() } else { ty })
|
if self.float_vars.contains(&vid) {
|
||||||
|
self.infcx.next_float_var()
|
||||||
|
} else {
|
||||||
|
ty
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => ty.super_fold_with(self),
|
_ => ty.super_fold_with(self),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||||
if let ty::ReVar(vid) = *r {
|
if let ty::ReVar(vid) = *r {
|
||||||
if self.region_vars.0.contains(&vid) {
|
if self.region_vars.0.contains(&vid) {
|
||||||
let idx = vid.index() - self.region_vars.0.start.index();
|
let idx = vid.index() - self.region_vars.0.start.index();
|
||||||
let origin = self.region_vars.1[idx];
|
let origin = self.region_vars.1[idx];
|
||||||
return Ok(self.infcx.next_region_var(origin));
|
return self.infcx.next_region_var(origin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(r)
|
r
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_const(
|
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||||
&mut self,
|
|
||||||
ct: &'tcx ty::Const<'tcx>,
|
|
||||||
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
|
|
||||||
if let ty::Const { val: ty::ConstKind::Infer(ty::InferConst::Var(vid)), ty } = ct {
|
if let ty::Const { val: ty::ConstKind::Infer(ty::InferConst::Var(vid)), ty } = ct {
|
||||||
if self.const_vars.0.contains(&vid) {
|
if self.const_vars.0.contains(&vid) {
|
||||||
// This variable was created during the fudging.
|
// This variable was created during the fudging.
|
||||||
// Recreate it with a fresh variable here.
|
// Recreate it with a fresh variable here.
|
||||||
let idx = (vid.index - self.const_vars.0.start.index) as usize;
|
let idx = (vid.index - self.const_vars.0.start.index) as usize;
|
||||||
let origin = self.const_vars.1[idx];
|
let origin = self.const_vars.1[idx];
|
||||||
Ok(self.infcx.next_const_var(ty, origin))
|
self.infcx.next_const_var(ty, origin)
|
||||||
} else {
|
} else {
|
||||||
Ok(ct)
|
ct
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ct.super_fold_with(self)
|
ct.super_fold_with(self)
|
||||||
|
|
|
@ -681,7 +681,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn freshen<T: TypeFoldable<'tcx>>(&self, t: T) -> T {
|
pub fn freshen<T: TypeFoldable<'tcx>>(&self, t: T) -> T {
|
||||||
t.fold_with(&mut self.freshener()).into_ok()
|
t.fold_with(&mut self.freshener())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the origin of the type variable identified by `vid`, or `None`
|
/// Returns the origin of the type variable identified by `vid`, or `None`
|
||||||
|
@ -1381,7 +1381,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
where
|
where
|
||||||
T: TypeFoldable<'tcx>,
|
T: TypeFoldable<'tcx>,
|
||||||
{
|
{
|
||||||
value.fold_with(&mut ShallowResolver { infcx: self }).into_ok()
|
value.fold_with(&mut ShallowResolver { infcx: self })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn root_var(&self, var: ty::TyVid) -> ty::TyVid {
|
pub fn root_var(&self, var: ty::TyVid) -> ty::TyVid {
|
||||||
|
@ -1402,7 +1402,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
return value; // Avoid duplicated subst-folding.
|
return value; // Avoid duplicated subst-folding.
|
||||||
}
|
}
|
||||||
let mut r = resolve::OpportunisticVarResolver::new(self);
|
let mut r = resolve::OpportunisticVarResolver::new(self);
|
||||||
value.fold_with(&mut r).into_ok()
|
value.fold_with(&mut r)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the first unresolved variable contained in `T`. In the
|
/// Returns the first unresolved variable contained in `T`. In the
|
||||||
|
@ -1745,15 +1745,12 @@ impl<'a, 'tcx> TypeFolder<'tcx> for ShallowResolver<'a, 'tcx> {
|
||||||
self.infcx.tcx
|
self.infcx.tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
Ok(self.infcx.shallow_resolve_ty(ty))
|
self.infcx.shallow_resolve_ty(ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_const(
|
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||||
&mut self,
|
if let ty::Const { val: ty::ConstKind::Infer(InferConst::Var(vid)), .. } = ct {
|
||||||
ct: &'tcx ty::Const<'tcx>,
|
|
||||||
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
|
|
||||||
Ok(if let ty::Const { val: ty::ConstKind::Infer(InferConst::Var(vid)), .. } = ct {
|
|
||||||
self.infcx
|
self.infcx
|
||||||
.inner
|
.inner
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
|
@ -1764,7 +1761,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for ShallowResolver<'a, 'tcx> {
|
||||||
.unwrap_or(ct)
|
.unwrap_or(ct)
|
||||||
} else {
|
} else {
|
||||||
ct
|
ct
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -418,94 +418,91 @@ struct Instantiator<'a, 'tcx> {
|
||||||
impl<'a, 'tcx> Instantiator<'a, 'tcx> {
|
impl<'a, 'tcx> Instantiator<'a, 'tcx> {
|
||||||
fn instantiate_opaque_types_in_map<T: TypeFoldable<'tcx>>(&mut self, value: T) -> T {
|
fn instantiate_opaque_types_in_map<T: TypeFoldable<'tcx>>(&mut self, value: T) -> T {
|
||||||
let tcx = self.infcx.tcx;
|
let tcx = self.infcx.tcx;
|
||||||
value
|
value.fold_with(&mut BottomUpFolder {
|
||||||
.fold_with(&mut BottomUpFolder {
|
tcx,
|
||||||
tcx,
|
ty_op: |ty| {
|
||||||
ty_op: |ty| {
|
if ty.references_error() {
|
||||||
if ty.references_error() {
|
return tcx.ty_error();
|
||||||
return tcx.ty_error();
|
} else if let ty::Opaque(def_id, substs) = ty.kind() {
|
||||||
} else if let ty::Opaque(def_id, substs) = ty.kind() {
|
// Check that this is `impl Trait` type is
|
||||||
// Check that this is `impl Trait` type is
|
// declared by `parent_def_id` -- i.e., one whose
|
||||||
// declared by `parent_def_id` -- i.e., one whose
|
// value we are inferring. At present, this is
|
||||||
// value we are inferring. At present, this is
|
// always true during the first phase of
|
||||||
// always true during the first phase of
|
// type-check, but not always true later on during
|
||||||
// type-check, but not always true later on during
|
// NLL. Once we support named opaque types more fully,
|
||||||
// NLL. Once we support named opaque types more fully,
|
// this same scenario will be able to arise during all phases.
|
||||||
// this same scenario will be able to arise during all phases.
|
//
|
||||||
//
|
// Here is an example using type alias `impl Trait`
|
||||||
// Here is an example using type alias `impl Trait`
|
// that indicates the distinction we are checking for:
|
||||||
// that indicates the distinction we are checking for:
|
//
|
||||||
//
|
// ```rust
|
||||||
// ```rust
|
// mod a {
|
||||||
// mod a {
|
// pub type Foo = impl Iterator;
|
||||||
// pub type Foo = impl Iterator;
|
// pub fn make_foo() -> Foo { .. }
|
||||||
// pub fn make_foo() -> Foo { .. }
|
// }
|
||||||
// }
|
//
|
||||||
//
|
// mod b {
|
||||||
// mod b {
|
// fn foo() -> a::Foo { a::make_foo() }
|
||||||
// fn foo() -> a::Foo { a::make_foo() }
|
// }
|
||||||
// }
|
// ```
|
||||||
// ```
|
//
|
||||||
//
|
// Here, the return type of `foo` references an
|
||||||
// Here, the return type of `foo` references an
|
// `Opaque` indeed, but not one whose value is
|
||||||
// `Opaque` indeed, but not one whose value is
|
// presently being inferred. You can get into a
|
||||||
// presently being inferred. You can get into a
|
// similar situation with closure return types
|
||||||
// similar situation with closure return types
|
// today:
|
||||||
// today:
|
//
|
||||||
//
|
// ```rust
|
||||||
// ```rust
|
// fn foo() -> impl Iterator { .. }
|
||||||
// fn foo() -> impl Iterator { .. }
|
// fn bar() {
|
||||||
// fn bar() {
|
// let x = || foo(); // returns the Opaque assoc with `foo`
|
||||||
// let x = || foo(); // returns the Opaque assoc with `foo`
|
// }
|
||||||
// }
|
// ```
|
||||||
// ```
|
if let Some(def_id) = def_id.as_local() {
|
||||||
if let Some(def_id) = def_id.as_local() {
|
let opaque_hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
|
||||||
let opaque_hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
|
let parent_def_id = self.infcx.defining_use_anchor;
|
||||||
let parent_def_id = self.infcx.defining_use_anchor;
|
let def_scope_default = || {
|
||||||
let def_scope_default = || {
|
let opaque_parent_hir_id = tcx.hir().get_parent_item(opaque_hir_id);
|
||||||
let opaque_parent_hir_id = tcx.hir().get_parent_item(opaque_hir_id);
|
parent_def_id == tcx.hir().local_def_id(opaque_parent_hir_id)
|
||||||
parent_def_id == tcx.hir().local_def_id(opaque_parent_hir_id)
|
};
|
||||||
};
|
let (in_definition_scope, origin) = match tcx.hir().expect_item(def_id).kind
|
||||||
let (in_definition_scope, origin) =
|
{
|
||||||
match tcx.hir().expect_item(def_id).kind {
|
// Anonymous `impl Trait`
|
||||||
// Anonymous `impl Trait`
|
hir::ItemKind::OpaqueTy(hir::OpaqueTy {
|
||||||
hir::ItemKind::OpaqueTy(hir::OpaqueTy {
|
impl_trait_fn: Some(parent),
|
||||||
impl_trait_fn: Some(parent),
|
origin,
|
||||||
origin,
|
..
|
||||||
..
|
}) => (parent == parent_def_id.to_def_id(), origin),
|
||||||
}) => (parent == parent_def_id.to_def_id(), origin),
|
// Named `type Foo = impl Bar;`
|
||||||
// Named `type Foo = impl Bar;`
|
hir::ItemKind::OpaqueTy(hir::OpaqueTy {
|
||||||
hir::ItemKind::OpaqueTy(hir::OpaqueTy {
|
impl_trait_fn: None,
|
||||||
impl_trait_fn: None,
|
origin,
|
||||||
origin,
|
..
|
||||||
..
|
}) => {
|
||||||
}) => (
|
(may_define_opaque_type(tcx, parent_def_id, opaque_hir_id), origin)
|
||||||
may_define_opaque_type(tcx, parent_def_id, opaque_hir_id),
|
|
||||||
origin,
|
|
||||||
),
|
|
||||||
_ => (def_scope_default(), hir::OpaqueTyOrigin::TyAlias),
|
|
||||||
};
|
|
||||||
if in_definition_scope {
|
|
||||||
let opaque_type_key =
|
|
||||||
OpaqueTypeKey { def_id: def_id.to_def_id(), substs };
|
|
||||||
return self.fold_opaque_ty(ty, opaque_type_key, origin);
|
|
||||||
}
|
}
|
||||||
|
_ => (def_scope_default(), hir::OpaqueTyOrigin::TyAlias),
|
||||||
|
};
|
||||||
|
if in_definition_scope {
|
||||||
|
let opaque_type_key =
|
||||||
|
OpaqueTypeKey { def_id: def_id.to_def_id(), substs };
|
||||||
|
return self.fold_opaque_ty(ty, opaque_type_key, origin);
|
||||||
|
}
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
"instantiate_opaque_types_in_map: \
|
"instantiate_opaque_types_in_map: \
|
||||||
encountered opaque outside its definition scope \
|
encountered opaque outside its definition scope \
|
||||||
def_id={:?}",
|
def_id={:?}",
|
||||||
def_id,
|
def_id,
|
||||||
);
|
);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ty
|
ty
|
||||||
},
|
},
|
||||||
lt_op: |lt| lt,
|
lt_op: |lt| lt,
|
||||||
ct_op: |ct| ct,
|
ct_op: |ct| ct,
|
||||||
})
|
})
|
||||||
.into_ok()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip(self), level = "debug")]
|
#[instrument(skip(self), level = "debug")]
|
||||||
|
@ -558,23 +555,21 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
|
||||||
debug!(?predicate);
|
debug!(?predicate);
|
||||||
|
|
||||||
// We can't normalize associated types from `rustc_infer`, but we can eagerly register inference variables for them.
|
// We can't normalize associated types from `rustc_infer`, but we can eagerly register inference variables for them.
|
||||||
let predicate = predicate
|
let predicate = predicate.fold_with(&mut BottomUpFolder {
|
||||||
.fold_with(&mut BottomUpFolder {
|
tcx,
|
||||||
tcx,
|
ty_op: |ty| match ty.kind() {
|
||||||
ty_op: |ty| match ty.kind() {
|
ty::Projection(projection_ty) => infcx.infer_projection(
|
||||||
ty::Projection(projection_ty) => infcx.infer_projection(
|
self.param_env,
|
||||||
self.param_env,
|
*projection_ty,
|
||||||
*projection_ty,
|
traits::ObligationCause::misc(self.value_span, self.body_id),
|
||||||
traits::ObligationCause::misc(self.value_span, self.body_id),
|
0,
|
||||||
0,
|
&mut self.obligations,
|
||||||
&mut self.obligations,
|
),
|
||||||
),
|
_ => ty,
|
||||||
_ => ty,
|
},
|
||||||
},
|
lt_op: |lt| lt,
|
||||||
lt_op: |lt| lt,
|
ct_op: |ct| ct,
|
||||||
ct_op: |ct| ct,
|
});
|
||||||
})
|
|
||||||
.into_ok();
|
|
||||||
debug!(?predicate);
|
debug!(?predicate);
|
||||||
|
|
||||||
if let ty::PredicateKind::Projection(projection) = predicate.kind().skip_binder() {
|
if let ty::PredicateKind::Projection(projection) = predicate.kind().skip_binder() {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use super::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
use super::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||||
use super::{FixupError, FixupResult, InferCtxt, Span};
|
use super::{FixupError, FixupResult, InferCtxt, Span};
|
||||||
use rustc_middle::mir;
|
use rustc_middle::mir;
|
||||||
use rustc_middle::ty::fold::{TypeFolder, TypeVisitor};
|
use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFolder, TypeVisitor};
|
||||||
use rustc_middle::ty::{self, Const, InferConst, Ty, TyCtxt, TypeFoldable};
|
use rustc_middle::ty::{self, Const, InferConst, Ty, TyCtxt, TypeFoldable};
|
||||||
|
|
||||||
use std::ops::ControlFlow;
|
use std::ops::ControlFlow;
|
||||||
|
@ -30,28 +30,25 @@ impl<'a, 'tcx> TypeFolder<'tcx> for OpportunisticVarResolver<'a, 'tcx> {
|
||||||
self.infcx.tcx
|
self.infcx.tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
if !t.has_infer_types_or_consts() {
|
if !t.has_infer_types_or_consts() {
|
||||||
Ok(t) // micro-optimize -- if there is nothing in this type that this fold affects...
|
t // micro-optimize -- if there is nothing in this type that this fold affects...
|
||||||
} else {
|
} else {
|
||||||
let t = self.infcx.shallow_resolve(t);
|
let t = self.infcx.shallow_resolve(t);
|
||||||
t.super_fold_with(self)
|
t.super_fold_with(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_const(&mut self, ct: &'tcx Const<'tcx>) -> Result<&'tcx Const<'tcx>, Self::Error> {
|
fn fold_const(&mut self, ct: &'tcx Const<'tcx>) -> &'tcx Const<'tcx> {
|
||||||
if !ct.has_infer_types_or_consts() {
|
if !ct.has_infer_types_or_consts() {
|
||||||
Ok(ct) // micro-optimize -- if there is nothing in this const that this fold affects...
|
ct // micro-optimize -- if there is nothing in this const that this fold affects...
|
||||||
} else {
|
} else {
|
||||||
let ct = self.infcx.shallow_resolve(ct);
|
let ct = self.infcx.shallow_resolve(ct);
|
||||||
ct.super_fold_with(self)
|
ct.super_fold_with(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_mir_const(
|
fn fold_mir_const(&mut self, constant: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> {
|
||||||
&mut self,
|
|
||||||
constant: mir::ConstantKind<'tcx>,
|
|
||||||
) -> Result<mir::ConstantKind<'tcx>, Self::Error> {
|
|
||||||
constant.super_fold_with(self)
|
constant.super_fold_with(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,16 +75,16 @@ impl<'a, 'tcx> TypeFolder<'tcx> for OpportunisticRegionResolver<'a, 'tcx> {
|
||||||
self.infcx.tcx
|
self.infcx.tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
if !t.has_infer_regions() {
|
if !t.has_infer_regions() {
|
||||||
Ok(t) // micro-optimize -- if there is nothing in this type that this fold affects...
|
t // micro-optimize -- if there is nothing in this type that this fold affects...
|
||||||
} else {
|
} else {
|
||||||
t.super_fold_with(self)
|
t.super_fold_with(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||||
Ok(match *r {
|
match *r {
|
||||||
ty::ReVar(rid) => {
|
ty::ReVar(rid) => {
|
||||||
let resolved = self
|
let resolved = self
|
||||||
.infcx
|
.infcx
|
||||||
|
@ -98,15 +95,12 @@ impl<'a, 'tcx> TypeFolder<'tcx> for OpportunisticRegionResolver<'a, 'tcx> {
|
||||||
self.tcx().reuse_or_mk_region(r, ty::ReVar(resolved))
|
self.tcx().reuse_or_mk_region(r, ty::ReVar(resolved))
|
||||||
}
|
}
|
||||||
_ => r,
|
_ => r,
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_const(
|
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||||
&mut self,
|
|
||||||
ct: &'tcx ty::Const<'tcx>,
|
|
||||||
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
|
|
||||||
if !ct.has_infer_regions() {
|
if !ct.has_infer_regions() {
|
||||||
Ok(ct) // micro-optimize -- if there is nothing in this const that this fold affects...
|
ct // micro-optimize -- if there is nothing in this const that this fold affects...
|
||||||
} else {
|
} else {
|
||||||
ct.super_fold_with(self)
|
ct.super_fold_with(self)
|
||||||
}
|
}
|
||||||
|
@ -181,7 +175,7 @@ pub fn fully_resolve<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>, value: T) -> Fixu
|
||||||
where
|
where
|
||||||
T: TypeFoldable<'tcx>,
|
T: TypeFoldable<'tcx>,
|
||||||
{
|
{
|
||||||
value.fold_with(&mut FullTypeResolver { infcx })
|
value.try_fold_with(&mut FullTypeResolver { infcx })
|
||||||
}
|
}
|
||||||
|
|
||||||
// N.B. This type is not public because the protocol around checking the
|
// N.B. This type is not public because the protocol around checking the
|
||||||
|
@ -196,8 +190,10 @@ impl<'a, 'tcx> TypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> {
|
||||||
fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
|
fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
|
||||||
self.infcx.tcx
|
self.infcx.tcx
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
impl<'a, 'tcx> FallibleTypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> {
|
||||||
|
fn try_fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||||
if !t.needs_infer() {
|
if !t.needs_infer() {
|
||||||
Ok(t) // micro-optimize -- if there is nothing in this type that this fold affects...
|
Ok(t) // micro-optimize -- if there is nothing in this type that this fold affects...
|
||||||
} else {
|
} else {
|
||||||
|
@ -209,12 +205,12 @@ impl<'a, 'tcx> TypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> {
|
||||||
ty::Infer(_) => {
|
ty::Infer(_) => {
|
||||||
bug!("Unexpected type in full type resolver: {:?}", t);
|
bug!("Unexpected type in full type resolver: {:?}", t);
|
||||||
}
|
}
|
||||||
_ => t.super_fold_with(self),
|
_ => t.try_super_fold_with(self),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
fn try_fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
||||||
match *r {
|
match *r {
|
||||||
ty::ReVar(rid) => Ok(self
|
ty::ReVar(rid) => Ok(self
|
||||||
.infcx
|
.infcx
|
||||||
|
@ -227,7 +223,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_const(
|
fn try_fold_const(
|
||||||
&mut self,
|
&mut self,
|
||||||
c: &'tcx ty::Const<'tcx>,
|
c: &'tcx ty::Const<'tcx>,
|
||||||
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
|
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
|
||||||
|
@ -244,7 +240,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
c.super_fold_with(self)
|
c.try_super_fold_with(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
#![feature(control_flow_enum)]
|
#![feature(control_flow_enum)]
|
||||||
#![feature(min_specialization)]
|
#![feature(min_specialization)]
|
||||||
#![feature(label_break_value)]
|
#![feature(label_break_value)]
|
||||||
#![feature(unwrap_infallible)]
|
|
||||||
#![recursion_limit = "512"] // For rustdoc
|
#![recursion_limit = "512"] // For rustdoc
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::traits;
|
use crate::traits;
|
||||||
use crate::traits::project::Normalized;
|
use crate::traits::project::Normalized;
|
||||||
use rustc_middle::ty;
|
use rustc_middle::ty;
|
||||||
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
|
use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeVisitor};
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::ops::ControlFlow;
|
use std::ops::ControlFlow;
|
||||||
|
@ -60,12 +60,15 @@ impl<'tcx> fmt::Debug for traits::MismatchedProjectionTypes<'tcx> {
|
||||||
// TypeFoldable implementations.
|
// TypeFoldable implementations.
|
||||||
|
|
||||||
impl<'tcx, O: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Obligation<'tcx, O> {
|
impl<'tcx, O: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Obligation<'tcx, O> {
|
||||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
|
||||||
|
self,
|
||||||
|
folder: &mut F,
|
||||||
|
) -> Result<Self, F::Error> {
|
||||||
Ok(traits::Obligation {
|
Ok(traits::Obligation {
|
||||||
cause: self.cause,
|
cause: self.cause,
|
||||||
recursion_depth: self.recursion_depth,
|
recursion_depth: self.recursion_depth,
|
||||||
predicate: self.predicate.fold_with(folder)?,
|
predicate: self.predicate.try_fold_with(folder)?,
|
||||||
param_env: self.param_env.fold_with(folder)?,
|
param_env: self.param_env.try_fold_with(folder)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ pub fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::
|
||||||
vi.construct(|_, index| {
|
vi.construct(|_, index| {
|
||||||
let bind = &bindings[index];
|
let bind = &bindings[index];
|
||||||
quote! {
|
quote! {
|
||||||
::rustc_middle::ty::fold::TypeFoldable::fold_with(#bind, __folder)?
|
::rustc_middle::ty::fold::TypeFoldable::try_fold_with(#bind, __folder)?
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
@ -25,7 +25,7 @@ pub fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::
|
||||||
s.bound_impl(
|
s.bound_impl(
|
||||||
quote!(::rustc_middle::ty::fold::TypeFoldable<'tcx>),
|
quote!(::rustc_middle::ty::fold::TypeFoldable<'tcx>),
|
||||||
quote! {
|
quote! {
|
||||||
fn super_fold_with<__F: ::rustc_middle::ty::fold::TypeFolder<'tcx>>(
|
fn try_super_fold_with<__F: ::rustc_middle::ty::fold::FallibleTypeFolder<'tcx>>(
|
||||||
self,
|
self,
|
||||||
__folder: &mut __F
|
__folder: &mut __F
|
||||||
) -> Result<Self, __F::Error> {
|
) -> Result<Self, __F::Error> {
|
||||||
|
|
|
@ -52,7 +52,7 @@ macro_rules! TrivialTypeFoldableImpls {
|
||||||
(for <$tcx:lifetime> { $($ty:ty,)+ }) => {
|
(for <$tcx:lifetime> { $($ty:ty,)+ }) => {
|
||||||
$(
|
$(
|
||||||
impl<$tcx> $crate::ty::fold::TypeFoldable<$tcx> for $ty {
|
impl<$tcx> $crate::ty::fold::TypeFoldable<$tcx> for $ty {
|
||||||
fn super_fold_with<F: $crate::ty::fold::TypeFolder<$tcx>>(
|
fn try_super_fold_with<F: $crate::ty::fold::FallibleTypeFolder<$tcx>>(
|
||||||
self,
|
self,
|
||||||
_: &mut F
|
_: &mut F
|
||||||
) -> ::std::result::Result<$ty, F::Error> {
|
) -> ::std::result::Result<$ty, F::Error> {
|
||||||
|
@ -95,7 +95,7 @@ macro_rules! EnumTypeFoldableImpl {
|
||||||
impl<$($p),*> $crate::ty::fold::TypeFoldable<$tcx> for $s
|
impl<$($p),*> $crate::ty::fold::TypeFoldable<$tcx> for $s
|
||||||
$(where $($wc)*)*
|
$(where $($wc)*)*
|
||||||
{
|
{
|
||||||
fn super_fold_with<V: $crate::ty::fold::TypeFolder<$tcx>>(
|
fn try_super_fold_with<V: $crate::ty::fold::FallibleTypeFolder<$tcx>>(
|
||||||
self,
|
self,
|
||||||
folder: &mut V,
|
folder: &mut V,
|
||||||
) -> ::std::result::Result<Self, V::Error> {
|
) -> ::std::result::Result<Self, V::Error> {
|
||||||
|
@ -126,7 +126,7 @@ macro_rules! EnumTypeFoldableImpl {
|
||||||
output(
|
output(
|
||||||
$variant ( $($variant_arg),* ) => {
|
$variant ( $($variant_arg),* ) => {
|
||||||
$variant (
|
$variant (
|
||||||
$($crate::ty::fold::TypeFoldable::fold_with($variant_arg, $folder)?),*
|
$($crate::ty::fold::TypeFoldable::try_fold_with($variant_arg, $folder)?),*
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
$($output)*
|
$($output)*
|
||||||
|
|
|
@ -7,7 +7,7 @@ use crate::mir::interpret::{Allocation, ConstValue, GlobalAlloc, Scalar};
|
||||||
use crate::mir::visit::MirVisitable;
|
use crate::mir::visit::MirVisitable;
|
||||||
use crate::ty::adjustment::PointerCast;
|
use crate::ty::adjustment::PointerCast;
|
||||||
use crate::ty::codec::{TyDecoder, TyEncoder};
|
use crate::ty::codec::{TyDecoder, TyEncoder};
|
||||||
use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
|
use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeVisitor};
|
||||||
use crate::ty::print::{FmtPrinter, Printer};
|
use crate::ty::print::{FmtPrinter, Printer};
|
||||||
use crate::ty::subst::{Subst, SubstsRef};
|
use crate::ty::subst::{Subst, SubstsRef};
|
||||||
use crate::ty::{self, List, Ty, TyCtxt};
|
use crate::ty::{self, List, Ty, TyCtxt};
|
||||||
|
@ -2760,10 +2760,13 @@ impl UserTypeProjection {
|
||||||
TrivialTypeFoldableAndLiftImpls! { ProjectionKind, }
|
TrivialTypeFoldableAndLiftImpls! { ProjectionKind, }
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for UserTypeProjection {
|
impl<'tcx> TypeFoldable<'tcx> for UserTypeProjection {
|
||||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
|
||||||
|
self,
|
||||||
|
folder: &mut F,
|
||||||
|
) -> Result<Self, F::Error> {
|
||||||
Ok(UserTypeProjection {
|
Ok(UserTypeProjection {
|
||||||
base: self.base.fold_with(folder)?,
|
base: self.base.try_fold_with(folder)?,
|
||||||
projs: self.projs.fold_with(folder)?,
|
projs: self.projs.try_fold_with(folder)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,39 +16,42 @@ TrivialTypeFoldableAndLiftImpls! {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
|
impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
|
||||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
|
||||||
|
self,
|
||||||
|
folder: &mut F,
|
||||||
|
) -> Result<Self, F::Error> {
|
||||||
use crate::mir::TerminatorKind::*;
|
use crate::mir::TerminatorKind::*;
|
||||||
|
|
||||||
let kind = match self.kind {
|
let kind = match self.kind {
|
||||||
Goto { target } => Goto { target },
|
Goto { target } => Goto { target },
|
||||||
SwitchInt { discr, switch_ty, targets } => SwitchInt {
|
SwitchInt { discr, switch_ty, targets } => SwitchInt {
|
||||||
discr: discr.fold_with(folder)?,
|
discr: discr.try_fold_with(folder)?,
|
||||||
switch_ty: switch_ty.fold_with(folder)?,
|
switch_ty: switch_ty.try_fold_with(folder)?,
|
||||||
targets,
|
targets,
|
||||||
},
|
},
|
||||||
Drop { place, target, unwind } => {
|
Drop { place, target, unwind } => {
|
||||||
Drop { place: place.fold_with(folder)?, target, unwind }
|
Drop { place: place.try_fold_with(folder)?, target, unwind }
|
||||||
}
|
}
|
||||||
DropAndReplace { place, value, target, unwind } => DropAndReplace {
|
DropAndReplace { place, value, target, unwind } => DropAndReplace {
|
||||||
place: place.fold_with(folder)?,
|
place: place.try_fold_with(folder)?,
|
||||||
value: value.fold_with(folder)?,
|
value: value.try_fold_with(folder)?,
|
||||||
target,
|
target,
|
||||||
unwind,
|
unwind,
|
||||||
},
|
},
|
||||||
Yield { value, resume, resume_arg, drop } => Yield {
|
Yield { value, resume, resume_arg, drop } => Yield {
|
||||||
value: value.fold_with(folder)?,
|
value: value.try_fold_with(folder)?,
|
||||||
resume,
|
resume,
|
||||||
resume_arg: resume_arg.fold_with(folder)?,
|
resume_arg: resume_arg.try_fold_with(folder)?,
|
||||||
drop,
|
drop,
|
||||||
},
|
},
|
||||||
Call { func, args, destination, cleanup, from_hir_call, fn_span } => {
|
Call { func, args, destination, cleanup, from_hir_call, fn_span } => {
|
||||||
let dest = destination
|
let dest = destination
|
||||||
.map(|(loc, dest)| (loc.fold_with(folder).map(|loc| (loc, dest))))
|
.map(|(loc, dest)| (loc.try_fold_with(folder).map(|loc| (loc, dest))))
|
||||||
.transpose()?;
|
.transpose()?;
|
||||||
|
|
||||||
Call {
|
Call {
|
||||||
func: func.fold_with(folder)?,
|
func: func.try_fold_with(folder)?,
|
||||||
args: args.fold_with(folder)?,
|
args: args.try_fold_with(folder)?,
|
||||||
destination: dest,
|
destination: dest,
|
||||||
cleanup,
|
cleanup,
|
||||||
from_hir_call,
|
from_hir_call,
|
||||||
|
@ -58,16 +61,19 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
|
||||||
Assert { cond, expected, msg, target, cleanup } => {
|
Assert { cond, expected, msg, target, cleanup } => {
|
||||||
use AssertKind::*;
|
use AssertKind::*;
|
||||||
let msg = match msg {
|
let msg = match msg {
|
||||||
BoundsCheck { len, index } => {
|
BoundsCheck { len, index } => BoundsCheck {
|
||||||
BoundsCheck { len: len.fold_with(folder)?, index: index.fold_with(folder)? }
|
len: len.try_fold_with(folder)?,
|
||||||
|
index: index.try_fold_with(folder)?,
|
||||||
|
},
|
||||||
|
Overflow(op, l, r) => {
|
||||||
|
Overflow(op, l.try_fold_with(folder)?, r.try_fold_with(folder)?)
|
||||||
}
|
}
|
||||||
Overflow(op, l, r) => Overflow(op, l.fold_with(folder)?, r.fold_with(folder)?),
|
OverflowNeg(op) => OverflowNeg(op.try_fold_with(folder)?),
|
||||||
OverflowNeg(op) => OverflowNeg(op.fold_with(folder)?),
|
DivisionByZero(op) => DivisionByZero(op.try_fold_with(folder)?),
|
||||||
DivisionByZero(op) => DivisionByZero(op.fold_with(folder)?),
|
RemainderByZero(op) => RemainderByZero(op.try_fold_with(folder)?),
|
||||||
RemainderByZero(op) => RemainderByZero(op.fold_with(folder)?),
|
|
||||||
ResumedAfterReturn(_) | ResumedAfterPanic(_) => msg,
|
ResumedAfterReturn(_) | ResumedAfterPanic(_) => msg,
|
||||||
};
|
};
|
||||||
Assert { cond: cond.fold_with(folder)?, expected, msg, target, cleanup }
|
Assert { cond: cond.try_fold_with(folder)?, expected, msg, target, cleanup }
|
||||||
}
|
}
|
||||||
GeneratorDrop => GeneratorDrop,
|
GeneratorDrop => GeneratorDrop,
|
||||||
Resume => Resume,
|
Resume => Resume,
|
||||||
|
@ -80,7 +86,7 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
|
||||||
FalseUnwind { real_target, unwind } => FalseUnwind { real_target, unwind },
|
FalseUnwind { real_target, unwind } => FalseUnwind { real_target, unwind },
|
||||||
InlineAsm { template, operands, options, line_spans, destination } => InlineAsm {
|
InlineAsm { template, operands, options, line_spans, destination } => InlineAsm {
|
||||||
template,
|
template,
|
||||||
operands: operands.fold_with(folder)?,
|
operands: operands.try_fold_with(folder)?,
|
||||||
options,
|
options,
|
||||||
line_spans,
|
line_spans,
|
||||||
destination,
|
destination,
|
||||||
|
@ -142,7 +148,7 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for GeneratorKind {
|
impl<'tcx> TypeFoldable<'tcx> for GeneratorKind {
|
||||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> {
|
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> {
|
||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,10 +158,13 @@ impl<'tcx> TypeFoldable<'tcx> for GeneratorKind {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for Place<'tcx> {
|
impl<'tcx> TypeFoldable<'tcx> for Place<'tcx> {
|
||||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
|
||||||
|
self,
|
||||||
|
folder: &mut F,
|
||||||
|
) -> Result<Self, F::Error> {
|
||||||
Ok(Place {
|
Ok(Place {
|
||||||
local: self.local.fold_with(folder)?,
|
local: self.local.try_fold_with(folder)?,
|
||||||
projection: self.projection.fold_with(folder)?,
|
projection: self.projection.try_fold_with(folder)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,7 +175,10 @@ impl<'tcx> TypeFoldable<'tcx> for Place<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<PlaceElem<'tcx>> {
|
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<PlaceElem<'tcx>> {
|
||||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
|
||||||
|
self,
|
||||||
|
folder: &mut F,
|
||||||
|
) -> Result<Self, F::Error> {
|
||||||
ty::util::fold_list(self, folder, |tcx, v| tcx.intern_place_elems(v))
|
ty::util::fold_list(self, folder, |tcx, v| tcx.intern_place_elems(v))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,48 +188,56 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<PlaceElem<'tcx>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
|
impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
|
||||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
|
||||||
|
self,
|
||||||
|
folder: &mut F,
|
||||||
|
) -> Result<Self, F::Error> {
|
||||||
use crate::mir::Rvalue::*;
|
use crate::mir::Rvalue::*;
|
||||||
Ok(match self {
|
Ok(match self {
|
||||||
Use(op) => Use(op.fold_with(folder)?),
|
Use(op) => Use(op.try_fold_with(folder)?),
|
||||||
Repeat(op, len) => Repeat(op.fold_with(folder)?, len.fold_with(folder)?),
|
Repeat(op, len) => Repeat(op.try_fold_with(folder)?, len.try_fold_with(folder)?),
|
||||||
ThreadLocalRef(did) => ThreadLocalRef(did.fold_with(folder)?),
|
ThreadLocalRef(did) => ThreadLocalRef(did.try_fold_with(folder)?),
|
||||||
Ref(region, bk, place) => Ref(region.fold_with(folder)?, bk, place.fold_with(folder)?),
|
Ref(region, bk, place) => {
|
||||||
AddressOf(mutability, place) => AddressOf(mutability, place.fold_with(folder)?),
|
Ref(region.try_fold_with(folder)?, bk, place.try_fold_with(folder)?)
|
||||||
Len(place) => Len(place.fold_with(folder)?),
|
}
|
||||||
Cast(kind, op, ty) => Cast(kind, op.fold_with(folder)?, ty.fold_with(folder)?),
|
AddressOf(mutability, place) => AddressOf(mutability, place.try_fold_with(folder)?),
|
||||||
|
Len(place) => Len(place.try_fold_with(folder)?),
|
||||||
|
Cast(kind, op, ty) => Cast(kind, op.try_fold_with(folder)?, ty.try_fold_with(folder)?),
|
||||||
BinaryOp(op, box (rhs, lhs)) => {
|
BinaryOp(op, box (rhs, lhs)) => {
|
||||||
BinaryOp(op, Box::new((rhs.fold_with(folder)?, lhs.fold_with(folder)?)))
|
BinaryOp(op, Box::new((rhs.try_fold_with(folder)?, lhs.try_fold_with(folder)?)))
|
||||||
}
|
}
|
||||||
CheckedBinaryOp(op, box (rhs, lhs)) => {
|
CheckedBinaryOp(op, box (rhs, lhs)) => CheckedBinaryOp(
|
||||||
CheckedBinaryOp(op, Box::new((rhs.fold_with(folder)?, lhs.fold_with(folder)?)))
|
op,
|
||||||
}
|
Box::new((rhs.try_fold_with(folder)?, lhs.try_fold_with(folder)?)),
|
||||||
UnaryOp(op, val) => UnaryOp(op, val.fold_with(folder)?),
|
),
|
||||||
Discriminant(place) => Discriminant(place.fold_with(folder)?),
|
UnaryOp(op, val) => UnaryOp(op, val.try_fold_with(folder)?),
|
||||||
NullaryOp(op, ty) => NullaryOp(op, ty.fold_with(folder)?),
|
Discriminant(place) => Discriminant(place.try_fold_with(folder)?),
|
||||||
|
NullaryOp(op, ty) => NullaryOp(op, ty.try_fold_with(folder)?),
|
||||||
Aggregate(kind, fields) => {
|
Aggregate(kind, fields) => {
|
||||||
let kind = kind.try_map_id(|kind| {
|
let kind = kind.try_map_id(|kind| {
|
||||||
Ok(match kind {
|
Ok(match kind {
|
||||||
AggregateKind::Array(ty) => AggregateKind::Array(ty.fold_with(folder)?),
|
AggregateKind::Array(ty) => AggregateKind::Array(ty.try_fold_with(folder)?),
|
||||||
AggregateKind::Tuple => AggregateKind::Tuple,
|
AggregateKind::Tuple => AggregateKind::Tuple,
|
||||||
AggregateKind::Adt(def, v, substs, user_ty, n) => AggregateKind::Adt(
|
AggregateKind::Adt(def, v, substs, user_ty, n) => AggregateKind::Adt(
|
||||||
def,
|
def,
|
||||||
v,
|
v,
|
||||||
substs.fold_with(folder)?,
|
substs.try_fold_with(folder)?,
|
||||||
user_ty.fold_with(folder)?,
|
user_ty.try_fold_with(folder)?,
|
||||||
n,
|
n,
|
||||||
),
|
),
|
||||||
AggregateKind::Closure(id, substs) => {
|
AggregateKind::Closure(id, substs) => {
|
||||||
AggregateKind::Closure(id, substs.fold_with(folder)?)
|
AggregateKind::Closure(id, substs.try_fold_with(folder)?)
|
||||||
}
|
}
|
||||||
AggregateKind::Generator(id, substs, movablity) => {
|
AggregateKind::Generator(id, substs, movablity) => {
|
||||||
AggregateKind::Generator(id, substs.fold_with(folder)?, movablity)
|
AggregateKind::Generator(id, substs.try_fold_with(folder)?, movablity)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})?;
|
})?;
|
||||||
Aggregate(kind, fields.fold_with(folder)?)
|
Aggregate(kind, fields.try_fold_with(folder)?)
|
||||||
|
}
|
||||||
|
ShallowInitBox(op, ty) => {
|
||||||
|
ShallowInitBox(op.try_fold_with(folder)?, ty.try_fold_with(folder)?)
|
||||||
}
|
}
|
||||||
ShallowInitBox(op, ty) => ShallowInitBox(op.fold_with(folder)?, ty.fold_with(folder)?),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,11 +292,14 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for Operand<'tcx> {
|
impl<'tcx> TypeFoldable<'tcx> for Operand<'tcx> {
|
||||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
|
||||||
|
self,
|
||||||
|
folder: &mut F,
|
||||||
|
) -> Result<Self, F::Error> {
|
||||||
Ok(match self {
|
Ok(match self {
|
||||||
Operand::Copy(place) => Operand::Copy(place.fold_with(folder)?),
|
Operand::Copy(place) => Operand::Copy(place.try_fold_with(folder)?),
|
||||||
Operand::Move(place) => Operand::Move(place.fold_with(folder)?),
|
Operand::Move(place) => Operand::Move(place.try_fold_with(folder)?),
|
||||||
Operand::Constant(c) => Operand::Constant(c.fold_with(folder)?),
|
Operand::Constant(c) => Operand::Constant(c.try_fold_with(folder)?),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,13 +312,16 @@ impl<'tcx> TypeFoldable<'tcx> for Operand<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for PlaceElem<'tcx> {
|
impl<'tcx> TypeFoldable<'tcx> for PlaceElem<'tcx> {
|
||||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
|
||||||
|
self,
|
||||||
|
folder: &mut F,
|
||||||
|
) -> Result<Self, F::Error> {
|
||||||
use crate::mir::ProjectionElem::*;
|
use crate::mir::ProjectionElem::*;
|
||||||
|
|
||||||
Ok(match self {
|
Ok(match self {
|
||||||
Deref => Deref,
|
Deref => Deref,
|
||||||
Field(f, ty) => Field(f, ty.fold_with(folder)?),
|
Field(f, ty) => Field(f, ty.try_fold_with(folder)?),
|
||||||
Index(v) => Index(v.fold_with(folder)?),
|
Index(v) => Index(v.try_fold_with(folder)?),
|
||||||
Downcast(symbol, variantidx) => Downcast(symbol, variantidx),
|
Downcast(symbol, variantidx) => Downcast(symbol, variantidx),
|
||||||
ConstantIndex { offset, min_length, from_end } => {
|
ConstantIndex { offset, min_length, from_end } => {
|
||||||
ConstantIndex { offset, min_length, from_end }
|
ConstantIndex { offset, min_length, from_end }
|
||||||
|
@ -319,7 +345,7 @@ impl<'tcx> TypeFoldable<'tcx> for PlaceElem<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for Field {
|
impl<'tcx> TypeFoldable<'tcx> for Field {
|
||||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> {
|
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> {
|
||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> {
|
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> {
|
||||||
|
@ -328,7 +354,7 @@ impl<'tcx> TypeFoldable<'tcx> for Field {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for GeneratorSavedLocal {
|
impl<'tcx> TypeFoldable<'tcx> for GeneratorSavedLocal {
|
||||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> {
|
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> {
|
||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> {
|
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> {
|
||||||
|
@ -337,7 +363,7 @@ impl<'tcx> TypeFoldable<'tcx> for GeneratorSavedLocal {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, R: Idx, C: Idx> TypeFoldable<'tcx> for BitMatrix<R, C> {
|
impl<'tcx, R: Idx, C: Idx> TypeFoldable<'tcx> for BitMatrix<R, C> {
|
||||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> {
|
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> {
|
||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> {
|
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> {
|
||||||
|
@ -346,11 +372,14 @@ impl<'tcx, R: Idx, C: Idx> TypeFoldable<'tcx> for BitMatrix<R, C> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for Constant<'tcx> {
|
impl<'tcx> TypeFoldable<'tcx> for Constant<'tcx> {
|
||||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
|
||||||
|
self,
|
||||||
|
folder: &mut F,
|
||||||
|
) -> Result<Self, F::Error> {
|
||||||
Ok(Constant {
|
Ok(Constant {
|
||||||
span: self.span,
|
span: self.span,
|
||||||
user_ty: self.user_ty.fold_with(folder)?,
|
user_ty: self.user_ty.try_fold_with(folder)?,
|
||||||
literal: self.literal.fold_with(folder)?,
|
literal: self.literal.try_fold_with(folder)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
||||||
|
@ -361,14 +390,17 @@ impl<'tcx> TypeFoldable<'tcx> for Constant<'tcx> {
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for ConstantKind<'tcx> {
|
impl<'tcx> TypeFoldable<'tcx> for ConstantKind<'tcx> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||||
folder.fold_mir_const(self)
|
folder.try_fold_mir_const(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
|
||||||
|
self,
|
||||||
|
folder: &mut F,
|
||||||
|
) -> Result<Self, F::Error> {
|
||||||
match self {
|
match self {
|
||||||
ConstantKind::Ty(c) => Ok(ConstantKind::Ty(c.fold_with(folder)?)),
|
ConstantKind::Ty(c) => Ok(ConstantKind::Ty(c.try_fold_with(folder)?)),
|
||||||
ConstantKind::Val(v, t) => Ok(ConstantKind::Val(v, t.fold_with(folder)?)),
|
ConstantKind::Val(v, t) => Ok(ConstantKind::Val(v, t.try_fold_with(folder)?)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ pub(super) fn provide(providers: &mut ty::query::Providers) {
|
||||||
fn erase_regions_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
|
fn erase_regions_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
// N.B., use `super_fold_with` here. If we used `fold_with`, it
|
// N.B., use `super_fold_with` here. If we used `fold_with`, it
|
||||||
// could invoke the `erase_regions_ty` query recursively.
|
// could invoke the `erase_regions_ty` query recursively.
|
||||||
ty.super_fold_with(&mut RegionEraserVisitor { tcx }).into_ok()
|
ty.super_fold_with(&mut RegionEraserVisitor { tcx })
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TyCtxt<'tcx> {
|
impl<'tcx> TyCtxt<'tcx> {
|
||||||
|
@ -27,7 +27,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
debug!("erase_regions({:?})", value);
|
debug!("erase_regions({:?})", value);
|
||||||
let value1 = value.fold_with(&mut RegionEraserVisitor { tcx: self }).into_ok();
|
let value1 = value.fold_with(&mut RegionEraserVisitor { tcx: self });
|
||||||
debug!("erase_regions = {:?}", value1);
|
debug!("erase_regions = {:?}", value1);
|
||||||
value1
|
value1
|
||||||
}
|
}
|
||||||
|
@ -42,11 +42,11 @@ impl TypeFolder<'tcx> for RegionEraserVisitor<'tcx> {
|
||||||
self.tcx
|
self.tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
if ty.needs_infer() { ty.super_fold_with(self) } else { Ok(self.tcx.erase_regions_ty(ty)) }
|
if ty.needs_infer() { ty.super_fold_with(self) } else { self.tcx.erase_regions_ty(ty) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_binder<T>(&mut self, t: ty::Binder<'tcx, T>) -> Result<ty::Binder<'tcx, T>, Self::Error>
|
fn fold_binder<T>(&mut self, t: ty::Binder<'tcx, T>) -> ty::Binder<'tcx, T>
|
||||||
where
|
where
|
||||||
T: TypeFoldable<'tcx>,
|
T: TypeFoldable<'tcx>,
|
||||||
{
|
{
|
||||||
|
@ -54,7 +54,7 @@ impl TypeFolder<'tcx> for RegionEraserVisitor<'tcx> {
|
||||||
u.super_fold_with(self)
|
u.super_fold_with(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||||
// because late-bound regions affect subtyping, we can't
|
// because late-bound regions affect subtyping, we can't
|
||||||
// erase the bound/free distinction, but we can replace
|
// erase the bound/free distinction, but we can replace
|
||||||
// all free regions with 'erased.
|
// all free regions with 'erased.
|
||||||
|
@ -64,15 +64,12 @@ impl TypeFolder<'tcx> for RegionEraserVisitor<'tcx> {
|
||||||
// away. In codegen, they will always be erased to 'erased
|
// away. In codegen, they will always be erased to 'erased
|
||||||
// whenever a substitution occurs.
|
// whenever a substitution occurs.
|
||||||
match *r {
|
match *r {
|
||||||
ty::ReLateBound(..) => Ok(r),
|
ty::ReLateBound(..) => r,
|
||||||
_ => Ok(self.tcx.lifetimes.re_erased),
|
_ => self.tcx.lifetimes.re_erased,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_mir_const(
|
fn fold_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> {
|
||||||
&mut self,
|
|
||||||
c: mir::ConstantKind<'tcx>,
|
|
||||||
) -> Result<mir::ConstantKind<'tcx>, Self::Error> {
|
|
||||||
c.super_fold_with(self)
|
c.super_fold_with(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,9 +46,30 @@ use std::ops::ControlFlow;
|
||||||
///
|
///
|
||||||
/// To implement this conveniently, use the derive macro located in `rustc_macros`.
|
/// To implement this conveniently, use the derive macro located in `rustc_macros`.
|
||||||
pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
|
pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
|
||||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error>;
|
/// Consumers may find this more convenient to use with infallible folders than
|
||||||
fn fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
/// [`try_super_fold_with`][`TypeFoldable::try_super_fold_with`], to which the
|
||||||
self.super_fold_with(folder)
|
/// provided default definition delegates. Implementors **should not** override
|
||||||
|
/// this provided default definition, to ensure that the two methods are coherent
|
||||||
|
/// (provide a definition of `try_super_fold_with` instead).
|
||||||
|
fn super_fold_with<F: TypeFolder<'tcx, Error = !>>(self, folder: &mut F) -> Self {
|
||||||
|
self.try_super_fold_with(folder).into_ok()
|
||||||
|
}
|
||||||
|
/// Consumers may find this more convenient to use with infallible folders than
|
||||||
|
/// [`try_fold_with`][`TypeFoldable::try_fold_with`], to which the provided
|
||||||
|
/// default definition delegates. Implementors **should not** override this
|
||||||
|
/// provided default definition, to ensure that the two methods are coherent
|
||||||
|
/// (provide a definition of `try_fold_with` instead).
|
||||||
|
fn fold_with<F: TypeFolder<'tcx, Error = !>>(self, folder: &mut F) -> Self {
|
||||||
|
self.try_fold_with(folder).into_ok()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
|
||||||
|
self,
|
||||||
|
folder: &mut F,
|
||||||
|
) -> Result<Self, F::Error>;
|
||||||
|
|
||||||
|
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||||
|
self.try_super_fold_with(folder)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy>;
|
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy>;
|
||||||
|
@ -179,7 +200,7 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TypeFoldable<'tcx> for hir::Constness {
|
impl TypeFoldable<'tcx> for hir::Constness {
|
||||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> {
|
fn try_super_fold_with<F: TypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> {
|
||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> {
|
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> {
|
||||||
|
@ -192,41 +213,102 @@ impl TypeFoldable<'tcx> for hir::Constness {
|
||||||
/// default implementation that does an "identity" fold. Within each
|
/// default implementation that does an "identity" fold. Within each
|
||||||
/// identity fold, it should invoke `foo.fold_with(self)` to fold each
|
/// identity fold, it should invoke `foo.fold_with(self)` to fold each
|
||||||
/// sub-item.
|
/// sub-item.
|
||||||
|
///
|
||||||
|
/// If this folder is fallible (and therefore its [`Error`][`TypeFolder::Error`]
|
||||||
|
/// associated type is something other than the default, never),
|
||||||
|
/// [`FallibleTypeFolder`] should be implemented manually; otherwise,
|
||||||
|
/// a blanket implementation of [`FallibleTypeFolder`] will defer to
|
||||||
|
/// the infallible methods of this trait to ensure that the two APIs
|
||||||
|
/// are coherent.
|
||||||
pub trait TypeFolder<'tcx>: Sized {
|
pub trait TypeFolder<'tcx>: Sized {
|
||||||
type Error = !;
|
type Error = !;
|
||||||
|
|
||||||
fn tcx<'a>(&'a self) -> TyCtxt<'tcx>;
|
fn tcx<'a>(&'a self) -> TyCtxt<'tcx>;
|
||||||
|
|
||||||
fn fold_binder<T>(&mut self, t: Binder<'tcx, T>) -> Result<Binder<'tcx, T>, Self::Error>
|
fn fold_binder<T>(&mut self, t: Binder<'tcx, T>) -> Binder<'tcx, T>
|
||||||
where
|
where
|
||||||
T: TypeFoldable<'tcx>,
|
T: TypeFoldable<'tcx>,
|
||||||
|
Self: TypeFolder<'tcx, Error = !>,
|
||||||
{
|
{
|
||||||
t.super_fold_with(self)
|
t.super_fold_with(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx>
|
||||||
|
where
|
||||||
|
Self: TypeFolder<'tcx, Error = !>,
|
||||||
|
{
|
||||||
t.super_fold_with(self)
|
t.super_fold_with(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx>
|
||||||
|
where
|
||||||
|
Self: TypeFolder<'tcx, Error = !>,
|
||||||
|
{
|
||||||
r.super_fold_with(self)
|
r.super_fold_with(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_const(
|
fn fold_const(&mut self, c: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx>
|
||||||
&mut self,
|
where
|
||||||
c: &'tcx ty::Const<'tcx>,
|
Self: TypeFolder<'tcx, Error = !>,
|
||||||
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
|
{
|
||||||
c.super_fold_with(self)
|
c.super_fold_with(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_predicate(
|
fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx>
|
||||||
&mut self,
|
where
|
||||||
p: ty::Predicate<'tcx>,
|
Self: TypeFolder<'tcx, Error = !>,
|
||||||
) -> Result<ty::Predicate<'tcx>, Self::Error> {
|
{
|
||||||
p.super_fold_with(self)
|
p.super_fold_with(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_mir_const(
|
fn fold_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx>
|
||||||
|
where
|
||||||
|
Self: TypeFolder<'tcx, Error = !>,
|
||||||
|
{
|
||||||
|
bug!("most type folders should not be folding MIR datastructures: {:?}", c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The `FallibleTypeFolder` trait defines the actual *folding*. There is a
|
||||||
|
/// method defined for every foldable type. Each of these has a
|
||||||
|
/// default implementation that does an "identity" fold. Within each
|
||||||
|
/// identity fold, it should invoke `foo.try_fold_with(self)` to fold each
|
||||||
|
/// sub-item.
|
||||||
|
///
|
||||||
|
/// A blanket implementation of this trait (that defers to the relevant
|
||||||
|
/// method of [`TypeFolder`]) is provided for all infallible folders in
|
||||||
|
/// order to ensure the two APIs are coherent.
|
||||||
|
pub trait FallibleTypeFolder<'tcx>: TypeFolder<'tcx> {
|
||||||
|
fn try_fold_binder<T>(&mut self, t: Binder<'tcx, T>) -> Result<Binder<'tcx, T>, Self::Error>
|
||||||
|
where
|
||||||
|
T: TypeFoldable<'tcx>,
|
||||||
|
{
|
||||||
|
t.try_super_fold_with(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn try_fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||||
|
t.try_super_fold_with(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn try_fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
||||||
|
r.try_super_fold_with(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn try_fold_const(
|
||||||
|
&mut self,
|
||||||
|
c: &'tcx ty::Const<'tcx>,
|
||||||
|
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
|
||||||
|
c.try_super_fold_with(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn try_fold_predicate(
|
||||||
|
&mut self,
|
||||||
|
p: ty::Predicate<'tcx>,
|
||||||
|
) -> Result<ty::Predicate<'tcx>, Self::Error> {
|
||||||
|
p.try_super_fold_with(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn try_fold_mir_const(
|
||||||
&mut self,
|
&mut self,
|
||||||
c: mir::ConstantKind<'tcx>,
|
c: mir::ConstantKind<'tcx>,
|
||||||
) -> Result<mir::ConstantKind<'tcx>, Self::Error> {
|
) -> Result<mir::ConstantKind<'tcx>, Self::Error> {
|
||||||
|
@ -234,6 +316,49 @@ pub trait TypeFolder<'tcx>: Sized {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Blanket implementation of fallible trait for infallible folders
|
||||||
|
// delegates to infallible methods to prevent incoherence
|
||||||
|
impl<'tcx, F> FallibleTypeFolder<'tcx> for F
|
||||||
|
where
|
||||||
|
F: TypeFolder<'tcx, Error = !>,
|
||||||
|
{
|
||||||
|
fn try_fold_binder<T>(&mut self, t: Binder<'tcx, T>) -> Result<Binder<'tcx, T>, Self::Error>
|
||||||
|
where
|
||||||
|
T: TypeFoldable<'tcx>,
|
||||||
|
{
|
||||||
|
Ok(self.fold_binder(t))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn try_fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||||
|
Ok(self.fold_ty(t))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn try_fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
||||||
|
Ok(self.fold_region(r))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn try_fold_const(
|
||||||
|
&mut self,
|
||||||
|
c: &'tcx ty::Const<'tcx>,
|
||||||
|
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
|
||||||
|
Ok(self.fold_const(c))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn try_fold_predicate(
|
||||||
|
&mut self,
|
||||||
|
p: ty::Predicate<'tcx>,
|
||||||
|
) -> Result<ty::Predicate<'tcx>, Self::Error> {
|
||||||
|
Ok(self.fold_predicate(p))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn try_fold_mir_const(
|
||||||
|
&mut self,
|
||||||
|
c: mir::ConstantKind<'tcx>,
|
||||||
|
) -> Result<mir::ConstantKind<'tcx>, Self::Error> {
|
||||||
|
Ok(self.fold_mir_const(c))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub trait TypeVisitor<'tcx>: Sized {
|
pub trait TypeVisitor<'tcx>: Sized {
|
||||||
type BreakTy = !;
|
type BreakTy = !;
|
||||||
/// Supplies the `tcx` for an unevaluated anonymous constant in case its default substs
|
/// Supplies the `tcx` for an unevaluated anonymous constant in case its default substs
|
||||||
|
@ -301,22 +426,19 @@ where
|
||||||
self.tcx
|
self.tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
let t = ty.super_fold_with(self)?;
|
let t = ty.super_fold_with(self);
|
||||||
Ok((self.ty_op)(t))
|
(self.ty_op)(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||||
let r = r.super_fold_with(self)?;
|
let r = r.super_fold_with(self);
|
||||||
Ok((self.lt_op)(r))
|
(self.lt_op)(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_const(
|
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||||
&mut self,
|
let ct = ct.super_fold_with(self);
|
||||||
ct: &'tcx ty::Const<'tcx>,
|
(self.ct_op)(ct)
|
||||||
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
|
|
||||||
let ct = ct.super_fold_with(self)?;
|
|
||||||
Ok((self.ct_op)(ct))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -336,7 +458,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
where
|
where
|
||||||
T: TypeFoldable<'tcx>,
|
T: TypeFoldable<'tcx>,
|
||||||
{
|
{
|
||||||
value.fold_with(&mut RegionFolder::new(self, skipped_regions, &mut f)).into_ok()
|
value.fold_with(&mut RegionFolder::new(self, skipped_regions, &mut f))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Invoke `callback` on every region appearing free in `value`.
|
/// Invoke `callback` on every region appearing free in `value`.
|
||||||
|
@ -484,7 +606,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for RegionFolder<'a, 'tcx> {
|
||||||
fn fold_binder<T: TypeFoldable<'tcx>>(
|
fn fold_binder<T: TypeFoldable<'tcx>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
t: ty::Binder<'tcx, T>,
|
t: ty::Binder<'tcx, T>,
|
||||||
) -> Result<ty::Binder<'tcx, T>, Self::Error> {
|
) -> ty::Binder<'tcx, T> {
|
||||||
self.current_index.shift_in(1);
|
self.current_index.shift_in(1);
|
||||||
let t = t.super_fold_with(self);
|
let t = t.super_fold_with(self);
|
||||||
self.current_index.shift_out(1);
|
self.current_index.shift_out(1);
|
||||||
|
@ -492,16 +614,16 @@ impl<'a, 'tcx> TypeFolder<'tcx> for RegionFolder<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip(self), level = "debug")]
|
#[instrument(skip(self), level = "debug")]
|
||||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||||
match *r {
|
match *r {
|
||||||
ty::ReLateBound(debruijn, _) if debruijn < self.current_index => {
|
ty::ReLateBound(debruijn, _) if debruijn < self.current_index => {
|
||||||
debug!(?self.current_index, "skipped bound region");
|
debug!(?self.current_index, "skipped bound region");
|
||||||
*self.skipped_regions = true;
|
*self.skipped_regions = true;
|
||||||
Ok(r)
|
r
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
debug!(?self.current_index, "folding free region");
|
debug!(?self.current_index, "folding free region");
|
||||||
Ok((self.fold_region_fn)(r, self.current_index))
|
(self.fold_region_fn)(r, self.current_index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -542,19 +664,19 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> {
|
||||||
fn fold_binder<T: TypeFoldable<'tcx>>(
|
fn fold_binder<T: TypeFoldable<'tcx>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
t: ty::Binder<'tcx, T>,
|
t: ty::Binder<'tcx, T>,
|
||||||
) -> Result<ty::Binder<'tcx, T>, Self::Error> {
|
) -> ty::Binder<'tcx, T> {
|
||||||
self.current_index.shift_in(1);
|
self.current_index.shift_in(1);
|
||||||
let t = t.super_fold_with(self);
|
let t = t.super_fold_with(self);
|
||||||
self.current_index.shift_out(1);
|
self.current_index.shift_out(1);
|
||||||
t
|
t
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
match *t.kind() {
|
match *t.kind() {
|
||||||
ty::Bound(debruijn, bound_ty) if debruijn == self.current_index => {
|
ty::Bound(debruijn, bound_ty) if debruijn == self.current_index => {
|
||||||
if let Some(fld_t) = self.fld_t.as_mut() {
|
if let Some(fld_t) = self.fld_t.as_mut() {
|
||||||
let ty = fld_t(bound_ty);
|
let ty = fld_t(bound_ty);
|
||||||
return Ok(ty::fold::shift_vars(self.tcx, &ty, self.current_index.as_u32()));
|
return ty::fold::shift_vars(self.tcx, &ty, self.current_index.as_u32());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ if t.has_vars_bound_at_or_above(self.current_index) => {
|
_ if t.has_vars_bound_at_or_above(self.current_index) => {
|
||||||
|
@ -562,10 +684,10 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
Ok(t)
|
t
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||||
match *r {
|
match *r {
|
||||||
ty::ReLateBound(debruijn, br) if debruijn == self.current_index => {
|
ty::ReLateBound(debruijn, br) if debruijn == self.current_index => {
|
||||||
if let Some(fld_r) = self.fld_r.as_mut() {
|
if let Some(fld_r) = self.fld_r.as_mut() {
|
||||||
|
@ -576,28 +698,25 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> {
|
||||||
// debruijn index. Then we adjust it to the
|
// debruijn index. Then we adjust it to the
|
||||||
// correct depth.
|
// correct depth.
|
||||||
assert_eq!(debruijn1, ty::INNERMOST);
|
assert_eq!(debruijn1, ty::INNERMOST);
|
||||||
Ok(self.tcx.mk_region(ty::ReLateBound(debruijn, br)))
|
self.tcx.mk_region(ty::ReLateBound(debruijn, br))
|
||||||
} else {
|
} else {
|
||||||
Ok(region)
|
region
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
Ok(r)
|
r
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_const(
|
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||||
&mut self,
|
|
||||||
ct: &'tcx ty::Const<'tcx>,
|
|
||||||
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
|
|
||||||
match *ct {
|
match *ct {
|
||||||
ty::Const { val: ty::ConstKind::Bound(debruijn, bound_const), ty }
|
ty::Const { val: ty::ConstKind::Bound(debruijn, bound_const), ty }
|
||||||
if debruijn == self.current_index =>
|
if debruijn == self.current_index =>
|
||||||
{
|
{
|
||||||
if let Some(fld_c) = self.fld_c.as_mut() {
|
if let Some(fld_c) = self.fld_c.as_mut() {
|
||||||
let ct = fld_c(bound_const, ty);
|
let ct = fld_c(bound_const, ty);
|
||||||
return Ok(ty::fold::shift_vars(self.tcx, &ct, self.current_index.as_u32()));
|
return ty::fold::shift_vars(self.tcx, &ct, self.current_index.as_u32());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ if ct.has_vars_bound_at_or_above(self.current_index) => {
|
_ if ct.has_vars_bound_at_or_above(self.current_index) => {
|
||||||
|
@ -605,7 +724,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
Ok(ct)
|
ct
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -638,7 +757,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
value
|
value
|
||||||
} else {
|
} else {
|
||||||
let mut replacer = BoundVarReplacer::new(self, Some(&mut real_fld_r), None, None);
|
let mut replacer = BoundVarReplacer::new(self, Some(&mut real_fld_r), None, None);
|
||||||
value.fold_with(&mut replacer).into_ok()
|
value.fold_with(&mut replacer)
|
||||||
};
|
};
|
||||||
(value, region_map)
|
(value, region_map)
|
||||||
}
|
}
|
||||||
|
@ -664,7 +783,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
} else {
|
} else {
|
||||||
let mut replacer =
|
let mut replacer =
|
||||||
BoundVarReplacer::new(self, Some(&mut fld_r), Some(&mut fld_t), Some(&mut fld_c));
|
BoundVarReplacer::new(self, Some(&mut fld_r), Some(&mut fld_t), Some(&mut fld_c));
|
||||||
value.fold_with(&mut replacer).into_ok()
|
value.fold_with(&mut replacer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -955,36 +1074,36 @@ impl TypeFolder<'tcx> for Shifter<'tcx> {
|
||||||
fn fold_binder<T: TypeFoldable<'tcx>>(
|
fn fold_binder<T: TypeFoldable<'tcx>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
t: ty::Binder<'tcx, T>,
|
t: ty::Binder<'tcx, T>,
|
||||||
) -> Result<ty::Binder<'tcx, T>, Self::Error> {
|
) -> ty::Binder<'tcx, T> {
|
||||||
self.current_index.shift_in(1);
|
self.current_index.shift_in(1);
|
||||||
let t = t.super_fold_with(self);
|
let t = t.super_fold_with(self);
|
||||||
self.current_index.shift_out(1);
|
self.current_index.shift_out(1);
|
||||||
t
|
t
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||||
match *r {
|
match *r {
|
||||||
ty::ReLateBound(debruijn, br) => {
|
ty::ReLateBound(debruijn, br) => {
|
||||||
if self.amount == 0 || debruijn < self.current_index {
|
if self.amount == 0 || debruijn < self.current_index {
|
||||||
Ok(r)
|
r
|
||||||
} else {
|
} else {
|
||||||
let debruijn = debruijn.shifted_in(self.amount);
|
let debruijn = debruijn.shifted_in(self.amount);
|
||||||
let shifted = ty::ReLateBound(debruijn, br);
|
let shifted = ty::ReLateBound(debruijn, br);
|
||||||
Ok(self.tcx.mk_region(shifted))
|
self.tcx.mk_region(shifted)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => Ok(r),
|
_ => r,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
match *ty.kind() {
|
match *ty.kind() {
|
||||||
ty::Bound(debruijn, bound_ty) => {
|
ty::Bound(debruijn, bound_ty) => {
|
||||||
if self.amount == 0 || debruijn < self.current_index {
|
if self.amount == 0 || debruijn < self.current_index {
|
||||||
Ok(ty)
|
ty
|
||||||
} else {
|
} else {
|
||||||
let debruijn = debruijn.shifted_in(self.amount);
|
let debruijn = debruijn.shifted_in(self.amount);
|
||||||
Ok(self.tcx.mk_ty(ty::Bound(debruijn, bound_ty)))
|
self.tcx.mk_ty(ty::Bound(debruijn, bound_ty))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -992,18 +1111,13 @@ impl TypeFolder<'tcx> for Shifter<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_const(
|
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||||
&mut self,
|
|
||||||
ct: &'tcx ty::Const<'tcx>,
|
|
||||||
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
|
|
||||||
if let ty::Const { val: ty::ConstKind::Bound(debruijn, bound_ct), ty } = *ct {
|
if let ty::Const { val: ty::ConstKind::Bound(debruijn, bound_ct), ty } = *ct {
|
||||||
if self.amount == 0 || debruijn < self.current_index {
|
if self.amount == 0 || debruijn < self.current_index {
|
||||||
Ok(ct)
|
ct
|
||||||
} else {
|
} else {
|
||||||
let debruijn = debruijn.shifted_in(self.amount);
|
let debruijn = debruijn.shifted_in(self.amount);
|
||||||
Ok(self
|
self.tcx.mk_const(ty::Const { val: ty::ConstKind::Bound(debruijn, bound_ct), ty })
|
||||||
.tcx
|
|
||||||
.mk_const(ty::Const { val: ty::ConstKind::Bound(debruijn, bound_ct), ty }))
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ct.super_fold_with(self)
|
ct.super_fold_with(self)
|
||||||
|
@ -1030,7 +1144,7 @@ where
|
||||||
{
|
{
|
||||||
debug!("shift_vars(value={:?}, amount={})", value, amount);
|
debug!("shift_vars(value={:?}, amount={})", value, amount);
|
||||||
|
|
||||||
value.fold_with(&mut Shifter::new(tcx, amount)).into_ok()
|
value.fold_with(&mut Shifter::new(tcx, amount))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||||
|
@ -1293,7 +1407,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
///
|
///
|
||||||
/// FIXME(@lcnr): explain this function a bit more
|
/// FIXME(@lcnr): explain this function a bit more
|
||||||
pub fn expose_default_const_substs<T: TypeFoldable<'tcx>>(self, v: T) -> T {
|
pub fn expose_default_const_substs<T: TypeFoldable<'tcx>>(self, v: T) -> T {
|
||||||
v.fold_with(&mut ExposeDefaultConstSubstsFolder { tcx: self }).into_ok()
|
v.fold_with(&mut ExposeDefaultConstSubstsFolder { tcx: self })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1306,22 +1420,19 @@ impl<'tcx> TypeFolder<'tcx> for ExposeDefaultConstSubstsFolder<'tcx> {
|
||||||
self.tcx
|
self.tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
if ty.flags().intersects(TypeFlags::HAS_UNKNOWN_DEFAULT_CONST_SUBSTS) {
|
if ty.flags().intersects(TypeFlags::HAS_UNKNOWN_DEFAULT_CONST_SUBSTS) {
|
||||||
ty.super_fold_with(self)
|
ty.super_fold_with(self)
|
||||||
} else {
|
} else {
|
||||||
Ok(ty)
|
ty
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_predicate(
|
fn fold_predicate(&mut self, pred: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> {
|
||||||
&mut self,
|
|
||||||
pred: ty::Predicate<'tcx>,
|
|
||||||
) -> Result<ty::Predicate<'tcx>, Self::Error> {
|
|
||||||
if pred.inner.flags.intersects(TypeFlags::HAS_UNKNOWN_DEFAULT_CONST_SUBSTS) {
|
if pred.inner.flags.intersects(TypeFlags::HAS_UNKNOWN_DEFAULT_CONST_SUBSTS) {
|
||||||
pred.super_fold_with(self)
|
pred.super_fold_with(self)
|
||||||
} else {
|
} else {
|
||||||
Ok(pred)
|
pred
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -622,7 +622,7 @@ fn polymorphize<'tcx>(
|
||||||
self.tcx
|
self.tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
debug!("fold_ty: ty={:?}", ty);
|
debug!("fold_ty: ty={:?}", ty);
|
||||||
match ty.kind {
|
match ty.kind {
|
||||||
ty::Closure(def_id, substs) => {
|
ty::Closure(def_id, substs) => {
|
||||||
|
@ -631,11 +631,11 @@ fn polymorphize<'tcx>(
|
||||||
ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id)),
|
ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id)),
|
||||||
substs,
|
substs,
|
||||||
);
|
);
|
||||||
Ok(if substs == polymorphized_substs {
|
if substs == polymorphized_substs {
|
||||||
ty
|
ty
|
||||||
} else {
|
} else {
|
||||||
self.tcx.mk_closure(def_id, polymorphized_substs)
|
self.tcx.mk_closure(def_id, polymorphized_substs)
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
ty::Generator(def_id, substs, movability) => {
|
ty::Generator(def_id, substs, movability) => {
|
||||||
let polymorphized_substs = polymorphize(
|
let polymorphized_substs = polymorphize(
|
||||||
|
@ -643,11 +643,11 @@ fn polymorphize<'tcx>(
|
||||||
ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id)),
|
ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id)),
|
||||||
substs,
|
substs,
|
||||||
);
|
);
|
||||||
Ok(if substs == polymorphized_substs {
|
if substs == polymorphized_substs {
|
||||||
ty
|
ty
|
||||||
} else {
|
} else {
|
||||||
self.tcx.mk_generator(def_id, polymorphized_substs, movability)
|
self.tcx.mk_generator(def_id, polymorphized_substs, movability)
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
_ => ty.super_fold_with(self),
|
_ => ty.super_fold_with(self),
|
||||||
}
|
}
|
||||||
|
@ -669,7 +669,7 @@ fn polymorphize<'tcx>(
|
||||||
// ..and polymorphize any closures/generators captured as upvars.
|
// ..and polymorphize any closures/generators captured as upvars.
|
||||||
let upvars_ty = upvars_ty.unwrap();
|
let upvars_ty = upvars_ty.unwrap();
|
||||||
let polymorphized_upvars_ty = upvars_ty.fold_with(
|
let polymorphized_upvars_ty = upvars_ty.fold_with(
|
||||||
&mut PolymorphizationFolder { tcx }).into_ok();
|
&mut PolymorphizationFolder { tcx });
|
||||||
debug!("polymorphize: polymorphized_upvars_ty={:?}", polymorphized_upvars_ty);
|
debug!("polymorphize: polymorphized_upvars_ty={:?}", polymorphized_upvars_ty);
|
||||||
ty::GenericArg::from(polymorphized_upvars_ty)
|
ty::GenericArg::from(polymorphized_upvars_ty)
|
||||||
},
|
},
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
//!
|
//!
|
||||||
//! ["The `ty` module: representing types"]: https://rustc-dev-guide.rust-lang.org/ty.html
|
//! ["The `ty` module: representing types"]: https://rustc-dev-guide.rust-lang.org/ty.html
|
||||||
|
|
||||||
pub use self::fold::{TypeFoldable, TypeFolder, TypeVisitor};
|
pub use self::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeVisitor};
|
||||||
pub use self::AssocItemContainer::*;
|
pub use self::AssocItemContainer::*;
|
||||||
pub use self::BorrowKind::*;
|
pub use self::BorrowKind::*;
|
||||||
pub use self::IntVarValue::*;
|
pub use self::IntVarValue::*;
|
||||||
|
@ -1269,14 +1269,14 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ParamEnv<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for ParamEnv<'tcx> {
|
impl<'tcx> TypeFoldable<'tcx> for ParamEnv<'tcx> {
|
||||||
fn super_fold_with<F: ty::fold::TypeFolder<'tcx>>(
|
fn try_super_fold_with<F: ty::fold::FallibleTypeFolder<'tcx>>(
|
||||||
self,
|
self,
|
||||||
folder: &mut F,
|
folder: &mut F,
|
||||||
) -> Result<Self, F::Error> {
|
) -> Result<Self, F::Error> {
|
||||||
Ok(ParamEnv::new(
|
Ok(ParamEnv::new(
|
||||||
self.caller_bounds().fold_with(folder)?,
|
self.caller_bounds().try_fold_with(folder)?,
|
||||||
self.reveal().fold_with(folder)?,
|
self.reveal().try_fold_with(folder)?,
|
||||||
self.constness().fold_with(folder)?,
|
self.constness().try_fold_with(folder)?,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
use crate::mir;
|
use crate::mir;
|
||||||
use crate::traits::query::NoSolution;
|
use crate::traits::query::NoSolution;
|
||||||
use crate::ty::fold::{TypeFoldable, TypeFolder};
|
use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder};
|
||||||
use crate::ty::subst::{Subst, SubstsRef};
|
use crate::ty::subst::{Subst, SubstsRef};
|
||||||
use crate::ty::{self, Ty, TyCtxt};
|
use crate::ty::{self, Ty, TyCtxt};
|
||||||
|
|
||||||
|
@ -55,9 +55,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
if !value.has_projections() {
|
if !value.has_projections() {
|
||||||
value
|
value
|
||||||
} else {
|
} else {
|
||||||
value
|
value.fold_with(&mut NormalizeAfterErasingRegionsFolder { tcx: self, param_env })
|
||||||
.fold_with(&mut NormalizeAfterErasingRegionsFolder { tcx: self, param_env })
|
|
||||||
.into_ok()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +88,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
Ok(value)
|
Ok(value)
|
||||||
} else {
|
} else {
|
||||||
let mut folder = TryNormalizeAfterErasingRegionsFolder::new(self, param_env);
|
let mut folder = TryNormalizeAfterErasingRegionsFolder::new(self, param_env);
|
||||||
value.fold_with(&mut folder)
|
value.try_fold_with(&mut folder)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,25 +159,19 @@ impl TypeFolder<'tcx> for NormalizeAfterErasingRegionsFolder<'tcx> {
|
||||||
self.tcx
|
self.tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
Ok(self.normalize_generic_arg_after_erasing_regions(ty.into()).expect_ty())
|
self.normalize_generic_arg_after_erasing_regions(ty.into()).expect_ty()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_const(
|
fn fold_const(&mut self, c: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||||
&mut self,
|
self.normalize_generic_arg_after_erasing_regions(c.into()).expect_const()
|
||||||
c: &'tcx ty::Const<'tcx>,
|
|
||||||
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
|
|
||||||
Ok(self.normalize_generic_arg_after_erasing_regions(c.into()).expect_const())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn fold_mir_const(
|
fn fold_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> {
|
||||||
&mut self,
|
|
||||||
c: mir::ConstantKind<'tcx>,
|
|
||||||
) -> Result<mir::ConstantKind<'tcx>, Self::Error> {
|
|
||||||
// FIXME: This *probably* needs canonicalization too!
|
// FIXME: This *probably* needs canonicalization too!
|
||||||
let arg = self.param_env.and(c);
|
let arg = self.param_env.and(c);
|
||||||
Ok(self.tcx.normalize_mir_const_after_erasing_regions(arg))
|
self.tcx.normalize_mir_const_after_erasing_regions(arg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,15 +203,17 @@ impl TypeFolder<'tcx> for TryNormalizeAfterErasingRegionsFolder<'tcx> {
|
||||||
fn tcx(&self) -> TyCtxt<'tcx> {
|
fn tcx(&self) -> TyCtxt<'tcx> {
|
||||||
self.tcx
|
self.tcx
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
impl FallibleTypeFolder<'tcx> for TryNormalizeAfterErasingRegionsFolder<'tcx> {
|
||||||
|
fn try_fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||||
match self.try_normalize_generic_arg_after_erasing_regions(ty.into()) {
|
match self.try_normalize_generic_arg_after_erasing_regions(ty.into()) {
|
||||||
Ok(t) => Ok(t.expect_ty()),
|
Ok(t) => Ok(t.expect_ty()),
|
||||||
Err(_) => Err(NormalizationError::Type(ty)),
|
Err(_) => Err(NormalizationError::Type(ty)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_const(
|
fn try_fold_const(
|
||||||
&mut self,
|
&mut self,
|
||||||
c: &'tcx ty::Const<'tcx>,
|
c: &'tcx ty::Const<'tcx>,
|
||||||
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
|
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
|
||||||
|
@ -229,7 +223,7 @@ impl TypeFolder<'tcx> for TryNormalizeAfterErasingRegionsFolder<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_mir_const(
|
fn try_fold_mir_const(
|
||||||
&mut self,
|
&mut self,
|
||||||
c: mir::ConstantKind<'tcx>,
|
c: mir::ConstantKind<'tcx>,
|
||||||
) -> Result<mir::ConstantKind<'tcx>, Self::Error> {
|
) -> Result<mir::ConstantKind<'tcx>, Self::Error> {
|
||||||
|
|
|
@ -2016,24 +2016,24 @@ impl<'a, 'tcx> ty::TypeFolder<'tcx> for RegionFolder<'a, 'tcx> {
|
||||||
fn fold_binder<T: TypeFoldable<'tcx>>(
|
fn fold_binder<T: TypeFoldable<'tcx>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
t: ty::Binder<'tcx, T>,
|
t: ty::Binder<'tcx, T>,
|
||||||
) -> Result<ty::Binder<'tcx, T>, Self::Error> {
|
) -> ty::Binder<'tcx, T> {
|
||||||
self.current_index.shift_in(1);
|
self.current_index.shift_in(1);
|
||||||
let t = t.super_fold_with(self);
|
let t = t.super_fold_with(self);
|
||||||
self.current_index.shift_out(1);
|
self.current_index.shift_out(1);
|
||||||
t
|
t
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
match *t.kind() {
|
match *t.kind() {
|
||||||
_ if t.has_vars_bound_at_or_above(self.current_index) || t.has_placeholders() => {
|
_ if t.has_vars_bound_at_or_above(self.current_index) || t.has_placeholders() => {
|
||||||
return t.super_fold_with(self);
|
return t.super_fold_with(self);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
Ok(t)
|
t
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||||
let name = &mut self.name;
|
let name = &mut self.name;
|
||||||
let region = match *r {
|
let region = match *r {
|
||||||
ty::ReLateBound(_, br) => self.region_map.entry(br).or_insert_with(|| name(br)),
|
ty::ReLateBound(_, br) => self.region_map.entry(br).or_insert_with(|| name(br)),
|
||||||
|
@ -2049,13 +2049,13 @@ impl<'a, 'tcx> ty::TypeFolder<'tcx> for RegionFolder<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => return Ok(r),
|
_ => return r,
|
||||||
};
|
};
|
||||||
if let ty::ReLateBound(debruijn1, br) = *region {
|
if let ty::ReLateBound(debruijn1, br) = *region {
|
||||||
assert_eq!(debruijn1, ty::INNERMOST);
|
assert_eq!(debruijn1, ty::INNERMOST);
|
||||||
Ok(self.tcx.mk_region(ty::ReLateBound(self.current_index, br)))
|
self.tcx.mk_region(ty::ReLateBound(self.current_index, br))
|
||||||
} else {
|
} else {
|
||||||
Ok(region)
|
region
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2193,7 +2193,7 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
|
||||||
name: &mut name,
|
name: &mut name,
|
||||||
region_map: BTreeMap::new(),
|
region_map: BTreeMap::new(),
|
||||||
};
|
};
|
||||||
let new_value = value.clone().skip_binder().fold_with(&mut folder).into_ok();
|
let new_value = value.clone().skip_binder().fold_with(&mut folder);
|
||||||
let region_map = folder.region_map;
|
let region_map = folder.region_map;
|
||||||
start_or_continue(&mut self, "", "> ");
|
start_or_continue(&mut self, "", "> ");
|
||||||
(new_value, region_map)
|
(new_value, region_map)
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
use crate::mir::interpret;
|
use crate::mir::interpret;
|
||||||
use crate::mir::ProjectionKind;
|
use crate::mir::ProjectionKind;
|
||||||
use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
|
use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeVisitor};
|
||||||
use crate::ty::print::{with_no_trimmed_paths, FmtPrinter, Printer};
|
use crate::ty::print::{with_no_trimmed_paths, FmtPrinter, Printer};
|
||||||
use crate::ty::{self, InferConst, Lift, Ty, TyCtxt};
|
use crate::ty::{self, InferConst, Lift, Ty, TyCtxt};
|
||||||
use rustc_data_structures::functor::IdFunctor;
|
use rustc_data_structures::functor::IdFunctor;
|
||||||
|
@ -669,7 +669,10 @@ impl<'a, 'tcx> Lift<'tcx> for ty::InstanceDef<'a> {
|
||||||
|
|
||||||
/// AdtDefs are basically the same as a DefId.
|
/// AdtDefs are basically the same as a DefId.
|
||||||
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::AdtDef {
|
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::AdtDef {
|
||||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, _folder: &mut F) -> Result<Self, F::Error> {
|
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
|
||||||
|
self,
|
||||||
|
_folder: &mut F,
|
||||||
|
) -> Result<Self, F::Error> {
|
||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -679,8 +682,11 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::AdtDef {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, T: TypeFoldable<'tcx>, U: TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T, U) {
|
impl<'tcx, T: TypeFoldable<'tcx>, U: TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T, U) {
|
||||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<(T, U), F::Error> {
|
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
|
||||||
Ok((self.0.fold_with(folder)?, self.1.fold_with(folder)?))
|
self,
|
||||||
|
folder: &mut F,
|
||||||
|
) -> Result<(T, U), F::Error> {
|
||||||
|
Ok((self.0.try_fold_with(folder)?, self.1.try_fold_with(folder)?))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
||||||
|
@ -692,8 +698,15 @@ impl<'tcx, T: TypeFoldable<'tcx>, U: TypeFoldable<'tcx>> TypeFoldable<'tcx> for
|
||||||
impl<'tcx, A: TypeFoldable<'tcx>, B: TypeFoldable<'tcx>, C: TypeFoldable<'tcx>> TypeFoldable<'tcx>
|
impl<'tcx, A: TypeFoldable<'tcx>, B: TypeFoldable<'tcx>, C: TypeFoldable<'tcx>> TypeFoldable<'tcx>
|
||||||
for (A, B, C)
|
for (A, B, C)
|
||||||
{
|
{
|
||||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<(A, B, C), F::Error> {
|
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
|
||||||
Ok((self.0.fold_with(folder)?, self.1.fold_with(folder)?, self.2.fold_with(folder)?))
|
self,
|
||||||
|
folder: &mut F,
|
||||||
|
) -> Result<(A, B, C), F::Error> {
|
||||||
|
Ok((
|
||||||
|
self.0.try_fold_with(folder)?,
|
||||||
|
self.1.try_fold_with(folder)?,
|
||||||
|
self.2.try_fold_with(folder)?,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
||||||
|
@ -718,9 +731,12 @@ EnumTypeFoldableImpl! {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Rc<T> {
|
impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Rc<T> {
|
||||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
|
||||||
|
self,
|
||||||
|
folder: &mut F,
|
||||||
|
) -> Result<Self, F::Error> {
|
||||||
// FIXME: Reuse the `Rc` here.
|
// FIXME: Reuse the `Rc` here.
|
||||||
Ok(Rc::new((*self).clone().fold_with(folder)?))
|
(*self).clone().try_fold_with(folder).map(Rc::new)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
||||||
|
@ -729,9 +745,12 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Rc<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Arc<T> {
|
impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Arc<T> {
|
||||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
|
||||||
|
self,
|
||||||
|
folder: &mut F,
|
||||||
|
) -> Result<Self, F::Error> {
|
||||||
// FIXME: Reuse the `Arc` here.
|
// FIXME: Reuse the `Arc` here.
|
||||||
Ok(Arc::new((*self).clone().fold_with(folder)?))
|
(*self).clone().try_fold_with(folder).map(Arc::new)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
||||||
|
@ -740,8 +759,11 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Arc<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<T> {
|
impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<T> {
|
||||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
|
||||||
self.try_map_id(|value| value.fold_with(folder))
|
self,
|
||||||
|
folder: &mut F,
|
||||||
|
) -> Result<Self, F::Error> {
|
||||||
|
self.try_map_id(|value| value.try_fold_with(folder))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
||||||
|
@ -750,8 +772,11 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Vec<T> {
|
impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Vec<T> {
|
||||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
|
||||||
self.try_map_id(|t| t.fold_with(folder))
|
self,
|
||||||
|
folder: &mut F,
|
||||||
|
) -> Result<Self, F::Error> {
|
||||||
|
self.try_map_id(|t| t.try_fold_with(folder))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
||||||
|
@ -760,8 +785,11 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Vec<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<[T]> {
|
impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<[T]> {
|
||||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
|
||||||
self.try_map_id(|t| t.fold_with(folder))
|
self,
|
||||||
|
folder: &mut F,
|
||||||
|
) -> Result<Self, F::Error> {
|
||||||
|
self.try_map_id(|t| t.try_fold_with(folder))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
||||||
|
@ -770,12 +798,15 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<[T]> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder<'tcx, T> {
|
impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder<'tcx, T> {
|
||||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
|
||||||
self.try_map_bound(|ty| ty.fold_with(folder))
|
self,
|
||||||
|
folder: &mut F,
|
||||||
|
) -> Result<Self, F::Error> {
|
||||||
|
self.try_map_bound(|ty| ty.try_fold_with(folder))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||||
folder.fold_binder(self)
|
folder.try_fold_binder(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
||||||
|
@ -788,7 +819,10 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder<'tcx, T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>> {
|
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>> {
|
||||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
|
||||||
|
self,
|
||||||
|
folder: &mut F,
|
||||||
|
) -> Result<Self, F::Error> {
|
||||||
ty::util::fold_list(self, folder, |tcx, v| tcx.intern_poly_existential_predicates(v))
|
ty::util::fold_list(self, folder, |tcx, v| tcx.intern_poly_existential_predicates(v))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -798,7 +832,10 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Binder<'tcx, ty::Existentia
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<Ty<'tcx>> {
|
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<Ty<'tcx>> {
|
||||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
|
||||||
|
self,
|
||||||
|
folder: &mut F,
|
||||||
|
) -> Result<Self, F::Error> {
|
||||||
ty::util::fold_list(self, folder, |tcx, v| tcx.intern_type_list(v))
|
ty::util::fold_list(self, folder, |tcx, v| tcx.intern_type_list(v))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -808,7 +845,10 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<Ty<'tcx>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ProjectionKind> {
|
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ProjectionKind> {
|
||||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
|
||||||
|
self,
|
||||||
|
folder: &mut F,
|
||||||
|
) -> Result<Self, F::Error> {
|
||||||
ty::util::fold_list(self, folder, |tcx, v| tcx.intern_projs(v))
|
ty::util::fold_list(self, folder, |tcx, v| tcx.intern_projs(v))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -818,22 +858,31 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ProjectionKind> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> {
|
impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> {
|
||||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
|
||||||
|
self,
|
||||||
|
folder: &mut F,
|
||||||
|
) -> Result<Self, F::Error> {
|
||||||
use crate::ty::InstanceDef::*;
|
use crate::ty::InstanceDef::*;
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
substs: self.substs.fold_with(folder)?,
|
substs: self.substs.try_fold_with(folder)?,
|
||||||
def: match self.def {
|
def: match self.def {
|
||||||
Item(def) => Item(def.fold_with(folder)?),
|
Item(def) => Item(def.try_fold_with(folder)?),
|
||||||
VtableShim(did) => VtableShim(did.fold_with(folder)?),
|
VtableShim(did) => VtableShim(did.try_fold_with(folder)?),
|
||||||
ReifyShim(did) => ReifyShim(did.fold_with(folder)?),
|
ReifyShim(did) => ReifyShim(did.try_fold_with(folder)?),
|
||||||
Intrinsic(did) => Intrinsic(did.fold_with(folder)?),
|
Intrinsic(did) => Intrinsic(did.try_fold_with(folder)?),
|
||||||
FnPtrShim(did, ty) => FnPtrShim(did.fold_with(folder)?, ty.fold_with(folder)?),
|
FnPtrShim(did, ty) => {
|
||||||
Virtual(did, i) => Virtual(did.fold_with(folder)?, i),
|
FnPtrShim(did.try_fold_with(folder)?, ty.try_fold_with(folder)?)
|
||||||
ClosureOnceShim { call_once, track_caller } => {
|
}
|
||||||
ClosureOnceShim { call_once: call_once.fold_with(folder)?, track_caller }
|
Virtual(did, i) => Virtual(did.try_fold_with(folder)?, i),
|
||||||
|
ClosureOnceShim { call_once, track_caller } => {
|
||||||
|
ClosureOnceShim { call_once: call_once.try_fold_with(folder)?, track_caller }
|
||||||
|
}
|
||||||
|
DropGlue(did, ty) => {
|
||||||
|
DropGlue(did.try_fold_with(folder)?, ty.try_fold_with(folder)?)
|
||||||
|
}
|
||||||
|
CloneShim(did, ty) => {
|
||||||
|
CloneShim(did.try_fold_with(folder)?, ty.try_fold_with(folder)?)
|
||||||
}
|
}
|
||||||
DropGlue(did, ty) => DropGlue(did.fold_with(folder)?, ty.fold_with(folder)?),
|
|
||||||
CloneShim(did, ty) => CloneShim(did.fold_with(folder)?, ty.fold_with(folder)?),
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -860,8 +909,11 @@ impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for interpret::GlobalId<'tcx> {
|
impl<'tcx> TypeFoldable<'tcx> for interpret::GlobalId<'tcx> {
|
||||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
|
||||||
Ok(Self { instance: self.instance.fold_with(folder)?, promoted: self.promoted })
|
self,
|
||||||
|
folder: &mut F,
|
||||||
|
) -> Result<Self, F::Error> {
|
||||||
|
Ok(Self { instance: self.instance.try_fold_with(folder)?, promoted: self.promoted })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
||||||
|
@ -870,26 +922,31 @@ impl<'tcx> TypeFoldable<'tcx> for interpret::GlobalId<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
|
impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
|
||||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
|
||||||
|
self,
|
||||||
|
folder: &mut F,
|
||||||
|
) -> Result<Self, F::Error> {
|
||||||
let kind = match *self.kind() {
|
let kind = match *self.kind() {
|
||||||
ty::RawPtr(tm) => ty::RawPtr(tm.fold_with(folder)?),
|
ty::RawPtr(tm) => ty::RawPtr(tm.try_fold_with(folder)?),
|
||||||
ty::Array(typ, sz) => ty::Array(typ.fold_with(folder)?, sz.fold_with(folder)?),
|
ty::Array(typ, sz) => ty::Array(typ.try_fold_with(folder)?, sz.try_fold_with(folder)?),
|
||||||
ty::Slice(typ) => ty::Slice(typ.fold_with(folder)?),
|
ty::Slice(typ) => ty::Slice(typ.try_fold_with(folder)?),
|
||||||
ty::Adt(tid, substs) => ty::Adt(tid, substs.fold_with(folder)?),
|
ty::Adt(tid, substs) => ty::Adt(tid, substs.try_fold_with(folder)?),
|
||||||
ty::Dynamic(trait_ty, region) => {
|
ty::Dynamic(trait_ty, region) => {
|
||||||
ty::Dynamic(trait_ty.fold_with(folder)?, region.fold_with(folder)?)
|
ty::Dynamic(trait_ty.try_fold_with(folder)?, region.try_fold_with(folder)?)
|
||||||
|
}
|
||||||
|
ty::Tuple(ts) => ty::Tuple(ts.try_fold_with(folder)?),
|
||||||
|
ty::FnDef(def_id, substs) => ty::FnDef(def_id, substs.try_fold_with(folder)?),
|
||||||
|
ty::FnPtr(f) => ty::FnPtr(f.try_fold_with(folder)?),
|
||||||
|
ty::Ref(r, ty, mutbl) => {
|
||||||
|
ty::Ref(r.try_fold_with(folder)?, ty.try_fold_with(folder)?, mutbl)
|
||||||
}
|
}
|
||||||
ty::Tuple(ts) => ty::Tuple(ts.fold_with(folder)?),
|
|
||||||
ty::FnDef(def_id, substs) => ty::FnDef(def_id, substs.fold_with(folder)?),
|
|
||||||
ty::FnPtr(f) => ty::FnPtr(f.fold_with(folder)?),
|
|
||||||
ty::Ref(r, ty, mutbl) => ty::Ref(r.fold_with(folder)?, ty.fold_with(folder)?, mutbl),
|
|
||||||
ty::Generator(did, substs, movability) => {
|
ty::Generator(did, substs, movability) => {
|
||||||
ty::Generator(did, substs.fold_with(folder)?, movability)
|
ty::Generator(did, substs.try_fold_with(folder)?, movability)
|
||||||
}
|
}
|
||||||
ty::GeneratorWitness(types) => ty::GeneratorWitness(types.fold_with(folder)?),
|
ty::GeneratorWitness(types) => ty::GeneratorWitness(types.try_fold_with(folder)?),
|
||||||
ty::Closure(did, substs) => ty::Closure(did, substs.fold_with(folder)?),
|
ty::Closure(did, substs) => ty::Closure(did, substs.try_fold_with(folder)?),
|
||||||
ty::Projection(data) => ty::Projection(data.fold_with(folder)?),
|
ty::Projection(data) => ty::Projection(data.try_fold_with(folder)?),
|
||||||
ty::Opaque(did, substs) => ty::Opaque(did, substs.fold_with(folder)?),
|
ty::Opaque(did, substs) => ty::Opaque(did, substs.try_fold_with(folder)?),
|
||||||
|
|
||||||
ty::Bool
|
ty::Bool
|
||||||
| ty::Char
|
| ty::Char
|
||||||
|
@ -909,8 +966,8 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
|
||||||
Ok(if *self.kind() == kind { self } else { folder.tcx().mk_ty(kind) })
|
Ok(if *self.kind() == kind { self } else { folder.tcx().mk_ty(kind) })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||||
folder.fold_ty(self)
|
folder.try_fold_ty(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
||||||
|
@ -961,12 +1018,15 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for ty::Region<'tcx> {
|
impl<'tcx> TypeFoldable<'tcx> for ty::Region<'tcx> {
|
||||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, _folder: &mut F) -> Result<Self, F::Error> {
|
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
|
||||||
|
self,
|
||||||
|
_folder: &mut F,
|
||||||
|
) -> Result<Self, F::Error> {
|
||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||||
folder.fold_region(self)
|
folder.try_fold_region(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
||||||
|
@ -979,12 +1039,15 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Region<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> {
|
impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> {
|
||||||
fn fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||||
folder.fold_predicate(self)
|
folder.try_fold_predicate(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
|
||||||
let new = self.inner.kind.fold_with(folder)?;
|
self,
|
||||||
|
folder: &mut F,
|
||||||
|
) -> Result<Self, F::Error> {
|
||||||
|
let new = self.inner.kind.try_fold_with(folder)?;
|
||||||
Ok(folder.tcx().reuse_or_mk_predicate(self, new))
|
Ok(folder.tcx().reuse_or_mk_predicate(self, new))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1006,7 +1069,10 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Predicate<'tcx>> {
|
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Predicate<'tcx>> {
|
||||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
|
||||||
|
self,
|
||||||
|
folder: &mut F,
|
||||||
|
) -> Result<Self, F::Error> {
|
||||||
ty::util::fold_list(self, folder, |tcx, v| tcx.intern_predicates(v))
|
ty::util::fold_list(self, folder, |tcx, v| tcx.intern_predicates(v))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1016,8 +1082,11 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Predicate<'tcx>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, T: TypeFoldable<'tcx>, I: Idx> TypeFoldable<'tcx> for IndexVec<I, T> {
|
impl<'tcx, T: TypeFoldable<'tcx>, I: Idx> TypeFoldable<'tcx> for IndexVec<I, T> {
|
||||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
|
||||||
self.try_map_id(|x| x.fold_with(folder))
|
self,
|
||||||
|
folder: &mut F,
|
||||||
|
) -> Result<Self, F::Error> {
|
||||||
|
self.try_map_id(|x| x.try_fold_with(folder))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
||||||
|
@ -1026,9 +1095,12 @@ impl<'tcx, T: TypeFoldable<'tcx>, I: Idx> TypeFoldable<'tcx> for IndexVec<I, T>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Const<'tcx> {
|
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Const<'tcx> {
|
||||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
|
||||||
let ty = self.ty.fold_with(folder)?;
|
self,
|
||||||
let val = self.val.fold_with(folder)?;
|
folder: &mut F,
|
||||||
|
) -> Result<Self, F::Error> {
|
||||||
|
let ty = self.ty.try_fold_with(folder)?;
|
||||||
|
let val = self.val.try_fold_with(folder)?;
|
||||||
if ty != self.ty || val != self.val {
|
if ty != self.ty || val != self.val {
|
||||||
Ok(folder.tcx().mk_const(ty::Const { ty, val }))
|
Ok(folder.tcx().mk_const(ty::Const { ty, val }))
|
||||||
} else {
|
} else {
|
||||||
|
@ -1036,8 +1108,8 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Const<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||||
folder.fold_const(self)
|
folder.try_fold_const(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
||||||
|
@ -1051,11 +1123,14 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Const<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> {
|
impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> {
|
||||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
|
||||||
|
self,
|
||||||
|
folder: &mut F,
|
||||||
|
) -> Result<Self, F::Error> {
|
||||||
Ok(match self {
|
Ok(match self {
|
||||||
ty::ConstKind::Infer(ic) => ty::ConstKind::Infer(ic.fold_with(folder)?),
|
ty::ConstKind::Infer(ic) => ty::ConstKind::Infer(ic.try_fold_with(folder)?),
|
||||||
ty::ConstKind::Param(p) => ty::ConstKind::Param(p.fold_with(folder)?),
|
ty::ConstKind::Param(p) => ty::ConstKind::Param(p.try_fold_with(folder)?),
|
||||||
ty::ConstKind::Unevaluated(uv) => ty::ConstKind::Unevaluated(uv.fold_with(folder)?),
|
ty::ConstKind::Unevaluated(uv) => ty::ConstKind::Unevaluated(uv.try_fold_with(folder)?),
|
||||||
ty::ConstKind::Value(_)
|
ty::ConstKind::Value(_)
|
||||||
| ty::ConstKind::Bound(..)
|
| ty::ConstKind::Bound(..)
|
||||||
| ty::ConstKind::Placeholder(..)
|
| ty::ConstKind::Placeholder(..)
|
||||||
|
@ -1077,7 +1152,10 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for InferConst<'tcx> {
|
impl<'tcx> TypeFoldable<'tcx> for InferConst<'tcx> {
|
||||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, _folder: &mut F) -> Result<Self, F::Error> {
|
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
|
||||||
|
self,
|
||||||
|
_folder: &mut F,
|
||||||
|
) -> Result<Self, F::Error> {
|
||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1087,10 +1165,13 @@ impl<'tcx> TypeFoldable<'tcx> for InferConst<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for ty::Unevaluated<'tcx> {
|
impl<'tcx> TypeFoldable<'tcx> for ty::Unevaluated<'tcx> {
|
||||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
|
||||||
|
self,
|
||||||
|
folder: &mut F,
|
||||||
|
) -> Result<Self, F::Error> {
|
||||||
Ok(ty::Unevaluated {
|
Ok(ty::Unevaluated {
|
||||||
def: self.def,
|
def: self.def,
|
||||||
substs_: Some(self.substs(folder.tcx()).fold_with(folder)?),
|
substs_: Some(self.substs(folder.tcx()).try_fold_with(folder)?),
|
||||||
promoted: self.promoted,
|
promoted: self.promoted,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1112,10 +1193,13 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Unevaluated<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for ty::Unevaluated<'tcx, ()> {
|
impl<'tcx> TypeFoldable<'tcx> for ty::Unevaluated<'tcx, ()> {
|
||||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
|
||||||
|
self,
|
||||||
|
folder: &mut F,
|
||||||
|
) -> Result<Self, F::Error> {
|
||||||
Ok(ty::Unevaluated {
|
Ok(ty::Unevaluated {
|
||||||
def: self.def,
|
def: self.def,
|
||||||
substs_: Some(self.substs(folder.tcx()).fold_with(folder)?),
|
substs_: Some(self.substs(folder.tcx()).try_fold_with(folder)?),
|
||||||
promoted: self.promoted,
|
promoted: self.promoted,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
use crate::mir;
|
use crate::mir;
|
||||||
use crate::ty::codec::{TyDecoder, TyEncoder};
|
use crate::ty::codec::{TyDecoder, TyEncoder};
|
||||||
use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
|
use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeVisitor};
|
||||||
use crate::ty::sty::{ClosureSubsts, GeneratorSubsts, InlineConstSubsts};
|
use crate::ty::sty::{ClosureSubsts, GeneratorSubsts, InlineConstSubsts};
|
||||||
use crate::ty::{self, Lift, List, ParamConst, Ty, TyCtxt};
|
use crate::ty::{self, Lift, List, ParamConst, Ty, TyCtxt};
|
||||||
|
|
||||||
|
@ -153,11 +153,14 @@ impl<'a, 'tcx> Lift<'tcx> for GenericArg<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for GenericArg<'tcx> {
|
impl<'tcx> TypeFoldable<'tcx> for GenericArg<'tcx> {
|
||||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
|
||||||
|
self,
|
||||||
|
folder: &mut F,
|
||||||
|
) -> Result<Self, F::Error> {
|
||||||
match self.unpack() {
|
match self.unpack() {
|
||||||
GenericArgKind::Lifetime(lt) => lt.fold_with(folder).map(Into::into),
|
GenericArgKind::Lifetime(lt) => lt.try_fold_with(folder).map(Into::into),
|
||||||
GenericArgKind::Type(ty) => ty.fold_with(folder).map(Into::into),
|
GenericArgKind::Type(ty) => ty.try_fold_with(folder).map(Into::into),
|
||||||
GenericArgKind::Const(ct) => ct.fold_with(folder).map(Into::into),
|
GenericArgKind::Const(ct) => ct.try_fold_with(folder).map(Into::into),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -372,7 +375,10 @@ impl<'a, 'tcx> InternalSubsts<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TypeFoldable<'tcx> for SubstsRef<'tcx> {
|
impl<'tcx> TypeFoldable<'tcx> for SubstsRef<'tcx> {
|
||||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
|
||||||
|
self,
|
||||||
|
folder: &mut F,
|
||||||
|
) -> Result<Self, F::Error> {
|
||||||
// This code is hot enough that it's worth specializing for the most
|
// This code is hot enough that it's worth specializing for the most
|
||||||
// common length lists, to avoid the overhead of `SmallVec` creation.
|
// common length lists, to avoid the overhead of `SmallVec` creation.
|
||||||
// The match arms are in order of frequency. The 1, 2, and 0 cases are
|
// The match arms are in order of frequency. The 1, 2, and 0 cases are
|
||||||
|
@ -381,12 +387,12 @@ impl<'tcx> TypeFoldable<'tcx> for SubstsRef<'tcx> {
|
||||||
// calling `intern_substs`.
|
// calling `intern_substs`.
|
||||||
match self.len() {
|
match self.len() {
|
||||||
1 => {
|
1 => {
|
||||||
let param0 = self[0].fold_with(folder)?;
|
let param0 = self[0].try_fold_with(folder)?;
|
||||||
if param0 == self[0] { Ok(self) } else { Ok(folder.tcx().intern_substs(&[param0])) }
|
if param0 == self[0] { Ok(self) } else { Ok(folder.tcx().intern_substs(&[param0])) }
|
||||||
}
|
}
|
||||||
2 => {
|
2 => {
|
||||||
let param0 = self[0].fold_with(folder)?;
|
let param0 = self[0].try_fold_with(folder)?;
|
||||||
let param1 = self[1].fold_with(folder)?;
|
let param1 = self[1].try_fold_with(folder)?;
|
||||||
if param0 == self[0] && param1 == self[1] {
|
if param0 == self[0] && param1 == self[1] {
|
||||||
Ok(self)
|
Ok(self)
|
||||||
} else {
|
} else {
|
||||||
|
@ -396,7 +402,7 @@ impl<'tcx> TypeFoldable<'tcx> for SubstsRef<'tcx> {
|
||||||
0 => Ok(self),
|
0 => Ok(self),
|
||||||
_ => {
|
_ => {
|
||||||
let params: SmallVec<[_; 8]> =
|
let params: SmallVec<[_; 8]> =
|
||||||
self.iter().map(|k| k.fold_with(folder)).collect::<Result<_, _>>()?;
|
self.iter().map(|k| k.try_fold_with(folder)).collect::<Result<_, _>>()?;
|
||||||
if params[..] == self[..] {
|
if params[..] == self[..] {
|
||||||
Ok(self)
|
Ok(self)
|
||||||
} else {
|
} else {
|
||||||
|
@ -439,7 +445,7 @@ impl<'tcx, T: TypeFoldable<'tcx>> Subst<'tcx> for T {
|
||||||
span: Option<Span>,
|
span: Option<Span>,
|
||||||
) -> T {
|
) -> T {
|
||||||
let mut folder = SubstFolder { tcx, substs, span, binders_passed: 0 };
|
let mut folder = SubstFolder { tcx, substs, span, binders_passed: 0 };
|
||||||
self.fold_with(&mut folder).into_ok()
|
self.fold_with(&mut folder)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -465,14 +471,14 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> {
|
||||||
fn fold_binder<T: TypeFoldable<'tcx>>(
|
fn fold_binder<T: TypeFoldable<'tcx>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
t: ty::Binder<'tcx, T>,
|
t: ty::Binder<'tcx, T>,
|
||||||
) -> Result<ty::Binder<'tcx, T>, Self::Error> {
|
) -> ty::Binder<'tcx, T> {
|
||||||
self.binders_passed += 1;
|
self.binders_passed += 1;
|
||||||
let t = t.super_fold_with(self)?;
|
let t = t.super_fold_with(self);
|
||||||
self.binders_passed -= 1;
|
self.binders_passed -= 1;
|
||||||
Ok(t)
|
t
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||||
// Note: This routine only handles regions that are bound on
|
// Note: This routine only handles regions that are bound on
|
||||||
// type declarations and other outer declarations, not those
|
// type declarations and other outer declarations, not those
|
||||||
// bound in *fn types*. Region substitution of the bound
|
// bound in *fn types*. Region substitution of the bound
|
||||||
|
@ -482,7 +488,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> {
|
||||||
ty::ReEarlyBound(data) => {
|
ty::ReEarlyBound(data) => {
|
||||||
let rk = self.substs.get(data.index as usize).map(|k| k.unpack());
|
let rk = self.substs.get(data.index as usize).map(|k| k.unpack());
|
||||||
match rk {
|
match rk {
|
||||||
Some(GenericArgKind::Lifetime(lt)) => Ok(self.shift_region_through_binders(lt)),
|
Some(GenericArgKind::Lifetime(lt)) => self.shift_region_through_binders(lt),
|
||||||
_ => {
|
_ => {
|
||||||
let span = self.span.unwrap_or(DUMMY_SP);
|
let span = self.span.unwrap_or(DUMMY_SP);
|
||||||
let msg = format!(
|
let msg = format!(
|
||||||
|
@ -494,37 +500,31 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => Ok(r),
|
_ => r,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
if !t.potentially_needs_subst() {
|
if !t.potentially_needs_subst() {
|
||||||
return Ok(t);
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
match *t.kind() {
|
match *t.kind() {
|
||||||
ty::Param(p) => Ok(self.ty_for_param(p, t)),
|
ty::Param(p) => self.ty_for_param(p, t),
|
||||||
_ => t.super_fold_with(self),
|
_ => t.super_fold_with(self),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_const(
|
fn fold_const(&mut self, c: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||||
&mut self,
|
|
||||||
c: &'tcx ty::Const<'tcx>,
|
|
||||||
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
|
|
||||||
if let ty::ConstKind::Param(p) = c.val {
|
if let ty::ConstKind::Param(p) = c.val {
|
||||||
Ok(self.const_for_param(p, c))
|
self.const_for_param(p, c)
|
||||||
} else {
|
} else {
|
||||||
c.super_fold_with(self)
|
c.super_fold_with(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn fold_mir_const(
|
fn fold_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> {
|
||||||
&mut self,
|
|
||||||
c: mir::ConstantKind<'tcx>,
|
|
||||||
) -> Result<mir::ConstantKind<'tcx>, Self::Error> {
|
|
||||||
c.super_fold_with(self)
|
c.super_fold_with(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//! Miscellaneous type-system utilities that are too small to deserve their own modules.
|
//! Miscellaneous type-system utilities that are too small to deserve their own modules.
|
||||||
|
|
||||||
use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
||||||
use crate::ty::fold::TypeFolder;
|
use crate::ty::fold::{FallibleTypeFolder, TypeFolder};
|
||||||
use crate::ty::layout::IntegerExt;
|
use crate::ty::layout::IntegerExt;
|
||||||
use crate::ty::query::TyCtxtAt;
|
use crate::ty::query::TyCtxtAt;
|
||||||
use crate::ty::subst::{GenericArgKind, Subst, SubstsRef};
|
use crate::ty::subst::{GenericArgKind, Subst, SubstsRef};
|
||||||
|
@ -574,14 +574,14 @@ impl<'tcx> OpaqueTypeExpander<'tcx> {
|
||||||
if self.found_any_recursion {
|
if self.found_any_recursion {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let substs = substs.fold_with(self).into_ok();
|
let substs = substs.fold_with(self);
|
||||||
if !self.check_recursion || self.seen_opaque_tys.insert(def_id) {
|
if !self.check_recursion || self.seen_opaque_tys.insert(def_id) {
|
||||||
let expanded_ty = match self.expanded_cache.get(&(def_id, substs)) {
|
let expanded_ty = match self.expanded_cache.get(&(def_id, substs)) {
|
||||||
Some(expanded_ty) => expanded_ty,
|
Some(expanded_ty) => expanded_ty,
|
||||||
None => {
|
None => {
|
||||||
let generic_ty = self.tcx.type_of(def_id);
|
let generic_ty = self.tcx.type_of(def_id);
|
||||||
let concrete_ty = generic_ty.subst(self.tcx, substs);
|
let concrete_ty = generic_ty.subst(self.tcx, substs);
|
||||||
let expanded_ty = self.fold_ty(concrete_ty).into_ok();
|
let expanded_ty = self.fold_ty(concrete_ty);
|
||||||
self.expanded_cache.insert((def_id, substs), expanded_ty);
|
self.expanded_cache.insert((def_id, substs), expanded_ty);
|
||||||
expanded_ty
|
expanded_ty
|
||||||
}
|
}
|
||||||
|
@ -605,13 +605,13 @@ impl<'tcx> TypeFolder<'tcx> for OpaqueTypeExpander<'tcx> {
|
||||||
self.tcx
|
self.tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
if let ty::Opaque(def_id, substs) = t.kind {
|
if let ty::Opaque(def_id, substs) = t.kind {
|
||||||
Ok(self.expand_opaque_ty(def_id, substs).unwrap_or(t))
|
self.expand_opaque_ty(def_id, substs).unwrap_or(t)
|
||||||
} else if t.has_opaque_types() {
|
} else if t.has_opaque_types() {
|
||||||
t.super_fold_with(self)
|
t.super_fold_with(self)
|
||||||
} else {
|
} else {
|
||||||
Ok(t)
|
t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1048,12 +1048,12 @@ pub fn fold_list<'tcx, F, T>(
|
||||||
intern: impl FnOnce(TyCtxt<'tcx>, &[T]) -> &'tcx ty::List<T>,
|
intern: impl FnOnce(TyCtxt<'tcx>, &[T]) -> &'tcx ty::List<T>,
|
||||||
) -> Result<&'tcx ty::List<T>, F::Error>
|
) -> Result<&'tcx ty::List<T>, F::Error>
|
||||||
where
|
where
|
||||||
F: TypeFolder<'tcx>,
|
F: FallibleTypeFolder<'tcx>,
|
||||||
T: TypeFoldable<'tcx> + PartialEq + Copy,
|
T: TypeFoldable<'tcx> + PartialEq + Copy,
|
||||||
{
|
{
|
||||||
let mut iter = list.iter();
|
let mut iter = list.iter();
|
||||||
// Look for the first element that changed
|
// Look for the first element that changed
|
||||||
match iter.by_ref().enumerate().find_map(|(i, t)| match t.fold_with(folder) {
|
match iter.by_ref().enumerate().find_map(|(i, t)| match t.try_fold_with(folder) {
|
||||||
Ok(new_t) if new_t == t => None,
|
Ok(new_t) if new_t == t => None,
|
||||||
new_t => Some((i, new_t)),
|
new_t => Some((i, new_t)),
|
||||||
}) {
|
}) {
|
||||||
|
@ -1063,7 +1063,7 @@ where
|
||||||
new_list.extend_from_slice(&list[..i]);
|
new_list.extend_from_slice(&list[..i]);
|
||||||
new_list.push(new_t);
|
new_list.push(new_t);
|
||||||
for t in iter {
|
for t in iter {
|
||||||
new_list.push(t.fold_with(folder)?)
|
new_list.push(t.try_fold_with(folder)?)
|
||||||
}
|
}
|
||||||
Ok(intern(folder.tcx(), &new_list))
|
Ok(intern(folder.tcx(), &new_list))
|
||||||
}
|
}
|
||||||
|
@ -1092,7 +1092,7 @@ pub fn normalize_opaque_types(
|
||||||
check_recursion: false,
|
check_recursion: false,
|
||||||
tcx,
|
tcx,
|
||||||
};
|
};
|
||||||
val.fold_with(&mut visitor).into_ok()
|
val.fold_with(&mut visitor)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn provide(providers: &mut ty::query::Providers) {
|
pub fn provide(providers: &mut ty::query::Providers) {
|
||||||
|
|
|
@ -22,7 +22,6 @@
|
||||||
#![feature(never_type)]
|
#![feature(never_type)]
|
||||||
#![feature(crate_visibility_modifier)]
|
#![feature(crate_visibility_modifier)]
|
||||||
#![feature(control_flow_enum)]
|
#![feature(control_flow_enum)]
|
||||||
#![feature(unwrap_infallible)]
|
|
||||||
#![recursion_limit = "512"] // For rustdoc
|
#![recursion_limit = "512"] // For rustdoc
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
|
|
@ -65,16 +65,14 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
// Convert the type from the function into a type valid outside
|
// Convert the type from the function into a type valid outside
|
||||||
// the function, by replacing invalid regions with 'static,
|
// the function, by replacing invalid regions with 'static,
|
||||||
// after producing an error for each of them.
|
// after producing an error for each of them.
|
||||||
let definition_ty = instantiated_ty
|
let definition_ty = instantiated_ty.fold_with(&mut ReverseMapper::new(
|
||||||
.fold_with(&mut ReverseMapper::new(
|
self.tcx,
|
||||||
self.tcx,
|
self.is_tainted_by_errors(),
|
||||||
self.is_tainted_by_errors(),
|
def_id,
|
||||||
def_id,
|
map,
|
||||||
map,
|
instantiated_ty,
|
||||||
instantiated_ty,
|
span,
|
||||||
span,
|
));
|
||||||
))
|
|
||||||
.into_ok();
|
|
||||||
debug!(?definition_ty);
|
debug!(?definition_ty);
|
||||||
|
|
||||||
definition_ty
|
definition_ty
|
||||||
|
@ -125,14 +123,14 @@ impl ReverseMapper<'tcx> {
|
||||||
) -> GenericArg<'tcx> {
|
) -> GenericArg<'tcx> {
|
||||||
assert!(!self.map_missing_regions_to_empty);
|
assert!(!self.map_missing_regions_to_empty);
|
||||||
self.map_missing_regions_to_empty = true;
|
self.map_missing_regions_to_empty = true;
|
||||||
let kind = kind.fold_with(self).into_ok();
|
let kind = kind.fold_with(self);
|
||||||
self.map_missing_regions_to_empty = false;
|
self.map_missing_regions_to_empty = false;
|
||||||
kind
|
kind
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_kind_normally(&mut self, kind: GenericArg<'tcx>) -> GenericArg<'tcx> {
|
fn fold_kind_normally(&mut self, kind: GenericArg<'tcx>) -> GenericArg<'tcx> {
|
||||||
assert!(!self.map_missing_regions_to_empty);
|
assert!(!self.map_missing_regions_to_empty);
|
||||||
kind.fold_with(self).into_ok()
|
kind.fold_with(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,17 +140,17 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip(self), level = "debug")]
|
#[instrument(skip(self), level = "debug")]
|
||||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||||
match r {
|
match r {
|
||||||
// Ignore bound regions and `'static` regions that appear in the
|
// Ignore bound regions and `'static` regions that appear in the
|
||||||
// type, we only need to remap regions that reference lifetimes
|
// type, we only need to remap regions that reference lifetimes
|
||||||
// from the function declaraion.
|
// from the function declaraion.
|
||||||
// This would ignore `'r` in a type like `for<'r> fn(&'r u32)`.
|
// This would ignore `'r` in a type like `for<'r> fn(&'r u32)`.
|
||||||
ty::ReLateBound(..) | ty::ReStatic => return Ok(r),
|
ty::ReLateBound(..) | ty::ReStatic => return r,
|
||||||
|
|
||||||
// If regions have been erased (by writeback), don't try to unerase
|
// If regions have been erased (by writeback), don't try to unerase
|
||||||
// them.
|
// them.
|
||||||
ty::ReErased => return Ok(r),
|
ty::ReErased => return r,
|
||||||
|
|
||||||
// The regions that we expect from borrow checking.
|
// The regions that we expect from borrow checking.
|
||||||
ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReEmpty(ty::UniverseIndex::ROOT) => {}
|
ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReEmpty(ty::UniverseIndex::ROOT) => {}
|
||||||
|
@ -167,10 +165,10 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
|
||||||
|
|
||||||
let generics = self.tcx().generics_of(self.opaque_type_def_id);
|
let generics = self.tcx().generics_of(self.opaque_type_def_id);
|
||||||
match self.map.get(&r.into()).map(|k| k.unpack()) {
|
match self.map.get(&r.into()).map(|k| k.unpack()) {
|
||||||
Some(GenericArgKind::Lifetime(r1)) => Ok(r1),
|
Some(GenericArgKind::Lifetime(r1)) => r1,
|
||||||
Some(u) => panic!("region mapped to unexpected kind: {:?}", u),
|
Some(u) => panic!("region mapped to unexpected kind: {:?}", u),
|
||||||
None if self.map_missing_regions_to_empty || self.tainted_by_errors => {
|
None if self.map_missing_regions_to_empty || self.tainted_by_errors => {
|
||||||
Ok(self.tcx.lifetimes.re_root_empty)
|
self.tcx.lifetimes.re_root_empty
|
||||||
}
|
}
|
||||||
None if generics.parent.is_some() => {
|
None if generics.parent.is_some() => {
|
||||||
if let Some(hidden_ty) = self.hidden_ty.take() {
|
if let Some(hidden_ty) = self.hidden_ty.take() {
|
||||||
|
@ -182,7 +180,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
|
||||||
)
|
)
|
||||||
.emit();
|
.emit();
|
||||||
}
|
}
|
||||||
Ok(self.tcx.lifetimes.re_root_empty)
|
self.tcx.lifetimes.re_root_empty
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
self.tcx
|
self.tcx
|
||||||
|
@ -198,12 +196,12 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
|
||||||
)
|
)
|
||||||
.emit();
|
.emit();
|
||||||
|
|
||||||
Ok(self.tcx().lifetimes.re_static)
|
self.tcx().lifetimes.re_static
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
match *ty.kind() {
|
match *ty.kind() {
|
||||||
ty::Closure(def_id, substs) => {
|
ty::Closure(def_id, substs) => {
|
||||||
// I am a horrible monster and I pray for death. When
|
// I am a horrible monster and I pray for death. When
|
||||||
|
@ -241,7 +239,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
Ok(self.tcx.mk_closure(def_id, substs))
|
self.tcx.mk_closure(def_id, substs)
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::Generator(def_id, substs, movability) => {
|
ty::Generator(def_id, substs, movability) => {
|
||||||
|
@ -256,7 +254,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
Ok(self.tcx.mk_generator(def_id, substs, movability))
|
self.tcx.mk_generator(def_id, substs, movability)
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::Param(param) => {
|
ty::Param(param) => {
|
||||||
|
@ -264,7 +262,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
|
||||||
match self.map.get(&ty.into()).map(|k| k.unpack()) {
|
match self.map.get(&ty.into()).map(|k| k.unpack()) {
|
||||||
// Found it in the substitution list; replace with the parameter from the
|
// Found it in the substitution list; replace with the parameter from the
|
||||||
// opaque type.
|
// opaque type.
|
||||||
Some(GenericArgKind::Type(t1)) => Ok(t1),
|
Some(GenericArgKind::Type(t1)) => t1,
|
||||||
Some(u) => panic!("type mapped to unexpected kind: {:?}", u),
|
Some(u) => panic!("type mapped to unexpected kind: {:?}", u),
|
||||||
None => {
|
None => {
|
||||||
debug!(?param, ?self.map);
|
debug!(?param, ?self.map);
|
||||||
|
@ -280,7 +278,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
|
||||||
)
|
)
|
||||||
.emit();
|
.emit();
|
||||||
|
|
||||||
Ok(self.tcx().ty_error())
|
self.tcx().ty_error()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -289,13 +287,10 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_const(
|
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||||
&mut self,
|
|
||||||
ct: &'tcx ty::Const<'tcx>,
|
|
||||||
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
|
|
||||||
trace!("checking const {:?}", ct);
|
trace!("checking const {:?}", ct);
|
||||||
// Find a const parameter
|
// Find a const parameter
|
||||||
Ok(match ct.val {
|
match ct.val {
|
||||||
ty::ConstKind::Param(..) => {
|
ty::ConstKind::Param(..) => {
|
||||||
// Look it up in the substitution list.
|
// Look it up in the substitution list.
|
||||||
match self.map.get(&ct.into()).map(|k| k.unpack()) {
|
match self.map.get(&ct.into()).map(|k| k.unpack()) {
|
||||||
|
@ -322,7 +317,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => ct,
|
_ => ct,
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -865,11 +865,11 @@ impl<'a, 'tcx> TypeFolder<'tcx> for RegionReplacer<'a, 'tcx> {
|
||||||
self.tcx
|
self.tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||||
Ok((match r {
|
(match r {
|
||||||
ty::ReVar(vid) => self.vid_to_region.get(vid).cloned(),
|
ty::ReVar(vid) => self.vid_to_region.get(vid).cloned(),
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
.unwrap_or_else(|| r.super_fold_with(self).into_ok()))
|
.unwrap_or_else(|| r.super_fold_with(self))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1898,15 +1898,15 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
self.infcx.tcx
|
self.infcx.tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
if let ty::Param(ty::ParamTy { name, .. }) = *ty.kind() {
|
if let ty::Param(ty::ParamTy { name, .. }) = *ty.kind() {
|
||||||
let infcx = self.infcx;
|
let infcx = self.infcx;
|
||||||
Ok(self.var_map.entry(ty).or_insert_with(|| {
|
self.var_map.entry(ty).or_insert_with(|| {
|
||||||
infcx.next_ty_var(TypeVariableOrigin {
|
infcx.next_ty_var(TypeVariableOrigin {
|
||||||
kind: TypeVariableOriginKind::TypeParameterDefinition(name, None),
|
kind: TypeVariableOriginKind::TypeParameterDefinition(name, None),
|
||||||
span: DUMMY_SP,
|
span: DUMMY_SP,
|
||||||
})
|
})
|
||||||
}))
|
})
|
||||||
} else {
|
} else {
|
||||||
ty.super_fold_with(self)
|
ty.super_fold_with(self)
|
||||||
}
|
}
|
||||||
|
@ -1916,9 +1916,8 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
self.probe(|_| {
|
self.probe(|_| {
|
||||||
let mut selcx = SelectionContext::new(self);
|
let mut selcx = SelectionContext::new(self);
|
||||||
|
|
||||||
let cleaned_pred = pred
|
let cleaned_pred =
|
||||||
.fold_with(&mut ParamToVarFolder { infcx: self, var_map: Default::default() })
|
pred.fold_with(&mut ParamToVarFolder { infcx: self, var_map: Default::default() });
|
||||||
.into_ok();
|
|
||||||
|
|
||||||
let cleaned_pred = super::project::normalize(
|
let cleaned_pred = super::project::normalize(
|
||||||
&mut selcx,
|
&mut selcx,
|
||||||
|
|
|
@ -339,7 +339,7 @@ impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> {
|
||||||
if !needs_normalization(&value, self.param_env.reveal()) {
|
if !needs_normalization(&value, self.param_env.reveal()) {
|
||||||
value
|
value
|
||||||
} else {
|
} else {
|
||||||
value.fold_with(self).into_ok()
|
value.fold_with(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -352,16 +352,16 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
|
||||||
fn fold_binder<T: TypeFoldable<'tcx>>(
|
fn fold_binder<T: TypeFoldable<'tcx>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
t: ty::Binder<'tcx, T>,
|
t: ty::Binder<'tcx, T>,
|
||||||
) -> Result<ty::Binder<'tcx, T>, Self::Error> {
|
) -> ty::Binder<'tcx, T> {
|
||||||
self.universes.push(None);
|
self.universes.push(None);
|
||||||
let t = t.super_fold_with(self);
|
let t = t.super_fold_with(self);
|
||||||
self.universes.pop();
|
self.universes.pop();
|
||||||
t
|
t
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
if !needs_normalization(&ty, self.param_env.reveal()) {
|
if !needs_normalization(&ty, self.param_env.reveal()) {
|
||||||
return Ok(ty);
|
return ty;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We try to be a little clever here as a performance optimization in
|
// We try to be a little clever here as a performance optimization in
|
||||||
|
@ -387,14 +387,14 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
|
||||||
// replace bound vars if the current type is a `Projection` and we need
|
// replace bound vars if the current type is a `Projection` and we need
|
||||||
// to make sure we don't forget to fold the substs regardless.
|
// to make sure we don't forget to fold the substs regardless.
|
||||||
|
|
||||||
Ok(match *ty.kind() {
|
match *ty.kind() {
|
||||||
// This is really important. While we *can* handle this, this has
|
// This is really important. While we *can* handle this, this has
|
||||||
// severe performance implications for large opaque types with
|
// severe performance implications for large opaque types with
|
||||||
// late-bound regions. See `issue-88862` benchmark.
|
// late-bound regions. See `issue-88862` benchmark.
|
||||||
ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => {
|
ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => {
|
||||||
// Only normalize `impl Trait` after type-checking, usually in codegen.
|
// Only normalize `impl Trait` after type-checking, usually in codegen.
|
||||||
match self.param_env.reveal() {
|
match self.param_env.reveal() {
|
||||||
Reveal::UserFacing => ty.super_fold_with(self)?,
|
Reveal::UserFacing => ty.super_fold_with(self),
|
||||||
|
|
||||||
Reveal::All => {
|
Reveal::All => {
|
||||||
let recursion_limit = self.tcx().recursion_limit();
|
let recursion_limit = self.tcx().recursion_limit();
|
||||||
|
@ -408,11 +408,11 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
|
||||||
self.selcx.infcx().report_overflow_error(&obligation, true);
|
self.selcx.infcx().report_overflow_error(&obligation, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
let substs = substs.super_fold_with(self)?;
|
let substs = substs.super_fold_with(self);
|
||||||
let generic_ty = self.tcx().type_of(def_id);
|
let generic_ty = self.tcx().type_of(def_id);
|
||||||
let concrete_ty = generic_ty.subst(self.tcx(), substs);
|
let concrete_ty = generic_ty.subst(self.tcx(), substs);
|
||||||
self.depth += 1;
|
self.depth += 1;
|
||||||
let folded_ty = self.fold_ty(concrete_ty)?;
|
let folded_ty = self.fold_ty(concrete_ty);
|
||||||
self.depth -= 1;
|
self.depth -= 1;
|
||||||
folded_ty
|
folded_ty
|
||||||
}
|
}
|
||||||
|
@ -426,7 +426,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
|
||||||
// register an obligation to *later* project, since we know
|
// register an obligation to *later* project, since we know
|
||||||
// there won't be bound vars there.
|
// there won't be bound vars there.
|
||||||
|
|
||||||
let data = data.super_fold_with(self)?;
|
let data = data.super_fold_with(self);
|
||||||
let normalized_ty = normalize_projection_type(
|
let normalized_ty = normalize_projection_type(
|
||||||
self.selcx,
|
self.selcx,
|
||||||
self.param_env,
|
self.param_env,
|
||||||
|
@ -461,7 +461,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
|
||||||
let infcx = self.selcx.infcx();
|
let infcx = self.selcx.infcx();
|
||||||
let (data, mapped_regions, mapped_types, mapped_consts) =
|
let (data, mapped_regions, mapped_types, mapped_consts) =
|
||||||
BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, data);
|
BoundVarReplacer::replace_bound_vars(infcx, &mut self.universes, data);
|
||||||
let data = data.super_fold_with(self)?;
|
let data = data.super_fold_with(self);
|
||||||
let normalized_ty = opt_normalize_projection_type(
|
let normalized_ty = opt_normalize_projection_type(
|
||||||
self.selcx,
|
self.selcx,
|
||||||
self.param_env,
|
self.param_env,
|
||||||
|
@ -473,18 +473,16 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
|
||||||
.ok()
|
.ok()
|
||||||
.flatten()
|
.flatten()
|
||||||
.map(|normalized_ty| {
|
.map(|normalized_ty| {
|
||||||
Ok({
|
PlaceholderReplacer::replace_placeholders(
|
||||||
PlaceholderReplacer::replace_placeholders(
|
infcx,
|
||||||
infcx,
|
mapped_regions,
|
||||||
mapped_regions,
|
mapped_types,
|
||||||
mapped_types,
|
mapped_consts,
|
||||||
mapped_consts,
|
&self.universes,
|
||||||
&self.universes,
|
normalized_ty,
|
||||||
normalized_ty,
|
)
|
||||||
)
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
.unwrap_or_else(|| ty.super_fold_with(self))?;
|
.unwrap_or_else(|| ty.super_fold_with(self));
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
?self.depth,
|
?self.depth,
|
||||||
|
@ -496,19 +494,16 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
|
||||||
normalized_ty
|
normalized_ty
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => ty.super_fold_with(self)?,
|
_ => ty.super_fold_with(self),
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_const(
|
fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||||
&mut self,
|
|
||||||
constant: &'tcx ty::Const<'tcx>,
|
|
||||||
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
|
|
||||||
if self.selcx.tcx().lazy_normalization() {
|
if self.selcx.tcx().lazy_normalization() {
|
||||||
Ok(constant)
|
constant
|
||||||
} else {
|
} else {
|
||||||
let constant = constant.super_fold_with(self)?;
|
let constant = constant.super_fold_with(self);
|
||||||
Ok(constant.eval(self.selcx.tcx(), self.param_env))
|
constant.eval(self.selcx.tcx(), self.param_env)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -555,7 +550,7 @@ impl<'me, 'tcx> BoundVarReplacer<'me, 'tcx> {
|
||||||
universe_indices,
|
universe_indices,
|
||||||
};
|
};
|
||||||
|
|
||||||
let value = value.super_fold_with(&mut replacer).into_ok();
|
let value = value.super_fold_with(&mut replacer);
|
||||||
|
|
||||||
(value, replacer.mapped_regions, replacer.mapped_types, replacer.mapped_consts)
|
(value, replacer.mapped_regions, replacer.mapped_types, replacer.mapped_consts)
|
||||||
}
|
}
|
||||||
|
@ -582,14 +577,14 @@ impl TypeFolder<'tcx> for BoundVarReplacer<'_, 'tcx> {
|
||||||
fn fold_binder<T: TypeFoldable<'tcx>>(
|
fn fold_binder<T: TypeFoldable<'tcx>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
t: ty::Binder<'tcx, T>,
|
t: ty::Binder<'tcx, T>,
|
||||||
) -> Result<ty::Binder<'tcx, T>, Self::Error> {
|
) -> ty::Binder<'tcx, T> {
|
||||||
self.current_index.shift_in(1);
|
self.current_index.shift_in(1);
|
||||||
let t = t.super_fold_with(self);
|
let t = t.super_fold_with(self);
|
||||||
self.current_index.shift_out(1);
|
self.current_index.shift_out(1);
|
||||||
t
|
t
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||||
match *r {
|
match *r {
|
||||||
ty::ReLateBound(debruijn, _)
|
ty::ReLateBound(debruijn, _)
|
||||||
if debruijn.as_usize() + 1
|
if debruijn.as_usize() + 1
|
||||||
|
@ -601,13 +596,13 @@ impl TypeFolder<'tcx> for BoundVarReplacer<'_, 'tcx> {
|
||||||
let universe = self.universe_for(debruijn);
|
let universe = self.universe_for(debruijn);
|
||||||
let p = ty::PlaceholderRegion { universe, name: br.kind };
|
let p = ty::PlaceholderRegion { universe, name: br.kind };
|
||||||
self.mapped_regions.insert(p, br);
|
self.mapped_regions.insert(p, br);
|
||||||
Ok(self.infcx.tcx.mk_region(ty::RePlaceholder(p)))
|
self.infcx.tcx.mk_region(ty::RePlaceholder(p))
|
||||||
}
|
}
|
||||||
_ => Ok(r),
|
_ => r,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
match *t.kind() {
|
match *t.kind() {
|
||||||
ty::Bound(debruijn, _)
|
ty::Bound(debruijn, _)
|
||||||
if debruijn.as_usize() + 1
|
if debruijn.as_usize() + 1
|
||||||
|
@ -619,17 +614,14 @@ impl TypeFolder<'tcx> for BoundVarReplacer<'_, 'tcx> {
|
||||||
let universe = self.universe_for(debruijn);
|
let universe = self.universe_for(debruijn);
|
||||||
let p = ty::PlaceholderType { universe, name: bound_ty.var };
|
let p = ty::PlaceholderType { universe, name: bound_ty.var };
|
||||||
self.mapped_types.insert(p, bound_ty);
|
self.mapped_types.insert(p, bound_ty);
|
||||||
Ok(self.infcx.tcx.mk_ty(ty::Placeholder(p)))
|
self.infcx.tcx.mk_ty(ty::Placeholder(p))
|
||||||
}
|
}
|
||||||
_ if t.has_vars_bound_at_or_above(self.current_index) => t.super_fold_with(self),
|
_ if t.has_vars_bound_at_or_above(self.current_index) => t.super_fold_with(self),
|
||||||
_ => Ok(t),
|
_ => t,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_const(
|
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||||
&mut self,
|
|
||||||
ct: &'tcx ty::Const<'tcx>,
|
|
||||||
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
|
|
||||||
match *ct {
|
match *ct {
|
||||||
ty::Const { val: ty::ConstKind::Bound(debruijn, _), ty: _ }
|
ty::Const { val: ty::ConstKind::Bound(debruijn, _), ty: _ }
|
||||||
if debruijn.as_usize() + 1
|
if debruijn.as_usize() + 1
|
||||||
|
@ -646,10 +638,10 @@ impl TypeFolder<'tcx> for BoundVarReplacer<'_, 'tcx> {
|
||||||
name: ty::BoundConst { var: bound_const, ty },
|
name: ty::BoundConst { var: bound_const, ty },
|
||||||
};
|
};
|
||||||
self.mapped_consts.insert(p, bound_const);
|
self.mapped_consts.insert(p, bound_const);
|
||||||
Ok(self.infcx.tcx.mk_const(ty::Const { val: ty::ConstKind::Placeholder(p), ty }))
|
self.infcx.tcx.mk_const(ty::Const { val: ty::ConstKind::Placeholder(p), ty })
|
||||||
}
|
}
|
||||||
_ if ct.has_vars_bound_at_or_above(self.current_index) => ct.super_fold_with(self),
|
_ if ct.has_vars_bound_at_or_above(self.current_index) => ct.super_fold_with(self),
|
||||||
_ => Ok(ct),
|
_ => ct,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -681,7 +673,7 @@ impl<'me, 'tcx> PlaceholderReplacer<'me, 'tcx> {
|
||||||
universe_indices,
|
universe_indices,
|
||||||
current_index: ty::INNERMOST,
|
current_index: ty::INNERMOST,
|
||||||
};
|
};
|
||||||
value.super_fold_with(&mut replacer).into_ok()
|
value.super_fold_with(&mut replacer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -693,9 +685,9 @@ impl TypeFolder<'tcx> for PlaceholderReplacer<'_, 'tcx> {
|
||||||
fn fold_binder<T: TypeFoldable<'tcx>>(
|
fn fold_binder<T: TypeFoldable<'tcx>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
t: ty::Binder<'tcx, T>,
|
t: ty::Binder<'tcx, T>,
|
||||||
) -> Result<ty::Binder<'tcx, T>, Self::Error> {
|
) -> ty::Binder<'tcx, T> {
|
||||||
if !t.has_placeholders() && !t.has_infer_regions() {
|
if !t.has_placeholders() && !t.has_infer_regions() {
|
||||||
return Ok(t);
|
return t;
|
||||||
}
|
}
|
||||||
self.current_index.shift_in(1);
|
self.current_index.shift_in(1);
|
||||||
let t = t.super_fold_with(self);
|
let t = t.super_fold_with(self);
|
||||||
|
@ -703,7 +695,7 @@ impl TypeFolder<'tcx> for PlaceholderReplacer<'_, 'tcx> {
|
||||||
t
|
t
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_region(&mut self, r0: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
fn fold_region(&mut self, r0: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||||
let r1 = match r0 {
|
let r1 = match r0 {
|
||||||
ty::ReVar(_) => self
|
ty::ReVar(_) => self
|
||||||
.infcx
|
.infcx
|
||||||
|
@ -737,10 +729,10 @@ impl TypeFolder<'tcx> for PlaceholderReplacer<'_, 'tcx> {
|
||||||
|
|
||||||
debug!(?r0, ?r1, ?r2, "fold_region");
|
debug!(?r0, ?r1, ?r2, "fold_region");
|
||||||
|
|
||||||
Ok(r2)
|
r2
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
match *ty.kind() {
|
match *ty.kind() {
|
||||||
ty::Placeholder(p) => {
|
ty::Placeholder(p) => {
|
||||||
let replace_var = self.mapped_types.get(&p);
|
let replace_var = self.mapped_types.get(&p);
|
||||||
|
@ -754,21 +746,18 @@ impl TypeFolder<'tcx> for PlaceholderReplacer<'_, 'tcx> {
|
||||||
let db = ty::DebruijnIndex::from_usize(
|
let db = ty::DebruijnIndex::from_usize(
|
||||||
self.universe_indices.len() - index + self.current_index.as_usize() - 1,
|
self.universe_indices.len() - index + self.current_index.as_usize() - 1,
|
||||||
);
|
);
|
||||||
Ok(self.tcx().mk_ty(ty::Bound(db, *replace_var)))
|
self.tcx().mk_ty(ty::Bound(db, *replace_var))
|
||||||
}
|
}
|
||||||
None => Ok(ty),
|
None => ty,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_ if ty.has_placeholders() || ty.has_infer_regions() => ty.super_fold_with(self),
|
_ if ty.has_placeholders() || ty.has_infer_regions() => ty.super_fold_with(self),
|
||||||
_ => Ok(ty),
|
_ => ty,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_const(
|
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||||
&mut self,
|
|
||||||
ct: &'tcx ty::Const<'tcx>,
|
|
||||||
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
|
|
||||||
if let ty::Const { val: ty::ConstKind::Placeholder(p), ty } = *ct {
|
if let ty::Const { val: ty::ConstKind::Placeholder(p), ty } = *ct {
|
||||||
let replace_var = self.mapped_consts.get(&p);
|
let replace_var = self.mapped_consts.get(&p);
|
||||||
match replace_var {
|
match replace_var {
|
||||||
|
@ -781,11 +770,10 @@ impl TypeFolder<'tcx> for PlaceholderReplacer<'_, 'tcx> {
|
||||||
let db = ty::DebruijnIndex::from_usize(
|
let db = ty::DebruijnIndex::from_usize(
|
||||||
self.universe_indices.len() - index + self.current_index.as_usize() - 1,
|
self.universe_indices.len() - index + self.current_index.as_usize() - 1,
|
||||||
);
|
);
|
||||||
Ok(self
|
self.tcx()
|
||||||
.tcx()
|
.mk_const(ty::Const { val: ty::ConstKind::Bound(db, *replace_var), ty })
|
||||||
.mk_const(ty::Const { val: ty::ConstKind::Bound(db, *replace_var), ty }))
|
|
||||||
}
|
}
|
||||||
None => Ok(ct),
|
None => ct,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ct.super_fold_with(self)
|
ct.super_fold_with(self)
|
||||||
|
@ -1546,8 +1534,7 @@ fn confirm_candidate<'cx, 'tcx>(
|
||||||
// when possible for this to work. See `auto-trait-projection-recursion.rs`
|
// when possible for this to work. See `auto-trait-projection-recursion.rs`
|
||||||
// for a case where this matters.
|
// for a case where this matters.
|
||||||
if progress.ty.has_infer_regions() {
|
if progress.ty.has_infer_regions() {
|
||||||
progress.ty =
|
progress.ty = OpportunisticRegionResolver::new(selcx.infcx()).fold_ty(progress.ty);
|
||||||
OpportunisticRegionResolver::new(selcx.infcx()).fold_ty(progress.ty).into_ok();
|
|
||||||
}
|
}
|
||||||
progress
|
progress
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ use rustc_data_structures::sso::SsoHashMap;
|
||||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||||
use rustc_infer::traits::Normalized;
|
use rustc_infer::traits::Normalized;
|
||||||
use rustc_middle::mir;
|
use rustc_middle::mir;
|
||||||
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder};
|
use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder};
|
||||||
use rustc_middle::ty::subst::Subst;
|
use rustc_middle::ty::subst::Subst;
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitor};
|
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitor};
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ impl<'cx, 'tcx> AtExt<'tcx> for At<'cx, 'tcx> {
|
||||||
normalizer.universes.extend((0..max_visitor.escaping).map(|_| None));
|
normalizer.universes.extend((0..max_visitor.escaping).map(|_| None));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let result = value.fold_with(&mut normalizer);
|
let result = value.try_fold_with(&mut normalizer);
|
||||||
info!(
|
info!(
|
||||||
"normalize::<{}>: result={:?} with {} obligations",
|
"normalize::<{}>: result={:?} with {} obligations",
|
||||||
std::any::type_name::<T>(),
|
std::any::type_name::<T>(),
|
||||||
|
@ -176,19 +176,21 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
||||||
fn tcx<'c>(&'c self) -> TyCtxt<'tcx> {
|
fn tcx<'c>(&'c self) -> TyCtxt<'tcx> {
|
||||||
self.infcx.tcx
|
self.infcx.tcx
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn fold_binder<T: TypeFoldable<'tcx>>(
|
impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
||||||
|
fn try_fold_binder<T: TypeFoldable<'tcx>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
t: ty::Binder<'tcx, T>,
|
t: ty::Binder<'tcx, T>,
|
||||||
) -> Result<ty::Binder<'tcx, T>, Self::Error> {
|
) -> Result<ty::Binder<'tcx, T>, Self::Error> {
|
||||||
self.universes.push(None);
|
self.universes.push(None);
|
||||||
let t = t.super_fold_with(self);
|
let t = t.try_super_fold_with(self);
|
||||||
self.universes.pop();
|
self.universes.pop();
|
||||||
t
|
t
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "debug", skip(self))]
|
#[instrument(level = "debug", skip(self))]
|
||||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
fn try_fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||||
if !needs_normalization(&ty, self.param_env.reveal()) {
|
if !needs_normalization(&ty, self.param_env.reveal()) {
|
||||||
return Ok(ty);
|
return Ok(ty);
|
||||||
}
|
}
|
||||||
|
@ -208,10 +210,10 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
||||||
ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => {
|
ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => {
|
||||||
// Only normalize `impl Trait` after type-checking, usually in codegen.
|
// Only normalize `impl Trait` after type-checking, usually in codegen.
|
||||||
match self.param_env.reveal() {
|
match self.param_env.reveal() {
|
||||||
Reveal::UserFacing => ty.super_fold_with(self),
|
Reveal::UserFacing => ty.try_super_fold_with(self),
|
||||||
|
|
||||||
Reveal::All => {
|
Reveal::All => {
|
||||||
let substs = substs.super_fold_with(self)?;
|
let substs = substs.try_super_fold_with(self)?;
|
||||||
let recursion_limit = self.tcx().recursion_limit();
|
let recursion_limit = self.tcx().recursion_limit();
|
||||||
if !recursion_limit.value_within_limit(self.anon_depth) {
|
if !recursion_limit.value_within_limit(self.anon_depth) {
|
||||||
let obligation = Obligation::with_depth(
|
let obligation = Obligation::with_depth(
|
||||||
|
@ -236,7 +238,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
||||||
ty
|
ty
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
let folded_ty = ensure_sufficient_stack(|| self.fold_ty(concrete_ty));
|
let folded_ty = ensure_sufficient_stack(|| self.try_fold_ty(concrete_ty));
|
||||||
self.anon_depth -= 1;
|
self.anon_depth -= 1;
|
||||||
folded_ty
|
folded_ty
|
||||||
}
|
}
|
||||||
|
@ -248,7 +250,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
||||||
// we don't need to replace them with placeholders (see branch below).
|
// we don't need to replace them with placeholders (see branch below).
|
||||||
|
|
||||||
let tcx = self.infcx.tcx;
|
let tcx = self.infcx.tcx;
|
||||||
let data = data.super_fold_with(self)?;
|
let data = data.try_super_fold_with(self)?;
|
||||||
|
|
||||||
let mut orig_values = OriginalQueryValues::default();
|
let mut orig_values = OriginalQueryValues::default();
|
||||||
// HACK(matthewjasper) `'static` is special-cased in selection,
|
// HACK(matthewjasper) `'static` is special-cased in selection,
|
||||||
|
@ -287,7 +289,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
||||||
&mut self.universes,
|
&mut self.universes,
|
||||||
data,
|
data,
|
||||||
);
|
);
|
||||||
let data = data.super_fold_with(self)?;
|
let data = data.try_super_fold_with(self)?;
|
||||||
|
|
||||||
let mut orig_values = OriginalQueryValues::default();
|
let mut orig_values = OriginalQueryValues::default();
|
||||||
// HACK(matthewjasper) `'static` is special-cased in selection,
|
// HACK(matthewjasper) `'static` is special-cased in selection,
|
||||||
|
@ -322,24 +324,24 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => ty.super_fold_with(self),
|
_ => ty.try_super_fold_with(self),
|
||||||
})()?;
|
})()?;
|
||||||
self.cache.insert(ty, res);
|
self.cache.insert(ty, res);
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_const(
|
fn try_fold_const(
|
||||||
&mut self,
|
&mut self,
|
||||||
constant: &'tcx ty::Const<'tcx>,
|
constant: &'tcx ty::Const<'tcx>,
|
||||||
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
|
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
|
||||||
let constant = constant.super_fold_with(self)?;
|
let constant = constant.try_super_fold_with(self)?;
|
||||||
Ok(constant.eval(self.infcx.tcx, self.param_env))
|
Ok(constant.eval(self.infcx.tcx, self.param_env))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_mir_const(
|
fn try_fold_mir_const(
|
||||||
&mut self,
|
&mut self,
|
||||||
constant: mir::ConstantKind<'tcx>,
|
constant: mir::ConstantKind<'tcx>,
|
||||||
) -> Result<mir::ConstantKind<'tcx>, Self::Error> {
|
) -> Result<mir::ConstantKind<'tcx>, Self::Error> {
|
||||||
constant.super_fold_with(self)
|
constant.try_super_fold_with(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2154,7 +2154,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
previous_stack: TraitObligationStackList<'o, 'tcx>,
|
previous_stack: TraitObligationStackList<'o, 'tcx>,
|
||||||
obligation: &'o TraitObligation<'tcx>,
|
obligation: &'o TraitObligation<'tcx>,
|
||||||
) -> TraitObligationStack<'o, 'tcx> {
|
) -> TraitObligationStack<'o, 'tcx> {
|
||||||
let fresh_trait_pred = obligation.predicate.fold_with(&mut self.freshener).into_ok();
|
let fresh_trait_pred = obligation.predicate.fold_with(&mut self.freshener);
|
||||||
|
|
||||||
let dfn = previous_stack.cache.next_dfn();
|
let dfn = previous_stack.cache.next_dfn();
|
||||||
let depth = previous_stack.depth() + 1;
|
let depth = previous_stack.depth() + 1;
|
||||||
|
|
|
@ -45,7 +45,7 @@ impl<'tcx> RustIrDatabase<'tcx> {
|
||||||
predicates
|
predicates
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(wc, _)| wc.subst(self.interner.tcx, bound_vars))
|
.map(|(wc, _)| wc.subst(self.interner.tcx, bound_vars))
|
||||||
.map(|wc| wc.fold_with(&mut regions_substitutor).into_ok())
|
.map(|wc| wc.fold_with(&mut regions_substitutor))
|
||||||
.filter_map(|wc| LowerInto::<Option<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>>>::lower_into(wc, &self.interner)).collect()
|
.filter_map(|wc| LowerInto::<Option<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>>>::lower_into(wc, &self.interner)).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,7 +287,7 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
|
||||||
let trait_ref = trait_ref.subst(self.interner.tcx, bound_vars);
|
let trait_ref = trait_ref.subst(self.interner.tcx, bound_vars);
|
||||||
let mut regions_substitutor =
|
let mut regions_substitutor =
|
||||||
lowering::RegionsSubstitutor::new(self.interner.tcx, self.reempty_placeholder);
|
lowering::RegionsSubstitutor::new(self.interner.tcx, self.reempty_placeholder);
|
||||||
let trait_ref = trait_ref.fold_with(&mut regions_substitutor).into_ok();
|
let trait_ref = trait_ref.fold_with(&mut regions_substitutor);
|
||||||
|
|
||||||
let where_clauses = self.where_clauses_for(def_id, bound_vars);
|
let where_clauses = self.where_clauses_for(def_id, bound_vars);
|
||||||
|
|
||||||
|
@ -335,7 +335,7 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
|
||||||
let self_ty = self_ty.subst(self.interner.tcx, bound_vars);
|
let self_ty = self_ty.subst(self.interner.tcx, bound_vars);
|
||||||
let mut regions_substitutor =
|
let mut regions_substitutor =
|
||||||
lowering::RegionsSubstitutor::new(self.interner.tcx, self.reempty_placeholder);
|
lowering::RegionsSubstitutor::new(self.interner.tcx, self.reempty_placeholder);
|
||||||
let self_ty = self_ty.fold_with(&mut regions_substitutor).into_ok();
|
let self_ty = self_ty.fold_with(&mut regions_substitutor);
|
||||||
let lowered_ty = self_ty.lower_into(&self.interner);
|
let lowered_ty = self_ty.lower_into(&self.interner);
|
||||||
|
|
||||||
parameters[0].assert_ty_ref(&self.interner).could_match(
|
parameters[0].assert_ty_ref(&self.interner).could_match(
|
||||||
|
@ -501,24 +501,22 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(bound, _)| bound.subst(self.interner.tcx, &bound_vars))
|
.map(|(bound, _)| bound.subst(self.interner.tcx, &bound_vars))
|
||||||
.map(|bound| {
|
.map(|bound| {
|
||||||
bound
|
bound.fold_with(&mut ty::fold::BottomUpFolder {
|
||||||
.fold_with(&mut ty::fold::BottomUpFolder {
|
tcx: self.interner.tcx,
|
||||||
tcx: self.interner.tcx,
|
ty_op: |ty| {
|
||||||
ty_op: |ty| {
|
if let ty::Opaque(def_id, substs) = *ty.kind() {
|
||||||
if let ty::Opaque(def_id, substs) = *ty.kind() {
|
if def_id == opaque_ty_id.0 && substs == identity_substs {
|
||||||
if def_id == opaque_ty_id.0 && substs == identity_substs {
|
return self.interner.tcx.mk_ty(ty::Bound(
|
||||||
return self.interner.tcx.mk_ty(ty::Bound(
|
ty::INNERMOST,
|
||||||
ty::INNERMOST,
|
ty::BoundTy::from(ty::BoundVar::from_u32(0)),
|
||||||
ty::BoundTy::from(ty::BoundVar::from_u32(0)),
|
));
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ty
|
}
|
||||||
},
|
ty
|
||||||
lt_op: |lt| lt,
|
},
|
||||||
ct_op: |ct| ct,
|
lt_op: |lt| lt,
|
||||||
})
|
ct_op: |ct| ct,
|
||||||
.into_ok()
|
})
|
||||||
})
|
})
|
||||||
.filter_map(|bound| {
|
.filter_map(|bound| {
|
||||||
LowerInto::<
|
LowerInto::<
|
||||||
|
|
|
@ -817,7 +817,7 @@ crate fn collect_bound_vars<'tcx, T: TypeFoldable<'tcx>>(
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let mut bound_var_substitutor = NamedBoundVarSubstitutor::new(tcx, &named_parameters);
|
let mut bound_var_substitutor = NamedBoundVarSubstitutor::new(tcx, &named_parameters);
|
||||||
let new_ty = ty.skip_binder().fold_with(&mut bound_var_substitutor).into_ok();
|
let new_ty = ty.skip_binder().fold_with(&mut bound_var_substitutor);
|
||||||
|
|
||||||
for var in named_parameters.values() {
|
for var in named_parameters.values() {
|
||||||
parameters.insert(*var, chalk_ir::VariableKind::Lifetime);
|
parameters.insert(*var, chalk_ir::VariableKind::Lifetime);
|
||||||
|
@ -943,23 +943,20 @@ impl<'a, 'tcx> TypeFolder<'tcx> for NamedBoundVarSubstitutor<'a, 'tcx> {
|
||||||
self.tcx
|
self.tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_binder<T: TypeFoldable<'tcx>>(
|
fn fold_binder<T: TypeFoldable<'tcx>>(&mut self, t: Binder<'tcx, T>) -> Binder<'tcx, T> {
|
||||||
&mut self,
|
|
||||||
t: Binder<'tcx, T>,
|
|
||||||
) -> Result<Binder<'tcx, T>, Self::Error> {
|
|
||||||
self.binder_index.shift_in(1);
|
self.binder_index.shift_in(1);
|
||||||
let result = t.super_fold_with(self);
|
let result = t.super_fold_with(self);
|
||||||
self.binder_index.shift_out(1);
|
self.binder_index.shift_out(1);
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_region(&mut self, r: Region<'tcx>) -> Result<Region<'tcx>, Self::Error> {
|
fn fold_region(&mut self, r: Region<'tcx>) -> Region<'tcx> {
|
||||||
match r {
|
match r {
|
||||||
ty::ReLateBound(index, br) if *index == self.binder_index => match br.kind {
|
ty::ReLateBound(index, br) if *index == self.binder_index => match br.kind {
|
||||||
ty::BrNamed(def_id, _name) => match self.named_parameters.get(&def_id) {
|
ty::BrNamed(def_id, _name) => match self.named_parameters.get(&def_id) {
|
||||||
Some(idx) => {
|
Some(idx) => {
|
||||||
let new_br = ty::BoundRegion { var: br.var, kind: ty::BrAnon(*idx) };
|
let new_br = ty::BoundRegion { var: br.var, kind: ty::BrAnon(*idx) };
|
||||||
return Ok(self.tcx.mk_region(RegionKind::ReLateBound(*index, new_br)));
|
return self.tcx.mk_region(RegionKind::ReLateBound(*index, new_br));
|
||||||
}
|
}
|
||||||
None => panic!("Missing `BrNamed`."),
|
None => panic!("Missing `BrNamed`."),
|
||||||
},
|
},
|
||||||
|
@ -1002,35 +999,32 @@ impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> {
|
||||||
self.tcx
|
self.tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_binder<T: TypeFoldable<'tcx>>(
|
fn fold_binder<T: TypeFoldable<'tcx>>(&mut self, t: Binder<'tcx, T>) -> Binder<'tcx, T> {
|
||||||
&mut self,
|
|
||||||
t: Binder<'tcx, T>,
|
|
||||||
) -> Result<Binder<'tcx, T>, Self::Error> {
|
|
||||||
self.binder_index.shift_in(1);
|
self.binder_index.shift_in(1);
|
||||||
let result = t.super_fold_with(self);
|
let result = t.super_fold_with(self);
|
||||||
self.binder_index.shift_out(1);
|
self.binder_index.shift_out(1);
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
match *t.kind() {
|
match *t.kind() {
|
||||||
// FIXME(chalk): currently we convert params to placeholders starting at
|
// FIXME(chalk): currently we convert params to placeholders starting at
|
||||||
// index `0`. To support placeholders, we'll actually need to do a
|
// index `0`. To support placeholders, we'll actually need to do a
|
||||||
// first pass to collect placeholders. Then we can insert params after.
|
// first pass to collect placeholders. Then we can insert params after.
|
||||||
ty::Placeholder(_) => unimplemented!(),
|
ty::Placeholder(_) => unimplemented!(),
|
||||||
ty::Param(param) => match self.list.iter().position(|r| r == ¶m) {
|
ty::Param(param) => match self.list.iter().position(|r| r == ¶m) {
|
||||||
Some(idx) => Ok(self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType {
|
Some(idx) => self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType {
|
||||||
universe: ty::UniverseIndex::from_usize(0),
|
universe: ty::UniverseIndex::from_usize(0),
|
||||||
name: ty::BoundVar::from_usize(idx),
|
name: ty::BoundVar::from_usize(idx),
|
||||||
}))),
|
})),
|
||||||
None => {
|
None => {
|
||||||
self.list.push(param);
|
self.list.push(param);
|
||||||
let idx = self.list.len() - 1 + self.next_ty_placeholder;
|
let idx = self.list.len() - 1 + self.next_ty_placeholder;
|
||||||
self.params.insert(idx, param);
|
self.params.insert(idx, param);
|
||||||
Ok(self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType {
|
self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType {
|
||||||
universe: ty::UniverseIndex::from_usize(0),
|
universe: ty::UniverseIndex::from_usize(0),
|
||||||
name: ty::BoundVar::from_usize(idx),
|
name: ty::BoundVar::from_usize(idx),
|
||||||
})))
|
}))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1038,7 +1032,7 @@ impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_region(&mut self, r: Region<'tcx>) -> Result<Region<'tcx>, Self::Error> {
|
fn fold_region(&mut self, r: Region<'tcx>) -> Region<'tcx> {
|
||||||
match r {
|
match r {
|
||||||
// FIXME(chalk) - jackh726 - this currently isn't hit in any tests.
|
// FIXME(chalk) - jackh726 - this currently isn't hit in any tests.
|
||||||
// This covers any region variables in a goal, right?
|
// This covers any region variables in a goal, right?
|
||||||
|
@ -1048,14 +1042,14 @@ impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> {
|
||||||
var: ty::BoundVar::from_u32(*idx),
|
var: ty::BoundVar::from_u32(*idx),
|
||||||
kind: ty::BrAnon(*idx),
|
kind: ty::BrAnon(*idx),
|
||||||
};
|
};
|
||||||
Ok(self.tcx.mk_region(RegionKind::ReLateBound(self.binder_index, br)))
|
self.tcx.mk_region(RegionKind::ReLateBound(self.binder_index, br))
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
let idx = self.named_regions.len() as u32;
|
let idx = self.named_regions.len() as u32;
|
||||||
let br =
|
let br =
|
||||||
ty::BoundRegion { var: ty::BoundVar::from_u32(idx), kind: ty::BrAnon(idx) };
|
ty::BoundRegion { var: ty::BoundVar::from_u32(idx), kind: ty::BrAnon(idx) };
|
||||||
self.named_regions.insert(_re.def_id, idx);
|
self.named_regions.insert(_re.def_id, idx);
|
||||||
Ok(self.tcx.mk_region(RegionKind::ReLateBound(self.binder_index, br)))
|
self.tcx.mk_region(RegionKind::ReLateBound(self.binder_index, br))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -1131,11 +1125,11 @@ impl<'tcx> TypeFolder<'tcx> for RegionsSubstitutor<'tcx> {
|
||||||
self.tcx
|
self.tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_region(&mut self, r: Region<'tcx>) -> Result<Region<'tcx>, Self::Error> {
|
fn fold_region(&mut self, r: Region<'tcx>) -> Region<'tcx> {
|
||||||
match r {
|
match r {
|
||||||
ty::ReEmpty(ui) => {
|
ty::ReEmpty(ui) => {
|
||||||
assert_eq!(ui.as_usize(), 0);
|
assert_eq!(ui.as_usize(), 0);
|
||||||
Ok(self.reempty_placeholder)
|
self.reempty_placeholder
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => r.super_fold_with(self),
|
_ => r.super_fold_with(self),
|
||||||
|
|
|
@ -49,12 +49,12 @@ crate fn evaluate_goal<'tcx>(
|
||||||
|
|
||||||
let mut params_substitutor =
|
let mut params_substitutor =
|
||||||
ParamsSubstitutor::new(tcx, placeholders_collector.next_ty_placeholder);
|
ParamsSubstitutor::new(tcx, placeholders_collector.next_ty_placeholder);
|
||||||
let obligation = obligation.fold_with(&mut params_substitutor).into_ok();
|
let obligation = obligation.fold_with(&mut params_substitutor);
|
||||||
// FIXME(chalk): we really should be substituting these back in the solution
|
// FIXME(chalk): we really should be substituting these back in the solution
|
||||||
let _params: FxHashMap<usize, ParamTy> = params_substitutor.params;
|
let _params: FxHashMap<usize, ParamTy> = params_substitutor.params;
|
||||||
|
|
||||||
let mut regions_substitutor = RegionsSubstitutor::new(tcx, reempty_placeholder);
|
let mut regions_substitutor = RegionsSubstitutor::new(tcx, reempty_placeholder);
|
||||||
let obligation = obligation.fold_with(&mut regions_substitutor).into_ok();
|
let obligation = obligation.fold_with(&mut regions_substitutor);
|
||||||
|
|
||||||
let max_universe = obligation.max_universe.index();
|
let max_universe = obligation.max_universe.index();
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
#![feature(crate_visibility_modifier)]
|
#![feature(crate_visibility_modifier)]
|
||||||
#![feature(in_band_lifetimes)]
|
#![feature(in_band_lifetimes)]
|
||||||
#![feature(nll)]
|
#![feature(nll)]
|
||||||
#![feature(unwrap_infallible)]
|
|
||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
|
|
@ -442,8 +442,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
let mut eraser = TypeParamEraser(self, expr.span);
|
let mut eraser = TypeParamEraser(self, expr.span);
|
||||||
let needs_bound = self
|
let needs_bound = self
|
||||||
.lookup_op_method(
|
.lookup_op_method(
|
||||||
eraser.fold_ty(lhs_ty).into_ok(),
|
eraser.fold_ty(lhs_ty),
|
||||||
&[eraser.fold_ty(rhs_ty).into_ok()],
|
&[eraser.fold_ty(rhs_ty)],
|
||||||
Op::Binary(op, is_assign),
|
Op::Binary(op, is_assign),
|
||||||
)
|
)
|
||||||
.is_ok();
|
.is_ok();
|
||||||
|
@ -1015,12 +1015,12 @@ impl TypeFolder<'tcx> for TypeParamEraser<'_, 'tcx> {
|
||||||
self.0.tcx
|
self.0.tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
match ty.kind() {
|
match ty.kind() {
|
||||||
ty::Param(_) => Ok(self.0.next_ty_var(TypeVariableOrigin {
|
ty::Param(_) => self.0.next_ty_var(TypeVariableOrigin {
|
||||||
kind: TypeVariableOriginKind::MiscVariable,
|
kind: TypeVariableOriginKind::MiscVariable,
|
||||||
span: self.1,
|
span: self.1,
|
||||||
})),
|
}),
|
||||||
_ => ty.super_fold_with(self),
|
_ => ty.super_fold_with(self),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -658,7 +658,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
||||||
T: TypeFoldable<'tcx>,
|
T: TypeFoldable<'tcx>,
|
||||||
{
|
{
|
||||||
let mut resolver = Resolver::new(self.fcx, span, self.body);
|
let mut resolver = Resolver::new(self.fcx, span, self.body);
|
||||||
let x = x.fold_with(&mut resolver).into_ok();
|
let x = x.fold_with(&mut resolver);
|
||||||
if cfg!(debug_assertions) && x.needs_infer() {
|
if cfg!(debug_assertions) && x.needs_infer() {
|
||||||
span_bug!(span.to_span(self.fcx.tcx), "writeback: `{:?}` has inference variables", x);
|
span_bug!(span.to_span(self.fcx.tcx), "writeback: `{:?}` has inference variables", x);
|
||||||
}
|
}
|
||||||
|
@ -749,15 +749,15 @@ impl<'tcx> TypeFolder<'tcx> for EraseEarlyRegions<'tcx> {
|
||||||
fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
|
fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
|
||||||
self.tcx
|
self.tcx
|
||||||
}
|
}
|
||||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
if ty.has_type_flags(ty::TypeFlags::HAS_POTENTIAL_FREE_REGIONS) {
|
if ty.has_type_flags(ty::TypeFlags::HAS_POTENTIAL_FREE_REGIONS) {
|
||||||
ty.super_fold_with(self)
|
ty.super_fold_with(self)
|
||||||
} else {
|
} else {
|
||||||
Ok(ty)
|
ty
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||||
Ok(if let ty::ReLateBound(..) = r { r } else { self.tcx.lifetimes.re_erased })
|
if let ty::ReLateBound(..) = r { r } else { self.tcx.lifetimes.re_erased }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -766,7 +766,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Resolver<'cx, 'tcx> {
|
||||||
self.tcx
|
self.tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
match self.infcx.fully_resolve(t) {
|
match self.infcx.fully_resolve(t) {
|
||||||
Ok(t) => {
|
Ok(t) => {
|
||||||
// Do not anonymize late-bound regions
|
// Do not anonymize late-bound regions
|
||||||
|
@ -779,21 +779,18 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Resolver<'cx, 'tcx> {
|
||||||
debug!("Resolver::fold_ty: input type `{:?}` not fully resolvable", t);
|
debug!("Resolver::fold_ty: input type `{:?}` not fully resolvable", t);
|
||||||
self.report_type_error(t);
|
self.report_type_error(t);
|
||||||
self.replaced_with_error = true;
|
self.replaced_with_error = true;
|
||||||
Ok(self.tcx().ty_error())
|
self.tcx().ty_error()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||||
debug_assert!(!r.is_late_bound(), "Should not be resolving bound region.");
|
debug_assert!(!r.is_late_bound(), "Should not be resolving bound region.");
|
||||||
Ok(self.tcx.lifetimes.re_erased)
|
self.tcx.lifetimes.re_erased
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_const(
|
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||||
&mut self,
|
match self.infcx.fully_resolve(ct) {
|
||||||
ct: &'tcx ty::Const<'tcx>,
|
|
||||||
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
|
|
||||||
Ok(match self.infcx.fully_resolve(ct) {
|
|
||||||
Ok(ct) => self.infcx.tcx.erase_regions(ct),
|
Ok(ct) => self.infcx.tcx.erase_regions(ct),
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
debug!("Resolver::fold_const: input const `{:?}` not fully resolvable", ct);
|
debug!("Resolver::fold_const: input const `{:?}` not fully resolvable", ct);
|
||||||
|
@ -801,7 +798,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Resolver<'cx, 'tcx> {
|
||||||
self.replaced_with_error = true;
|
self.replaced_with_error = true;
|
||||||
self.tcx().const_error(ct.ty)
|
self.tcx().const_error(ct.ty)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -729,17 +729,17 @@ fn infer_placeholder_type<'a>(
|
||||||
self.tcx
|
self.tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
if !self.success {
|
if !self.success {
|
||||||
return Ok(ty);
|
return ty;
|
||||||
}
|
}
|
||||||
|
|
||||||
match ty.kind() {
|
match ty.kind() {
|
||||||
ty::FnDef(def_id, _) => Ok(self.tcx.mk_fn_ptr(self.tcx.fn_sig(*def_id))),
|
ty::FnDef(def_id, _) => self.tcx.mk_fn_ptr(self.tcx.fn_sig(*def_id)),
|
||||||
// FIXME: non-capturing closures should also suggest a function pointer
|
// FIXME: non-capturing closures should also suggest a function pointer
|
||||||
ty::Closure(..) | ty::Generator(..) => {
|
ty::Closure(..) | ty::Generator(..) => {
|
||||||
self.success = false;
|
self.success = false;
|
||||||
Ok(ty)
|
ty
|
||||||
}
|
}
|
||||||
_ => ty.super_fold_with(self),
|
_ => ty.super_fold_with(self),
|
||||||
}
|
}
|
||||||
|
@ -761,7 +761,7 @@ fn infer_placeholder_type<'a>(
|
||||||
|
|
||||||
// Suggesting unnameable types won't help.
|
// Suggesting unnameable types won't help.
|
||||||
let mut mk_nameable = MakeNameable::new(tcx);
|
let mut mk_nameable = MakeNameable::new(tcx);
|
||||||
let ty = mk_nameable.fold_ty(ty).into_ok();
|
let ty = mk_nameable.fold_ty(ty);
|
||||||
let sugg_ty = if mk_nameable.success { Some(ty) } else { None };
|
let sugg_ty = if mk_nameable.success { Some(ty) } else { None };
|
||||||
if let Some(sugg_ty) = sugg_ty {
|
if let Some(sugg_ty) = sugg_ty {
|
||||||
err.span_suggestion(
|
err.span_suggestion(
|
||||||
|
@ -785,7 +785,7 @@ fn infer_placeholder_type<'a>(
|
||||||
|
|
||||||
if !ty.references_error() {
|
if !ty.references_error() {
|
||||||
let mut mk_nameable = MakeNameable::new(tcx);
|
let mut mk_nameable = MakeNameable::new(tcx);
|
||||||
let ty = mk_nameable.fold_ty(ty).into_ok();
|
let ty = mk_nameable.fold_ty(ty);
|
||||||
let sugg_ty = if mk_nameable.success { Some(ty) } else { None };
|
let sugg_ty = if mk_nameable.success { Some(ty) } else { None };
|
||||||
if let Some(sugg_ty) = sugg_ty {
|
if let Some(sugg_ty) = sugg_ty {
|
||||||
diag.span_suggestion(
|
diag.span_suggestion(
|
||||||
|
|
|
@ -71,11 +71,8 @@ fn diagnostic_hir_wf_check<'tcx>(
|
||||||
fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
|
fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
|
||||||
self.tcx.infer_ctxt().enter(|infcx| {
|
self.tcx.infer_ctxt().enter(|infcx| {
|
||||||
let mut fulfill = traits::FulfillmentContext::new();
|
let mut fulfill = traits::FulfillmentContext::new();
|
||||||
let tcx_ty = self
|
let tcx_ty =
|
||||||
.icx
|
self.icx.to_ty(ty).fold_with(&mut EraseAllBoundRegions { tcx: self.tcx });
|
||||||
.to_ty(ty)
|
|
||||||
.fold_with(&mut EraseAllBoundRegions { tcx: self.tcx })
|
|
||||||
.into_ok();
|
|
||||||
let cause = traits::ObligationCause::new(
|
let cause = traits::ObligationCause::new(
|
||||||
ty.span,
|
ty.span,
|
||||||
self.hir_id,
|
self.hir_id,
|
||||||
|
@ -186,7 +183,7 @@ impl<'tcx> TypeFolder<'tcx> for EraseAllBoundRegions<'tcx> {
|
||||||
fn tcx<'a>(&'a self) -> TyCtxt<'tcx> {
|
fn tcx<'a>(&'a self) -> TyCtxt<'tcx> {
|
||||||
self.tcx
|
self.tcx
|
||||||
}
|
}
|
||||||
fn fold_region(&mut self, r: Region<'tcx>) -> Result<Region<'tcx>, Self::Error> {
|
fn fold_region(&mut self, r: Region<'tcx>) -> Region<'tcx> {
|
||||||
if let ty::ReLateBound(..) = r { Ok(&ty::ReErased) } else { Ok(r) }
|
if let ty::ReLateBound(..) = r { &ty::ReErased } else { r }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,6 @@ This API is completely unstable and subject to change.
|
||||||
#![feature(slice_partition_dedup)]
|
#![feature(slice_partition_dedup)]
|
||||||
#![feature(control_flow_enum)]
|
#![feature(control_flow_enum)]
|
||||||
#![feature(hash_drain_filter)]
|
#![feature(hash_drain_filter)]
|
||||||
#![feature(unwrap_infallible)]
|
|
||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
|
|
@ -449,7 +449,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.map(|p| p.fold_with(&mut replacer).into_ok());
|
.map(|p| p.fold_with(&mut replacer));
|
||||||
|
|
||||||
let mut generic_params =
|
let mut generic_params =
|
||||||
(tcx.generics_of(item_def_id), tcx.explicit_predicates_of(item_def_id))
|
(tcx.generics_of(item_def_id), tcx.explicit_predicates_of(item_def_id))
|
||||||
|
@ -714,11 +714,11 @@ impl<'a, 'tcx> TypeFolder<'tcx> for RegionReplacer<'a, 'tcx> {
|
||||||
self.tcx
|
self.tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||||
Ok((match *r {
|
(match *r {
|
||||||
ty::ReVar(vid) => self.vid_to_region.get(&vid).cloned(),
|
ty::ReVar(vid) => self.vid_to_region.get(&vid).cloned(),
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
.unwrap_or_else(|| r.super_fold_with(self).into_ok()))
|
.unwrap_or_else(|| r.super_fold_with(self))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
#![feature(type_ascription)]
|
#![feature(type_ascription)]
|
||||||
#![feature(iter_intersperse)]
|
#![feature(iter_intersperse)]
|
||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
#![feature(unwrap_infallible)]
|
|
||||||
#![warn(rustc::internal)]
|
#![warn(rustc::internal)]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue