Skip to content

Commit 539d7bd

Browse files
committed
Auto merge of #86275 - lqd:ctfe-validation, r=RalfJung
Improve CTFE UB validation error messages As mentioned in #86245 (comment) this PR slightly improves the formatting of validation errors, to move the path to the error prefix. From: `type validation failed: encountered invalid vtable: size is bigger than largest supported object at .0` To: `type validation failed at .0: encountered invalid vtable: size is bigger than largest supported object`.
2 parents 3044419 + 5af1c72 commit 539d7bd

34 files changed

+121
-112
lines changed

compiler/rustc_middle/src/mir/interpret/error.rs

+12-4
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,12 @@ pub enum UndefinedBehaviorInfo<'tcx> {
256256
/// The value validity check found a problem.
257257
/// Should only be thrown by `validity.rs` and always point out which part of the value
258258
/// is the problem.
259-
ValidationFailure(String),
259+
ValidationFailure {
260+
/// The "path" to the value in question, e.g. `.0[5].field` for a struct
261+
/// field in the 6th element of an array that is the first element of a tuple.
262+
path: Option<String>,
263+
msg: String,
264+
},
260265
/// Using a non-boolean `u8` as bool.
261266
InvalidBool(u8),
262267
/// Using a non-character `u32` as character.
@@ -331,7 +336,10 @@ impl fmt::Display for UndefinedBehaviorInfo<'_> {
331336
),
332337
WriteToReadOnly(a) => write!(f, "writing to {} which is read-only", a),
333338
DerefFunctionPointer(a) => write!(f, "accessing {} which contains a function", a),
334-
ValidationFailure(ref err) => write!(f, "type validation failed: {}", err),
339+
ValidationFailure { path: None, msg } => write!(f, "type validation failed: {}", msg),
340+
ValidationFailure { path: Some(path), msg } => {
341+
write!(f, "type validation failed at {}: {}", path, msg)
342+
}
335343
InvalidBool(b) => {
336344
write!(f, "interpreting an invalid 8-bit value as a bool: 0x{:02x}", b)
337345
}
@@ -499,13 +507,13 @@ impl fmt::Debug for InterpError<'_> {
499507
}
500508

