mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
Auto merge of #91230 - eggyal:fallible-type-fold, r=jackh726
Make `TypeFolder::fold_*` return `Result` Implements rust-lang/compiler-team#432. Initially this is just a rebase of `@LeSeulArtichaut's` work in #85469 (abandoned; see https://github.com/rust-lang/rust/pull/85485#issuecomment-908781112). At that time, it caused a regression in performance that required some further exploration... with this rebased PR bors can hopefully report some perf analysis from which we can investigate further (if the regression is indeed still present). r? `@jackh726` cc `@nikomatsakis`
This commit is contained in:
commit
e6d2de9483
@ -23,6 +23,7 @@ Rust MIR: a lowered representation of Rust.
|
||||
#![feature(trusted_len)]
|
||||
#![feature(trusted_step)]
|
||||
#![feature(try_blocks)]
|
||||
#![feature(unwrap_infallible)]
|
||||
#![recursion_limit = "256"]
|
||||
|
||||
#[macro_use]
|
||||
|
@ -95,7 +95,8 @@ pub fn equal_up_to_regions(
|
||||
// Leave consts and types unchanged.
|
||||
ct_op: |ct| ct,
|
||||
ty_op: |ty| ty,
|
||||
}),
|
||||
})
|
||||
.into_ok(),
|
||||
)
|
||||
};
|
||||
tcx.infer_ctxt().enter(|infcx| infcx.can_eq(param_env, normalize(src), normalize(dest)).is_ok())
|
||||
|
@ -1,35 +1,42 @@
|
||||
use rustc_index::vec::{Idx, IndexVec};
|
||||
use std::mem;
|
||||
use std::ptr;
|
||||
|
||||
pub trait IdFunctor {
|
||||
pub trait IdFunctor: Sized {
|
||||
type Inner;
|
||||
|
||||
fn map_id<F>(self, f: F) -> Self
|
||||
where
|
||||
F: FnMut(Self::Inner) -> Self::Inner;
|
||||
}
|
||||
|
||||
impl<T> IdFunctor for Box<T> {
|
||||
type Inner = T;
|
||||
|
||||
#[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>
|
||||
where
|
||||
F: FnMut(Self::Inner) -> Result<Self::Inner, E>;
|
||||
}
|
||||
|
||||
impl<T> IdFunctor for Box<T> {
|
||||
type Inner = T;
|
||||
|
||||
#[inline]
|
||||
fn try_map_id<F, E>(self, mut f: F) -> Result<Self, E>
|
||||
where
|
||||
F: FnMut(Self::Inner) -> Result<Self::Inner, E>,
|
||||
{
|
||||
let raw = Box::into_raw(self);
|
||||
unsafe {
|
||||
Ok(unsafe {
|
||||
// SAFETY: The raw pointer points to a valid value of type `T`.
|
||||
let value = ptr::read(raw);
|
||||
let value = raw.read();
|
||||
// SAFETY: Converts `Box<T>` to `Box<MaybeUninit<T>>` which is the
|
||||
// inverse of `Box::assume_init()` and should be safe.
|
||||
let mut raw: Box<mem::MaybeUninit<T>> = Box::from_raw(raw.cast());
|
||||
// SAFETY: Write the mapped value back into the `Box`.
|
||||
raw.write(f(value));
|
||||
raw.write(f(value)?);
|
||||
// SAFETY: We just initialized `raw`.
|
||||
raw.assume_init()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,9 +44,9 @@ impl<T> IdFunctor for Vec<T> {
|
||||
type Inner = T;
|
||||
|
||||
#[inline]
|
||||
fn map_id<F>(mut self, mut f: F) -> Self
|
||||
fn try_map_id<F, E>(mut self, mut f: F) -> Result<Self, E>
|
||||
where
|
||||
F: FnMut(Self::Inner) -> Self::Inner,
|
||||
F: FnMut(Self::Inner) -> Result<Self::Inner, E>,
|
||||
{
|
||||
// FIXME: We don't really care about panics here and leak
|
||||
// far more than we should, but that should be fine for now.
|
||||
@ -49,11 +56,26 @@ impl<T> IdFunctor for Vec<T> {
|
||||
let start = self.as_mut_ptr();
|
||||
for i in 0..len {
|
||||
let p = start.add(i);
|
||||
ptr::write(p, f(ptr::read(p)));
|
||||
match f(p.read()) {
|
||||
Ok(val) => p.write(val),
|
||||
Err(err) => {
|
||||
// drop all other elements in self
|
||||
// (current element was "moved" into the call to f)
|
||||
for j in (0..i).chain(i + 1..len) {
|
||||
start.add(j).drop_in_place();
|
||||
}
|
||||
|
||||
// returning will drop self, releasing the allocation
|
||||
// (len is 0 so elements will not be re-dropped)
|
||||
return Err(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Even if we encountered an error, set the len back
|
||||
// so we don't leak memory.
|
||||
self.set_len(len);
|
||||
}
|
||||
self
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
||||
@ -61,11 +83,11 @@ impl<T> IdFunctor for Box<[T]> {
|
||||
type Inner = T;
|
||||
|
||||
#[inline]
|
||||
fn map_id<F>(self, f: F) -> Self
|
||||
fn try_map_id<F, E>(self, f: F) -> Result<Self, E>
|
||||
where
|
||||
F: FnMut(Self::Inner) -> Self::Inner,
|
||||
F: FnMut(Self::Inner) -> Result<Self::Inner, E>,
|
||||
{
|
||||
Vec::from(self).map_id(f).into()
|
||||
Vec::from(self).try_map_id(f).map(Into::into)
|
||||
}
|
||||
}
|
||||
|
||||
@ -73,10 +95,10 @@ impl<I: Idx, T> IdFunctor for IndexVec<I, T> {
|
||||
type Inner = T;
|
||||
|
||||
#[inline]
|
||||
fn map_id<F>(self, f: F) -> Self
|
||||
fn try_map_id<F, E>(self, f: F) -> Result<Self, E>
|
||||
where
|
||||
F: FnMut(Self::Inner) -> Self::Inner,
|
||||
F: FnMut(Self::Inner) -> Result<Self::Inner, E>,
|
||||
{
|
||||
IndexVec::from_raw(self.raw.map_id(f))
|
||||
self.raw.try_map_id(f).map(IndexVec::from_raw)
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,7 @@
|
||||
#![feature(once_cell)]
|
||||
#![feature(test)]
|
||||
#![feature(thread_id_value)]
|
||||
#![feature(unwrap_infallible)]
|
||||
#![allow(rustc::default_hash_types)]
|
||||
#![deny(unaligned_references)]
|
||||
|
||||
|
@ -278,7 +278,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
fn fold_binder<T>(&mut self, t: ty::Binder<'tcx, T>) -> ty::Binder<'tcx, T>
|
||||
fn fold_binder<T>(&mut self, t: ty::Binder<'tcx, T>) -> Result<ty::Binder<'tcx, T>, Self::Error>
|
||||
where
|
||||
T: TypeFoldable<'tcx>,
|
||||
{
|
||||
@ -288,13 +288,13 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
|
||||
t
|
||||
}
|
||||
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
||||
match *r {
|
||||
ty::ReLateBound(index, ..) => {
|
||||
if index >= self.binder_index {
|
||||
bug!("escaping late-bound region during canonicalization");
|
||||
} else {
|
||||
r
|
||||
Ok(r)
|
||||
}
|
||||
}
|
||||
|
||||
@ -311,7 +311,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
|
||||
vid, r
|
||||
);
|
||||
let r = self.tcx.reuse_or_mk_region(r, ty::ReVar(resolved_vid));
|
||||
self.canonicalize_region_mode.canonicalize_free_region(self, r)
|
||||
Ok(self.canonicalize_region_mode.canonicalize_free_region(self, r))
|
||||
}
|
||||
|
||||
ty::ReStatic
|
||||
@ -319,11 +319,11 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
|
||||
| ty::ReFree(_)
|
||||
| ty::ReEmpty(_)
|
||||
| ty::RePlaceholder(..)
|
||||
| ty::ReErased => self.canonicalize_region_mode.canonicalize_free_region(self, r),
|
||||
| ty::ReErased => Ok(self.canonicalize_region_mode.canonicalize_free_region(self, r)),
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
match *t.kind() {
|
||||
ty::Infer(ty::TyVar(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) => {
|
||||
// FIXME: perf problem described in #55921.
|
||||
ui = ty::UniverseIndex::ROOT;
|
||||
self.canonicalize_ty_var(
|
||||
Ok(self.canonicalize_ty_var(
|
||||
CanonicalVarInfo {
|
||||
kind: CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui)),
|
||||
},
|
||||
t,
|
||||
)
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ty::Infer(ty::IntVar(_)) => self.canonicalize_ty_var(
|
||||
ty::Infer(ty::IntVar(_)) => Ok(self.canonicalize_ty_var(
|
||||
CanonicalVarInfo { kind: CanonicalVarKind::Ty(CanonicalTyVarKind::Int) },
|
||||
t,
|
||||
),
|
||||
)),
|
||||
|
||||
ty::Infer(ty::FloatVar(_)) => self.canonicalize_ty_var(
|
||||
ty::Infer(ty::FloatVar(_)) => Ok(self.canonicalize_ty_var(
|
||||
CanonicalVarInfo { kind: CanonicalVarKind::Ty(CanonicalTyVarKind::Float) },
|
||||
t,
|
||||
),
|
||||
)),
|
||||
|
||||
ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
|
||||
bug!("encountered a fresh type during canonicalization")
|
||||
}
|
||||
|
||||
ty::Placeholder(placeholder) => self.canonicalize_ty_var(
|
||||
ty::Placeholder(placeholder) => Ok(self.canonicalize_ty_var(
|
||||
CanonicalVarInfo { kind: CanonicalVarKind::PlaceholderTy(placeholder) },
|
||||
t,
|
||||
),
|
||||
)),
|
||||
|
||||
ty::Bound(debruijn, _) => {
|
||||
if debruijn >= self.binder_index {
|
||||
bug!("escaping bound type during canonicalization")
|
||||
} else {
|
||||
t
|
||||
Ok(t)
|
||||
}
|
||||
}
|
||||
|
||||
@ -403,13 +403,16 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
|
||||
if t.flags().intersects(self.needs_canonical_flags) {
|
||||
t.super_fold_with(self)
|
||||
} else {
|
||||
t
|
||||
Ok(t)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||
fn fold_const(
|
||||
&mut self,
|
||||
ct: &'tcx ty::Const<'tcx>,
|
||||
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
|
||||
match ct.val {
|
||||
ty::ConstKind::Infer(InferConst::Var(vid)) => {
|
||||
debug!("canonical: const var found with vid {:?}", vid);
|
||||
@ -424,10 +427,10 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
|
||||
Err(mut ui) => {
|
||||
// FIXME: perf problem described in #55921.
|
||||
ui = ty::UniverseIndex::ROOT;
|
||||
return self.canonicalize_const_var(
|
||||
return Ok(self.canonicalize_const_var(
|
||||
CanonicalVarInfo { kind: CanonicalVarKind::Const(ui) },
|
||||
ct,
|
||||
);
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -438,20 +441,20 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> {
|
||||
if debruijn >= self.binder_index {
|
||||
bug!("escaping bound type during canonicalization")
|
||||
} else {
|
||||
return ct;
|
||||
return Ok(ct);
|
||||
}
|
||||
}
|
||||
ty::ConstKind::Placeholder(placeholder) => {
|
||||
return self.canonicalize_const_var(
|
||||
return Ok(self.canonicalize_const_var(
|
||||
CanonicalVarInfo { kind: CanonicalVarKind::PlaceholderConst(placeholder) },
|
||||
ct,
|
||||
);
|
||||
));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let flags = FlagComputation::for_const(ct);
|
||||
if flags.intersects(self.needs_canonical_flags) { ct.super_fold_with(self) } else { ct }
|
||||
if flags.intersects(self.needs_canonical_flags) { ct.super_fold_with(self) } else { Ok(ct) }
|
||||
}
|
||||
}
|
||||
|
||||
@ -500,7 +503,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
|
||||
indices: FxHashMap::default(),
|
||||
binder_index: ty::INNERMOST,
|
||||
};
|
||||
let out_value = value.fold_with(&mut canonicalizer);
|
||||
let out_value = value.fold_with(&mut canonicalizer).into_ok();
|
||||
|
||||
// Once we have canonicalized `out_value`, it should not
|
||||
// contain anything that ties it to this inference context
|
||||
@ -618,7 +621,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
|
||||
let infcx = self.infcx;
|
||||
let bound_to = infcx.shallow_resolve(ty_var);
|
||||
if bound_to != ty_var {
|
||||
self.fold_ty(bound_to)
|
||||
self.fold_ty(bound_to).into_ok()
|
||||
} else {
|
||||
let var = self.canonical_var(info, ty_var.into());
|
||||
self.tcx().mk_ty(ty::Bound(self.binder_index, var.into()))
|
||||
@ -637,12 +640,12 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
|
||||
let infcx = self.infcx;
|
||||
let bound_to = infcx.shallow_resolve(const_var);
|
||||
if bound_to != const_var {
|
||||
self.fold_const(bound_to)
|
||||
self.fold_const(bound_to).into_ok()
|
||||
} else {
|
||||
let var = self.canonical_var(info, const_var.into());
|
||||
self.tcx().mk_const(ty::Const {
|
||||
val: ty::ConstKind::Bound(self.binder_index, var),
|
||||
ty: self.fold_ty(const_var.ty),
|
||||
ty: self.fold_ty(const_var.ty).into_ok(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> {
|
||||
F: FnOnce(u32) -> ty::InferTy,
|
||||
{
|
||||
if let Some(ty) = opt_ty {
|
||||
return ty.fold_with(self);
|
||||
return ty.fold_with(self).into_ok();
|
||||
}
|
||||
|
||||
match self.ty_freshen_map.entry(key) {
|
||||
@ -98,7 +98,7 @@ impl<'a, 'tcx> TypeFreshener<'a, 'tcx> {
|
||||
F: FnOnce(u32) -> ty::InferConst<'tcx>,
|
||||
{
|
||||
if let Some(ct) = opt_ct {
|
||||
return ct.fold_with(self);
|
||||
return ct.fold_with(self).into_ok();
|
||||
}
|
||||
|
||||
match self.const_freshen_map.entry(key) {
|
||||
@ -119,11 +119,11 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
|
||||
self.infcx.tcx
|
||||
}
|
||||
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
||||
match *r {
|
||||
ty::ReLateBound(..) => {
|
||||
// leave bound regions alone
|
||||
r
|
||||
Ok(r)
|
||||
}
|
||||
|
||||
ty::ReEarlyBound(..)
|
||||
@ -133,21 +133,21 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
|
||||
| ty::ReEmpty(_)
|
||||
| ty::ReErased => {
|
||||
// replace all free regions with 'erased
|
||||
self.tcx().lifetimes.re_erased
|
||||
Ok(self.tcx().lifetimes.re_erased)
|
||||
}
|
||||
ty::ReStatic => {
|
||||
if self.keep_static {
|
||||
r
|
||||
Ok(r)
|
||||
} else {
|
||||
self.tcx().lifetimes.re_erased
|
||||
Ok(self.tcx().lifetimes.re_erased)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
if !t.needs_infer() && !t.has_erasable_regions(self.tcx()) {
|
||||
return t;
|
||||
return Ok(t);
|
||||
}
|
||||
|
||||
let tcx = self.infcx.tcx;
|
||||
@ -155,10 +155,10 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
|
||||
match *t.kind() {
|
||||
ty::Infer(ty::TyVar(v)) => {
|
||||
let opt_ty = self.infcx.inner.borrow_mut().type_variables().probe(v).known();
|
||||
self.freshen_ty(opt_ty, ty::TyVar(v), ty::FreshTy)
|
||||
Ok(self.freshen_ty(opt_ty, ty::TyVar(v), ty::FreshTy))
|
||||
}
|
||||
|
||||
ty::Infer(ty::IntVar(v)) => self.freshen_ty(
|
||||
ty::Infer(ty::IntVar(v)) => Ok(self.freshen_ty(
|
||||
self.infcx
|
||||
.inner
|
||||
.borrow_mut()
|
||||
@ -167,9 +167,9 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
|
||||
.map(|v| v.to_type(tcx)),
|
||||
ty::IntVar(v),
|
||||
ty::FreshIntTy,
|
||||
),
|
||||
)),
|
||||
|
||||
ty::Infer(ty::FloatVar(v)) => self.freshen_ty(
|
||||
ty::Infer(ty::FloatVar(v)) => Ok(self.freshen_ty(
|
||||
self.infcx
|
||||
.inner
|
||||
.borrow_mut()
|
||||
@ -178,7 +178,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
|
||||
.map(|v| v.to_type(tcx)),
|
||||
ty::FloatVar(v),
|
||||
ty::FreshFloatTy,
|
||||
),
|
||||
)),
|
||||
|
||||
ty::Infer(ty::FreshTy(ct) | ty::FreshIntTy(ct) | ty::FreshFloatTy(ct)) => {
|
||||
if ct >= self.ty_freshen_count {
|
||||
@ -189,7 +189,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
|
||||
self.ty_freshen_count
|
||||
);
|
||||
}
|
||||
t
|
||||
Ok(t)
|
||||
}
|
||||
|
||||
ty::Generator(..)
|
||||
@ -221,7 +221,10 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||
fn fold_const(
|
||||
&mut self,
|
||||
ct: &'tcx ty::Const<'tcx>,
|
||||
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
|
||||
match ct.val {
|
||||
ty::ConstKind::Infer(ty::InferConst::Var(v)) => {
|
||||
let opt_ct = self
|
||||
@ -232,12 +235,12 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
|
||||
.probe_value(v)
|
||||
.val
|
||||
.known();
|
||||
return self.freshen_const(
|
||||
return Ok(self.freshen_const(
|
||||
opt_ct,
|
||||
ty::InferConst::Var(v),
|
||||
ty::InferConst::Fresh,
|
||||
ct.ty,
|
||||
);
|
||||
));
|
||||
}
|
||||
ty::ConstKind::Infer(ty::InferConst::Fresh(i)) => {
|
||||
if i >= self.const_freshen_count {
|
||||
@ -248,7 +251,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
|
||||
self.const_freshen_count,
|
||||
);
|
||||
}
|
||||
return ct;
|
||||
return Ok(ct);
|
||||
}
|
||||
|
||||
ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(_) => {
|
||||
|
@ -161,7 +161,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
{
|
||||
Ok(value)
|
||||
} else {
|
||||
Ok(value.fold_with(&mut fudger))
|
||||
Ok(value.fold_with(&mut fudger).into_ok())
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -180,7 +180,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for InferenceFudger<'a, 'tcx> {
|
||||
self.infcx.tcx
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
match *ty.kind() {
|
||||
ty::Infer(ty::InferTy::TyVar(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.
|
||||
let idx = (vid.as_usize() - self.type_vars.0.start.as_usize()) as usize;
|
||||
let origin = self.type_vars.1[idx];
|
||||
self.infcx.next_ty_var(origin)
|
||||
Ok(self.infcx.next_ty_var(origin))
|
||||
} else {
|
||||
// This variable was created before the
|
||||
// "fudging". Since we refresh all type
|
||||
@ -198,48 +198,43 @@ impl<'a, 'tcx> TypeFolder<'tcx> for InferenceFudger<'a, 'tcx> {
|
||||
debug_assert!(
|
||||
self.infcx.inner.borrow_mut().type_variables().probe(vid).is_unknown()
|
||||
);
|
||||
ty
|
||||
Ok(ty)
|
||||
}
|
||||
}
|
||||
ty::Infer(ty::InferTy::IntVar(vid)) => {
|
||||
if self.int_vars.contains(&vid) {
|
||||
self.infcx.next_int_var()
|
||||
} else {
|
||||
ty
|
||||
}
|
||||
Ok(if self.int_vars.contains(&vid) { self.infcx.next_int_var() } else { ty })
|
||||
}
|
||||
ty::Infer(ty::InferTy::FloatVar(vid)) => {
|
||||
if self.float_vars.contains(&vid) {
|
||||
self.infcx.next_float_var()
|
||||
} else {
|
||||
ty
|
||||
}
|
||||
Ok(if self.float_vars.contains(&vid) { self.infcx.next_float_var() } else { ty })
|
||||
}
|
||||
_ => ty.super_fold_with(self),
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
||||
if let ty::ReVar(vid) = *r {
|
||||
if self.region_vars.0.contains(&vid) {
|
||||
let idx = vid.index() - self.region_vars.0.start.index();
|
||||
let origin = self.region_vars.1[idx];
|
||||
return self.infcx.next_region_var(origin);
|
||||
return Ok(self.infcx.next_region_var(origin));
|
||||
}
|
||||
}
|
||||
r
|
||||
Ok(r)
|
||||
}
|
||||
|
||||
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||
fn fold_const(
|
||||
&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 self.const_vars.0.contains(&vid) {
|
||||
// This variable was created during the fudging.
|
||||
// Recreate it with a fresh variable here.
|
||||
let idx = (vid.index - self.const_vars.0.start.index) as usize;
|
||||
let origin = self.const_vars.1[idx];
|
||||
self.infcx.next_const_var(ty, origin)
|
||||
Ok(self.infcx.next_const_var(ty, origin))
|
||||
} else {
|
||||
ct
|
||||
Ok(ct)
|
||||
}
|
||||
} else {
|
||||
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 {
|
||||
t.fold_with(&mut self.freshener())
|
||||
t.fold_with(&mut self.freshener()).into_ok()
|
||||
}
|
||||
|
||||
/// Returns the origin of the type variable identified by `vid`, or `None`
|
||||
@ -1381,7 +1381,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
where
|
||||
T: TypeFoldable<'tcx>,
|
||||
{
|
||||
value.fold_with(&mut ShallowResolver { infcx: self })
|
||||
value.fold_with(&mut ShallowResolver { infcx: self }).into_ok()
|
||||
}
|
||||
|
||||
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.
|
||||
}
|
||||
let mut r = resolve::OpportunisticVarResolver::new(self);
|
||||
value.fold_with(&mut r)
|
||||
value.fold_with(&mut r).into_ok()
|
||||
}
|
||||
|
||||
/// Returns the first unresolved variable contained in `T`. In the
|
||||
@ -1745,12 +1745,15 @@ impl<'a, 'tcx> TypeFolder<'tcx> for ShallowResolver<'a, 'tcx> {
|
||||
self.infcx.tcx
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
self.infcx.shallow_resolve_ty(ty)
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
Ok(self.infcx.shallow_resolve_ty(ty))
|
||||
}
|
||||
|
||||
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||
if let ty::Const { val: ty::ConstKind::Infer(InferConst::Var(vid)), .. } = ct {
|
||||
fn fold_const(
|
||||
&mut self,
|
||||
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
|
||||
.inner
|
||||
.borrow_mut()
|
||||
@ -1761,7 +1764,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for ShallowResolver<'a, 'tcx> {
|
||||
.unwrap_or(ct)
|
||||
} else {
|
||||
ct
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -418,7 +418,8 @@ struct Instantiator<'a, 'tcx> {
|
||||
impl<'a, 'tcx> Instantiator<'a, 'tcx> {
|
||||
fn instantiate_opaque_types_in_map<T: TypeFoldable<'tcx>>(&mut self, value: T) -> T {
|
||||
let tcx = self.infcx.tcx;
|
||||
value.fold_with(&mut BottomUpFolder {
|
||||
value
|
||||
.fold_with(&mut BottomUpFolder {
|
||||
tcx,
|
||||
ty_op: |ty| {
|
||||
if ty.references_error() {
|
||||
@ -504,6 +505,7 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
|
||||
lt_op: |lt| lt,
|
||||
ct_op: |ct| ct,
|
||||
})
|
||||
.into_ok()
|
||||
}
|
||||
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
@ -556,7 +558,8 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
|
||||
debug!(?predicate);
|
||||
|
||||
// We can't normalize associated types from `rustc_infer`, but we can eagerly register inference variables for them.
|
||||
let predicate = predicate.fold_with(&mut BottomUpFolder {
|
||||
let predicate = predicate
|
||||
.fold_with(&mut BottomUpFolder {
|
||||
tcx,
|
||||
ty_op: |ty| match ty.kind() {
|
||||
ty::Projection(projection_ty) => infcx.infer_projection(
|
||||
@ -570,7 +573,8 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
|
||||
},
|
||||
lt_op: |lt| lt,
|
||||
ct_op: |ct| ct,
|
||||
});
|
||||
})
|
||||
.into_ok();
|
||||
debug!(?predicate);
|
||||
|
||||
if let ty::PredicateKind::Projection(projection) = predicate.kind().skip_binder() {
|
||||
|
@ -30,25 +30,28 @@ impl<'a, 'tcx> TypeFolder<'tcx> for OpportunisticVarResolver<'a, 'tcx> {
|
||||
self.infcx.tcx
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
if !t.has_infer_types_or_consts() {
|
||||
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 {
|
||||
let t = self.infcx.shallow_resolve(t);
|
||||
t.super_fold_with(self)
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_const(&mut self, ct: &'tcx Const<'tcx>) -> &'tcx Const<'tcx> {
|
||||
fn fold_const(&mut self, ct: &'tcx Const<'tcx>) -> Result<&'tcx Const<'tcx>, Self::Error> {
|
||||
if !ct.has_infer_types_or_consts() {
|
||||
ct // micro-optimize -- if there is nothing in this const that this fold affects...
|
||||
Ok(ct) // micro-optimize -- if there is nothing in this const that this fold affects...
|
||||
} else {
|
||||
let ct = self.infcx.shallow_resolve(ct);
|
||||
ct.super_fold_with(self)
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_mir_const(&mut self, constant: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> {
|
||||
fn fold_mir_const(
|
||||
&mut self,
|
||||
constant: mir::ConstantKind<'tcx>,
|
||||
) -> Result<mir::ConstantKind<'tcx>, Self::Error> {
|
||||
constant.super_fold_with(self)
|
||||
}
|
||||
}
|
||||
@ -75,16 +78,16 @@ impl<'a, 'tcx> TypeFolder<'tcx> for OpportunisticRegionResolver<'a, 'tcx> {
|
||||
self.infcx.tcx
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
if !t.has_infer_regions() {
|
||||
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 {
|
||||
t.super_fold_with(self)
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
match *r {
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
||||
Ok(match *r {
|
||||
ty::ReVar(rid) => {
|
||||
let resolved = self
|
||||
.infcx
|
||||
@ -95,12 +98,15 @@ impl<'a, 'tcx> TypeFolder<'tcx> for OpportunisticRegionResolver<'a, 'tcx> {
|
||||
self.tcx().reuse_or_mk_region(r, ty::ReVar(resolved))
|
||||
}
|
||||
_ => r,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||
fn fold_const(
|
||||
&mut self,
|
||||
ct: &'tcx ty::Const<'tcx>,
|
||||
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
|
||||
if !ct.has_infer_regions() {
|
||||
ct // micro-optimize -- if there is nothing in this const that this fold affects...
|
||||
Ok(ct) // micro-optimize -- if there is nothing in this const that this fold affects...
|
||||
} else {
|
||||
ct.super_fold_with(self)
|
||||
}
|
||||
@ -175,44 +181,31 @@ pub fn fully_resolve<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>, value: T) -> Fixu
|
||||
where
|
||||
T: TypeFoldable<'tcx>,
|
||||
{
|
||||
let mut full_resolver = FullTypeResolver { infcx, err: None };
|
||||
let result = value.fold_with(&mut full_resolver);
|
||||
match full_resolver.err {
|
||||
None => Ok(result),
|
||||
Some(e) => Err(e),
|
||||
}
|
||||
value.fold_with(&mut FullTypeResolver { infcx })
|
||||
}
|
||||
|
||||
// N.B. This type is not public because the protocol around checking the
|
||||
// `err` field is not enforceable otherwise.
|
||||
struct FullTypeResolver<'a, 'tcx> {
|
||||
infcx: &'a InferCtxt<'a, 'tcx>,
|
||||
err: Option<FixupError<'tcx>>,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> TypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> {
|
||||
type Error = FixupError<'tcx>;
|
||||
|
||||
fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
|
||||
self.infcx.tcx
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
if !t.needs_infer() {
|
||||
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 {
|
||||
let t = self.infcx.shallow_resolve(t);
|
||||
match *t.kind() {
|
||||
ty::Infer(ty::TyVar(vid)) => {
|
||||
self.err = Some(FixupError::UnresolvedTy(vid));
|
||||
self.tcx().ty_error()
|
||||
}
|
||||
ty::Infer(ty::IntVar(vid)) => {
|
||||
self.err = Some(FixupError::UnresolvedIntTy(vid));
|
||||
self.tcx().ty_error()
|
||||
}
|
||||
ty::Infer(ty::FloatVar(vid)) => {
|
||||
self.err = Some(FixupError::UnresolvedFloatTy(vid));
|
||||
self.tcx().ty_error()
|
||||
}
|
||||
ty::Infer(ty::TyVar(vid)) => Err(FixupError::UnresolvedTy(vid)),
|
||||
ty::Infer(ty::IntVar(vid)) => Err(FixupError::UnresolvedIntTy(vid)),
|
||||
ty::Infer(ty::FloatVar(vid)) => Err(FixupError::UnresolvedFloatTy(vid)),
|
||||
ty::Infer(_) => {
|
||||
bug!("Unexpected type in full type resolver: {:?}", t);
|
||||
}
|
||||
@ -221,28 +214,30 @@ impl<'a, 'tcx> TypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
||||
match *r {
|
||||
ty::ReVar(rid) => self
|
||||
ty::ReVar(rid) => Ok(self
|
||||
.infcx
|
||||
.lexical_region_resolutions
|
||||
.borrow()
|
||||
.as_ref()
|
||||
.expect("region resolution not performed")
|
||||
.resolve_var(rid),
|
||||
_ => r,
|
||||
.resolve_var(rid)),
|
||||
_ => Ok(r),
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_const(&mut self, c: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||
fn fold_const(
|
||||
&mut self,
|
||||
c: &'tcx ty::Const<'tcx>,
|
||||
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
|
||||
if !c.needs_infer() {
|
||||
c // micro-optimize -- if there is nothing in this const that this fold affects...
|
||||
Ok(c) // micro-optimize -- if there is nothing in this const that this fold affects...
|
||||
} else {
|
||||
let c = self.infcx.shallow_resolve(c);
|
||||
match c.val {
|
||||
ty::ConstKind::Infer(InferConst::Var(vid)) => {
|
||||
self.err = Some(FixupError::UnresolvedConst(vid));
|
||||
return self.tcx().const_error(c.ty);
|
||||
return Err(FixupError::UnresolvedConst(vid));
|
||||
}
|
||||
ty::ConstKind::Infer(InferConst::Fresh(_)) => {
|
||||
bug!("Unexpected const in full const resolver: {:?}", c);
|
||||
|
@ -24,6 +24,7 @@
|
||||
#![feature(control_flow_enum)]
|
||||
#![feature(min_specialization)]
|
||||
#![feature(label_break_value)]
|
||||
#![feature(unwrap_infallible)]
|
||||
#![recursion_limit = "512"] // For rustdoc
|
||||
|
||||
#[macro_use]
|
||||
|
@ -60,13 +60,13 @@ impl<'tcx> fmt::Debug for traits::MismatchedProjectionTypes<'tcx> {
|
||||
// TypeFoldable implementations.
|
||||
|
||||
impl<'tcx, O: TypeFoldable<'tcx>> TypeFoldable<'tcx> for traits::Obligation<'tcx, O> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
|
||||
traits::Obligation {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||
Ok(traits::Obligation {
|
||||
cause: self.cause,
|
||||
recursion_depth: self.recursion_depth,
|
||||
predicate: self.predicate.fold_with(folder),
|
||||
param_env: self.param_env.fold_with(folder),
|
||||
}
|
||||
predicate: self.predicate.fold_with(folder)?,
|
||||
param_env: self.param_env.fold_with(folder)?,
|
||||
})
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
||||
|
@ -17,7 +17,7 @@ pub fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::
|
||||
vi.construct(|_, index| {
|
||||
let bind = &bindings[index];
|
||||
quote! {
|
||||
::rustc_middle::ty::fold::TypeFoldable::fold_with(#bind, __folder)
|
||||
::rustc_middle::ty::fold::TypeFoldable::fold_with(#bind, __folder)?
|
||||
}
|
||||
})
|
||||
});
|
||||
@ -28,8 +28,8 @@ pub fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::
|
||||
fn super_fold_with<__F: ::rustc_middle::ty::fold::TypeFolder<'tcx>>(
|
||||
self,
|
||||
__folder: &mut __F
|
||||
) -> Self {
|
||||
match self { #body_fold }
|
||||
) -> Result<Self, __F::Error> {
|
||||
Ok(match self { #body_fold })
|
||||
}
|
||||
|
||||
fn super_visit_with<__F: ::rustc_middle::ty::fold::TypeVisitor<'tcx>>(
|
||||
|
@ -56,6 +56,7 @@
|
||||
#![feature(try_blocks)]
|
||||
#![feature(try_reserve_kind)]
|
||||
#![feature(nonzero_ops)]
|
||||
#![feature(unwrap_infallible)]
|
||||
#![recursion_limit = "512"]
|
||||
|
||||
#[macro_use]
|
||||
|
@ -55,8 +55,8 @@ macro_rules! TrivialTypeFoldableImpls {
|
||||
fn super_fold_with<F: $crate::ty::fold::TypeFolder<$tcx>>(
|
||||
self,
|
||||
_: &mut F
|
||||
) -> $ty {
|
||||
self
|
||||
) -> ::std::result::Result<$ty, F::Error> {
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
fn super_visit_with<F: $crate::ty::fold::TypeVisitor<$tcx>>(
|
||||
@ -98,7 +98,7 @@ macro_rules! EnumTypeFoldableImpl {
|
||||
fn super_fold_with<V: $crate::ty::fold::TypeFolder<$tcx>>(
|
||||
self,
|
||||
folder: &mut V,
|
||||
) -> Self {
|
||||
) -> ::std::result::Result<Self, V::Error> {
|
||||
EnumTypeFoldableImpl!(@FoldVariants(self, folder) input($($variants)*) output())
|
||||
}
|
||||
|
||||
@ -112,9 +112,9 @@ macro_rules! EnumTypeFoldableImpl {
|
||||
};
|
||||
|
||||
(@FoldVariants($this:expr, $folder:expr) input() output($($output:tt)*)) => {
|
||||
match $this {
|
||||
Ok(match $this {
|
||||
$($output)*
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
(@FoldVariants($this:expr, $folder:expr)
|
||||
@ -126,7 +126,7 @@ macro_rules! EnumTypeFoldableImpl {
|
||||
output(
|
||||
$variant ( $($variant_arg),* ) => {
|
||||
$variant (
|
||||
$($crate::ty::fold::TypeFoldable::fold_with($variant_arg, $folder)),*
|
||||
$($crate::ty::fold::TypeFoldable::fold_with($variant_arg, $folder)?),*
|
||||
)
|
||||
}
|
||||
$($output)*
|
||||
@ -145,7 +145,7 @@ macro_rules! EnumTypeFoldableImpl {
|
||||
$variant {
|
||||
$($variant_arg: $crate::ty::fold::TypeFoldable::fold_with(
|
||||
$variant_arg, $folder
|
||||
)),* }
|
||||
)?),* }
|
||||
}
|
||||
$($output)*
|
||||
)
|
||||
|
@ -2760,11 +2760,11 @@ impl UserTypeProjection {
|
||||
TrivialTypeFoldableAndLiftImpls! { ProjectionKind, }
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for UserTypeProjection {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
|
||||
UserTypeProjection {
|
||||
base: self.base.fold_with(folder),
|
||||
projs: self.projs.fold_with(folder),
|
||||
}
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||
Ok(UserTypeProjection {
|
||||
base: self.base.fold_with(folder)?,
|
||||
projs: self.projs.fold_with(folder)?,
|
||||
})
|
||||
}
|
||||
|
||||
fn super_visit_with<Vs: TypeVisitor<'tcx>>(
|
||||
|
@ -16,37 +16,39 @@ TrivialTypeFoldableAndLiftImpls! {
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||
use crate::mir::TerminatorKind::*;
|
||||
|
||||
let kind = match self.kind {
|
||||
Goto { target } => Goto { target },
|
||||
SwitchInt { discr, switch_ty, targets } => SwitchInt {
|
||||
discr: discr.fold_with(folder),
|
||||
switch_ty: switch_ty.fold_with(folder),
|
||||
discr: discr.fold_with(folder)?,
|
||||
switch_ty: switch_ty.fold_with(folder)?,
|
||||
targets,
|
||||
},
|
||||
Drop { place, target, unwind } => {
|
||||
Drop { place: place.fold_with(folder), target, unwind }
|
||||
Drop { place: place.fold_with(folder)?, target, unwind }
|
||||
}
|
||||
DropAndReplace { place, value, target, unwind } => DropAndReplace {
|
||||
place: place.fold_with(folder),
|
||||
value: value.fold_with(folder),
|
||||
place: place.fold_with(folder)?,
|
||||
value: value.fold_with(folder)?,
|
||||
target,
|
||||
unwind,
|
||||
},
|
||||
Yield { value, resume, resume_arg, drop } => Yield {
|
||||
value: value.fold_with(folder),
|
||||
value: value.fold_with(folder)?,
|
||||
resume,
|
||||
resume_arg: resume_arg.fold_with(folder),
|
||||
resume_arg: resume_arg.fold_with(folder)?,
|
||||
drop,
|
||||
},
|
||||
Call { func, args, destination, cleanup, from_hir_call, fn_span } => {
|
||||
let dest = destination.map(|(loc, dest)| (loc.fold_with(folder), dest));
|
||||
let dest = destination
|
||||
.map(|(loc, dest)| (loc.fold_with(folder).map(|loc| (loc, dest))))
|
||||
.transpose()?;
|
||||
|
||||
Call {
|
||||
func: func.fold_with(folder),
|
||||
args: args.fold_with(folder),
|
||||
func: func.fold_with(folder)?,
|
||||
args: args.fold_with(folder)?,
|
||||
destination: dest,
|
||||
cleanup,
|
||||
from_hir_call,
|
||||
@ -57,15 +59,15 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
|
||||
use AssertKind::*;
|
||||
let msg = match msg {
|
||||
BoundsCheck { len, index } => {
|
||||
BoundsCheck { len: len.fold_with(folder), index: index.fold_with(folder) }
|
||||
BoundsCheck { len: len.fold_with(folder)?, index: index.fold_with(folder)? }
|
||||
}
|
||||
Overflow(op, l, r) => Overflow(op, l.fold_with(folder), r.fold_with(folder)),
|
||||
OverflowNeg(op) => OverflowNeg(op.fold_with(folder)),
|
||||
DivisionByZero(op) => DivisionByZero(op.fold_with(folder)),
|
||||
RemainderByZero(op) => RemainderByZero(op.fold_with(folder)),
|
||||
Overflow(op, l, r) => Overflow(op, l.fold_with(folder)?, r.fold_with(folder)?),
|
||||
OverflowNeg(op) => OverflowNeg(op.fold_with(folder)?),
|
||||
DivisionByZero(op) => DivisionByZero(op.fold_with(folder)?),
|
||||
RemainderByZero(op) => RemainderByZero(op.fold_with(folder)?),
|
||||
ResumedAfterReturn(_) | ResumedAfterPanic(_) => msg,
|
||||
};
|
||||
Assert { cond: cond.fold_with(folder), expected, msg, target, cleanup }
|
||||
Assert { cond: cond.fold_with(folder)?, expected, msg, target, cleanup }
|
||||
}
|
||||
GeneratorDrop => GeneratorDrop,
|
||||
Resume => Resume,
|
||||
@ -78,13 +80,13 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
|
||||
FalseUnwind { real_target, unwind } => FalseUnwind { real_target, unwind },
|
||||
InlineAsm { template, operands, options, line_spans, destination } => InlineAsm {
|
||||
template,
|
||||
operands: operands.fold_with(folder),
|
||||
operands: operands.fold_with(folder)?,
|
||||
options,
|
||||
line_spans,
|
||||
destination,
|
||||
},
|
||||
};
|
||||
Terminator { source_info: self.source_info, kind }
|
||||
Ok(Terminator { source_info: self.source_info, kind })
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
||||
@ -140,8 +142,8 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for GeneratorKind {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, _: &mut F) -> Self {
|
||||
self
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> {
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> {
|
||||
@ -150,8 +152,11 @@ impl<'tcx> TypeFoldable<'tcx> for GeneratorKind {
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for Place<'tcx> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
|
||||
Place { local: self.local.fold_with(folder), projection: self.projection.fold_with(folder) }
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||
Ok(Place {
|
||||
local: self.local.fold_with(folder)?,
|
||||
projection: self.projection.fold_with(folder)?,
|
||||
})
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
||||
@ -161,7 +166,7 @@ impl<'tcx> TypeFoldable<'tcx> for Place<'tcx> {
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<PlaceElem<'tcx>> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||
ty::util::fold_list(self, folder, |tcx, v| tcx.intern_place_elems(v))
|
||||
}
|
||||
|
||||
@ -171,47 +176,49 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<PlaceElem<'tcx>> {
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||
use crate::mir::Rvalue::*;
|
||||
match self {
|
||||
Use(op) => Use(op.fold_with(folder)),
|
||||
Repeat(op, len) => Repeat(op.fold_with(folder), len.fold_with(folder)),
|
||||
ThreadLocalRef(did) => ThreadLocalRef(did.fold_with(folder)),
|
||||
Ref(region, bk, place) => Ref(region.fold_with(folder), bk, place.fold_with(folder)),
|
||||
AddressOf(mutability, place) => AddressOf(mutability, place.fold_with(folder)),
|
||||
Len(place) => Len(place.fold_with(folder)),
|
||||
Cast(kind, op, ty) => Cast(kind, op.fold_with(folder), ty.fold_with(folder)),
|
||||
Ok(match self {
|
||||
Use(op) => Use(op.fold_with(folder)?),
|
||||
Repeat(op, len) => Repeat(op.fold_with(folder)?, len.fold_with(folder)?),
|
||||
ThreadLocalRef(did) => ThreadLocalRef(did.fold_with(folder)?),
|
||||
Ref(region, bk, place) => Ref(region.fold_with(folder)?, bk, place.fold_with(folder)?),
|
||||
AddressOf(mutability, place) => AddressOf(mutability, place.fold_with(folder)?),
|
||||
Len(place) => Len(place.fold_with(folder)?),
|
||||
Cast(kind, op, ty) => Cast(kind, op.fold_with(folder)?, ty.fold_with(folder)?),
|
||||
BinaryOp(op, box (rhs, lhs)) => {
|
||||
BinaryOp(op, Box::new((rhs.fold_with(folder), lhs.fold_with(folder))))
|
||||
BinaryOp(op, Box::new((rhs.fold_with(folder)?, lhs.fold_with(folder)?)))
|
||||
}
|
||||
CheckedBinaryOp(op, box (rhs, lhs)) => {
|
||||
CheckedBinaryOp(op, Box::new((rhs.fold_with(folder), lhs.fold_with(folder))))
|
||||
CheckedBinaryOp(op, Box::new((rhs.fold_with(folder)?, lhs.fold_with(folder)?)))
|
||||
}
|
||||
UnaryOp(op, val) => UnaryOp(op, val.fold_with(folder)),
|
||||
Discriminant(place) => Discriminant(place.fold_with(folder)),
|
||||
NullaryOp(op, ty) => NullaryOp(op, ty.fold_with(folder)),
|
||||
UnaryOp(op, val) => UnaryOp(op, val.fold_with(folder)?),
|
||||
Discriminant(place) => Discriminant(place.fold_with(folder)?),
|
||||
NullaryOp(op, ty) => NullaryOp(op, ty.fold_with(folder)?),
|
||||
Aggregate(kind, fields) => {
|
||||
let kind = kind.map_id(|kind| match kind {
|
||||
AggregateKind::Array(ty) => AggregateKind::Array(ty.fold_with(folder)),
|
||||
let kind = kind.try_map_id(|kind| {
|
||||
Ok(match kind {
|
||||
AggregateKind::Array(ty) => AggregateKind::Array(ty.fold_with(folder)?),
|
||||
AggregateKind::Tuple => AggregateKind::Tuple,
|
||||
AggregateKind::Adt(def, v, substs, user_ty, n) => AggregateKind::Adt(
|
||||
def,
|
||||
v,
|
||||
substs.fold_with(folder),
|
||||
user_ty.fold_with(folder),
|
||||
substs.fold_with(folder)?,
|
||||
user_ty.fold_with(folder)?,
|
||||
n,
|
||||
),
|
||||
AggregateKind::Closure(id, substs) => {
|
||||
AggregateKind::Closure(id, substs.fold_with(folder))
|
||||
AggregateKind::Closure(id, substs.fold_with(folder)?)
|
||||
}
|
||||
AggregateKind::Generator(id, substs, movablity) => {
|
||||
AggregateKind::Generator(id, substs.fold_with(folder), movablity)
|
||||
AggregateKind::Generator(id, substs.fold_with(folder)?, movablity)
|
||||
}
|
||||
});
|
||||
Aggregate(kind, fields.fold_with(folder))
|
||||
}
|
||||
ShallowInitBox(op, ty) => ShallowInitBox(op.fold_with(folder), ty.fold_with(folder)),
|
||||
})
|
||||
})?;
|
||||
Aggregate(kind, fields.fold_with(folder)?)
|
||||
}
|
||||
ShallowInitBox(op, ty) => ShallowInitBox(op.fold_with(folder)?, ty.fold_with(folder)?),
|
||||
})
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
||||
@ -265,12 +272,12 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for Operand<'tcx> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
|
||||
match self {
|
||||
Operand::Copy(place) => Operand::Copy(place.fold_with(folder)),
|
||||
Operand::Move(place) => Operand::Move(place.fold_with(folder)),
|
||||
Operand::Constant(c) => Operand::Constant(c.fold_with(folder)),
|
||||
}
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||
Ok(match self {
|
||||
Operand::Copy(place) => Operand::Copy(place.fold_with(folder)?),
|
||||
Operand::Move(place) => Operand::Move(place.fold_with(folder)?),
|
||||
Operand::Constant(c) => Operand::Constant(c.fold_with(folder)?),
|
||||
})
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
||||
@ -282,19 +289,19 @@ impl<'tcx> TypeFoldable<'tcx> for Operand<'tcx> {
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for PlaceElem<'tcx> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||
use crate::mir::ProjectionElem::*;
|
||||
|
||||
match self {
|
||||
Ok(match self {
|
||||
Deref => Deref,
|
||||
Field(f, ty) => Field(f, ty.fold_with(folder)),
|
||||
Index(v) => Index(v.fold_with(folder)),
|
||||
Field(f, ty) => Field(f, ty.fold_with(folder)?),
|
||||
Index(v) => Index(v.fold_with(folder)?),
|
||||
Downcast(symbol, variantidx) => Downcast(symbol, variantidx),
|
||||
ConstantIndex { offset, min_length, from_end } => {
|
||||
ConstantIndex { offset, min_length, from_end }
|
||||
}
|
||||
Subslice { from, to, from_end } => Subslice { from, to, from_end },
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn super_visit_with<Vs: TypeVisitor<'tcx>>(
|
||||
@ -312,8 +319,8 @@ impl<'tcx> TypeFoldable<'tcx> for PlaceElem<'tcx> {
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for Field {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, _: &mut F) -> Self {
|
||||
self
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> {
|
||||
Ok(self)
|
||||
}
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> {
|
||||
ControlFlow::CONTINUE
|
||||
@ -321,8 +328,8 @@ impl<'tcx> TypeFoldable<'tcx> for Field {
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for GeneratorSavedLocal {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, _: &mut F) -> Self {
|
||||
self
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> {
|
||||
Ok(self)
|
||||
}
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> {
|
||||
ControlFlow::CONTINUE
|
||||
@ -330,8 +337,8 @@ impl<'tcx> TypeFoldable<'tcx> for GeneratorSavedLocal {
|
||||
}
|
||||
|
||||
impl<'tcx, R: Idx, C: Idx> TypeFoldable<'tcx> for BitMatrix<R, C> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, _: &mut F) -> Self {
|
||||
self
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> {
|
||||
Ok(self)
|
||||
}
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> {
|
||||
ControlFlow::CONTINUE
|
||||
@ -339,12 +346,12 @@ impl<'tcx, R: Idx, C: Idx> TypeFoldable<'tcx> for BitMatrix<R, C> {
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for Constant<'tcx> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
|
||||
Constant {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||
Ok(Constant {
|
||||
span: self.span,
|
||||
user_ty: self.user_ty.fold_with(folder),
|
||||
literal: self.literal.fold_with(folder),
|
||||
}
|
||||
user_ty: self.user_ty.fold_with(folder)?,
|
||||
literal: self.literal.fold_with(folder)?,
|
||||
})
|
||||
}
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
||||
self.literal.visit_with(visitor)?;
|
||||
@ -354,14 +361,14 @@ impl<'tcx> TypeFoldable<'tcx> for Constant<'tcx> {
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for ConstantKind<'tcx> {
|
||||
#[inline(always)]
|
||||
fn fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
|
||||
fn fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||
folder.fold_mir_const(self)
|
||||
}
|
||||
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||
match self {
|
||||
ConstantKind::Ty(c) => ConstantKind::Ty(c.fold_with(folder)),
|
||||
ConstantKind::Val(v, t) => ConstantKind::Val(v, t.fold_with(folder)),
|
||||
ConstantKind::Ty(c) => Ok(ConstantKind::Ty(c.fold_with(folder)?)),
|
||||
ConstantKind::Val(v, t) => Ok(ConstantKind::Val(v, t.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> {
|
||||
// N.B., use `super_fold_with` here. If we used `fold_with`, it
|
||||
// could invoke the `erase_regions_ty` query recursively.
|
||||
ty.super_fold_with(&mut RegionEraserVisitor { tcx })
|
||||
ty.super_fold_with(&mut RegionEraserVisitor { tcx }).into_ok()
|
||||
}
|
||||
|
||||
impl<'tcx> TyCtxt<'tcx> {
|
||||
@ -27,7 +27,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
return value;
|
||||
}
|
||||
debug!("erase_regions({:?})", value);
|
||||
let value1 = value.fold_with(&mut RegionEraserVisitor { tcx: self });
|
||||
let value1 = value.fold_with(&mut RegionEraserVisitor { tcx: self }).into_ok();
|
||||
debug!("erase_regions = {:?}", value1);
|
||||
value1
|
||||
}
|
||||
@ -42,11 +42,11 @@ impl TypeFolder<'tcx> for RegionEraserVisitor<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
if ty.needs_infer() { ty.super_fold_with(self) } else { self.tcx.erase_regions_ty(ty) }
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
if ty.needs_infer() { ty.super_fold_with(self) } else { Ok(self.tcx.erase_regions_ty(ty)) }
|
||||
}
|
||||
|
||||
fn fold_binder<T>(&mut self, t: ty::Binder<'tcx, T>) -> ty::Binder<'tcx, T>
|
||||
fn fold_binder<T>(&mut self, t: ty::Binder<'tcx, T>) -> Result<ty::Binder<'tcx, T>, Self::Error>
|
||||
where
|
||||
T: TypeFoldable<'tcx>,
|
||||
{
|
||||
@ -54,7 +54,7 @@ impl TypeFolder<'tcx> for RegionEraserVisitor<'tcx> {
|
||||
u.super_fold_with(self)
|
||||
}
|
||||
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
||||
// because late-bound regions affect subtyping, we can't
|
||||
// erase the bound/free distinction, but we can replace
|
||||
// all free regions with 'erased.
|
||||
@ -64,12 +64,15 @@ impl TypeFolder<'tcx> for RegionEraserVisitor<'tcx> {
|
||||
// away. In codegen, they will always be erased to 'erased
|
||||
// whenever a substitution occurs.
|
||||
match *r {
|
||||
ty::ReLateBound(..) => r,
|
||||
_ => self.tcx.lifetimes.re_erased,
|
||||
ty::ReLateBound(..) => Ok(r),
|
||||
_ => Ok(self.tcx.lifetimes.re_erased),
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> {
|
||||
fn fold_mir_const(
|
||||
&mut self,
|
||||
c: mir::ConstantKind<'tcx>,
|
||||
) -> Result<mir::ConstantKind<'tcx>, Self::Error> {
|
||||
c.super_fold_with(self)
|
||||
}
|
||||
}
|
||||
|
@ -46,8 +46,8 @@ use std::ops::ControlFlow;
|
||||
///
|
||||
/// To implement this conveniently, use the derive macro located in `rustc_macros`.
|
||||
pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self;
|
||||
fn fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error>;
|
||||
fn fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||
self.super_fold_with(folder)
|
||||
}
|
||||
|
||||
@ -179,8 +179,8 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
|
||||
}
|
||||
|
||||
impl TypeFoldable<'tcx> for hir::Constness {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, _: &mut F) -> Self {
|
||||
self
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> {
|
||||
Ok(self)
|
||||
}
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> {
|
||||
ControlFlow::CONTINUE
|
||||
@ -193,32 +193,43 @@ impl TypeFoldable<'tcx> for hir::Constness {
|
||||
/// identity fold, it should invoke `foo.fold_with(self)` to fold each
|
||||
/// sub-item.
|
||||
pub trait TypeFolder<'tcx>: Sized {
|
||||
type Error = !;
|
||||
|
||||
fn tcx<'a>(&'a self) -> TyCtxt<'tcx>;
|
||||
|
||||
fn fold_binder<T>(&mut self, t: Binder<'tcx, T>) -> Binder<'tcx, T>
|
||||
fn fold_binder<T>(&mut self, t: Binder<'tcx, T>) -> Result<Binder<'tcx, T>, Self::Error>
|
||||
where
|
||||
T: TypeFoldable<'tcx>,
|
||||
{
|
||||
t.super_fold_with(self)
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
t.super_fold_with(self)
|
||||
}
|
||||
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
||||
r.super_fold_with(self)
|
||||
}
|
||||
|
||||
fn fold_const(&mut self, c: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||
fn fold_const(
|
||||
&mut self,
|
||||
c: &'tcx ty::Const<'tcx>,
|
||||
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
|
||||
c.super_fold_with(self)
|
||||
}
|
||||
|
||||
fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> {
|
||||
fn fold_predicate(
|
||||
&mut self,
|
||||
p: ty::Predicate<'tcx>,
|
||||
) -> Result<ty::Predicate<'tcx>, Self::Error> {
|
||||
p.super_fold_with(self)
|
||||
}
|
||||
|
||||
fn fold_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> {
|
||||
fn fold_mir_const(
|
||||
&mut self,
|
||||
c: mir::ConstantKind<'tcx>,
|
||||
) -> Result<mir::ConstantKind<'tcx>, Self::Error> {
|
||||
bug!("most type folders should not be folding MIR datastructures: {:?}", c)
|
||||
}
|
||||
}
|
||||
@ -290,19 +301,22 @@ where
|
||||
self.tcx
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
let t = ty.super_fold_with(self);
|
||||
(self.ty_op)(t)
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
let t = ty.super_fold_with(self)?;
|
||||
Ok((self.ty_op)(t))
|
||||
}
|
||||
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
let r = r.super_fold_with(self);
|
||||
(self.lt_op)(r)
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
||||
let r = r.super_fold_with(self)?;
|
||||
Ok((self.lt_op)(r))
|
||||
}
|
||||
|
||||
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||
let ct = ct.super_fold_with(self);
|
||||
(self.ct_op)(ct)
|
||||
fn fold_const(
|
||||
&mut self,
|
||||
ct: &'tcx ty::Const<'tcx>,
|
||||
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
|
||||
let ct = ct.super_fold_with(self)?;
|
||||
Ok((self.ct_op)(ct))
|
||||
}
|
||||
}
|
||||
|
||||
@ -322,7 +336,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
where
|
||||
T: TypeFoldable<'tcx>,
|
||||
{
|
||||
value.fold_with(&mut RegionFolder::new(self, skipped_regions, &mut f))
|
||||
value.fold_with(&mut RegionFolder::new(self, skipped_regions, &mut f)).into_ok()
|
||||
}
|
||||
|
||||
/// Invoke `callback` on every region appearing free in `value`.
|
||||
@ -470,7 +484,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for RegionFolder<'a, 'tcx> {
|
||||
fn fold_binder<T: TypeFoldable<'tcx>>(
|
||||
&mut self,
|
||||
t: ty::Binder<'tcx, T>,
|
||||
) -> ty::Binder<'tcx, T> {
|
||||
) -> Result<ty::Binder<'tcx, T>, Self::Error> {
|
||||
self.current_index.shift_in(1);
|
||||
let t = t.super_fold_with(self);
|
||||
self.current_index.shift_out(1);
|
||||
@ -478,16 +492,16 @@ impl<'a, 'tcx> TypeFolder<'tcx> for RegionFolder<'a, 'tcx> {
|
||||
}
|
||||
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
||||
match *r {
|
||||
ty::ReLateBound(debruijn, _) if debruijn < self.current_index => {
|
||||
debug!(?self.current_index, "skipped bound region");
|
||||
*self.skipped_regions = true;
|
||||
r
|
||||
Ok(r)
|
||||
}
|
||||
_ => {
|
||||
debug!(?self.current_index, "folding free region");
|
||||
(self.fold_region_fn)(r, self.current_index)
|
||||
Ok((self.fold_region_fn)(r, self.current_index))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -528,19 +542,19 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> {
|
||||
fn fold_binder<T: TypeFoldable<'tcx>>(
|
||||
&mut self,
|
||||
t: ty::Binder<'tcx, T>,
|
||||
) -> ty::Binder<'tcx, T> {
|
||||
) -> Result<ty::Binder<'tcx, T>, Self::Error> {
|
||||
self.current_index.shift_in(1);
|
||||
let t = t.super_fold_with(self);
|
||||
self.current_index.shift_out(1);
|
||||
t
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
match *t.kind() {
|
||||
ty::Bound(debruijn, bound_ty) if debruijn == self.current_index => {
|
||||
if let Some(fld_t) = self.fld_t.as_mut() {
|
||||
let ty = fld_t(bound_ty);
|
||||
return ty::fold::shift_vars(self.tcx, &ty, self.current_index.as_u32());
|
||||
return Ok(ty::fold::shift_vars(self.tcx, &ty, self.current_index.as_u32()));
|
||||
}
|
||||
}
|
||||
_ if t.has_vars_bound_at_or_above(self.current_index) => {
|
||||
@ -548,10 +562,10 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> {
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
t
|
||||
Ok(t)
|
||||
}
|
||||
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
||||
match *r {
|
||||
ty::ReLateBound(debruijn, br) if debruijn == self.current_index => {
|
||||
if let Some(fld_r) = self.fld_r.as_mut() {
|
||||
@ -562,25 +576,28 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> {
|
||||
// debruijn index. Then we adjust it to the
|
||||
// correct depth.
|
||||
assert_eq!(debruijn1, ty::INNERMOST);
|
||||
self.tcx.mk_region(ty::ReLateBound(debruijn, br))
|
||||
Ok(self.tcx.mk_region(ty::ReLateBound(debruijn, br)))
|
||||
} else {
|
||||
region
|
||||
Ok(region)
|
||||
};
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
r
|
||||
Ok(r)
|
||||
}
|
||||
|
||||
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||
fn fold_const(
|
||||
&mut self,
|
||||
ct: &'tcx ty::Const<'tcx>,
|
||||
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
|
||||
match *ct {
|
||||
ty::Const { val: ty::ConstKind::Bound(debruijn, bound_const), ty }
|
||||
if debruijn == self.current_index =>
|
||||
{
|
||||
if let Some(fld_c) = self.fld_c.as_mut() {
|
||||
let ct = fld_c(bound_const, ty);
|
||||
return ty::fold::shift_vars(self.tcx, &ct, self.current_index.as_u32());
|
||||
return Ok(ty::fold::shift_vars(self.tcx, &ct, self.current_index.as_u32()));
|
||||
}
|
||||
}
|
||||
_ if ct.has_vars_bound_at_or_above(self.current_index) => {
|
||||
@ -588,7 +605,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> {
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
ct
|
||||
Ok(ct)
|
||||
}
|
||||
}
|
||||
|
||||
@ -621,7 +638,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
value
|
||||
} else {
|
||||
let mut replacer = BoundVarReplacer::new(self, Some(&mut real_fld_r), None, None);
|
||||
value.fold_with(&mut replacer)
|
||||
value.fold_with(&mut replacer).into_ok()
|
||||
};
|
||||
(value, region_map)
|
||||
}
|
||||
@ -647,7 +664,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
} else {
|
||||
let mut replacer =
|
||||
BoundVarReplacer::new(self, Some(&mut fld_r), Some(&mut fld_t), Some(&mut fld_c));
|
||||
value.fold_with(&mut replacer)
|
||||
value.fold_with(&mut replacer).into_ok()
|
||||
}
|
||||
}
|
||||
|
||||
@ -938,36 +955,36 @@ impl TypeFolder<'tcx> for Shifter<'tcx> {
|
||||
fn fold_binder<T: TypeFoldable<'tcx>>(
|
||||
&mut self,
|
||||
t: ty::Binder<'tcx, T>,
|
||||
) -> ty::Binder<'tcx, T> {
|
||||
) -> Result<ty::Binder<'tcx, T>, Self::Error> {
|
||||
self.current_index.shift_in(1);
|
||||
let t = t.super_fold_with(self);
|
||||
self.current_index.shift_out(1);
|
||||
t
|
||||
}
|
||||
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
||||
match *r {
|
||||
ty::ReLateBound(debruijn, br) => {
|
||||
if self.amount == 0 || debruijn < self.current_index {
|
||||
r
|
||||
Ok(r)
|
||||
} else {
|
||||
let debruijn = debruijn.shifted_in(self.amount);
|
||||
let shifted = ty::ReLateBound(debruijn, br);
|
||||
self.tcx.mk_region(shifted)
|
||||
Ok(self.tcx.mk_region(shifted))
|
||||
}
|
||||
}
|
||||
_ => r,
|
||||
_ => Ok(r),
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
match *ty.kind() {
|
||||
ty::Bound(debruijn, bound_ty) => {
|
||||
if self.amount == 0 || debruijn < self.current_index {
|
||||
ty
|
||||
Ok(ty)
|
||||
} else {
|
||||
let debruijn = debruijn.shifted_in(self.amount);
|
||||
self.tcx.mk_ty(ty::Bound(debruijn, bound_ty))
|
||||
Ok(self.tcx.mk_ty(ty::Bound(debruijn, bound_ty)))
|
||||
}
|
||||
}
|
||||
|
||||
@ -975,13 +992,18 @@ impl TypeFolder<'tcx> for Shifter<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||
fn fold_const(
|
||||
&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 self.amount == 0 || debruijn < self.current_index {
|
||||
ct
|
||||
Ok(ct)
|
||||
} else {
|
||||
let debruijn = debruijn.shifted_in(self.amount);
|
||||
self.tcx.mk_const(ty::Const { val: ty::ConstKind::Bound(debruijn, bound_ct), ty })
|
||||
Ok(self
|
||||
.tcx
|
||||
.mk_const(ty::Const { val: ty::ConstKind::Bound(debruijn, bound_ct), ty }))
|
||||
}
|
||||
} else {
|
||||
ct.super_fold_with(self)
|
||||
@ -1008,7 +1030,7 @@ where
|
||||
{
|
||||
debug!("shift_vars(value={:?}, amount={})", value, amount);
|
||||
|
||||
value.fold_with(&mut Shifter::new(tcx, amount))
|
||||
value.fold_with(&mut Shifter::new(tcx, amount)).into_ok()
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||
@ -1271,7 +1293,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
///
|
||||
/// FIXME(@lcnr): explain this function a bit more
|
||||
pub fn expose_default_const_substs<T: TypeFoldable<'tcx>>(self, v: T) -> T {
|
||||
v.fold_with(&mut ExposeDefaultConstSubstsFolder { tcx: self })
|
||||
v.fold_with(&mut ExposeDefaultConstSubstsFolder { tcx: self }).into_ok()
|
||||
}
|
||||
}
|
||||
|
||||
@ -1284,19 +1306,22 @@ impl<'tcx> TypeFolder<'tcx> for ExposeDefaultConstSubstsFolder<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
if ty.flags().intersects(TypeFlags::HAS_UNKNOWN_DEFAULT_CONST_SUBSTS) {
|
||||
ty.super_fold_with(self)
|
||||
} else {
|
||||
ty
|
||||
Ok(ty)
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_predicate(&mut self, pred: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> {
|
||||
fn fold_predicate(
|
||||
&mut self,
|
||||
pred: ty::Predicate<'tcx>,
|
||||
) -> Result<ty::Predicate<'tcx>, Self::Error> {
|
||||
if pred.inner.flags.intersects(TypeFlags::HAS_UNKNOWN_DEFAULT_CONST_SUBSTS) {
|
||||
pred.super_fold_with(self)
|
||||
} else {
|
||||
pred
|
||||
Ok(pred)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -622,7 +622,7 @@ fn polymorphize<'tcx>(
|
||||
self.tcx
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
debug!("fold_ty: ty={:?}", ty);
|
||||
match ty.kind {
|
||||
ty::Closure(def_id, substs) => {
|
||||
@ -631,11 +631,11 @@ fn polymorphize<'tcx>(
|
||||
ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id)),
|
||||
substs,
|
||||
);
|
||||
if substs == polymorphized_substs {
|
||||
Ok(if substs == polymorphized_substs {
|
||||
ty
|
||||
} else {
|
||||
self.tcx.mk_closure(def_id, polymorphized_substs)
|
||||
}
|
||||
})
|
||||
}
|
||||
ty::Generator(def_id, substs, movability) => {
|
||||
let polymorphized_substs = polymorphize(
|
||||
@ -643,11 +643,11 @@ fn polymorphize<'tcx>(
|
||||
ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id)),
|
||||
substs,
|
||||
);
|
||||
if substs == polymorphized_substs {
|
||||
Ok(if substs == polymorphized_substs {
|
||||
ty
|
||||
} else {
|
||||
self.tcx.mk_generator(def_id, polymorphized_substs, movability)
|
||||
}
|
||||
})
|
||||
}
|
||||
_ => ty.super_fold_with(self),
|
||||
}
|
||||
@ -669,7 +669,7 @@ fn polymorphize<'tcx>(
|
||||
// ..and polymorphize any closures/generators captured as upvars.
|
||||
let upvars_ty = upvars_ty.unwrap();
|
||||
let polymorphized_upvars_ty = upvars_ty.fold_with(
|
||||
&mut PolymorphizationFolder { tcx });
|
||||
&mut PolymorphizationFolder { tcx }).into_ok();
|
||||
debug!("polymorphize: polymorphized_upvars_ty={:?}", polymorphized_upvars_ty);
|
||||
ty::GenericArg::from(polymorphized_upvars_ty)
|
||||
},
|
||||
|
@ -1260,8 +1260,11 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ParamEnv<'tcx> {
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for ParamEnv<'tcx> {
|
||||
fn super_fold_with<F: ty::fold::TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
|
||||
ParamEnv::new(self.caller_bounds().fold_with(folder), self.reveal().fold_with(folder))
|
||||
fn super_fold_with<F: ty::fold::TypeFolder<'tcx>>(
|
||||
self,
|
||||
folder: &mut F,
|
||||
) -> Result<Self, F::Error> {
|
||||
Ok(ParamEnv::new(self.caller_bounds().fold_with(folder)?, self.reveal().fold_with(folder)?))
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
||||
|
@ -35,7 +35,9 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
if !value.has_projections() {
|
||||
value
|
||||
} else {
|
||||
value.fold_with(&mut NormalizeAfterErasingRegionsFolder { tcx: self, param_env })
|
||||
value
|
||||
.fold_with(&mut NormalizeAfterErasingRegionsFolder { tcx: self, param_env })
|
||||
.into_ok()
|
||||
}
|
||||
}
|
||||
|
||||
@ -103,18 +105,24 @@ impl TypeFolder<'tcx> for NormalizeAfterErasingRegionsFolder<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
self.normalize_generic_arg_after_erasing_regions(ty.into()).expect_ty()
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
Ok(self.normalize_generic_arg_after_erasing_regions(ty.into()).expect_ty())
|
||||
}
|
||||
|
||||
fn fold_const(&mut self, c: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||
self.normalize_generic_arg_after_erasing_regions(c.into()).expect_const()
|
||||
fn fold_const(
|
||||
&mut self,
|
||||
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]
|
||||
fn fold_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> {
|
||||
fn fold_mir_const(
|
||||
&mut self,
|
||||
c: mir::ConstantKind<'tcx>,
|
||||
) -> Result<mir::ConstantKind<'tcx>, Self::Error> {
|
||||
// FIXME: This *probably* needs canonicalization too!
|
||||
let arg = self.param_env.and(c);
|
||||
self.tcx.normalize_mir_const_after_erasing_regions(arg)
|
||||
Ok(self.tcx.normalize_mir_const_after_erasing_regions(arg))
|
||||
}
|
||||
}
|
||||
|
@ -2016,24 +2016,24 @@ impl<'a, 'tcx> ty::TypeFolder<'tcx> for RegionFolder<'a, 'tcx> {
|
||||
fn fold_binder<T: TypeFoldable<'tcx>>(
|
||||
&mut self,
|
||||
t: ty::Binder<'tcx, T>,
|
||||
) -> ty::Binder<'tcx, T> {
|
||||
) -> Result<ty::Binder<'tcx, T>, Self::Error> {
|
||||
self.current_index.shift_in(1);
|
||||
let t = t.super_fold_with(self);
|
||||
self.current_index.shift_out(1);
|
||||
t
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
match *t.kind() {
|
||||
_ if t.has_vars_bound_at_or_above(self.current_index) || t.has_placeholders() => {
|
||||
return t.super_fold_with(self);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
t
|
||||
Ok(t)
|
||||
}
|
||||
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
||||
let name = &mut self.name;
|
||||
let region = match *r {
|
||||
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 r,
|
||||
_ => return Ok(r),
|
||||
};
|
||||
if let ty::ReLateBound(debruijn1, br) = *region {
|
||||
assert_eq!(debruijn1, ty::INNERMOST);
|
||||
self.tcx.mk_region(ty::ReLateBound(self.current_index, br))
|
||||
Ok(self.tcx.mk_region(ty::ReLateBound(self.current_index, br)))
|
||||
} else {
|
||||
region
|
||||
Ok(region)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2193,7 +2193,7 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
|
||||
name: &mut name,
|
||||
region_map: BTreeMap::new(),
|
||||
};
|
||||
let new_value = value.clone().skip_binder().fold_with(&mut folder);
|
||||
let new_value = value.clone().skip_binder().fold_with(&mut folder).into_ok();
|
||||
let region_map = folder.region_map;
|
||||
start_or_continue(&mut self, "", "> ");
|
||||
(new_value, region_map)
|
||||
|
@ -669,8 +669,8 @@ impl<'a, 'tcx> Lift<'tcx> for ty::InstanceDef<'a> {
|
||||
|
||||
/// AdtDefs are basically the same as a DefId.
|
||||
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::AdtDef {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, _folder: &mut F) -> Self {
|
||||
self
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, _folder: &mut F) -> Result<Self, F::Error> {
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
||||
@ -679,8 +679,8 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::AdtDef {
|
||||
}
|
||||
|
||||
impl<'tcx, T: TypeFoldable<'tcx>, U: TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T, U) {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> (T, U) {
|
||||
(self.0.fold_with(folder), self.1.fold_with(folder))
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<(T, U), F::Error> {
|
||||
Ok((self.0.fold_with(folder)?, self.1.fold_with(folder)?))
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
||||
@ -692,8 +692,8 @@ impl<'tcx, T: TypeFoldable<'tcx>, U: TypeFoldable<'tcx>> TypeFoldable<'tcx> for
|
||||
impl<'tcx, A: TypeFoldable<'tcx>, B: TypeFoldable<'tcx>, C: TypeFoldable<'tcx>> TypeFoldable<'tcx>
|
||||
for (A, B, C)
|
||||
{
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> (A, B, C) {
|
||||
(self.0.fold_with(folder), self.1.fold_with(folder), self.2.fold_with(folder))
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<(A, B, C), F::Error> {
|
||||
Ok((self.0.fold_with(folder)?, self.1.fold_with(folder)?, self.2.fold_with(folder)?))
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
||||
@ -718,9 +718,9 @@ EnumTypeFoldableImpl! {
|
||||
}
|
||||
|
||||
impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Rc<T> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||
// FIXME: Reuse the `Rc` here.
|
||||
Rc::new((*self).clone().fold_with(folder))
|
||||
Ok(Rc::new((*self).clone().fold_with(folder)?))
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
||||
@ -729,9 +729,9 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Rc<T> {
|
||||
}
|
||||
|
||||
impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Arc<T> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||
// FIXME: Reuse the `Arc` here.
|
||||
Arc::new((*self).clone().fold_with(folder))
|
||||
Ok(Arc::new((*self).clone().fold_with(folder)?))
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
||||
@ -740,8 +740,8 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Arc<T> {
|
||||
}
|
||||
|
||||
impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<T> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
|
||||
self.map_id(|value| value.fold_with(folder))
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||
self.try_map_id(|value| value.fold_with(folder))
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
||||
@ -750,8 +750,8 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<T> {
|
||||
}
|
||||
|
||||
impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Vec<T> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
|
||||
self.map_id(|t| t.fold_with(folder))
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||
self.try_map_id(|t| t.fold_with(folder))
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
||||
@ -760,8 +760,8 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Vec<T> {
|
||||
}
|
||||
|
||||
impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<[T]> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
|
||||
self.map_id(|t| t.fold_with(folder))
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||
self.try_map_id(|t| t.fold_with(folder))
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
||||
@ -770,11 +770,11 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<[T]> {
|
||||
}
|
||||
|
||||
impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder<'tcx, T> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
|
||||
self.map_bound(|ty| ty.fold_with(folder))
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||
self.try_map_bound(|ty| ty.fold_with(folder))
|
||||
}
|
||||
|
||||
fn fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
|
||||
fn fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||
folder.fold_binder(self)
|
||||
}
|
||||
|
||||
@ -788,7 +788,7 @@ 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>>> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||
ty::util::fold_list(self, folder, |tcx, v| tcx.intern_poly_existential_predicates(v))
|
||||
}
|
||||
|
||||
@ -798,7 +798,7 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Binder<'tcx, ty::Existentia
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<Ty<'tcx>> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||
ty::util::fold_list(self, folder, |tcx, v| tcx.intern_type_list(v))
|
||||
}
|
||||
|
||||
@ -808,7 +808,7 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<Ty<'tcx>> {
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ProjectionKind> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||
ty::util::fold_list(self, folder, |tcx, v| tcx.intern_projs(v))
|
||||
}
|
||||
|
||||
@ -818,24 +818,24 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ProjectionKind> {
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||
use crate::ty::InstanceDef::*;
|
||||
Self {
|
||||
substs: self.substs.fold_with(folder),
|
||||
Ok(Self {
|
||||
substs: self.substs.fold_with(folder)?,
|
||||
def: match self.def {
|
||||
Item(def) => Item(def.fold_with(folder)),
|
||||
VtableShim(did) => VtableShim(did.fold_with(folder)),
|
||||
ReifyShim(did) => ReifyShim(did.fold_with(folder)),
|
||||
Intrinsic(did) => Intrinsic(did.fold_with(folder)),
|
||||
FnPtrShim(did, ty) => FnPtrShim(did.fold_with(folder), ty.fold_with(folder)),
|
||||
Virtual(did, i) => Virtual(did.fold_with(folder), i),
|
||||
Item(def) => Item(def.fold_with(folder)?),
|
||||
VtableShim(did) => VtableShim(did.fold_with(folder)?),
|
||||
ReifyShim(did) => ReifyShim(did.fold_with(folder)?),
|
||||
Intrinsic(did) => Intrinsic(did.fold_with(folder)?),
|
||||
FnPtrShim(did, ty) => FnPtrShim(did.fold_with(folder)?, ty.fold_with(folder)?),
|
||||
Virtual(did, i) => Virtual(did.fold_with(folder)?, i),
|
||||
ClosureOnceShim { call_once, track_caller } => {
|
||||
ClosureOnceShim { call_once: call_once.fold_with(folder), track_caller }
|
||||
ClosureOnceShim { call_once: call_once.fold_with(folder)?, track_caller }
|
||||
}
|
||||
DropGlue(did, ty) => DropGlue(did.fold_with(folder), ty.fold_with(folder)),
|
||||
CloneShim(did, ty) => CloneShim(did.fold_with(folder), ty.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)?),
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
||||
@ -860,8 +860,8 @@ impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> {
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for interpret::GlobalId<'tcx> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
|
||||
Self { instance: self.instance.fold_with(folder), promoted: self.promoted }
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||
Ok(Self { instance: self.instance.fold_with(folder)?, promoted: self.promoted })
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
||||
@ -870,26 +870,26 @@ impl<'tcx> TypeFoldable<'tcx> for interpret::GlobalId<'tcx> {
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||
let kind = match *self.kind() {
|
||||
ty::RawPtr(tm) => ty::RawPtr(tm.fold_with(folder)),
|
||||
ty::Array(typ, sz) => ty::Array(typ.fold_with(folder), sz.fold_with(folder)),
|
||||
ty::Slice(typ) => ty::Slice(typ.fold_with(folder)),
|
||||
ty::Adt(tid, substs) => ty::Adt(tid, substs.fold_with(folder)),
|
||||
ty::RawPtr(tm) => ty::RawPtr(tm.fold_with(folder)?),
|
||||
ty::Array(typ, sz) => ty::Array(typ.fold_with(folder)?, sz.fold_with(folder)?),
|
||||
ty::Slice(typ) => ty::Slice(typ.fold_with(folder)?),
|
||||
ty::Adt(tid, substs) => ty::Adt(tid, substs.fold_with(folder)?),
|
||||
ty::Dynamic(trait_ty, region) => {
|
||||
ty::Dynamic(trait_ty.fold_with(folder), region.fold_with(folder))
|
||||
ty::Dynamic(trait_ty.fold_with(folder)?, region.fold_with(folder)?)
|
||||
}
|
||||
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::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.fold_with(folder), movability)
|
||||
ty::Generator(did, substs.fold_with(folder)?, movability)
|
||||
}
|
||||
ty::GeneratorWitness(types) => ty::GeneratorWitness(types.fold_with(folder)),
|
||||
ty::Closure(did, substs) => ty::Closure(did, substs.fold_with(folder)),
|
||||
ty::Projection(data) => ty::Projection(data.fold_with(folder)),
|
||||
ty::Opaque(did, substs) => ty::Opaque(did, substs.fold_with(folder)),
|
||||
ty::GeneratorWitness(types) => ty::GeneratorWitness(types.fold_with(folder)?),
|
||||
ty::Closure(did, substs) => ty::Closure(did, substs.fold_with(folder)?),
|
||||
ty::Projection(data) => ty::Projection(data.fold_with(folder)?),
|
||||
ty::Opaque(did, substs) => ty::Opaque(did, substs.fold_with(folder)?),
|
||||
|
||||
ty::Bool
|
||||
| ty::Char
|
||||
@ -903,13 +903,13 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
|
||||
| ty::Bound(..)
|
||||
| ty::Placeholder(..)
|
||||
| ty::Never
|
||||
| ty::Foreign(..) => return self,
|
||||
| ty::Foreign(..) => return Ok(self),
|
||||
};
|
||||
|
||||
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) -> Self {
|
||||
fn fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||
folder.fold_ty(self)
|
||||
}
|
||||
|
||||
@ -961,11 +961,11 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for ty::Region<'tcx> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, _folder: &mut F) -> Self {
|
||||
self
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, _folder: &mut F) -> Result<Self, F::Error> {
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
fn fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
|
||||
fn fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||
folder.fold_region(self)
|
||||
}
|
||||
|
||||
@ -979,13 +979,13 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Region<'tcx> {
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> {
|
||||
fn fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
|
||||
fn fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||
folder.fold_predicate(self)
|
||||
}
|
||||
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
|
||||
let new = self.inner.kind.fold_with(folder);
|
||||
folder.tcx().reuse_or_mk_predicate(self, new)
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||
let new = self.inner.kind.fold_with(folder)?;
|
||||
Ok(folder.tcx().reuse_or_mk_predicate(self, new))
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
||||
@ -1006,7 +1006,7 @@ impl<'tcx> TypeFoldable<'tcx> for 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) -> Self {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||
ty::util::fold_list(self, folder, |tcx, v| tcx.intern_predicates(v))
|
||||
}
|
||||
|
||||
@ -1016,8 +1016,8 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Predicate<'tcx>> {
|
||||
}
|
||||
|
||||
impl<'tcx, T: TypeFoldable<'tcx>, I: Idx> TypeFoldable<'tcx> for IndexVec<I, T> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
|
||||
self.map_id(|x| x.fold_with(folder))
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||
self.try_map_id(|x| x.fold_with(folder))
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
||||
@ -1026,17 +1026,17 @@ impl<'tcx, T: TypeFoldable<'tcx>, I: Idx> TypeFoldable<'tcx> for IndexVec<I, T>
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Const<'tcx> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
|
||||
let ty = self.ty.fold_with(folder);
|
||||
let val = self.val.fold_with(folder);
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||
let ty = self.ty.fold_with(folder)?;
|
||||
let val = self.val.fold_with(folder)?;
|
||||
if ty != self.ty || val != self.val {
|
||||
folder.tcx().mk_const(ty::Const { ty, val })
|
||||
Ok(folder.tcx().mk_const(ty::Const { ty, val }))
|
||||
} else {
|
||||
self
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
|
||||
fn fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||
folder.fold_const(self)
|
||||
}
|
||||
|
||||
@ -1051,16 +1051,16 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Const<'tcx> {
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
|
||||
match self {
|
||||
ty::ConstKind::Infer(ic) => ty::ConstKind::Infer(ic.fold_with(folder)),
|
||||
ty::ConstKind::Param(p) => ty::ConstKind::Param(p.fold_with(folder)),
|
||||
ty::ConstKind::Unevaluated(uv) => ty::ConstKind::Unevaluated(uv.fold_with(folder)),
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||
Ok(match self {
|
||||
ty::ConstKind::Infer(ic) => ty::ConstKind::Infer(ic.fold_with(folder)?),
|
||||
ty::ConstKind::Param(p) => ty::ConstKind::Param(p.fold_with(folder)?),
|
||||
ty::ConstKind::Unevaluated(uv) => ty::ConstKind::Unevaluated(uv.fold_with(folder)?),
|
||||
ty::ConstKind::Value(_)
|
||||
| ty::ConstKind::Bound(..)
|
||||
| ty::ConstKind::Placeholder(..)
|
||||
| ty::ConstKind::Error(_) => self,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
||||
@ -1077,8 +1077,8 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> {
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for InferConst<'tcx> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, _folder: &mut F) -> Self {
|
||||
self
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, _folder: &mut F) -> Result<Self, F::Error> {
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
||||
@ -1087,12 +1087,12 @@ impl<'tcx> TypeFoldable<'tcx> for InferConst<'tcx> {
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for ty::Unevaluated<'tcx> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
|
||||
ty::Unevaluated {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||
Ok(ty::Unevaluated {
|
||||
def: self.def,
|
||||
substs_: Some(self.substs(folder.tcx()).fold_with(folder)),
|
||||
substs_: Some(self.substs(folder.tcx()).fold_with(folder)?),
|
||||
promoted: self.promoted,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
||||
@ -1112,12 +1112,12 @@ 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) -> Self {
|
||||
ty::Unevaluated {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||
Ok(ty::Unevaluated {
|
||||
def: self.def,
|
||||
substs_: Some(self.substs(folder.tcx()).fold_with(folder)),
|
||||
substs_: Some(self.substs(folder.tcx()).fold_with(folder)?),
|
||||
promoted: self.promoted,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
||||
|
@ -1101,6 +1101,18 @@ impl<'tcx, T> Binder<'tcx, T> {
|
||||
Binder(value, self.1)
|
||||
}
|
||||
|
||||
pub fn try_map_bound<F, U: TypeFoldable<'tcx>, E>(self, f: F) -> Result<Binder<'tcx, U>, E>
|
||||
where
|
||||
F: FnOnce(T) -> Result<U, E>,
|
||||
{
|
||||
let value = f(self.0)?;
|
||||
if cfg!(debug_assertions) {
|
||||
let mut validator = ValidateBoundVars::new(self.1);
|
||||
value.visit_with(&mut validator);
|
||||
}
|
||||
Ok(Binder(value, self.1))
|
||||
}
|
||||
|
||||
/// Wraps a `value` in a binder, using the same bound variables as the
|
||||
/// current `Binder`. This should not be used if the new value *changes*
|
||||
/// the bound variables. Note: the (old or new) value itself does not
|
||||
|
@ -153,11 +153,11 @@ impl<'a, 'tcx> Lift<'tcx> for GenericArg<'a> {
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for GenericArg<'tcx> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||
match self.unpack() {
|
||||
GenericArgKind::Lifetime(lt) => lt.fold_with(folder).into(),
|
||||
GenericArgKind::Type(ty) => ty.fold_with(folder).into(),
|
||||
GenericArgKind::Const(ct) => ct.fold_with(folder).into(),
|
||||
GenericArgKind::Lifetime(lt) => lt.fold_with(folder).map(Into::into),
|
||||
GenericArgKind::Type(ty) => ty.fold_with(folder).map(Into::into),
|
||||
GenericArgKind::Const(ct) => ct.fold_with(folder).map(Into::into),
|
||||
}
|
||||
}
|
||||
|
||||
@ -372,7 +372,7 @@ impl<'a, 'tcx> InternalSubsts<'tcx> {
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for SubstsRef<'tcx> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
|
||||
// This code is hot enough that it's worth specializing for the most
|
||||
// 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
|
||||
@ -381,22 +381,27 @@ impl<'tcx> TypeFoldable<'tcx> for SubstsRef<'tcx> {
|
||||
// calling `intern_substs`.
|
||||
match self.len() {
|
||||
1 => {
|
||||
let param0 = self[0].fold_with(folder);
|
||||
if param0 == self[0] { self } else { folder.tcx().intern_substs(&[param0]) }
|
||||
let param0 = self[0].fold_with(folder)?;
|
||||
if param0 == self[0] { Ok(self) } else { Ok(folder.tcx().intern_substs(&[param0])) }
|
||||
}
|
||||
2 => {
|
||||
let param0 = self[0].fold_with(folder);
|
||||
let param1 = self[1].fold_with(folder);
|
||||
let param0 = self[0].fold_with(folder)?;
|
||||
let param1 = self[1].fold_with(folder)?;
|
||||
if param0 == self[0] && param1 == self[1] {
|
||||
self
|
||||
Ok(self)
|
||||
} else {
|
||||
folder.tcx().intern_substs(&[param0, param1])
|
||||
Ok(folder.tcx().intern_substs(&[param0, param1]))
|
||||
}
|
||||
}
|
||||
0 => self,
|
||||
0 => Ok(self),
|
||||
_ => {
|
||||
let params: SmallVec<[_; 8]> = self.iter().map(|k| k.fold_with(folder)).collect();
|
||||
if params[..] == self[..] { self } else { folder.tcx().intern_substs(¶ms) }
|
||||
let params: SmallVec<[_; 8]> =
|
||||
self.iter().map(|k| k.fold_with(folder)).collect::<Result<_, _>>()?;
|
||||
if params[..] == self[..] {
|
||||
Ok(self)
|
||||
} else {
|
||||
Ok(folder.tcx().intern_substs(¶ms))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -434,7 +439,7 @@ impl<'tcx, T: TypeFoldable<'tcx>> Subst<'tcx> for T {
|
||||
span: Option<Span>,
|
||||
) -> T {
|
||||
let mut folder = SubstFolder { tcx, substs, span, binders_passed: 0 };
|
||||
self.fold_with(&mut folder)
|
||||
self.fold_with(&mut folder).into_ok()
|
||||
}
|
||||
}
|
||||
|
||||
@ -460,14 +465,14 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> {
|
||||
fn fold_binder<T: TypeFoldable<'tcx>>(
|
||||
&mut self,
|
||||
t: ty::Binder<'tcx, T>,
|
||||
) -> ty::Binder<'tcx, T> {
|
||||
) -> Result<ty::Binder<'tcx, T>, Self::Error> {
|
||||
self.binders_passed += 1;
|
||||
let t = t.super_fold_with(self);
|
||||
let t = t.super_fold_with(self)?;
|
||||
self.binders_passed -= 1;
|
||||
t
|
||||
Ok(t)
|
||||
}
|
||||
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
||||
// Note: This routine only handles regions that are bound on
|
||||
// type declarations and other outer declarations, not those
|
||||
// bound in *fn types*. Region substitution of the bound
|
||||
@ -477,7 +482,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> {
|
||||
ty::ReEarlyBound(data) => {
|
||||
let rk = self.substs.get(data.index as usize).map(|k| k.unpack());
|
||||
match rk {
|
||||
Some(GenericArgKind::Lifetime(lt)) => self.shift_region_through_binders(lt),
|
||||
Some(GenericArgKind::Lifetime(lt)) => Ok(self.shift_region_through_binders(lt)),
|
||||
_ => {
|
||||
let span = self.span.unwrap_or(DUMMY_SP);
|
||||
let msg = format!(
|
||||
@ -489,31 +494,37 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => r,
|
||||
_ => Ok(r),
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
if !t.potentially_needs_subst() {
|
||||
return t;
|
||||
return Ok(t);
|
||||
}
|
||||
|
||||
match *t.kind() {
|
||||
ty::Param(p) => self.ty_for_param(p, t),
|
||||
ty::Param(p) => Ok(self.ty_for_param(p, t)),
|
||||
_ => t.super_fold_with(self),
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_const(&mut self, c: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||
fn fold_const(
|
||||
&mut self,
|
||||
c: &'tcx ty::Const<'tcx>,
|
||||
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
|
||||
if let ty::ConstKind::Param(p) = c.val {
|
||||
self.const_for_param(p, c)
|
||||
Ok(self.const_for_param(p, c))
|
||||
} else {
|
||||
c.super_fold_with(self)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn fold_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> {
|
||||
fn fold_mir_const(
|
||||
&mut self,
|
||||
c: mir::ConstantKind<'tcx>,
|
||||
) -> Result<mir::ConstantKind<'tcx>, Self::Error> {
|
||||
c.super_fold_with(self)
|
||||
}
|
||||
}
|
||||
|
@ -574,14 +574,14 @@ impl<'tcx> OpaqueTypeExpander<'tcx> {
|
||||
if self.found_any_recursion {
|
||||
return None;
|
||||
}
|
||||
let substs = substs.fold_with(self);
|
||||
let substs = substs.fold_with(self).into_ok();
|
||||
if !self.check_recursion || self.seen_opaque_tys.insert(def_id) {
|
||||
let expanded_ty = match self.expanded_cache.get(&(def_id, substs)) {
|
||||
Some(expanded_ty) => expanded_ty,
|
||||
None => {
|
||||
let generic_ty = self.tcx.type_of(def_id);
|
||||
let concrete_ty = generic_ty.subst(self.tcx, substs);
|
||||
let expanded_ty = self.fold_ty(concrete_ty);
|
||||
let expanded_ty = self.fold_ty(concrete_ty).into_ok();
|
||||
self.expanded_cache.insert((def_id, substs), expanded_ty);
|
||||
expanded_ty
|
||||
}
|
||||
@ -605,13 +605,13 @@ impl<'tcx> TypeFolder<'tcx> for OpaqueTypeExpander<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
if let ty::Opaque(def_id, substs) = t.kind {
|
||||
self.expand_opaque_ty(def_id, substs).unwrap_or(t)
|
||||
Ok(self.expand_opaque_ty(def_id, substs).unwrap_or(t))
|
||||
} else if t.has_opaque_types() {
|
||||
t.super_fold_with(self)
|
||||
} else {
|
||||
t
|
||||
Ok(t)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1046,25 +1046,31 @@ pub fn fold_list<'tcx, F, T>(
|
||||
list: &'tcx ty::List<T>,
|
||||
folder: &mut F,
|
||||
intern: impl FnOnce(TyCtxt<'tcx>, &[T]) -> &'tcx ty::List<T>,
|
||||
) -> &'tcx ty::List<T>
|
||||
) -> Result<&'tcx ty::List<T>, F::Error>
|
||||
where
|
||||
F: TypeFolder<'tcx>,
|
||||
T: TypeFoldable<'tcx> + PartialEq + Copy,
|
||||
{
|
||||
let mut iter = list.iter();
|
||||
// Look for the first element that changed
|
||||
if let Some((i, new_t)) = iter.by_ref().enumerate().find_map(|(i, t)| {
|
||||
let new_t = t.fold_with(folder);
|
||||
if new_t == t { None } else { Some((i, new_t)) }
|
||||
match iter.by_ref().enumerate().find_map(|(i, t)| match t.fold_with(folder) {
|
||||
Ok(new_t) if new_t == t => None,
|
||||
new_t => Some((i, new_t)),
|
||||
}) {
|
||||
Some((i, Ok(new_t))) => {
|
||||
// An element changed, prepare to intern the resulting list
|
||||
let mut new_list = SmallVec::<[_; 8]>::with_capacity(list.len());
|
||||
new_list.extend_from_slice(&list[..i]);
|
||||
new_list.push(new_t);
|
||||
new_list.extend(iter.map(|t| t.fold_with(folder)));
|
||||
intern(folder.tcx(), &new_list)
|
||||
} else {
|
||||
list
|
||||
for t in iter {
|
||||
new_list.push(t.fold_with(folder)?)
|
||||
}
|
||||
Ok(intern(folder.tcx(), &new_list))
|
||||
}
|
||||
Some((_, Err(err))) => {
|
||||
return Err(err);
|
||||
}
|
||||
None => Ok(list),
|
||||
}
|
||||
}
|
||||
|
||||
@ -1086,7 +1092,7 @@ pub fn normalize_opaque_types(
|
||||
check_recursion: false,
|
||||
tcx,
|
||||
};
|
||||
val.fold_with(&mut visitor)
|
||||
val.fold_with(&mut visitor).into_ok()
|
||||
}
|
||||
|
||||
pub fn provide(providers: &mut ty::query::Providers) {
|
||||
|
@ -22,6 +22,7 @@
|
||||
#![feature(never_type)]
|
||||
#![feature(crate_visibility_modifier)]
|
||||
#![feature(control_flow_enum)]
|
||||
#![feature(unwrap_infallible)]
|
||||
#![recursion_limit = "512"] // For rustdoc
|
||||
|
||||
#[macro_use]
|
||||
|
@ -65,14 +65,16 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
// Convert the type from the function into a type valid outside
|
||||
// the function, by replacing invalid regions with 'static,
|
||||
// after producing an error for each of them.
|
||||
let definition_ty = instantiated_ty.fold_with(&mut ReverseMapper::new(
|
||||
let definition_ty = instantiated_ty
|
||||
.fold_with(&mut ReverseMapper::new(
|
||||
self.tcx,
|
||||
self.is_tainted_by_errors(),
|
||||
def_id,
|
||||
map,
|
||||
instantiated_ty,
|
||||
span,
|
||||
));
|
||||
))
|
||||
.into_ok();
|
||||
debug!(?definition_ty);
|
||||
|
||||
definition_ty
|
||||
@ -123,14 +125,14 @@ impl ReverseMapper<'tcx> {
|
||||
) -> GenericArg<'tcx> {
|
||||
assert!(!self.map_missing_regions_to_empty);
|
||||
self.map_missing_regions_to_empty = true;
|
||||
let kind = kind.fold_with(self);
|
||||
let kind = kind.fold_with(self).into_ok();
|
||||
self.map_missing_regions_to_empty = false;
|
||||
kind
|
||||
}
|
||||
|
||||
fn fold_kind_normally(&mut self, kind: GenericArg<'tcx>) -> GenericArg<'tcx> {
|
||||
assert!(!self.map_missing_regions_to_empty);
|
||||
kind.fold_with(self)
|
||||
kind.fold_with(self).into_ok()
|
||||
}
|
||||
}
|
||||
|
||||
@ -140,17 +142,17 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
|
||||
}
|
||||
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
||||
match r {
|
||||
// Ignore bound regions and `'static` regions that appear in the
|
||||
// type, we only need to remap regions that reference lifetimes
|
||||
// from the function declaraion.
|
||||
// This would ignore `'r` in a type like `for<'r> fn(&'r u32)`.
|
||||
ty::ReLateBound(..) | ty::ReStatic => return r,
|
||||
ty::ReLateBound(..) | ty::ReStatic => return Ok(r),
|
||||
|
||||
// If regions have been erased (by writeback), don't try to unerase
|
||||
// them.
|
||||
ty::ReErased => return r,
|
||||
ty::ReErased => return Ok(r),
|
||||
|
||||
// The regions that we expect from borrow checking.
|
||||
ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReEmpty(ty::UniverseIndex::ROOT) => {}
|
||||
@ -165,10 +167,10 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
|
||||
|
||||
let generics = self.tcx().generics_of(self.opaque_type_def_id);
|
||||
match self.map.get(&r.into()).map(|k| k.unpack()) {
|
||||
Some(GenericArgKind::Lifetime(r1)) => r1,
|
||||
Some(GenericArgKind::Lifetime(r1)) => Ok(r1),
|
||||
Some(u) => panic!("region mapped to unexpected kind: {:?}", u),
|
||||
None if self.map_missing_regions_to_empty || self.tainted_by_errors => {
|
||||
self.tcx.lifetimes.re_root_empty
|
||||
Ok(self.tcx.lifetimes.re_root_empty)
|
||||
}
|
||||
None if generics.parent.is_some() => {
|
||||
if let Some(hidden_ty) = self.hidden_ty.take() {
|
||||
@ -180,7 +182,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
self.tcx.lifetimes.re_root_empty
|
||||
Ok(self.tcx.lifetimes.re_root_empty)
|
||||
}
|
||||
None => {
|
||||
self.tcx
|
||||
@ -196,12 +198,12 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
|
||||
)
|
||||
.emit();
|
||||
|
||||
self.tcx().lifetimes.re_static
|
||||
Ok(self.tcx().lifetimes.re_static)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
match *ty.kind() {
|
||||
ty::Closure(def_id, substs) => {
|
||||
// I am a horrible monster and I pray for death. When
|
||||
@ -239,7 +241,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
|
||||
}
|
||||
}));
|
||||
|
||||
self.tcx.mk_closure(def_id, substs)
|
||||
Ok(self.tcx.mk_closure(def_id, substs))
|
||||
}
|
||||
|
||||
ty::Generator(def_id, substs, movability) => {
|
||||
@ -254,7 +256,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
|
||||
}
|
||||
}));
|
||||
|
||||
self.tcx.mk_generator(def_id, substs, movability)
|
||||
Ok(self.tcx.mk_generator(def_id, substs, movability))
|
||||
}
|
||||
|
||||
ty::Param(param) => {
|
||||
@ -262,7 +264,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
|
||||
match self.map.get(&ty.into()).map(|k| k.unpack()) {
|
||||
// Found it in the substitution list; replace with the parameter from the
|
||||
// opaque type.
|
||||
Some(GenericArgKind::Type(t1)) => t1,
|
||||
Some(GenericArgKind::Type(t1)) => Ok(t1),
|
||||
Some(u) => panic!("type mapped to unexpected kind: {:?}", u),
|
||||
None => {
|
||||
debug!(?param, ?self.map);
|
||||
@ -278,7 +280,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
|
||||
)
|
||||
.emit();
|
||||
|
||||
self.tcx().ty_error()
|
||||
Ok(self.tcx().ty_error())
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -287,10 +289,13 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||
fn fold_const(
|
||||
&mut self,
|
||||
ct: &'tcx ty::Const<'tcx>,
|
||||
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
|
||||
trace!("checking const {:?}", ct);
|
||||
// Find a const parameter
|
||||
match ct.val {
|
||||
Ok(match ct.val {
|
||||
ty::ConstKind::Param(..) => {
|
||||
// Look it up in the substitution list.
|
||||
match self.map.get(&ct.into()).map(|k| k.unpack()) {
|
||||
@ -317,7 +322,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
|
||||
}
|
||||
|
||||
_ => ct,
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -860,11 +860,11 @@ impl<'a, 'tcx> TypeFolder<'tcx> for RegionReplacer<'a, 'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
(match r {
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
||||
Ok((match r {
|
||||
ty::ReVar(vid) => self.vid_to_region.get(vid).cloned(),
|
||||
_ => None,
|
||||
})
|
||||
.unwrap_or_else(|| r.super_fold_with(self))
|
||||
.unwrap_or_else(|| r.super_fold_with(self).into_ok()))
|
||||
}
|
||||
}
|
||||
|
@ -1898,15 +1898,15 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
self.infcx.tcx
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
if let ty::Param(ty::ParamTy { name, .. }) = *ty.kind() {
|
||||
let infcx = self.infcx;
|
||||
self.var_map.entry(ty).or_insert_with(|| {
|
||||
Ok(self.var_map.entry(ty).or_insert_with(|| {
|
||||
infcx.next_ty_var(TypeVariableOrigin {
|
||||
kind: TypeVariableOriginKind::TypeParameterDefinition(name, None),
|
||||
span: DUMMY_SP,
|
||||
})
|
||||
})
|
||||
}))
|
||||
} else {
|
||||
ty.super_fold_with(self)
|
||||
}
|
||||
@ -1916,8 +1916,9 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
self.probe(|_| {
|
||||
let mut selcx = SelectionContext::new(self);
|
||||
|
||||
let cleaned_pred =
|
||||
pred.fold_with(&mut ParamToVarFolder { infcx: self, var_map: Default::default() });
|
||||
let cleaned_pred = pred
|
||||
.fold_with(&mut ParamToVarFolder { infcx: self, var_map: Default::default() })
|
||||
.into_ok();
|
||||
|
||||
let cleaned_pred = super::project::normalize(
|
||||
&mut selcx,
|
||||
|
@ -339,7 +339,7 @@ impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> {
|
||||
if !needs_normalization(&value, self.param_env.reveal()) {
|
||||
value
|
||||
} else {
|
||||
value.fold_with(self)
|
||||
value.fold_with(self).into_ok()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -352,16 +352,16 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
|
||||
fn fold_binder<T: TypeFoldable<'tcx>>(
|
||||
&mut self,
|
||||
t: ty::Binder<'tcx, T>,
|
||||
) -> ty::Binder<'tcx, T> {
|
||||
) -> Result<ty::Binder<'tcx, T>, Self::Error> {
|
||||
self.universes.push(None);
|
||||
let t = t.super_fold_with(self);
|
||||
self.universes.pop();
|
||||
t
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
if !needs_normalization(&ty, self.param_env.reveal()) {
|
||||
return ty;
|
||||
return Ok(ty);
|
||||
}
|
||||
|
||||
// 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
|
||||
// to make sure we don't forget to fold the substs regardless.
|
||||
|
||||
match *ty.kind() {
|
||||
Ok(match *ty.kind() {
|
||||
// This is really important. While we *can* handle this, this has
|
||||
// severe performance implications for large opaque types with
|
||||
// late-bound regions. See `issue-88862` benchmark.
|
||||
ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => {
|
||||
// Only normalize `impl Trait` after type-checking, usually in codegen.
|
||||
match self.param_env.reveal() {
|
||||
Reveal::UserFacing => ty.super_fold_with(self),
|
||||
Reveal::UserFacing => ty.super_fold_with(self)?,
|
||||
|
||||
Reveal::All => {
|
||||
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);
|
||||
}
|
||||
|
||||
let substs = substs.super_fold_with(self);
|
||||
let substs = substs.super_fold_with(self)?;
|
||||
let generic_ty = self.tcx().type_of(def_id);
|
||||
let concrete_ty = generic_ty.subst(self.tcx(), substs);
|
||||
self.depth += 1;
|
||||
let folded_ty = self.fold_ty(concrete_ty);
|
||||
let folded_ty = self.fold_ty(concrete_ty)?;
|
||||
self.depth -= 1;
|
||||
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
|
||||
// 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(
|
||||
self.selcx,
|
||||
self.param_env,
|
||||
@ -461,7 +461,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
|
||||
let infcx = self.selcx.infcx();
|
||||
let (data, mapped_regions, mapped_types, mapped_consts) =
|
||||
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(
|
||||
self.selcx,
|
||||
self.param_env,
|
||||
@ -473,6 +473,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
|
||||
.ok()
|
||||
.flatten()
|
||||
.map(|normalized_ty| {
|
||||
Ok({
|
||||
PlaceholderReplacer::replace_placeholders(
|
||||
infcx,
|
||||
mapped_regions,
|
||||
@ -482,7 +483,8 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
|
||||
normalized_ty,
|
||||
)
|
||||
})
|
||||
.unwrap_or_else(|| ty.super_fold_with(self));
|
||||
})
|
||||
.unwrap_or_else(|| ty.super_fold_with(self))?;
|
||||
|
||||
debug!(
|
||||
?self.depth,
|
||||
@ -494,16 +496,19 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
|
||||
normalized_ty
|
||||
}
|
||||
|
||||
_ => ty.super_fold_with(self),
|
||||
}
|
||||
_ => ty.super_fold_with(self)?,
|
||||
})
|
||||
}
|
||||
|
||||
fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||
fn fold_const(
|
||||
&mut self,
|
||||
constant: &'tcx ty::Const<'tcx>,
|
||||
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
|
||||
if self.selcx.tcx().lazy_normalization() {
|
||||
constant
|
||||
Ok(constant)
|
||||
} else {
|
||||
let constant = constant.super_fold_with(self);
|
||||
constant.eval(self.selcx.tcx(), self.param_env)
|
||||
let constant = constant.super_fold_with(self)?;
|
||||
Ok(constant.eval(self.selcx.tcx(), self.param_env))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -550,7 +555,7 @@ impl<'me, 'tcx> BoundVarReplacer<'me, 'tcx> {
|
||||
universe_indices,
|
||||
};
|
||||
|
||||
let value = value.super_fold_with(&mut replacer);
|
||||
let value = value.super_fold_with(&mut replacer).into_ok();
|
||||
|
||||
(value, replacer.mapped_regions, replacer.mapped_types, replacer.mapped_consts)
|
||||
}
|
||||
@ -577,14 +582,14 @@ impl TypeFolder<'tcx> for BoundVarReplacer<'_, 'tcx> {
|
||||
fn fold_binder<T: TypeFoldable<'tcx>>(
|
||||
&mut self,
|
||||
t: ty::Binder<'tcx, T>,
|
||||
) -> ty::Binder<'tcx, T> {
|
||||
) -> Result<ty::Binder<'tcx, T>, Self::Error> {
|
||||
self.current_index.shift_in(1);
|
||||
let t = t.super_fold_with(self);
|
||||
self.current_index.shift_out(1);
|
||||
t
|
||||
}
|
||||
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
||||
match *r {
|
||||
ty::ReLateBound(debruijn, _)
|
||||
if debruijn.as_usize() + 1
|
||||
@ -596,13 +601,13 @@ impl TypeFolder<'tcx> for BoundVarReplacer<'_, 'tcx> {
|
||||
let universe = self.universe_for(debruijn);
|
||||
let p = ty::PlaceholderRegion { universe, name: br.kind };
|
||||
self.mapped_regions.insert(p, br);
|
||||
self.infcx.tcx.mk_region(ty::RePlaceholder(p))
|
||||
Ok(self.infcx.tcx.mk_region(ty::RePlaceholder(p)))
|
||||
}
|
||||
_ => r,
|
||||
_ => Ok(r),
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
match *t.kind() {
|
||||
ty::Bound(debruijn, _)
|
||||
if debruijn.as_usize() + 1
|
||||
@ -614,14 +619,17 @@ impl TypeFolder<'tcx> for BoundVarReplacer<'_, 'tcx> {
|
||||
let universe = self.universe_for(debruijn);
|
||||
let p = ty::PlaceholderType { universe, name: bound_ty.var };
|
||||
self.mapped_types.insert(p, bound_ty);
|
||||
self.infcx.tcx.mk_ty(ty::Placeholder(p))
|
||||
Ok(self.infcx.tcx.mk_ty(ty::Placeholder(p)))
|
||||
}
|
||||
_ if t.has_vars_bound_at_or_above(self.current_index) => t.super_fold_with(self),
|
||||
_ => t,
|
||||
_ => Ok(t),
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||
fn fold_const(
|
||||
&mut self,
|
||||
ct: &'tcx ty::Const<'tcx>,
|
||||
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
|
||||
match *ct {
|
||||
ty::Const { val: ty::ConstKind::Bound(debruijn, _), ty: _ }
|
||||
if debruijn.as_usize() + 1
|
||||
@ -638,10 +646,10 @@ impl TypeFolder<'tcx> for BoundVarReplacer<'_, 'tcx> {
|
||||
name: ty::BoundConst { var: bound_const, ty },
|
||||
};
|
||||
self.mapped_consts.insert(p, bound_const);
|
||||
self.infcx.tcx.mk_const(ty::Const { val: ty::ConstKind::Placeholder(p), ty })
|
||||
Ok(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),
|
||||
_ => ct,
|
||||
_ => Ok(ct),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -673,7 +681,7 @@ impl<'me, 'tcx> PlaceholderReplacer<'me, 'tcx> {
|
||||
universe_indices,
|
||||
current_index: ty::INNERMOST,
|
||||
};
|
||||
value.super_fold_with(&mut replacer)
|
||||
value.super_fold_with(&mut replacer).into_ok()
|
||||
}
|
||||
}
|
||||
|
||||
@ -685,9 +693,9 @@ impl TypeFolder<'tcx> for PlaceholderReplacer<'_, 'tcx> {
|
||||
fn fold_binder<T: TypeFoldable<'tcx>>(
|
||||
&mut self,
|
||||
t: ty::Binder<'tcx, T>,
|
||||
) -> ty::Binder<'tcx, T> {
|
||||
) -> Result<ty::Binder<'tcx, T>, Self::Error> {
|
||||
if !t.has_placeholders() && !t.has_infer_regions() {
|
||||
return t;
|
||||
return Ok(t);
|
||||
}
|
||||
self.current_index.shift_in(1);
|
||||
let t = t.super_fold_with(self);
|
||||
@ -695,7 +703,7 @@ impl TypeFolder<'tcx> for PlaceholderReplacer<'_, 'tcx> {
|
||||
t
|
||||
}
|
||||
|
||||
fn fold_region(&mut self, r0: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
fn fold_region(&mut self, r0: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
||||
let r1 = match r0 {
|
||||
ty::ReVar(_) => self
|
||||
.infcx
|
||||
@ -729,10 +737,10 @@ impl TypeFolder<'tcx> for PlaceholderReplacer<'_, 'tcx> {
|
||||
|
||||
debug!(?r0, ?r1, ?r2, "fold_region");
|
||||
|
||||
r2
|
||||
Ok(r2)
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
match *ty.kind() {
|
||||
ty::Placeholder(p) => {
|
||||
let replace_var = self.mapped_types.get(&p);
|
||||
@ -746,18 +754,21 @@ impl TypeFolder<'tcx> for PlaceholderReplacer<'_, 'tcx> {
|
||||
let db = ty::DebruijnIndex::from_usize(
|
||||
self.universe_indices.len() - index + self.current_index.as_usize() - 1,
|
||||
);
|
||||
self.tcx().mk_ty(ty::Bound(db, *replace_var))
|
||||
Ok(self.tcx().mk_ty(ty::Bound(db, *replace_var)))
|
||||
}
|
||||
None => ty,
|
||||
None => Ok(ty),
|
||||
}
|
||||
}
|
||||
|
||||
_ if ty.has_placeholders() || ty.has_infer_regions() => ty.super_fold_with(self),
|
||||
_ => ty,
|
||||
_ => Ok(ty),
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||
fn fold_const(
|
||||
&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 {
|
||||
let replace_var = self.mapped_consts.get(&p);
|
||||
match replace_var {
|
||||
@ -770,10 +781,11 @@ impl TypeFolder<'tcx> for PlaceholderReplacer<'_, 'tcx> {
|
||||
let db = ty::DebruijnIndex::from_usize(
|
||||
self.universe_indices.len() - index + self.current_index.as_usize() - 1,
|
||||
);
|
||||
self.tcx()
|
||||
.mk_const(ty::Const { val: ty::ConstKind::Bound(db, *replace_var), ty })
|
||||
Ok(self
|
||||
.tcx()
|
||||
.mk_const(ty::Const { val: ty::ConstKind::Bound(db, *replace_var), ty }))
|
||||
}
|
||||
None => ct,
|
||||
None => Ok(ct),
|
||||
}
|
||||
} else {
|
||||
ct.super_fold_with(self)
|
||||
@ -1534,7 +1546,8 @@ fn confirm_candidate<'cx, 'tcx>(
|
||||
// when possible for this to work. See `auto-trait-projection-recursion.rs`
|
||||
// for a case where this matters.
|
||||
if progress.ty.has_infer_regions() {
|
||||
progress.ty = OpportunisticRegionResolver::new(selcx.infcx()).fold_ty(progress.ty);
|
||||
progress.ty =
|
||||
OpportunisticRegionResolver::new(selcx.infcx()).fold_ty(progress.ty).into_ok();
|
||||
}
|
||||
progress
|
||||
}
|
||||
|
@ -61,7 +61,6 @@ impl<'cx, 'tcx> AtExt<'tcx> for At<'cx, 'tcx> {
|
||||
cause: self.cause,
|
||||
param_env: self.param_env,
|
||||
obligations: vec![],
|
||||
error: false,
|
||||
cache: SsoHashMap::new(),
|
||||
anon_depth: 0,
|
||||
universes: vec![],
|
||||
@ -100,11 +99,7 @@ impl<'cx, 'tcx> AtExt<'tcx> for At<'cx, 'tcx> {
|
||||
std::any::type_name::<T>(),
|
||||
normalizer.obligations,
|
||||
);
|
||||
if normalizer.error {
|
||||
Err(NoSolution)
|
||||
} else {
|
||||
Ok(Normalized { value: result, obligations: normalizer.obligations })
|
||||
}
|
||||
result.map(|value| Normalized { value, obligations: normalizer.obligations })
|
||||
}
|
||||
}
|
||||
|
||||
@ -171,12 +166,13 @@ struct QueryNormalizer<'cx, 'tcx> {
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
obligations: Vec<PredicateObligation<'tcx>>,
|
||||
cache: SsoHashMap<Ty<'tcx>, Ty<'tcx>>,
|
||||
error: bool,
|
||||
anon_depth: usize,
|
||||
universes: Vec<Option<ty::UniverseIndex>>,
|
||||
}
|
||||
|
||||
impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
||||
type Error = NoSolution;
|
||||
|
||||
fn tcx<'c>(&'c self) -> TyCtxt<'tcx> {
|
||||
self.infcx.tcx
|
||||
}
|
||||
@ -184,7 +180,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
||||
fn fold_binder<T: TypeFoldable<'tcx>>(
|
||||
&mut self,
|
||||
t: ty::Binder<'tcx, T>,
|
||||
) -> ty::Binder<'tcx, T> {
|
||||
) -> Result<ty::Binder<'tcx, T>, Self::Error> {
|
||||
self.universes.push(None);
|
||||
let t = t.super_fold_with(self);
|
||||
self.universes.pop();
|
||||
@ -192,13 +188,13 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
if !needs_normalization(&ty, self.param_env.reveal()) {
|
||||
return ty;
|
||||
return Ok(ty);
|
||||
}
|
||||
|
||||
if let Some(ty) = self.cache.get(&ty) {
|
||||
return ty;
|
||||
return Ok(ty);
|
||||
}
|
||||
|
||||
// See note in `rustc_trait_selection::traits::project` about why we
|
||||
@ -215,7 +211,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
||||
Reveal::UserFacing => ty.super_fold_with(self),
|
||||
|
||||
Reveal::All => {
|
||||
let substs = substs.super_fold_with(self);
|
||||
let substs = substs.super_fold_with(self)?;
|
||||
let recursion_limit = self.tcx().recursion_limit();
|
||||
if !recursion_limit.value_within_limit(self.anon_depth) {
|
||||
let obligation = Obligation::with_depth(
|
||||
@ -252,7 +248,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
||||
// we don't need to replace them with placeholders (see branch below).
|
||||
|
||||
let tcx = self.infcx.tcx;
|
||||
let data = data.super_fold_with(self);
|
||||
let data = data.super_fold_with(self)?;
|
||||
|
||||
let mut orig_values = OriginalQueryValues::default();
|
||||
// HACK(matthewjasper) `'static` is special-cased in selection,
|
||||
@ -262,39 +258,22 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
||||
.canonicalize_query_keep_static(self.param_env.and(data), &mut orig_values);
|
||||
debug!("QueryNormalizer: c_data = {:#?}", c_data);
|
||||
debug!("QueryNormalizer: orig_values = {:#?}", orig_values);
|
||||
match tcx.normalize_projection_ty(c_data) {
|
||||
Ok(result) => {
|
||||
let result = tcx.normalize_projection_ty(c_data)?;
|
||||
// We don't expect ambiguity.
|
||||
if result.is_ambiguous() {
|
||||
self.error = true;
|
||||
return ty.super_fold_with(self);
|
||||
return Err(NoSolution);
|
||||
}
|
||||
|
||||
match self.infcx.instantiate_query_response_and_region_obligations(
|
||||
let InferOk { value: result, obligations } =
|
||||
self.infcx.instantiate_query_response_and_region_obligations(
|
||||
self.cause,
|
||||
self.param_env,
|
||||
&orig_values,
|
||||
result,
|
||||
) {
|
||||
Ok(InferOk { value: result, obligations }) => {
|
||||
)?;
|
||||
debug!("QueryNormalizer: result = {:#?}", result);
|
||||
debug!("QueryNormalizer: obligations = {:#?}", obligations);
|
||||
self.obligations.extend(obligations);
|
||||
result.normalized_ty
|
||||
}
|
||||
|
||||
Err(_) => {
|
||||
self.error = true;
|
||||
ty.super_fold_with(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Err(NoSolution) => {
|
||||
self.error = true;
|
||||
ty.super_fold_with(self)
|
||||
}
|
||||
}
|
||||
Ok(result.normalized_ty)
|
||||
}
|
||||
|
||||
ty::Projection(data) => {
|
||||
@ -308,7 +287,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
||||
&mut self.universes,
|
||||
data,
|
||||
);
|
||||
let data = data.super_fold_with(self);
|
||||
let data = data.super_fold_with(self)?;
|
||||
|
||||
let mut orig_values = OriginalQueryValues::default();
|
||||
// HACK(matthewjasper) `'static` is special-cased in selection,
|
||||
@ -318,57 +297,49 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
||||
.canonicalize_query_keep_static(self.param_env.and(data), &mut orig_values);
|
||||
debug!("QueryNormalizer: c_data = {:#?}", c_data);
|
||||
debug!("QueryNormalizer: orig_values = {:#?}", orig_values);
|
||||
match tcx.normalize_projection_ty(c_data) {
|
||||
Ok(result) => {
|
||||
let result = tcx.normalize_projection_ty(c_data)?;
|
||||
// We don't expect ambiguity.
|
||||
if result.is_ambiguous() {
|
||||
self.error = true;
|
||||
return ty.super_fold_with(self);
|
||||
return Err(NoSolution);
|
||||
}
|
||||
match self.infcx.instantiate_query_response_and_region_obligations(
|
||||
let InferOk { value: result, obligations } =
|
||||
self.infcx.instantiate_query_response_and_region_obligations(
|
||||
self.cause,
|
||||
self.param_env,
|
||||
&orig_values,
|
||||
result,
|
||||
) {
|
||||
Ok(InferOk { value: result, obligations }) => {
|
||||
)?;
|
||||
debug!("QueryNormalizer: result = {:#?}", result);
|
||||
debug!("QueryNormalizer: obligations = {:#?}", obligations);
|
||||
self.obligations.extend(obligations);
|
||||
crate::traits::project::PlaceholderReplacer::replace_placeholders(
|
||||
Ok(crate::traits::project::PlaceholderReplacer::replace_placeholders(
|
||||
infcx,
|
||||
mapped_regions,
|
||||
mapped_types,
|
||||
mapped_consts,
|
||||
&self.universes,
|
||||
result.normalized_ty,
|
||||
)
|
||||
}
|
||||
Err(_) => {
|
||||
self.error = true;
|
||||
ty.super_fold_with(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(NoSolution) => {
|
||||
self.error = true;
|
||||
ty.super_fold_with(self)
|
||||
}
|
||||
}
|
||||
))
|
||||
}
|
||||
|
||||
_ => ty.super_fold_with(self),
|
||||
})();
|
||||
})()?;
|
||||
self.cache.insert(ty, res);
|
||||
res
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||
let constant = constant.super_fold_with(self);
|
||||
constant.eval(self.infcx.tcx, self.param_env)
|
||||
fn fold_const(
|
||||
&mut self,
|
||||
constant: &'tcx ty::Const<'tcx>,
|
||||
) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
|
||||
let constant = constant.super_fold_with(self)?;
|
||||
Ok(constant.eval(self.infcx.tcx, self.param_env))
|
||||
}
|
||||
|
||||
fn fold_mir_const(&mut self, constant: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> {
|
||||
fn fold_mir_const(
|
||||
&mut self,
|
||||
constant: mir::ConstantKind<'tcx>,
|
||||
) -> Result<mir::ConstantKind<'tcx>, Self::Error> {
|
||||
constant.super_fold_with(self)
|
||||
}
|
||||
}
|
||||
|
@ -2222,6 +2222,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
.predicate
|
||||
.to_poly_trait_ref()
|
||||
.fold_with(&mut self.freshener)
|
||||
.into_ok()
|
||||
.with_constness(obligation.predicate.skip_binder().constness);
|
||||
|
||||
let dfn = previous_stack.cache.next_dfn();
|
||||
|
@ -45,7 +45,7 @@ impl<'tcx> RustIrDatabase<'tcx> {
|
||||
predicates
|
||||
.iter()
|
||||
.map(|(wc, _)| wc.subst(self.interner.tcx, bound_vars))
|
||||
.map(|wc| wc.fold_with(&mut regions_substitutor))
|
||||
.map(|wc| wc.fold_with(&mut regions_substitutor).into_ok())
|
||||
.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 mut regions_substitutor =
|
||||
lowering::RegionsSubstitutor::new(self.interner.tcx, self.reempty_placeholder);
|
||||
let trait_ref = trait_ref.fold_with(&mut regions_substitutor);
|
||||
let trait_ref = trait_ref.fold_with(&mut regions_substitutor).into_ok();
|
||||
|
||||
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 mut regions_substitutor =
|
||||
lowering::RegionsSubstitutor::new(self.interner.tcx, self.reempty_placeholder);
|
||||
let self_ty = self_ty.fold_with(&mut regions_substitutor);
|
||||
let self_ty = self_ty.fold_with(&mut regions_substitutor).into_ok();
|
||||
let lowered_ty = self_ty.lower_into(&self.interner);
|
||||
|
||||
parameters[0].assert_ty_ref(&self.interner).could_match(
|
||||
@ -501,7 +501,8 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
|
||||
.iter()
|
||||
.map(|(bound, _)| bound.subst(self.interner.tcx, &bound_vars))
|
||||
.map(|bound| {
|
||||
bound.fold_with(&mut ty::fold::BottomUpFolder {
|
||||
bound
|
||||
.fold_with(&mut ty::fold::BottomUpFolder {
|
||||
tcx: self.interner.tcx,
|
||||
ty_op: |ty| {
|
||||
if let ty::Opaque(def_id, substs) = *ty.kind() {
|
||||
@ -517,6 +518,7 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
|
||||
lt_op: |lt| lt,
|
||||
ct_op: |ct| ct,
|
||||
})
|
||||
.into_ok()
|
||||
})
|
||||
.filter_map(|bound| {
|
||||
LowerInto::<
|
||||
|
@ -817,7 +817,7 @@ crate fn collect_bound_vars<'tcx, T: TypeFoldable<'tcx>>(
|
||||
.collect();
|
||||
|
||||
let mut bound_var_substitutor = NamedBoundVarSubstitutor::new(tcx, &named_parameters);
|
||||
let new_ty = ty.skip_binder().fold_with(&mut bound_var_substitutor);
|
||||
let new_ty = ty.skip_binder().fold_with(&mut bound_var_substitutor).into_ok();
|
||||
|
||||
for var in named_parameters.values() {
|
||||
parameters.insert(*var, chalk_ir::VariableKind::Lifetime);
|
||||
@ -943,20 +943,23 @@ impl<'a, 'tcx> TypeFolder<'tcx> for NamedBoundVarSubstitutor<'a, 'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
fn fold_binder<T: TypeFoldable<'tcx>>(&mut self, t: Binder<'tcx, T>) -> Binder<'tcx, T> {
|
||||
fn fold_binder<T: TypeFoldable<'tcx>>(
|
||||
&mut self,
|
||||
t: Binder<'tcx, T>,
|
||||
) -> Result<Binder<'tcx, T>, Self::Error> {
|
||||
self.binder_index.shift_in(1);
|
||||
let result = t.super_fold_with(self);
|
||||
self.binder_index.shift_out(1);
|
||||
result
|
||||
}
|
||||
|
||||
fn fold_region(&mut self, r: Region<'tcx>) -> Region<'tcx> {
|
||||
fn fold_region(&mut self, r: Region<'tcx>) -> Result<Region<'tcx>, Self::Error> {
|
||||
match r {
|
||||
ty::ReLateBound(index, br) if *index == self.binder_index => match br.kind {
|
||||
ty::BrNamed(def_id, _name) => match self.named_parameters.get(&def_id) {
|
||||
Some(idx) => {
|
||||
let new_br = ty::BoundRegion { var: br.var, kind: ty::BrAnon(*idx) };
|
||||
return self.tcx.mk_region(RegionKind::ReLateBound(*index, new_br));
|
||||
return Ok(self.tcx.mk_region(RegionKind::ReLateBound(*index, new_br)));
|
||||
}
|
||||
None => panic!("Missing `BrNamed`."),
|
||||
},
|
||||
@ -999,32 +1002,35 @@ impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
fn fold_binder<T: TypeFoldable<'tcx>>(&mut self, t: Binder<'tcx, T>) -> Binder<'tcx, T> {
|
||||
fn fold_binder<T: TypeFoldable<'tcx>>(
|
||||
&mut self,
|
||||
t: Binder<'tcx, T>,
|
||||
) -> Result<Binder<'tcx, T>, Self::Error> {
|
||||
self.binder_index.shift_in(1);
|
||||
let result = t.super_fold_with(self);
|
||||
self.binder_index.shift_out(1);
|
||||
result
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
match *t.kind() {
|
||||
// FIXME(chalk): currently we convert params to placeholders starting at
|
||||
// index `0`. To support placeholders, we'll actually need to do a
|
||||
// first pass to collect placeholders. Then we can insert params after.
|
||||
ty::Placeholder(_) => unimplemented!(),
|
||||
ty::Param(param) => match self.list.iter().position(|r| r == ¶m) {
|
||||
Some(idx) => self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType {
|
||||
Some(idx) => Ok(self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType {
|
||||
universe: ty::UniverseIndex::from_usize(0),
|
||||
name: ty::BoundVar::from_usize(idx),
|
||||
})),
|
||||
}))),
|
||||
None => {
|
||||
self.list.push(param);
|
||||
let idx = self.list.len() - 1 + self.next_ty_placeholder;
|
||||
self.params.insert(idx, param);
|
||||
self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType {
|
||||
Ok(self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType {
|
||||
universe: ty::UniverseIndex::from_usize(0),
|
||||
name: ty::BoundVar::from_usize(idx),
|
||||
}))
|
||||
})))
|
||||
}
|
||||
},
|
||||
|
||||
@ -1032,7 +1038,7 @@ impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_region(&mut self, r: Region<'tcx>) -> Region<'tcx> {
|
||||
fn fold_region(&mut self, r: Region<'tcx>) -> Result<Region<'tcx>, Self::Error> {
|
||||
match r {
|
||||
// FIXME(chalk) - jackh726 - this currently isn't hit in any tests.
|
||||
// This covers any region variables in a goal, right?
|
||||
@ -1042,14 +1048,14 @@ impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> {
|
||||
var: ty::BoundVar::from_u32(*idx),
|
||||
kind: ty::BrAnon(*idx),
|
||||
};
|
||||
self.tcx.mk_region(RegionKind::ReLateBound(self.binder_index, br))
|
||||
Ok(self.tcx.mk_region(RegionKind::ReLateBound(self.binder_index, br)))
|
||||
}
|
||||
None => {
|
||||
let idx = self.named_regions.len() as u32;
|
||||
let br =
|
||||
ty::BoundRegion { var: ty::BoundVar::from_u32(idx), kind: ty::BrAnon(idx) };
|
||||
self.named_regions.insert(_re.def_id, idx);
|
||||
self.tcx.mk_region(RegionKind::ReLateBound(self.binder_index, br))
|
||||
Ok(self.tcx.mk_region(RegionKind::ReLateBound(self.binder_index, br)))
|
||||
}
|
||||
},
|
||||
|
||||
@ -1125,11 +1131,11 @@ impl<'tcx> TypeFolder<'tcx> for RegionsSubstitutor<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
fn fold_region(&mut self, r: Region<'tcx>) -> Region<'tcx> {
|
||||
fn fold_region(&mut self, r: Region<'tcx>) -> Result<Region<'tcx>, Self::Error> {
|
||||
match r {
|
||||
ty::ReEmpty(ui) => {
|
||||
assert_eq!(ui.as_usize(), 0);
|
||||
self.reempty_placeholder
|
||||
Ok(self.reempty_placeholder)
|
||||
}
|
||||
|
||||
_ => r.super_fold_with(self),
|
||||
|
@ -49,12 +49,12 @@ crate fn evaluate_goal<'tcx>(
|
||||
|
||||
let mut params_substitutor =
|
||||
ParamsSubstitutor::new(tcx, placeholders_collector.next_ty_placeholder);
|
||||
let obligation = obligation.fold_with(&mut params_substitutor);
|
||||
let obligation = obligation.fold_with(&mut params_substitutor).into_ok();
|
||||
// FIXME(chalk): we really should be substituting these back in the solution
|
||||
let _params: FxHashMap<usize, ParamTy> = params_substitutor.params;
|
||||
|
||||
let mut regions_substitutor = RegionsSubstitutor::new(tcx, reempty_placeholder);
|
||||
let obligation = obligation.fold_with(&mut regions_substitutor);
|
||||
let obligation = obligation.fold_with(&mut regions_substitutor).into_ok();
|
||||
|
||||
let max_universe = obligation.max_universe.index();
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
#![feature(crate_visibility_modifier)]
|
||||
#![feature(in_band_lifetimes)]
|
||||
#![feature(nll)]
|
||||
#![feature(unwrap_infallible)]
|
||||
#![recursion_limit = "256"]
|
||||
|
||||
#[macro_use]
|
||||
|
@ -442,8 +442,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let mut eraser = TypeParamEraser(self, expr.span);
|
||||
let needs_bound = self
|
||||
.lookup_op_method(
|
||||
eraser.fold_ty(lhs_ty),
|
||||
&[eraser.fold_ty(rhs_ty)],
|
||||
eraser.fold_ty(lhs_ty).into_ok(),
|
||||
&[eraser.fold_ty(rhs_ty).into_ok()],
|
||||
Op::Binary(op, is_assign),
|
||||
)
|
||||
.is_ok();
|
||||
@ -1015,12 +1015,12 @@ impl TypeFolder<'tcx> for TypeParamEraser<'_, 'tcx> {
|
||||
self.0.tcx
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
match ty.kind() {
|
||||
ty::Param(_) => self.0.next_ty_var(TypeVariableOrigin {
|
||||
ty::Param(_) => Ok(self.0.next_ty_var(TypeVariableOrigin {
|
||||
kind: TypeVariableOriginKind::MiscVariable,
|
||||
span: self.1,
|
||||
}),
|
||||
})),
|
||||
_ => ty.super_fold_with(self),
|
||||
}
|
||||
}
|
||||
|
@ -658,7 +658,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
||||
T: TypeFoldable<'tcx>,
|
||||
{
|
||||
let mut resolver = Resolver::new(self.fcx, span, self.body);
|
||||
let x = x.fold_with(&mut resolver);
|
||||
let x = x.fold_with(&mut resolver).into_ok();
|
||||
if cfg!(debug_assertions) && x.needs_infer() {
|
||||
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> {
|
||||
self.tcx
|
||||
}
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
if ty.has_type_flags(ty::TypeFlags::HAS_POTENTIAL_FREE_REGIONS) {
|
||||
ty.super_fold_with(self)
|
||||
} else {
|
||||
ty
|
||||
Ok(ty)
|
||||
}
|
||||
}
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
if let ty::ReLateBound(..) = r { r } else { self.tcx.lifetimes.re_erased }
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
||||
Ok(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
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
match self.infcx.fully_resolve(t) {
|
||||
Ok(t) => {
|
||||
// Do not anonymize late-bound regions
|
||||
@ -779,18 +779,21 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Resolver<'cx, 'tcx> {
|
||||
debug!("Resolver::fold_ty: input type `{:?}` not fully resolvable", t);
|
||||
self.report_type_error(t);
|
||||
self.replaced_with_error = true;
|
||||
self.tcx().ty_error()
|
||||
Ok(self.tcx().ty_error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
||||
debug_assert!(!r.is_late_bound(), "Should not be resolving bound region.");
|
||||
self.tcx.lifetimes.re_erased
|
||||
Ok(self.tcx.lifetimes.re_erased)
|
||||
}
|
||||
|
||||
fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||
match self.infcx.fully_resolve(ct) {
|
||||
fn fold_const(
|
||||
&mut self,
|
||||
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),
|
||||
Err(_) => {
|
||||
debug!("Resolver::fold_const: input const `{:?}` not fully resolvable", ct);
|
||||
@ -798,7 +801,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Resolver<'cx, 'tcx> {
|
||||
self.replaced_with_error = true;
|
||||
self.tcx().const_error(ct.ty)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -729,17 +729,17 @@ fn infer_placeholder_type<'a>(
|
||||
self.tcx
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
if !self.success {
|
||||
return ty;
|
||||
return Ok(ty);
|
||||
}
|
||||
|
||||
match ty.kind() {
|
||||
ty::FnDef(def_id, _) => self.tcx.mk_fn_ptr(self.tcx.fn_sig(*def_id)),
|
||||
ty::FnDef(def_id, _) => Ok(self.tcx.mk_fn_ptr(self.tcx.fn_sig(*def_id))),
|
||||
// FIXME: non-capturing closures should also suggest a function pointer
|
||||
ty::Closure(..) | ty::Generator(..) => {
|
||||
self.success = false;
|
||||
ty
|
||||
Ok(ty)
|
||||
}
|
||||
_ => ty.super_fold_with(self),
|
||||
}
|
||||
@ -761,7 +761,7 @@ fn infer_placeholder_type<'a>(
|
||||
|
||||
// Suggesting unnameable types won't help.
|
||||
let mut mk_nameable = MakeNameable::new(tcx);
|
||||
let ty = mk_nameable.fold_ty(ty);
|
||||
let ty = mk_nameable.fold_ty(ty).into_ok();
|
||||
let sugg_ty = if mk_nameable.success { Some(ty) } else { None };
|
||||
if let Some(sugg_ty) = sugg_ty {
|
||||
err.span_suggestion(
|
||||
@ -785,7 +785,7 @@ fn infer_placeholder_type<'a>(
|
||||
|
||||
if !ty.references_error() {
|
||||
let mut mk_nameable = MakeNameable::new(tcx);
|
||||
let ty = mk_nameable.fold_ty(ty);
|
||||
let ty = mk_nameable.fold_ty(ty).into_ok();
|
||||
let sugg_ty = if mk_nameable.success { Some(ty) } else { None };
|
||||
if let Some(sugg_ty) = sugg_ty {
|
||||
diag.span_suggestion(
|
||||
|
@ -71,8 +71,11 @@ fn diagnostic_hir_wf_check<'tcx>(
|
||||
fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
|
||||
self.tcx.infer_ctxt().enter(|infcx| {
|
||||
let mut fulfill = traits::FulfillmentContext::new();
|
||||
let tcx_ty =
|
||||
self.icx.to_ty(ty).fold_with(&mut EraseAllBoundRegions { tcx: self.tcx });
|
||||
let tcx_ty = self
|
||||
.icx
|
||||
.to_ty(ty)
|
||||
.fold_with(&mut EraseAllBoundRegions { tcx: self.tcx })
|
||||
.into_ok();
|
||||
let cause = traits::ObligationCause::new(
|
||||
ty.span,
|
||||
self.hir_id,
|
||||
@ -183,7 +186,7 @@ impl<'tcx> TypeFolder<'tcx> for EraseAllBoundRegions<'tcx> {
|
||||
fn tcx<'a>(&'a self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
fn fold_region(&mut self, r: Region<'tcx>) -> Region<'tcx> {
|
||||
if let ty::ReLateBound(..) = r { &ty::ReErased } else { r }
|
||||
fn fold_region(&mut self, r: Region<'tcx>) -> Result<Region<'tcx>, Self::Error> {
|
||||
if let ty::ReLateBound(..) = r { Ok(&ty::ReErased) } else { Ok(r) }
|
||||
}
|
||||
}
|
||||
|
@ -71,6 +71,7 @@ This API is completely unstable and subject to change.
|
||||
#![feature(slice_partition_dedup)]
|
||||
#![feature(control_flow_enum)]
|
||||
#![feature(hash_drain_filter)]
|
||||
#![feature(unwrap_infallible)]
|
||||
#![recursion_limit = "256"]
|
||||
|
||||
#[macro_use]
|
||||
|
@ -449,7 +449,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
|
||||
_ => false,
|
||||
}
|
||||
})
|
||||
.map(|p| p.fold_with(&mut replacer));
|
||||
.map(|p| p.fold_with(&mut replacer).into_ok());
|
||||
|
||||
let mut generic_params =
|
||||
(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
|
||||
}
|
||||
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
(match *r {
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
||||
Ok((match *r {
|
||||
ty::ReVar(vid) => self.vid_to_region.get(&vid).cloned(),
|
||||
_ => None,
|
||||
})
|
||||
.unwrap_or_else(|| r.super_fold_with(self))
|
||||
.unwrap_or_else(|| r.super_fold_with(self).into_ok()))
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
#![feature(type_ascription)]
|
||||
#![feature(iter_intersperse)]
|
||||
#![recursion_limit = "256"]
|
||||
#![feature(unwrap_infallible)]
|
||||
#![warn(rustc::internal)]
|
||||
|
||||
#[macro_use]
|
||||
|
Loading…
Reference in New Issue
Block a user