diff options
Diffstat (limited to 'compiler/rustc_middle/src')
| -rw-r--r-- | compiler/rustc_middle/src/macros.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/mod.rs | 11 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/mir/type_foldable.rs | 160 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/erase_regions.rs | 21 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/fold.rs | 249 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/instance.rs | 12 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/mod.rs | 10 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/normalize_erasing_regions.rs | 34 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/print/pretty.rs | 16 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/structural_impls.rs | 238 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/subst.rs | 58 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/util.rs | 20 |
12 files changed, 527 insertions, 308 deletions
diff --git a/compiler/rustc_middle/src/macros.rs b/compiler/rustc_middle/src/macros.rs index c0cf265b228..a2f1218650b 100644 --- a/compiler/rustc_middle/src/macros.rs +++ b/compiler/rustc_middle/src/macros.rs @@ -52,7 +52,7 @@ macro_rules! TrivialTypeFoldableImpls { (for <$tcx:lifetime> { $($ty:ty,)+ }) => { $( impl<$tcx> $crate::ty::fold::TypeFoldable<$tcx> for $ty { - fn super_fold_with<F: $crate::ty::fold::TypeFolder<$tcx>>( + fn try_super_fold_with<F: $crate::ty::fold::TypeFolderFallible<$tcx>>( self, _: &mut F ) -> ::std::result::Result<$ty, F::Error> { @@ -95,7 +95,7 @@ macro_rules! EnumTypeFoldableImpl { impl<$($p),*> $crate::ty::fold::TypeFoldable<$tcx> for $s $(where $($wc)*)* { - fn super_fold_with<V: $crate::ty::fold::TypeFolder<$tcx>>( + fn try_super_fold_with<V: $crate::ty::fold::TypeFolderFallible<$tcx>>( self, folder: &mut V, ) -> ::std::result::Result<Self, V::Error> { @@ -126,7 +126,7 @@ macro_rules! EnumTypeFoldableImpl { output( $variant ( $($variant_arg),* ) => { $variant ( - $($crate::ty::fold::TypeFoldable::fold_with($variant_arg, $folder)?),* + $($crate::ty::fold::TypeFoldable::try_fold_with($variant_arg, $folder)?),* ) } $($output)* diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index a05b8a1da8d..ac129559c8e 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -7,7 +7,7 @@ use crate::mir::interpret::{Allocation, ConstValue, GlobalAlloc, Scalar}; use crate::mir::visit::MirVisitable; use crate::ty::adjustment::PointerCast; use crate::ty::codec::{TyDecoder, TyEncoder}; -use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; +use crate::ty::fold::{TypeFoldable, TypeFolderFallible, TypeVisitor}; use crate::ty::print::{FmtPrinter, Printer}; use crate::ty::subst::{Subst, SubstsRef}; use crate::ty::{self, List, Ty, TyCtxt}; @@ -2760,10 +2760,13 @@ impl UserTypeProjection { TrivialTypeFoldableAndLiftImpls! { ProjectionKind, } impl<'tcx> TypeFoldable<'tcx> for UserTypeProjection { - fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { + fn try_super_fold_with<F: TypeFolderFallible<'tcx>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { Ok(UserTypeProjection { - base: self.base.fold_with(folder)?, - projs: self.projs.fold_with(folder)?, + base: self.base.try_fold_with(folder)?, + projs: self.projs.try_fold_with(folder)?, }) } diff --git a/compiler/rustc_middle/src/mir/type_foldable.rs b/compiler/rustc_middle/src/mir/type_foldable.rs index df7c6d9cf66..4f38be54f2f 100644 --- a/compiler/rustc_middle/src/mir/type_foldable.rs +++ b/compiler/rustc_middle/src/mir/type_foldable.rs @@ -16,39 +16,42 @@ TrivialTypeFoldableAndLiftImpls! { } impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> { - fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { + fn try_super_fold_with<F: TypeFolderFallible<'tcx>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { use crate::mir::TerminatorKind::*; let kind = match self.kind { Goto { target } => Goto { target }, SwitchInt { discr, switch_ty, targets } => SwitchInt { - discr: discr.fold_with(folder)?, - switch_ty: switch_ty.fold_with(folder)?, + discr: discr.try_fold_with(folder)?, + switch_ty: switch_ty.try_fold_with(folder)?, targets, }, Drop { place, target, unwind } => { - Drop { place: place.fold_with(folder)?, target, unwind } + Drop { place: place.try_fold_with(folder)?, target, unwind } } DropAndReplace { place, value, target, unwind } => DropAndReplace { - place: place.fold_with(folder)?, - value: value.fold_with(folder)?, + place: place.try_fold_with(folder)?, + value: value.try_fold_with(folder)?, target, unwind, }, Yield { value, resume, resume_arg, drop } => Yield { - value: value.fold_with(folder)?, + value: value.try_fold_with(folder)?, resume, - resume_arg: resume_arg.fold_with(folder)?, + resume_arg: resume_arg.try_fold_with(folder)?, drop, }, Call { func, args, destination, cleanup, from_hir_call, fn_span } => { let dest = destination - .map(|(loc, dest)| (loc.fold_with(folder).map(|loc| (loc, dest)))) + .map(|(loc, dest)| (loc.try_fold_with(folder).map(|loc| (loc, dest)))) .transpose()?; Call { - func: func.fold_with(folder)?, - args: args.fold_with(folder)?, + func: func.try_fold_with(folder)?, + args: args.try_fold_with(folder)?, destination: dest, cleanup, from_hir_call, @@ -58,16 +61,19 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> { Assert { cond, expected, msg, target, cleanup } => { use AssertKind::*; let msg = match msg { - BoundsCheck { len, index } => { - BoundsCheck { len: len.fold_with(folder)?, index: index.fold_with(folder)? } + BoundsCheck { len, index } => BoundsCheck { + len: len.try_fold_with(folder)?, + index: index.try_fold_with(folder)?, + }, + Overflow(op, l, r) => { + Overflow(op, l.try_fold_with(folder)?, r.try_fold_with(folder)?) } - Overflow(op, l, r) => Overflow(op, l.fold_with(folder)?, r.fold_with(folder)?), - OverflowNeg(op) => OverflowNeg(op.fold_with(folder)?), - DivisionByZero(op) => DivisionByZero(op.fold_with(folder)?), - RemainderByZero(op) => RemainderByZero(op.fold_with(folder)?), + OverflowNeg(op) => OverflowNeg(op.try_fold_with(folder)?), + DivisionByZero(op) => DivisionByZero(op.try_fold_with(folder)?), + RemainderByZero(op) => RemainderByZero(op.try_fold_with(folder)?), ResumedAfterReturn(_) | ResumedAfterPanic(_) => msg, }; - Assert { cond: cond.fold_with(folder)?, expected, msg, target, cleanup } + Assert { cond: cond.try_fold_with(folder)?, expected, msg, target, cleanup } } GeneratorDrop => GeneratorDrop, Resume => Resume, @@ -80,7 +86,7 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> { FalseUnwind { real_target, unwind } => FalseUnwind { real_target, unwind }, InlineAsm { template, operands, options, line_spans, destination } => InlineAsm { template, - operands: operands.fold_with(folder)?, + operands: operands.try_fold_with(folder)?, options, line_spans, destination, @@ -142,7 +148,7 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> { } impl<'tcx> TypeFoldable<'tcx> for GeneratorKind { - fn super_fold_with<F: TypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> { + fn try_super_fold_with<F: TypeFolderFallible<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> { Ok(self) } @@ -152,10 +158,13 @@ impl<'tcx> TypeFoldable<'tcx> for GeneratorKind { } impl<'tcx> TypeFoldable<'tcx> for Place<'tcx> { - fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { + fn try_super_fold_with<F: TypeFolderFallible<'tcx>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { Ok(Place { - local: self.local.fold_with(folder)?, - projection: self.projection.fold_with(folder)?, + local: self.local.try_fold_with(folder)?, + projection: self.projection.try_fold_with(folder)?, }) } @@ -166,7 +175,10 @@ impl<'tcx> TypeFoldable<'tcx> for Place<'tcx> { } impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<PlaceElem<'tcx>> { - fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { + fn try_super_fold_with<F: TypeFolderFallible<'tcx>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { ty::util::fold_list(self, folder, |tcx, v| tcx.intern_place_elems(v)) } @@ -176,48 +188,56 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<PlaceElem<'tcx>> { } impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> { - fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { + fn try_super_fold_with<F: TypeFolderFallible<'tcx>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { use crate::mir::Rvalue::*; Ok(match self { - Use(op) => Use(op.fold_with(folder)?), - Repeat(op, len) => Repeat(op.fold_with(folder)?, len.fold_with(folder)?), - ThreadLocalRef(did) => ThreadLocalRef(did.fold_with(folder)?), - Ref(region, bk, place) => Ref(region.fold_with(folder)?, bk, place.fold_with(folder)?), - AddressOf(mutability, place) => AddressOf(mutability, place.fold_with(folder)?), - Len(place) => Len(place.fold_with(folder)?), - Cast(kind, op, ty) => Cast(kind, op.fold_with(folder)?, ty.fold_with(folder)?), - BinaryOp(op, box (rhs, lhs)) => { - BinaryOp(op, Box::new((rhs.fold_with(folder)?, lhs.fold_with(folder)?))) + Use(op) => Use(op.try_fold_with(folder)?), + Repeat(op, len) => Repeat(op.try_fold_with(folder)?, len.try_fold_with(folder)?), + ThreadLocalRef(did) => ThreadLocalRef(did.try_fold_with(folder)?), + Ref(region, bk, place) => { + Ref(region.try_fold_with(folder)?, bk, place.try_fold_with(folder)?) } - CheckedBinaryOp(op, box (rhs, lhs)) => { - CheckedBinaryOp(op, Box::new((rhs.fold_with(folder)?, lhs.fold_with(folder)?))) + AddressOf(mutability, place) => AddressOf(mutability, place.try_fold_with(folder)?), + Len(place) => Len(place.try_fold_with(folder)?), + Cast(kind, op, ty) => Cast(kind, op.try_fold_with(folder)?, ty.try_fold_with(folder)?), + BinaryOp(op, box (rhs, lhs)) => { + BinaryOp(op, Box::new((rhs.try_fold_with(folder)?, lhs.try_fold_with(folder)?))) } - UnaryOp(op, val) => UnaryOp(op, val.fold_with(folder)?), - Discriminant(place) => Discriminant(place.fold_with(folder)?), - NullaryOp(op, ty) => NullaryOp(op, ty.fold_with(folder)?), + CheckedBinaryOp(op, box (rhs, lhs)) => CheckedBinaryOp( + op, + Box::new((rhs.try_fold_with(folder)?, lhs.try_fold_with(folder)?)), + ), + UnaryOp(op, val) => UnaryOp(op, val.try_fold_with(folder)?), + Discriminant(place) => Discriminant(place.try_fold_with(folder)?), + NullaryOp(op, ty) => NullaryOp(op, ty.try_fold_with(folder)?), Aggregate(kind, fields) => { let kind = kind.try_map_id(|kind| { Ok(match kind { - AggregateKind::Array(ty) => AggregateKind::Array(ty.fold_with(folder)?), + AggregateKind::Array(ty) => AggregateKind::Array(ty.try_fold_with(folder)?), AggregateKind::Tuple => AggregateKind::Tuple, AggregateKind::Adt(def, v, substs, user_ty, n) => AggregateKind::Adt( def, v, - substs.fold_with(folder)?, - user_ty.fold_with(folder)?, + substs.try_fold_with(folder)?, + user_ty.try_fold_with(folder)?, n, ), AggregateKind::Closure(id, substs) => { - AggregateKind::Closure(id, substs.fold_with(folder)?) + AggregateKind::Closure(id, substs.try_fold_with(folder)?) } AggregateKind::Generator(id, substs, movablity) => { - AggregateKind::Generator(id, substs.fold_with(folder)?, movablity) + AggregateKind::Generator(id, substs.try_fold_with(folder)?, movablity) } }) })?; - Aggregate(kind, fields.fold_with(folder)?) + Aggregate(kind, fields.try_fold_with(folder)?) + } + ShallowInitBox(op, ty) => { + ShallowInitBox(op.try_fold_with(folder)?, ty.try_fold_with(folder)?) } - ShallowInitBox(op, ty) => ShallowInitBox(op.fold_with(folder)?, ty.fold_with(folder)?), }) } @@ -272,11 +292,14 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> { } impl<'tcx> TypeFoldable<'tcx> for Operand<'tcx> { - fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { + fn try_super_fold_with<F: TypeFolderFallible<'tcx>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { Ok(match self { - Operand::Copy(place) => Operand::Copy(place.fold_with(folder)?), - Operand::Move(place) => Operand::Move(place.fold_with(folder)?), - Operand::Constant(c) => Operand::Constant(c.fold_with(folder)?), + Operand::Copy(place) => Operand::Copy(place.try_fold_with(folder)?), + Operand::Move(place) => Operand::Move(place.try_fold_with(folder)?), + Operand::Constant(c) => Operand::Constant(c.try_fold_with(folder)?), }) } @@ -289,13 +312,16 @@ impl<'tcx> TypeFoldable<'tcx> for Operand<'tcx> { } impl<'tcx> TypeFoldable<'tcx> for PlaceElem<'tcx> { - fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { + fn try_super_fold_with<F: TypeFolderFallible<'tcx>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { use crate::mir::ProjectionElem::*; Ok(match self { Deref => Deref, - Field(f, ty) => Field(f, ty.fold_with(folder)?), - Index(v) => Index(v.fold_with(folder)?), + Field(f, ty) => Field(f, ty.try_fold_with(folder)?), + Index(v) => Index(v.try_fold_with(folder)?), Downcast(symbol, variantidx) => Downcast(symbol, variantidx), ConstantIndex { offset, min_length, from_end } => { ConstantIndex { offset, min_length, from_end } @@ -319,7 +345,7 @@ impl<'tcx> TypeFoldable<'tcx> for PlaceElem<'tcx> { } impl<'tcx> TypeFoldable<'tcx> for Field { - fn super_fold_with<F: TypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> { + fn try_super_fold_with<F: TypeFolderFallible<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> { Ok(self) } fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> { @@ -328,7 +354,7 @@ impl<'tcx> TypeFoldable<'tcx> for Field { } impl<'tcx> TypeFoldable<'tcx> for GeneratorSavedLocal { - fn super_fold_with<F: TypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> { + fn try_super_fold_with<F: TypeFolderFallible<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> { Ok(self) } fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> { @@ -337,7 +363,7 @@ impl<'tcx> TypeFoldable<'tcx> for GeneratorSavedLocal { } impl<'tcx, R: Idx, C: Idx> TypeFoldable<'tcx> for BitMatrix<R, C> { - fn super_fold_with<F: TypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> { + fn try_super_fold_with<F: TypeFolderFallible<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> { Ok(self) } fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> { @@ -346,11 +372,14 @@ impl<'tcx, R: Idx, C: Idx> TypeFoldable<'tcx> for BitMatrix<R, C> { } impl<'tcx> TypeFoldable<'tcx> for Constant<'tcx> { - fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { + fn try_super_fold_with<F: TypeFolderFallible<'tcx>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { Ok(Constant { span: self.span, - user_ty: self.user_ty.fold_with(folder)?, - literal: self.literal.fold_with(folder)?, + user_ty: self.user_ty.try_fold_with(folder)?, + literal: self.literal.try_fold_with(folder)?, }) } fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { @@ -361,14 +390,17 @@ impl<'tcx> TypeFoldable<'tcx> for Constant<'tcx> { impl<'tcx> TypeFoldable<'tcx> for ConstantKind<'tcx> { #[inline(always)] - fn fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { - folder.fold_mir_const(self) + fn try_fold_with<F: TypeFolderFallible<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { + folder.try_fold_mir_const(self) } - fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { + fn try_super_fold_with<F: TypeFolderFallible<'tcx>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { match self { - ConstantKind::Ty(c) => Ok(ConstantKind::Ty(c.fold_with(folder)?)), - ConstantKind::Val(v, t) => Ok(ConstantKind::Val(v, t.fold_with(folder)?)), + ConstantKind::Ty(c) => Ok(ConstantKind::Ty(c.try_fold_with(folder)?)), + ConstantKind::Val(v, t) => Ok(ConstantKind::Val(v, t.try_fold_with(folder)?)), } } diff --git a/compiler/rustc_middle/src/ty/erase_regions.rs b/compiler/rustc_middle/src/ty/erase_regions.rs index 25b460cf16d..63eb55ed1a6 100644 --- a/compiler/rustc_middle/src/ty/erase_regions.rs +++ b/compiler/rustc_middle/src/ty/erase_regions.rs @@ -9,7 +9,7 @@ pub(super) fn provide(providers: &mut ty::query::Providers) { fn erase_regions_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { // N.B., use `super_fold_with` here. If we used `fold_with`, it // could invoke the `erase_regions_ty` query recursively. - ty.super_fold_with(&mut RegionEraserVisitor { tcx }).into_ok() + ty.super_fold_with(&mut RegionEraserVisitor { tcx }) } impl<'tcx> TyCtxt<'tcx> { @@ -27,7 +27,7 @@ impl<'tcx> TyCtxt<'tcx> { return value; } debug!("erase_regions({:?})", value); - let value1 = value.fold_with(&mut RegionEraserVisitor { tcx: self }).into_ok(); + let value1 = value.fold_with(&mut RegionEraserVisitor { tcx: self }); debug!("erase_regions = {:?}", value1); value1 } @@ -42,11 +42,11 @@ impl TypeFolder<'tcx> for RegionEraserVisitor<'tcx> { self.tcx } - fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> { - if ty.needs_infer() { ty.super_fold_with(self) } else { Ok(self.tcx.erase_regions_ty(ty)) } + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { + if ty.needs_infer() { ty.super_fold_with(self) } else { self.tcx.erase_regions_ty(ty) } } - fn fold_binder<T>(&mut self, t: ty::Binder<'tcx, T>) -> Result<ty::Binder<'tcx, T>, Self::Error> + fn fold_binder<T>(&mut self, t: ty::Binder<'tcx, T>) -> ty::Binder<'tcx, T> where T: TypeFoldable<'tcx>, { @@ -54,7 +54,7 @@ impl TypeFolder<'tcx> for RegionEraserVisitor<'tcx> { u.super_fold_with(self) } - fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> { + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { // because late-bound regions affect subtyping, we can't // erase the bound/free distinction, but we can replace // all free regions with 'erased. @@ -64,15 +64,12 @@ impl TypeFolder<'tcx> for RegionEraserVisitor<'tcx> { // away. In codegen, they will always be erased to 'erased // whenever a substitution occurs. match *r { - ty::ReLateBound(..) => Ok(r), - _ => Ok(self.tcx.lifetimes.re_erased), + ty::ReLateBound(..) => r, + _ => self.tcx.lifetimes.re_erased, } } - fn fold_mir_const( - &mut self, - c: mir::ConstantKind<'tcx>, - ) -> Result<mir::ConstantKind<'tcx>, Self::Error> { + fn fold_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> { c.super_fold_with(self) } } diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index 31055c03a5d..4039577df88 100644 --- a/compiler/rustc_middle/src/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs @@ -46,9 +46,28 @@ use std::ops::ControlFlow; /// /// To implement this conveniently, use the derive macro located in `rustc_macros`. pub trait TypeFoldable<'tcx>: fmt::Debug + Clone { - fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error>; - fn fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { - self.super_fold_with(folder) + /// Consumers may find this more convenient to use with infallible folders than + /// [`try_super_fold_with`][`TypeFoldable::try_super_fold_with`], to which the + /// provided default definition delegates. Implementors **should not** override + /// this provided default definition, to ensure that the two methods are coherent + /// (provide a definition of `try_super_fold_with` instead). + fn super_fold_with<F: TypeFolder<'tcx, Error = !>>(self, folder: &mut F) -> Self { + self.try_super_fold_with(folder).into_ok() + } + /// Consumers may find this more convenient to use with infallible folders than + /// [`try_fold_with`][`TypeFoldable::try_fold_with`], to which the provided + /// default definition delegates. Implementors **should not** override this + /// provided default definition, to ensure that the two methods are coherent + /// (provide a definition of `try_fold_with` instead). + fn fold_with<F: TypeFolder<'tcx, Error = !>>(self, folder: &mut F) -> Self { + self.try_fold_with(folder).into_ok() + } + fn try_super_fold_with<F: TypeFolderFallible<'tcx>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error>; + fn try_fold_with<F: TypeFolderFallible<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { + self.try_super_fold_with(folder) } fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy>; @@ -179,7 +198,7 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone { } impl TypeFoldable<'tcx> for hir::Constness { - fn super_fold_with<F: TypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> { + fn try_super_fold_with<F: TypeFolder<'tcx>>(self, _: &mut F) -> Result<Self, F::Error> { Ok(self) } fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> ControlFlow<V::BreakTy> { @@ -192,41 +211,102 @@ impl TypeFoldable<'tcx> for hir::Constness { /// default implementation that does an "identity" fold. Within each /// identity fold, it should invoke `foo.fold_with(self)` to fold each /// sub-item. +/// +/// If this folder is fallible (and therefore its [`Error`][`TypeFolder::Error`] +/// associated type is something other than the default, never), +/// [`TypeFolderFallible`] should be implemented manually; otherwise, +/// a blanket implementation of [`TypeFolderFallible`] will defer to +/// the infallible methods of this trait to ensure that the two APIs +/// are coherent. pub trait TypeFolder<'tcx>: Sized { type Error = !; fn tcx<'a>(&'a self) -> TyCtxt<'tcx>; - fn fold_binder<T>(&mut self, t: Binder<'tcx, T>) -> Result<Binder<'tcx, T>, Self::Error> + fn fold_binder<T>(&mut self, t: Binder<'tcx, T>) -> Binder<'tcx, T> where T: TypeFoldable<'tcx>, + Self: TypeFolder<'tcx, Error = !>, { t.super_fold_with(self) } - fn fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> { + fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> + where + Self: TypeFolder<'tcx, Error = !>, + { t.super_fold_with(self) } - fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> { + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> + where + Self: TypeFolder<'tcx, Error = !>, + { r.super_fold_with(self) } - fn fold_const( + fn fold_const(&mut self, c: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> + where + Self: TypeFolder<'tcx, Error = !>, + { + c.super_fold_with(self) + } + + fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> + where + Self: TypeFolder<'tcx, Error = !>, + { + p.super_fold_with(self) + } + + fn fold_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> + where + Self: TypeFolder<'tcx, Error = !>, + { + bug!("most type folders should not be folding MIR datastructures: {:?}", c) + } +} + +/// The `TypeFolderFallible` trait defines the actual *folding*. There is a +/// method defined for every foldable type. Each of these has a +/// default implementation that does an "identity" fold. Within each +/// identity fold, it should invoke `foo.try_fold_with(self)` to fold each +/// sub-item. +/// +/// A blanket implementation of this trait (that defers to the relevant +/// method of [`TypeFolder`]) is provided for all infallible folders in +/// order to ensure the two APIs are coherent. +pub trait TypeFolderFallible<'tcx>: TypeFolder<'tcx> { + fn try_fold_binder<T>(&mut self, t: Binder<'tcx, T>) -> Result<Binder<'tcx, T>, Self::Error> + where + T: TypeFoldable<'tcx>, + { + t.try_super_fold_with(self) + } + + fn try_fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> { + t.try_super_fold_with(self) + } + + fn try_fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> { + r.try_super_fold_with(self) + } + + fn try_fold_const( &mut self, c: &'tcx ty::Const<'tcx>, ) -> Result<&'tcx ty::Const<'tcx>, Self::Error> { - c.super_fold_with(self) + c.try_super_fold_with(self) } - fn fold_predicate( + fn try_fold_predicate( &mut self, p: ty::Predicate<'tcx>, ) -> Result<ty::Predicate<'tcx>, Self::Error> { - p.super_fold_with(self) + p.try_super_fold_with(self) } - fn fold_mir_const( + fn try_fold_mir_const( &mut self, c: mir::ConstantKind<'tcx>, ) -> Result<mir::ConstantKind<'tcx>, Self::Error> { @@ -234,6 +314,49 @@ pub trait TypeFolder<'tcx>: Sized { } } +// Blanket implementation of fallible trait for infallible folders +// delegates to infallible methods to prevent incoherence +impl<'tcx, F> TypeFolderFallible<'tcx> for F +where + F: TypeFolder<'tcx, Error = !>, +{ + fn try_fold_binder<T>(&mut self, t: Binder<'tcx, T>) -> Result<Binder<'tcx, T>, Self::Error> + where + T: TypeFoldable<'tcx>, + { + Ok(self.fold_binder(t)) + } + + fn try_fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> { + Ok(self.fold_ty(t)) + } + + fn try_fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> { + Ok(self.fold_region(r)) + } + + fn try_fold_const( + &mut self, + c: &'tcx ty::Const<'tcx>, + ) -> Result<&'tcx ty::Const<'tcx>, Self::Error> { + Ok(self.fold_const(c)) + } + + fn try_fold_predicate( + &mut self, + p: ty::Predicate<'tcx>, + ) -> Result<ty::Predicate<'tcx>, Self::Error> { + Ok(self.fold_predicate(p)) + } + + fn try_fold_mir_const( + &mut self, + c: mir::ConstantKind<'tcx>, + ) -> Result<mir::ConstantKind<'tcx>, Self::Error> { + Ok(self.fold_mir_const(c)) + } +} + pub trait TypeVisitor<'tcx>: Sized { type BreakTy = !; /// Supplies the `tcx` for an unevaluated anonymous constant in case its default substs @@ -301,22 +424,19 @@ where self.tcx } - fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> { - let t = ty.super_fold_with(self)?; - Ok((self.ty_op)(t)) + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { + let t = ty.super_fold_with(self); + (self.ty_op)(t) } - fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> { - let r = r.super_fold_with(self)?; - Ok((self.lt_op)(r)) + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { + let r = r.super_fold_with(self); + (self.lt_op)(r) } - fn fold_const( - &mut self, - ct: &'tcx ty::Const<'tcx>, - ) -> Result<&'tcx ty::Const<'tcx>, Self::Error> { - let ct = ct.super_fold_with(self)?; - Ok((self.ct_op)(ct)) + fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> { + let ct = ct.super_fold_with(self); + (self.ct_op)(ct) } } @@ -336,7 +456,7 @@ impl<'tcx> TyCtxt<'tcx> { where T: TypeFoldable<'tcx>, { - value.fold_with(&mut RegionFolder::new(self, skipped_regions, &mut f)).into_ok() + value.fold_with(&mut RegionFolder::new(self, skipped_regions, &mut f)) } /// Invoke `callback` on every region appearing free in `value`. @@ -484,7 +604,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for RegionFolder<'a, 'tcx> { fn fold_binder<T: TypeFoldable<'tcx>>( &mut self, t: ty::Binder<'tcx, T>, - ) -> Result<ty::Binder<'tcx, T>, Self::Error> { + ) -> ty::Binder<'tcx, T> { self.current_index.shift_in(1); let t = t.super_fold_with(self); self.current_index.shift_out(1); @@ -492,16 +612,16 @@ impl<'a, 'tcx> TypeFolder<'tcx> for RegionFolder<'a, 'tcx> { } #[instrument(skip(self), level = "debug")] - fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> { + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { match *r { ty::ReLateBound(debruijn, _) if debruijn < self.current_index => { debug!(?self.current_index, "skipped bound region"); *self.skipped_regions = true; - Ok(r) + r } _ => { debug!(?self.current_index, "folding free region"); - Ok((self.fold_region_fn)(r, self.current_index)) + (self.fold_region_fn)(r, self.current_index) } } } @@ -542,19 +662,19 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> { fn fold_binder<T: TypeFoldable<'tcx>>( &mut self, t: ty::Binder<'tcx, T>, - ) -> Result<ty::Binder<'tcx, T>, Self::Error> { + ) -> ty::Binder<'tcx, T> { self.current_index.shift_in(1); let t = t.super_fold_with(self); self.current_index.shift_out(1); t } - fn fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> { + fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { match *t.kind() { ty::Bound(debruijn, bound_ty) if debruijn == self.current_index => { if let Some(fld_t) = self.fld_t.as_mut() { let ty = fld_t(bound_ty); - return Ok(ty::fold::shift_vars(self.tcx, &ty, self.current_index.as_u32())); + return ty::fold::shift_vars(self.tcx, &ty, self.current_index.as_u32()); } } _ if t.has_vars_bound_at_or_above(self.current_index) => { @@ -562,10 +682,10 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> { } _ => {} } - Ok(t) + t } - fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> { + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { match *r { ty::ReLateBound(debruijn, br) if debruijn == self.current_index => { if let Some(fld_r) = self.fld_r.as_mut() { @@ -576,28 +696,25 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> { // debruijn index. Then we adjust it to the // correct depth. assert_eq!(debruijn1, ty::INNERMOST); - Ok(self.tcx.mk_region(ty::ReLateBound(debruijn, br))) + self.tcx.mk_region(ty::ReLateBound(debruijn, br)) } else { - Ok(region) + region }; } } _ => {} } - Ok(r) + r } - fn fold_const( - &mut self, - ct: &'tcx ty::Const<'tcx>, - ) -> Result<&'tcx ty::Const<'tcx>, Self::Error> { + fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> { match *ct { ty::Const { val: ty::ConstKind::Bound(debruijn, bound_const), ty } if debruijn == self.current_index => { if let Some(fld_c) = self.fld_c.as_mut() { let ct = fld_c(bound_const, ty); - return Ok(ty::fold::shift_vars(self.tcx, &ct, self.current_index.as_u32())); + return ty::fold::shift_vars(self.tcx, &ct, self.current_index.as_u32()); } } _ if ct.has_vars_bound_at_or_above(self.current_index) => { @@ -605,7 +722,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for BoundVarReplacer<'a, 'tcx> { } _ => {} } - Ok(ct) + ct } } @@ -638,7 +755,7 @@ impl<'tcx> TyCtxt<'tcx> { value } else { let mut replacer = BoundVarReplacer::new(self, Some(&mut real_fld_r), None, None); - value.fold_with(&mut replacer).into_ok() + value.fold_with(&mut replacer) }; (value, region_map) } @@ -664,7 +781,7 @@ impl<'tcx> TyCtxt<'tcx> { } else { let mut replacer = BoundVarReplacer::new(self, Some(&mut fld_r), Some(&mut fld_t), Some(&mut fld_c)); - value.fold_with(&mut replacer).into_ok() + value.fold_with(&mut replacer) } } @@ -955,36 +1072,36 @@ impl TypeFolder<'tcx> for Shifter<'tcx> { fn fold_binder<T: TypeFoldable<'tcx>>( &mut self, t: ty::Binder<'tcx, T>, - ) -> Result<ty::Binder<'tcx, T>, Self::Error> { + ) -> ty::Binder<'tcx, T> { self.current_index.shift_in(1); let t = t.super_fold_with(self); self.current_index.shift_out(1); t } - fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> { + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { match *r { ty::ReLateBound(debruijn, br) => { if self.amount == 0 || debruijn < self.current_index { - Ok(r) + r } else { let debruijn = debruijn.shifted_in(self.amount); let shifted = ty::ReLateBound(debruijn, br); - Ok(self.tcx.mk_region(shifted)) + self.tcx.mk_region(shifted) } } - _ => Ok(r), + _ => r, } } - fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> { + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { match *ty.kind() { ty::Bound(debruijn, bound_ty) => { if self.amount == 0 || debruijn < self.current_index { - Ok(ty) + ty } else { let debruijn = debruijn.shifted_in(self.amount); - Ok(self.tcx.mk_ty(ty::Bound(debruijn, bound_ty))) + self.tcx.mk_ty(ty::Bound(debruijn, bound_ty)) } } @@ -992,18 +1109,13 @@ impl TypeFolder<'tcx> for Shifter<'tcx> { } } - fn fold_const( - &mut self, - ct: &'tcx ty::Const<'tcx>, - ) -> Result<&'tcx ty::Const<'tcx>, Self::Error> { + fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> { if let ty::Const { val: ty::ConstKind::Bound(debruijn, bound_ct), ty } = *ct { if self.amount == 0 || debruijn < self.current_index { - Ok(ct) + ct } else { let debruijn = debruijn.shifted_in(self.amount); - Ok(self - .tcx - .mk_const(ty::Const { val: ty::ConstKind::Bound(debruijn, bound_ct), ty })) + self.tcx.mk_const(ty::Const { val: ty::ConstKind::Bound(debruijn, bound_ct), ty }) } } else { ct.super_fold_with(self) @@ -1030,7 +1142,7 @@ where { debug!("shift_vars(value={:?}, amount={})", value, amount); - value.fold_with(&mut Shifter::new(tcx, amount)).into_ok() + value.fold_with(&mut Shifter::new(tcx, amount)) } #[derive(Debug, PartialEq, Eq, Copy, Clone)] @@ -1293,7 +1405,7 @@ impl<'tcx> TyCtxt<'tcx> { /// /// FIXME(@lcnr): explain this function a bit more pub fn expose_default_const_substs<T: TypeFoldable<'tcx>>(self, v: T) -> T { - v.fold_with(&mut ExposeDefaultConstSubstsFolder { tcx: self }).into_ok() + v.fold_with(&mut ExposeDefaultConstSubstsFolder { tcx: self }) } } @@ -1306,22 +1418,19 @@ impl<'tcx> TypeFolder<'tcx> for ExposeDefaultConstSubstsFolder<'tcx> { self.tcx } - fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> { + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { if ty.flags().intersects(TypeFlags::HAS_UNKNOWN_DEFAULT_CONST_SUBSTS) { ty.super_fold_with(self) } else { - Ok(ty) + ty } } - fn fold_predicate( - &mut self, - pred: ty::Predicate<'tcx>, - ) -> Result<ty::Predicate<'tcx>, Self::Error> { + fn fold_predicate(&mut self, pred: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> { if pred.inner.flags.intersects(TypeFlags::HAS_UNKNOWN_DEFAULT_CONST_SUBSTS) { pred.super_fold_with(self) } else { - Ok(pred) + pred } } } diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 15931b8d2c8..4b38105e447 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -622,7 +622,7 @@ fn polymorphize<'tcx>( self.tcx } - fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> { + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { debug!("fold_ty: ty={:?}", ty); match ty.kind { ty::Closure(def_id, substs) => { @@ -631,11 +631,11 @@ fn polymorphize<'tcx>( ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id)), substs, ); - Ok(if substs == polymorphized_substs { + if substs == polymorphized_substs { ty } else { self.tcx.mk_closure(def_id, polymorphized_substs) - }) + } } ty::Generator(def_id, substs, movability) => { let polymorphized_substs = polymorphize( @@ -643,11 +643,11 @@ fn polymorphize<'tcx>( ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id)), substs, ); - Ok(if substs == polymorphized_substs { + if substs == polymorphized_substs { ty } else { self.tcx.mk_generator(def_id, polymorphized_substs, movability) - }) + } } _ => ty.super_fold_with(self), } @@ -669,7 +669,7 @@ fn polymorphize<'tcx>( // ..and polymorphize any closures/generators captured as upvars. let upvars_ty = upvars_ty.unwrap(); let polymorphized_upvars_ty = upvars_ty.fold_with( - &mut PolymorphizationFolder { tcx }).into_ok(); + &mut PolymorphizationFolder { tcx }); debug!("polymorphize: polymorphized_upvars_ty={:?}", polymorphized_upvars_ty); ty::GenericArg::from(polymorphized_upvars_ty) }, diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index cd60519ac34..f18ea9dac31 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -9,7 +9,7 @@ //! //! ["The `ty` module: representing types"]: https://rustc-dev-guide.rust-lang.org/ty.html -pub use self::fold::{TypeFoldable, TypeFolder, TypeVisitor}; +pub use self::fold::{TypeFoldable, TypeFolder, TypeFolderFallible, TypeVisitor}; pub use self::AssocItemContainer::*; pub use self::BorrowKind::*; pub use self::IntVarValue::*; @@ -1269,14 +1269,14 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ParamEnv<'tcx> { } impl<'tcx> TypeFoldable<'tcx> for ParamEnv<'tcx> { - fn super_fold_with<F: ty::fold::TypeFolder<'tcx>>( + fn try_super_fold_with<F: ty::fold::TypeFolderFallible<'tcx>>( self, folder: &mut F, ) -> Result<Self, F::Error> { Ok(ParamEnv::new( - self.caller_bounds().fold_with(folder)?, - self.reveal().fold_with(folder)?, - self.constness().fold_with(folder)?, + self.caller_bounds().try_fold_with(folder)?, + self.reveal().try_fold_with(folder)?, + self.constness().try_fold_with(folder)?, )) } diff --git a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs index fce7cbfbb3d..c0e1360640f 100644 --- a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs +++ b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs @@ -9,7 +9,7 @@ use crate::mir; use crate::traits::query::NoSolution; -use crate::ty::fold::{TypeFoldable, TypeFolder}; +use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder}; use crate::ty::subst::{Subst, SubstsRef}; use crate::ty::{self, Ty, TyCtxt}; @@ -55,9 +55,7 @@ impl<'tcx> TyCtxt<'tcx> { if !value.has_projections() { value } else { - value - .fold_with(&mut NormalizeAfterErasingRegionsFolder { tcx: self, param_env }) - .into_ok() + value.fold_with(&mut NormalizeAfterErasingRegionsFolder { tcx: self, param_env }) } } @@ -90,7 +88,7 @@ impl<'tcx> TyCtxt<'tcx> { Ok(value) } else { let mut folder = TryNormalizeAfterErasingRegionsFolder::new(self, param_env); - value.fold_with(&mut folder) + value.try_fold_with(&mut folder) } } @@ -161,25 +159,19 @@ impl TypeFolder<'tcx> for NormalizeAfterErasingRegionsFolder<'tcx> { self.tcx } - fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> { - Ok(self.normalize_generic_arg_after_erasing_regions(ty.into()).expect_ty()) + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { + self.normalize_generic_arg_after_erasing_regions(ty.into()).expect_ty() } - fn fold_const( - &mut self, - c: &'tcx ty::Const<'tcx>, - ) -> Result<&'tcx ty::Const<'tcx>, Self::Error> { - Ok(self.normalize_generic_arg_after_erasing_regions(c.into()).expect_const()) + fn fold_const(&mut self, c: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> { + self.normalize_generic_arg_after_erasing_regions(c.into()).expect_const() } #[inline] - fn fold_mir_const( - &mut self, - c: mir::ConstantKind<'tcx>, - ) -> Result<mir::ConstantKind<'tcx>, Self::Error> { + fn fold_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> { // FIXME: This *probably* needs canonicalization too! let arg = self.param_env.and(c); - Ok(self.tcx.normalize_mir_const_after_erasing_regions(arg)) + self.tcx.normalize_mir_const_after_erasing_regions(arg) } } @@ -211,15 +203,17 @@ impl TypeFolder<'tcx> for TryNormalizeAfterErasingRegionsFolder<'tcx> { fn tcx(&self) -> TyCtxt<'tcx> { self.tcx } +} - fn fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> { +impl FallibleTypeFolder<'tcx> for TryNormalizeAfterErasingRegionsFolder<'tcx> { + fn try_fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> { match self.try_normalize_generic_arg_after_erasing_regions(ty.into()) { Ok(t) => Ok(t.expect_ty()), Err(_) => Err(NormalizationError::Type(ty)), } } - fn fold_const( + fn try_fold_const( &mut self, c: &'tcx ty::Const<'tcx>, ) -> Result<&'tcx ty::Const<'tcx>, Self::Error> { @@ -229,7 +223,7 @@ impl TypeFolder<'tcx> for TryNormalizeAfterErasingRegionsFolder<'tcx> { } } - fn fold_mir_const( + fn try_fold_mir_const( &mut self, c: mir::ConstantKind<'tcx>, ) -> Result<mir::ConstantKind<'tcx>, Self::Error> { diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index f454b95862b..175295b3199 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2016,24 +2016,24 @@ impl<'a, 'tcx> ty::TypeFolder<'tcx> for RegionFolder<'a, 'tcx> { fn fold_binder<T: TypeFoldable<'tcx>>( &mut self, t: ty::Binder<'tcx, T>, - ) -> Result<ty::Binder<'tcx, T>, Self::Error> { + ) -> ty::Binder<'tcx, T> { self.current_index.shift_in(1); let t = t.super_fold_with(self); self.current_index.shift_out(1); t } - fn fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> { + fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { match *t.kind() { _ if t.has_vars_bound_at_or_above(self.current_index) || t.has_placeholders() => { return t.super_fold_with(self); } _ => {} } - Ok(t) + t } - fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> { + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { let name = &mut self.name; let region = match *r { ty::ReLateBound(_, br) => self.region_map.entry(br).or_insert_with(|| name(br)), @@ -2049,13 +2049,13 @@ impl<'a, 'tcx> ty::TypeFolder<'tcx> for RegionFolder<'a, 'tcx> { } } } - _ => return Ok(r), + _ => return r, }; if let ty::ReLateBound(debruijn1, br) = *region { assert_eq!(debruijn1, ty::INNERMOST); - Ok(self.tcx.mk_region(ty::ReLateBound(self.current_index, br))) + self.tcx.mk_region(ty::ReLateBound(self.current_index, br)) } else { - Ok(region) + region } } } @@ -2193,7 +2193,7 @@ impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> { name: &mut name, region_map: BTreeMap::new(), }; - let new_value = value.clone().skip_binder().fold_with(&mut folder).into_ok(); + let new_value = value.clone().skip_binder().fold_with(&mut folder); let region_map = folder.region_map; start_or_continue(&mut self, "", "> "); (new_value, region_map) diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index f637412a117..0782a100e31 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -4,7 +4,7 @@ use crate::mir::interpret; use crate::mir::ProjectionKind; -use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; +use crate::ty::fold::{TypeFoldable, TypeFolderFallible, TypeVisitor}; use crate::ty::print::{with_no_trimmed_paths, FmtPrinter, Printer}; use crate::ty::{self, InferConst, Lift, Ty, TyCtxt}; use rustc_data_structures::functor::IdFunctor; @@ -669,7 +669,10 @@ impl<'a, 'tcx> Lift<'tcx> for ty::InstanceDef<'a> { /// AdtDefs are basically the same as a DefId. impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::AdtDef { - fn super_fold_with<F: TypeFolder<'tcx>>(self, _folder: &mut F) -> Result<Self, F::Error> { + fn try_super_fold_with<F: TypeFolderFallible<'tcx>>( + self, + _folder: &mut F, + ) -> Result<Self, F::Error> { Ok(self) } @@ -679,8 +682,11 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::AdtDef { } impl<'tcx, T: TypeFoldable<'tcx>, U: TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T, U) { - fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<(T, U), F::Error> { - Ok((self.0.fold_with(folder)?, self.1.fold_with(folder)?)) + fn try_super_fold_with<F: TypeFolderFallible<'tcx>>( + self, + folder: &mut F, + ) -> Result<(T, U), F::Error> { + Ok((self.0.try_fold_with(folder)?, self.1.try_fold_with(folder)?)) } fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { @@ -692,8 +698,15 @@ impl<'tcx, T: TypeFoldable<'tcx>, U: TypeFoldable<'tcx>> TypeFoldable<'tcx> for impl<'tcx, A: TypeFoldable<'tcx>, B: TypeFoldable<'tcx>, C: TypeFoldable<'tcx>> TypeFoldable<'tcx> for (A, B, C) { - fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<(A, B, C), F::Error> { - Ok((self.0.fold_with(folder)?, self.1.fold_with(folder)?, self.2.fold_with(folder)?)) + fn try_super_fold_with<F: TypeFolderFallible<'tcx>>( + self, + folder: &mut F, + ) -> Result<(A, B, C), F::Error> { + Ok(( + self.0.try_fold_with(folder)?, + self.1.try_fold_with(folder)?, + self.2.try_fold_with(folder)?, + )) } fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { @@ -718,9 +731,12 @@ EnumTypeFoldableImpl! { } impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Rc<T> { - fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { + fn try_super_fold_with<F: TypeFolderFallible<'tcx>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { // FIXME: Reuse the `Rc` here. - Ok(Rc::new((*self).clone().fold_with(folder)?)) + (*self).clone().try_fold_with(folder).map(Rc::new) } fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { @@ -729,9 +745,12 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Rc<T> { } impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Arc<T> { - fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { + fn try_super_fold_with<F: TypeFolderFallible<'tcx>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { // FIXME: Reuse the `Arc` here. - Ok(Arc::new((*self).clone().fold_with(folder)?)) + (*self).clone().try_fold_with(folder).map(Arc::new) } fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { @@ -740,8 +759,11 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Arc<T> { } impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<T> { - fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { - self.try_map_id(|value| value.fold_with(folder)) + fn try_super_fold_with<F: TypeFolderFallible<'tcx>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { + self.try_map_id(|value| value.try_fold_with(folder)) } fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { @@ -750,8 +772,11 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<T> { } impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Vec<T> { - fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { - self.try_map_id(|t| t.fold_with(folder)) + fn try_super_fold_with<F: TypeFolderFallible<'tcx>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { + self.try_map_id(|t| t.try_fold_with(folder)) } fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { @@ -760,8 +785,11 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Vec<T> { } impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<[T]> { - fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { - self.try_map_id(|t| t.fold_with(folder)) + fn try_super_fold_with<F: TypeFolderFallible<'tcx>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { + self.try_map_id(|t| t.try_fold_with(folder)) } fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { @@ -770,12 +798,15 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Box<[T]> { } impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder<'tcx, T> { - fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { - self.try_map_bound(|ty| ty.fold_with(folder)) + fn try_super_fold_with<F: TypeFolderFallible<'tcx>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { + self.try_map_bound(|ty| ty.try_fold_with(folder)) } - fn fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { - folder.fold_binder(self) + fn try_fold_with<F: TypeFolderFallible<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { + folder.try_fold_binder(self) } fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { @@ -788,7 +819,10 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder<'tcx, T> { } impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>> { - fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { + fn try_super_fold_with<F: TypeFolderFallible<'tcx>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { ty::util::fold_list(self, folder, |tcx, v| tcx.intern_poly_existential_predicates(v)) } @@ -798,7 +832,10 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Binder<'tcx, ty::Existentia } impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<Ty<'tcx>> { - fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { + fn try_super_fold_with<F: TypeFolderFallible<'tcx>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { ty::util::fold_list(self, folder, |tcx, v| tcx.intern_type_list(v)) } @@ -808,7 +845,10 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<Ty<'tcx>> { } impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ProjectionKind> { - fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { + fn try_super_fold_with<F: TypeFolderFallible<'tcx>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { ty::util::fold_list(self, folder, |tcx, v| tcx.intern_projs(v)) } @@ -818,22 +858,31 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ProjectionKind> { } impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> { - fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { + fn try_super_fold_with<F: TypeFolderFallible<'tcx>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { use crate::ty::InstanceDef::*; Ok(Self { - substs: self.substs.fold_with(folder)?, + substs: self.substs.try_fold_with(folder)?, def: match self.def { - Item(def) => Item(def.fold_with(folder)?), - VtableShim(did) => VtableShim(did.fold_with(folder)?), - ReifyShim(did) => ReifyShim(did.fold_with(folder)?), - Intrinsic(did) => Intrinsic(did.fold_with(folder)?), - FnPtrShim(did, ty) => FnPtrShim(did.fold_with(folder)?, ty.fold_with(folder)?), - Virtual(did, i) => Virtual(did.fold_with(folder)?, i), + Item(def) => Item(def.try_fold_with(folder)?), + VtableShim(did) => VtableShim(did.try_fold_with(folder)?), + ReifyShim(did) => ReifyShim(did.try_fold_with(folder)?), + Intrinsic(did) => Intrinsic(did.try_fold_with(folder)?), + FnPtrShim(did, ty) => { + FnPtrShim(did.try_fold_with(folder)?, ty.try_fold_with(folder)?) + } + Virtual(did, i) => Virtual(did.try_fold_with(folder)?, i), ClosureOnceShim { call_once, track_caller } => { - ClosureOnceShim { call_once: call_once.fold_with(folder)?, track_caller } + ClosureOnceShim { call_once: call_once.try_fold_with(folder)?, track_caller } + } + DropGlue(did, ty) => { + DropGlue(did.try_fold_with(folder)?, ty.try_fold_with(folder)?) + } + CloneShim(did, ty) => { + CloneShim(did.try_fold_with(folder)?, ty.try_fold_with(folder)?) } - DropGlue(did, ty) => DropGlue(did.fold_with(folder)?, ty.fold_with(folder)?), - CloneShim(did, ty) => CloneShim(did.fold_with(folder)?, ty.fold_with(folder)?), }, }) } @@ -860,8 +909,11 @@ impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> { } impl<'tcx> TypeFoldable<'tcx> for interpret::GlobalId<'tcx> { - fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { - Ok(Self { instance: self.instance.fold_with(folder)?, promoted: self.promoted }) + fn try_super_fold_with<F: TypeFolderFallible<'tcx>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { + Ok(Self { instance: self.instance.try_fold_with(folder)?, promoted: self.promoted }) } fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { @@ -870,26 +922,31 @@ impl<'tcx> TypeFoldable<'tcx> for interpret::GlobalId<'tcx> { } impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { - fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { + fn try_super_fold_with<F: TypeFolderFallible<'tcx>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { let kind = match *self.kind() { - ty::RawPtr(tm) => ty::RawPtr(tm.fold_with(folder)?), - ty::Array(typ, sz) => ty::Array(typ.fold_with(folder)?, sz.fold_with(folder)?), - ty::Slice(typ) => ty::Slice(typ.fold_with(folder)?), - ty::Adt(tid, substs) => ty::Adt(tid, substs.fold_with(folder)?), + ty::RawPtr(tm) => ty::RawPtr(tm.try_fold_with(folder)?), + ty::Array(typ, sz) => ty::Array(typ.try_fold_with(folder)?, sz.try_fold_with(folder)?), + ty::Slice(typ) => ty::Slice(typ.try_fold_with(folder)?), + ty::Adt(tid, substs) => ty::Adt(tid, substs.try_fold_with(folder)?), ty::Dynamic(trait_ty, region) => { - ty::Dynamic(trait_ty.fold_with(folder)?, region.fold_with(folder)?) + ty::Dynamic(trait_ty.try_fold_with(folder)?, region.try_fold_with(folder)?) + } + ty::Tuple(ts) => ty::Tuple(ts.try_fold_with(folder)?), + ty::FnDef(def_id, substs) => ty::FnDef(def_id, substs.try_fold_with(folder)?), + ty::FnPtr(f) => ty::FnPtr(f.try_fold_with(folder)?), + ty::Ref(r, ty, mutbl) => { + ty::Ref(r.try_fold_with(folder)?, ty.try_fold_with(folder)?, mutbl) } - ty::Tuple(ts) => ty::Tuple(ts.fold_with(folder)?), - ty::FnDef(def_id, substs) => ty::FnDef(def_id, substs.fold_with(folder)?), - ty::FnPtr(f) => ty::FnPtr(f.fold_with(folder)?), - ty::Ref(r, ty, mutbl) => ty::Ref(r.fold_with(folder)?, ty.fold_with(folder)?, mutbl), ty::Generator(did, substs, movability) => { - ty::Generator(did, substs.fold_with(folder)?, movability) + ty::Generator(did, substs.try_fold_with(folder)?, movability) } - ty::GeneratorWitness(types) => ty::GeneratorWitness(types.fold_with(folder)?), - ty::Closure(did, substs) => ty::Closure(did, substs.fold_with(folder)?), - ty::Projection(data) => ty::Projection(data.fold_with(folder)?), - ty::Opaque(did, substs) => ty::Opaque(did, substs.fold_with(folder)?), + ty::GeneratorWitness(types) => ty::GeneratorWitness(types.try_fold_with(folder)?), + ty::Closure(did, substs) => ty::Closure(did, substs.try_fold_with(folder)?), + ty::Projection(data) => ty::Projection(data.try_fold_with(folder)?), + ty::Opaque(did, substs) => ty::Opaque(did, substs.try_fold_with(folder)?), ty::Bool | ty::Char @@ -909,8 +966,8 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { Ok(if *self.kind() == kind { self } else { folder.tcx().mk_ty(kind) }) } - fn fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { - folder.fold_ty(self) + fn try_fold_with<F: TypeFolderFallible<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { + folder.try_fold_ty(self) } fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { @@ -961,12 +1018,15 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> { } impl<'tcx> TypeFoldable<'tcx> for ty::Region<'tcx> { - fn super_fold_with<F: TypeFolder<'tcx>>(self, _folder: &mut F) -> Result<Self, F::Error> { + fn try_super_fold_with<F: TypeFolderFallible<'tcx>>( + self, + _folder: &mut F, + ) -> Result<Self, F::Error> { Ok(self) } - fn fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { - folder.fold_region(self) + fn try_fold_with<F: TypeFolderFallible<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { + folder.try_fold_region(self) } fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> ControlFlow<V::BreakTy> { @@ -979,12 +1039,15 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Region<'tcx> { } impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> { - fn fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { - folder.fold_predicate(self) + fn try_fold_with<F: TypeFolderFallible<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { + folder.try_fold_predicate(self) } - fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { - let new = self.inner.kind.fold_with(folder)?; + fn try_super_fold_with<F: TypeFolderFallible<'tcx>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { + let new = self.inner.kind.try_fold_with(folder)?; Ok(folder.tcx().reuse_or_mk_predicate(self, new)) } @@ -1006,7 +1069,10 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> { } impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Predicate<'tcx>> { - fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { + fn try_super_fold_with<F: TypeFolderFallible<'tcx>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { ty::util::fold_list(self, folder, |tcx, v| tcx.intern_predicates(v)) } @@ -1016,8 +1082,11 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Predicate<'tcx>> { } impl<'tcx, T: TypeFoldable<'tcx>, I: Idx> TypeFoldable<'tcx> for IndexVec<I, T> { - fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { - self.try_map_id(|x| x.fold_with(folder)) + fn try_super_fold_with<F: TypeFolderFallible<'tcx>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { + self.try_map_id(|x| x.try_fold_with(folder)) } fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { @@ -1026,9 +1095,12 @@ impl<'tcx, T: TypeFoldable<'tcx>, I: Idx> TypeFoldable<'tcx> for IndexVec<I, T> } impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Const<'tcx> { - fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { - let ty = self.ty.fold_with(folder)?; - let val = self.val.fold_with(folder)?; + fn try_super_fold_with<F: TypeFolderFallible<'tcx>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { + let ty = self.ty.try_fold_with(folder)?; + let val = self.val.try_fold_with(folder)?; if ty != self.ty || val != self.val { Ok(folder.tcx().mk_const(ty::Const { ty, val })) } else { @@ -1036,8 +1108,8 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Const<'tcx> { } } - fn fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { - folder.fold_const(self) + fn try_fold_with<F: TypeFolderFallible<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { + folder.try_fold_const(self) } fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { @@ -1051,11 +1123,14 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Const<'tcx> { } impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> { - fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { + fn try_super_fold_with<F: TypeFolderFallible<'tcx>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { Ok(match self { - ty::ConstKind::Infer(ic) => ty::ConstKind::Infer(ic.fold_with(folder)?), - ty::ConstKind::Param(p) => ty::ConstKind::Param(p.fold_with(folder)?), - ty::ConstKind::Unevaluated(uv) => ty::ConstKind::Unevaluated(uv.fold_with(folder)?), + ty::ConstKind::Infer(ic) => ty::ConstKind::Infer(ic.try_fold_with(folder)?), + ty::ConstKind::Param(p) => ty::ConstKind::Param(p.try_fold_with(folder)?), + ty::ConstKind::Unevaluated(uv) => ty::ConstKind::Unevaluated(uv.try_fold_with(folder)?), ty::ConstKind::Value(_) | ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(..) @@ -1077,7 +1152,10 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> { } impl<'tcx> TypeFoldable<'tcx> for InferConst<'tcx> { - fn super_fold_with<F: TypeFolder<'tcx>>(self, _folder: &mut F) -> Result<Self, F::Error> { + fn try_super_fold_with<F: TypeFolderFallible<'tcx>>( + self, + _folder: &mut F, + ) -> Result<Self, F::Error> { Ok(self) } @@ -1087,10 +1165,13 @@ impl<'tcx> TypeFoldable<'tcx> for InferConst<'tcx> { } impl<'tcx> TypeFoldable<'tcx> for ty::Unevaluated<'tcx> { - fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { + fn try_super_fold_with<F: TypeFolderFallible<'tcx>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { Ok(ty::Unevaluated { def: self.def, - substs_: Some(self.substs(folder.tcx()).fold_with(folder)?), + substs_: Some(self.substs(folder.tcx()).try_fold_with(folder)?), promoted: self.promoted, }) } @@ -1112,10 +1193,13 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Unevaluated<'tcx> { } impl<'tcx> TypeFoldable<'tcx> for ty::Unevaluated<'tcx, ()> { - fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { + fn try_super_fold_with<F: TypeFolderFallible<'tcx>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { Ok(ty::Unevaluated { def: self.def, - substs_: Some(self.substs(folder.tcx()).fold_with(folder)?), + substs_: Some(self.substs(folder.tcx()).try_fold_with(folder)?), promoted: self.promoted, }) } diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index ffa495ce480..a0f0e06435d 100644 --- a/compiler/rustc_middle/src/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs @@ -2,7 +2,7 @@ use crate::mir; use crate::ty::codec::{TyDecoder, TyEncoder}; -use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; +use crate::ty::fold::{TypeFoldable, TypeFolder, TypeFolderFallible, TypeVisitor}; use crate::ty::sty::{ClosureSubsts, GeneratorSubsts, InlineConstSubsts}; use crate::ty::{self, Lift, List, ParamConst, Ty, TyCtxt}; @@ -153,11 +153,14 @@ impl<'a, 'tcx> Lift<'tcx> for GenericArg<'a> { } impl<'tcx> TypeFoldable<'tcx> for GenericArg<'tcx> { - fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { + fn try_super_fold_with<F: TypeFolderFallible<'tcx>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { match self.unpack() { - GenericArgKind::Lifetime(lt) => lt.fold_with(folder).map(Into::into), - GenericArgKind::Type(ty) => ty.fold_with(folder).map(Into::into), - GenericArgKind::Const(ct) => ct.fold_with(folder).map(Into::into), + GenericArgKind::Lifetime(lt) => lt.try_fold_with(folder).map(Into::into), + GenericArgKind::Type(ty) => ty.try_fold_with(folder).map(Into::into), + GenericArgKind::Const(ct) => ct.try_fold_with(folder).map(Into::into), } } @@ -372,7 +375,10 @@ impl<'a, 'tcx> InternalSubsts<'tcx> { } impl<'tcx> TypeFoldable<'tcx> for SubstsRef<'tcx> { - fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { + fn try_super_fold_with<F: TypeFolderFallible<'tcx>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { // This code is hot enough that it's worth specializing for the most // common length lists, to avoid the overhead of `SmallVec` creation. // The match arms are in order of frequency. The 1, 2, and 0 cases are @@ -381,12 +387,12 @@ impl<'tcx> TypeFoldable<'tcx> for SubstsRef<'tcx> { // calling `intern_substs`. match self.len() { 1 => { - let param0 = self[0].fold_with(folder)?; + let param0 = self[0].try_fold_with(folder)?; if param0 == self[0] { Ok(self) } else { Ok(folder.tcx().intern_substs(&[param0])) } } 2 => { - let param0 = self[0].fold_with(folder)?; - let param1 = self[1].fold_with(folder)?; + let param0 = self[0].try_fold_with(folder)?; + let param1 = self[1].try_fold_with(folder)?; if param0 == self[0] && param1 == self[1] { Ok(self) } else { @@ -396,7 +402,7 @@ impl<'tcx> TypeFoldable<'tcx> for SubstsRef<'tcx> { 0 => Ok(self), _ => { let params: SmallVec<[_; 8]> = - self.iter().map(|k| k.fold_with(folder)).collect::<Result<_, _>>()?; + self.iter().map(|k| k.try_fold_with(folder)).collect::<Result<_, _>>()?; if params[..] == self[..] { Ok(self) } else { @@ -439,7 +445,7 @@ impl<'tcx, T: TypeFoldable<'tcx>> Subst<'tcx> for T { span: Option<Span>, ) -> T { let mut folder = SubstFolder { tcx, substs, span, binders_passed: 0 }; - self.fold_with(&mut folder).into_ok() + self.fold_with(&mut folder) } } @@ -465,14 +471,14 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> { fn fold_binder<T: TypeFoldable<'tcx>>( &mut self, t: ty::Binder<'tcx, T>, - ) -> Result<ty::Binder<'tcx, T>, Self::Error> { + ) -> ty::Binder<'tcx, T> { self.binders_passed += 1; - let t = t.super_fold_with(self)?; + let t = t.super_fold_with(self); self.binders_passed -= 1; - Ok(t) + t } - fn fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> { + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { // Note: This routine only handles regions that are bound on // type declarations and other outer declarations, not those // bound in *fn types*. Region substitution of the bound @@ -482,7 +488,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> { ty::ReEarlyBound(data) => { let rk = self.substs.get(data.index as usize).map(|k| k.unpack()); match rk { - Some(GenericArgKind::Lifetime(lt)) => Ok(self.shift_region_through_binders(lt)), + Some(GenericArgKind::Lifetime(lt)) => self.shift_region_through_binders(lt), _ => { let span = self.span.unwrap_or(DUMMY_SP); let msg = format!( @@ -494,37 +500,31 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> { } } } - _ => Ok(r), + _ => r, } } - fn fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> { + fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { if !t.potentially_needs_subst() { - return Ok(t); + return t; } match *t.kind() { - ty::Param(p) => Ok(self.ty_for_param(p, t)), + ty::Param(p) => self.ty_for_param(p, t), _ => t.super_fold_with(self), } } - fn fold_const( - &mut self, - c: &'tcx ty::Const<'tcx>, - ) -> Result<&'tcx ty::Const<'tcx>, Self::Error> { + fn fold_const(&mut self, c: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> { if let ty::ConstKind::Param(p) = c.val { - Ok(self.const_for_param(p, c)) + self.const_for_param(p, c) } else { c.super_fold_with(self) } } #[inline] - fn fold_mir_const( - &mut self, - c: mir::ConstantKind<'tcx>, - ) -> Result<mir::ConstantKind<'tcx>, Self::Error> { + fn fold_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> { c.super_fold_with(self) } } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 5137f965063..8537ef7ccb5 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -1,7 +1,7 @@ //! Miscellaneous type-system utilities that are too small to deserve their own modules. use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; -use crate::ty::fold::TypeFolder; +use crate::ty::fold::{TypeFolder, TypeFolderFallible}; use crate::ty::layout::IntegerExt; use crate::ty::query::TyCtxtAt; use crate::ty::subst::{GenericArgKind, Subst, SubstsRef}; @@ -574,14 +574,14 @@ impl<'tcx> OpaqueTypeExpander<'tcx> { if self.found_any_recursion { return None; } - let substs = substs.fold_with(self).into_ok(); + let substs = substs.fold_with(self); if !self.check_recursion || self.seen_opaque_tys.insert(def_id) { let expanded_ty = match self.expanded_cache.get(&(def_id, substs)) { Some(expanded_ty) => expanded_ty, None => { let generic_ty = self.tcx.type_of(def_id); let concrete_ty = generic_ty.subst(self.tcx, substs); - let expanded_ty = self.fold_ty(concrete_ty).into_ok(); + let expanded_ty = self.fold_ty(concrete_ty); self.expanded_cache.insert((def_id, substs), expanded_ty); expanded_ty } @@ -605,13 +605,13 @@ impl<'tcx> TypeFolder<'tcx> for OpaqueTypeExpander<'tcx> { self.tcx } - fn fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> { + fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { if let ty::Opaque(def_id, substs) = t.kind { - Ok(self.expand_opaque_ty(def_id, substs).unwrap_or(t)) + self.expand_opaque_ty(def_id, substs).unwrap_or(t) } else if t.has_opaque_types() { t.super_fold_with(self) } else { - Ok(t) + t } } } @@ -1048,12 +1048,12 @@ pub fn fold_list<'tcx, F, T>( intern: impl FnOnce(TyCtxt<'tcx>, &[T]) -> &'tcx ty::List<T>, ) -> Result<&'tcx ty::List<T>, F::Error> where - F: TypeFolder<'tcx>, + F: TypeFolderFallible<'tcx>, T: TypeFoldable<'tcx> + PartialEq + Copy, { let mut iter = list.iter(); // Look for the first element that changed - match iter.by_ref().enumerate().find_map(|(i, t)| match t.fold_with(folder) { + match iter.by_ref().enumerate().find_map(|(i, t)| match t.try_fold_with(folder) { Ok(new_t) if new_t == t => None, new_t => Some((i, new_t)), }) { @@ -1063,7 +1063,7 @@ where new_list.extend_from_slice(&list[..i]); new_list.push(new_t); for t in iter { - new_list.push(t.fold_with(folder)?) + new_list.push(t.try_fold_with(folder)?) } Ok(intern(folder.tcx(), &new_list)) } @@ -1092,7 +1092,7 @@ pub fn normalize_opaque_types( check_recursion: false, tcx, }; - val.fold_with(&mut visitor).into_ok() + val.fold_with(&mut visitor) } pub fn provide(providers: &mut ty::query::Providers) { |
