diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index aca39d438c1..b01eb28e946 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -256,7 +256,10 @@ pub enum UndefinedBehaviorInfo<'tcx> { /// The value validity check found a problem. /// Should only be thrown by `validity.rs` and always point out which part of the value /// is the problem. - ValidationFailure(String), + ValidationFailure { + path: Option, + msg: String, + }, /// Using a non-boolean `u8` as bool. InvalidBool(u8), /// Using a non-character `u32` as character. @@ -331,7 +334,10 @@ impl fmt::Display for UndefinedBehaviorInfo<'_> { ), WriteToReadOnly(a) => write!(f, "writing to {} which is read-only", a), DerefFunctionPointer(a) => write!(f, "accessing {} which contains a function", a), - ValidationFailure(ref err) => write!(f, "type validation failed: {}", err), + ValidationFailure { path: None, msg } => write!(f, "type validation failed: {}", msg), + ValidationFailure { path: Some(path), msg } => { + write!(f, "type validation failed at {}: {}", path, msg) + } InvalidBool(b) => { write!(f, "interpreting an invalid 8-bit value as a bool: 0x{:02x}", b) } @@ -499,13 +505,13 @@ impl fmt::Debug for InterpError<'_> { } impl InterpError<'_> { - /// Some errors to string formatting even if the error is never printed. + /// Some errors do string formatting even if the error is never printed. /// To avoid performance issues, there are places where we want to be sure to never raise these formatting errors, /// so this method lets us detect them and `bug!` on unexpected errors. pub fn formatted_string(&self) -> bool { match self { InterpError::Unsupported(UnsupportedOpInfo::Unsupported(_)) - | InterpError::UndefinedBehavior(UndefinedBehaviorInfo::ValidationFailure(_)) + | InterpError::UndefinedBehavior(UndefinedBehaviorInfo::ValidationFailure { .. }) | InterpError::UndefinedBehavior(UndefinedBehaviorInfo::Ub(_)) => true, _ => false, } diff --git a/compiler/rustc_mir/src/interpret/validity.rs b/compiler/rustc_mir/src/interpret/validity.rs index c9ebffe8d1c..7511890090b 100644 --- a/compiler/rustc_mir/src/interpret/validity.rs +++ b/compiler/rustc_mir/src/interpret/validity.rs @@ -26,23 +26,27 @@ use super::{ macro_rules! throw_validation_failure { ($where:expr, { $( $what_fmt:expr ),+ } $( expected { $( $expected_fmt:expr ),+ } )?) => {{ - let msg = rustc_middle::ty::print::with_no_trimmed_paths(|| { + let (path, msg) = rustc_middle::ty::print::with_no_trimmed_paths(|| { let mut msg = String::new(); msg.push_str("encountered "); write!(&mut msg, $($what_fmt),+).unwrap(); - let where_ = &$where; - if !where_.is_empty() { - msg.push_str(" at "); - write_path(&mut msg, where_); - } $( msg.push_str(", but expected "); write!(&mut msg, $($expected_fmt),+).unwrap(); )? - msg + let where_ = &$where; + let path = if !where_.is_empty() { + let mut path = String::new(); + write_path(&mut path, where_); + Some(path) + } else { + None + }; + + (path, msg) }); - throw_ub!(ValidationFailure(msg)) + throw_ub!(ValidationFailure { path, msg }) }}; }