501509
impl InterpError<'_> {
502-
/// Some errors to string formatting even if the error is never printed.
510+
/// Some errors do string formatting even if the error is never printed.
503511
/// To avoid performance issues, there are places where we want to be sure to never raise these formatting errors,
504512
/// so this method lets us detect them and `bug!` on unexpected errors.
505513
pub fn formatted_string(&self) -> bool {
506514
match self {
507515
InterpError::Unsupported(UnsupportedOpInfo::Unsupported(_))
508-
| InterpError::UndefinedBehavior(UndefinedBehaviorInfo::ValidationFailure(_))
516+
| InterpError::UndefinedBehavior(UndefinedBehaviorInfo::ValidationFailure { .. })
509517
| InterpError::UndefinedBehavior(UndefinedBehaviorInfo::Ub(_)) => true,
510518
_ => false,
511519
}

compiler/rustc_mir/src/interpret/validity.rs

+14-13
Original file line numberDiff line numberDiff line change
@@ -26,23 +26,24 @@ use super::{
2626

2727
macro_rules! throw_validation_failure {
2828
($where:expr, { $( $what_fmt:expr ),+ } $( expected { $( $expected_fmt:expr ),+ } )?) => {{
29-
let msg = rustc_middle::ty::print::with_no_trimmed_paths(|| {
30-
let mut msg = String::new();
31-
msg.push_str("encountered ");
32-
write!(&mut msg, $($what_fmt),+).unwrap();
29+
let mut msg = String::new();
30+
msg.push_str("encountered ");
31+
write!(&mut msg, $($what_fmt),+).unwrap();
32+
$(
33+
msg.push_str(", but expected ");
34+
write!(&mut msg, $($expected_fmt),+).unwrap();
35+
)?
36+
let path = rustc_middle::ty::print::with_no_trimmed_paths(|| {
3337
let where_ = &$where;
3438
if !where_.is_empty() {
35-
msg.push_str(" at ");
36-
write_path(&mut msg, where_);
39+
let mut path = String::new();
40+
write_path(&mut path, where_);
41+
Some(path)
42+
} else {
43+
None
3744
}
38-
$(
39-
msg.push_str(", but expected ");
40-
write!(&mut msg, $($expected_fmt),+).unwrap();
41-
)?
42-
43-
msg
4445
});
45-
throw_ub!(ValidationFailure(msg))
46+
throw_ub!(ValidationFailure { path, msg })
4647
}};
4748
}
4849

src/test/ui/consts/const-eval/heap/alloc_intrinsic_uninit.32bit.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0080]: it is undefined behavior to use this value
22
--> $DIR/alloc_intrinsic_uninit.rs:9:1
33
|
44
LL | const BAR: &i32 = unsafe { &*(intrinsics::const_allocate(4, 4) as *mut i32) };
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes at .<deref>, but expected initialized plain (non-pointer) bytes
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .<deref>: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes
66
|
77
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
88
= note: the raw bytes of the constant (size: 4, align: 4) {

src/test/ui/consts/const-eval/heap/alloc_intrinsic_uninit.64bit.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0080]: it is undefined behavior to use this value
22
--> $DIR/alloc_intrinsic_uninit.rs:9:1
33
|
44
LL | const BAR: &i32 = unsafe { &*(intrinsics::const_allocate(4, 4) as *mut i32) };
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes at .<deref>, but expected initialized plain (non-pointer) bytes
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .<deref>: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes
66
|
77
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
88
= note: the raw bytes of the constant (size: 8, align: 8) {

src/test/ui/consts/const-eval/ub-enum.32bit.stderr

+13-13
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0080]: it is undefined behavior to use this value
22
--> $DIR/ub-enum.rs:24:1
33
|
44
LL | const BAD_ENUM: Enum = unsafe { mem::transmute(1usize) };
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x00000001 at .<enum-tag>, but expected a valid enum tag
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .<enum-tag>: encountered 0x00000001, but expected a valid enum tag
66
|
77
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
88
= note: the raw bytes of the constant (size: 4, align: 4) {
@@ -13,7 +13,7 @@ error[E0080]: it is undefined behavior to use this value
1313
--> $DIR/ub-enum.rs:27:1
1414
|
1515
LL | const BAD_ENUM_PTR: Enum = unsafe { mem::transmute(&1) };
16-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc8 at .<enum-tag>, but expected initialized plain (non-pointer) bytes
16+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .<enum-tag>: encountered pointer to alloc8, but expected initialized plain (non-pointer) bytes
1717
|
1818
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
1919
= note: the raw bytes of the constant (size: 4, align: 4) {
@@ -24,7 +24,7 @@ error[E0080]: it is undefined behavior to use this value
2424
--> $DIR/ub-enum.rs:30:1
2525
|
2626
LL | const BAD_ENUM_WRAPPED: Wrap<Enum> = unsafe { mem::transmute(&1) };
27-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc12 at .0.<enum-tag>, but expected initialized plain (non-pointer) bytes
27+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .0.<enum-tag>: encountered pointer to alloc12, but expected initialized plain (non-pointer) bytes
2828
|
2929
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
3030
= note: the raw bytes of the constant (size: 4, align: 4) {
@@ -35,7 +35,7 @@ error[E0080]: it is undefined behavior to use this value
3535
--> $DIR/ub-enum.rs:42:1
3636
|
3737
LL | const BAD_ENUM2: Enum2 = unsafe { mem::transmute(0usize) };
38-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0x00000000 at .<enum-tag>, but expected a valid enum tag
38+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .<enum-tag>: encountered 0x00000000, but expected a valid enum tag
3939
|
4040
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
4141
= note: the raw bytes of the constant (size: 4, align: 4) {
@@ -46,7 +46,7 @@ error[E0080]: it is undefined behavior to use this value
4646
--> $DIR/ub-enum.rs:44:1
4747
|
4848
LL | const BAD_ENUM2_PTR: Enum2 = unsafe { mem::transmute(&0) };
49-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc18 at .<enum-tag>, but expected initialized plain (non-pointer) bytes
49+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .<enum-tag>: encountered pointer to alloc18, but expected initialized plain (non-pointer) bytes
5050
|
5151
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
5252
= note: the raw bytes of the constant (size: 4, align: 4) {
@@ -57,7 +57,7 @@ error[E0080]: it is undefined behavior to use this value
5757
--> $DIR/ub-enum.rs:47:1
5858
|
5959
LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { mem::transmute(&0) };
60-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc22 at .0.<enum-tag>, but expected initialized plain (non-pointer) bytes
60+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .0.<enum-tag>: encountered pointer to alloc22, but expected initialized plain (non-pointer) bytes
6161
|
6262
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
6363
= note: the raw bytes of the constant (size: 4, align: 4) {
@@ -68,7 +68,7 @@ error[E0080]: it is undefined behavior to use this value
6868
--> $DIR/ub-enum.rs:56:1
6969
|
7070
LL | const BAD_ENUM2_UNDEF : Enum2 = unsafe { MaybeUninit { uninit: () }.init };
71-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes at .<enum-tag>, but expected initialized plain (non-pointer) bytes
71+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .<enum-tag>: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes
7272
|
7373
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
7474
= note: the raw bytes of the constant (size: 4, align: 4) {
@@ -79,7 +79,7 @@ error[E0080]: it is undefined behavior to use this value
7979
--> $DIR/ub-enum.rs:60:1
8080
|
8181
LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) };
82-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer to alloc28 at .<enum-tag>, but expected initialized plain (non-pointer) bytes
82+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .<enum-tag>: encountered pointer to alloc28, but expected initialized plain (non-pointer) bytes
8383
|
8484
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
8585
= note: the raw bytes of the constant (size: 4, align: 4) {
@@ -90,7 +90,7 @@ error[E0080]: it is undefined behavior to use this value
9090
--> $DIR/ub-enum.rs:77:1
9191
|
9292
LL | const BAD_UNINHABITED_VARIANT1: UninhDiscriminant = unsafe { mem::transmute(1u8) };
93-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of the never type `!` at .<enum-variant(B)>.0
93+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .<enum-variant(B)>.0: encountered a value of the never type `!`
9494
|
9595
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
9696
= note: the raw bytes of the constant (size: 1, align: 1) {
@@ -101,7 +101,7 @@ error[E0080]: it is undefined behavior to use this value
101101
--> $DIR/ub-enum.rs:79:1
102102
|
103103
LL | const BAD_UNINHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute(3u8) };
104-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of uninhabited type Never at .<enum-variant(D)>.0
104+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .<enum-variant(D)>.0: encountered a value of uninhabited type Never
105105
|
106106
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
107107
= note: the raw bytes of the constant (size: 1, align: 1) {
@@ -112,7 +112,7 @@ error[E0080]: it is undefined behavior to use this value
112112
--> $DIR/ub-enum.rs:87:1
113113
|
114114
LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::transmute(!0u32) }));
115-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0xffffffff at .<enum-variant(Some)>.0.1, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`)
115+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .<enum-variant(Some)>.0.1: encountered 0xffffffff, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`)
116116
|
117117
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
118118
= note: the raw bytes of the constant (size: 8, align: 4) {
@@ -123,7 +123,7 @@ error[E0080]: it is undefined behavior to use this value
123123
--> $DIR/ub-enum.rs:92:1
124124
|
125125
LL | const BAD_UNINHABITED_WITH_DATA1: Result<(i32, Never), (i32, !)> = unsafe { mem::transmute(0u64) };
126-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of uninhabited type Never at .<enum-variant(Ok)>.0.1
126+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .<enum-variant(Ok)>.0.1: encountered a value of uninhabited type Never
127127
|
128128
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
129129
= note: the raw bytes of the constant (size: 8, align: 4) {
@@ -134,7 +134,7 @@ error[E0080]: it is undefined behavior to use this value
134134
--> $DIR/ub-enum.rs:94:1
135135
|
136136
LL | const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe { mem::transmute(0u64) };
137-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of the never type `!` at .<enum-variant(Ok)>.0.1
137+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .<enum-variant(Ok)>.0.1: encountered a value of the never type `!`
138138
|
139139
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
140140
= note: the raw bytes of the constant (size: 8, align: 4) {

0 commit comments

Comments
 (0)