Adapt TypeFolder implementors to return a Result

Co-authored-by: Alan Egerton <eggyal@gmail.com>
This commit is contained in:
LeSeulArtichaut 2021-05-19 15:01:30 +02:00 committed by Alan Egerton
parent 6e3fa20b00
commit 6dc3dae46f
No known key found for this signature in database
GPG key ID: 07CAC3CCA7E0643F
24 changed files with 387 additions and 305 deletions

View file

@ -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) }
} }
} }

View file

@ -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(_) => {

View file

@ -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)

View file

@ -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
} })
} }
} }

View file

@ -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)
} }
@ -195,23 +201,23 @@ impl<'a, 'tcx> TypeFolder<'tcx> for FullTypeResolver<'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.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)) => {
self.err = Some(FixupError::UnresolvedTy(vid)); self.err = Some(FixupError::UnresolvedTy(vid));
self.tcx().ty_error() Ok(self.tcx().ty_error())
} }
ty::Infer(ty::IntVar(vid)) => { ty::Infer(ty::IntVar(vid)) => {
self.err = Some(FixupError::UnresolvedIntTy(vid)); self.err = Some(FixupError::UnresolvedIntTy(vid));
self.tcx().ty_error() Ok(self.tcx().ty_error())
} }
ty::Infer(ty::FloatVar(vid)) => { ty::Infer(ty::FloatVar(vid)) => {
self.err = Some(FixupError::UnresolvedFloatTy(vid)); self.err = Some(FixupError::UnresolvedFloatTy(vid));
self.tcx().ty_error() Ok(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 +227,31 @@ 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)); self.err = Some(FixupError::UnresolvedConst(vid));
return self.tcx().const_error(c.ty); return Ok(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);

View file

@ -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)
} }
} }

View file

@ -301,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))
} }
} }
@ -481,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);
@ -489,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))
} }
} }
} }
@ -539,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) => {
@ -559,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() {
@ -573,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) => {
@ -599,7 +605,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> {
} }
_ => {} _ => {}
} }
ct Ok(ct)
} }
} }
@ -949,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)))
} }
} }
@ -986,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)
@ -1295,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)
} }
} }
} }

View file

@ -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),
} }

View file

@ -103,18 +103,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))
} }
} }

View file

@ -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)
} }
} }
} }

View file

@ -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> {

View file

@ -465,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
@ -482,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!(
@ -494,31 +494,41 @@ 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 !c.potentially_needs_subst() {
return Ok(c);
}
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)
} }
} }

View file

@ -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),
} }
} }

View file

@ -140,17 +140,17 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
} }
#[instrument(skip(self), level = "debug")] #[instrument(skip(self), level = "debug")]
fn fold_region(&mut self, r: ty::Region<'tcx>) -> 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 +165,10 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
let generics = self.tcx().generics_of(self.opaque_type_def_id); let generics = self.tcx().generics_of(self.opaque_type_def_id);
match self.map.get(&r.into()).map(|k| k.unpack()) { match self.map.get(&r.into()).map(|k| k.unpack()) {
Some(GenericArgKind::Lifetime(r1)) => 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 +180,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 +196,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 +239,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 +254,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 +262,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
match self.map.get(&ty.into()).map(|k| k.unpack()) { match self.map.get(&ty.into()).map(|k| k.unpack()) {
// Found it in the substitution list; replace with the parameter from the // Found it in the substitution list; replace with the parameter from the
// opaque type. // opaque type.
Some(GenericArgKind::Type(t1)) => 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 +278,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
) )
.emit(); .emit();
self.tcx().ty_error() Ok(self.tcx().ty_error())
} }
} }
} }
@ -287,10 +287,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 +320,7 @@ impl TypeFolder<'tcx> for ReverseMapper<'tcx> {
} }
_ => ct, _ => ct,
} })
} }
} }

View file

@ -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()))
} }
} }

View file

@ -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)
} }

View file

@ -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))
} }
} }
} }
@ -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),
} }
} }
} }
@ -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)

View file

@ -184,7 +184,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 +192,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 +215,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 +252,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,
@ -280,7 +280,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
debug!("QueryNormalizer: result = {:#?}", result); debug!("QueryNormalizer: result = {:#?}", result);
debug!("QueryNormalizer: obligations = {:#?}", obligations); debug!("QueryNormalizer: obligations = {:#?}", obligations);
self.obligations.extend(obligations); self.obligations.extend(obligations);
result.normalized_ty Ok(result.normalized_ty)
} }
Err(_) => { Err(_) => {
@ -308,7 +308,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,
@ -335,14 +335,14 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
debug!("QueryNormalizer: result = {:#?}", result); debug!("QueryNormalizer: result = {:#?}", result);
debug!("QueryNormalizer: obligations = {:#?}", obligations); debug!("QueryNormalizer: obligations = {:#?}", obligations);
self.obligations.extend(obligations); self.obligations.extend(obligations);
crate::traits::project::PlaceholderReplacer::replace_placeholders( Ok(crate::traits::project::PlaceholderReplacer::replace_placeholders(
infcx, infcx,
mapped_regions, mapped_regions,
mapped_types, mapped_types,
mapped_consts, mapped_consts,
&self.universes, &self.universes,
result.normalized_ty, result.normalized_ty,
) ))
} }
Err(_) => { Err(_) => {
self.error = true; self.error = true;
@ -358,17 +358,23 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
} }
_ => 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)
} }
} }

View file

@ -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 == &param) { ty::Param(param) => match self.list.iter().position(|r| r == &param) {
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),

View file

@ -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),
} }
} }

View file

@ -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)
} }
} })
} }
} }

View file

@ -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),
} }

View file

@ -183,7 +183,7 @@ impl<'tcx> TypeFolder<'tcx> for EraseAllBoundRegions<'tcx> {
fn tcx<'a>(&'a self) -> TyCtxt<'tcx> { fn tcx<'a>(&'a self) -> TyCtxt<'tcx> {
self.tcx self.tcx
} }
fn fold_region(&mut self, r: Region<'tcx>) -> 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) }
} }
} }

View file

@ -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()))
} }
} }