mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 08:44:35 +00:00
Detect uninhabited types early in const eval.
This commit is contained in:
parent
83dec62b26
commit
f066d6785d
@ -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(
|
||||
|
@ -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() {}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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() {
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
9
tests/ui/consts/issue-64506.stderr
Normal file
9
tests/ui/consts/issue-64506.stderr
Normal 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`.
|
Loading…
Reference in New Issue
Block a user