Skip to content

Commit f066d67

Browse files
committed
Detect uninhabited types early in const eval.
1 parent 83dec62 commit f066d67

8 files changed

+28
-30
lines changed

compiler/rustc_const_eval/src/const_eval/machine.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -335,8 +335,8 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
335335
}
336336

337337
#[inline(always)]
338-
fn enforce_validity(ecx: &InterpCx<'mir, 'tcx, Self>, _layout: TyAndLayout<'tcx>) -> bool {
339-
ecx.tcx.sess.opts.unstable_opts.extra_const_ub_checks
338+
fn enforce_validity(ecx: &InterpCx<'mir, 'tcx, Self>, layout: TyAndLayout<'tcx>) -> bool {
339+
ecx.tcx.sess.opts.unstable_opts.extra_const_ub_checks || layout.abi.is_uninhabited()
340340
}
341341

342342
fn alignment_check_failed(

tests/ui/consts/const-eval/ub-uninhabit.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@ union MaybeUninit<T: Copy> {
1414
}
1515

1616
const BAD_BAD_BAD: Bar = unsafe { MaybeUninit { uninit: () }.init };
17-
//~^ ERROR it is undefined behavior to use this value
17+
//~^ ERROR evaluation of constant value failed
1818

1919
const BAD_BAD_REF: &Bar = unsafe { mem::transmute(1usize) };
2020
//~^ ERROR it is undefined behavior to use this value
2121

2222
const BAD_BAD_ARRAY: [Bar; 1] = unsafe { MaybeUninit { uninit: () }.init };
23-
//~^ ERROR it is undefined behavior to use this value
23+
//~^ ERROR evaluation of constant value failed
2424

2525
fn main() {}

tests/ui/consts/const-eval/ub-uninhabit.stderr

+6-12
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
1-
error[E0080]: it is undefined behavior to use this value
2-
--> $DIR/ub-uninhabit.rs:16:1
1+
error[E0080]: evaluation of constant value failed
2+
--> $DIR/ub-uninhabit.rs:16:35
33
|
44
LL | const BAD_BAD_BAD: Bar = unsafe { MaybeUninit { uninit: () }.init };
5-
| ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a value of uninhabited type Bar
6-
|
7-
= 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.
8-
= note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {}
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a value of uninhabited type Bar
96

107
error[E0080]: it is undefined behavior to use this value
118
--> $DIR/ub-uninhabit.rs:19:1
@@ -18,14 +15,11 @@ LL | const BAD_BAD_REF: &Bar = unsafe { mem::transmute(1usize) };
1815
HEX_DUMP
1916
}
2017

21-
error[E0080]: it is undefined behavior to use this value
22-
--> $DIR/ub-uninhabit.rs:22:1
18+
error[E0080]: evaluation of constant value failed
19+
--> $DIR/ub-uninhabit.rs:22:42
2320
|
2421
LL | const BAD_BAD_ARRAY: [Bar; 1] = unsafe { MaybeUninit { uninit: () }.init };
25-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at [0]: encountered a value of uninhabited type Bar
26-
|
27-
= 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.
28-
= note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {}
22+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at [0]: encountered a value of uninhabited type Bar
2923

3024
error: aborting due to 3 previous errors
3125

tests/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr

+3-6
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,11 @@ note: inside `FOO`
2424
LL | const FOO: [empty::Empty; 3] = [foo(); 3];
2525
| ^^^^^
2626

27-
error[E0080]: it is undefined behavior to use this value
28-
--> $DIR/validate_uninhabited_zsts.rs:21:1
27+
error[E0080]: evaluation of constant value failed
28+
--> $DIR/validate_uninhabited_zsts.rs:21:42
2929
|
3030
LL | const BAR: [empty::Empty; 3] = [unsafe { std::mem::transmute(()) }; 3];
31-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at [0].0: encountered a value of uninhabited type empty::Void
32-
|
33-
= 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.
34-
= note: the raw bytes of the constant (size: 0, align: 1) {}
31+
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered a value of uninhabited type empty::Void
3532

3633
warning: the type `empty::Empty` does not permit zero-initialization
3734
--> $DIR/validate_uninhabited_zsts.rs:21:42

tests/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr

+3-6
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,11 @@ note: inside `FOO`
2424
LL | const FOO: [empty::Empty; 3] = [foo(); 3];
2525
| ^^^^^
2626

27-
error[E0080]: it is undefined behavior to use this value
28-
--> $DIR/validate_uninhabited_zsts.rs:21:1
27+
error[E0080]: evaluation of constant value failed
28+
--> $DIR/validate_uninhabited_zsts.rs:21:42
2929
|
3030
LL | const BAR: [empty::Empty; 3] = [unsafe { std::mem::transmute(()) }; 3];
31-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at [0].0: encountered a value of uninhabited type empty::Void
32-
|
33-
= 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.
34-
= note: the raw bytes of the constant (size: 0, align: 1) {}
31+
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered a value of uninhabited type empty::Void
3532

3633
warning: the type `empty::Empty` does not permit zero-initialization
3734
--> $DIR/validate_uninhabited_zsts.rs:21:42

tests/ui/consts/const-eval/validate_uninhabited_zsts.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pub mod empty {
1919
const FOO: [empty::Empty; 3] = [foo(); 3];
2020

2121
const BAR: [empty::Empty; 3] = [unsafe { std::mem::transmute(()) }; 3];
22-
//~^ ERROR it is undefined behavior to use this value
22+
//~^ ERROR evaluation of constant value failed
2323
//~| WARN the type `empty::Empty` does not permit zero-initialization
2424

2525
fn main() {

tests/ui/consts/issue-64506.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// check-pass
1+
// check-fail
22

33
#[derive(Copy, Clone)]
44
pub struct ChildStdin {
@@ -14,6 +14,7 @@ const FOO: () = {
1414
b: (),
1515
}
1616
let x = unsafe { Foo { b: () }.a };
17+
//~^ ERROR: evaluation of constant value failed
1718
let x = &x.inner;
1819
};
1920

tests/ui/consts/issue-64506.stderr

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0080]: evaluation of constant value failed
2+
--> $DIR/issue-64506.rs:16:22
3+
|
4+
LL | let x = unsafe { Foo { b: () }.a };
5+
| ^^^^^^^^^^^^^^^ constructing invalid value at .inner: encountered a value of uninhabited type AnonPipe
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0080`.

0 commit comments

Comments
 (0)