X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=compiler%2Frustc_middle%2Fsrc%2Fmir%2Ftype_foldable.rs;h=ad8b9d323eed584be331cc999292a64f044d9208;hb=2a9e0831d6603d87220cedd1b1293e2eb82ef55c;hp=b7201f7acf392dac6567e4d4ba7d6e69298b467c;hpb=ffdf18d1447b57faafded06a887b6dae1f7293c7;p=rust.git diff --git a/compiler/rustc_middle/src/mir/type_foldable.rs b/compiler/rustc_middle/src/mir/type_foldable.rs index b7201f7acf3..ad8b9d323ee 100644 --- a/compiler/rustc_middle/src/mir/type_foldable.rs +++ b/compiler/rustc_middle/src/mir/type_foldable.rs @@ -16,37 +16,42 @@ } impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> { - fn super_fold_with>(self, folder: &mut F) -> Self { + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result { 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), dest)); + let dest = destination + .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, @@ -56,16 +61,19 @@ fn super_fold_with>(self, folder: &mut F) -> Self { 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, @@ -78,13 +86,13 @@ fn super_fold_with>(self, folder: &mut F) -> Self { 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, }, }; - Terminator { source_info: self.source_info, kind } + Ok(Terminator { source_info: self.source_info, kind }) } fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow { @@ -140,8 +148,8 @@ fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow } impl<'tcx> TypeFoldable<'tcx> for GeneratorKind { - fn super_fold_with>(self, _: &mut F) -> Self { - self + fn try_super_fold_with>(self, _: &mut F) -> Result { + Ok(self) } fn super_visit_with>(&self, _: &mut V) -> ControlFlow { @@ -150,8 +158,14 @@ fn super_visit_with>(&self, _: &mut V) -> ControlFlow TypeFoldable<'tcx> for Place<'tcx> { - fn super_fold_with>(self, folder: &mut F) -> Self { - Place { local: self.local.fold_with(folder), projection: self.projection.fold_with(folder) } + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result { + Ok(Place { + local: self.local.try_fold_with(folder)?, + projection: self.projection.try_fold_with(folder)?, + }) } fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow { @@ -161,7 +175,10 @@ fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow } impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List> { - fn super_fold_with>(self, folder: &mut F) -> Self { + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result { ty::util::fold_list(self, folder, |tcx, v| tcx.intern_place_elems(v)) } @@ -171,47 +188,57 @@ fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow } impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> { - fn super_fold_with>(self, folder: &mut F) -> Self { + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result { use crate::mir::Rvalue::*; - match self { - Use(op) => Use(op.fold_with(folder)), - Repeat(op, len) => Repeat(op.fold_with(folder), len.fold_with(folder)), - ThreadLocalRef(did) => ThreadLocalRef(did.fold_with(folder)), - Ref(region, bk, place) => Ref(region.fold_with(folder), bk, place.fold_with(folder)), - AddressOf(mutability, place) => AddressOf(mutability, place.fold_with(folder)), - Len(place) => Len(place.fold_with(folder)), - Cast(kind, op, ty) => Cast(kind, op.fold_with(folder), ty.fold_with(folder)), - BinaryOp(op, box (rhs, lhs)) => { - BinaryOp(op, Box::new((rhs.fold_with(folder), lhs.fold_with(folder)))) + Ok(match self { + 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.map_id(|kind| match kind { - AggregateKind::Array(ty) => AggregateKind::Array(ty.fold_with(folder)), - AggregateKind::Tuple => AggregateKind::Tuple, - AggregateKind::Adt(def, v, substs, user_ty, n) => AggregateKind::Adt( - def, - v, - substs.fold_with(folder), - user_ty.fold_with(folder), - n, - ), - AggregateKind::Closure(id, substs) => { - AggregateKind::Closure(id, substs.fold_with(folder)) - } - AggregateKind::Generator(id, substs, movablity) => { - AggregateKind::Generator(id, substs.fold_with(folder), movablity) - } - }); - Aggregate(kind, fields.fold_with(folder)) + let kind = kind.try_map_id(|kind| { + Ok(match kind { + 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.try_fold_with(folder)?, + user_ty.try_fold_with(folder)?, + n, + ), + AggregateKind::Closure(id, substs) => { + AggregateKind::Closure(id, substs.try_fold_with(folder)?) + } + AggregateKind::Generator(id, substs, movablity) => { + AggregateKind::Generator(id, substs.try_fold_with(folder)?, movablity) + } + }) + })?; + Aggregate(kind, fields.try_fold_with(folder)?) } - ShallowInitBox(op, ty) => ShallowInitBox(op.fold_with(folder), ty.fold_with(folder)), - } + ShallowInitBox(op, ty) => { + ShallowInitBox(op.try_fold_with(folder)?, ty.try_fold_with(folder)?) + } + }) } fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow { @@ -265,12 +292,15 @@ fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow } impl<'tcx> TypeFoldable<'tcx> for Operand<'tcx> { - fn super_fold_with>(self, folder: &mut F) -> Self { - match self { - Operand::Copy(place) => Operand::Copy(place.fold_with(folder)), - Operand::Move(place) => Operand::Move(place.fold_with(folder)), - Operand::Constant(c) => Operand::Constant(c.fold_with(folder)), - } + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result { + Ok(match self { + 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)?), + }) } fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow { @@ -282,19 +312,22 @@ fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow } impl<'tcx> TypeFoldable<'tcx> for PlaceElem<'tcx> { - fn super_fold_with>(self, folder: &mut F) -> Self { + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result { use crate::mir::ProjectionElem::*; - match self { + Ok(match self { Deref => Deref, - Field(f, ty) => Field(f, ty.fold_with(folder)), - Index(v) => Index(v.fold_with(folder)), + Field(f, ty) => Field(f, ty.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 } } Subslice { from, to, from_end } => Subslice { from, to, from_end }, - } + }) } fn super_visit_with>( @@ -312,8 +345,8 @@ fn super_visit_with>( } impl<'tcx> TypeFoldable<'tcx> for Field { - fn super_fold_with>(self, _: &mut F) -> Self { - self + fn try_super_fold_with>(self, _: &mut F) -> Result { + Ok(self) } fn super_visit_with>(&self, _: &mut V) -> ControlFlow { ControlFlow::CONTINUE @@ -321,8 +354,8 @@ fn super_visit_with>(&self, _: &mut V) -> ControlFlow TypeFoldable<'tcx> for GeneratorSavedLocal { - fn super_fold_with>(self, _: &mut F) -> Self { - self + fn try_super_fold_with>(self, _: &mut F) -> Result { + Ok(self) } fn super_visit_with>(&self, _: &mut V) -> ControlFlow { ControlFlow::CONTINUE @@ -330,8 +363,8 @@ fn super_visit_with>(&self, _: &mut V) -> ControlFlow TypeFoldable<'tcx> for BitMatrix { - fn super_fold_with>(self, _: &mut F) -> Self { - self + fn try_super_fold_with>(self, _: &mut F) -> Result { + Ok(self) } fn super_visit_with>(&self, _: &mut V) -> ControlFlow { ControlFlow::CONTINUE @@ -339,12 +372,15 @@ fn super_visit_with>(&self, _: &mut V) -> ControlFlow TypeFoldable<'tcx> for Constant<'tcx> { - fn super_fold_with>(self, folder: &mut F) -> Self { - Constant { + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result { + 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>(&self, visitor: &mut V) -> ControlFlow { self.literal.visit_with(visitor)?; @@ -354,14 +390,17 @@ fn super_visit_with>(&self, visitor: &mut V) -> ControlFlow impl<'tcx> TypeFoldable<'tcx> for ConstantKind<'tcx> { #[inline(always)] - fn fold_with>(self, folder: &mut F) -> Self { - folder.fold_mir_const(self) + fn try_fold_with>(self, folder: &mut F) -> Result { + folder.try_fold_mir_const(self) } - fn super_fold_with>(self, folder: &mut F) -> Self { + fn try_super_fold_with>( + self, + folder: &mut F, + ) -> Result { match self { - ConstantKind::Ty(c) => ConstantKind::Ty(c.fold_with(folder)), - ConstantKind::Val(v, t) => ConstantKind::Val(v, t.fold_with(folder)), + ConstantKind::Ty(c) => Ok(ConstantKind::Ty(c.try_fold_with(folder)?)), + ConstantKind::Val(v, t) => Ok(ConstantKind::Val(v, t.try_fold_with(folder)?)), } }