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