From 0aa9658f5d29340e630d3bfcffd41abe16a96b34 Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Thu, 25 Jul 2019 16:59:38 +0530 Subject: [PATCH 01/25] changing the fields of InterpError --- src/librustc/mir/interpret/error.rs | 31 +++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index 5309d5b039e9e..8b5f1b7fc93e9 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -309,8 +309,30 @@ impl fmt::Debug for PanicMessage { } } +#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] +pub enum InvalidProgramMessage<'tcx> { + /// Resolution can fail if we are in a too generic context + TooGeneric, + /// Cannot compute this constant because it depends on another one + /// which already produced an error + ReferencedConstant, + /// Abort in case type errors are reached + TypeckError, +} + #[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] pub enum InterpError<'tcx> { + /// The program caused undefined behavior. + UndefinedBehaviour(UndefinedBehaviourMessage<'tcx>), + /// The program did something the interpreter does not support (some of these *might* be UB + /// but the interpreter is not sure). + Unsupported(UnsupportedMessage<'tcx>), + /// The program was invalid (ill-typed, not sufficiently monomorphized, ...). + InvalidProgram(InvalidProgramMessage<'tcx>), + /// The program exhausted the interpreter's resources (stack/heap too big, + /// execution takes too long, ..). + ResourceExhaustion(ResourceExhaustionMessage<'tcx>), + /// This variant is used by machines to signal their own errors that do not /// match an existing variant. MachineError(String), @@ -374,18 +396,11 @@ pub enum InterpError<'tcx> { HeapAllocZeroBytes, HeapAllocNonPowerOfTwoAlignment(u64), Unreachable, + /// The program panicked. Panic(PanicMessage), ReadFromReturnPointer, PathNotFound(Vec), UnimplementedTraitSelection, - /// Abort in case type errors are reached - TypeckError, - /// Resolution can fail if we are in a too generic context - TooGeneric, - /// Cannot compute this constant because it depends on another one - /// which already produced an error - ReferencedConstant, - InfiniteLoop, } pub type InterpResult<'tcx, T = ()> = Result>; From 01859bb1602c486a1df1eec9e6884d4bdae60fed Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Fri, 26 Jul 2019 10:51:54 +0530 Subject: [PATCH 02/25] grouping the variants of InterpError --- src/librustc/mir/interpret/error.rs | 36 +++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index 8b5f1b7fc93e9..b17d3244bc354 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -139,9 +139,11 @@ impl<'tcx> ConstEvalErr<'tcx> { ) -> Result, ErrorHandled> { match self.error { InterpError::Layout(LayoutError::Unknown(_)) | - InterpError::TooGeneric => return Err(ErrorHandled::TooGeneric), + InterpError::InvalidProgram(InvalidProgramMessage::TooGeneric) => + return Err(ErrorHandled::TooGeneric), InterpError::Layout(LayoutError::SizeOverflow(_)) | - InterpError::TypeckError => return Err(ErrorHandled::Reported), + InterpError::InvalidProgram(InvalidProgramMessage::TypeckError) => + return Err(ErrorHandled::Reported), _ => {}, } trace!("reporting const eval failure at {:?}", self.span); @@ -310,7 +312,7 @@ impl fmt::Debug for PanicMessage { } #[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] -pub enum InvalidProgramMessage<'tcx> { +pub enum InvalidProgramMessage { /// Resolution can fail if we are in a too generic context TooGeneric, /// Cannot compute this constant because it depends on another one @@ -320,19 +322,35 @@ pub enum InvalidProgramMessage<'tcx> { TypeckError, } +#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] +pub enum UndefinedBehaviourMessage { +} + +#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] +pub enum UnsupportedMessage { +} + +#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] +pub enum ResourceExhaustionMessage { +} + #[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] pub enum InterpError<'tcx> { + /// The program panicked. + Panic(PanicMessage), /// The program caused undefined behavior. - UndefinedBehaviour(UndefinedBehaviourMessage<'tcx>), + UndefinedBehaviour(UndefinedBehaviourMessage), /// The program did something the interpreter does not support (some of these *might* be UB /// but the interpreter is not sure). - Unsupported(UnsupportedMessage<'tcx>), + Unsupported(UnsupportedMessage), /// The program was invalid (ill-typed, not sufficiently monomorphized, ...). - InvalidProgram(InvalidProgramMessage<'tcx>), + InvalidProgram(InvalidProgramMessage), /// The program exhausted the interpreter's resources (stack/heap too big, /// execution takes too long, ..). - ResourceExhaustion(ResourceExhaustionMessage<'tcx>), - + ResourceExhaustion(ResourceExhaustionMessage), + + /// THe above 5 variants are what we want to group all the remaining InterpError variants into + /// This variant is used by machines to signal their own errors that do not /// match an existing variant. MachineError(String), @@ -396,8 +414,6 @@ pub enum InterpError<'tcx> { HeapAllocZeroBytes, HeapAllocNonPowerOfTwoAlignment(u64), Unreachable, - /// The program panicked. - Panic(PanicMessage), ReadFromReturnPointer, PathNotFound(Vec), UnimplementedTraitSelection, From fc48f3e824333f1dc8166f9760795a8b67c84714 Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Fri, 26 Jul 2019 15:28:27 +0530 Subject: [PATCH 03/25] more grouping of the variants in InterpError --- src/librustc/mir/interpret/error.rs | 86 +++++++++++++++-------------- 1 file changed, 44 insertions(+), 42 deletions(-) diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index b17d3244bc354..2897c70d71d25 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -137,12 +137,13 @@ impl<'tcx> ConstEvalErr<'tcx> { message: &str, lint_root: Option, ) -> Result, ErrorHandled> { + use InvalidProgramInfo::*; match self.error { - InterpError::Layout(LayoutError::Unknown(_)) | - InterpError::InvalidProgram(InvalidProgramMessage::TooGeneric) => + InterpError::InvalidProgram(Layout(LayoutError::Unknown(_))) | + InterpError::InvalidProgram(TooGeneric) => return Err(ErrorHandled::TooGeneric), InterpError::Layout(LayoutError::SizeOverflow(_)) | - InterpError::InvalidProgram(InvalidProgramMessage::TypeckError) => + InterpError::InvalidProgram(TypeckError) => return Err(ErrorHandled::Reported), _ => {}, } @@ -312,7 +313,7 @@ impl fmt::Debug for PanicMessage { } #[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] -pub enum InvalidProgramMessage { +pub enum InvalidProgramInfo<'tcx> { /// Resolution can fail if we are in a too generic context TooGeneric, /// Cannot compute this constant because it depends on another one @@ -320,18 +321,50 @@ pub enum InvalidProgramMessage { ReferencedConstant, /// Abort in case type errors are reached TypeckError, + Layout(layout::LayoutError<'tcx>), } #[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] -pub enum UndefinedBehaviourMessage { +pub enum UndefinedBehaviourInfo { + Unreachable, } #[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] -pub enum UnsupportedMessage { +pub enum UnsupportedInfo<'tcx> { + FunctionAbiMismatch(Abi, Abi), + FunctionArgMismatch(Ty<'tcx>, Ty<'tcx>), + FunctionRetMismatch(Ty<'tcx>, Ty<'tcx>), + FunctionArgCountMismatch, + UnterminatedCString(Pointer), + DanglingPointerDeref, + DoubleFree, + InvalidMemoryAccess, + InvalidFunctionPointer, + InvalidBool, + InvalidDiscriminant(ScalarMaybeUndef), + PointerOutOfBounds { + ptr: Pointer, + msg: CheckInAllocMsg, + allocation_size: Size, + }, + InvalidNullPointerUsage, + ReadPointerAsBytes, + ReadBytesAsPointer, + ReadForeignStatic, + InvalidPointerMath, + ReadUndefBytes(Size), + DeadLocal, + InvalidBoolOp(mir::BinOp), + InlineAsm, + UnimplementedTraitSelection, + CalledClosureAsFunction, + NoMirFor(String), } #[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] -pub enum ResourceExhaustionMessage { +pub enum ResourceExhaustionInfo { + StackFrameLimitReached, + InfiniteLoop, } #[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] @@ -339,15 +372,15 @@ pub enum InterpError<'tcx> { /// The program panicked. Panic(PanicMessage), /// The program caused undefined behavior. - UndefinedBehaviour(UndefinedBehaviourMessage), + UndefinedBehaviour(UndefinedBehaviourInfo), /// The program did something the interpreter does not support (some of these *might* be UB /// but the interpreter is not sure). - Unsupported(UnsupportedMessage), + Unsupported(UnsupportedInfo<'tcx>), /// The program was invalid (ill-typed, not sufficiently monomorphized, ...). - InvalidProgram(InvalidProgramMessage), + InvalidProgram(InvalidProgramInfo<'tcx>), /// The program exhausted the interpreter's resources (stack/heap too big, /// execution takes too long, ..). - ResourceExhaustion(ResourceExhaustionMessage), + ResourceExhaustion(ResourceExhaustionInfo), /// THe above 5 variants are what we want to group all the remaining InterpError variants into @@ -359,37 +392,11 @@ pub enum InterpError<'tcx> { /// with the given status code. Used by Miri, but not by CTFE. Exit(i32), - FunctionAbiMismatch(Abi, Abi), - FunctionArgMismatch(Ty<'tcx>, Ty<'tcx>), - FunctionRetMismatch(Ty<'tcx>, Ty<'tcx>), - FunctionArgCountMismatch, - NoMirFor(String), - UnterminatedCString(Pointer), - DanglingPointerDeref, - DoubleFree, - InvalidMemoryAccess, - InvalidFunctionPointer, - InvalidBool, - InvalidDiscriminant(ScalarMaybeUndef), - PointerOutOfBounds { - ptr: Pointer, - msg: CheckInAllocMsg, - allocation_size: Size, - }, - InvalidNullPointerUsage, - ReadPointerAsBytes, - ReadBytesAsPointer, - ReadForeignStatic, - InvalidPointerMath, - ReadUndefBytes(Size), - DeadLocal, - InvalidBoolOp(mir::BinOp), Unimplemented(String), DerefFunctionPointer, ExecuteMemory, Intrinsic(String), InvalidChar(u128), - StackFrameLimitReached, OutOfTls, TlsOutOfBounds, AbiViolation(String), @@ -398,25 +405,20 @@ pub enum InterpError<'tcx> { has: Align, }, ValidationFailure(String), - CalledClosureAsFunction, VtableForArgumentlessMethod, ModifiedConstantMemory, ModifiedStatic, AssumptionNotHeld, - InlineAsm, TypeNotPrimitive(Ty<'tcx>), ReallocatedWrongMemoryKind(String, String), DeallocatedWrongMemoryKind(String, String), ReallocateNonBasePtr, DeallocateNonBasePtr, IncorrectAllocationInformation(Size, Size, Align, Align), - Layout(layout::LayoutError<'tcx>), HeapAllocZeroBytes, HeapAllocNonPowerOfTwoAlignment(u64), - Unreachable, ReadFromReturnPointer, PathNotFound(Vec), - UnimplementedTraitSelection, } pub type InterpResult<'tcx, T = ()> = Result>; From eeb2335401b173e7f7ae84c699b96cbd7a6c3e50 Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Fri, 26 Jul 2019 16:31:12 +0530 Subject: [PATCH 04/25] moving remaining variants to UnsupportedInfo --- src/librustc/mir/interpret/error.rs | 47 ++++++++++++++--------------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index 2897c70d71d25..d0f3df800e4d0 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -359,31 +359,6 @@ pub enum UnsupportedInfo<'tcx> { UnimplementedTraitSelection, CalledClosureAsFunction, NoMirFor(String), -} - -#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] -pub enum ResourceExhaustionInfo { - StackFrameLimitReached, - InfiniteLoop, -} - -#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] -pub enum InterpError<'tcx> { - /// The program panicked. - Panic(PanicMessage), - /// The program caused undefined behavior. - UndefinedBehaviour(UndefinedBehaviourInfo), - /// The program did something the interpreter does not support (some of these *might* be UB - /// but the interpreter is not sure). - Unsupported(UnsupportedInfo<'tcx>), - /// The program was invalid (ill-typed, not sufficiently monomorphized, ...). - InvalidProgram(InvalidProgramInfo<'tcx>), - /// The program exhausted the interpreter's resources (stack/heap too big, - /// execution takes too long, ..). - ResourceExhaustion(ResourceExhaustionInfo), - - /// THe above 5 variants are what we want to group all the remaining InterpError variants into - /// This variant is used by machines to signal their own errors that do not /// match an existing variant. MachineError(String), @@ -421,6 +396,28 @@ pub enum InterpError<'tcx> { PathNotFound(Vec), } +#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] +pub enum ResourceExhaustionInfo { + StackFrameLimitReached, + InfiniteLoop, +} + +#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] +pub enum InterpError<'tcx> { + /// The program panicked. + Panic(PanicMessage), + /// The program caused undefined behavior. + UndefinedBehaviour(UndefinedBehaviourInfo), + /// The program did something the interpreter does not support (some of these *might* be UB + /// but the interpreter is not sure). + Unsupported(UnsupportedInfo<'tcx>), + /// The program was invalid (ill-typed, not sufficiently monomorphized, ...). + InvalidProgram(InvalidProgramInfo<'tcx>), + /// The program exhausted the interpreter's resources (stack/heap too big, + /// execution takes too long, ..). + ResourceExhaustion(ResourceExhaustionInfo), +} + pub type InterpResult<'tcx, T = ()> = Result>; impl fmt::Display for InterpError<'_> { From 4f0ab6ccce86bb9742090b97f1e130360ac7734a Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Fri, 26 Jul 2019 19:08:12 +0530 Subject: [PATCH 05/25] code review fixes --- src/librustc/mir/interpret/error.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index d0f3df800e4d0..dd06991b46aca 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -321,16 +321,20 @@ pub enum InvalidProgramInfo<'tcx> { ReferencedConstant, /// Abort in case type errors are reached TypeckError, + /// An error occurred during layout computation. Layout(layout::LayoutError<'tcx>), } #[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] pub enum UndefinedBehaviourInfo { + /// Handle cases which for which we do not have a fixed variant + Ub(String), Unreachable, } #[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] pub enum UnsupportedInfo<'tcx> { + Unimplemented(String), FunctionAbiMismatch(Abi, Abi), FunctionArgMismatch(Ty<'tcx>, Ty<'tcx>), FunctionRetMismatch(Ty<'tcx>, Ty<'tcx>), @@ -362,12 +366,6 @@ pub enum UnsupportedInfo<'tcx> { /// This variant is used by machines to signal their own errors that do not /// match an existing variant. MachineError(String), - - /// Not actually an interpreter error -- used to signal that execution has exited - /// with the given status code. Used by Miri, but not by CTFE. - Exit(i32), - - Unimplemented(String), DerefFunctionPointer, ExecuteMemory, Intrinsic(String), @@ -416,6 +414,9 @@ pub enum InterpError<'tcx> { /// The program exhausted the interpreter's resources (stack/heap too big, /// execution takes too long, ..). ResourceExhaustion(ResourceExhaustionInfo), + /// Not actually an interpreter error -- used to signal that execution has exited + /// with the given status code. Used by Miri, but not by CTFE. + Exit(i32), } pub type InterpResult<'tcx, T = ()> = Result>; From 307798aa38b00d92c9d541a199c3b2ed5422d358 Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Sat, 27 Jul 2019 17:49:12 +0530 Subject: [PATCH 06/25] fixing fallout due to InterpError refactor --- src/librustc/mir/interpret/allocation.rs | 7 +- src/librustc/mir/interpret/error.rs | 172 +++++++++++++-------- src/librustc/mir/interpret/mod.rs | 3 +- src/librustc/mir/interpret/pointer.rs | 5 +- src/librustc/mir/interpret/value.rs | 13 +- src/librustc_mir/const_eval.rs | 15 +- src/librustc_mir/interpret/cast.rs | 7 +- src/librustc_mir/interpret/eval_context.rs | 29 ++-- src/librustc_mir/interpret/intern.rs | 8 +- src/librustc_mir/interpret/intrinsics.rs | 12 +- src/librustc_mir/interpret/machine.rs | 8 +- src/librustc_mir/interpret/memory.rs | 66 ++++---- src/librustc_mir/interpret/operand.rs | 22 ++- src/librustc_mir/interpret/operator.rs | 6 +- src/librustc_mir/interpret/place.rs | 5 +- src/librustc_mir/interpret/snapshot.rs | 4 +- src/librustc_mir/interpret/step.rs | 4 +- src/librustc_mir/interpret/terminator.rs | 27 ++-- src/librustc_mir/interpret/traits.rs | 4 +- src/librustc_mir/interpret/validity.rs | 22 +-- src/librustc_mir/transform/const_prop.rs | 86 ++--------- 21 files changed, 259 insertions(+), 266 deletions(-) diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs index 51b2d0272a597..b5ec30c9212f3 100644 --- a/src/librustc/mir/interpret/allocation.rs +++ b/src/librustc/mir/interpret/allocation.rs @@ -4,6 +4,7 @@ use super::{ Pointer, InterpResult, AllocId, ScalarMaybeUndef, write_target_uint, read_target_uint, Scalar, }; +use super::error::UnsupportedInfo::*; use crate::ty::layout::{Size, Align}; use syntax::ast::Mutability; use std::iter; @@ -244,7 +245,7 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra> Allocation { Ok(&self.get_bytes(cx, ptr, size_with_null)?[..size]) } // This includes the case where `offset` is out-of-bounds to begin with. - None => err!(UnterminatedCString(ptr.erase_tag())), + None => err!(Unsupported(UnterminatedCString(ptr.erase_tag()))), } } @@ -446,7 +447,7 @@ impl<'tcx, Tag: Copy, Extra> Allocation { if self.relocations(cx, ptr, size).is_empty() { Ok(()) } else { - err!(ReadPointerAsBytes) + err!(Unsupported(ReadPointerAsBytes)) } } @@ -516,7 +517,7 @@ impl<'tcx, Tag, Extra> Allocation { self.undef_mask.is_range_defined( ptr.offset, ptr.offset + size, - ).or_else(|idx| err!(ReadUndefBytes(idx))) + ).or_else(|idx| err!(Unsupported(ReadUndefBytes(idx)))) } pub fn mark_definedness( diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index dd06991b46aca..c28582f1ab08d 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -142,7 +142,7 @@ impl<'tcx> ConstEvalErr<'tcx> { InterpError::InvalidProgram(Layout(LayoutError::Unknown(_))) | InterpError::InvalidProgram(TooGeneric) => return Err(ErrorHandled::TooGeneric), - InterpError::Layout(LayoutError::SizeOverflow(_)) | + InterpError::InvalidProgram(Layout(LayoutError::SizeOverflow(_))) | InterpError::InvalidProgram(TypeckError) => return Err(ErrorHandled::Reported), _ => {}, @@ -325,16 +325,47 @@ pub enum InvalidProgramInfo<'tcx> { Layout(layout::LayoutError<'tcx>), } +impl fmt::Debug for InvalidProgramInfo<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + use InvalidProgramInfo::*; + match self { + TooGeneric => + write!(f, "encountered overly generic constant"), + ReferencedConstant => + write!(f, "referenced constant has errors"), + TypeckError => + write!(f, "encountered constants with type errors, stopping evaluation"), + Layout(ref err) => + write!(f, "rustc layout computation failed: {:?}", err), + } + } +} + #[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] pub enum UndefinedBehaviourInfo { - /// Handle cases which for which we do not have a fixed variant + /// Handle cases which for which we do not have a fixed variant. Ub(String), + /// Unreachable code was executed. Unreachable, } +impl fmt::Debug for UndefinedBehaviourInfo { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + use UndefinedBehaviourInfo::*; + match self { + Ub(ref msg) => + write!(f, "{}", msg), + Unreachable => + write!(f, "entered unreachable code"), + } + } +} + #[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] pub enum UnsupportedInfo<'tcx> { Unimplemented(String), + + // -- Everything below is not classified yet -- FunctionAbiMismatch(Abi, Abi), FunctionArgMismatch(Ty<'tcx>, Ty<'tcx>), FunctionRetMismatch(Ty<'tcx>, Ty<'tcx>), @@ -400,6 +431,19 @@ pub enum ResourceExhaustionInfo { InfiniteLoop, } +impl fmt::Debug for ResourceExhaustionInfo { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + use ResourceExhaustionInfo::*; + match self { + StackFrameLimitReached => + write!(f, "reached the configured maximum number of stack frames"), + InfiniteLoop => + write!(f, "duplicate interpreter state observed here, const evaluation will never \ + terminate"), + } + } +} + #[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] pub enum InterpError<'tcx> { /// The program panicked. @@ -431,139 +475,131 @@ impl fmt::Display for InterpError<'_> { impl fmt::Debug for InterpError<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { use InterpError::*; + use UnsupportedInfo::*; match *self { - PointerOutOfBounds { ptr, msg, allocation_size } => { + Unsupported(PointerOutOfBounds { ptr, msg, allocation_size }) => { write!(f, "{} failed: pointer must be in-bounds at offset {}, \ but is outside bounds of allocation {} which has size {}", msg, ptr.offset.bytes(), ptr.alloc_id, allocation_size.bytes()) }, - ValidationFailure(ref err) => { + Unsupported(ValidationFailure(ref err)) => { write!(f, "type validation failed: {}", err) } - NoMirFor(ref func) => write!(f, "no mir for `{}`", func), - FunctionAbiMismatch(caller_abi, callee_abi) => + Unsupported(NoMirFor(ref func)) => write!(f, "no mir for `{}`", func), + Unsupported(FunctionAbiMismatch(caller_abi, callee_abi)) => write!(f, "tried to call a function with ABI {:?} using caller ABI {:?}", callee_abi, caller_abi), - FunctionArgMismatch(caller_ty, callee_ty) => + Unsupported(FunctionArgMismatch(caller_ty, callee_ty)) => write!(f, "tried to call a function with argument of type {:?} \ passing data of type {:?}", callee_ty, caller_ty), - FunctionRetMismatch(caller_ty, callee_ty) => + Unsupported(FunctionRetMismatch(caller_ty, callee_ty)) => write!(f, "tried to call a function with return type {:?} \ passing return place of type {:?}", callee_ty, caller_ty), - FunctionArgCountMismatch => + Unsupported(FunctionArgCountMismatch) => write!(f, "tried to call a function with incorrect number of arguments"), - ReallocatedWrongMemoryKind(ref old, ref new) => + Unsupported(ReallocatedWrongMemoryKind(ref old, ref new)) => write!(f, "tried to reallocate memory from {} to {}", old, new), - DeallocatedWrongMemoryKind(ref old, ref new) => + Unsupported(DeallocatedWrongMemoryKind(ref old, ref new)) => write!(f, "tried to deallocate {} memory but gave {} as the kind", old, new), - InvalidChar(c) => + Unsupported(InvalidChar(c)) => write!(f, "tried to interpret an invalid 32-bit value as a char: {}", c), - AlignmentCheckFailed { required, has } => + Unsupported(AlignmentCheckFailed { required, has }) => write!(f, "tried to access memory with alignment {}, but alignment {} is required", has.bytes(), required.bytes()), - TypeNotPrimitive(ty) => + Unsupported(TypeNotPrimitive(ty)) => write!(f, "expected primitive type, got {}", ty), - Layout(ref err) => - write!(f, "rustc layout computation failed: {:?}", err), - PathNotFound(ref path) => + Unsupported(PathNotFound(ref path)) => write!(f, "Cannot find path {:?}", path), - IncorrectAllocationInformation(size, size2, align, align2) => + Unsupported(IncorrectAllocationInformation(size, size2, align, align2)) => write!(f, "incorrect alloc info: expected size {} and align {}, \ got size {} and align {}", size.bytes(), align.bytes(), size2.bytes(), align2.bytes()), - InvalidDiscriminant(val) => + Unsupported(InvalidDiscriminant(val)) => write!(f, "encountered invalid enum discriminant {}", val), - Exit(code) => - write!(f, "exited with status code {}", code), - InvalidMemoryAccess => + Unsupported(InvalidMemoryAccess) => write!(f, "tried to access memory through an invalid pointer"), - DanglingPointerDeref => + Unsupported(DanglingPointerDeref) => write!(f, "dangling pointer was dereferenced"), - DoubleFree => + Unsupported(DoubleFree) => write!(f, "tried to deallocate dangling pointer"), - InvalidFunctionPointer => + Unsupported(InvalidFunctionPointer) => write!(f, "tried to use a function pointer after offsetting it"), - InvalidBool => + Unsupported(InvalidBool) => write!(f, "invalid boolean value read"), - InvalidNullPointerUsage => + Unsupported(InvalidNullPointerUsage) => write!(f, "invalid use of NULL pointer"), - ReadPointerAsBytes => + Unsupported(ReadPointerAsBytes) => write!(f, "a raw memory access tried to access part of a pointer value as raw \ bytes"), - ReadBytesAsPointer => + Unsupported(ReadBytesAsPointer) => write!(f, "a memory access tried to interpret some bytes as a pointer"), - ReadForeignStatic => + Unsupported(ReadForeignStatic) => write!(f, "tried to read from foreign (extern) static"), - InvalidPointerMath => + Unsupported(InvalidPointerMath) => write!(f, "attempted to do invalid arithmetic on pointers that would leak base \ addresses, e.g., comparing pointers into different allocations"), - DeadLocal => + Unsupported(DeadLocal) => write!(f, "tried to access a dead local variable"), - DerefFunctionPointer => + Unsupported(DerefFunctionPointer) => write!(f, "tried to dereference a function pointer"), - ExecuteMemory => + Unsupported(ExecuteMemory) => write!(f, "tried to treat a memory pointer as a function pointer"), - StackFrameLimitReached => - write!(f, "reached the configured maximum number of stack frames"), - OutOfTls => + Unsupported(OutOfTls) => write!(f, "reached the maximum number of representable TLS keys"), - TlsOutOfBounds => + Unsupported(TlsOutOfBounds) => write!(f, "accessed an invalid (unallocated) TLS key"), - CalledClosureAsFunction => + Unsupported(CalledClosureAsFunction) => write!(f, "tried to call a closure through a function pointer"), - VtableForArgumentlessMethod => + Unsupported(VtableForArgumentlessMethod) => write!(f, "tried to call a vtable function without arguments"), - ModifiedConstantMemory => + Unsupported(ModifiedConstantMemory) => write!(f, "tried to modify constant memory"), - ModifiedStatic => + Unsupported(ModifiedStatic) => write!(f, "tried to modify a static's initial value from another static's \ initializer"), - AssumptionNotHeld => + Unsupported(AssumptionNotHeld) => write!(f, "`assume` argument was false"), - InlineAsm => + Unsupported(InlineAsm) => write!(f, "miri does not support inline assembly"), - ReallocateNonBasePtr => + Unsupported(ReallocateNonBasePtr) => write!(f, "tried to reallocate with a pointer not to the beginning of an \ existing object"), - DeallocateNonBasePtr => + Unsupported(DeallocateNonBasePtr) => write!(f, "tried to deallocate with a pointer not to the beginning of an \ existing object"), - HeapAllocZeroBytes => + Unsupported(HeapAllocZeroBytes) => write!(f, "tried to re-, de- or allocate zero bytes on the heap"), - Unreachable => - write!(f, "entered unreachable code"), - ReadFromReturnPointer => + Unsupported(ReadFromReturnPointer) => write!(f, "tried to read from the return pointer"), - UnimplementedTraitSelection => + Unsupported(UnimplementedTraitSelection) => write!(f, "there were unresolved type arguments during trait selection"), - TypeckError => - write!(f, "encountered constants with type errors, stopping evaluation"), - TooGeneric => - write!(f, "encountered overly generic constant"), - ReferencedConstant => - write!(f, "referenced constant has errors"), - InfiniteLoop => - write!(f, "duplicate interpreter state observed here, const evaluation will never \ - terminate"), - InvalidBoolOp(_) => + Unsupported(InvalidBoolOp(_)) => write!(f, "invalid boolean operation"), - UnterminatedCString(_) => + Unsupported(UnterminatedCString(_)) => write!(f, "attempted to get length of a null terminated string, but no null \ found before end of allocation"), - ReadUndefBytes(_) => + Unsupported(ReadUndefBytes(_)) => write!(f, "attempted to read undefined bytes"), - HeapAllocNonPowerOfTwoAlignment(_) => + Unsupported(HeapAllocNonPowerOfTwoAlignment(_)) => write!(f, "tried to re-, de-, or allocate heap memory with alignment that is \ not a power of two"), - MachineError(ref msg) | - Unimplemented(ref msg) | - AbiViolation(ref msg) | - Intrinsic(ref msg) => + Unsupported(MachineError(ref msg)) | + Unsupported(Unimplemented(ref msg)) | + Unsupported(AbiViolation(ref msg)) | + Unsupported(Intrinsic(ref msg)) => write!(f, "{}", msg), + InvalidProgram(ref msg) => + write!(f, "{:?}", msg), + UndefinedBehaviour(ref msg) => + write!(f, "{:?}", msg), + ResourceExhaustion(ref msg) => + write!(f, "{:?}", msg), Panic(ref msg) => write!(f, "{:?}", msg), + Exit(code) => + write!(f, "exited with status code {}", code), } } } diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs index 121b6ac0ac88c..ceed59885b275 100644 --- a/src/librustc/mir/interpret/mod.rs +++ b/src/librustc/mir/interpret/mod.rs @@ -12,7 +12,8 @@ mod pointer; pub use self::error::{ InterpErrorInfo, InterpResult, InterpError, AssertMessage, ConstEvalErr, struct_error, - FrameInfo, ConstEvalRawResult, ConstEvalResult, ErrorHandled, PanicMessage + FrameInfo, ConstEvalRawResult, ConstEvalResult, ErrorHandled, PanicMessage, UnsupportedInfo, + InvalidProgramInfo, ResourceExhaustionInfo, UndefinedBehaviourInfo, }; pub use self::value::{Scalar, ScalarMaybeUndef, RawConst, ConstValue}; diff --git a/src/librustc/mir/interpret/pointer.rs b/src/librustc/mir/interpret/pointer.rs index 0e3b8459115e3..afbe1ed9a9395 100644 --- a/src/librustc/mir/interpret/pointer.rs +++ b/src/librustc/mir/interpret/pointer.rs @@ -1,5 +1,6 @@ use std::fmt::{self, Display}; +use super::error::UnsupportedInfo::*; use crate::mir; use crate::ty::layout::{self, HasDataLayout, Size}; use rustc_macros::HashStable; @@ -198,11 +199,11 @@ impl<'tcx, Tag> Pointer { msg: CheckInAllocMsg, ) -> InterpResult<'tcx, ()> { if self.offset > allocation_size { - err!(PointerOutOfBounds { + err!(Unsupported(PointerOutOfBounds { ptr: self.erase_tag(), msg, allocation_size, - }) + })) } else { Ok(()) } diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs index 4a59d845b3b42..29bf94292ef86 100644 --- a/src/librustc/mir/interpret/value.rs +++ b/src/librustc/mir/interpret/value.rs @@ -2,6 +2,7 @@ use std::fmt; use rustc_macros::HashStable; use rustc_apfloat::{Float, ieee::{Double, Single}}; +use super::error::UnsupportedInfo::*; use crate::ty::{Ty, InferConst, ParamConst, layout::{HasDataLayout, Size, Align}, subst::SubstsRef}; use crate::ty::PlaceholderConst; use crate::hir::def_id::DefId; @@ -360,7 +361,7 @@ impl<'tcx, Tag> Scalar { Scalar::check_data(data, size); Ok(data) } - Scalar::Ptr(_) => err!(ReadPointerAsBytes), + Scalar::Ptr(_) => err!(Unsupported(ReadPointerAsBytes)), } } @@ -373,8 +374,8 @@ impl<'tcx, Tag> Scalar { #[inline] pub fn to_ptr(self) -> InterpResult<'tcx, Pointer> { match self { - Scalar::Raw { data: 0, .. } => err!(InvalidNullPointerUsage), - Scalar::Raw { .. } => err!(ReadBytesAsPointer), + Scalar::Raw { data: 0, .. } => err!(Unsupported(InvalidNullPointerUsage)), + Scalar::Raw { .. } => err!(Unsupported(ReadBytesAsPointer)), Scalar::Ptr(p) => Ok(p), } } @@ -406,7 +407,7 @@ impl<'tcx, Tag> Scalar { match self { Scalar::Raw { data: 0, size: 1 } => Ok(false), Scalar::Raw { data: 1, size: 1 } => Ok(true), - _ => err!(InvalidBool), + _ => err!(Unsupported(InvalidBool)), } } @@ -414,7 +415,7 @@ impl<'tcx, Tag> Scalar { let val = self.to_u32()?; match ::std::char::from_u32(val) { Some(c) => Ok(c), - None => err!(InvalidChar(val as u128)), + None => err!(Unsupported(InvalidChar(val as u128))), } } @@ -537,7 +538,7 @@ impl<'tcx, Tag> ScalarMaybeUndef { pub fn not_undef(self) -> InterpResult<'static, Scalar> { match self { ScalarMaybeUndef::Scalar(scalar) => Ok(scalar), - ScalarMaybeUndef::Undef => err!(ReadUndefBytes(Size::from_bytes(0))), + ScalarMaybeUndef::Undef => err!(Unsupported(ReadUndefBytes(Size::from_bytes(0)))), } } diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 37d4c5b2f09ce..60381e0365fae 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -24,7 +24,8 @@ use crate::interpret::{self, RawConst, ConstValue, InterpResult, InterpErrorInfo, InterpError, GlobalId, InterpCx, StackPopCleanup, Allocation, AllocId, MemoryKind, - snapshot, RefTracking, intern_const_alloc_recursive, + snapshot, RefTracking, intern_const_alloc_recursive, UnsupportedInfo::*, + InvalidProgramInfo::*, }; /// Number of steps until the detector even starts doing anything. @@ -183,7 +184,7 @@ fn eval_body_using_ecx<'mir, 'tcx>( impl<'tcx> Into> for ConstEvalError { fn into(self) -> InterpErrorInfo<'tcx> { - InterpError::MachineError(self.to_string()).into() + InterpError::Unsupported(MachineError(self.to_string())).into() } } @@ -352,7 +353,9 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, ecx.goto_block(ret)?; // fully evaluated and done Ok(None) } else { - err!(MachineError(format!("calling non-const function `{}`", instance))) + err!(Unsupported( + MachineError(format!("calling non-const function `{}`", instance)) + )) }; } } @@ -360,7 +363,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, Ok(Some(match ecx.load_mir(instance.def) { Ok(body) => body, Err(err) => { - if let InterpError::NoMirFor(ref path) = err.kind { + if let InterpError::Unsupported(NoMirFor(ref path)) = err.kind { return Err( ConstEvalError::NeedsRfc(format!("calling extern function `{}`", path)) .into(), @@ -412,7 +415,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, _tcx: TyCtxt<'tcx>, _def_id: DefId, ) -> InterpResult<'tcx, Cow<'tcx, Allocation>> { - err!(ReadForeignStatic) + err!(Unsupported(ReadForeignStatic)) } #[inline(always)] @@ -698,7 +701,7 @@ pub fn const_eval_raw_provider<'tcx>( // any other kind of error will be reported to the user as a deny-by-default lint _ => if let Some(p) = cid.promoted { let span = tcx.promoted_mir(def_id)[p].span; - if let InterpError::ReferencedConstant = err.error { + if let InterpError::InvalidProgram(ReferencedConstant) = err.error { err.report_as_error( tcx.at(span), "evaluation of constant expression failed", diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs index 980697360eb75..443d264b351f7 100644 --- a/src/librustc_mir/interpret/cast.rs +++ b/src/librustc_mir/interpret/cast.rs @@ -9,7 +9,8 @@ use rustc_apfloat::{Float, FloatConvert}; use rustc::mir::interpret::{ Scalar, InterpResult, Pointer, PointerArithmetic, InterpError, }; -use rustc::mir::CastKind; +use rustc::mir::{CastKind, interpret::{UnsupportedInfo::*, InvalidProgramInfo::*}}; + use super::{InterpCx, Machine, PlaceTy, OpTy, Immediate, FnVal}; @@ -85,7 +86,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.param_env, def_id, substs, - ).ok_or_else(|| InterpError::TooGeneric.into()); + ).ok_or_else(|| InterpError::InvalidProgram(TooGeneric).into()); let fn_ptr = self.memory.create_fn_alloc(FnVal::Instance(instance?)); self.write_scalar(Scalar::Ptr(fn_ptr.into()), dest)?; } @@ -199,7 +200,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { }, // Casts to bool are not permitted by rustc, no need to handle them here. - _ => err!(Unimplemented(format!("int to {:?} cast", dest_layout.ty))), + _ => err!(Unsupported(Unimplemented(format!("int to {:?} cast", dest_layout.ty)))), } } diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 007ec8cb2db5c..e732484b9b7bc 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -17,7 +17,8 @@ use rustc::mir::interpret::{ ErrorHandled, GlobalId, Scalar, Pointer, FrameInfo, AllocId, InterpResult, InterpError, - truncate, sign_extend, + truncate, sign_extend, UnsupportedInfo::*, InvalidProgramInfo::*, + ResourceExhaustionInfo::*, UndefinedBehaviourInfo::*, }; use rustc_data_structures::fx::FxHashMap; @@ -135,7 +136,7 @@ pub enum LocalValue { impl<'tcx, Tag: Copy + 'static> LocalState<'tcx, Tag> { pub fn access(&self) -> InterpResult<'tcx, Operand> { match self.value { - LocalValue::Dead => err!(DeadLocal), + LocalValue::Dead => err!(Unsupported(DeadLocal)), LocalValue::Uninitialized => bug!("The type checker should prevent reading from a never-written local"), LocalValue::Live(val) => Ok(val), @@ -148,7 +149,7 @@ impl<'tcx, Tag: Copy + 'static> LocalState<'tcx, Tag> { &mut self, ) -> InterpResult<'tcx, Result<&mut LocalValue, MemPlace>> { match self.value { - LocalValue::Dead => err!(DeadLocal), + LocalValue::Dead => err!(Unsupported(DeadLocal)), LocalValue::Live(Operand::Indirect(mplace)) => Ok(Err(mplace)), ref mut local @ LocalValue::Live(Operand::Immediate(_)) | ref mut local @ LocalValue::Uninitialized => { @@ -191,7 +192,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> LayoutOf for InterpCx<'mir, 'tcx, M> { #[inline] fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyLayout { self.tcx.layout_of(self.param_env.and(ty)) - .map_err(|layout| InterpError::Layout(layout).into()) + .map_err(|layout| InterpError::InvalidProgram(Layout(layout)).into()) } } @@ -302,7 +303,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { &substs, )), None => if substs.needs_subst() { - err!(TooGeneric).into() + err!(InvalidProgram(TooGeneric)).into() } else { Ok(substs) }, @@ -323,7 +324,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.param_env, def_id, substs, - ).ok_or_else(|| InterpError::TooGeneric.into()) + ).ok_or_else(|| InterpError::InvalidProgram(TooGeneric).into()) } pub fn load_mir( @@ -336,14 +337,14 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { && self.tcx.has_typeck_tables(did) && self.tcx.typeck_tables_of(did).tainted_by_errors { - return err!(TypeckError); + return err!(InvalidProgram(TypeckError)); } trace!("load mir {:?}", instance); match instance { ty::InstanceDef::Item(def_id) => if self.tcx.is_mir_available(did) { Ok(self.tcx.optimized_mir(did)) } else { - err!(NoMirFor(self.tcx.def_path_str(def_id))) + err!(Unsupported(NoMirFor(self.tcx.def_path_str(def_id)))) }, _ => Ok(self.tcx.instance_mir(instance)), } @@ -356,7 +357,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { match self.stack.last() { Some(frame) => Ok(self.monomorphize_with_substs(t, frame.instance.substs)?), None => if t.needs_subst() { - err!(TooGeneric).into() + err!(InvalidProgram(TooGeneric)).into() } else { Ok(t) }, @@ -373,7 +374,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let substituted = t.subst(*self.tcx, substs); if substituted.needs_subst() { - return err!(TooGeneric); + return err!(InvalidProgram(TooGeneric)); } Ok(self.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), substituted)) @@ -572,7 +573,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { info!("ENTERING({}) {}", self.cur_frame(), self.frame().instance); if self.stack.len() > self.tcx.sess.const_eval_stack_frame_limit { - err!(StackFrameLimitReached) + err!(ResourceExhaustion(StackFrameLimitReached)) } else { Ok(()) } @@ -620,7 +621,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } } else { // Uh, that shouldn't happen... the function did not intend to return - return err!(Unreachable); + return err!(UndefinedBehaviour(Unreachable)); } // Jump to new block -- *after* validation so that the spans make more sense. match frame.return_to_block { @@ -694,8 +695,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // `Memory::get_static_alloc` which has to use `const_eval_raw` to avoid cycles. let val = self.tcx.const_eval_raw(param_env.and(gid)).map_err(|err| { match err { - ErrorHandled::Reported => InterpError::ReferencedConstant, - ErrorHandled::TooGeneric => InterpError::TooGeneric, + ErrorHandled::Reported => InterpError::InvalidProgram(ReferencedConstant), + ErrorHandled::TooGeneric => InterpError::InvalidProgram(TooGeneric), } })?; self.raw_const_to_mplace(val) diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs index bcd36ac547c73..f1e6132132c0b 100644 --- a/src/librustc_mir/interpret/intern.rs +++ b/src/librustc_mir/interpret/intern.rs @@ -5,7 +5,7 @@ use rustc::ty::{Ty, TyCtxt, ParamEnv, self}; use rustc::mir::interpret::{ - InterpResult, ErrorHandled, + InterpResult, ErrorHandled, UnsupportedInfo::*, }; use rustc::hir; use rustc::hir::def_id::DefId; @@ -293,7 +293,7 @@ pub fn intern_const_alloc_recursive( if let Err(error) = interned { // This can happen when e.g. the tag of an enum is not a valid discriminant. We do have // to read enum discriminants in order to find references in enum variant fields. - if let InterpError::ValidationFailure(_) = error.kind { + if let InterpError::Unsupported(ValidationFailure(_)) = error.kind { let err = crate::const_eval::error_to_const_error(&ecx, error); match err.struct_error(ecx.tcx, "it is undefined behavior to use this value") { Ok(mut diag) => { @@ -328,9 +328,9 @@ pub fn intern_const_alloc_recursive( } } else if ecx.memory().dead_alloc_map.contains_key(&alloc_id) { // dangling pointer - return err!(ValidationFailure( + return err!(Unsupported(ValidationFailure( "encountered dangling pointer in final constant".into(), - )) + ))) } } Ok(()) diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index 6a5b933e4a530..880984ed88cef 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -7,7 +7,7 @@ use rustc::ty; use rustc::ty::layout::{LayoutOf, Primitive, Size}; use rustc::mir::BinOp; use rustc::mir::interpret::{ - InterpResult, InterpError, Scalar, PanicMessage, + InterpResult, InterpError, Scalar, PanicMessage, UnsupportedInfo::*, }; use super::{ @@ -100,11 +100,13 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let bits = self.read_scalar(args[0])?.to_bits(layout_of.size)?; let kind = match layout_of.abi { ty::layout::Abi::Scalar(ref scalar) => scalar.value, - _ => Err(::rustc::mir::interpret::InterpError::TypeNotPrimitive(ty))?, + _ => Err(InterpError::Unsupported(TypeNotPrimitive(ty)))?, }; let out_val = if intrinsic_name.ends_with("_nonzero") { if bits == 0 { - return err!(Intrinsic(format!("{} called on 0", intrinsic_name))); + return err!( + Unsupported(Intrinsic(format!("{} called on 0", intrinsic_name))) + ); } numeric_intrinsic(intrinsic_name.trim_end_matches("_nonzero"), bits, kind)? } else { @@ -190,9 +192,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { if overflowed { let layout = self.layout_of(substs.type_at(0))?; let r_val = r.to_scalar()?.to_bits(layout.size)?; - return err!(Intrinsic( + return err!(Unsupported(Intrinsic( format!("Overflowing shift by {} in {}", r_val, intrinsic_name), - )); + ))); } self.write_scalar(val, dest)?; } diff --git a/src/librustc_mir/interpret/machine.rs b/src/librustc_mir/interpret/machine.rs index e3f16a3c9ea45..c40f80940688c 100644 --- a/src/librustc_mir/interpret/machine.rs +++ b/src/librustc_mir/interpret/machine.rs @@ -11,7 +11,7 @@ use rustc::ty::{self, TyCtxt}; use super::{ Allocation, AllocId, InterpResult, InterpError, Scalar, AllocationExtra, - InterpCx, PlaceTy, OpTy, ImmTy, MemoryKind, Pointer, Memory, + InterpCx, PlaceTy, OpTy, ImmTy, MemoryKind, Pointer, Memory, UnsupportedInfo::* }; /// Whether this kind of memory is allowed to leak @@ -240,9 +240,9 @@ pub trait Machine<'mir, 'tcx>: Sized { int: u64, ) -> InterpResult<'tcx, Pointer> { Err((if int == 0 { - InterpError::InvalidNullPointerUsage + InterpError::Unsupported(InvalidNullPointerUsage) } else { - InterpError::ReadBytesAsPointer + InterpError::Unsupported(ReadBytesAsPointer) }).into()) } @@ -251,6 +251,6 @@ pub trait Machine<'mir, 'tcx>: Sized { _mem: &Memory<'mir, 'tcx, Self>, _ptr: Pointer, ) -> InterpResult<'tcx, u64> { - err!(ReadPointerAsBytes) + err!(Unsupported(ReadPointerAsBytes)) } } diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 87dd7738410ee..74da59182c145 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -19,7 +19,8 @@ use syntax::ast::Mutability; use super::{ Pointer, AllocId, Allocation, GlobalId, AllocationExtra, InterpResult, Scalar, InterpError, GlobalAlloc, PointerArithmetic, - Machine, AllocMap, MayLeak, ErrorHandled, CheckInAllocMsg, + Machine, AllocMap, MayLeak, ErrorHandled, CheckInAllocMsg, UnsupportedInfo::*, + InvalidProgramInfo::* }; #[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)] @@ -66,10 +67,9 @@ impl<'tcx, Other> FnVal<'tcx, Other> { match self { FnVal::Instance(instance) => Ok(instance), - FnVal::Other(_) => - err!(MachineError( - format!("Expected instance function pointer, got 'other' pointer") - )), + FnVal::Other(_) => err!(Unsupported(MachineError(format!( + "Expected instance function pointer, got 'other' pointer" + )))), } } } @@ -203,7 +203,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { kind: MemoryKind, ) -> InterpResult<'tcx, Pointer> { if ptr.offset.bytes() != 0 { - return err!(ReallocateNonBasePtr); + return err!(Unsupported(ReallocateNonBasePtr)); } // For simplicities' sake, we implement reallocate as "alloc, copy, dealloc". @@ -244,7 +244,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { trace!("deallocating: {}", ptr.alloc_id); if ptr.offset.bytes() != 0 { - return err!(DeallocateNonBasePtr); + return err!(Unsupported(DeallocateNonBasePtr)); } let (alloc_kind, mut alloc) = match self.alloc_map.remove(&ptr.alloc_id) { @@ -252,33 +252,33 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { None => { // Deallocating static memory -- always an error return match self.tcx.alloc_map.lock().get(ptr.alloc_id) { - Some(GlobalAlloc::Function(..)) => err!(DeallocatedWrongMemoryKind( + Some(GlobalAlloc::Function(..)) => err!(Unsupported(DeallocatedWrongMemoryKind( "function".to_string(), format!("{:?}", kind), - )), + ))), Some(GlobalAlloc::Static(..)) | - Some(GlobalAlloc::Memory(..)) => err!(DeallocatedWrongMemoryKind( + Some(GlobalAlloc::Memory(..)) => err!(Unsupported(DeallocatedWrongMemoryKind( "static".to_string(), format!("{:?}", kind), - )), - None => err!(DoubleFree) + ))), + None => err!(Unsupported(DoubleFree)) } } }; if alloc_kind != kind { - return err!(DeallocatedWrongMemoryKind( + return err!(Unsupported(DeallocatedWrongMemoryKind( format!("{:?}", alloc_kind), format!("{:?}", kind), - )); + ))); } if let Some((size, align)) = old_size_and_align { if size.bytes() != alloc.bytes.len() as u64 || align != alloc.align { let bytes = Size::from_bytes(alloc.bytes.len() as u64); - return err!(IncorrectAllocationInformation(size, + return err!(Unsupported(IncorrectAllocationInformation(size, bytes, align, - alloc.align)); + alloc.align))); } } @@ -323,10 +323,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { } else { // The biggest power of two through which `offset` is divisible. let offset_pow2 = 1 << offset.trailing_zeros(); - err!(AlignmentCheckFailed { + err!(Unsupported(AlignmentCheckFailed { has: Align::from_bytes(offset_pow2).unwrap(), required: align, - }) + })) } } @@ -345,7 +345,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { assert!(size.bytes() == 0); // Must be non-NULL and aligned. if bits == 0 { - return err!(InvalidNullPointerUsage); + return err!(Unsupported(InvalidNullPointerUsage)); } check_offset_align(bits, align)?; None @@ -366,10 +366,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { // got picked we might be aligned even if this check fails. // We instead have to fall back to converting to an integer and checking // the "real" alignment. - return err!(AlignmentCheckFailed { + return err!(Unsupported(AlignmentCheckFailed { has: alloc_align, required: align, - }); + })); } check_offset_align(ptr.offset.bytes(), align)?; @@ -417,9 +417,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { Some(GlobalAlloc::Memory(mem)) => Cow::Borrowed(mem), Some(GlobalAlloc::Function(..)) => - return err!(DerefFunctionPointer), + return err!(Unsupported(DerefFunctionPointer)), None => - return err!(DanglingPointerDeref), + return err!(Unsupported(DanglingPointerDeref)), Some(GlobalAlloc::Static(def_id)) => { // We got a "lazy" static that has not been computed yet. if tcx.is_foreign_item(def_id) { @@ -440,8 +440,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { // for statics assert!(tcx.is_static(def_id)); match err { - ErrorHandled::Reported => InterpError::ReferencedConstant, - ErrorHandled::TooGeneric => InterpError::TooGeneric, + ErrorHandled::Reported => + InterpError::InvalidProgram(ReferencedConstant), + ErrorHandled::TooGeneric => + InterpError::InvalidProgram(TooGeneric), } })?; // Make sure we use the ID of the resolved memory, not the lazy one! @@ -505,11 +507,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { // to give us a cheap reference. let alloc = Self::get_static_alloc(memory_extra, tcx, id)?; if alloc.mutability == Mutability::Immutable { - return err!(ModifiedConstantMemory); + return err!(Unsupported(ModifiedConstantMemory)); } match M::STATIC_KIND { Some(kind) => Ok((MemoryKind::Machine(kind), alloc.into_owned())), - None => err!(ModifiedStatic), + None => err!(Unsupported(ModifiedStatic)), } }); // Unpack the error type manually because type inference doesn't @@ -519,7 +521,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { Ok(a) => { let a = &mut a.1; if a.mutability == Mutability::Immutable { - return err!(ModifiedConstantMemory); + return err!(Unsupported(ModifiedConstantMemory)); } Ok(a) } @@ -591,7 +593,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { } else { match self.tcx.alloc_map.lock().get(id) { Some(GlobalAlloc::Function(instance)) => Ok(FnVal::Instance(instance)), - _ => Err(InterpError::ExecuteMemory.into()), + _ => Err(InterpError::Unsupported(ExecuteMemory).into()), } } } @@ -602,7 +604,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { ) -> InterpResult<'tcx, FnVal<'tcx, M::ExtraFnVal>> { let ptr = self.force_ptr(ptr)?; // We definitely need a pointer value. if ptr.offset.bytes() != 0 { - return err!(InvalidFunctionPointer); + return err!(Unsupported(InvalidFunctionPointer)); } self.get_fn_alloc(ptr.alloc_id) } @@ -837,9 +839,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { if (src.offset <= dest.offset && src.offset + size > dest.offset) || (dest.offset <= src.offset && dest.offset + size > src.offset) { - return err!(Intrinsic( + return err!(Unsupported(Intrinsic( "copy_nonoverlapping called on overlapping ranges".to_string(), - )); + ))); } } diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 1816171d7b127..3edc7748e5b04 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -12,7 +12,7 @@ use rustc::mir::interpret::{ GlobalId, AllocId, ConstValue, Pointer, Scalar, InterpResult, InterpError, - sign_extend, truncate, + sign_extend, truncate, UnsupportedInfo::*, InvalidProgramInfo::* }; use super::{ InterpCx, Machine, @@ -332,7 +332,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let len = mplace.len(self)?; let bytes = self.memory.read_bytes(mplace.ptr, Size::from_bytes(len as u64))?; let str = ::std::str::from_utf8(bytes) - .map_err(|err| InterpError::ValidationFailure(err.to_string()))?; + .map_err(|err| InterpError::Unsupported(ValidationFailure(err.to_string())))?; Ok(str) } @@ -459,7 +459,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { mir_place.iterate(|place_base, place_projection| { let mut op = match place_base { - PlaceBase::Local(mir::RETURN_PLACE) => return err!(ReadFromReturnPointer), + PlaceBase::Local(mir::RETURN_PLACE) => + return err!(Unsupported(ReadFromReturnPointer)), PlaceBase::Local(local) => { // Do not use the layout passed in as argument if the base we are looking at // here is not the entire place. @@ -530,7 +531,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { }; // Early-return cases. match val.val { - ConstValue::Param(_) => return err!(TooGeneric), // FIXME(oli-obk): try to monomorphize + ConstValue::Param(_) => + // FIXME(oli-obk): try to monomorphize + return err!(InvalidProgram(TooGeneric)), ConstValue::Unevaluated(def_id, substs) => { let instance = self.resolve(def_id, substs)?; return Ok(OpTy::from(self.const_eval_raw(GlobalId { @@ -604,7 +607,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { layout::DiscriminantKind::Tag => { let bits_discr = match raw_discr.to_bits(discr_val.layout.size) { Ok(raw_discr) => raw_discr, - Err(_) => return err!(InvalidDiscriminant(raw_discr.erase_tag())), + Err(_) => + return err!(Unsupported(InvalidDiscriminant(raw_discr.erase_tag()))), }; let real_discr = if discr_val.layout.ty.is_signed() { // going from layout tag type to typeck discriminant type @@ -630,7 +634,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { .discriminants(*def_id, self.tcx.tcx) .find(|(_, var)| var.val == real_discr), _ => bug!("tagged layout for non-adt non-generator"), - }.ok_or_else(|| InterpError::InvalidDiscriminant(raw_discr.erase_tag()))?; + }.ok_or_else( + || InterpError::Unsupported(InvalidDiscriminant(raw_discr.erase_tag())) + )?; (real_discr, index.0) }, layout::DiscriminantKind::Niche { @@ -641,14 +647,14 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let variants_start = niche_variants.start().as_u32() as u128; let variants_end = niche_variants.end().as_u32() as u128; let raw_discr = raw_discr.not_undef() - .map_err(|_| InterpError::InvalidDiscriminant(ScalarMaybeUndef::Undef))?; + .map_err(|_| InterpError::Unsupported(InvalidDiscriminant(ScalarMaybeUndef::Undef)))?; match raw_discr.to_bits_or_ptr(discr_val.layout.size, self) { Err(ptr) => { // The niche must be just 0 (which an inbounds pointer value never is) let ptr_valid = niche_start == 0 && variants_start == variants_end && !self.memory.ptr_may_be_null(ptr); if !ptr_valid { - return err!(InvalidDiscriminant(raw_discr.erase_tag().into())); + return err!(Unsupported(InvalidDiscriminant(raw_discr.erase_tag().into()))); } (dataful_variant.as_u32() as u128, dataful_variant) }, diff --git a/src/librustc_mir/interpret/operator.rs b/src/librustc_mir/interpret/operator.rs index b4edee72a4d19..8af4c71299d21 100644 --- a/src/librustc_mir/interpret/operator.rs +++ b/src/librustc_mir/interpret/operator.rs @@ -4,7 +4,7 @@ use syntax::ast::FloatTy; use rustc_apfloat::Float; use rustc::mir::interpret::{InterpResult, PanicMessage, Scalar}; -use super::{InterpCx, PlaceTy, Immediate, Machine, ImmTy}; +use super::{InterpCx, PlaceTy, Immediate, Machine, ImmTy, UnsupportedInfo::*}; impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { @@ -155,7 +155,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { r, right_layout.ty ); - return err!(Unimplemented(msg)); + return err!(Unsupported(Unimplemented(msg))); } // Operations that need special treatment for signed integers @@ -250,7 +250,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { r, right_layout.ty, ); - return err!(Unimplemented(msg)); + return err!(Unsupported(Unimplemented(msg))); } }; diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 8fe882934dfb5..65e70b7bedc70 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -14,7 +14,8 @@ use rustc::ty::TypeFoldable; use super::{ GlobalId, AllocId, Allocation, Scalar, InterpResult, Pointer, PointerArithmetic, InterpCx, Machine, AllocMap, AllocationExtra, PanicMessage, - RawConst, Immediate, ImmTy, ScalarMaybeUndef, Operand, OpTy, MemoryKind, LocalValue + RawConst, Immediate, ImmTy, ScalarMaybeUndef, Operand, OpTy, MemoryKind, LocalValue, + UnsupportedInfo::*, }; #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] @@ -622,7 +623,7 @@ where .layout_of(self.monomorphize(self.frame().body.return_ty())?)?, } } - None => return err!(InvalidNullPointerUsage), + None => return err!(Unsupported(InvalidNullPointerUsage)), }, PlaceBase::Local(local) => PlaceTy { // This works even for dead/uninitialized locals; we check further when writing diff --git a/src/librustc_mir/interpret/snapshot.rs b/src/librustc_mir/interpret/snapshot.rs index ad631793a0827..112e592329f5f 100644 --- a/src/librustc_mir/interpret/snapshot.rs +++ b/src/librustc_mir/interpret/snapshot.rs @@ -12,7 +12,7 @@ use rustc::mir; use rustc::mir::interpret::{ AllocId, Pointer, Scalar, Relocations, Allocation, UndefMask, - InterpResult, InterpError, + InterpResult, InterpError, ResourceExhaustionInfo::*, }; use rustc::ty::{self, TyCtxt}; @@ -77,7 +77,7 @@ impl<'mir, 'tcx> InfiniteLoopDetector<'mir, 'tcx> { } // Second cycle - Err(InterpError::InfiniteLoop.into()) + Err(InterpError::ResourceExhaustion(InfiniteLoop).into()) } } diff --git a/src/librustc_mir/interpret/step.rs b/src/librustc_mir/interpret/step.rs index 246c90ba48e3a..24aa5489e528a 100644 --- a/src/librustc_mir/interpret/step.rs +++ b/src/librustc_mir/interpret/step.rs @@ -4,7 +4,7 @@ use rustc::mir; use rustc::ty::layout::LayoutOf; -use rustc::mir::interpret::{InterpResult, Scalar, PointerArithmetic}; +use rustc::mir::interpret::{InterpResult, Scalar, PointerArithmetic, UnsupportedInfo}; use super::{InterpCx, Machine}; @@ -121,7 +121,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // size of MIR constantly. Nop => {} - InlineAsm { .. } => return err!(InlineAsm), + InlineAsm { .. } => return err!(Unsupported(UnsupportedInfo::InlineAsm)), } self.stack[frame_idx].stmt += 1; diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs index 27bd0f8889634..cfb901d380ea0 100644 --- a/src/librustc_mir/interpret/terminator.rs +++ b/src/librustc_mir/interpret/terminator.rs @@ -9,6 +9,7 @@ use rustc_target::spec::abi::Abi; use super::{ InterpResult, PointerArithmetic, InterpError, Scalar, InterpCx, Machine, Immediate, OpTy, ImmTy, PlaceTy, MPlaceTy, StackPopCleanup, FnVal, + UndefinedBehaviourInfo, UnsupportedInfo::*, }; impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { @@ -19,7 +20,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.frame_mut().stmt = 0; Ok(()) } else { - err!(Unreachable) + err!(UndefinedBehaviour(UndefinedBehaviourInfo::Unreachable)) } } @@ -89,7 +90,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { }, _ => { let msg = format!("can't handle callee of type {:?}", func.layout.ty); - return err!(Unimplemented(msg)); + return err!(Unsupported(Unimplemented(msg))); } }; let args = self.eval_operands(args)?; @@ -173,7 +174,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { `simplify_branches` mir pass"), FalseUnwind { .. } => bug!("should have been eliminated by\ `simplify_branches` mir pass"), - Unreachable => return err!(Unreachable), + Unreachable => return err!(UndefinedBehaviour(UndefinedBehaviourInfo::Unreachable)), } Ok(()) @@ -220,13 +221,15 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { return Ok(()); } let caller_arg = caller_arg.next() - .ok_or_else(|| InterpError::FunctionArgCountMismatch)?; + .ok_or_else(|| InterpError::Unsupported(FunctionArgCountMismatch))?; if rust_abi { debug_assert!(!caller_arg.layout.is_zst(), "ZSTs must have been already filtered out"); } // Now, check if !Self::check_argument_compat(rust_abi, caller_arg.layout, callee_arg.layout) { - return err!(FunctionArgMismatch(caller_arg.layout.ty, callee_arg.layout.ty)); + return err!( + Unsupported(FunctionArgMismatch(caller_arg.layout.ty, callee_arg.layout.ty)) + ); } // We allow some transmutes here self.copy_op_transmute(caller_arg, callee_arg) @@ -254,13 +257,13 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { match instance.def { ty::InstanceDef::Intrinsic(..) => { if caller_abi != Abi::RustIntrinsic { - return err!(FunctionAbiMismatch(caller_abi, Abi::RustIntrinsic)); + return err!(Unsupported(FunctionAbiMismatch(caller_abi, Abi::RustIntrinsic))); } // The intrinsic itself cannot diverge, so if we got here without a return // place... (can happen e.g., for transmute returning `!`) let dest = match dest { Some(dest) => dest, - None => return err!(Unreachable) + None => return err!(UndefinedBehaviour(UndefinedBehaviourInfo::Unreachable)) }; M::call_intrinsic(self, instance, args, dest)?; // No stack frame gets pushed, the main loop will just act as if the @@ -295,7 +298,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { abi, }; if normalize_abi(caller_abi) != normalize_abi(callee_abi) { - return err!(FunctionAbiMismatch(caller_abi, callee_abi)); + return err!(Unsupported(FunctionAbiMismatch(caller_abi, callee_abi))); } } @@ -390,7 +393,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Now we should have no more caller args if caller_iter.next().is_some() { trace!("Caller has passed too many args"); - return err!(FunctionArgCountMismatch); + return err!(Unsupported(FunctionArgCountMismatch)); } // Don't forget to check the return type! if let Some(caller_ret) = dest { @@ -402,15 +405,15 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { caller_ret.layout, callee_ret.layout, ) { - return err!(FunctionRetMismatch( - caller_ret.layout.ty, callee_ret.layout.ty + return err!(Unsupported( + FunctionRetMismatch(caller_ret.layout.ty, callee_ret.layout.ty) )); } } else { let local = mir::RETURN_PLACE; let ty = self.frame().body.local_decls[local].ty; if !self.tcx.is_ty_uninhabited_from_any_module(ty) { - return err!(FunctionRetMismatch(self.tcx.types.never, ty)); + return err!(Unsupported(FunctionRetMismatch(self.tcx.types.never, ty))); } } Ok(()) diff --git a/src/librustc_mir/interpret/traits.rs b/src/librustc_mir/interpret/traits.rs index e7363f6876c28..677d6c89b38d5 100644 --- a/src/librustc_mir/interpret/traits.rs +++ b/src/librustc_mir/interpret/traits.rs @@ -1,6 +1,6 @@ use rustc::ty::{self, Ty, Instance}; use rustc::ty::layout::{Size, Align, LayoutOf}; -use rustc::mir::interpret::{Scalar, Pointer, InterpResult, PointerArithmetic}; +use rustc::mir::interpret::{Scalar, Pointer, InterpResult, PointerArithmetic, InvalidProgramInfo}; use super::{InterpCx, InterpError, Machine, MemoryKind, FnVal}; @@ -83,7 +83,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.param_env, def_id, substs, - ).ok_or_else(|| InterpError::TooGeneric)?; + ).ok_or_else(|| InterpError::InvalidProgram(InvalidProgramInfo::TooGeneric))?; let fn_ptr = self.memory.create_fn_alloc(FnVal::Instance(instance)); let method_ptr = vtable.offset(ptr_size * (3 + i as u64), self)?; self.memory diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs index da9780ac0a305..acbd2066d0e47 100644 --- a/src/librustc_mir/interpret/validity.rs +++ b/src/librustc_mir/interpret/validity.rs @@ -11,7 +11,7 @@ use std::hash::Hash; use super::{ GlobalAlloc, InterpResult, InterpError, - OpTy, Machine, InterpCx, ValueVisitor, MPlaceTy, + OpTy, Machine, InterpCx, ValueVisitor, MPlaceTy, UnsupportedInfo::*, }; macro_rules! validation_failure { @@ -22,10 +22,10 @@ macro_rules! validation_failure { } else { format!(" at {}", where_) }; - err!(ValidationFailure(format!( + err!(Unsupported(ValidationFailure(format!( "encountered {}{}, but expected {}", $what, where_, $details, - ))) + )))) }}; ($what:expr, $where:expr) => {{ let where_ = path_format(&$where); @@ -34,10 +34,10 @@ macro_rules! validation_failure { } else { format!(" at {}", where_) }; - err!(ValidationFailure(format!( + err!(Unsupported(ValidationFailure(format!( "encountered {}{}", $what, where_, - ))) + )))) }}; } @@ -297,11 +297,11 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> match self.walk_value(op) { Ok(()) => Ok(()), Err(err) => match err.kind { - InterpError::InvalidDiscriminant(val) => + InterpError::Unsupported(InvalidDiscriminant(val)) => validation_failure!( val, self.path, "a valid enum discriminant" ), - InterpError::ReadPointerAsBytes => + InterpError::Unsupported(ReadPointerAsBytes) => validation_failure!( "a pointer", self.path, "plain (non-pointer) bytes" ), @@ -406,13 +406,13 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> ptr, size, align ); match err.kind { - InterpError::InvalidNullPointerUsage => + InterpError::Unsupported(InvalidNullPointerUsage) => return validation_failure!("NULL reference", self.path), - InterpError::AlignmentCheckFailed { required, has } => + InterpError::Unsupported(AlignmentCheckFailed { required, has }) => return validation_failure!(format!("unaligned reference \ (required {} byte alignment but found {})", required.bytes(), has.bytes()), self.path), - InterpError::ReadBytesAsPointer => + InterpError::Unsupported(ReadBytesAsPointer) => return validation_failure!( "dangling reference (created from integer)", self.path @@ -608,7 +608,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> Err(err) => { // For some errors we might be able to provide extra information match err.kind { - InterpError::ReadUndefBytes(offset) => { + InterpError::Unsupported(ReadUndefBytes(offset)) => { // Some byte was undefined, determine which // element that byte belongs to so we can // provide an index. diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 7a2d78b2e986b..518489753a120 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -257,86 +257,20 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { Err(error) => { let diagnostic = error_to_const_error(&self.ecx, error); use rustc::mir::interpret::InterpError::*; + use rustc::mir::interpret::UnsupportedInfo::*; match diagnostic.error { - // don't report these, they make no sense in a const prop context - | MachineError(_) - | Exit(_) - // at runtime these transformations might make sense - // FIXME: figure out the rules and start linting - | FunctionAbiMismatch(..) - | FunctionArgMismatch(..) - | FunctionRetMismatch(..) - | FunctionArgCountMismatch - // fine at runtime, might be a register address or sth - | ReadBytesAsPointer - // fine at runtime - | ReadForeignStatic - | Unimplemented(_) - // don't report const evaluator limits - | StackFrameLimitReached - | NoMirFor(..) - | InlineAsm - => {}, - - | InvalidMemoryAccess - | DanglingPointerDeref - | DoubleFree - | InvalidFunctionPointer - | InvalidBool - | InvalidDiscriminant(..) - | PointerOutOfBounds { .. } - | InvalidNullPointerUsage - | ValidationFailure(..) - | InvalidPointerMath - | ReadUndefBytes(_) - | DeadLocal - | InvalidBoolOp(_) - | DerefFunctionPointer - | ExecuteMemory - | Intrinsic(..) - | InvalidChar(..) - | AbiViolation(_) - | AlignmentCheckFailed{..} - | CalledClosureAsFunction - | VtableForArgumentlessMethod - | ModifiedConstantMemory - | ModifiedStatic - | AssumptionNotHeld - // FIXME: should probably be removed and turned into a bug! call - | TypeNotPrimitive(_) - | ReallocatedWrongMemoryKind(_, _) - | DeallocatedWrongMemoryKind(_, _) - | ReallocateNonBasePtr - | DeallocateNonBasePtr - | IncorrectAllocationInformation(..) - | UnterminatedCString(_) - | HeapAllocZeroBytes - | HeapAllocNonPowerOfTwoAlignment(_) - | Unreachable - | ReadFromReturnPointer - | ReferencedConstant - | InfiniteLoop - => { - // FIXME: report UB here - }, + Exit(_) => {}, - | OutOfTls - | TlsOutOfBounds - | PathNotFound(_) + | Unsupported(OutOfTls) + | Unsupported(TlsOutOfBounds) + | Unsupported(PathNotFound(_)) => bug!("these should not be in rustc, but in miri's machine errors"), - | Layout(_) - | UnimplementedTraitSelection - | TypeckError - | TooGeneric - // these are just noise - => {}, - - // non deterministic - | ReadPointerAsBytes - // FIXME: implement - => {}, - + | Unsupported(_) => {}, + | UndefinedBehaviour(_) => {}, + | InvalidProgram(_) => {}, + | ResourceExhaustion(_) => {}, + | Panic(_) => { diagnostic.report_as_lint( From aa3d40cd7189b324afd20fbe3baffe76ea1a67a1 Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Sat, 27 Jul 2019 17:56:45 +0530 Subject: [PATCH 07/25] tidy fixes --- src/librustc_mir/interpret/operand.rs | 9 ++++++--- src/librustc_mir/transform/const_prop.rs | 1 - 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 3edc7748e5b04..3b89b50f1a41d 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -646,15 +646,18 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } => { let variants_start = niche_variants.start().as_u32() as u128; let variants_end = niche_variants.end().as_u32() as u128; - let raw_discr = raw_discr.not_undef() - .map_err(|_| InterpError::Unsupported(InvalidDiscriminant(ScalarMaybeUndef::Undef)))?; + let raw_discr = raw_discr.not_undef().map_err(|_| { + InterpError::Unsupported(InvalidDiscriminant(ScalarMaybeUndef::Undef)) + })?; match raw_discr.to_bits_or_ptr(discr_val.layout.size, self) { Err(ptr) => { // The niche must be just 0 (which an inbounds pointer value never is) let ptr_valid = niche_start == 0 && variants_start == variants_end && !self.memory.ptr_may_be_null(ptr); if !ptr_valid { - return err!(Unsupported(InvalidDiscriminant(raw_discr.erase_tag().into()))); + return err!(Unsupported(InvalidDiscriminant( + raw_discr.erase_tag().into() + ))); } (dataful_variant.as_u32() as u128, dataful_variant) }, diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 518489753a120..6a39839de45b3 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -270,7 +270,6 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { | UndefinedBehaviour(_) => {}, | InvalidProgram(_) => {}, | ResourceExhaustion(_) => {}, - | Panic(_) => { diagnostic.report_as_lint( From 9782b373b381906c57967b2854a3164de95ea88a Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Sun, 28 Jul 2019 20:07:33 +0530 Subject: [PATCH 08/25] implementing Debug for UnsupportedInfo --- src/librustc/mir/interpret/error.rs | 207 +++++++++++++++------------- 1 file changed, 108 insertions(+), 99 deletions(-) diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index c28582f1ab08d..e519a83c02667 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -425,171 +425,180 @@ pub enum UnsupportedInfo<'tcx> { PathNotFound(Vec), } -#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] -pub enum ResourceExhaustionInfo { - StackFrameLimitReached, - InfiniteLoop, -} - -impl fmt::Debug for ResourceExhaustionInfo { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - use ResourceExhaustionInfo::*; - match self { - StackFrameLimitReached => - write!(f, "reached the configured maximum number of stack frames"), - InfiniteLoop => - write!(f, "duplicate interpreter state observed here, const evaluation will never \ - terminate"), - } - } -} - -#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] -pub enum InterpError<'tcx> { - /// The program panicked. - Panic(PanicMessage), - /// The program caused undefined behavior. - UndefinedBehaviour(UndefinedBehaviourInfo), - /// The program did something the interpreter does not support (some of these *might* be UB - /// but the interpreter is not sure). - Unsupported(UnsupportedInfo<'tcx>), - /// The program was invalid (ill-typed, not sufficiently monomorphized, ...). - InvalidProgram(InvalidProgramInfo<'tcx>), - /// The program exhausted the interpreter's resources (stack/heap too big, - /// execution takes too long, ..). - ResourceExhaustion(ResourceExhaustionInfo), - /// Not actually an interpreter error -- used to signal that execution has exited - /// with the given status code. Used by Miri, but not by CTFE. - Exit(i32), -} - -pub type InterpResult<'tcx, T = ()> = Result>; - -impl fmt::Display for InterpError<'_> { +impl fmt::Debug for UnsupportedInfo<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - // Forward `Display` to `Debug` - write!(f, "{:?}", self) - } -} - -impl fmt::Debug for InterpError<'_> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - use InterpError::*; use UnsupportedInfo::*; - match *self { - Unsupported(PointerOutOfBounds { ptr, msg, allocation_size }) => { + match self { + PointerOutOfBounds { ptr, msg, allocation_size } => { write!(f, "{} failed: pointer must be in-bounds at offset {}, \ but is outside bounds of allocation {} which has size {}", msg, ptr.offset.bytes(), ptr.alloc_id, allocation_size.bytes()) }, - Unsupported(ValidationFailure(ref err)) => { + ValidationFailure(ref err) => { write!(f, "type validation failed: {}", err) } - Unsupported(NoMirFor(ref func)) => write!(f, "no mir for `{}`", func), - Unsupported(FunctionAbiMismatch(caller_abi, callee_abi)) => + NoMirFor(ref func) => write!(f, "no mir for `{}`", func), + FunctionAbiMismatch(caller_abi, callee_abi) => write!(f, "tried to call a function with ABI {:?} using caller ABI {:?}", callee_abi, caller_abi), - Unsupported(FunctionArgMismatch(caller_ty, callee_ty)) => + FunctionArgMismatch(caller_ty, callee_ty) => write!(f, "tried to call a function with argument of type {:?} \ passing data of type {:?}", callee_ty, caller_ty), - Unsupported(FunctionRetMismatch(caller_ty, callee_ty)) => + FunctionRetMismatch(caller_ty, callee_ty) => write!(f, "tried to call a function with return type {:?} \ passing return place of type {:?}", callee_ty, caller_ty), - Unsupported(FunctionArgCountMismatch) => + FunctionArgCountMismatch => write!(f, "tried to call a function with incorrect number of arguments"), - Unsupported(ReallocatedWrongMemoryKind(ref old, ref new)) => + ReallocatedWrongMemoryKind(ref old, ref new) => write!(f, "tried to reallocate memory from {} to {}", old, new), - Unsupported(DeallocatedWrongMemoryKind(ref old, ref new)) => + DeallocatedWrongMemoryKind(ref old, ref new) => write!(f, "tried to deallocate {} memory but gave {} as the kind", old, new), - Unsupported(InvalidChar(c)) => + InvalidChar(c) => write!(f, "tried to interpret an invalid 32-bit value as a char: {}", c), - Unsupported(AlignmentCheckFailed { required, has }) => + AlignmentCheckFailed { required, has } => write!(f, "tried to access memory with alignment {}, but alignment {} is required", has.bytes(), required.bytes()), - Unsupported(TypeNotPrimitive(ty)) => + TypeNotPrimitive(ty) => write!(f, "expected primitive type, got {}", ty), - Unsupported(PathNotFound(ref path)) => + PathNotFound(ref path) => write!(f, "Cannot find path {:?}", path), - Unsupported(IncorrectAllocationInformation(size, size2, align, align2)) => + IncorrectAllocationInformation(size, size2, align, align2) => write!(f, "incorrect alloc info: expected size {} and align {}, \ got size {} and align {}", size.bytes(), align.bytes(), size2.bytes(), align2.bytes()), - Unsupported(InvalidDiscriminant(val)) => + InvalidDiscriminant(val) => write!(f, "encountered invalid enum discriminant {}", val), - Unsupported(InvalidMemoryAccess) => + InvalidMemoryAccess => write!(f, "tried to access memory through an invalid pointer"), - Unsupported(DanglingPointerDeref) => + DanglingPointerDeref => write!(f, "dangling pointer was dereferenced"), - Unsupported(DoubleFree) => + DoubleFree => write!(f, "tried to deallocate dangling pointer"), - Unsupported(InvalidFunctionPointer) => + InvalidFunctionPointer => write!(f, "tried to use a function pointer after offsetting it"), - Unsupported(InvalidBool) => + InvalidBool => write!(f, "invalid boolean value read"), - Unsupported(InvalidNullPointerUsage) => + InvalidNullPointerUsage => write!(f, "invalid use of NULL pointer"), - Unsupported(ReadPointerAsBytes) => + ReadPointerAsBytes => write!(f, "a raw memory access tried to access part of a pointer value as raw \ bytes"), - Unsupported(ReadBytesAsPointer) => + ReadBytesAsPointer => write!(f, "a memory access tried to interpret some bytes as a pointer"), - Unsupported(ReadForeignStatic) => + ReadForeignStatic => write!(f, "tried to read from foreign (extern) static"), - Unsupported(InvalidPointerMath) => + InvalidPointerMath => write!(f, "attempted to do invalid arithmetic on pointers that would leak base \ addresses, e.g., comparing pointers into different allocations"), - Unsupported(DeadLocal) => + DeadLocal => write!(f, "tried to access a dead local variable"), - Unsupported(DerefFunctionPointer) => + DerefFunctionPointer => write!(f, "tried to dereference a function pointer"), - Unsupported(ExecuteMemory) => + ExecuteMemory => write!(f, "tried to treat a memory pointer as a function pointer"), - Unsupported(OutOfTls) => + OutOfTls => write!(f, "reached the maximum number of representable TLS keys"), - Unsupported(TlsOutOfBounds) => + TlsOutOfBounds => write!(f, "accessed an invalid (unallocated) TLS key"), - Unsupported(CalledClosureAsFunction) => + CalledClosureAsFunction => write!(f, "tried to call a closure through a function pointer"), - Unsupported(VtableForArgumentlessMethod) => + VtableForArgumentlessMethod => write!(f, "tried to call a vtable function without arguments"), - Unsupported(ModifiedConstantMemory) => + ModifiedConstantMemory => write!(f, "tried to modify constant memory"), - Unsupported(ModifiedStatic) => + ModifiedStatic => write!(f, "tried to modify a static's initial value from another static's \ initializer"), - Unsupported(AssumptionNotHeld) => + AssumptionNotHeld => write!(f, "`assume` argument was false"), - Unsupported(InlineAsm) => + InlineAsm => write!(f, "miri does not support inline assembly"), - Unsupported(ReallocateNonBasePtr) => + ReallocateNonBasePtr => write!(f, "tried to reallocate with a pointer not to the beginning of an \ existing object"), - Unsupported(DeallocateNonBasePtr) => + DeallocateNonBasePtr => write!(f, "tried to deallocate with a pointer not to the beginning of an \ existing object"), - Unsupported(HeapAllocZeroBytes) => + HeapAllocZeroBytes => write!(f, "tried to re-, de- or allocate zero bytes on the heap"), - Unsupported(ReadFromReturnPointer) => + ReadFromReturnPointer => write!(f, "tried to read from the return pointer"), - Unsupported(UnimplementedTraitSelection) => + UnimplementedTraitSelection => write!(f, "there were unresolved type arguments during trait selection"), - Unsupported(InvalidBoolOp(_)) => + InvalidBoolOp(_) => write!(f, "invalid boolean operation"), - Unsupported(UnterminatedCString(_)) => + UnterminatedCString(_) => write!(f, "attempted to get length of a null terminated string, but no null \ found before end of allocation"), - Unsupported(ReadUndefBytes(_)) => + ReadUndefBytes(_) => write!(f, "attempted to read undefined bytes"), - Unsupported(HeapAllocNonPowerOfTwoAlignment(_)) => + HeapAllocNonPowerOfTwoAlignment(_) => write!(f, "tried to re-, de-, or allocate heap memory with alignment that is \ not a power of two"), - Unsupported(MachineError(ref msg)) | - Unsupported(Unimplemented(ref msg)) | - Unsupported(AbiViolation(ref msg)) | - Unsupported(Intrinsic(ref msg)) => + MachineError(ref msg) | + Unimplemented(ref msg) | + AbiViolation(ref msg) | + Intrinsic(ref msg) => write!(f, "{}", msg), + } + } +} + +#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] +pub enum ResourceExhaustionInfo { + StackFrameLimitReached, + InfiniteLoop, +} + +impl fmt::Debug for ResourceExhaustionInfo { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + use ResourceExhaustionInfo::*; + match self { + StackFrameLimitReached => + write!(f, "reached the configured maximum number of stack frames"), + InfiniteLoop => + write!(f, "duplicate interpreter state observed here, const evaluation will never \ + terminate"), + } + } +} + +#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] +pub enum InterpError<'tcx> { + /// The program panicked. + Panic(PanicMessage), + /// The program caused undefined behavior. + UndefinedBehaviour(UndefinedBehaviourInfo), + /// The program did something the interpreter does not support (some of these *might* be UB + /// but the interpreter is not sure). + Unsupported(UnsupportedInfo<'tcx>), + /// The program was invalid (ill-typed, not sufficiently monomorphized, ...). + InvalidProgram(InvalidProgramInfo<'tcx>), + /// The program exhausted the interpreter's resources (stack/heap too big, + /// execution takes too long, ..). + ResourceExhaustion(ResourceExhaustionInfo), + /// Not actually an interpreter error -- used to signal that execution has exited + /// with the given status code. Used by Miri, but not by CTFE. + Exit(i32), +} + +pub type InterpResult<'tcx, T = ()> = Result>; + +impl fmt::Display for InterpError<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // Forward `Display` to `Debug` + write!(f, "{:?}", self) + } +} + +impl fmt::Debug for InterpError<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + use InterpError::*; + match *self { + Unsupported(ref msg) => + write!(f, "{:?}", msg), InvalidProgram(ref msg) => write!(f, "{:?}", msg), UndefinedBehaviour(ref msg) => From 8e9d0faff28cff0290d76c2cda175bb8a79b293b Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Mon, 29 Jul 2019 13:06:42 +0530 Subject: [PATCH 09/25] adding a err macro for each of the InterpError variants --- src/librustc/mir/interpret/allocation.rs | 7 ++- src/librustc/mir/interpret/mod.rs | 42 ++++++++++++++++- src/librustc/mir/interpret/pointer.rs | 15 ++---- src/librustc/mir/interpret/value.rs | 13 +++--- src/librustc_mir/const_eval.rs | 6 +-- src/librustc_mir/interpret/cast.rs | 4 +- src/librustc_mir/interpret/eval_context.rs | 21 ++++----- src/librustc_mir/interpret/intern.rs | 4 +- src/librustc_mir/interpret/intrinsics.rs | 8 ++-- src/librustc_mir/interpret/machine.rs | 2 +- src/librustc_mir/interpret/memory.rs | 53 ++++++++++------------ src/librustc_mir/interpret/operand.rs | 12 ++--- src/librustc_mir/interpret/operator.rs | 16 +++---- src/librustc_mir/interpret/place.rs | 7 ++- src/librustc_mir/interpret/step.rs | 4 +- src/librustc_mir/interpret/terminator.rs | 40 ++++++++-------- src/librustc_mir/interpret/validity.rs | 8 ++-- src/librustc_mir/transform/const_prop.rs | 2 +- 18 files changed, 140 insertions(+), 124 deletions(-) diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs index b5ec30c9212f3..51b2d0272a597 100644 --- a/src/librustc/mir/interpret/allocation.rs +++ b/src/librustc/mir/interpret/allocation.rs @@ -4,7 +4,6 @@ use super::{ Pointer, InterpResult, AllocId, ScalarMaybeUndef, write_target_uint, read_target_uint, Scalar, }; -use super::error::UnsupportedInfo::*; use crate::ty::layout::{Size, Align}; use syntax::ast::Mutability; use std::iter; @@ -245,7 +244,7 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra> Allocation { Ok(&self.get_bytes(cx, ptr, size_with_null)?[..size]) } // This includes the case where `offset` is out-of-bounds to begin with. - None => err!(Unsupported(UnterminatedCString(ptr.erase_tag()))), + None => err!(UnterminatedCString(ptr.erase_tag())), } } @@ -447,7 +446,7 @@ impl<'tcx, Tag: Copy, Extra> Allocation { if self.relocations(cx, ptr, size).is_empty() { Ok(()) } else { - err!(Unsupported(ReadPointerAsBytes)) + err!(ReadPointerAsBytes) } } @@ -517,7 +516,7 @@ impl<'tcx, Tag, Extra> Allocation { self.undef_mask.is_range_defined( ptr.offset, ptr.offset + size, - ).or_else(|idx| err!(Unsupported(ReadUndefBytes(idx)))) + ).or_else(|idx| err!(ReadUndefBytes(idx))) } pub fn mark_definedness( diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs index ceed59885b275..c4a3bbfc28b18 100644 --- a/src/librustc/mir/interpret/mod.rs +++ b/src/librustc/mir/interpret/mod.rs @@ -2,7 +2,47 @@ #[macro_export] macro_rules! err { - ($($tt:tt)*) => { Err($crate::mir::interpret::InterpError::$($tt)*.into()) }; + ($($tt:tt)*) => { + Err($crate::mir::interpret::InterpError::Unsupported( + $crate::mir::interpret::UnsupportedInfo::$($tt)* + ).into()) + }; +} + +#[macro_export] +macro_rules! err_inval { + ($($tt:tt)*) => { + Err($crate::mir::interpret::InterpError::InvalidProgram( + $crate::mir::interpret::InvalidProgramInfo::$($tt)* + ).into()) + }; +} + +#[macro_export] +macro_rules! err_ub { + ($($tt:tt)*) => { + Err($crate::mir::interpret::InterpError::UndefinedBehaviour( + $crate::mir::interpret::UndefinedBehaviourInfo::$($tt)* + ).into()) + }; +} + +#[macro_export] +macro_rules! err_panic { + ($($tt:tt)*) => { + Err($crate::mir::interpret::InterpError::Panic( + $crate::mir::interpret::PanicMessage::$($tt)* + ).into()) + }; +} + +#[macro_export] +macro_rules! err_exhaust { + ($($tt:tt)*) => { + Err($crate::mir::interpret::InterpError::ResourceExhaustion( + $crate::mir::interpret::ResourceExhaustionInfo::$($tt)* + ).into()) + }; } mod error; diff --git a/src/librustc/mir/interpret/pointer.rs b/src/librustc/mir/interpret/pointer.rs index afbe1ed9a9395..faca04412402e 100644 --- a/src/librustc/mir/interpret/pointer.rs +++ b/src/librustc/mir/interpret/pointer.rs @@ -1,13 +1,10 @@ use std::fmt::{self, Display}; -use super::error::UnsupportedInfo::*; use crate::mir; use crate::ty::layout::{self, HasDataLayout, Size}; use rustc_macros::HashStable; -use super::{ - AllocId, InterpResult, PanicMessage -}; +use super::{AllocId, InterpResult}; /// Used by `check_in_alloc` to indicate context of check #[derive(Debug, Copy, Clone, RustcEncodable, RustcDecodable, HashStable)] @@ -77,13 +74,13 @@ pub trait PointerArithmetic: layout::HasDataLayout { #[inline] fn offset<'tcx>(&self, val: u64, i: u64) -> InterpResult<'tcx, u64> { let (res, over) = self.overflowing_offset(val, i); - if over { err!(Panic(PanicMessage::Overflow(mir::BinOp::Add))) } else { Ok(res) } + if over { err_panic!(Overflow(mir::BinOp::Add)) } else { Ok(res) } } #[inline] fn signed_offset<'tcx>(&self, val: u64, i: i64) -> InterpResult<'tcx, u64> { let (res, over) = self.overflowing_signed_offset(val, i128::from(i)); - if over { err!(Panic(PanicMessage::Overflow(mir::BinOp::Add))) } else { Ok(res) } + if over { err_panic!(Overflow(mir::BinOp::Add)) } else { Ok(res) } } } @@ -199,11 +196,7 @@ impl<'tcx, Tag> Pointer { msg: CheckInAllocMsg, ) -> InterpResult<'tcx, ()> { if self.offset > allocation_size { - err!(Unsupported(PointerOutOfBounds { - ptr: self.erase_tag(), - msg, - allocation_size, - })) + err!(PointerOutOfBounds { ptr: self.erase_tag(),msg,allocation_size }) } else { Ok(()) } diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs index 29bf94292ef86..4a59d845b3b42 100644 --- a/src/librustc/mir/interpret/value.rs +++ b/src/librustc/mir/interpret/value.rs @@ -2,7 +2,6 @@ use std::fmt; use rustc_macros::HashStable; use rustc_apfloat::{Float, ieee::{Double, Single}}; -use super::error::UnsupportedInfo::*; use crate::ty::{Ty, InferConst, ParamConst, layout::{HasDataLayout, Size, Align}, subst::SubstsRef}; use crate::ty::PlaceholderConst; use crate::hir::def_id::DefId; @@ -361,7 +360,7 @@ impl<'tcx, Tag> Scalar { Scalar::check_data(data, size); Ok(data) } - Scalar::Ptr(_) => err!(Unsupported(ReadPointerAsBytes)), + Scalar::Ptr(_) => err!(ReadPointerAsBytes), } } @@ -374,8 +373,8 @@ impl<'tcx, Tag> Scalar { #[inline] pub fn to_ptr(self) -> InterpResult<'tcx, Pointer> { match self { - Scalar::Raw { data: 0, .. } => err!(Unsupported(InvalidNullPointerUsage)), - Scalar::Raw { .. } => err!(Unsupported(ReadBytesAsPointer)), + Scalar::Raw { data: 0, .. } => err!(InvalidNullPointerUsage), + Scalar::Raw { .. } => err!(ReadBytesAsPointer), Scalar::Ptr(p) => Ok(p), } } @@ -407,7 +406,7 @@ impl<'tcx, Tag> Scalar { match self { Scalar::Raw { data: 0, size: 1 } => Ok(false), Scalar::Raw { data: 1, size: 1 } => Ok(true), - _ => err!(Unsupported(InvalidBool)), + _ => err!(InvalidBool), } } @@ -415,7 +414,7 @@ impl<'tcx, Tag> Scalar { let val = self.to_u32()?; match ::std::char::from_u32(val) { Some(c) => Ok(c), - None => err!(Unsupported(InvalidChar(val as u128))), + None => err!(InvalidChar(val as u128)), } } @@ -538,7 +537,7 @@ impl<'tcx, Tag> ScalarMaybeUndef { pub fn not_undef(self) -> InterpResult<'static, Scalar> { match self { ScalarMaybeUndef::Scalar(scalar) => Ok(scalar), - ScalarMaybeUndef::Undef => err!(Unsupported(ReadUndefBytes(Size::from_bytes(0)))), + ScalarMaybeUndef::Undef => err!(ReadUndefBytes(Size::from_bytes(0))), } } diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 60381e0365fae..bbee3b392345e 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -353,9 +353,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, ecx.goto_block(ret)?; // fully evaluated and done Ok(None) } else { - err!(Unsupported( - MachineError(format!("calling non-const function `{}`", instance)) - )) + err!(MachineError(format!("calling non-const function `{}`", instance))) }; } } @@ -415,7 +413,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, _tcx: TyCtxt<'tcx>, _def_id: DefId, ) -> InterpResult<'tcx, Cow<'tcx, Allocation>> { - err!(Unsupported(ReadForeignStatic)) + err!(ReadForeignStatic) } #[inline(always)] diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs index 443d264b351f7..7157e714f0522 100644 --- a/src/librustc_mir/interpret/cast.rs +++ b/src/librustc_mir/interpret/cast.rs @@ -9,7 +9,7 @@ use rustc_apfloat::{Float, FloatConvert}; use rustc::mir::interpret::{ Scalar, InterpResult, Pointer, PointerArithmetic, InterpError, }; -use rustc::mir::{CastKind, interpret::{UnsupportedInfo::*, InvalidProgramInfo::*}}; +use rustc::mir::{CastKind, interpret::{InvalidProgramInfo::*}}; use super::{InterpCx, Machine, PlaceTy, OpTy, Immediate, FnVal}; @@ -200,7 +200,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { }, // Casts to bool are not permitted by rustc, no need to handle them here. - _ => err!(Unsupported(Unimplemented(format!("int to {:?} cast", dest_layout.ty)))), + _ => err!(Unimplemented(format!("int to {:?} cast", dest_layout.ty))), } } diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index e732484b9b7bc..1ee6871f5efc7 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -17,8 +17,7 @@ use rustc::mir::interpret::{ ErrorHandled, GlobalId, Scalar, Pointer, FrameInfo, AllocId, InterpResult, InterpError, - truncate, sign_extend, UnsupportedInfo::*, InvalidProgramInfo::*, - ResourceExhaustionInfo::*, UndefinedBehaviourInfo::*, + truncate, sign_extend, InvalidProgramInfo::*, }; use rustc_data_structures::fx::FxHashMap; @@ -136,7 +135,7 @@ pub enum LocalValue { impl<'tcx, Tag: Copy + 'static> LocalState<'tcx, Tag> { pub fn access(&self) -> InterpResult<'tcx, Operand> { match self.value { - LocalValue::Dead => err!(Unsupported(DeadLocal)), + LocalValue::Dead => err!(DeadLocal), LocalValue::Uninitialized => bug!("The type checker should prevent reading from a never-written local"), LocalValue::Live(val) => Ok(val), @@ -149,7 +148,7 @@ impl<'tcx, Tag: Copy + 'static> LocalState<'tcx, Tag> { &mut self, ) -> InterpResult<'tcx, Result<&mut LocalValue, MemPlace>> { match self.value { - LocalValue::Dead => err!(Unsupported(DeadLocal)), + LocalValue::Dead => err!(DeadLocal), LocalValue::Live(Operand::Indirect(mplace)) => Ok(Err(mplace)), ref mut local @ LocalValue::Live(Operand::Immediate(_)) | ref mut local @ LocalValue::Uninitialized => { @@ -303,7 +302,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { &substs, )), None => if substs.needs_subst() { - err!(InvalidProgram(TooGeneric)).into() + err_inval!(TooGeneric).into() } else { Ok(substs) }, @@ -337,14 +336,14 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { && self.tcx.has_typeck_tables(did) && self.tcx.typeck_tables_of(did).tainted_by_errors { - return err!(InvalidProgram(TypeckError)); + return err_inval!(TypeckError); } trace!("load mir {:?}", instance); match instance { ty::InstanceDef::Item(def_id) => if self.tcx.is_mir_available(did) { Ok(self.tcx.optimized_mir(did)) } else { - err!(Unsupported(NoMirFor(self.tcx.def_path_str(def_id)))) + err!(NoMirFor(self.tcx.def_path_str(def_id))) }, _ => Ok(self.tcx.instance_mir(instance)), } @@ -357,7 +356,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { match self.stack.last() { Some(frame) => Ok(self.monomorphize_with_substs(t, frame.instance.substs)?), None => if t.needs_subst() { - err!(InvalidProgram(TooGeneric)).into() + err_inval!(TooGeneric).into() } else { Ok(t) }, @@ -374,7 +373,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let substituted = t.subst(*self.tcx, substs); if substituted.needs_subst() { - return err!(InvalidProgram(TooGeneric)); + return err_inval!(TooGeneric); } Ok(self.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), substituted)) @@ -573,7 +572,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { info!("ENTERING({}) {}", self.cur_frame(), self.frame().instance); if self.stack.len() > self.tcx.sess.const_eval_stack_frame_limit { - err!(ResourceExhaustion(StackFrameLimitReached)) + err_exhaust!(StackFrameLimitReached) } else { Ok(()) } @@ -621,7 +620,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } } else { // Uh, that shouldn't happen... the function did not intend to return - return err!(UndefinedBehaviour(Unreachable)); + return err_ub!(Unreachable); } // Jump to new block -- *after* validation so that the spans make more sense. match frame.return_to_block { diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs index f1e6132132c0b..261cfbce17144 100644 --- a/src/librustc_mir/interpret/intern.rs +++ b/src/librustc_mir/interpret/intern.rs @@ -328,9 +328,7 @@ pub fn intern_const_alloc_recursive( } } else if ecx.memory().dead_alloc_map.contains_key(&alloc_id) { // dangling pointer - return err!(Unsupported(ValidationFailure( - "encountered dangling pointer in final constant".into(), - ))) + return err!(ValidationFailure("encountered dangling pointer in final constant".into())) } } Ok(()) diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index 880984ed88cef..f943ff67c0858 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -104,9 +104,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { }; let out_val = if intrinsic_name.ends_with("_nonzero") { if bits == 0 { - return err!( - Unsupported(Intrinsic(format!("{} called on 0", intrinsic_name))) - ); + return err!(Intrinsic(format!("{} called on 0", intrinsic_name))); } numeric_intrinsic(intrinsic_name.trim_end_matches("_nonzero"), bits, kind)? } else { @@ -192,9 +190,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { if overflowed { let layout = self.layout_of(substs.type_at(0))?; let r_val = r.to_scalar()?.to_bits(layout.size)?; - return err!(Unsupported(Intrinsic( + return err!(Intrinsic( format!("Overflowing shift by {} in {}", r_val, intrinsic_name), - ))); + )); } self.write_scalar(val, dest)?; } diff --git a/src/librustc_mir/interpret/machine.rs b/src/librustc_mir/interpret/machine.rs index c40f80940688c..4f04803addd8b 100644 --- a/src/librustc_mir/interpret/machine.rs +++ b/src/librustc_mir/interpret/machine.rs @@ -251,6 +251,6 @@ pub trait Machine<'mir, 'tcx>: Sized { _mem: &Memory<'mir, 'tcx, Self>, _ptr: Pointer, ) -> InterpResult<'tcx, u64> { - err!(Unsupported(ReadPointerAsBytes)) + err!(ReadPointerAsBytes) } } diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 74da59182c145..72feb73f751a4 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -67,9 +67,9 @@ impl<'tcx, Other> FnVal<'tcx, Other> { match self { FnVal::Instance(instance) => Ok(instance), - FnVal::Other(_) => err!(Unsupported(MachineError(format!( + FnVal::Other(_) => err!(MachineError(format!( "Expected instance function pointer, got 'other' pointer" - )))), + ))), } } } @@ -203,7 +203,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { kind: MemoryKind, ) -> InterpResult<'tcx, Pointer> { if ptr.offset.bytes() != 0 { - return err!(Unsupported(ReallocateNonBasePtr)); + return err!(ReallocateNonBasePtr); } // For simplicities' sake, we implement reallocate as "alloc, copy, dealloc". @@ -244,7 +244,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { trace!("deallocating: {}", ptr.alloc_id); if ptr.offset.bytes() != 0 { - return err!(Unsupported(DeallocateNonBasePtr)); + return err!(DeallocateNonBasePtr); } let (alloc_kind, mut alloc) = match self.alloc_map.remove(&ptr.alloc_id) { @@ -252,33 +252,30 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { None => { // Deallocating static memory -- always an error return match self.tcx.alloc_map.lock().get(ptr.alloc_id) { - Some(GlobalAlloc::Function(..)) => err!(Unsupported(DeallocatedWrongMemoryKind( + Some(GlobalAlloc::Function(..)) => err!(DeallocatedWrongMemoryKind( "function".to_string(), format!("{:?}", kind), - ))), + )), Some(GlobalAlloc::Static(..)) | - Some(GlobalAlloc::Memory(..)) => err!(Unsupported(DeallocatedWrongMemoryKind( + Some(GlobalAlloc::Memory(..)) => err!(DeallocatedWrongMemoryKind( "static".to_string(), format!("{:?}", kind), - ))), - None => err!(Unsupported(DoubleFree)) + )), + None => err!(DoubleFree) } } }; if alloc_kind != kind { - return err!(Unsupported(DeallocatedWrongMemoryKind( + return err!(DeallocatedWrongMemoryKind( format!("{:?}", alloc_kind), format!("{:?}", kind), - ))); + )); } if let Some((size, align)) = old_size_and_align { if size.bytes() != alloc.bytes.len() as u64 || align != alloc.align { let bytes = Size::from_bytes(alloc.bytes.len() as u64); - return err!(Unsupported(IncorrectAllocationInformation(size, - bytes, - align, - alloc.align))); + return err!(IncorrectAllocationInformation(size, bytes, align, alloc.align)); } } @@ -323,10 +320,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { } else { // The biggest power of two through which `offset` is divisible. let offset_pow2 = 1 << offset.trailing_zeros(); - err!(Unsupported(AlignmentCheckFailed { + err!(AlignmentCheckFailed { has: Align::from_bytes(offset_pow2).unwrap(), required: align, - })) + }) } } @@ -345,7 +342,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { assert!(size.bytes() == 0); // Must be non-NULL and aligned. if bits == 0 { - return err!(Unsupported(InvalidNullPointerUsage)); + return err!(InvalidNullPointerUsage); } check_offset_align(bits, align)?; None @@ -366,10 +363,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { // got picked we might be aligned even if this check fails. // We instead have to fall back to converting to an integer and checking // the "real" alignment. - return err!(Unsupported(AlignmentCheckFailed { + return err!(AlignmentCheckFailed { has: alloc_align, required: align, - })); + }); } check_offset_align(ptr.offset.bytes(), align)?; @@ -417,9 +414,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { Some(GlobalAlloc::Memory(mem)) => Cow::Borrowed(mem), Some(GlobalAlloc::Function(..)) => - return err!(Unsupported(DerefFunctionPointer)), + return err!(DerefFunctionPointer), None => - return err!(Unsupported(DanglingPointerDeref)), + return err!(DanglingPointerDeref), Some(GlobalAlloc::Static(def_id)) => { // We got a "lazy" static that has not been computed yet. if tcx.is_foreign_item(def_id) { @@ -507,11 +504,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { // to give us a cheap reference. let alloc = Self::get_static_alloc(memory_extra, tcx, id)?; if alloc.mutability == Mutability::Immutable { - return err!(Unsupported(ModifiedConstantMemory)); + return err!(ModifiedConstantMemory); } match M::STATIC_KIND { Some(kind) => Ok((MemoryKind::Machine(kind), alloc.into_owned())), - None => err!(Unsupported(ModifiedStatic)), + None => err!(ModifiedStatic), } }); // Unpack the error type manually because type inference doesn't @@ -521,7 +518,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { Ok(a) => { let a = &mut a.1; if a.mutability == Mutability::Immutable { - return err!(Unsupported(ModifiedConstantMemory)); + return err!(ModifiedConstantMemory); } Ok(a) } @@ -604,7 +601,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { ) -> InterpResult<'tcx, FnVal<'tcx, M::ExtraFnVal>> { let ptr = self.force_ptr(ptr)?; // We definitely need a pointer value. if ptr.offset.bytes() != 0 { - return err!(Unsupported(InvalidFunctionPointer)); + return err!(InvalidFunctionPointer); } self.get_fn_alloc(ptr.alloc_id) } @@ -839,9 +836,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { if (src.offset <= dest.offset && src.offset + size > dest.offset) || (dest.offset <= src.offset && dest.offset + size > src.offset) { - return err!(Unsupported(Intrinsic( + return err!(Intrinsic( "copy_nonoverlapping called on overlapping ranges".to_string(), - ))); + )); } } diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 3b89b50f1a41d..1896c3cda13d6 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -12,7 +12,7 @@ use rustc::mir::interpret::{ GlobalId, AllocId, ConstValue, Pointer, Scalar, InterpResult, InterpError, - sign_extend, truncate, UnsupportedInfo::*, InvalidProgramInfo::* + sign_extend, truncate, UnsupportedInfo::*, }; use super::{ InterpCx, Machine, @@ -460,7 +460,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { mir_place.iterate(|place_base, place_projection| { let mut op = match place_base { PlaceBase::Local(mir::RETURN_PLACE) => - return err!(Unsupported(ReadFromReturnPointer)), + return err!(ReadFromReturnPointer), PlaceBase::Local(local) => { // Do not use the layout passed in as argument if the base we are looking at // here is not the entire place. @@ -533,7 +533,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { match val.val { ConstValue::Param(_) => // FIXME(oli-obk): try to monomorphize - return err!(InvalidProgram(TooGeneric)), + return err_inval!(TooGeneric), ConstValue::Unevaluated(def_id, substs) => { let instance = self.resolve(def_id, substs)?; return Ok(OpTy::from(self.const_eval_raw(GlobalId { @@ -608,7 +608,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let bits_discr = match raw_discr.to_bits(discr_val.layout.size) { Ok(raw_discr) => raw_discr, Err(_) => - return err!(Unsupported(InvalidDiscriminant(raw_discr.erase_tag()))), + return err!(InvalidDiscriminant(raw_discr.erase_tag())), }; let real_discr = if discr_val.layout.ty.is_signed() { // going from layout tag type to typeck discriminant type @@ -655,9 +655,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let ptr_valid = niche_start == 0 && variants_start == variants_end && !self.memory.ptr_may_be_null(ptr); if !ptr_valid { - return err!(Unsupported(InvalidDiscriminant( - raw_discr.erase_tag().into() - ))); + return err!(InvalidDiscriminant(raw_discr.erase_tag().into())); } (dataful_variant.as_u32() as u128, dataful_variant) }, diff --git a/src/librustc_mir/interpret/operator.rs b/src/librustc_mir/interpret/operator.rs index 8af4c71299d21..eecb752e72be2 100644 --- a/src/librustc_mir/interpret/operator.rs +++ b/src/librustc_mir/interpret/operator.rs @@ -2,9 +2,9 @@ use rustc::mir; use rustc::ty::{self, layout::TyLayout}; use syntax::ast::FloatTy; use rustc_apfloat::Float; -use rustc::mir::interpret::{InterpResult, PanicMessage, Scalar}; +use rustc::mir::interpret::{InterpResult, Scalar}; -use super::{InterpCx, PlaceTy, Immediate, Machine, ImmTy, UnsupportedInfo::*}; +use super::{InterpCx, PlaceTy, Immediate, Machine, ImmTy}; impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { @@ -155,7 +155,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { r, right_layout.ty ); - return err!(Unsupported(Unimplemented(msg))); + return err!(Unimplemented(msg)); } // Operations that need special treatment for signed integers @@ -173,8 +173,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { return Ok((Scalar::from_bool(op(&l, &r)), false)); } let op: Option (i128, bool)> = match bin_op { - Div if r == 0 => return err!(Panic(PanicMessage::DivisionByZero)), - Rem if r == 0 => return err!(Panic(PanicMessage::RemainderByZero)), + Div if r == 0 => return err_panic!(DivisionByZero), + Rem if r == 0 => return err_panic!(RemainderByZero), Div => Some(i128::overflowing_div), Rem => Some(i128::overflowing_rem), Add => Some(i128::overflowing_add), @@ -231,8 +231,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Add => u128::overflowing_add, Sub => u128::overflowing_sub, Mul => u128::overflowing_mul, - Div if r == 0 => return err!(Panic(PanicMessage::DivisionByZero)), - Rem if r == 0 => return err!(Panic(PanicMessage::RemainderByZero)), + Div if r == 0 => return err_panic!(DivisionByZero), + Rem if r == 0 => return err_panic!(RemainderByZero), Div => u128::overflowing_div, Rem => u128::overflowing_rem, _ => bug!(), @@ -250,7 +250,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { r, right_layout.ty, ); - return err!(Unsupported(Unimplemented(msg))); + return err!(Unimplemented(msg)); } }; diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 65e70b7bedc70..75e3f70aebb31 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -13,9 +13,8 @@ use rustc::ty::TypeFoldable; use super::{ GlobalId, AllocId, Allocation, Scalar, InterpResult, Pointer, PointerArithmetic, - InterpCx, Machine, AllocMap, AllocationExtra, PanicMessage, + InterpCx, Machine, AllocMap, AllocationExtra, RawConst, Immediate, ImmTy, ScalarMaybeUndef, Operand, OpTy, MemoryKind, LocalValue, - UnsupportedInfo::*, }; #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] @@ -357,7 +356,7 @@ where // This can be violated because this runs during promotion on code where the // type system has not yet ensured that such things don't happen. debug!("tried to access element {} of array/slice with length {}", field, len); - return err!(Panic(PanicMessage::BoundsCheck { len, index: field })); + return err_panic!(BoundsCheck { len, index: field }); } stride * field } @@ -623,7 +622,7 @@ where .layout_of(self.monomorphize(self.frame().body.return_ty())?)?, } } - None => return err!(Unsupported(InvalidNullPointerUsage)), + None => return err!(InvalidNullPointerUsage), }, PlaceBase::Local(local) => PlaceTy { // This works even for dead/uninitialized locals; we check further when writing diff --git a/src/librustc_mir/interpret/step.rs b/src/librustc_mir/interpret/step.rs index 24aa5489e528a..246c90ba48e3a 100644 --- a/src/librustc_mir/interpret/step.rs +++ b/src/librustc_mir/interpret/step.rs @@ -4,7 +4,7 @@ use rustc::mir; use rustc::ty::layout::LayoutOf; -use rustc::mir::interpret::{InterpResult, Scalar, PointerArithmetic, UnsupportedInfo}; +use rustc::mir::interpret::{InterpResult, Scalar, PointerArithmetic}; use super::{InterpCx, Machine}; @@ -121,7 +121,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // size of MIR constantly. Nop => {} - InlineAsm { .. } => return err!(Unsupported(UnsupportedInfo::InlineAsm)), + InlineAsm { .. } => return err!(InlineAsm), } self.stack[frame_idx].stmt += 1; diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs index cfb901d380ea0..b7dbc8384586e 100644 --- a/src/librustc_mir/interpret/terminator.rs +++ b/src/librustc_mir/interpret/terminator.rs @@ -9,7 +9,7 @@ use rustc_target::spec::abi::Abi; use super::{ InterpResult, PointerArithmetic, InterpError, Scalar, InterpCx, Machine, Immediate, OpTy, ImmTy, PlaceTy, MPlaceTy, StackPopCleanup, FnVal, - UndefinedBehaviourInfo, UnsupportedInfo::*, + UnsupportedInfo::*, }; impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { @@ -20,7 +20,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.frame_mut().stmt = 0; Ok(()) } else { - err!(UndefinedBehaviour(UndefinedBehaviourInfo::Unreachable)) + err_ub!(Unreachable) } } @@ -90,7 +90,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { }, _ => { let msg = format!("can't handle callee of type {:?}", func.layout.ty); - return err!(Unsupported(Unimplemented(msg))); + return err!(Unimplemented(msg)); } }; let args = self.eval_operands(args)?; @@ -145,20 +145,20 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let index = self.read_immediate(self.eval_operand(index, None)?) .expect("can't eval index").to_scalar()? .to_bits(self.memory().pointer_size())? as u64; - err!(Panic(BoundsCheck { len, index })) + err_panic!(BoundsCheck { len, index }) } Overflow(op) => - err!(Panic(Overflow(*op))), + err_panic!(Overflow(*op)), OverflowNeg => - err!(Panic(OverflowNeg)), + err_panic!(OverflowNeg), DivisionByZero => - err!(Panic(DivisionByZero)), + err_panic!(DivisionByZero), RemainderByZero => - err!(Panic(RemainderByZero)), + err_panic!(RemainderByZero), GeneratorResumedAfterReturn => - err!(Panic(GeneratorResumedAfterReturn)), + err_panic!(GeneratorResumedAfterReturn), GeneratorResumedAfterPanic => - err!(Panic(GeneratorResumedAfterPanic)), + err_panic!(GeneratorResumedAfterPanic), Panic { .. } => bug!("`Panic` variant cannot occur in MIR"), }; @@ -174,7 +174,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { `simplify_branches` mir pass"), FalseUnwind { .. } => bug!("should have been eliminated by\ `simplify_branches` mir pass"), - Unreachable => return err!(UndefinedBehaviour(UndefinedBehaviourInfo::Unreachable)), + Unreachable => return err_ub!(Unreachable), } Ok(()) @@ -227,9 +227,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } // Now, check if !Self::check_argument_compat(rust_abi, caller_arg.layout, callee_arg.layout) { - return err!( - Unsupported(FunctionArgMismatch(caller_arg.layout.ty, callee_arg.layout.ty)) - ); + return err!(FunctionArgMismatch(caller_arg.layout.ty, callee_arg.layout.ty)); } // We allow some transmutes here self.copy_op_transmute(caller_arg, callee_arg) @@ -257,13 +255,13 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { match instance.def { ty::InstanceDef::Intrinsic(..) => { if caller_abi != Abi::RustIntrinsic { - return err!(Unsupported(FunctionAbiMismatch(caller_abi, Abi::RustIntrinsic))); + return err!(FunctionAbiMismatch(caller_abi, Abi::RustIntrinsic)); } // The intrinsic itself cannot diverge, so if we got here without a return // place... (can happen e.g., for transmute returning `!`) let dest = match dest { Some(dest) => dest, - None => return err!(UndefinedBehaviour(UndefinedBehaviourInfo::Unreachable)) + None => return err_ub!(Unreachable) }; M::call_intrinsic(self, instance, args, dest)?; // No stack frame gets pushed, the main loop will just act as if the @@ -298,7 +296,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { abi, }; if normalize_abi(caller_abi) != normalize_abi(callee_abi) { - return err!(Unsupported(FunctionAbiMismatch(caller_abi, callee_abi))); + return err!(FunctionAbiMismatch(caller_abi, callee_abi)); } } @@ -393,7 +391,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Now we should have no more caller args if caller_iter.next().is_some() { trace!("Caller has passed too many args"); - return err!(Unsupported(FunctionArgCountMismatch)); + return err!(FunctionArgCountMismatch); } // Don't forget to check the return type! if let Some(caller_ret) = dest { @@ -405,15 +403,15 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { caller_ret.layout, callee_ret.layout, ) { - return err!(Unsupported( + return err!( FunctionRetMismatch(caller_ret.layout.ty, callee_ret.layout.ty) - )); + ); } } else { let local = mir::RETURN_PLACE; let ty = self.frame().body.local_decls[local].ty; if !self.tcx.is_ty_uninhabited_from_any_module(ty) { - return err!(Unsupported(FunctionRetMismatch(self.tcx.types.never, ty))); + return err!(FunctionRetMismatch(self.tcx.types.never, ty)); } } Ok(()) diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs index acbd2066d0e47..ea8b88e51f0a0 100644 --- a/src/librustc_mir/interpret/validity.rs +++ b/src/librustc_mir/interpret/validity.rs @@ -22,10 +22,10 @@ macro_rules! validation_failure { } else { format!(" at {}", where_) }; - err!(Unsupported(ValidationFailure(format!( + err!(ValidationFailure(format!( "encountered {}{}, but expected {}", $what, where_, $details, - )))) + ))) }}; ($what:expr, $where:expr) => {{ let where_ = path_format(&$where); @@ -34,10 +34,10 @@ macro_rules! validation_failure { } else { format!(" at {}", where_) }; - err!(Unsupported(ValidationFailure(format!( + err!(ValidationFailure(format!( "encountered {}{}", $what, where_, - )))) + ))) }}; } diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 6a39839de45b3..9918356d355b8 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -448,7 +448,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { // Need to do overflow check here: For actual CTFE, MIR // generation emits code that does this before calling the op. if prim.to_bits()? == (1 << (prim.layout.size.bits() - 1)) { - return err!(Panic(PanicMessage::OverflowNeg)); + return err_panic!(OverflowNeg); } } UnOp::Not => { From 654519d3c5cd0bdece35a3282bdb433bf945ee57 Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Mon, 29 Jul 2019 13:28:55 +0530 Subject: [PATCH 10/25] use PanicInfo and UnsupportedOpInfo --- src/librustc/mir/interpret/error.rs | 16 ++++++++-------- src/librustc/mir/interpret/mod.rs | 4 ++-- src/librustc/mir/mod.rs | 6 +++--- src/librustc/mir/visit.rs | 2 +- src/librustc_codegen_ssa/mir/block.rs | 6 +++--- src/librustc_mir/borrow_check/mod.rs | 4 ++-- .../borrow_check/nll/invalidation.rs | 4 ++-- .../borrow_check/nll/type_check/mod.rs | 4 ++-- src/librustc_mir/build/expr/as_place.rs | 2 +- src/librustc_mir/build/expr/as_rvalue.rs | 12 ++++++------ src/librustc_mir/interpret/intrinsics.rs | 6 +++--- src/librustc_mir/interpret/terminator.rs | 2 +- src/librustc_mir/transform/const_prop.rs | 14 +++++++------- src/librustc_mir/transform/generator.rs | 2 +- 14 files changed, 42 insertions(+), 42 deletions(-) diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index e519a83c02667..5a464ddd383ce 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -237,7 +237,7 @@ impl<'tcx> From> for InterpErrorInfo<'tcx> { } #[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] -pub enum PanicMessage { +pub enum PanicInfo { Panic { msg: Symbol, line: u32, @@ -257,14 +257,14 @@ pub enum PanicMessage { } /// Type for MIR `Assert` terminator error messages. -pub type AssertMessage<'tcx> = PanicMessage>; +pub type AssertMessage<'tcx> = PanicInfo>; -impl PanicMessage { +impl PanicInfo { /// Getting a description does not require `O` to be printable, and does not /// require allocation. /// The caller is expected to handle `Panic` and `BoundsCheck` separately. pub fn description(&self) -> &'static str { - use PanicMessage::*; + use PanicInfo::*; match self { Overflow(mir::BinOp::Add) => "attempt to add with overflow", @@ -293,14 +293,14 @@ impl PanicMessage { GeneratorResumedAfterPanic => "generator resumed after panicking", Panic { .. } | BoundsCheck { .. } => - bug!("Unexpected PanicMessage"), + bug!("Unexpected PanicInfo"), } } } -impl fmt::Debug for PanicMessage { +impl fmt::Debug for PanicInfo { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - use PanicMessage::*; + use PanicInfo::*; match self { Panic { ref msg, line, col, ref file } => write!(f, "the evaluated program panicked at '{}', {}:{}:{}", msg, file, line, col), @@ -568,7 +568,7 @@ impl fmt::Debug for ResourceExhaustionInfo { #[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] pub enum InterpError<'tcx> { /// The program panicked. - Panic(PanicMessage), + Panic(PanicInfo), /// The program caused undefined behavior. UndefinedBehaviour(UndefinedBehaviourInfo), /// The program did something the interpreter does not support (some of these *might* be UB diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs index c4a3bbfc28b18..4b09da87d314b 100644 --- a/src/librustc/mir/interpret/mod.rs +++ b/src/librustc/mir/interpret/mod.rs @@ -31,7 +31,7 @@ macro_rules! err_ub { macro_rules! err_panic { ($($tt:tt)*) => { Err($crate::mir::interpret::InterpError::Panic( - $crate::mir::interpret::PanicMessage::$($tt)* + $crate::mir::interpret::PanicInfo::$($tt)* ).into()) }; } @@ -52,7 +52,7 @@ mod pointer; pub use self::error::{ InterpErrorInfo, InterpResult, InterpError, AssertMessage, ConstEvalErr, struct_error, - FrameInfo, ConstEvalRawResult, ConstEvalResult, ErrorHandled, PanicMessage, UnsupportedInfo, + FrameInfo, ConstEvalRawResult, ConstEvalResult, ErrorHandled, PanicInfo, UnsupportedInfo, InvalidProgramInfo, ResourceExhaustionInfo, UndefinedBehaviourInfo, }; diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 50f16858c0486..1e2ec08301cf9 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -7,7 +7,7 @@ use crate::hir::def::{CtorKind, Namespace}; use crate::hir::def_id::DefId; use crate::hir::{self, InlineAsm as HirInlineAsm}; -use crate::mir::interpret::{ConstValue, PanicMessage, Scalar}; +use crate::mir::interpret::{ConstValue, PanicInfo, Scalar}; use crate::mir::visit::MirVisitable; use crate::ty::adjustment::PointerCast; use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; @@ -3152,7 +3152,7 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> { } } Assert { ref cond, expected, ref msg, target, cleanup } => { - use PanicMessage::*; + use PanicInfo::*; let msg = match msg { BoundsCheck { ref len, ref index } => BoundsCheck { @@ -3200,7 +3200,7 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> { } Assert { ref cond, ref msg, .. } => { if cond.visit_with(visitor) { - use PanicMessage::*; + use PanicInfo::*; match msg { BoundsCheck { ref len, ref index } => len.visit_with(visitor) || index.visit_with(visitor), diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index 7562981f94f61..ee4ecb6762c96 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -514,7 +514,7 @@ macro_rules! make_mir_visitor { fn super_assert_message(&mut self, msg: & $($mutability)? AssertMessage<'tcx>, location: Location) { - use crate::mir::interpret::PanicMessage::*; + use crate::mir::interpret::PanicInfo::*; match msg { BoundsCheck { len, index } => { self.visit_operand(len, location); diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index 18611c3e167d2..006ebcbdec672 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -2,7 +2,7 @@ use rustc::middle::lang_items; use rustc::ty::{self, Ty, TypeFoldable, Instance}; use rustc::ty::layout::{self, LayoutOf, HasTyCtxt, FnTypeExt}; use rustc::mir::{self, Place, PlaceBase, Static, StaticKind}; -use rustc::mir::interpret::PanicMessage; +use rustc::mir::interpret::PanicInfo; use rustc_target::abi::call::{ArgType, FnType, PassMode, IgnoreMode}; use rustc_target::spec::abi::Abi; use crate::base; @@ -368,7 +368,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // checked operation, just a comparison with the minimum // value, so we have to check for the assert message. if !bx.check_overflow() { - if let PanicMessage::OverflowNeg = *msg { + if let PanicInfo::OverflowNeg = *msg { const_cond = Some(expected); } } @@ -403,7 +403,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // Put together the arguments to the panic entry point. let (lang_item, args) = match msg { - PanicMessage::BoundsCheck { ref len, ref index } => { + PanicInfo::BoundsCheck { ref len, ref index } => { let len = self.codegen_operand(&mut bx, len).immediate(); let index = self.codegen_operand(&mut bx, index).immediate(); diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 92774bbb7a6b4..2be39799b5273 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -733,8 +733,8 @@ impl<'cx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tcx cleanup: _, } => { self.consume_operand(loc, (cond, span), flow_state); - use rustc::mir::interpret::PanicMessage; - if let PanicMessage::BoundsCheck { ref len, ref index } = *msg { + use rustc::mir::interpret::PanicInfo; + if let PanicInfo::BoundsCheck { ref len, ref index } = *msg { self.consume_operand(loc, (len, span), flow_state); self.consume_operand(loc, (index, span), flow_state); } diff --git a/src/librustc_mir/borrow_check/nll/invalidation.rs b/src/librustc_mir/borrow_check/nll/invalidation.rs index aa9e68bd7de44..631a81421131c 100644 --- a/src/librustc_mir/borrow_check/nll/invalidation.rs +++ b/src/librustc_mir/borrow_check/nll/invalidation.rs @@ -207,8 +207,8 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> { cleanup: _, } => { self.consume_operand(location, cond); - use rustc::mir::interpret::PanicMessage; - if let PanicMessage::BoundsCheck { ref len, ref index } = *msg { + use rustc::mir::interpret::PanicInfo; + if let PanicInfo::BoundsCheck { ref len, ref index } = *msg { self.consume_operand(location, len); self.consume_operand(location, index); } diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index 50c0640f885f2..f10d505fe8983 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -26,7 +26,7 @@ use rustc::infer::canonical::QueryRegionConstraints; use rustc::infer::outlives::env::RegionBoundPairs; use rustc::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime, NLLRegionVariableOrigin}; use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; -use rustc::mir::interpret::{ConstValue, PanicMessage}; +use rustc::mir::interpret::{ConstValue, PanicInfo}; use rustc::mir::tcx::PlaceTy; use rustc::mir::visit::{PlaceContext, Visitor, NonMutatingUseContext}; use rustc::mir::*; @@ -1632,7 +1632,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { span_mirbug!(self, term, "bad Assert ({:?}, not bool", cond_ty); } - if let PanicMessage::BoundsCheck { ref len, ref index } = *msg { + if let PanicInfo::BoundsCheck { ref len, ref index } = *msg { if len.ty(body, tcx) != tcx.types.usize { span_mirbug!(self, len, "bounds-check length non-usize {:?}", len) } diff --git a/src/librustc_mir/build/expr/as_place.rs b/src/librustc_mir/build/expr/as_place.rs index 7a428a2ec9f36..7005f274e0e7d 100644 --- a/src/librustc_mir/build/expr/as_place.rs +++ b/src/librustc_mir/build/expr/as_place.rs @@ -4,7 +4,7 @@ use crate::build::expr::category::Category; use crate::build::ForGuard::{OutsideGuard, RefWithinGuard}; use crate::build::{BlockAnd, BlockAndExtension, Builder}; use crate::hair::*; -use rustc::mir::interpret::{PanicMessage::BoundsCheck}; +use rustc::mir::interpret::{PanicInfo::BoundsCheck}; use rustc::mir::*; use rustc::ty::{CanonicalUserTypeAnnotation, Variance}; diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs index 92daf06e6f8fe..ec061e7453577 100644 --- a/src/librustc_mir/build/expr/as_rvalue.rs +++ b/src/librustc_mir/build/expr/as_rvalue.rs @@ -7,7 +7,7 @@ use crate::build::expr::category::{Category, RvalueFunc}; use crate::build::{BlockAnd, BlockAndExtension, Builder}; use crate::hair::*; use rustc::middle::region; -use rustc::mir::interpret::PanicMessage; +use rustc::mir::interpret::PanicInfo; use rustc::mir::*; use rustc::ty::{self, CanonicalUserTypeAnnotation, Ty, UpvarSubsts}; use syntax_pos::Span; @@ -101,7 +101,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { block, Operand::Move(is_min), false, - PanicMessage::OverflowNeg, + PanicInfo::OverflowNeg, expr_span, ); } @@ -401,7 +401,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let val = result_value.clone().field(val_fld, ty); let of = result_value.field(of_fld, bool_ty); - let err = PanicMessage::Overflow(op); + let err = PanicInfo::Overflow(op); block = self.assert(block, Operand::Move(of), false, err, span); @@ -412,11 +412,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // and 2. there are two possible failure cases, divide-by-zero and overflow. let zero_err = if op == BinOp::Div { - PanicMessage::DivisionByZero + PanicInfo::DivisionByZero } else { - PanicMessage::RemainderByZero + PanicInfo::RemainderByZero }; - let overflow_err = PanicMessage::Overflow(op); + let overflow_err = PanicInfo::Overflow(op); // Check for / 0 let is_zero = self.temp(bool_ty, span); diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index f943ff67c0858..9605395b84b17 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -7,7 +7,7 @@ use rustc::ty; use rustc::ty::layout::{LayoutOf, Primitive, Size}; use rustc::mir::BinOp; use rustc::mir::interpret::{ - InterpResult, InterpError, Scalar, PanicMessage, UnsupportedInfo::*, + InterpResult, InterpError, Scalar, PanicInfo, UnsupportedInfo::*, }; use super::{ @@ -250,7 +250,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let file = Symbol::intern(self.read_str(file_place)?); let line = self.read_scalar(line.into())?.to_u32()?; let col = self.read_scalar(col.into())?.to_u32()?; - return Err(InterpError::Panic(PanicMessage::Panic { msg, file, line, col }).into()); + return Err(InterpError::Panic(PanicInfo::Panic { msg, file, line, col }).into()); } else if Some(def_id) == self.tcx.lang_items().begin_panic_fn() { assert!(args.len() == 2); // &'static str, &(&'static str, u32, u32) @@ -268,7 +268,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let file = Symbol::intern(self.read_str(file_place)?); let line = self.read_scalar(line.into())?.to_u32()?; let col = self.read_scalar(col.into())?.to_u32()?; - return Err(InterpError::Panic(PanicMessage::Panic { msg, file, line, col }).into()); + return Err(InterpError::Panic(PanicInfo::Panic { msg, file, line, col }).into()); } else { return Ok(false); } diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs index b7dbc8384586e..14b92f2b3d49d 100644 --- a/src/librustc_mir/interpret/terminator.rs +++ b/src/librustc_mir/interpret/terminator.rs @@ -136,7 +136,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.goto_block(Some(target))?; } else { // Compute error message - use rustc::mir::interpret::PanicMessage::*; + use rustc::mir::interpret::PanicInfo::*; return match msg { BoundsCheck { ref len, ref index } => { let len = self.read_immediate(self.eval_operand(len, None)?) diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 9918356d355b8..ec8a33f7a43fa 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -13,7 +13,7 @@ use rustc::mir::{ use rustc::mir::visit::{ Visitor, PlaceContext, MutatingUseContext, MutVisitor, NonMutatingUseContext, }; -use rustc::mir::interpret::{Scalar, GlobalId, InterpResult, InterpError, PanicMessage}; +use rustc::mir::interpret::{Scalar, GlobalId, InterpResult, InterpError, PanicInfo}; use rustc::ty::{self, Instance, ParamEnv, Ty, TyCtxt}; use syntax_pos::{Span, DUMMY_SP}; use rustc::ty::subst::InternalSubsts; @@ -526,7 +526,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { ) } else { if overflow { - let err = InterpError::Panic(PanicMessage::Overflow(op)).into(); + let err = InterpError::Panic(PanicInfo::Overflow(op)).into(); let _: Option<()> = self.use_ecx(source_info, |_| Err(err)); return None; } @@ -763,12 +763,12 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> { .as_local_hir_id(self.source.def_id()) .expect("some part of a failing const eval must be local"); let msg = match msg { - PanicMessage::Overflow(_) | - PanicMessage::OverflowNeg | - PanicMessage::DivisionByZero | - PanicMessage::RemainderByZero => + PanicInfo::Overflow(_) | + PanicInfo::OverflowNeg | + PanicInfo::DivisionByZero | + PanicInfo::RemainderByZero => msg.description().to_owned(), - PanicMessage::BoundsCheck { ref len, ref index } => { + PanicInfo::BoundsCheck { ref len, ref index } => { let len = self .eval_operand(len, source_info) .expect("len must be const"); diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index 5461a2e470c7e..94bb70e10aa53 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -1016,7 +1016,7 @@ fn create_generator_resume_function<'tcx>( let mut cases = create_cases(body, &transform, |point| Some(point.resume)); - use rustc::mir::interpret::PanicMessage::{ + use rustc::mir::interpret::PanicInfo::{ GeneratorResumedAfterPanic, GeneratorResumedAfterReturn, }; From 03d47be8f0149bfd2ccf2f406af74920f72f0c52 Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Mon, 29 Jul 2019 13:41:32 +0530 Subject: [PATCH 11/25] code review fixes --- src/librustc/mir/interpret/error.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index 5a464ddd383ce..b347000ae046e 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -363,6 +363,7 @@ impl fmt::Debug for UndefinedBehaviourInfo { #[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] pub enum UnsupportedInfo<'tcx> { + /// Handle cases which for which we do not have a fixed variant. Unimplemented(String), // -- Everything below is not classified yet -- From 9f8b099846f3bb5cd5f17698b6e653e0271f057e Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Mon, 29 Jul 2019 20:17:52 +0530 Subject: [PATCH 12/25] code review fixes --- src/librustc/mir/interpret/error.rs | 14 +++++++------- src/librustc/mir/interpret/mod.rs | 4 ++-- src/librustc/mir/interpret/pointer.rs | 2 +- src/librustc_mir/const_eval.rs | 8 ++++---- src/librustc_mir/interpret/cast.rs | 4 ++-- src/librustc_mir/interpret/eval_context.rs | 19 ++++++++++++------- src/librustc_mir/interpret/intern.rs | 4 ++-- src/librustc_mir/interpret/intrinsics.rs | 4 ++-- src/librustc_mir/interpret/machine.rs | 6 +++--- src/librustc_mir/interpret/memory.rs | 11 ++++++----- src/librustc_mir/interpret/operand.rs | 8 +++++--- src/librustc_mir/interpret/snapshot.rs | 4 ++-- src/librustc_mir/interpret/terminator.rs | 4 ++-- src/librustc_mir/interpret/validity.rs | 9 +++++---- src/librustc_mir/transform/const_prop.rs | 4 ++-- 15 files changed, 57 insertions(+), 48 deletions(-) diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index b347000ae046e..36635e62c15e1 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -314,12 +314,12 @@ impl fmt::Debug for PanicInfo { #[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] pub enum InvalidProgramInfo<'tcx> { - /// Resolution can fail if we are in a too generic context + /// Resolution can fail if we are in a too generic context. TooGeneric, /// Cannot compute this constant because it depends on another one - /// which already produced an error + /// which already produced an error. ReferencedConstant, - /// Abort in case type errors are reached + /// Abort in case type errors are reached. TypeckError, /// An error occurred during layout computation. Layout(layout::LayoutError<'tcx>), @@ -362,7 +362,7 @@ impl fmt::Debug for UndefinedBehaviourInfo { } #[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] -pub enum UnsupportedInfo<'tcx> { +pub enum UnsupportedOpInfo<'tcx> { /// Handle cases which for which we do not have a fixed variant. Unimplemented(String), @@ -426,9 +426,9 @@ pub enum UnsupportedInfo<'tcx> { PathNotFound(Vec), } -impl fmt::Debug for UnsupportedInfo<'tcx> { +impl fmt::Debug for UnsupportedOpInfo<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - use UnsupportedInfo::*; + use UnsupportedOpInfo::*; match self { PointerOutOfBounds { ptr, msg, allocation_size } => { write!(f, "{} failed: pointer must be in-bounds at offset {}, \ @@ -574,7 +574,7 @@ pub enum InterpError<'tcx> { UndefinedBehaviour(UndefinedBehaviourInfo), /// The program did something the interpreter does not support (some of these *might* be UB /// but the interpreter is not sure). - Unsupported(UnsupportedInfo<'tcx>), + Unsupported(UnsupportedOpInfo<'tcx>), /// The program was invalid (ill-typed, not sufficiently monomorphized, ...). InvalidProgram(InvalidProgramInfo<'tcx>), /// The program exhausted the interpreter's resources (stack/heap too big, diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs index 4b09da87d314b..e4bf8efad72eb 100644 --- a/src/librustc/mir/interpret/mod.rs +++ b/src/librustc/mir/interpret/mod.rs @@ -4,7 +4,7 @@ macro_rules! err { ($($tt:tt)*) => { Err($crate::mir::interpret::InterpError::Unsupported( - $crate::mir::interpret::UnsupportedInfo::$($tt)* + $crate::mir::interpret::UnsupportedOpInfo::$($tt)* ).into()) }; } @@ -52,7 +52,7 @@ mod pointer; pub use self::error::{ InterpErrorInfo, InterpResult, InterpError, AssertMessage, ConstEvalErr, struct_error, - FrameInfo, ConstEvalRawResult, ConstEvalResult, ErrorHandled, PanicInfo, UnsupportedInfo, + FrameInfo, ConstEvalRawResult, ConstEvalResult, ErrorHandled, PanicInfo, UnsupportedOpInfo, InvalidProgramInfo, ResourceExhaustionInfo, UndefinedBehaviourInfo, }; diff --git a/src/librustc/mir/interpret/pointer.rs b/src/librustc/mir/interpret/pointer.rs index faca04412402e..fbc726deb3dc3 100644 --- a/src/librustc/mir/interpret/pointer.rs +++ b/src/librustc/mir/interpret/pointer.rs @@ -196,7 +196,7 @@ impl<'tcx, Tag> Pointer { msg: CheckInAllocMsg, ) -> InterpResult<'tcx, ()> { if self.offset > allocation_size { - err!(PointerOutOfBounds { ptr: self.erase_tag(),msg,allocation_size }) + err!(PointerOutOfBounds { ptr: self.erase_tag(), msg, allocation_size }) } else { Ok(()) } diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index bbee3b392345e..e059d766a6f5b 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -24,8 +24,7 @@ use crate::interpret::{self, RawConst, ConstValue, InterpResult, InterpErrorInfo, InterpError, GlobalId, InterpCx, StackPopCleanup, Allocation, AllocId, MemoryKind, - snapshot, RefTracking, intern_const_alloc_recursive, UnsupportedInfo::*, - InvalidProgramInfo::*, + snapshot, RefTracking, intern_const_alloc_recursive, UnsupportedOpInfo, }; /// Number of steps until the detector even starts doing anything. @@ -184,7 +183,7 @@ fn eval_body_using_ecx<'mir, 'tcx>( impl<'tcx> Into> for ConstEvalError { fn into(self) -> InterpErrorInfo<'tcx> { - InterpError::Unsupported(MachineError(self.to_string())).into() + InterpError::Unsupported(UnsupportedOpInfo::MachineError(self.to_string())).into() } } @@ -361,7 +360,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, Ok(Some(match ecx.load_mir(instance.def) { Ok(body) => body, Err(err) => { - if let InterpError::Unsupported(NoMirFor(ref path)) = err.kind { + if let InterpError::Unsupported(UnsupportedOpInfo::NoMirFor(ref path)) = err.kind { return Err( ConstEvalError::NeedsRfc(format!("calling extern function `{}`", path)) .into(), @@ -698,6 +697,7 @@ pub fn const_eval_raw_provider<'tcx>( // promoting runtime code is only allowed to error if it references broken constants // any other kind of error will be reported to the user as a deny-by-default lint _ => if let Some(p) = cid.promoted { + use crate::interpret::InvalidProgramInfo::*; let span = tcx.promoted_mir(def_id)[p].span; if let InterpError::InvalidProgram(ReferencedConstant) = err.error { err.report_as_error( diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs index 7157e714f0522..c7a56c29b4b54 100644 --- a/src/librustc_mir/interpret/cast.rs +++ b/src/librustc_mir/interpret/cast.rs @@ -9,8 +9,7 @@ use rustc_apfloat::{Float, FloatConvert}; use rustc::mir::interpret::{ Scalar, InterpResult, Pointer, PointerArithmetic, InterpError, }; -use rustc::mir::{CastKind, interpret::{InvalidProgramInfo::*}}; - +use rustc::mir::CastKind; use super::{InterpCx, Machine, PlaceTy, OpTy, Immediate, FnVal}; @@ -75,6 +74,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } Pointer(PointerCast::ReifyFnPointer) => { + use rustc::mir::interpret::InvalidProgramInfo::TooGeneric; // The src operand does not matter, just its type match src.layout.ty.sty { ty::FnDef(def_id, substs) => { diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 1ee6871f5efc7..76de3b32fc7fe 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -17,7 +17,7 @@ use rustc::mir::interpret::{ ErrorHandled, GlobalId, Scalar, Pointer, FrameInfo, AllocId, InterpResult, InterpError, - truncate, sign_extend, InvalidProgramInfo::*, + truncate, sign_extend, InvalidProgramInfo, }; use rustc_data_structures::fx::FxHashMap; @@ -190,8 +190,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> LayoutOf for InterpCx<'mir, 'tcx, M> { #[inline] fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyLayout { - self.tcx.layout_of(self.param_env.and(ty)) - .map_err(|layout| InterpError::InvalidProgram(Layout(layout)).into()) + self.tcx + .layout_of(self.param_env.and(ty)) + .map_err(|layout| { + InterpError::InvalidProgram(InvalidProgramInfo::Layout(layout)).into() + }) } } @@ -302,7 +305,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { &substs, )), None => if substs.needs_subst() { - err_inval!(TooGeneric).into() + err_inval!(TooGeneric) } else { Ok(substs) }, @@ -323,7 +326,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.param_env, def_id, substs, - ).ok_or_else(|| InterpError::InvalidProgram(TooGeneric).into()) + ).ok_or_else(|| InterpError::InvalidProgram(InvalidProgramInfo::TooGeneric).into()) } pub fn load_mir( @@ -694,8 +697,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // `Memory::get_static_alloc` which has to use `const_eval_raw` to avoid cycles. let val = self.tcx.const_eval_raw(param_env.and(gid)).map_err(|err| { match err { - ErrorHandled::Reported => InterpError::InvalidProgram(ReferencedConstant), - ErrorHandled::TooGeneric => InterpError::InvalidProgram(TooGeneric), + ErrorHandled::Reported => + InterpError::InvalidProgram(InvalidProgramInfo::ReferencedConstant), + ErrorHandled::TooGeneric => + InterpError::InvalidProgram(InvalidProgramInfo::TooGeneric), } })?; self.raw_const_to_mplace(val) diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs index 261cfbce17144..af7da6fa53229 100644 --- a/src/librustc_mir/interpret/intern.rs +++ b/src/librustc_mir/interpret/intern.rs @@ -5,7 +5,7 @@ use rustc::ty::{Ty, TyCtxt, ParamEnv, self}; use rustc::mir::interpret::{ - InterpResult, ErrorHandled, UnsupportedInfo::*, + InterpResult, ErrorHandled, UnsupportedOpInfo, }; use rustc::hir; use rustc::hir::def_id::DefId; @@ -293,7 +293,7 @@ pub fn intern_const_alloc_recursive( if let Err(error) = interned { // This can happen when e.g. the tag of an enum is not a valid discriminant. We do have // to read enum discriminants in order to find references in enum variant fields. - if let InterpError::Unsupported(ValidationFailure(_)) = error.kind { + if let InterpError::Unsupported(UnsupportedOpInfo::ValidationFailure(_)) = error.kind { let err = crate::const_eval::error_to_const_error(&ecx, error); match err.struct_error(ecx.tcx, "it is undefined behavior to use this value") { Ok(mut diag) => { diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index 9605395b84b17..0b4df6cc7bc59 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -7,7 +7,7 @@ use rustc::ty; use rustc::ty::layout::{LayoutOf, Primitive, Size}; use rustc::mir::BinOp; use rustc::mir::interpret::{ - InterpResult, InterpError, Scalar, PanicInfo, UnsupportedInfo::*, + InterpResult, InterpError, Scalar, PanicInfo, UnsupportedOpInfo, }; use super::{ @@ -100,7 +100,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let bits = self.read_scalar(args[0])?.to_bits(layout_of.size)?; let kind = match layout_of.abi { ty::layout::Abi::Scalar(ref scalar) => scalar.value, - _ => Err(InterpError::Unsupported(TypeNotPrimitive(ty)))?, + _ => Err(InterpError::Unsupported(UnsupportedOpInfo::TypeNotPrimitive(ty)))?, }; let out_val = if intrinsic_name.ends_with("_nonzero") { if bits == 0 { diff --git a/src/librustc_mir/interpret/machine.rs b/src/librustc_mir/interpret/machine.rs index 4f04803addd8b..064ca0f4253bb 100644 --- a/src/librustc_mir/interpret/machine.rs +++ b/src/librustc_mir/interpret/machine.rs @@ -11,7 +11,7 @@ use rustc::ty::{self, TyCtxt}; use super::{ Allocation, AllocId, InterpResult, InterpError, Scalar, AllocationExtra, - InterpCx, PlaceTy, OpTy, ImmTy, MemoryKind, Pointer, Memory, UnsupportedInfo::* + InterpCx, PlaceTy, OpTy, ImmTy, MemoryKind, Pointer, Memory, UnsupportedOpInfo, }; /// Whether this kind of memory is allowed to leak @@ -240,9 +240,9 @@ pub trait Machine<'mir, 'tcx>: Sized { int: u64, ) -> InterpResult<'tcx, Pointer> { Err((if int == 0 { - InterpError::Unsupported(InvalidNullPointerUsage) + InterpError::Unsupported(UnsupportedOpInfo::InvalidNullPointerUsage) } else { - InterpError::Unsupported(ReadBytesAsPointer) + InterpError::Unsupported(UnsupportedOpInfo::ReadBytesAsPointer) }).into()) } diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 72feb73f751a4..edaf7855e872f 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -19,8 +19,7 @@ use syntax::ast::Mutability; use super::{ Pointer, AllocId, Allocation, GlobalId, AllocationExtra, InterpResult, Scalar, InterpError, GlobalAlloc, PointerArithmetic, - Machine, AllocMap, MayLeak, ErrorHandled, CheckInAllocMsg, UnsupportedInfo::*, - InvalidProgramInfo::* + Machine, AllocMap, MayLeak, ErrorHandled, CheckInAllocMsg, InvalidProgramInfo, }; #[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)] @@ -438,9 +437,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { assert!(tcx.is_static(def_id)); match err { ErrorHandled::Reported => - InterpError::InvalidProgram(ReferencedConstant), + InterpError::InvalidProgram( + InvalidProgramInfo::ReferencedConstant + ), ErrorHandled::TooGeneric => - InterpError::InvalidProgram(TooGeneric), + InterpError::InvalidProgram(InvalidProgramInfo::TooGeneric), } })?; // Make sure we use the ID of the resolved memory, not the lazy one! @@ -590,7 +591,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { } else { match self.tcx.alloc_map.lock().get(id) { Some(GlobalAlloc::Function(instance)) => Ok(FnVal::Instance(instance)), - _ => Err(InterpError::Unsupported(ExecuteMemory).into()), + _ => err!(ExecuteMemory), } } } diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 1896c3cda13d6..4dd308f5bf4da 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -12,7 +12,7 @@ use rustc::mir::interpret::{ GlobalId, AllocId, ConstValue, Pointer, Scalar, InterpResult, InterpError, - sign_extend, truncate, UnsupportedInfo::*, + sign_extend, truncate, UnsupportedOpInfo, }; use super::{ InterpCx, Machine, @@ -331,8 +331,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ) -> InterpResult<'tcx, &str> { let len = mplace.len(self)?; let bytes = self.memory.read_bytes(mplace.ptr, Size::from_bytes(len as u64))?; - let str = ::std::str::from_utf8(bytes) - .map_err(|err| InterpError::Unsupported(ValidationFailure(err.to_string())))?; + let str = ::std::str::from_utf8(bytes).map_err(|err| { + InterpError::Unsupported(UnsupportedOpInfo::ValidationFailure(err.to_string())) + })?; Ok(str) } @@ -603,6 +604,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let raw_discr = discr_val.to_scalar_or_undef(); trace!("discr value: {:?}", raw_discr); // post-process + use rustc::mir::interpret::UnsupportedOpInfo::InvalidDiscriminant; Ok(match *discr_kind { layout::DiscriminantKind::Tag => { let bits_discr = match raw_discr.to_bits(discr_val.layout.size) { diff --git a/src/librustc_mir/interpret/snapshot.rs b/src/librustc_mir/interpret/snapshot.rs index 112e592329f5f..ebf7dd3b6628c 100644 --- a/src/librustc_mir/interpret/snapshot.rs +++ b/src/librustc_mir/interpret/snapshot.rs @@ -12,7 +12,7 @@ use rustc::mir; use rustc::mir::interpret::{ AllocId, Pointer, Scalar, Relocations, Allocation, UndefMask, - InterpResult, InterpError, ResourceExhaustionInfo::*, + InterpResult, InterpError, ResourceExhaustionInfo, }; use rustc::ty::{self, TyCtxt}; @@ -77,7 +77,7 @@ impl<'mir, 'tcx> InfiniteLoopDetector<'mir, 'tcx> { } // Second cycle - Err(InterpError::ResourceExhaustion(InfiniteLoop).into()) + Err(InterpError::ResourceExhaustion(ResourceExhaustionInfo::InfiniteLoop).into()) } } diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs index 14b92f2b3d49d..b1706e72dd475 100644 --- a/src/librustc_mir/interpret/terminator.rs +++ b/src/librustc_mir/interpret/terminator.rs @@ -9,7 +9,7 @@ use rustc_target::spec::abi::Abi; use super::{ InterpResult, PointerArithmetic, InterpError, Scalar, InterpCx, Machine, Immediate, OpTy, ImmTy, PlaceTy, MPlaceTy, StackPopCleanup, FnVal, - UnsupportedInfo::*, + UnsupportedOpInfo, }; impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { @@ -221,7 +221,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { return Ok(()); } let caller_arg = caller_arg.next() - .ok_or_else(|| InterpError::Unsupported(FunctionArgCountMismatch))?; + .ok_or_else(|| InterpError::Unsupported(UnsupportedOpInfo::FunctionArgCountMismatch))?; if rust_abi { debug_assert!(!caller_arg.layout.is_zst(), "ZSTs must have been already filtered out"); } diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs index ea8b88e51f0a0..9404711bd9708 100644 --- a/src/librustc_mir/interpret/validity.rs +++ b/src/librustc_mir/interpret/validity.rs @@ -11,7 +11,7 @@ use std::hash::Hash; use super::{ GlobalAlloc, InterpResult, InterpError, - OpTy, Machine, InterpCx, ValueVisitor, MPlaceTy, UnsupportedInfo::*, + OpTy, Machine, InterpCx, ValueVisitor, MPlaceTy, UnsupportedOpInfo, }; macro_rules! validation_failure { @@ -297,11 +297,11 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> match self.walk_value(op) { Ok(()) => Ok(()), Err(err) => match err.kind { - InterpError::Unsupported(InvalidDiscriminant(val)) => + InterpError::Unsupported(UnsupportedOpInfo::InvalidDiscriminant(val)) => validation_failure!( val, self.path, "a valid enum discriminant" ), - InterpError::Unsupported(ReadPointerAsBytes) => + InterpError::Unsupported(UnsupportedOpInfo::ReadPointerAsBytes) => validation_failure!( "a pointer", self.path, "plain (non-pointer) bytes" ), @@ -405,6 +405,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> "{:?} did not pass access check for size {:?}, align {:?}", ptr, size, align ); + use super::UnsupportedOpInfo::*; match err.kind { InterpError::Unsupported(InvalidNullPointerUsage) => return validation_failure!("NULL reference", self.path), @@ -608,7 +609,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> Err(err) => { // For some errors we might be able to provide extra information match err.kind { - InterpError::Unsupported(ReadUndefBytes(offset)) => { + InterpError::Unsupported(UnsupportedOpInfo::ReadUndefBytes(offset)) => { // Some byte was undefined, determine which // element that byte belongs to so we can // provide an index. diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index ec8a33f7a43fa..191c6f2dc8aeb 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -257,9 +257,9 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { Err(error) => { let diagnostic = error_to_const_error(&self.ecx, error); use rustc::mir::interpret::InterpError::*; - use rustc::mir::interpret::UnsupportedInfo::*; + use rustc::mir::interpret::UnsupportedOpInfo::*; match diagnostic.error { - Exit(_) => {}, + Exit(_) => bug!("the CTFE program cannot exit"), | Unsupported(OutOfTls) | Unsupported(TlsOutOfBounds) From 5bb06b3acb83999de128cacbdcf629424842e3e5 Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Mon, 29 Jul 2019 20:26:25 +0530 Subject: [PATCH 13/25] code review fixes --- src/librustc_mir/const_eval.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index e059d766a6f5b..97b89552cff39 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -697,7 +697,7 @@ pub fn const_eval_raw_provider<'tcx>( // promoting runtime code is only allowed to error if it references broken constants // any other kind of error will be reported to the user as a deny-by-default lint _ => if let Some(p) = cid.promoted { - use crate::interpret::InvalidProgramInfo::*; + use crate::interpret::InvalidProgramInfo::ReferencedConstant; let span = tcx.promoted_mir(def_id)[p].span; if let InterpError::InvalidProgram(ReferencedConstant) = err.error { err.report_as_error( From 96205212e5294fe5a6f4cfd901d39c5446fa8e60 Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Tue, 30 Jul 2019 12:32:43 +0530 Subject: [PATCH 14/25] code review fixes --- src/librustc_mir/transform/const_prop.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 191c6f2dc8aeb..5043687f060d9 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -257,15 +257,8 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { Err(error) => { let diagnostic = error_to_const_error(&self.ecx, error); use rustc::mir::interpret::InterpError::*; - use rustc::mir::interpret::UnsupportedOpInfo::*; match diagnostic.error { Exit(_) => bug!("the CTFE program cannot exit"), - - | Unsupported(OutOfTls) - | Unsupported(TlsOutOfBounds) - | Unsupported(PathNotFound(_)) - => bug!("these should not be in rustc, but in miri's machine errors"), - | Unsupported(_) => {}, | UndefinedBehaviour(_) => {}, | InvalidProgram(_) => {}, From 2a33fbff22c1145f59805aee0c4fa458d4242ebb Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Tue, 30 Jul 2019 13:18:36 +0530 Subject: [PATCH 15/25] addding an interp_error module --- src/librustc/mir/interpret/interp_error.rs | 20 ++++++++++++++++++++ src/librustc/mir/interpret/mod.rs | 1 + src/librustc_mir/interpret/cast.rs | 5 ++--- src/librustc_mir/interpret/eval_context.rs | 2 +- src/librustc_mir/interpret/operand.rs | 2 +- src/librustc_mir/interpret/terminator.rs | 5 ++--- src/librustc_mir/interpret/traits.rs | 6 +++--- 7 files changed, 30 insertions(+), 11 deletions(-) create mode 100644 src/librustc/mir/interpret/interp_error.rs diff --git a/src/librustc/mir/interpret/interp_error.rs b/src/librustc/mir/interpret/interp_error.rs new file mode 100644 index 0000000000000..c5a7adf1b6710 --- /dev/null +++ b/src/librustc/mir/interpret/interp_error.rs @@ -0,0 +1,20 @@ +//! macros to do something like `.ok_or_else(|| inval!(TooGeneric).into())` rather than +//! `.ok_or_else(|| InterpError::InvalidProgram(TooGeneric).into())` + +#[macro_export] +macro_rules! inval { + ($($tt:tt)*) => { + $crate::mir::interpret::InterpError::InvalidProgram( + $crate::mir::interpret::InvalidProgramInfo::$($tt)* + ) + }; +} + +#[macro_export] +macro_rules! unsup { + ($($tt:tt)*) => { + $crate::mir::interpret::InterpError::Unsupported( + $crate::mir::interpret::UnsupportedOpInfo::$($tt)* + ) + }; +} diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs index e4bf8efad72eb..064ff831e4ee8 100644 --- a/src/librustc/mir/interpret/mod.rs +++ b/src/librustc/mir/interpret/mod.rs @@ -49,6 +49,7 @@ mod error; mod value; mod allocation; mod pointer; +mod interp_error; pub use self::error::{ InterpErrorInfo, InterpResult, InterpError, AssertMessage, ConstEvalErr, struct_error, diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs index c7a56c29b4b54..4cb8351947b3c 100644 --- a/src/librustc_mir/interpret/cast.rs +++ b/src/librustc_mir/interpret/cast.rs @@ -7,7 +7,7 @@ use syntax::symbol::sym; use rustc_apfloat::ieee::{Single, Double}; use rustc_apfloat::{Float, FloatConvert}; use rustc::mir::interpret::{ - Scalar, InterpResult, Pointer, PointerArithmetic, InterpError, + Scalar, InterpResult, Pointer, PointerArithmetic, }; use rustc::mir::CastKind; @@ -74,7 +74,6 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } Pointer(PointerCast::ReifyFnPointer) => { - use rustc::mir::interpret::InvalidProgramInfo::TooGeneric; // The src operand does not matter, just its type match src.layout.ty.sty { ty::FnDef(def_id, substs) => { @@ -86,7 +85,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.param_env, def_id, substs, - ).ok_or_else(|| InterpError::InvalidProgram(TooGeneric).into()); + ).ok_or_else(|| inval!(TooGeneric).into()); let fn_ptr = self.memory.create_fn_alloc(FnVal::Instance(instance?)); self.write_scalar(Scalar::Ptr(fn_ptr.into()), dest)?; } diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 76de3b32fc7fe..c0e61184780ba 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -326,7 +326,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.param_env, def_id, substs, - ).ok_or_else(|| InterpError::InvalidProgram(InvalidProgramInfo::TooGeneric).into()) + ).ok_or_else(|| inval!(TooGeneric).into()) } pub fn load_mir( diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 4dd308f5bf4da..cdc89e7055cd2 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -637,7 +637,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { .find(|(_, var)| var.val == real_discr), _ => bug!("tagged layout for non-adt non-generator"), }.ok_or_else( - || InterpError::Unsupported(InvalidDiscriminant(raw_discr.erase_tag())) + || unsup!(InvalidDiscriminant(raw_discr.erase_tag())) )?; (real_discr, index.0) }, diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs index b1706e72dd475..51ed156f6cfcf 100644 --- a/src/librustc_mir/interpret/terminator.rs +++ b/src/librustc_mir/interpret/terminator.rs @@ -7,9 +7,8 @@ use syntax::source_map::Span; use rustc_target::spec::abi::Abi; use super::{ - InterpResult, PointerArithmetic, InterpError, Scalar, + InterpResult, PointerArithmetic, Scalar, InterpCx, Machine, Immediate, OpTy, ImmTy, PlaceTy, MPlaceTy, StackPopCleanup, FnVal, - UnsupportedOpInfo, }; impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { @@ -221,7 +220,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { return Ok(()); } let caller_arg = caller_arg.next() - .ok_or_else(|| InterpError::Unsupported(UnsupportedOpInfo::FunctionArgCountMismatch))?; + .ok_or_else(|| unsup!(FunctionArgCountMismatch)) ?; if rust_abi { debug_assert!(!caller_arg.layout.is_zst(), "ZSTs must have been already filtered out"); } diff --git a/src/librustc_mir/interpret/traits.rs b/src/librustc_mir/interpret/traits.rs index 677d6c89b38d5..71f2cfceaf225 100644 --- a/src/librustc_mir/interpret/traits.rs +++ b/src/librustc_mir/interpret/traits.rs @@ -1,8 +1,8 @@ use rustc::ty::{self, Ty, Instance}; use rustc::ty::layout::{Size, Align, LayoutOf}; -use rustc::mir::interpret::{Scalar, Pointer, InterpResult, PointerArithmetic, InvalidProgramInfo}; +use rustc::mir::interpret::{Scalar, Pointer, InterpResult, PointerArithmetic,}; -use super::{InterpCx, InterpError, Machine, MemoryKind, FnVal}; +use super::{InterpCx, Machine, MemoryKind, FnVal}; impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// Creates a dynamic vtable for the given type and vtable origin. This is used only for @@ -83,7 +83,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.param_env, def_id, substs, - ).ok_or_else(|| InterpError::InvalidProgram(InvalidProgramInfo::TooGeneric))?; + ).ok_or_else(|| inval!(TooGeneric))?; let fn_ptr = self.memory.create_fn_alloc(FnVal::Instance(instance)); let method_ptr = vtable.offset(ptr_size * (3 + i as u64), self)?; self.memory From 69daf844daac2f8c75ae0db662c584f05dd9838e Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Tue, 30 Jul 2019 15:25:12 +0530 Subject: [PATCH 16/25] adding throw_ and err_ macros for InterpError --- src/librustc/mir/interpret/allocation.rs | 6 ++-- src/librustc/mir/interpret/error.rs | 2 +- src/librustc/mir/interpret/interp_error.rs | 20 ----------- src/librustc/mir/interpret/mod.rs | 29 +++++++++++---- src/librustc/mir/interpret/pointer.rs | 6 ++-- src/librustc/mir/interpret/value.rs | 12 +++---- src/librustc_mir/const_eval.rs | 4 +-- src/librustc_mir/interpret/cast.rs | 4 +-- src/librustc_mir/interpret/eval_context.rs | 20 +++++------ src/librustc_mir/interpret/intern.rs | 2 +- src/librustc_mir/interpret/intrinsics.rs | 4 +-- src/librustc_mir/interpret/machine.rs | 2 +- src/librustc_mir/interpret/memory.rs | 42 +++++++++++----------- src/librustc_mir/interpret/operand.rs | 10 +++--- src/librustc_mir/interpret/operator.rs | 12 +++---- src/librustc_mir/interpret/place.rs | 4 +-- src/librustc_mir/interpret/step.rs | 2 +- src/librustc_mir/interpret/terminator.rs | 36 +++++++++---------- src/librustc_mir/interpret/traits.rs | 2 +- src/librustc_mir/interpret/validity.rs | 4 +-- src/librustc_mir/transform/const_prop.rs | 2 +- 21 files changed, 111 insertions(+), 114 deletions(-) delete mode 100644 src/librustc/mir/interpret/interp_error.rs diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs index 51b2d0272a597..00f908007941e 100644 --- a/src/librustc/mir/interpret/allocation.rs +++ b/src/librustc/mir/interpret/allocation.rs @@ -244,7 +244,7 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra> Allocation { Ok(&self.get_bytes(cx, ptr, size_with_null)?[..size]) } // This includes the case where `offset` is out-of-bounds to begin with. - None => err!(UnterminatedCString(ptr.erase_tag())), + None => throw_err!(UnterminatedCString(ptr.erase_tag())), } } @@ -446,7 +446,7 @@ impl<'tcx, Tag: Copy, Extra> Allocation { if self.relocations(cx, ptr, size).is_empty() { Ok(()) } else { - err!(ReadPointerAsBytes) + throw_err!(ReadPointerAsBytes) } } @@ -516,7 +516,7 @@ impl<'tcx, Tag, Extra> Allocation { self.undef_mask.is_range_defined( ptr.offset, ptr.offset + size, - ).or_else(|idx| err!(ReadUndefBytes(idx))) + ).or_else(|idx| throw_err!(ReadUndefBytes(idx))) } pub fn mark_definedness( diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index 36635e62c15e1..183298ee3f1e3 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -184,7 +184,7 @@ pub fn struct_error<'tcx>(tcx: TyCtxtAt<'tcx>, msg: &str) -> DiagnosticBuilder<' /// Packages the kind of error we got from the const code interpreter /// up with a Rust-level backtrace of where the error occured. /// Thsese should always be constructed by calling `.into()` on -/// a `InterpError`. In `librustc_mir::interpret`, we have the `err!` +/// a `InterpError`. In `librustc_mir::interpret`, we have the `throw_err!` /// macro for this. #[derive(Debug, Clone)] pub struct InterpErrorInfo<'tcx> { diff --git a/src/librustc/mir/interpret/interp_error.rs b/src/librustc/mir/interpret/interp_error.rs deleted file mode 100644 index c5a7adf1b6710..0000000000000 --- a/src/librustc/mir/interpret/interp_error.rs +++ /dev/null @@ -1,20 +0,0 @@ -//! macros to do something like `.ok_or_else(|| inval!(TooGeneric).into())` rather than -//! `.ok_or_else(|| InterpError::InvalidProgram(TooGeneric).into())` - -#[macro_export] -macro_rules! inval { - ($($tt:tt)*) => { - $crate::mir::interpret::InterpError::InvalidProgram( - $crate::mir::interpret::InvalidProgramInfo::$($tt)* - ) - }; -} - -#[macro_export] -macro_rules! unsup { - ($($tt:tt)*) => { - $crate::mir::interpret::InterpError::Unsupported( - $crate::mir::interpret::UnsupportedOpInfo::$($tt)* - ) - }; -} diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs index 064ff831e4ee8..6e8e56a1b11f5 100644 --- a/src/librustc/mir/interpret/mod.rs +++ b/src/librustc/mir/interpret/mod.rs @@ -1,7 +1,7 @@ //! An interpreter for MIR used in CTFE and by miri #[macro_export] -macro_rules! err { +macro_rules! throw_err { ($($tt:tt)*) => { Err($crate::mir::interpret::InterpError::Unsupported( $crate::mir::interpret::UnsupportedOpInfo::$($tt)* @@ -10,7 +10,7 @@ macro_rules! err { } #[macro_export] -macro_rules! err_inval { +macro_rules! throw_err_inval { ($($tt:tt)*) => { Err($crate::mir::interpret::InterpError::InvalidProgram( $crate::mir::interpret::InvalidProgramInfo::$($tt)* @@ -19,7 +19,7 @@ macro_rules! err_inval { } #[macro_export] -macro_rules! err_ub { +macro_rules! throw_err_ub { ($($tt:tt)*) => { Err($crate::mir::interpret::InterpError::UndefinedBehaviour( $crate::mir::interpret::UndefinedBehaviourInfo::$($tt)* @@ -28,7 +28,7 @@ macro_rules! err_ub { } #[macro_export] -macro_rules! err_panic { +macro_rules! throw_err_panic { ($($tt:tt)*) => { Err($crate::mir::interpret::InterpError::Panic( $crate::mir::interpret::PanicInfo::$($tt)* @@ -37,7 +37,7 @@ macro_rules! err_panic { } #[macro_export] -macro_rules! err_exhaust { +macro_rules! throw_err_exhaust { ($($tt:tt)*) => { Err($crate::mir::interpret::InterpError::ResourceExhaustion( $crate::mir::interpret::ResourceExhaustionInfo::$($tt)* @@ -45,11 +45,28 @@ macro_rules! err_exhaust { }; } +#[macro_export] +macro_rules! err_inval { + ($($tt:tt)*) => { + $crate::mir::interpret::InterpError::InvalidProgram( + $crate::mir::interpret::InvalidProgramInfo::$($tt)* + ) + }; +} + +#[macro_export] +macro_rules! err { + ($($tt:tt)*) => { + $crate::mir::interpret::InterpError::Unsupported( + $crate::mir::interpret::UnsupportedOpInfo::$($tt)* + ) + }; +} + mod error; mod value; mod allocation; mod pointer; -mod interp_error; pub use self::error::{ InterpErrorInfo, InterpResult, InterpError, AssertMessage, ConstEvalErr, struct_error, diff --git a/src/librustc/mir/interpret/pointer.rs b/src/librustc/mir/interpret/pointer.rs index fbc726deb3dc3..27a41bba4c1b1 100644 --- a/src/librustc/mir/interpret/pointer.rs +++ b/src/librustc/mir/interpret/pointer.rs @@ -74,13 +74,13 @@ pub trait PointerArithmetic: layout::HasDataLayout { #[inline] fn offset<'tcx>(&self, val: u64, i: u64) -> InterpResult<'tcx, u64> { let (res, over) = self.overflowing_offset(val, i); - if over { err_panic!(Overflow(mir::BinOp::Add)) } else { Ok(res) } + if over { throw_err_panic!(Overflow(mir::BinOp::Add)) } else { Ok(res) } } #[inline] fn signed_offset<'tcx>(&self, val: u64, i: i64) -> InterpResult<'tcx, u64> { let (res, over) = self.overflowing_signed_offset(val, i128::from(i)); - if over { err_panic!(Overflow(mir::BinOp::Add)) } else { Ok(res) } + if over { throw_err_panic!(Overflow(mir::BinOp::Add)) } else { Ok(res) } } } @@ -196,7 +196,7 @@ impl<'tcx, Tag> Pointer { msg: CheckInAllocMsg, ) -> InterpResult<'tcx, ()> { if self.offset > allocation_size { - err!(PointerOutOfBounds { ptr: self.erase_tag(), msg, allocation_size }) + throw_err!(PointerOutOfBounds { ptr: self.erase_tag(), msg, allocation_size }) } else { Ok(()) } diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs index 4a59d845b3b42..9379054bdfc9d 100644 --- a/src/librustc/mir/interpret/value.rs +++ b/src/librustc/mir/interpret/value.rs @@ -360,7 +360,7 @@ impl<'tcx, Tag> Scalar { Scalar::check_data(data, size); Ok(data) } - Scalar::Ptr(_) => err!(ReadPointerAsBytes), + Scalar::Ptr(_) => throw_err!(ReadPointerAsBytes), } } @@ -373,8 +373,8 @@ impl<'tcx, Tag> Scalar { #[inline] pub fn to_ptr(self) -> InterpResult<'tcx, Pointer> { match self { - Scalar::Raw { data: 0, .. } => err!(InvalidNullPointerUsage), - Scalar::Raw { .. } => err!(ReadBytesAsPointer), + Scalar::Raw { data: 0, .. } => throw_err!(InvalidNullPointerUsage), + Scalar::Raw { .. } => throw_err!(ReadBytesAsPointer), Scalar::Ptr(p) => Ok(p), } } @@ -406,7 +406,7 @@ impl<'tcx, Tag> Scalar { match self { Scalar::Raw { data: 0, size: 1 } => Ok(false), Scalar::Raw { data: 1, size: 1 } => Ok(true), - _ => err!(InvalidBool), + _ => throw_err!(InvalidBool), } } @@ -414,7 +414,7 @@ impl<'tcx, Tag> Scalar { let val = self.to_u32()?; match ::std::char::from_u32(val) { Some(c) => Ok(c), - None => err!(InvalidChar(val as u128)), + None => throw_err!(InvalidChar(val as u128)), } } @@ -537,7 +537,7 @@ impl<'tcx, Tag> ScalarMaybeUndef { pub fn not_undef(self) -> InterpResult<'static, Scalar> { match self { ScalarMaybeUndef::Scalar(scalar) => Ok(scalar), - ScalarMaybeUndef::Undef => err!(ReadUndefBytes(Size::from_bytes(0))), + ScalarMaybeUndef::Undef => throw_err!(ReadUndefBytes(Size::from_bytes(0))), } } diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 97b89552cff39..786e2e71ec664 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -352,7 +352,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, ecx.goto_block(ret)?; // fully evaluated and done Ok(None) } else { - err!(MachineError(format!("calling non-const function `{}`", instance))) + throw_err!(MachineError(format!("calling non-const function `{}`", instance))) }; } } @@ -412,7 +412,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, _tcx: TyCtxt<'tcx>, _def_id: DefId, ) -> InterpResult<'tcx, Cow<'tcx, Allocation>> { - err!(ReadForeignStatic) + throw_err!(ReadForeignStatic) } #[inline(always)] diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs index 4cb8351947b3c..fb0ad26d56695 100644 --- a/src/librustc_mir/interpret/cast.rs +++ b/src/librustc_mir/interpret/cast.rs @@ -85,7 +85,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.param_env, def_id, substs, - ).ok_or_else(|| inval!(TooGeneric).into()); + ).ok_or_else(|| err_inval!(TooGeneric).into()); let fn_ptr = self.memory.create_fn_alloc(FnVal::Instance(instance?)); self.write_scalar(Scalar::Ptr(fn_ptr.into()), dest)?; } @@ -199,7 +199,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { }, // Casts to bool are not permitted by rustc, no need to handle them here. - _ => err!(Unimplemented(format!("int to {:?} cast", dest_layout.ty))), + _ => throw_err!(Unimplemented(format!("int to {:?} cast", dest_layout.ty))), } } diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index c0e61184780ba..61ebcb58b91b2 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -135,7 +135,7 @@ pub enum LocalValue { impl<'tcx, Tag: Copy + 'static> LocalState<'tcx, Tag> { pub fn access(&self) -> InterpResult<'tcx, Operand> { match self.value { - LocalValue::Dead => err!(DeadLocal), + LocalValue::Dead => throw_err!(DeadLocal), LocalValue::Uninitialized => bug!("The type checker should prevent reading from a never-written local"), LocalValue::Live(val) => Ok(val), @@ -148,7 +148,7 @@ impl<'tcx, Tag: Copy + 'static> LocalState<'tcx, Tag> { &mut self, ) -> InterpResult<'tcx, Result<&mut LocalValue, MemPlace>> { match self.value { - LocalValue::Dead => err!(DeadLocal), + LocalValue::Dead => throw_err!(DeadLocal), LocalValue::Live(Operand::Indirect(mplace)) => Ok(Err(mplace)), ref mut local @ LocalValue::Live(Operand::Immediate(_)) | ref mut local @ LocalValue::Uninitialized => { @@ -305,7 +305,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { &substs, )), None => if substs.needs_subst() { - err_inval!(TooGeneric) + throw_err_inval!(TooGeneric) } else { Ok(substs) }, @@ -326,7 +326,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.param_env, def_id, substs, - ).ok_or_else(|| inval!(TooGeneric).into()) + ).ok_or_else(|| err_inval!(TooGeneric).into()) } pub fn load_mir( @@ -339,14 +339,14 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { && self.tcx.has_typeck_tables(did) && self.tcx.typeck_tables_of(did).tainted_by_errors { - return err_inval!(TypeckError); + return throw_err_inval!(TypeckError); } trace!("load mir {:?}", instance); match instance { ty::InstanceDef::Item(def_id) => if self.tcx.is_mir_available(did) { Ok(self.tcx.optimized_mir(did)) } else { - err!(NoMirFor(self.tcx.def_path_str(def_id))) + throw_err!(NoMirFor(self.tcx.def_path_str(def_id))) }, _ => Ok(self.tcx.instance_mir(instance)), } @@ -359,7 +359,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { match self.stack.last() { Some(frame) => Ok(self.monomorphize_with_substs(t, frame.instance.substs)?), None => if t.needs_subst() { - err_inval!(TooGeneric).into() + throw_err_inval!(TooGeneric).into() } else { Ok(t) }, @@ -376,7 +376,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let substituted = t.subst(*self.tcx, substs); if substituted.needs_subst() { - return err_inval!(TooGeneric); + return throw_err_inval!(TooGeneric); } Ok(self.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), substituted)) @@ -575,7 +575,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { info!("ENTERING({}) {}", self.cur_frame(), self.frame().instance); if self.stack.len() > self.tcx.sess.const_eval_stack_frame_limit { - err_exhaust!(StackFrameLimitReached) + throw_err_exhaust!(StackFrameLimitReached) } else { Ok(()) } @@ -623,7 +623,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } } else { // Uh, that shouldn't happen... the function did not intend to return - return err_ub!(Unreachable); + return throw_err_ub!(Unreachable); } // Jump to new block -- *after* validation so that the spans make more sense. match frame.return_to_block { diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs index af7da6fa53229..f362ea812f5fa 100644 --- a/src/librustc_mir/interpret/intern.rs +++ b/src/librustc_mir/interpret/intern.rs @@ -328,7 +328,7 @@ pub fn intern_const_alloc_recursive( } } else if ecx.memory().dead_alloc_map.contains_key(&alloc_id) { // dangling pointer - return err!(ValidationFailure("encountered dangling pointer in final constant".into())) + return throw_err!(ValidationFailure("encountered dangling pointer in final constant".into())) } } Ok(()) diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index 0b4df6cc7bc59..d571d90e896f8 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -104,7 +104,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { }; let out_val = if intrinsic_name.ends_with("_nonzero") { if bits == 0 { - return err!(Intrinsic(format!("{} called on 0", intrinsic_name))); + return throw_err!(Intrinsic(format!("{} called on 0", intrinsic_name))); } numeric_intrinsic(intrinsic_name.trim_end_matches("_nonzero"), bits, kind)? } else { @@ -190,7 +190,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { if overflowed { let layout = self.layout_of(substs.type_at(0))?; let r_val = r.to_scalar()?.to_bits(layout.size)?; - return err!(Intrinsic( + return throw_err!(Intrinsic( format!("Overflowing shift by {} in {}", r_val, intrinsic_name), )); } diff --git a/src/librustc_mir/interpret/machine.rs b/src/librustc_mir/interpret/machine.rs index 064ca0f4253bb..5fc43c7712c55 100644 --- a/src/librustc_mir/interpret/machine.rs +++ b/src/librustc_mir/interpret/machine.rs @@ -251,6 +251,6 @@ pub trait Machine<'mir, 'tcx>: Sized { _mem: &Memory<'mir, 'tcx, Self>, _ptr: Pointer, ) -> InterpResult<'tcx, u64> { - err!(ReadPointerAsBytes) + throw_err!(ReadPointerAsBytes) } } diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index edaf7855e872f..ee5607c49386c 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -66,7 +66,7 @@ impl<'tcx, Other> FnVal<'tcx, Other> { match self { FnVal::Instance(instance) => Ok(instance), - FnVal::Other(_) => err!(MachineError(format!( + FnVal::Other(_) => throw_err!(MachineError(format!( "Expected instance function pointer, got 'other' pointer" ))), } @@ -202,7 +202,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { kind: MemoryKind, ) -> InterpResult<'tcx, Pointer> { if ptr.offset.bytes() != 0 { - return err!(ReallocateNonBasePtr); + return throw_err!(ReallocateNonBasePtr); } // For simplicities' sake, we implement reallocate as "alloc, copy, dealloc". @@ -243,7 +243,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { trace!("deallocating: {}", ptr.alloc_id); if ptr.offset.bytes() != 0 { - return err!(DeallocateNonBasePtr); + return throw_err!(DeallocateNonBasePtr); } let (alloc_kind, mut alloc) = match self.alloc_map.remove(&ptr.alloc_id) { @@ -251,22 +251,22 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { None => { // Deallocating static memory -- always an error return match self.tcx.alloc_map.lock().get(ptr.alloc_id) { - Some(GlobalAlloc::Function(..)) => err!(DeallocatedWrongMemoryKind( + Some(GlobalAlloc::Function(..)) => throw_err!(DeallocatedWrongMemoryKind( "function".to_string(), format!("{:?}", kind), )), Some(GlobalAlloc::Static(..)) | - Some(GlobalAlloc::Memory(..)) => err!(DeallocatedWrongMemoryKind( + Some(GlobalAlloc::Memory(..)) => throw_err!(DeallocatedWrongMemoryKind( "static".to_string(), format!("{:?}", kind), )), - None => err!(DoubleFree) + None => throw_err!(DoubleFree) } } }; if alloc_kind != kind { - return err!(DeallocatedWrongMemoryKind( + return throw_err!(DeallocatedWrongMemoryKind( format!("{:?}", alloc_kind), format!("{:?}", kind), )); @@ -274,7 +274,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { if let Some((size, align)) = old_size_and_align { if size.bytes() != alloc.bytes.len() as u64 || align != alloc.align { let bytes = Size::from_bytes(alloc.bytes.len() as u64); - return err!(IncorrectAllocationInformation(size, bytes, align, alloc.align)); + return throw_err!(IncorrectAllocationInformation(size, bytes, align, alloc.align)); } } @@ -319,7 +319,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { } else { // The biggest power of two through which `offset` is divisible. let offset_pow2 = 1 << offset.trailing_zeros(); - err!(AlignmentCheckFailed { + throw_err!(AlignmentCheckFailed { has: Align::from_bytes(offset_pow2).unwrap(), required: align, }) @@ -341,7 +341,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { assert!(size.bytes() == 0); // Must be non-NULL and aligned. if bits == 0 { - return err!(InvalidNullPointerUsage); + return throw_err!(InvalidNullPointerUsage); } check_offset_align(bits, align)?; None @@ -362,7 +362,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { // got picked we might be aligned even if this check fails. // We instead have to fall back to converting to an integer and checking // the "real" alignment. - return err!(AlignmentCheckFailed { + return throw_err!(AlignmentCheckFailed { has: alloc_align, required: align, }); @@ -413,9 +413,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { Some(GlobalAlloc::Memory(mem)) => Cow::Borrowed(mem), Some(GlobalAlloc::Function(..)) => - return err!(DerefFunctionPointer), + return throw_err!(DerefFunctionPointer), None => - return err!(DanglingPointerDeref), + return throw_err!(DanglingPointerDeref), Some(GlobalAlloc::Static(def_id)) => { // We got a "lazy" static that has not been computed yet. if tcx.is_foreign_item(def_id) { @@ -505,11 +505,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { // to give us a cheap reference. let alloc = Self::get_static_alloc(memory_extra, tcx, id)?; if alloc.mutability == Mutability::Immutable { - return err!(ModifiedConstantMemory); + return throw_err!(ModifiedConstantMemory); } match M::STATIC_KIND { Some(kind) => Ok((MemoryKind::Machine(kind), alloc.into_owned())), - None => err!(ModifiedStatic), + None => throw_err!(ModifiedStatic), } }); // Unpack the error type manually because type inference doesn't @@ -519,7 +519,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { Ok(a) => { let a = &mut a.1; if a.mutability == Mutability::Immutable { - return err!(ModifiedConstantMemory); + return throw_err!(ModifiedConstantMemory); } Ok(a) } @@ -548,7 +548,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { if let Ok(_) = self.get_fn_alloc(id) { return if let AllocCheck::Dereferencable = liveness { // The caller requested no function pointers. - err!(DerefFunctionPointer) + throw_err!(DerefFunctionPointer) } else { Ok((Size::ZERO, Align::from_bytes(1).unwrap())) }; @@ -579,7 +579,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { .expect("deallocated pointers should all be recorded in \ `dead_alloc_map`")) } else { - err!(DanglingPointerDeref) + throw_err!(DanglingPointerDeref) }, } } @@ -591,7 +591,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { } else { match self.tcx.alloc_map.lock().get(id) { Some(GlobalAlloc::Function(instance)) => Ok(FnVal::Instance(instance)), - _ => err!(ExecuteMemory), + _ => throw_err!(ExecuteMemory), } } } @@ -602,7 +602,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { ) -> InterpResult<'tcx, FnVal<'tcx, M::ExtraFnVal>> { let ptr = self.force_ptr(ptr)?; // We definitely need a pointer value. if ptr.offset.bytes() != 0 { - return err!(InvalidFunctionPointer); + return throw_err!(InvalidFunctionPointer); } self.get_fn_alloc(ptr.alloc_id) } @@ -837,7 +837,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { if (src.offset <= dest.offset && src.offset + size > dest.offset) || (dest.offset <= src.offset && dest.offset + size > src.offset) { - return err!(Intrinsic( + return throw_err!(Intrinsic( "copy_nonoverlapping called on overlapping ranges".to_string(), )); } diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index cdc89e7055cd2..346dd83f1d59a 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -461,7 +461,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { mir_place.iterate(|place_base, place_projection| { let mut op = match place_base { PlaceBase::Local(mir::RETURN_PLACE) => - return err!(ReadFromReturnPointer), + return throw_err!(ReadFromReturnPointer), PlaceBase::Local(local) => { // Do not use the layout passed in as argument if the base we are looking at // here is not the entire place. @@ -534,7 +534,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { match val.val { ConstValue::Param(_) => // FIXME(oli-obk): try to monomorphize - return err_inval!(TooGeneric), + return throw_err_inval!(TooGeneric), ConstValue::Unevaluated(def_id, substs) => { let instance = self.resolve(def_id, substs)?; return Ok(OpTy::from(self.const_eval_raw(GlobalId { @@ -610,7 +610,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let bits_discr = match raw_discr.to_bits(discr_val.layout.size) { Ok(raw_discr) => raw_discr, Err(_) => - return err!(InvalidDiscriminant(raw_discr.erase_tag())), + return throw_err!(InvalidDiscriminant(raw_discr.erase_tag())), }; let real_discr = if discr_val.layout.ty.is_signed() { // going from layout tag type to typeck discriminant type @@ -637,7 +637,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { .find(|(_, var)| var.val == real_discr), _ => bug!("tagged layout for non-adt non-generator"), }.ok_or_else( - || unsup!(InvalidDiscriminant(raw_discr.erase_tag())) + || err!(InvalidDiscriminant(raw_discr.erase_tag())) )?; (real_discr, index.0) }, @@ -657,7 +657,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let ptr_valid = niche_start == 0 && variants_start == variants_end && !self.memory.ptr_may_be_null(ptr); if !ptr_valid { - return err!(InvalidDiscriminant(raw_discr.erase_tag().into())); + return throw_err!(InvalidDiscriminant(raw_discr.erase_tag().into())); } (dataful_variant.as_u32() as u128, dataful_variant) }, diff --git a/src/librustc_mir/interpret/operator.rs b/src/librustc_mir/interpret/operator.rs index eecb752e72be2..5aea423e388ab 100644 --- a/src/librustc_mir/interpret/operator.rs +++ b/src/librustc_mir/interpret/operator.rs @@ -155,7 +155,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { r, right_layout.ty ); - return err!(Unimplemented(msg)); + return throw_err!(Unimplemented(msg)); } // Operations that need special treatment for signed integers @@ -173,8 +173,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { return Ok((Scalar::from_bool(op(&l, &r)), false)); } let op: Option (i128, bool)> = match bin_op { - Div if r == 0 => return err_panic!(DivisionByZero), - Rem if r == 0 => return err_panic!(RemainderByZero), + Div if r == 0 => return throw_err_panic!(DivisionByZero), + Rem if r == 0 => return throw_err_panic!(RemainderByZero), Div => Some(i128::overflowing_div), Rem => Some(i128::overflowing_rem), Add => Some(i128::overflowing_add), @@ -231,8 +231,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Add => u128::overflowing_add, Sub => u128::overflowing_sub, Mul => u128::overflowing_mul, - Div if r == 0 => return err_panic!(DivisionByZero), - Rem if r == 0 => return err_panic!(RemainderByZero), + Div if r == 0 => return throw_err_panic!(DivisionByZero), + Rem if r == 0 => return throw_err_panic!(RemainderByZero), Div => u128::overflowing_div, Rem => u128::overflowing_rem, _ => bug!(), @@ -250,7 +250,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { r, right_layout.ty, ); - return err!(Unimplemented(msg)); + return throw_err!(Unimplemented(msg)); } }; diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 75e3f70aebb31..4349c99a6196c 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -356,7 +356,7 @@ where // This can be violated because this runs during promotion on code where the // type system has not yet ensured that such things don't happen. debug!("tried to access element {} of array/slice with length {}", field, len); - return err_panic!(BoundsCheck { len, index: field }); + return throw_err_panic!(BoundsCheck { len, index: field }); } stride * field } @@ -622,7 +622,7 @@ where .layout_of(self.monomorphize(self.frame().body.return_ty())?)?, } } - None => return err!(InvalidNullPointerUsage), + None => return throw_err!(InvalidNullPointerUsage), }, PlaceBase::Local(local) => PlaceTy { // This works even for dead/uninitialized locals; we check further when writing diff --git a/src/librustc_mir/interpret/step.rs b/src/librustc_mir/interpret/step.rs index 246c90ba48e3a..3aa0144fa8f68 100644 --- a/src/librustc_mir/interpret/step.rs +++ b/src/librustc_mir/interpret/step.rs @@ -121,7 +121,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // size of MIR constantly. Nop => {} - InlineAsm { .. } => return err!(InlineAsm), + InlineAsm { .. } => return throw_err!(InlineAsm), } self.stack[frame_idx].stmt += 1; diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs index 51ed156f6cfcf..5399220108118 100644 --- a/src/librustc_mir/interpret/terminator.rs +++ b/src/librustc_mir/interpret/terminator.rs @@ -19,7 +19,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.frame_mut().stmt = 0; Ok(()) } else { - err_ub!(Unreachable) + throw_err_ub!(Unreachable) } } @@ -89,7 +89,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { }, _ => { let msg = format!("can't handle callee of type {:?}", func.layout.ty); - return err!(Unimplemented(msg)); + return throw_err!(Unimplemented(msg)); } }; let args = self.eval_operands(args)?; @@ -144,20 +144,20 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let index = self.read_immediate(self.eval_operand(index, None)?) .expect("can't eval index").to_scalar()? .to_bits(self.memory().pointer_size())? as u64; - err_panic!(BoundsCheck { len, index }) + throw_err_panic!(BoundsCheck { len, index }) } Overflow(op) => - err_panic!(Overflow(*op)), + throw_err_panic!(Overflow(*op)), OverflowNeg => - err_panic!(OverflowNeg), + throw_err_panic!(OverflowNeg), DivisionByZero => - err_panic!(DivisionByZero), + throw_err_panic!(DivisionByZero), RemainderByZero => - err_panic!(RemainderByZero), + throw_err_panic!(RemainderByZero), GeneratorResumedAfterReturn => - err_panic!(GeneratorResumedAfterReturn), + throw_err_panic!(GeneratorResumedAfterReturn), GeneratorResumedAfterPanic => - err_panic!(GeneratorResumedAfterPanic), + throw_err_panic!(GeneratorResumedAfterPanic), Panic { .. } => bug!("`Panic` variant cannot occur in MIR"), }; @@ -173,7 +173,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { `simplify_branches` mir pass"), FalseUnwind { .. } => bug!("should have been eliminated by\ `simplify_branches` mir pass"), - Unreachable => return err_ub!(Unreachable), + Unreachable => return throw_err_ub!(Unreachable), } Ok(()) @@ -220,13 +220,13 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { return Ok(()); } let caller_arg = caller_arg.next() - .ok_or_else(|| unsup!(FunctionArgCountMismatch)) ?; + .ok_or_else(|| err!(FunctionArgCountMismatch)) ?; if rust_abi { debug_assert!(!caller_arg.layout.is_zst(), "ZSTs must have been already filtered out"); } // Now, check if !Self::check_argument_compat(rust_abi, caller_arg.layout, callee_arg.layout) { - return err!(FunctionArgMismatch(caller_arg.layout.ty, callee_arg.layout.ty)); + return throw_err!(FunctionArgMismatch(caller_arg.layout.ty, callee_arg.layout.ty)); } // We allow some transmutes here self.copy_op_transmute(caller_arg, callee_arg) @@ -254,13 +254,13 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { match instance.def { ty::InstanceDef::Intrinsic(..) => { if caller_abi != Abi::RustIntrinsic { - return err!(FunctionAbiMismatch(caller_abi, Abi::RustIntrinsic)); + return throw_err!(FunctionAbiMismatch(caller_abi, Abi::RustIntrinsic)); } // The intrinsic itself cannot diverge, so if we got here without a return // place... (can happen e.g., for transmute returning `!`) let dest = match dest { Some(dest) => dest, - None => return err_ub!(Unreachable) + None => return throw_err_ub!(Unreachable) }; M::call_intrinsic(self, instance, args, dest)?; // No stack frame gets pushed, the main loop will just act as if the @@ -295,7 +295,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { abi, }; if normalize_abi(caller_abi) != normalize_abi(callee_abi) { - return err!(FunctionAbiMismatch(caller_abi, callee_abi)); + return throw_err!(FunctionAbiMismatch(caller_abi, callee_abi)); } } @@ -390,7 +390,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Now we should have no more caller args if caller_iter.next().is_some() { trace!("Caller has passed too many args"); - return err!(FunctionArgCountMismatch); + return throw_err!(FunctionArgCountMismatch); } // Don't forget to check the return type! if let Some(caller_ret) = dest { @@ -402,7 +402,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { caller_ret.layout, callee_ret.layout, ) { - return err!( + return throw_err!( FunctionRetMismatch(caller_ret.layout.ty, callee_ret.layout.ty) ); } @@ -410,7 +410,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let local = mir::RETURN_PLACE; let ty = self.frame().body.local_decls[local].ty; if !self.tcx.is_ty_uninhabited_from_any_module(ty) { - return err!(FunctionRetMismatch(self.tcx.types.never, ty)); + return throw_err!(FunctionRetMismatch(self.tcx.types.never, ty)); } } Ok(()) diff --git a/src/librustc_mir/interpret/traits.rs b/src/librustc_mir/interpret/traits.rs index 71f2cfceaf225..e55b0d0fb1f2a 100644 --- a/src/librustc_mir/interpret/traits.rs +++ b/src/librustc_mir/interpret/traits.rs @@ -83,7 +83,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.param_env, def_id, substs, - ).ok_or_else(|| inval!(TooGeneric))?; + ).ok_or_else(|| err_inval!(TooGeneric))?; let fn_ptr = self.memory.create_fn_alloc(FnVal::Instance(instance)); let method_ptr = vtable.offset(ptr_size * (3 + i as u64), self)?; self.memory diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs index 9404711bd9708..511ebfd023cd3 100644 --- a/src/librustc_mir/interpret/validity.rs +++ b/src/librustc_mir/interpret/validity.rs @@ -22,7 +22,7 @@ macro_rules! validation_failure { } else { format!(" at {}", where_) }; - err!(ValidationFailure(format!( + throw_err!(ValidationFailure(format!( "encountered {}{}, but expected {}", $what, where_, $details, ))) @@ -34,7 +34,7 @@ macro_rules! validation_failure { } else { format!(" at {}", where_) }; - err!(ValidationFailure(format!( + throw_err!(ValidationFailure(format!( "encountered {}{}", $what, where_, ))) diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 5043687f060d9..db6b62e95ce0a 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -441,7 +441,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { // Need to do overflow check here: For actual CTFE, MIR // generation emits code that does this before calling the op. if prim.to_bits()? == (1 << (prim.layout.size.bits() - 1)) { - return err_panic!(OverflowNeg); + return throw_err_panic!(OverflowNeg); } } UnOp::Not => { From b60a336e86dece15a277139ba76117ed4f17eb3c Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Tue, 30 Jul 2019 15:46:02 +0530 Subject: [PATCH 17/25] tidy fixes --- src/librustc_mir/interpret/intern.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs index f362ea812f5fa..a47cea9a70ac3 100644 --- a/src/librustc_mir/interpret/intern.rs +++ b/src/librustc_mir/interpret/intern.rs @@ -328,7 +328,9 @@ pub fn intern_const_alloc_recursive( } } else if ecx.memory().dead_alloc_map.contains_key(&alloc_id) { // dangling pointer - return throw_err!(ValidationFailure("encountered dangling pointer in final constant".into())) + return throw_err!( + ValidationFailure("encountered dangling pointer in final constant".into()) + ) } } Ok(()) From fc5df1dfbfdd9af311e04b4841f209b0fc9aaafb Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Tue, 30 Jul 2019 16:08:32 +0530 Subject: [PATCH 18/25] renaming err to err_unsup --- src/librustc/mir/interpret/allocation.rs | 6 +-- src/librustc/mir/interpret/error.rs | 4 +- src/librustc/mir/interpret/mod.rs | 4 +- src/librustc/mir/interpret/pointer.rs | 2 +- src/librustc/mir/interpret/value.rs | 12 +++--- src/librustc_mir/const_eval.rs | 6 ++- src/librustc_mir/interpret/cast.rs | 2 +- src/librustc_mir/interpret/eval_context.rs | 6 +-- src/librustc_mir/interpret/intern.rs | 2 +- src/librustc_mir/interpret/intrinsics.rs | 6 ++- src/librustc_mir/interpret/machine.rs | 2 +- src/librustc_mir/interpret/memory.rs | 44 +++++++++++----------- src/librustc_mir/interpret/operand.rs | 10 +++-- src/librustc_mir/interpret/operator.rs | 4 +- src/librustc_mir/interpret/place.rs | 2 +- src/librustc_mir/interpret/step.rs | 2 +- src/librustc_mir/interpret/terminator.rs | 18 +++++---- src/librustc_mir/interpret/validity.rs | 4 +- 18 files changed, 73 insertions(+), 63 deletions(-) diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs index 00f908007941e..b8686754fa764 100644 --- a/src/librustc/mir/interpret/allocation.rs +++ b/src/librustc/mir/interpret/allocation.rs @@ -244,7 +244,7 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra> Allocation { Ok(&self.get_bytes(cx, ptr, size_with_null)?[..size]) } // This includes the case where `offset` is out-of-bounds to begin with. - None => throw_err!(UnterminatedCString(ptr.erase_tag())), + None => throw_err_unsup!(UnterminatedCString(ptr.erase_tag())), } } @@ -446,7 +446,7 @@ impl<'tcx, Tag: Copy, Extra> Allocation { if self.relocations(cx, ptr, size).is_empty() { Ok(()) } else { - throw_err!(ReadPointerAsBytes) + throw_err_unsup!(ReadPointerAsBytes) } } @@ -516,7 +516,7 @@ impl<'tcx, Tag, Extra> Allocation { self.undef_mask.is_range_defined( ptr.offset, ptr.offset + size, - ).or_else(|idx| throw_err!(ReadUndefBytes(idx))) + ).or_else(|idx| throw_err_unsup!(ReadUndefBytes(idx))) } pub fn mark_definedness( diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index 183298ee3f1e3..7108f69d39ed4 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -184,8 +184,8 @@ pub fn struct_error<'tcx>(tcx: TyCtxtAt<'tcx>, msg: &str) -> DiagnosticBuilder<' /// Packages the kind of error we got from the const code interpreter /// up with a Rust-level backtrace of where the error occured. /// Thsese should always be constructed by calling `.into()` on -/// a `InterpError`. In `librustc_mir::interpret`, we have the `throw_err!` -/// macro for this. +/// a `InterpError`. In `librustc_mir::interpret`, we have `throw_err_*` +/// macros for this. #[derive(Debug, Clone)] pub struct InterpErrorInfo<'tcx> { pub kind: InterpError<'tcx>, diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs index 6e8e56a1b11f5..bc72050de181b 100644 --- a/src/librustc/mir/interpret/mod.rs +++ b/src/librustc/mir/interpret/mod.rs @@ -1,7 +1,7 @@ //! An interpreter for MIR used in CTFE and by miri #[macro_export] -macro_rules! throw_err { +macro_rules! throw_err_unsup { ($($tt:tt)*) => { Err($crate::mir::interpret::InterpError::Unsupported( $crate::mir::interpret::UnsupportedOpInfo::$($tt)* @@ -55,7 +55,7 @@ macro_rules! err_inval { } #[macro_export] -macro_rules! err { +macro_rules! err_unsup { ($($tt:tt)*) => { $crate::mir::interpret::InterpError::Unsupported( $crate::mir::interpret::UnsupportedOpInfo::$($tt)* diff --git a/src/librustc/mir/interpret/pointer.rs b/src/librustc/mir/interpret/pointer.rs index 27a41bba4c1b1..17f963609f6d8 100644 --- a/src/librustc/mir/interpret/pointer.rs +++ b/src/librustc/mir/interpret/pointer.rs @@ -196,7 +196,7 @@ impl<'tcx, Tag> Pointer { msg: CheckInAllocMsg, ) -> InterpResult<'tcx, ()> { if self.offset > allocation_size { - throw_err!(PointerOutOfBounds { ptr: self.erase_tag(), msg, allocation_size }) + throw_err_unsup!(PointerOutOfBounds { ptr: self.erase_tag(), msg, allocation_size }) } else { Ok(()) } diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs index 9379054bdfc9d..01db0e48e21e0 100644 --- a/src/librustc/mir/interpret/value.rs +++ b/src/librustc/mir/interpret/value.rs @@ -360,7 +360,7 @@ impl<'tcx, Tag> Scalar { Scalar::check_data(data, size); Ok(data) } - Scalar::Ptr(_) => throw_err!(ReadPointerAsBytes), + Scalar::Ptr(_) => throw_err_unsup!(ReadPointerAsBytes), } } @@ -373,8 +373,8 @@ impl<'tcx, Tag> Scalar { #[inline] pub fn to_ptr(self) -> InterpResult<'tcx, Pointer> { match self { - Scalar::Raw { data: 0, .. } => throw_err!(InvalidNullPointerUsage), - Scalar::Raw { .. } => throw_err!(ReadBytesAsPointer), + Scalar::Raw { data: 0, .. } => throw_err_unsup!(InvalidNullPointerUsage), + Scalar::Raw { .. } => throw_err_unsup!(ReadBytesAsPointer), Scalar::Ptr(p) => Ok(p), } } @@ -406,7 +406,7 @@ impl<'tcx, Tag> Scalar { match self { Scalar::Raw { data: 0, size: 1 } => Ok(false), Scalar::Raw { data: 1, size: 1 } => Ok(true), - _ => throw_err!(InvalidBool), + _ => throw_err_unsup!(InvalidBool), } } @@ -414,7 +414,7 @@ impl<'tcx, Tag> Scalar { let val = self.to_u32()?; match ::std::char::from_u32(val) { Some(c) => Ok(c), - None => throw_err!(InvalidChar(val as u128)), + None => throw_err_unsup!(InvalidChar(val as u128)), } } @@ -537,7 +537,7 @@ impl<'tcx, Tag> ScalarMaybeUndef { pub fn not_undef(self) -> InterpResult<'static, Scalar> { match self { ScalarMaybeUndef::Scalar(scalar) => Ok(scalar), - ScalarMaybeUndef::Undef => throw_err!(ReadUndefBytes(Size::from_bytes(0))), + ScalarMaybeUndef::Undef => throw_err_unsup!(ReadUndefBytes(Size::from_bytes(0))), } } diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 786e2e71ec664..423449bc95d4e 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -352,7 +352,9 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, ecx.goto_block(ret)?; // fully evaluated and done Ok(None) } else { - throw_err!(MachineError(format!("calling non-const function `{}`", instance))) + throw_err_unsup!( + MachineError(format!("calling non-const function `{}`", instance)) + ) }; } } @@ -412,7 +414,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, _tcx: TyCtxt<'tcx>, _def_id: DefId, ) -> InterpResult<'tcx, Cow<'tcx, Allocation>> { - throw_err!(ReadForeignStatic) + throw_err_unsup!(ReadForeignStatic) } #[inline(always)] diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs index fb0ad26d56695..94f3148aaaf9e 100644 --- a/src/librustc_mir/interpret/cast.rs +++ b/src/librustc_mir/interpret/cast.rs @@ -199,7 +199,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { }, // Casts to bool are not permitted by rustc, no need to handle them here. - _ => throw_err!(Unimplemented(format!("int to {:?} cast", dest_layout.ty))), + _ => throw_err_unsup!(Unimplemented(format!("int to {:?} cast", dest_layout.ty))), } } diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 61ebcb58b91b2..61ee60fd3d503 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -135,7 +135,7 @@ pub enum LocalValue { impl<'tcx, Tag: Copy + 'static> LocalState<'tcx, Tag> { pub fn access(&self) -> InterpResult<'tcx, Operand> { match self.value { - LocalValue::Dead => throw_err!(DeadLocal), + LocalValue::Dead => throw_err_unsup!(DeadLocal), LocalValue::Uninitialized => bug!("The type checker should prevent reading from a never-written local"), LocalValue::Live(val) => Ok(val), @@ -148,7 +148,7 @@ impl<'tcx, Tag: Copy + 'static> LocalState<'tcx, Tag> { &mut self, ) -> InterpResult<'tcx, Result<&mut LocalValue, MemPlace>> { match self.value { - LocalValue::Dead => throw_err!(DeadLocal), + LocalValue::Dead => throw_err_unsup!(DeadLocal), LocalValue::Live(Operand::Indirect(mplace)) => Ok(Err(mplace)), ref mut local @ LocalValue::Live(Operand::Immediate(_)) | ref mut local @ LocalValue::Uninitialized => { @@ -346,7 +346,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ty::InstanceDef::Item(def_id) => if self.tcx.is_mir_available(did) { Ok(self.tcx.optimized_mir(did)) } else { - throw_err!(NoMirFor(self.tcx.def_path_str(def_id))) + throw_err_unsup!(NoMirFor(self.tcx.def_path_str(def_id))) }, _ => Ok(self.tcx.instance_mir(instance)), } diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs index a47cea9a70ac3..4539a1c7e1ddd 100644 --- a/src/librustc_mir/interpret/intern.rs +++ b/src/librustc_mir/interpret/intern.rs @@ -328,7 +328,7 @@ pub fn intern_const_alloc_recursive( } } else if ecx.memory().dead_alloc_map.contains_key(&alloc_id) { // dangling pointer - return throw_err!( + return throw_err_unsup!( ValidationFailure("encountered dangling pointer in final constant".into()) ) } diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index d571d90e896f8..687265c983f26 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -104,7 +104,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { }; let out_val = if intrinsic_name.ends_with("_nonzero") { if bits == 0 { - return throw_err!(Intrinsic(format!("{} called on 0", intrinsic_name))); + return throw_err_unsup!( + Intrinsic(format!("{} called on 0", intrinsic_name)) + ); } numeric_intrinsic(intrinsic_name.trim_end_matches("_nonzero"), bits, kind)? } else { @@ -190,7 +192,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { if overflowed { let layout = self.layout_of(substs.type_at(0))?; let r_val = r.to_scalar()?.to_bits(layout.size)?; - return throw_err!(Intrinsic( + return throw_err_unsup!(Intrinsic( format!("Overflowing shift by {} in {}", r_val, intrinsic_name), )); } diff --git a/src/librustc_mir/interpret/machine.rs b/src/librustc_mir/interpret/machine.rs index 5fc43c7712c55..3f3d4376d29cd 100644 --- a/src/librustc_mir/interpret/machine.rs +++ b/src/librustc_mir/interpret/machine.rs @@ -251,6 +251,6 @@ pub trait Machine<'mir, 'tcx>: Sized { _mem: &Memory<'mir, 'tcx, Self>, _ptr: Pointer, ) -> InterpResult<'tcx, u64> { - throw_err!(ReadPointerAsBytes) + throw_err_unsup!(ReadPointerAsBytes) } } diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index ee5607c49386c..8c43fb3dc40de 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -66,7 +66,7 @@ impl<'tcx, Other> FnVal<'tcx, Other> { match self { FnVal::Instance(instance) => Ok(instance), - FnVal::Other(_) => throw_err!(MachineError(format!( + FnVal::Other(_) => throw_err_unsup!(MachineError(format!( "Expected instance function pointer, got 'other' pointer" ))), } @@ -202,7 +202,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { kind: MemoryKind, ) -> InterpResult<'tcx, Pointer> { if ptr.offset.bytes() != 0 { - return throw_err!(ReallocateNonBasePtr); + return throw_err_unsup!(ReallocateNonBasePtr); } // For simplicities' sake, we implement reallocate as "alloc, copy, dealloc". @@ -243,7 +243,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { trace!("deallocating: {}", ptr.alloc_id); if ptr.offset.bytes() != 0 { - return throw_err!(DeallocateNonBasePtr); + return throw_err_unsup!(DeallocateNonBasePtr); } let (alloc_kind, mut alloc) = match self.alloc_map.remove(&ptr.alloc_id) { @@ -251,22 +251,22 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { None => { // Deallocating static memory -- always an error return match self.tcx.alloc_map.lock().get(ptr.alloc_id) { - Some(GlobalAlloc::Function(..)) => throw_err!(DeallocatedWrongMemoryKind( + Some(GlobalAlloc::Function(..)) => throw_err_unsup!(DeallocatedWrongMemoryKind( "function".to_string(), format!("{:?}", kind), )), Some(GlobalAlloc::Static(..)) | - Some(GlobalAlloc::Memory(..)) => throw_err!(DeallocatedWrongMemoryKind( + Some(GlobalAlloc::Memory(..)) => throw_err_unsup!(DeallocatedWrongMemoryKind( "static".to_string(), format!("{:?}", kind), )), - None => throw_err!(DoubleFree) + None => throw_err_unsup!(DoubleFree) } } }; if alloc_kind != kind { - return throw_err!(DeallocatedWrongMemoryKind( + return throw_err_unsup!(DeallocatedWrongMemoryKind( format!("{:?}", alloc_kind), format!("{:?}", kind), )); @@ -274,7 +274,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { if let Some((size, align)) = old_size_and_align { if size.bytes() != alloc.bytes.len() as u64 || align != alloc.align { let bytes = Size::from_bytes(alloc.bytes.len() as u64); - return throw_err!(IncorrectAllocationInformation(size, bytes, align, alloc.align)); + return throw_err_unsup!( + IncorrectAllocationInformation(size, bytes, align, alloc.align) + ); } } @@ -319,7 +321,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { } else { // The biggest power of two through which `offset` is divisible. let offset_pow2 = 1 << offset.trailing_zeros(); - throw_err!(AlignmentCheckFailed { + throw_err_unsup!(AlignmentCheckFailed { has: Align::from_bytes(offset_pow2).unwrap(), required: align, }) @@ -341,7 +343,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { assert!(size.bytes() == 0); // Must be non-NULL and aligned. if bits == 0 { - return throw_err!(InvalidNullPointerUsage); + return throw_err_unsup!(InvalidNullPointerUsage); } check_offset_align(bits, align)?; None @@ -362,7 +364,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { // got picked we might be aligned even if this check fails. // We instead have to fall back to converting to an integer and checking // the "real" alignment. - return throw_err!(AlignmentCheckFailed { + return throw_err_unsup!(AlignmentCheckFailed { has: alloc_align, required: align, }); @@ -413,9 +415,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { Some(GlobalAlloc::Memory(mem)) => Cow::Borrowed(mem), Some(GlobalAlloc::Function(..)) => - return throw_err!(DerefFunctionPointer), + return throw_err_unsup!(DerefFunctionPointer), None => - return throw_err!(DanglingPointerDeref), + return throw_err_unsup!(DanglingPointerDeref), Some(GlobalAlloc::Static(def_id)) => { // We got a "lazy" static that has not been computed yet. if tcx.is_foreign_item(def_id) { @@ -505,11 +507,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { // to give us a cheap reference. let alloc = Self::get_static_alloc(memory_extra, tcx, id)?; if alloc.mutability == Mutability::Immutable { - return throw_err!(ModifiedConstantMemory); + return throw_err_unsup!(ModifiedConstantMemory); } match M::STATIC_KIND { Some(kind) => Ok((MemoryKind::Machine(kind), alloc.into_owned())), - None => throw_err!(ModifiedStatic), + None => throw_err_unsup!(ModifiedStatic), } }); // Unpack the error type manually because type inference doesn't @@ -519,7 +521,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { Ok(a) => { let a = &mut a.1; if a.mutability == Mutability::Immutable { - return throw_err!(ModifiedConstantMemory); + return throw_err_unsup!(ModifiedConstantMemory); } Ok(a) } @@ -548,7 +550,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { if let Ok(_) = self.get_fn_alloc(id) { return if let AllocCheck::Dereferencable = liveness { // The caller requested no function pointers. - throw_err!(DerefFunctionPointer) + throw_err_unsup!(DerefFunctionPointer) } else { Ok((Size::ZERO, Align::from_bytes(1).unwrap())) }; @@ -579,7 +581,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { .expect("deallocated pointers should all be recorded in \ `dead_alloc_map`")) } else { - throw_err!(DanglingPointerDeref) + throw_err_unsup!(DanglingPointerDeref) }, } } @@ -591,7 +593,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { } else { match self.tcx.alloc_map.lock().get(id) { Some(GlobalAlloc::Function(instance)) => Ok(FnVal::Instance(instance)), - _ => throw_err!(ExecuteMemory), + _ => throw_err_unsup!(ExecuteMemory), } } } @@ -602,7 +604,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { ) -> InterpResult<'tcx, FnVal<'tcx, M::ExtraFnVal>> { let ptr = self.force_ptr(ptr)?; // We definitely need a pointer value. if ptr.offset.bytes() != 0 { - return throw_err!(InvalidFunctionPointer); + return throw_err_unsup!(InvalidFunctionPointer); } self.get_fn_alloc(ptr.alloc_id) } @@ -837,7 +839,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { if (src.offset <= dest.offset && src.offset + size > dest.offset) || (dest.offset <= src.offset && dest.offset + size > src.offset) { - return throw_err!(Intrinsic( + return throw_err_unsup!(Intrinsic( "copy_nonoverlapping called on overlapping ranges".to_string(), )); } diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 346dd83f1d59a..8c443c9579f75 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -461,7 +461,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { mir_place.iterate(|place_base, place_projection| { let mut op = match place_base { PlaceBase::Local(mir::RETURN_PLACE) => - return throw_err!(ReadFromReturnPointer), + return throw_err_unsup!(ReadFromReturnPointer), PlaceBase::Local(local) => { // Do not use the layout passed in as argument if the base we are looking at // here is not the entire place. @@ -610,7 +610,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let bits_discr = match raw_discr.to_bits(discr_val.layout.size) { Ok(raw_discr) => raw_discr, Err(_) => - return throw_err!(InvalidDiscriminant(raw_discr.erase_tag())), + return throw_err_unsup!(InvalidDiscriminant(raw_discr.erase_tag())), }; let real_discr = if discr_val.layout.ty.is_signed() { // going from layout tag type to typeck discriminant type @@ -637,7 +637,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { .find(|(_, var)| var.val == real_discr), _ => bug!("tagged layout for non-adt non-generator"), }.ok_or_else( - || err!(InvalidDiscriminant(raw_discr.erase_tag())) + || err_unsup!(InvalidDiscriminant(raw_discr.erase_tag())) )?; (real_discr, index.0) }, @@ -657,7 +657,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let ptr_valid = niche_start == 0 && variants_start == variants_end && !self.memory.ptr_may_be_null(ptr); if !ptr_valid { - return throw_err!(InvalidDiscriminant(raw_discr.erase_tag().into())); + return throw_err_unsup!( + InvalidDiscriminant(raw_discr.erase_tag().into()) + ); } (dataful_variant.as_u32() as u128, dataful_variant) }, diff --git a/src/librustc_mir/interpret/operator.rs b/src/librustc_mir/interpret/operator.rs index 5aea423e388ab..334cf09ba122b 100644 --- a/src/librustc_mir/interpret/operator.rs +++ b/src/librustc_mir/interpret/operator.rs @@ -155,7 +155,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { r, right_layout.ty ); - return throw_err!(Unimplemented(msg)); + return throw_err_unsup!(Unimplemented(msg)); } // Operations that need special treatment for signed integers @@ -250,7 +250,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { r, right_layout.ty, ); - return throw_err!(Unimplemented(msg)); + return throw_err_unsup!(Unimplemented(msg)); } }; diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 4349c99a6196c..b385862490a23 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -622,7 +622,7 @@ where .layout_of(self.monomorphize(self.frame().body.return_ty())?)?, } } - None => return throw_err!(InvalidNullPointerUsage), + None => return throw_err_unsup!(InvalidNullPointerUsage), }, PlaceBase::Local(local) => PlaceTy { // This works even for dead/uninitialized locals; we check further when writing diff --git a/src/librustc_mir/interpret/step.rs b/src/librustc_mir/interpret/step.rs index 3aa0144fa8f68..de798ecee7348 100644 --- a/src/librustc_mir/interpret/step.rs +++ b/src/librustc_mir/interpret/step.rs @@ -121,7 +121,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // size of MIR constantly. Nop => {} - InlineAsm { .. } => return throw_err!(InlineAsm), + InlineAsm { .. } => return throw_err_unsup!(InlineAsm), } self.stack[frame_idx].stmt += 1; diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs index 5399220108118..f1c91058b713d 100644 --- a/src/librustc_mir/interpret/terminator.rs +++ b/src/librustc_mir/interpret/terminator.rs @@ -89,7 +89,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { }, _ => { let msg = format!("can't handle callee of type {:?}", func.layout.ty); - return throw_err!(Unimplemented(msg)); + return throw_err_unsup!(Unimplemented(msg)); } }; let args = self.eval_operands(args)?; @@ -220,13 +220,15 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { return Ok(()); } let caller_arg = caller_arg.next() - .ok_or_else(|| err!(FunctionArgCountMismatch)) ?; + .ok_or_else(|| err_unsup!(FunctionArgCountMismatch)) ?; if rust_abi { debug_assert!(!caller_arg.layout.is_zst(), "ZSTs must have been already filtered out"); } // Now, check if !Self::check_argument_compat(rust_abi, caller_arg.layout, callee_arg.layout) { - return throw_err!(FunctionArgMismatch(caller_arg.layout.ty, callee_arg.layout.ty)); + return throw_err_unsup!( + FunctionArgMismatch(caller_arg.layout.ty, callee_arg.layout.ty) + ); } // We allow some transmutes here self.copy_op_transmute(caller_arg, callee_arg) @@ -254,7 +256,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { match instance.def { ty::InstanceDef::Intrinsic(..) => { if caller_abi != Abi::RustIntrinsic { - return throw_err!(FunctionAbiMismatch(caller_abi, Abi::RustIntrinsic)); + return throw_err_unsup!(FunctionAbiMismatch(caller_abi, Abi::RustIntrinsic)); } // The intrinsic itself cannot diverge, so if we got here without a return // place... (can happen e.g., for transmute returning `!`) @@ -295,7 +297,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { abi, }; if normalize_abi(caller_abi) != normalize_abi(callee_abi) { - return throw_err!(FunctionAbiMismatch(caller_abi, callee_abi)); + return throw_err_unsup!(FunctionAbiMismatch(caller_abi, callee_abi)); } } @@ -390,7 +392,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Now we should have no more caller args if caller_iter.next().is_some() { trace!("Caller has passed too many args"); - return throw_err!(FunctionArgCountMismatch); + return throw_err_unsup!(FunctionArgCountMismatch); } // Don't forget to check the return type! if let Some(caller_ret) = dest { @@ -402,7 +404,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { caller_ret.layout, callee_ret.layout, ) { - return throw_err!( + return throw_err_unsup!( FunctionRetMismatch(caller_ret.layout.ty, callee_ret.layout.ty) ); } @@ -410,7 +412,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let local = mir::RETURN_PLACE; let ty = self.frame().body.local_decls[local].ty; if !self.tcx.is_ty_uninhabited_from_any_module(ty) { - return throw_err!(FunctionRetMismatch(self.tcx.types.never, ty)); + return throw_err_unsup!(FunctionRetMismatch(self.tcx.types.never, ty)); } } Ok(()) diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs index 511ebfd023cd3..df6fb7a7c63c8 100644 --- a/src/librustc_mir/interpret/validity.rs +++ b/src/librustc_mir/interpret/validity.rs @@ -22,7 +22,7 @@ macro_rules! validation_failure { } else { format!(" at {}", where_) }; - throw_err!(ValidationFailure(format!( + throw_err_unsup!(ValidationFailure(format!( "encountered {}{}, but expected {}", $what, where_, $details, ))) @@ -34,7 +34,7 @@ macro_rules! validation_failure { } else { format!(" at {}", where_) }; - throw_err!(ValidationFailure(format!( + throw_err_unsup!(ValidationFailure(format!( "encountered {}{}", $what, where_, ))) From 35417e722ba088b2b9dd832160f6194a64aa3277 Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Tue, 30 Jul 2019 20:18:50 +0530 Subject: [PATCH 19/25] renaming throw_err_* to throw_* --- src/librustc/mir/interpret/allocation.rs | 6 +-- src/librustc/mir/interpret/mod.rs | 20 ++++---- src/librustc/mir/interpret/pointer.rs | 6 +-- src/librustc/mir/interpret/value.rs | 12 ++--- src/librustc_mir/const_eval.rs | 6 +-- src/librustc_mir/interpret/cast.rs | 2 +- src/librustc_mir/interpret/eval_context.rs | 18 ++++---- src/librustc_mir/interpret/intern.rs | 4 +- src/librustc_mir/interpret/intrinsics.rs | 10 ++-- src/librustc_mir/interpret/machine.rs | 2 +- src/librustc_mir/interpret/memory.rs | 54 +++++++++++----------- src/librustc_mir/interpret/operand.rs | 10 ++-- src/librustc_mir/interpret/operator.rs | 12 ++--- src/librustc_mir/interpret/place.rs | 4 +- src/librustc_mir/interpret/step.rs | 2 +- src/librustc_mir/interpret/terminator.rs | 40 ++++++++-------- src/librustc_mir/interpret/validity.rs | 28 ++++++----- src/librustc_mir/transform/const_prop.rs | 2 +- 18 files changed, 112 insertions(+), 126 deletions(-) diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs index b8686754fa764..a9393561bfd09 100644 --- a/src/librustc/mir/interpret/allocation.rs +++ b/src/librustc/mir/interpret/allocation.rs @@ -244,7 +244,7 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra> Allocation { Ok(&self.get_bytes(cx, ptr, size_with_null)?[..size]) } // This includes the case where `offset` is out-of-bounds to begin with. - None => throw_err_unsup!(UnterminatedCString(ptr.erase_tag())), + None => throw_unsup!(UnterminatedCString(ptr.erase_tag())), } } @@ -446,7 +446,7 @@ impl<'tcx, Tag: Copy, Extra> Allocation { if self.relocations(cx, ptr, size).is_empty() { Ok(()) } else { - throw_err_unsup!(ReadPointerAsBytes) + throw_unsup!(ReadPointerAsBytes) } } @@ -516,7 +516,7 @@ impl<'tcx, Tag, Extra> Allocation { self.undef_mask.is_range_defined( ptr.offset, ptr.offset + size, - ).or_else(|idx| throw_err_unsup!(ReadUndefBytes(idx))) + ).or_else(|idx| throw_unsup!(ReadUndefBytes(idx))) } pub fn mark_definedness( diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs index bc72050de181b..2409d22e5f0a3 100644 --- a/src/librustc/mir/interpret/mod.rs +++ b/src/librustc/mir/interpret/mod.rs @@ -1,45 +1,45 @@ //! An interpreter for MIR used in CTFE and by miri #[macro_export] -macro_rules! throw_err_unsup { +macro_rules! throw_unsup { ($($tt:tt)*) => { - Err($crate::mir::interpret::InterpError::Unsupported( + return Err($crate::mir::interpret::InterpError::Unsupported( $crate::mir::interpret::UnsupportedOpInfo::$($tt)* ).into()) }; } #[macro_export] -macro_rules! throw_err_inval { +macro_rules! throw_inval { ($($tt:tt)*) => { - Err($crate::mir::interpret::InterpError::InvalidProgram( + return Err($crate::mir::interpret::InterpError::InvalidProgram( $crate::mir::interpret::InvalidProgramInfo::$($tt)* ).into()) }; } #[macro_export] -macro_rules! throw_err_ub { +macro_rules! throw_ub { ($($tt:tt)*) => { - Err($crate::mir::interpret::InterpError::UndefinedBehaviour( + return Err($crate::mir::interpret::InterpError::UndefinedBehaviour( $crate::mir::interpret::UndefinedBehaviourInfo::$($tt)* ).into()) }; } #[macro_export] -macro_rules! throw_err_panic { +macro_rules! throw_panic { ($($tt:tt)*) => { - Err($crate::mir::interpret::InterpError::Panic( + return Err($crate::mir::interpret::InterpError::Panic( $crate::mir::interpret::PanicInfo::$($tt)* ).into()) }; } #[macro_export] -macro_rules! throw_err_exhaust { +macro_rules! throw_exhaust { ($($tt:tt)*) => { - Err($crate::mir::interpret::InterpError::ResourceExhaustion( + return Err($crate::mir::interpret::InterpError::ResourceExhaustion( $crate::mir::interpret::ResourceExhaustionInfo::$($tt)* ).into()) }; diff --git a/src/librustc/mir/interpret/pointer.rs b/src/librustc/mir/interpret/pointer.rs index 17f963609f6d8..0a99851337994 100644 --- a/src/librustc/mir/interpret/pointer.rs +++ b/src/librustc/mir/interpret/pointer.rs @@ -74,13 +74,13 @@ pub trait PointerArithmetic: layout::HasDataLayout { #[inline] fn offset<'tcx>(&self, val: u64, i: u64) -> InterpResult<'tcx, u64> { let (res, over) = self.overflowing_offset(val, i); - if over { throw_err_panic!(Overflow(mir::BinOp::Add)) } else { Ok(res) } + if over { throw_panic!(Overflow(mir::BinOp::Add)) } else { Ok(res) } } #[inline] fn signed_offset<'tcx>(&self, val: u64, i: i64) -> InterpResult<'tcx, u64> { let (res, over) = self.overflowing_signed_offset(val, i128::from(i)); - if over { throw_err_panic!(Overflow(mir::BinOp::Add)) } else { Ok(res) } + if over { throw_panic!(Overflow(mir::BinOp::Add)) } else { Ok(res) } } } @@ -196,7 +196,7 @@ impl<'tcx, Tag> Pointer { msg: CheckInAllocMsg, ) -> InterpResult<'tcx, ()> { if self.offset > allocation_size { - throw_err_unsup!(PointerOutOfBounds { ptr: self.erase_tag(), msg, allocation_size }) + throw_unsup!(PointerOutOfBounds { ptr: self.erase_tag(), msg, allocation_size }) } else { Ok(()) } diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs index 01db0e48e21e0..607bcea7fe801 100644 --- a/src/librustc/mir/interpret/value.rs +++ b/src/librustc/mir/interpret/value.rs @@ -360,7 +360,7 @@ impl<'tcx, Tag> Scalar { Scalar::check_data(data, size); Ok(data) } - Scalar::Ptr(_) => throw_err_unsup!(ReadPointerAsBytes), + Scalar::Ptr(_) => throw_unsup!(ReadPointerAsBytes), } } @@ -373,8 +373,8 @@ impl<'tcx, Tag> Scalar { #[inline] pub fn to_ptr(self) -> InterpResult<'tcx, Pointer> { match self { - Scalar::Raw { data: 0, .. } => throw_err_unsup!(InvalidNullPointerUsage), - Scalar::Raw { .. } => throw_err_unsup!(ReadBytesAsPointer), + Scalar::Raw { data: 0, .. } => throw_unsup!(InvalidNullPointerUsage), + Scalar::Raw { .. } => throw_unsup!(ReadBytesAsPointer), Scalar::Ptr(p) => Ok(p), } } @@ -406,7 +406,7 @@ impl<'tcx, Tag> Scalar { match self { Scalar::Raw { data: 0, size: 1 } => Ok(false), Scalar::Raw { data: 1, size: 1 } => Ok(true), - _ => throw_err_unsup!(InvalidBool), + _ => throw_unsup!(InvalidBool), } } @@ -414,7 +414,7 @@ impl<'tcx, Tag> Scalar { let val = self.to_u32()?; match ::std::char::from_u32(val) { Some(c) => Ok(c), - None => throw_err_unsup!(InvalidChar(val as u128)), + None => throw_unsup!(InvalidChar(val as u128)), } } @@ -537,7 +537,7 @@ impl<'tcx, Tag> ScalarMaybeUndef { pub fn not_undef(self) -> InterpResult<'static, Scalar> { match self { ScalarMaybeUndef::Scalar(scalar) => Ok(scalar), - ScalarMaybeUndef::Undef => throw_err_unsup!(ReadUndefBytes(Size::from_bytes(0))), + ScalarMaybeUndef::Undef => throw_unsup!(ReadUndefBytes(Size::from_bytes(0))), } } diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 423449bc95d4e..75186b5fcf062 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -352,9 +352,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, ecx.goto_block(ret)?; // fully evaluated and done Ok(None) } else { - throw_err_unsup!( - MachineError(format!("calling non-const function `{}`", instance)) - ) + throw_unsup!(MachineError(format!("calling non-const function `{}`", instance))) }; } } @@ -414,7 +412,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, _tcx: TyCtxt<'tcx>, _def_id: DefId, ) -> InterpResult<'tcx, Cow<'tcx, Allocation>> { - throw_err_unsup!(ReadForeignStatic) + throw_unsup!(ReadForeignStatic) } #[inline(always)] diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs index 94f3148aaaf9e..9e87e112892cd 100644 --- a/src/librustc_mir/interpret/cast.rs +++ b/src/librustc_mir/interpret/cast.rs @@ -199,7 +199,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { }, // Casts to bool are not permitted by rustc, no need to handle them here. - _ => throw_err_unsup!(Unimplemented(format!("int to {:?} cast", dest_layout.ty))), + _ => throw_unsup!(Unimplemented(format!("int to {:?} cast", dest_layout.ty))), } } diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 61ee60fd3d503..cd057e059d50d 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -135,7 +135,7 @@ pub enum LocalValue { impl<'tcx, Tag: Copy + 'static> LocalState<'tcx, Tag> { pub fn access(&self) -> InterpResult<'tcx, Operand> { match self.value { - LocalValue::Dead => throw_err_unsup!(DeadLocal), + LocalValue::Dead => throw_unsup!(DeadLocal), LocalValue::Uninitialized => bug!("The type checker should prevent reading from a never-written local"), LocalValue::Live(val) => Ok(val), @@ -148,7 +148,7 @@ impl<'tcx, Tag: Copy + 'static> LocalState<'tcx, Tag> { &mut self, ) -> InterpResult<'tcx, Result<&mut LocalValue, MemPlace>> { match self.value { - LocalValue::Dead => throw_err_unsup!(DeadLocal), + LocalValue::Dead => throw_unsup!(DeadLocal), LocalValue::Live(Operand::Indirect(mplace)) => Ok(Err(mplace)), ref mut local @ LocalValue::Live(Operand::Immediate(_)) | ref mut local @ LocalValue::Uninitialized => { @@ -305,7 +305,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { &substs, )), None => if substs.needs_subst() { - throw_err_inval!(TooGeneric) + throw_inval!(TooGeneric) } else { Ok(substs) }, @@ -339,14 +339,14 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { && self.tcx.has_typeck_tables(did) && self.tcx.typeck_tables_of(did).tainted_by_errors { - return throw_err_inval!(TypeckError); + throw_inval!(TypeckError) } trace!("load mir {:?}", instance); match instance { ty::InstanceDef::Item(def_id) => if self.tcx.is_mir_available(did) { Ok(self.tcx.optimized_mir(did)) } else { - throw_err_unsup!(NoMirFor(self.tcx.def_path_str(def_id))) + throw_unsup!(NoMirFor(self.tcx.def_path_str(def_id))) }, _ => Ok(self.tcx.instance_mir(instance)), } @@ -359,7 +359,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { match self.stack.last() { Some(frame) => Ok(self.monomorphize_with_substs(t, frame.instance.substs)?), None => if t.needs_subst() { - throw_err_inval!(TooGeneric).into() + throw_inval!(TooGeneric) } else { Ok(t) }, @@ -376,7 +376,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let substituted = t.subst(*self.tcx, substs); if substituted.needs_subst() { - return throw_err_inval!(TooGeneric); + throw_inval!(TooGeneric) } Ok(self.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), substituted)) @@ -575,7 +575,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { info!("ENTERING({}) {}", self.cur_frame(), self.frame().instance); if self.stack.len() > self.tcx.sess.const_eval_stack_frame_limit { - throw_err_exhaust!(StackFrameLimitReached) + throw_exhaust!(StackFrameLimitReached) } else { Ok(()) } @@ -623,7 +623,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } } else { // Uh, that shouldn't happen... the function did not intend to return - return throw_err_ub!(Unreachable); + throw_ub!(Unreachable) } // Jump to new block -- *after* validation so that the spans make more sense. match frame.return_to_block { diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs index 4539a1c7e1ddd..1cc409d7a9baa 100644 --- a/src/librustc_mir/interpret/intern.rs +++ b/src/librustc_mir/interpret/intern.rs @@ -328,9 +328,7 @@ pub fn intern_const_alloc_recursive( } } else if ecx.memory().dead_alloc_map.contains_key(&alloc_id) { // dangling pointer - return throw_err_unsup!( - ValidationFailure("encountered dangling pointer in final constant".into()) - ) + throw_unsup!(ValidationFailure("encountered dangling pointer in final constant".into())) } } Ok(()) diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index 687265c983f26..e5af9d86cb329 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -104,9 +104,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { }; let out_val = if intrinsic_name.ends_with("_nonzero") { if bits == 0 { - return throw_err_unsup!( - Intrinsic(format!("{} called on 0", intrinsic_name)) - ); + throw_unsup!(Intrinsic(format!("{} called on 0", intrinsic_name))) } numeric_intrinsic(intrinsic_name.trim_end_matches("_nonzero"), bits, kind)? } else { @@ -192,9 +190,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { if overflowed { let layout = self.layout_of(substs.type_at(0))?; let r_val = r.to_scalar()?.to_bits(layout.size)?; - return throw_err_unsup!(Intrinsic( - format!("Overflowing shift by {} in {}", r_val, intrinsic_name), - )); + throw_unsup!( + Intrinsic(format!("Overflowing shift by {} in {}", r_val, intrinsic_name)) + ) } self.write_scalar(val, dest)?; } diff --git a/src/librustc_mir/interpret/machine.rs b/src/librustc_mir/interpret/machine.rs index 3f3d4376d29cd..2e7e2ad93d44c 100644 --- a/src/librustc_mir/interpret/machine.rs +++ b/src/librustc_mir/interpret/machine.rs @@ -251,6 +251,6 @@ pub trait Machine<'mir, 'tcx>: Sized { _mem: &Memory<'mir, 'tcx, Self>, _ptr: Pointer, ) -> InterpResult<'tcx, u64> { - throw_err_unsup!(ReadPointerAsBytes) + throw_unsup!(ReadPointerAsBytes) } } diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 8c43fb3dc40de..949f9194d9ea2 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -66,7 +66,7 @@ impl<'tcx, Other> FnVal<'tcx, Other> { match self { FnVal::Instance(instance) => Ok(instance), - FnVal::Other(_) => throw_err_unsup!(MachineError(format!( + FnVal::Other(_) => throw_unsup!(MachineError(format!( "Expected instance function pointer, got 'other' pointer" ))), } @@ -202,7 +202,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { kind: MemoryKind, ) -> InterpResult<'tcx, Pointer> { if ptr.offset.bytes() != 0 { - return throw_err_unsup!(ReallocateNonBasePtr); + throw_unsup!(ReallocateNonBasePtr) } // For simplicities' sake, we implement reallocate as "alloc, copy, dealloc". @@ -243,40 +243,38 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { trace!("deallocating: {}", ptr.alloc_id); if ptr.offset.bytes() != 0 { - return throw_err_unsup!(DeallocateNonBasePtr); + throw_unsup!(DeallocateNonBasePtr) } let (alloc_kind, mut alloc) = match self.alloc_map.remove(&ptr.alloc_id) { Some(alloc) => alloc, None => { // Deallocating static memory -- always an error - return match self.tcx.alloc_map.lock().get(ptr.alloc_id) { - Some(GlobalAlloc::Function(..)) => throw_err_unsup!(DeallocatedWrongMemoryKind( + match self.tcx.alloc_map.lock().get(ptr.alloc_id) { + Some(GlobalAlloc::Function(..)) => throw_unsup!(DeallocatedWrongMemoryKind( "function".to_string(), format!("{:?}", kind), )), Some(GlobalAlloc::Static(..)) | - Some(GlobalAlloc::Memory(..)) => throw_err_unsup!(DeallocatedWrongMemoryKind( + Some(GlobalAlloc::Memory(..)) => throw_unsup!(DeallocatedWrongMemoryKind( "static".to_string(), format!("{:?}", kind), )), - None => throw_err_unsup!(DoubleFree) + None => throw_unsup!(DoubleFree) } } }; if alloc_kind != kind { - return throw_err_unsup!(DeallocatedWrongMemoryKind( + throw_unsup!(DeallocatedWrongMemoryKind( format!("{:?}", alloc_kind), format!("{:?}", kind), - )); + )) } if let Some((size, align)) = old_size_and_align { if size.bytes() != alloc.bytes.len() as u64 || align != alloc.align { let bytes = Size::from_bytes(alloc.bytes.len() as u64); - return throw_err_unsup!( - IncorrectAllocationInformation(size, bytes, align, alloc.align) - ); + throw_unsup!(IncorrectAllocationInformation(size, bytes, align, alloc.align)) } } @@ -321,7 +319,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { } else { // The biggest power of two through which `offset` is divisible. let offset_pow2 = 1 << offset.trailing_zeros(); - throw_err_unsup!(AlignmentCheckFailed { + throw_unsup!(AlignmentCheckFailed { has: Align::from_bytes(offset_pow2).unwrap(), required: align, }) @@ -343,7 +341,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { assert!(size.bytes() == 0); // Must be non-NULL and aligned. if bits == 0 { - return throw_err_unsup!(InvalidNullPointerUsage); + throw_unsup!(InvalidNullPointerUsage) } check_offset_align(bits, align)?; None @@ -364,10 +362,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { // got picked we might be aligned even if this check fails. // We instead have to fall back to converting to an integer and checking // the "real" alignment. - return throw_err_unsup!(AlignmentCheckFailed { + throw_unsup!(AlignmentCheckFailed { has: alloc_align, - required: align, - }); + required: align + }) } check_offset_align(ptr.offset.bytes(), align)?; @@ -415,9 +413,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { Some(GlobalAlloc::Memory(mem)) => Cow::Borrowed(mem), Some(GlobalAlloc::Function(..)) => - return throw_err_unsup!(DerefFunctionPointer), + throw_unsup!(DerefFunctionPointer), None => - return throw_err_unsup!(DanglingPointerDeref), + throw_unsup!(DanglingPointerDeref), Some(GlobalAlloc::Static(def_id)) => { // We got a "lazy" static that has not been computed yet. if tcx.is_foreign_item(def_id) { @@ -507,11 +505,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { // to give us a cheap reference. let alloc = Self::get_static_alloc(memory_extra, tcx, id)?; if alloc.mutability == Mutability::Immutable { - return throw_err_unsup!(ModifiedConstantMemory); + throw_unsup!(ModifiedConstantMemory) } match M::STATIC_KIND { Some(kind) => Ok((MemoryKind::Machine(kind), alloc.into_owned())), - None => throw_err_unsup!(ModifiedStatic), + None => throw_unsup!(ModifiedStatic), } }); // Unpack the error type manually because type inference doesn't @@ -521,7 +519,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { Ok(a) => { let a = &mut a.1; if a.mutability == Mutability::Immutable { - return throw_err_unsup!(ModifiedConstantMemory); + throw_unsup!(ModifiedConstantMemory) } Ok(a) } @@ -550,7 +548,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { if let Ok(_) = self.get_fn_alloc(id) { return if let AllocCheck::Dereferencable = liveness { // The caller requested no function pointers. - throw_err_unsup!(DerefFunctionPointer) + throw_unsup!(DerefFunctionPointer) } else { Ok((Size::ZERO, Align::from_bytes(1).unwrap())) }; @@ -581,7 +579,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { .expect("deallocated pointers should all be recorded in \ `dead_alloc_map`")) } else { - throw_err_unsup!(DanglingPointerDeref) + throw_unsup!(DanglingPointerDeref) }, } } @@ -593,7 +591,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { } else { match self.tcx.alloc_map.lock().get(id) { Some(GlobalAlloc::Function(instance)) => Ok(FnVal::Instance(instance)), - _ => throw_err_unsup!(ExecuteMemory), + _ => throw_unsup!(ExecuteMemory), } } } @@ -604,7 +602,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { ) -> InterpResult<'tcx, FnVal<'tcx, M::ExtraFnVal>> { let ptr = self.force_ptr(ptr)?; // We definitely need a pointer value. if ptr.offset.bytes() != 0 { - return throw_err_unsup!(InvalidFunctionPointer); + throw_unsup!(InvalidFunctionPointer) } self.get_fn_alloc(ptr.alloc_id) } @@ -839,9 +837,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { if (src.offset <= dest.offset && src.offset + size > dest.offset) || (dest.offset <= src.offset && dest.offset + size > src.offset) { - return throw_err_unsup!(Intrinsic( + throw_unsup!(Intrinsic( "copy_nonoverlapping called on overlapping ranges".to_string(), - )); + )) } } diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 8c443c9579f75..402a9a5c5ce74 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -461,7 +461,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { mir_place.iterate(|place_base, place_projection| { let mut op = match place_base { PlaceBase::Local(mir::RETURN_PLACE) => - return throw_err_unsup!(ReadFromReturnPointer), + throw_unsup!(ReadFromReturnPointer), PlaceBase::Local(local) => { // Do not use the layout passed in as argument if the base we are looking at // here is not the entire place. @@ -534,7 +534,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { match val.val { ConstValue::Param(_) => // FIXME(oli-obk): try to monomorphize - return throw_err_inval!(TooGeneric), + throw_inval!(TooGeneric), ConstValue::Unevaluated(def_id, substs) => { let instance = self.resolve(def_id, substs)?; return Ok(OpTy::from(self.const_eval_raw(GlobalId { @@ -610,7 +610,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let bits_discr = match raw_discr.to_bits(discr_val.layout.size) { Ok(raw_discr) => raw_discr, Err(_) => - return throw_err_unsup!(InvalidDiscriminant(raw_discr.erase_tag())), + throw_unsup!(InvalidDiscriminant(raw_discr.erase_tag())), }; let real_discr = if discr_val.layout.ty.is_signed() { // going from layout tag type to typeck discriminant type @@ -657,9 +657,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let ptr_valid = niche_start == 0 && variants_start == variants_end && !self.memory.ptr_may_be_null(ptr); if !ptr_valid { - return throw_err_unsup!( - InvalidDiscriminant(raw_discr.erase_tag().into()) - ); + throw_unsup!(InvalidDiscriminant(raw_discr.erase_tag().into())) } (dataful_variant.as_u32() as u128, dataful_variant) }, diff --git a/src/librustc_mir/interpret/operator.rs b/src/librustc_mir/interpret/operator.rs index 334cf09ba122b..a942da5771b00 100644 --- a/src/librustc_mir/interpret/operator.rs +++ b/src/librustc_mir/interpret/operator.rs @@ -155,7 +155,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { r, right_layout.ty ); - return throw_err_unsup!(Unimplemented(msg)); + throw_unsup!(Unimplemented(msg)) } // Operations that need special treatment for signed integers @@ -173,8 +173,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { return Ok((Scalar::from_bool(op(&l, &r)), false)); } let op: Option (i128, bool)> = match bin_op { - Div if r == 0 => return throw_err_panic!(DivisionByZero), - Rem if r == 0 => return throw_err_panic!(RemainderByZero), + Div if r == 0 => throw_panic!(DivisionByZero), + Rem if r == 0 => throw_panic!(RemainderByZero), Div => Some(i128::overflowing_div), Rem => Some(i128::overflowing_rem), Add => Some(i128::overflowing_add), @@ -231,8 +231,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Add => u128::overflowing_add, Sub => u128::overflowing_sub, Mul => u128::overflowing_mul, - Div if r == 0 => return throw_err_panic!(DivisionByZero), - Rem if r == 0 => return throw_err_panic!(RemainderByZero), + Div if r == 0 => throw_panic!(DivisionByZero), + Rem if r == 0 => throw_panic!(RemainderByZero), Div => u128::overflowing_div, Rem => u128::overflowing_rem, _ => bug!(), @@ -250,7 +250,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { r, right_layout.ty, ); - return throw_err_unsup!(Unimplemented(msg)); + throw_unsup!(Unimplemented(msg)) } }; diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index b385862490a23..f66c4adf76397 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -356,7 +356,7 @@ where // This can be violated because this runs during promotion on code where the // type system has not yet ensured that such things don't happen. debug!("tried to access element {} of array/slice with length {}", field, len); - return throw_err_panic!(BoundsCheck { len, index: field }); + throw_panic!(BoundsCheck { len, index: field }); } stride * field } @@ -622,7 +622,7 @@ where .layout_of(self.monomorphize(self.frame().body.return_ty())?)?, } } - None => return throw_err_unsup!(InvalidNullPointerUsage), + None => throw_unsup!(InvalidNullPointerUsage), }, PlaceBase::Local(local) => PlaceTy { // This works even for dead/uninitialized locals; we check further when writing diff --git a/src/librustc_mir/interpret/step.rs b/src/librustc_mir/interpret/step.rs index de798ecee7348..95824d0ebc166 100644 --- a/src/librustc_mir/interpret/step.rs +++ b/src/librustc_mir/interpret/step.rs @@ -121,7 +121,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // size of MIR constantly. Nop => {} - InlineAsm { .. } => return throw_err_unsup!(InlineAsm), + InlineAsm { .. } => throw_unsup!(InlineAsm), } self.stack[frame_idx].stmt += 1; diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs index f1c91058b713d..aa06922fb95f7 100644 --- a/src/librustc_mir/interpret/terminator.rs +++ b/src/librustc_mir/interpret/terminator.rs @@ -19,7 +19,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.frame_mut().stmt = 0; Ok(()) } else { - throw_err_ub!(Unreachable) + throw_ub!(Unreachable) } } @@ -89,7 +89,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { }, _ => { let msg = format!("can't handle callee of type {:?}", func.layout.ty); - return throw_err_unsup!(Unimplemented(msg)); + throw_unsup!(Unimplemented(msg)) } }; let args = self.eval_operands(args)?; @@ -136,7 +136,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } else { // Compute error message use rustc::mir::interpret::PanicInfo::*; - return match msg { + match msg { BoundsCheck { ref len, ref index } => { let len = self.read_immediate(self.eval_operand(len, None)?) .expect("can't eval len").to_scalar()? @@ -144,20 +144,20 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let index = self.read_immediate(self.eval_operand(index, None)?) .expect("can't eval index").to_scalar()? .to_bits(self.memory().pointer_size())? as u64; - throw_err_panic!(BoundsCheck { len, index }) + throw_panic!(BoundsCheck { len, index }) } Overflow(op) => - throw_err_panic!(Overflow(*op)), + throw_panic!(Overflow(*op)), OverflowNeg => - throw_err_panic!(OverflowNeg), + throw_panic!(OverflowNeg), DivisionByZero => - throw_err_panic!(DivisionByZero), + throw_panic!(DivisionByZero), RemainderByZero => - throw_err_panic!(RemainderByZero), + throw_panic!(RemainderByZero), GeneratorResumedAfterReturn => - throw_err_panic!(GeneratorResumedAfterReturn), + throw_panic!(GeneratorResumedAfterReturn), GeneratorResumedAfterPanic => - throw_err_panic!(GeneratorResumedAfterPanic), + throw_panic!(GeneratorResumedAfterPanic), Panic { .. } => bug!("`Panic` variant cannot occur in MIR"), }; @@ -173,7 +173,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { `simplify_branches` mir pass"), FalseUnwind { .. } => bug!("should have been eliminated by\ `simplify_branches` mir pass"), - Unreachable => return throw_err_ub!(Unreachable), + Unreachable => throw_ub!(Unreachable), } Ok(()) @@ -226,9 +226,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } // Now, check if !Self::check_argument_compat(rust_abi, caller_arg.layout, callee_arg.layout) { - return throw_err_unsup!( - FunctionArgMismatch(caller_arg.layout.ty, callee_arg.layout.ty) - ); + throw_unsup!(FunctionArgMismatch(caller_arg.layout.ty, callee_arg.layout.ty)) } // We allow some transmutes here self.copy_op_transmute(caller_arg, callee_arg) @@ -256,13 +254,13 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { match instance.def { ty::InstanceDef::Intrinsic(..) => { if caller_abi != Abi::RustIntrinsic { - return throw_err_unsup!(FunctionAbiMismatch(caller_abi, Abi::RustIntrinsic)); + throw_unsup!(FunctionAbiMismatch(caller_abi, Abi::RustIntrinsic)) } // The intrinsic itself cannot diverge, so if we got here without a return // place... (can happen e.g., for transmute returning `!`) let dest = match dest { Some(dest) => dest, - None => return throw_err_ub!(Unreachable) + None => throw_ub!(Unreachable) }; M::call_intrinsic(self, instance, args, dest)?; // No stack frame gets pushed, the main loop will just act as if the @@ -297,7 +295,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { abi, }; if normalize_abi(caller_abi) != normalize_abi(callee_abi) { - return throw_err_unsup!(FunctionAbiMismatch(caller_abi, callee_abi)); + throw_unsup!(FunctionAbiMismatch(caller_abi, callee_abi)) } } @@ -392,7 +390,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Now we should have no more caller args if caller_iter.next().is_some() { trace!("Caller has passed too many args"); - return throw_err_unsup!(FunctionArgCountMismatch); + throw_unsup!(FunctionArgCountMismatch) } // Don't forget to check the return type! if let Some(caller_ret) = dest { @@ -404,15 +402,15 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { caller_ret.layout, callee_ret.layout, ) { - return throw_err_unsup!( + throw_unsup!( FunctionRetMismatch(caller_ret.layout.ty, callee_ret.layout.ty) - ); + ) } } else { let local = mir::RETURN_PLACE; let ty = self.frame().body.local_decls[local].ty; if !self.tcx.is_ty_uninhabited_from_any_module(ty) { - return throw_err_unsup!(FunctionRetMismatch(self.tcx.types.never, ty)); + throw_unsup!(FunctionRetMismatch(self.tcx.types.never, ty)) } } Ok(()) diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs index df6fb7a7c63c8..aa2461729641d 100644 --- a/src/librustc_mir/interpret/validity.rs +++ b/src/librustc_mir/interpret/validity.rs @@ -22,7 +22,7 @@ macro_rules! validation_failure { } else { format!(" at {}", where_) }; - throw_err_unsup!(ValidationFailure(format!( + throw_unsup!(ValidationFailure(format!( "encountered {}{}, but expected {}", $what, where_, $details, ))) @@ -34,7 +34,7 @@ macro_rules! validation_failure { } else { format!(" at {}", where_) }; - throw_err_unsup!(ValidationFailure(format!( + throw_unsup!(ValidationFailure(format!( "encountered {}{}", $what, where_, ))) @@ -45,14 +45,14 @@ macro_rules! try_validation { ($e:expr, $what:expr, $where:expr, $details:expr) => {{ match $e { Ok(x) => x, - Err(_) => return validation_failure!($what, $where, $details), + Err(_) => validation_failure!($what, $where, $details), } }}; ($e:expr, $what:expr, $where:expr) => {{ match $e { Ok(x) => x, - Err(_) => return validation_failure!($what, $where), + Err(_) => validation_failure!($what, $where), } }} } @@ -408,18 +408,18 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> use super::UnsupportedOpInfo::*; match err.kind { InterpError::Unsupported(InvalidNullPointerUsage) => - return validation_failure!("NULL reference", self.path), + validation_failure!("NULL reference", self.path), InterpError::Unsupported(AlignmentCheckFailed { required, has }) => - return validation_failure!(format!("unaligned reference \ + validation_failure!(format!("unaligned reference \ (required {} byte alignment but found {})", required.bytes(), has.bytes()), self.path), InterpError::Unsupported(ReadBytesAsPointer) => - return validation_failure!( + validation_failure!( "dangling reference (created from integer)", self.path ), _ => - return validation_failure!( + validation_failure!( "dangling reference (not entirely in bounds)", self.path ), @@ -512,27 +512,27 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> if lo == 1 && hi == max_hi { // Only NULL is the niche. So make sure the ptr is NOT NULL. if self.ecx.memory.ptr_may_be_null(ptr) { - return validation_failure!( + validation_failure!( "a potentially NULL pointer", self.path, format!( "something that cannot possibly fail to be {}", wrapping_range_format(&layout.valid_range, max_hi) ) - ); + ) } return Ok(()); } else { // Conservatively, we reject, because the pointer *could* have a bad // value. - return validation_failure!( + validation_failure!( "a pointer", self.path, format!( "something that cannot possibly fail to be {}", wrapping_range_format(&layout.valid_range, max_hi) ) - ); + ) } } Ok(data) => @@ -616,9 +616,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> let i = (offset.bytes() / ty_size.bytes()) as usize; self.path.push(PathElem::ArrayElem(i)); - return validation_failure!( - "undefined bytes", self.path - ) + validation_failure!("undefined bytes", self.path) }, // Other errors shouldn't be possible _ => return Err(err), diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index db6b62e95ce0a..807a7e88498b8 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -441,7 +441,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { // Need to do overflow check here: For actual CTFE, MIR // generation emits code that does this before calling the op. if prim.to_bits()? == (1 << (prim.layout.size.bits() - 1)) { - return throw_err_panic!(OverflowNeg); + throw_panic!(OverflowNeg) } } UnOp::Not => { From 5585445a3359d74c304773e7d5d066409316ba36 Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Tue, 30 Jul 2019 20:36:17 +0530 Subject: [PATCH 20/25] throw_X macros use err_X macros --- src/librustc/mir/interpret/mod.rs | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs index 2409d22e5f0a3..ad18e2779bab2 100644 --- a/src/librustc/mir/interpret/mod.rs +++ b/src/librustc/mir/interpret/mod.rs @@ -2,20 +2,12 @@ #[macro_export] macro_rules! throw_unsup { - ($($tt:tt)*) => { - return Err($crate::mir::interpret::InterpError::Unsupported( - $crate::mir::interpret::UnsupportedOpInfo::$($tt)* - ).into()) - }; + ($($tt:tt)*) => { return Err(err_unsup!($($tt)*).into()) }; } #[macro_export] macro_rules! throw_inval { - ($($tt:tt)*) => { - return Err($crate::mir::interpret::InterpError::InvalidProgram( - $crate::mir::interpret::InvalidProgramInfo::$($tt)* - ).into()) - }; + ($($tt:tt)*) => { return Err(err_inval!($($tt)*).into()) }; } #[macro_export] From 152f0d347e9b3b661adfcc0289412badfa45ab5a Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Wed, 31 Jul 2019 12:48:54 +0530 Subject: [PATCH 21/25] code review fixes --- src/librustc/mir/interpret/error.rs | 11 +++--- src/librustc/mir/interpret/mod.rs | 30 ++++++++++----- src/librustc_mir/const_eval.rs | 11 +++--- src/librustc_mir/interpret/eval_context.rs | 9 ++--- src/librustc_mir/interpret/intern.rs | 8 ++-- src/librustc_mir/interpret/intrinsics.rs | 10 ++--- src/librustc_mir/interpret/machine.rs | 8 ++-- src/librustc_mir/interpret/memory.rs | 25 ++++++------ src/librustc_mir/interpret/operand.rs | 8 ++-- src/librustc_mir/interpret/snapshot.rs | 5 +-- src/librustc_mir/interpret/terminator.rs | 40 +++++++++---------- src/librustc_mir/interpret/validity.rs | 45 +++++++++++----------- src/librustc_mir/transform/const_prop.rs | 4 +- 13 files changed, 105 insertions(+), 109 deletions(-) diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index 7108f69d39ed4..8d41b019c221a 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -137,13 +137,12 @@ impl<'tcx> ConstEvalErr<'tcx> { message: &str, lint_root: Option, ) -> Result, ErrorHandled> { - use InvalidProgramInfo::*; match self.error { - InterpError::InvalidProgram(Layout(LayoutError::Unknown(_))) | - InterpError::InvalidProgram(TooGeneric) => + err_inval!(Layout(LayoutError::Unknown(_))) | + err_inval!(TooGeneric) => return Err(ErrorHandled::TooGeneric), - InterpError::InvalidProgram(Layout(LayoutError::SizeOverflow(_))) | - InterpError::InvalidProgram(TypeckError) => + err_inval!(Layout(LayoutError::SizeOverflow(_))) | + err_inval!(TypeckError) => return Err(ErrorHandled::Reported), _ => {}, } @@ -549,7 +548,9 @@ impl fmt::Debug for UnsupportedOpInfo<'tcx> { #[derive(Clone, RustcEncodable, RustcDecodable, HashStable)] pub enum ResourceExhaustionInfo { + /// The stack grew too big. StackFrameLimitReached, + /// The program ran into an infinite loop. InfiniteLoop, } diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs index ad18e2779bab2..8feb04ffe88db 100644 --- a/src/librustc/mir/interpret/mod.rs +++ b/src/librustc/mir/interpret/mod.rs @@ -21,20 +21,12 @@ macro_rules! throw_ub { #[macro_export] macro_rules! throw_panic { - ($($tt:tt)*) => { - return Err($crate::mir::interpret::InterpError::Panic( - $crate::mir::interpret::PanicInfo::$($tt)* - ).into()) - }; + ($($tt:tt)*) => { return Err(err_panic!($($tt)*).into()) }; } #[macro_export] macro_rules! throw_exhaust { - ($($tt:tt)*) => { - return Err($crate::mir::interpret::InterpError::ResourceExhaustion( - $crate::mir::interpret::ResourceExhaustionInfo::$($tt)* - ).into()) - }; + ($($tt:tt)*) => { return Err(err_exhaust!($($tt)*).into()) }; } #[macro_export] @@ -55,6 +47,24 @@ macro_rules! err_unsup { }; } +#[macro_export] +macro_rules! err_exhaust { + ($($tt:tt)*) => { + $crate::mir::interpret::InterpError::ResourceExhaustion( + $crate::mir::interpret::ResourceExhaustionInfo::$($tt)* + ) + }; +} + +#[macro_export] +macro_rules! err_panic { + ($($tt:tt)*) => { + $crate::mir::interpret::InterpError::Panic( + $crate::mir::interpret::PanicInfo::$($tt)* + ) + }; +} + mod error; mod value; mod allocation; diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 75186b5fcf062..1b92e4992ffb1 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -22,9 +22,9 @@ use syntax::source_map::{Span, DUMMY_SP}; use crate::interpret::{self, PlaceTy, MPlaceTy, OpTy, ImmTy, Immediate, Scalar, RawConst, ConstValue, - InterpResult, InterpErrorInfo, InterpError, GlobalId, InterpCx, StackPopCleanup, + InterpResult, InterpErrorInfo, GlobalId, InterpCx, StackPopCleanup, Allocation, AllocId, MemoryKind, - snapshot, RefTracking, intern_const_alloc_recursive, UnsupportedOpInfo, + snapshot, RefTracking, intern_const_alloc_recursive, }; /// Number of steps until the detector even starts doing anything. @@ -183,7 +183,7 @@ fn eval_body_using_ecx<'mir, 'tcx>( impl<'tcx> Into> for ConstEvalError { fn into(self) -> InterpErrorInfo<'tcx> { - InterpError::Unsupported(UnsupportedOpInfo::MachineError(self.to_string())).into() + err_unsup!(MachineError(self.to_string())).into() } } @@ -360,7 +360,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, Ok(Some(match ecx.load_mir(instance.def) { Ok(body) => body, Err(err) => { - if let InterpError::Unsupported(UnsupportedOpInfo::NoMirFor(ref path)) = err.kind { + if let err_unsup!(NoMirFor(ref path)) = err.kind { return Err( ConstEvalError::NeedsRfc(format!("calling extern function `{}`", path)) .into(), @@ -697,9 +697,8 @@ pub fn const_eval_raw_provider<'tcx>( // promoting runtime code is only allowed to error if it references broken constants // any other kind of error will be reported to the user as a deny-by-default lint _ => if let Some(p) = cid.promoted { - use crate::interpret::InvalidProgramInfo::ReferencedConstant; let span = tcx.promoted_mir(def_id)[p].span; - if let InterpError::InvalidProgram(ReferencedConstant) = err.error { + if let err_inval!(ReferencedConstant) = err.error { err.report_as_error( tcx.at(span), "evaluation of constant expression failed", diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index cd057e059d50d..7ab99976b404b 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -16,8 +16,7 @@ use rustc_data_structures::indexed_vec::IndexVec; use rustc::mir::interpret::{ ErrorHandled, GlobalId, Scalar, Pointer, FrameInfo, AllocId, - InterpResult, InterpError, - truncate, sign_extend, InvalidProgramInfo, + InterpResult, truncate, sign_extend, }; use rustc_data_structures::fx::FxHashMap; @@ -193,7 +192,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> LayoutOf for InterpCx<'mir, 'tcx, M> { self.tcx .layout_of(self.param_env.and(ty)) .map_err(|layout| { - InterpError::InvalidProgram(InvalidProgramInfo::Layout(layout)).into() + err_inval!(Layout(layout)).into() }) } } @@ -698,9 +697,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let val = self.tcx.const_eval_raw(param_env.and(gid)).map_err(|err| { match err { ErrorHandled::Reported => - InterpError::InvalidProgram(InvalidProgramInfo::ReferencedConstant), + err_inval!(ReferencedConstant), ErrorHandled::TooGeneric => - InterpError::InvalidProgram(InvalidProgramInfo::TooGeneric), + err_inval!(TooGeneric), } })?; self.raw_const_to_mplace(val) diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs index 1cc409d7a9baa..e9bba7889119a 100644 --- a/src/librustc_mir/interpret/intern.rs +++ b/src/librustc_mir/interpret/intern.rs @@ -4,9 +4,7 @@ //! memory, we need to extract all memory allocations to the global memory pool so they stay around. use rustc::ty::{Ty, TyCtxt, ParamEnv, self}; -use rustc::mir::interpret::{ - InterpResult, ErrorHandled, UnsupportedOpInfo, -}; +use rustc::mir::interpret::{InterpResult, ErrorHandled}; use rustc::hir; use rustc::hir::def_id::DefId; use super::validity::RefTracking; @@ -16,7 +14,7 @@ use syntax::ast::Mutability; use syntax_pos::Span; use super::{ - ValueVisitor, MemoryKind, Pointer, AllocId, MPlaceTy, InterpError, Scalar, + ValueVisitor, MemoryKind, Pointer, AllocId, MPlaceTy, Scalar, }; use crate::const_eval::{CompileTimeInterpreter, CompileTimeEvalContext}; @@ -293,7 +291,7 @@ pub fn intern_const_alloc_recursive( if let Err(error) = interned { // This can happen when e.g. the tag of an enum is not a valid discriminant. We do have // to read enum discriminants in order to find references in enum variant fields. - if let InterpError::Unsupported(UnsupportedOpInfo::ValidationFailure(_)) = error.kind { + if let err_unsup!(ValidationFailure(_)) = error.kind { let err = crate::const_eval::error_to_const_error(&ecx, error); match err.struct_error(ecx.tcx, "it is undefined behavior to use this value") { Ok(mut diag) => { diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs index e5af9d86cb329..97866adcfa333 100644 --- a/src/librustc_mir/interpret/intrinsics.rs +++ b/src/librustc_mir/interpret/intrinsics.rs @@ -6,9 +6,7 @@ use syntax::symbol::Symbol; use rustc::ty; use rustc::ty::layout::{LayoutOf, Primitive, Size}; use rustc::mir::BinOp; -use rustc::mir::interpret::{ - InterpResult, InterpError, Scalar, PanicInfo, UnsupportedOpInfo, -}; +use rustc::mir::interpret::{InterpResult, Scalar}; use super::{ Machine, PlaceTy, OpTy, InterpCx, Immediate, @@ -100,7 +98,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let bits = self.read_scalar(args[0])?.to_bits(layout_of.size)?; let kind = match layout_of.abi { ty::layout::Abi::Scalar(ref scalar) => scalar.value, - _ => Err(InterpError::Unsupported(UnsupportedOpInfo::TypeNotPrimitive(ty)))?, + _ => Err(err_unsup!(TypeNotPrimitive(ty)))?, }; let out_val = if intrinsic_name.ends_with("_nonzero") { if bits == 0 { @@ -250,7 +248,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let file = Symbol::intern(self.read_str(file_place)?); let line = self.read_scalar(line.into())?.to_u32()?; let col = self.read_scalar(col.into())?.to_u32()?; - return Err(InterpError::Panic(PanicInfo::Panic { msg, file, line, col }).into()); + throw_panic!(Panic { msg, file, line, col }) } else if Some(def_id) == self.tcx.lang_items().begin_panic_fn() { assert!(args.len() == 2); // &'static str, &(&'static str, u32, u32) @@ -268,7 +266,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let file = Symbol::intern(self.read_str(file_place)?); let line = self.read_scalar(line.into())?.to_u32()?; let col = self.read_scalar(col.into())?.to_u32()?; - return Err(InterpError::Panic(PanicInfo::Panic { msg, file, line, col }).into()); + throw_panic!(Panic { msg, file, line, col }) } else { return Ok(false); } diff --git a/src/librustc_mir/interpret/machine.rs b/src/librustc_mir/interpret/machine.rs index 2e7e2ad93d44c..78902b1016634 100644 --- a/src/librustc_mir/interpret/machine.rs +++ b/src/librustc_mir/interpret/machine.rs @@ -10,8 +10,8 @@ use rustc::mir; use rustc::ty::{self, TyCtxt}; use super::{ - Allocation, AllocId, InterpResult, InterpError, Scalar, AllocationExtra, - InterpCx, PlaceTy, OpTy, ImmTy, MemoryKind, Pointer, Memory, UnsupportedOpInfo, + Allocation, AllocId, InterpResult, Scalar, AllocationExtra, + InterpCx, PlaceTy, OpTy, ImmTy, MemoryKind, Pointer, Memory, }; /// Whether this kind of memory is allowed to leak @@ -240,9 +240,9 @@ pub trait Machine<'mir, 'tcx>: Sized { int: u64, ) -> InterpResult<'tcx, Pointer> { Err((if int == 0 { - InterpError::Unsupported(UnsupportedOpInfo::InvalidNullPointerUsage) + err_unsup!(InvalidNullPointerUsage) } else { - InterpError::Unsupported(UnsupportedOpInfo::ReadBytesAsPointer) + err_unsup!(ReadBytesAsPointer) }).into()) } diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 949f9194d9ea2..85ed3b3efd68c 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -18,8 +18,8 @@ use syntax::ast::Mutability; use super::{ Pointer, AllocId, Allocation, GlobalId, AllocationExtra, - InterpResult, Scalar, InterpError, GlobalAlloc, PointerArithmetic, - Machine, AllocMap, MayLeak, ErrorHandled, CheckInAllocMsg, InvalidProgramInfo, + InterpResult, Scalar, GlobalAlloc, PointerArithmetic, + Machine, AllocMap, MayLeak, ErrorHandled, CheckInAllocMsg, }; #[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)] @@ -250,18 +250,17 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { Some(alloc) => alloc, None => { // Deallocating static memory -- always an error - match self.tcx.alloc_map.lock().get(ptr.alloc_id) { - Some(GlobalAlloc::Function(..)) => throw_unsup!(DeallocatedWrongMemoryKind( + return Err(match self.tcx.alloc_map.lock().get(ptr.alloc_id) { + Some(GlobalAlloc::Function(..)) => err_unsup!(DeallocatedWrongMemoryKind( "function".to_string(), format!("{:?}", kind), )), - Some(GlobalAlloc::Static(..)) | - Some(GlobalAlloc::Memory(..)) => throw_unsup!(DeallocatedWrongMemoryKind( - "static".to_string(), - format!("{:?}", kind), - )), - None => throw_unsup!(DoubleFree) + Some(GlobalAlloc::Static(..)) | Some(GlobalAlloc::Memory(..)) => err_unsup!( + DeallocatedWrongMemoryKind("static".to_string(), format!("{:?}", kind)) + ), + None => err_unsup!(DoubleFree), } + .into()); } }; @@ -437,11 +436,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { assert!(tcx.is_static(def_id)); match err { ErrorHandled::Reported => - InterpError::InvalidProgram( - InvalidProgramInfo::ReferencedConstant - ), + err_inval!(ReferencedConstant), ErrorHandled::TooGeneric => - InterpError::InvalidProgram(InvalidProgramInfo::TooGeneric), + err_inval!(TooGeneric), } })?; // Make sure we use the ID of the resolved memory, not the lazy one! diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 402a9a5c5ce74..e64a474b4ca71 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -11,8 +11,7 @@ use rustc::ty::layout::{ use rustc::mir::interpret::{ GlobalId, AllocId, ConstValue, Pointer, Scalar, - InterpResult, InterpError, - sign_extend, truncate, UnsupportedOpInfo, + InterpResult, sign_extend, truncate, }; use super::{ InterpCx, Machine, @@ -332,7 +331,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let len = mplace.len(self)?; let bytes = self.memory.read_bytes(mplace.ptr, Size::from_bytes(len as u64))?; let str = ::std::str::from_utf8(bytes).map_err(|err| { - InterpError::Unsupported(UnsupportedOpInfo::ValidationFailure(err.to_string())) + err_unsup!(ValidationFailure(err.to_string())) })?; Ok(str) } @@ -604,7 +603,6 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let raw_discr = discr_val.to_scalar_or_undef(); trace!("discr value: {:?}", raw_discr); // post-process - use rustc::mir::interpret::UnsupportedOpInfo::InvalidDiscriminant; Ok(match *discr_kind { layout::DiscriminantKind::Tag => { let bits_discr = match raw_discr.to_bits(discr_val.layout.size) { @@ -649,7 +647,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let variants_start = niche_variants.start().as_u32() as u128; let variants_end = niche_variants.end().as_u32() as u128; let raw_discr = raw_discr.not_undef().map_err(|_| { - InterpError::Unsupported(InvalidDiscriminant(ScalarMaybeUndef::Undef)) + err_unsup!(InvalidDiscriminant(ScalarMaybeUndef::Undef)) })?; match raw_discr.to_bits_or_ptr(discr_val.layout.size, self) { Err(ptr) => { diff --git a/src/librustc_mir/interpret/snapshot.rs b/src/librustc_mir/interpret/snapshot.rs index ebf7dd3b6628c..70a297c866280 100644 --- a/src/librustc_mir/interpret/snapshot.rs +++ b/src/librustc_mir/interpret/snapshot.rs @@ -11,8 +11,7 @@ use rustc::ich::StableHashingContextProvider; use rustc::mir; use rustc::mir::interpret::{ AllocId, Pointer, Scalar, - Relocations, Allocation, UndefMask, - InterpResult, InterpError, ResourceExhaustionInfo, + Relocations, Allocation, UndefMask, InterpResult, }; use rustc::ty::{self, TyCtxt}; @@ -77,7 +76,7 @@ impl<'mir, 'tcx> InfiniteLoopDetector<'mir, 'tcx> { } // Second cycle - Err(InterpError::ResourceExhaustion(ResourceExhaustionInfo::InfiniteLoop).into()) + throw_exhaust!(InfiniteLoop) } } diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs index aa06922fb95f7..d4bc8f460e894 100644 --- a/src/librustc_mir/interpret/terminator.rs +++ b/src/librustc_mir/interpret/terminator.rs @@ -136,31 +136,29 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } else { // Compute error message use rustc::mir::interpret::PanicInfo::*; - match msg { + return Err(match msg { BoundsCheck { ref len, ref index } => { - let len = self.read_immediate(self.eval_operand(len, None)?) - .expect("can't eval len").to_scalar()? + let len = self + .read_immediate(self.eval_operand(len, None)?) + .expect("can't eval len") + .to_scalar()? .to_bits(self.memory().pointer_size())? as u64; - let index = self.read_immediate(self.eval_operand(index, None)?) - .expect("can't eval index").to_scalar()? + let index = self + .read_immediate(self.eval_operand(index, None)?) + .expect("can't eval index") + .to_scalar()? .to_bits(self.memory().pointer_size())? as u64; - throw_panic!(BoundsCheck { len, index }) + err_panic!(BoundsCheck { len, index }) } - Overflow(op) => - throw_panic!(Overflow(*op)), - OverflowNeg => - throw_panic!(OverflowNeg), - DivisionByZero => - throw_panic!(DivisionByZero), - RemainderByZero => - throw_panic!(RemainderByZero), - GeneratorResumedAfterReturn => - throw_panic!(GeneratorResumedAfterReturn), - GeneratorResumedAfterPanic => - throw_panic!(GeneratorResumedAfterPanic), - Panic { .. } => - bug!("`Panic` variant cannot occur in MIR"), - }; + Overflow(op) => err_panic!(Overflow(*op)), + OverflowNeg => err_panic!(OverflowNeg), + DivisionByZero => err_panic!(DivisionByZero), + RemainderByZero => err_panic!(RemainderByZero), + GeneratorResumedAfterReturn => err_panic!(GeneratorResumedAfterReturn), + GeneratorResumedAfterPanic => err_panic!(GeneratorResumedAfterPanic), + Panic { .. } => bug!("`Panic` variant cannot occur in MIR"), + } + .into()); } } diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs index aa2461729641d..072c9afc50ae0 100644 --- a/src/librustc_mir/interpret/validity.rs +++ b/src/librustc_mir/interpret/validity.rs @@ -10,11 +10,11 @@ use rustc_data_structures::fx::FxHashSet; use std::hash::Hash; use super::{ - GlobalAlloc, InterpResult, InterpError, - OpTy, Machine, InterpCx, ValueVisitor, MPlaceTy, UnsupportedOpInfo, + GlobalAlloc, InterpResult, + OpTy, Machine, InterpCx, ValueVisitor, MPlaceTy, }; -macro_rules! validation_failure { +macro_rules! throw_validation_failure { ($what:expr, $where:expr, $details:expr) => {{ let where_ = path_format(&$where); let where_ = if where_.is_empty() { @@ -45,14 +45,14 @@ macro_rules! try_validation { ($e:expr, $what:expr, $where:expr, $details:expr) => {{ match $e { Ok(x) => x, - Err(_) => validation_failure!($what, $where, $details), + Err(_) => throw_validation_failure!($what, $where, $details), } }}; ($e:expr, $what:expr, $where:expr) => {{ match $e { Ok(x) => x, - Err(_) => validation_failure!($what, $where), + Err(_) => throw_validation_failure!($what, $where), } }} } @@ -297,12 +297,12 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> match self.walk_value(op) { Ok(()) => Ok(()), Err(err) => match err.kind { - InterpError::Unsupported(UnsupportedOpInfo::InvalidDiscriminant(val)) => - validation_failure!( + err_unsup!(InvalidDiscriminant(val)) => + throw_validation_failure!( val, self.path, "a valid enum discriminant" ), - InterpError::Unsupported(UnsupportedOpInfo::ReadPointerAsBytes) => - validation_failure!( + err_unsup!(ReadPointerAsBytes) => + throw_validation_failure!( "a pointer", self.path, "plain (non-pointer) bytes" ), _ => Err(err), @@ -405,21 +405,20 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> "{:?} did not pass access check for size {:?}, align {:?}", ptr, size, align ); - use super::UnsupportedOpInfo::*; match err.kind { - InterpError::Unsupported(InvalidNullPointerUsage) => - validation_failure!("NULL reference", self.path), - InterpError::Unsupported(AlignmentCheckFailed { required, has }) => - validation_failure!(format!("unaligned reference \ + err_unsup!(InvalidNullPointerUsage) => + throw_validation_failure!("NULL reference", self.path), + err_unsup!(AlignmentCheckFailed { required, has }) => + throw_validation_failure!(format!("unaligned reference \ (required {} byte alignment but found {})", required.bytes(), has.bytes()), self.path), - InterpError::Unsupported(ReadBytesAsPointer) => - validation_failure!( + err_unsup!(ReadBytesAsPointer) => + throw_validation_failure!( "dangling reference (created from integer)", self.path ), _ => - validation_failure!( + throw_validation_failure!( "dangling reference (not entirely in bounds)", self.path ), @@ -479,7 +478,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> fn visit_uninhabited(&mut self) -> InterpResult<'tcx> { - validation_failure!("a value of an uninhabited type", self.path) + throw_validation_failure!("a value of an uninhabited type", self.path) } fn visit_scalar( @@ -512,7 +511,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> if lo == 1 && hi == max_hi { // Only NULL is the niche. So make sure the ptr is NOT NULL. if self.ecx.memory.ptr_may_be_null(ptr) { - validation_failure!( + throw_validation_failure!( "a potentially NULL pointer", self.path, format!( @@ -525,7 +524,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> } else { // Conservatively, we reject, because the pointer *could* have a bad // value. - validation_failure!( + throw_validation_failure!( "a pointer", self.path, format!( @@ -542,7 +541,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> if wrapping_range_contains(&layout.valid_range, bits) { Ok(()) } else { - validation_failure!( + throw_validation_failure!( bits, self.path, format!("something {}", wrapping_range_format(&layout.valid_range, max_hi)) @@ -609,14 +608,14 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> Err(err) => { // For some errors we might be able to provide extra information match err.kind { - InterpError::Unsupported(UnsupportedOpInfo::ReadUndefBytes(offset)) => { + err_unsup!(ReadUndefBytes(offset)) => { // Some byte was undefined, determine which // element that byte belongs to so we can // provide an index. let i = (offset.bytes() / ty_size.bytes()) as usize; self.path.push(PathElem::ArrayElem(i)); - validation_failure!("undefined bytes", self.path) + throw_validation_failure!("undefined bytes", self.path) }, // Other errors shouldn't be possible _ => return Err(err), diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 807a7e88498b8..164a268004d2d 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -13,7 +13,7 @@ use rustc::mir::{ use rustc::mir::visit::{ Visitor, PlaceContext, MutatingUseContext, MutVisitor, NonMutatingUseContext, }; -use rustc::mir::interpret::{Scalar, GlobalId, InterpResult, InterpError, PanicInfo}; +use rustc::mir::interpret::{Scalar, GlobalId, InterpResult, PanicInfo}; use rustc::ty::{self, Instance, ParamEnv, Ty, TyCtxt}; use syntax_pos::{Span, DUMMY_SP}; use rustc::ty::subst::InternalSubsts; @@ -519,7 +519,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { ) } else { if overflow { - let err = InterpError::Panic(PanicInfo::Overflow(op)).into(); + let err = err_panic!(Overflow(op)).into(); let _: Option<()> = self.use_ecx(source_info, |_| Err(err)); return None; } From a1e59d17e33d317842ccbc3253517b3629e31eb0 Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Wed, 31 Jul 2019 16:38:39 +0530 Subject: [PATCH 22/25] code review fixes --- src/librustc_mir/interpret/cast.rs | 6 +++--- src/librustc_mir/interpret/memory.rs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs index 9e87e112892cd..a481a3b37b717 100644 --- a/src/librustc_mir/interpret/cast.rs +++ b/src/librustc_mir/interpret/cast.rs @@ -80,13 +80,13 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { if self.tcx.has_attr(def_id, sym::rustc_args_required_const) { bug!("reifying a fn ptr that requires const arguments"); } - let instance: InterpResult<'tcx, _> = ty::Instance::resolve( + let instance = ty::Instance::resolve( *self.tcx, self.param_env, def_id, substs, - ).ok_or_else(|| err_inval!(TooGeneric).into()); - let fn_ptr = self.memory.create_fn_alloc(FnVal::Instance(instance?)); + ).ok_or_else(|| err_inval!(TooGeneric))?; + let fn_ptr = self.memory.create_fn_alloc(FnVal::Instance(instance)); self.write_scalar(Scalar::Ptr(fn_ptr.into()), dest)?; } _ => bug!("reify fn pointer on {:?}", src.layout.ty), diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 85ed3b3efd68c..a1574cd5935e9 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -363,7 +363,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { // the "real" alignment. throw_unsup!(AlignmentCheckFailed { has: alloc_align, - required: align + required: align, }) } check_offset_align(ptr.offset.bytes(), align)?; From c17d11fb39d93b1093fe19ca3c3db09130d3f47c Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Wed, 31 Jul 2019 18:14:49 +0530 Subject: [PATCH 23/25] code review fixes --- src/librustc/mir/interpret/allocation.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs index a9393561bfd09..ce04cca96e0f9 100644 --- a/src/librustc/mir/interpret/allocation.rs +++ b/src/librustc/mir/interpret/allocation.rs @@ -235,17 +235,17 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra> Allocation { { assert_eq!(ptr.offset.bytes() as usize as u64, ptr.offset.bytes()); let offset = ptr.offset.bytes() as usize; - match self.bytes[offset..].iter().position(|&c| c == 0) { + Ok(match self.bytes[offset..].iter().position(|&c| c == 0) { Some(size) => { let size_with_null = Size::from_bytes((size + 1) as u64); // Go through `get_bytes` for checks and AllocationExtra hooks. // We read the null, so we include it in the request, but we want it removed // from the result, so we do subslicing. - Ok(&self.get_bytes(cx, ptr, size_with_null)?[..size]) + &self.get_bytes(cx, ptr, size_with_null)?[..size] } // This includes the case where `offset` is out-of-bounds to begin with. None => throw_unsup!(UnterminatedCString(ptr.erase_tag())), - } + }) } /// Validates that `ptr.offset` and `ptr.offset + size` do not point to the middle of a From 0c4513e8ed576050c677763eeb632afbba83dce1 Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Thu, 1 Aug 2019 09:49:01 +0530 Subject: [PATCH 24/25] code review fixes --- src/librustc/mir/interpret/mod.rs | 71 ++++++++++++---------- src/librustc_mir/interpret/eval_context.rs | 4 +- src/librustc_mir/transform/const_prop.rs | 8 +-- 3 files changed, 43 insertions(+), 40 deletions(-) diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs index 8feb04ffe88db..f3ed4ffab7d0f 100644 --- a/src/librustc/mir/interpret/mod.rs +++ b/src/librustc/mir/interpret/mod.rs @@ -1,34 +1,14 @@ //! An interpreter for MIR used in CTFE and by miri #[macro_export] -macro_rules! throw_unsup { - ($($tt:tt)*) => { return Err(err_unsup!($($tt)*).into()) }; -} - -#[macro_export] -macro_rules! throw_inval { - ($($tt:tt)*) => { return Err(err_inval!($($tt)*).into()) }; -} - -#[macro_export] -macro_rules! throw_ub { +macro_rules! err_unsup { ($($tt:tt)*) => { - return Err($crate::mir::interpret::InterpError::UndefinedBehaviour( - $crate::mir::interpret::UndefinedBehaviourInfo::$($tt)* - ).into()) + $crate::mir::interpret::InterpError::Unsupported( + $crate::mir::interpret::UnsupportedOpInfo::$($tt)* + ) }; } -#[macro_export] -macro_rules! throw_panic { - ($($tt:tt)*) => { return Err(err_panic!($($tt)*).into()) }; -} - -#[macro_export] -macro_rules! throw_exhaust { - ($($tt:tt)*) => { return Err(err_exhaust!($($tt)*).into()) }; -} - #[macro_export] macro_rules! err_inval { ($($tt:tt)*) => { @@ -39,10 +19,19 @@ macro_rules! err_inval { } #[macro_export] -macro_rules! err_unsup { +macro_rules! err_ub { ($($tt:tt)*) => { - $crate::mir::interpret::InterpError::Unsupported( - $crate::mir::interpret::UnsupportedOpInfo::$($tt)* + $crate::mir::interpret::InterpError::UndefinedBehaviour( + $crate::mir::interpret::UndefinedBehaviourInfo::$($tt)* + ) + }; +} + +#[macro_export] +macro_rules! err_panic { + ($($tt:tt)*) => { + $crate::mir::interpret::InterpError::Panic( + $crate::mir::interpret::PanicInfo::$($tt)* ) }; } @@ -57,14 +46,34 @@ macro_rules! err_exhaust { } #[macro_export] -macro_rules! err_panic { +macro_rules! throw_unsup { + ($($tt:tt)*) => { return Err(err_unsup!($($tt)*).into()) }; +} + +#[macro_export] +macro_rules! throw_inval { + ($($tt:tt)*) => { return Err(err_inval!($($tt)*).into()) }; +} + +#[macro_export] +macro_rules! throw_ub { ($($tt:tt)*) => { - $crate::mir::interpret::InterpError::Panic( - $crate::mir::interpret::PanicInfo::$($tt)* - ) + return Err($crate::mir::interpret::InterpError::UndefinedBehaviour( + $crate::mir::interpret::UndefinedBehaviourInfo::$($tt)* + ).into()) }; } +#[macro_export] +macro_rules! throw_panic { + ($($tt:tt)*) => { return Err(err_panic!($($tt)*).into()) }; +} + +#[macro_export] +macro_rules! throw_exhaust { + ($($tt:tt)*) => { return Err(err_exhaust!($($tt)*).into()) }; +} + mod error; mod value; mod allocation; diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 7ab99976b404b..f10d7fb965116 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -191,9 +191,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> LayoutOf for InterpCx<'mir, 'tcx, M> { fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyLayout { self.tcx .layout_of(self.param_env.and(ty)) - .map_err(|layout| { - err_inval!(Layout(layout)).into() - }) + .map_err(|layout| err_inval!(Layout(layout)).into()) } } diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 164a268004d2d..5783f53316c57 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -259,12 +259,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { use rustc::mir::interpret::InterpError::*; match diagnostic.error { Exit(_) => bug!("the CTFE program cannot exit"), - | Unsupported(_) => {}, - | UndefinedBehaviour(_) => {}, - | InvalidProgram(_) => {}, - | ResourceExhaustion(_) => {}, - | Panic(_) - => { + Panic(_) => { diagnostic.report_as_lint( self.ecx.tcx, "this expression will panic at runtime", @@ -272,6 +267,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { None, ); } + _ => {}, } None }, From 00d32e8687a91f016580e0dee22cec0531ed028b Mon Sep 17 00:00:00 2001 From: Saleem Jaffer Date: Thu, 1 Aug 2019 12:13:49 +0530 Subject: [PATCH 25/25] code review fixes --- src/librustc/mir/interpret/mod.rs | 6 +----- src/librustc_mir/transform/const_prop.rs | 7 ++++++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs index f3ed4ffab7d0f..723a30792fddc 100644 --- a/src/librustc/mir/interpret/mod.rs +++ b/src/librustc/mir/interpret/mod.rs @@ -57,11 +57,7 @@ macro_rules! throw_inval { #[macro_export] macro_rules! throw_ub { - ($($tt:tt)*) => { - return Err($crate::mir::interpret::InterpError::UndefinedBehaviour( - $crate::mir::interpret::UndefinedBehaviourInfo::$($tt)* - ).into()) - }; + ($($tt:tt)*) => { return Err(err_ub!($($tt)*).into()) }; } #[macro_export] diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 5783f53316c57..a450ec32e1a47 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -259,6 +259,12 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { use rustc::mir::interpret::InterpError::*; match diagnostic.error { Exit(_) => bug!("the CTFE program cannot exit"), + Unsupported(_) + | UndefinedBehaviour(_) + | InvalidProgram(_) + | ResourceExhaustion(_) => { + // Ignore these errors. + } Panic(_) => { diagnostic.report_as_lint( self.ecx.tcx, @@ -267,7 +273,6 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { None, ); } - _ => {}, } None },