about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRémy Rakic <remy.rakic+github@gmail.com>2021-06-13 22:40:42 +0200
committerRémy Rakic <remy.rakic+github@gmail.com>2021-06-13 22:40:42 +0200
commit87ecf84c360331a5917f6e6d29951b98d5a614ed (patch)
tree723149fe9aeda02d093c0cb8e245beda4153bc5e
parentfb3ea63d9b4c3e9bb90d4250b870faaffb9c8fd2 (diff)
downloadrust-87ecf84c360331a5917f6e6d29951b98d5a614ed.tar.gz
rust-87ecf84c360331a5917f6e6d29951b98d5a614ed.zip
Improve CTFE validation error message
-rw-r--r--compiler/rustc_middle/src/mir/interpret/error.rs14
-rw-r--r--compiler/rustc_mir/src/interpret/validity.rs20
2 files changed, 22 insertions, 12 deletions
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<String>,
+        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 })
     }};
 }