Detect uninhabited types early in const eval.

This commit is contained in:
Oli Scherer 2023-03-21 10:20:00 +00:00
parent 83dec62b26
commit f066d6785d
8 changed files with 28 additions and 30 deletions

View File

@ -335,8 +335,8 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
}
#[inline(always)]
fn enforce_validity(ecx: &InterpCx<'mir, 'tcx, Self>, _layout: TyAndLayout<'tcx>) -> bool {
ecx.tcx.sess.opts.unstable_opts.extra_const_ub_checks
fn enforce_validity(ecx: &InterpCx<'mir, 'tcx, Self>, layout: TyAndLayout<'tcx>) -> bool {
ecx.tcx.sess.opts.unstable_opts.extra_const_ub_checks || layout.abi.is_uninhabited()
}
fn alignment_check_failed(

View File

@ -14,12 +14,12 @@ union MaybeUninit<T: Copy> {
}
const BAD_BAD_BAD: Bar = unsafe { MaybeUninit { uninit: () }.init };
//~^ ERROR it is undefined behavior to use this value
//~^ ERROR evaluation of constant value failed
const BAD_BAD_REF: &Bar = unsafe { mem::transmute(1usize) };
//~^ ERROR it is undefined behavior to use this value
const BAD_BAD_ARRAY: [Bar; 1] = unsafe { MaybeUninit { uninit: () }.init };
//~^ ERROR it is undefined behavior to use this value
//~^ ERROR evaluation of constant value failed
fn main() {}

View File

@ -1,11 +1,8 @@
error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-uninhabit.rs:16:1
error[E0080]: evaluation of constant value failed
--> $DIR/ub-uninhabit.rs:16:35
|
LL | const BAD_BAD_BAD: Bar = unsafe { MaybeUninit { uninit: () }.init };
| ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a value of uninhabited type Bar
|
= 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.
= note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a value of uninhabited type Bar
error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-uninhabit.rs:19:1
@ -18,14 +15,11 @@ LL | const BAD_BAD_REF: &Bar = unsafe { mem::transmute(1usize) };
HEX_DUMP
}
error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-uninhabit.rs:22:1
error[E0080]: evaluation of constant value failed
--> $DIR/ub-uninhabit.rs:22:42
|
LL | const BAD_BAD_ARRAY: [Bar; 1] = unsafe { MaybeUninit { uninit: () }.init };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at [0]: encountered a value of uninhabited type Bar
|
= 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.
= note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at [0]: encountered a value of uninhabited type Bar
error: aborting due to 3 previous errors

View File

@ -24,14 +24,11 @@ note: inside `FOO`
LL | const FOO: [empty::Empty; 3] = [foo(); 3];
| ^^^^^
error[E0080]: it is undefined behavior to use this value
--> $DIR/validate_uninhabited_zsts.rs:21:1
error[E0080]: evaluation of constant value failed
--> $DIR/validate_uninhabited_zsts.rs:21:42
|
LL | const BAR: [empty::Empty; 3] = [unsafe { std::mem::transmute(()) }; 3];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at [0].0: encountered a value of uninhabited type empty::Void
|
= 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.
= note: the raw bytes of the constant (size: 0, align: 1) {}
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered a value of uninhabited type empty::Void
warning: the type `empty::Empty` does not permit zero-initialization
--> $DIR/validate_uninhabited_zsts.rs:21:42

View File

@ -24,14 +24,11 @@ note: inside `FOO`
LL | const FOO: [empty::Empty; 3] = [foo(); 3];
| ^^^^^
error[E0080]: it is undefined behavior to use this value
--> $DIR/validate_uninhabited_zsts.rs:21:1
error[E0080]: evaluation of constant value failed
--> $DIR/validate_uninhabited_zsts.rs:21:42
|
LL | const BAR: [empty::Empty; 3] = [unsafe { std::mem::transmute(()) }; 3];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at [0].0: encountered a value of uninhabited type empty::Void
|
= 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.
= note: the raw bytes of the constant (size: 0, align: 1) {}
| ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered a value of uninhabited type empty::Void
warning: the type `empty::Empty` does not permit zero-initialization
--> $DIR/validate_uninhabited_zsts.rs:21:42

View File

@ -19,7 +19,7 @@ pub mod empty {
const FOO: [empty::Empty; 3] = [foo(); 3];
const BAR: [empty::Empty; 3] = [unsafe { std::mem::transmute(()) }; 3];
//~^ ERROR it is undefined behavior to use this value
//~^ ERROR evaluation of constant value failed
//~| WARN the type `empty::Empty` does not permit zero-initialization
fn main() {

View File

@ -1,4 +1,4 @@
// check-pass
// check-fail
#[derive(Copy, Clone)]
pub struct ChildStdin {
@ -14,6 +14,7 @@ const FOO: () = {
b: (),
}
let x = unsafe { Foo { b: () }.a };
//~^ ERROR: evaluation of constant value failed
let x = &x.inner;
};

View File

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