fix const_prop spans and re-bless tests
This commit is contained in:
parent
dc6ffaebd5
commit
0ac6fd0405
|
@ -2,7 +2,7 @@ use std::error::Error;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use rustc_middle::mir::AssertKind;
|
use rustc_middle::mir::AssertKind;
|
||||||
use rustc_span::Symbol;
|
use rustc_span::{Span, Symbol};
|
||||||
|
|
||||||
use super::InterpCx;
|
use super::InterpCx;
|
||||||
use crate::interpret::{ConstEvalErr, InterpErrorInfo, Machine};
|
use crate::interpret::{ConstEvalErr, InterpErrorInfo, Machine};
|
||||||
|
@ -53,8 +53,9 @@ impl Error for ConstEvalErrKind {}
|
||||||
pub fn error_to_const_error<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>>(
|
pub fn error_to_const_error<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>>(
|
||||||
ecx: &InterpCx<'mir, 'tcx, M>,
|
ecx: &InterpCx<'mir, 'tcx, M>,
|
||||||
error: InterpErrorInfo<'tcx>,
|
error: InterpErrorInfo<'tcx>,
|
||||||
|
span: Option<Span>,
|
||||||
) -> ConstEvalErr<'tcx> {
|
) -> ConstEvalErr<'tcx> {
|
||||||
error.print_backtrace();
|
error.print_backtrace();
|
||||||
let stacktrace = ecx.generate_stacktrace();
|
let stacktrace = ecx.generate_stacktrace();
|
||||||
ConstEvalErr { error: error.kind, stacktrace, span: ecx.cur_span() }
|
ConstEvalErr { error: error.kind, stacktrace, span: span.unwrap_or_else(|| ecx.cur_span()) }
|
||||||
}
|
}
|
||||||
|
|
|
@ -213,7 +213,7 @@ fn validate_and_turn_into_const<'tcx>(
|
||||||
})();
|
})();
|
||||||
|
|
||||||
val.map_err(|error| {
|
val.map_err(|error| {
|
||||||
let err = error_to_const_error(&ecx, error);
|
let err = error_to_const_error(&ecx, error, None);
|
||||||
err.struct_error(ecx.tcx_at(), "it is undefined behavior to use this value", |mut diag| {
|
err.struct_error(ecx.tcx_at(), "it is undefined behavior to use this value", |mut diag| {
|
||||||
diag.note(note_on_undefined_behavior_error());
|
diag.note(note_on_undefined_behavior_error());
|
||||||
diag.emit();
|
diag.emit();
|
||||||
|
@ -312,7 +312,7 @@ pub fn const_eval_raw_provider<'tcx>(
|
||||||
res.and_then(|body| eval_body_using_ecx(&mut ecx, cid, &body))
|
res.and_then(|body| eval_body_using_ecx(&mut ecx, cid, &body))
|
||||||
.map(|place| RawConst { alloc_id: place.ptr.assert_ptr().alloc_id, ty: place.layout.ty })
|
.map(|place| RawConst { alloc_id: place.ptr.assert_ptr().alloc_id, ty: place.layout.ty })
|
||||||
.map_err(|error| {
|
.map_err(|error| {
|
||||||
let err = error_to_const_error(&ecx, error);
|
let err = error_to_const_error(&ecx, error, None);
|
||||||
// errors in statics are always emitted as fatal errors
|
// errors in statics are always emitted as fatal errors
|
||||||
if is_static {
|
if is_static {
|
||||||
// Ensure that if the above error was either `TooGeneric` or `Reported`
|
// Ensure that if the above error was either `TooGeneric` or `Reported`
|
||||||
|
|
|
@ -268,11 +268,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
(&ty::Array(_, length), &ty::Slice(_)) => {
|
(&ty::Array(_, length), &ty::Slice(_)) => {
|
||||||
let ptr = self.read_immediate(src)?.to_scalar()?;
|
let ptr = self.read_immediate(src)?.to_scalar()?;
|
||||||
// u64 cast is from usize to u64, which is always good
|
// u64 cast is from usize to u64, which is always good
|
||||||
let val = Immediate::new_slice(
|
let val =
|
||||||
ptr,
|
Immediate::new_slice(ptr, length.eval_usize(self.tcx, self.param_env), self);
|
||||||
length.eval_usize(self.tcx, self.param_env),
|
|
||||||
self,
|
|
||||||
);
|
|
||||||
self.write_immediate(val, dest)
|
self.write_immediate(val, dest)
|
||||||
}
|
}
|
||||||
(&ty::Dynamic(..), &ty::Dynamic(..)) => {
|
(&ty::Dynamic(..), &ty::Dynamic(..)) => {
|
||||||
|
|
|
@ -314,8 +314,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn cur_span(&self) -> Span {
|
pub fn cur_span(&self) -> Span {
|
||||||
self
|
self.stack()
|
||||||
.stack()
|
|
||||||
.last()
|
.last()
|
||||||
.and_then(|f| f.current_source_info())
|
.and_then(|f| f.current_source_info())
|
||||||
.map(|si| si.span)
|
.map(|si| si.span)
|
||||||
|
@ -419,7 +418,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
let did = instance.def_id();
|
let did = instance.def_id();
|
||||||
if let Some(did) = did.as_local() {
|
if let Some(did) = did.as_local() {
|
||||||
if self.tcx_at().has_typeck_tables(did) {
|
if self.tcx_at().has_typeck_tables(did) {
|
||||||
if let Some(error_reported) = self.tcx_at().typeck_tables_of(did).tainted_by_errors {
|
if let Some(error_reported) = self.tcx_at().typeck_tables_of(did).tainted_by_errors
|
||||||
|
{
|
||||||
throw_inval!(TypeckError(error_reported))
|
throw_inval!(TypeckError(error_reported))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -404,7 +404,10 @@ where
|
||||||
// to get some code to work that probably ought to work.
|
// to get some code to work that probably ought to work.
|
||||||
field_layout.align.abi
|
field_layout.align.abi
|
||||||
}
|
}
|
||||||
None => span_bug!(self.cur_span(), "cannot compute offset for extern type field at non-0 offset"),
|
None => span_bug!(
|
||||||
|
self.cur_span(),
|
||||||
|
"cannot compute offset for extern type field at non-0 offset"
|
||||||
|
),
|
||||||
};
|
};
|
||||||
(base.meta, offset.align_to(align))
|
(base.meta, offset.align_to(align))
|
||||||
} else {
|
} else {
|
||||||
|
@ -440,7 +443,11 @@ where
|
||||||
assert!(!field_layout.is_unsized());
|
assert!(!field_layout.is_unsized());
|
||||||
base.offset(offset, MemPlaceMeta::None, field_layout, self)
|
base.offset(offset, MemPlaceMeta::None, field_layout, self)
|
||||||
}
|
}
|
||||||
_ => span_bug!(self.cur_span(), "`mplace_index` called on non-array type {:?}", base.layout.ty),
|
_ => span_bug!(
|
||||||
|
self.cur_span(),
|
||||||
|
"`mplace_index` called on non-array type {:?}",
|
||||||
|
base.layout.ty
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -484,7 +491,9 @@ where
|
||||||
// (that have count 0 in their layout).
|
// (that have count 0 in their layout).
|
||||||
let from_offset = match base.layout.fields {
|
let from_offset = match base.layout.fields {
|
||||||
FieldsShape::Array { stride, .. } => stride * from, // `Size` multiplication is checked
|
FieldsShape::Array { stride, .. } => stride * from, // `Size` multiplication is checked
|
||||||
_ => span_bug!(self.cur_span(), "unexpected layout of index access: {:#?}", base.layout),
|
_ => {
|
||||||
|
span_bug!(self.cur_span(), "unexpected layout of index access: {:#?}", base.layout)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Compute meta and new layout
|
// Compute meta and new layout
|
||||||
|
@ -497,7 +506,9 @@ where
|
||||||
let len = Scalar::from_machine_usize(inner_len, self);
|
let len = Scalar::from_machine_usize(inner_len, self);
|
||||||
(MemPlaceMeta::Meta(len), base.layout.ty)
|
(MemPlaceMeta::Meta(len), base.layout.ty)
|
||||||
}
|
}
|
||||||
_ => span_bug!(self.cur_span(), "cannot subslice non-array type: `{:?}`", base.layout.ty),
|
_ => {
|
||||||
|
span_bug!(self.cur_span(), "cannot subslice non-array type: `{:?}`", base.layout.ty)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
let layout = self.layout_of(ty)?;
|
let layout = self.layout_of(ty)?;
|
||||||
base.offset(from_offset, meta, layout, self)
|
base.offset(from_offset, meta, layout, self)
|
||||||
|
@ -776,9 +787,11 @@ where
|
||||||
Immediate::Scalar(scalar) => {
|
Immediate::Scalar(scalar) => {
|
||||||
match dest.layout.abi {
|
match dest.layout.abi {
|
||||||
Abi::Scalar(_) => {} // fine
|
Abi::Scalar(_) => {} // fine
|
||||||
_ => {
|
_ => span_bug!(
|
||||||
span_bug!(self.cur_span(), "write_immediate_to_mplace: invalid Scalar layout: {:#?}", dest.layout)
|
self.cur_span(),
|
||||||
}
|
"write_immediate_to_mplace: invalid Scalar layout: {:#?}",
|
||||||
|
dest.layout
|
||||||
|
),
|
||||||
}
|
}
|
||||||
self.memory.get_raw_mut(ptr.alloc_id)?.write_scalar(
|
self.memory.get_raw_mut(ptr.alloc_id)?.write_scalar(
|
||||||
&tcx,
|
&tcx,
|
||||||
|
|
|
@ -405,7 +405,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
||||||
Ok(op) => Some(op),
|
Ok(op) => Some(op),
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
let tcx = self.ecx.tcx.at(c.span);
|
let tcx = self.ecx.tcx.at(c.span);
|
||||||
let err = error_to_const_error(&self.ecx, error);
|
let err = error_to_const_error(&self.ecx, error, Some(c.span));
|
||||||
if let Some(lint_root) = self.lint_root(source_info) {
|
if let Some(lint_root) = self.lint_root(source_info) {
|
||||||
let lint_only = match c.literal.val {
|
let lint_only = match c.literal.val {
|
||||||
// Promoteds must lint and not error as the user didn't ask for them
|
// Promoteds must lint and not error as the user didn't ask for them
|
||||||
|
@ -417,12 +417,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
||||||
if lint_only {
|
if lint_only {
|
||||||
// Out of backwards compatibility we cannot report hard errors in unused
|
// Out of backwards compatibility we cannot report hard errors in unused
|
||||||
// generic functions using associated constants of the generic parameters.
|
// generic functions using associated constants of the generic parameters.
|
||||||
err.report_as_lint(
|
err.report_as_lint(tcx, "erroneous constant used", lint_root, Some(c.span));
|
||||||
tcx,
|
|
||||||
"erroneous constant used",
|
|
||||||
lint_root,
|
|
||||||
Some(c.span),
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
err.report_as_error(tcx, "erroneous constant used");
|
err.report_as_error(tcx, "erroneous constant used");
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,10 +23,10 @@ LL | n = if n % 2 == 0 { n/2 } else { 3*n + 1 };
|
||||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||||
|
|
||||||
error[E0080]: evaluation of constant value failed
|
error[E0080]: evaluation of constant value failed
|
||||||
--> $DIR/infinite_loop.rs:8:20
|
--> $DIR/infinite_loop.rs:8:17
|
||||||
|
|
|
|
||||||
LL | n = if n % 2 == 0 { n/2 } else { 3*n + 1 };
|
LL | n = if n % 2 == 0 { n/2 } else { 3*n + 1 };
|
||||||
| ^^^^^^^^^^ exceeded interpreter step limit (see `#[const_eval_limit]`)
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ exceeded interpreter step limit (see `#[const_eval_limit]`)
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
error: any use of this value will cause an error
|
error: any use of this value will cause an error
|
||||||
--> $DIR/const_eval_limit_reached.rs:8:11
|
--> $DIR/const_eval_limit_reached.rs:8:5
|
||||||
|
|
|
|
||||||
LL | / const X: usize = {
|
LL | / const X: usize = {
|
||||||
LL | | let mut x = 0;
|
LL | | let mut x = 0;
|
||||||
LL | | while x != 1000 {
|
LL | | while x != 1000 {
|
||||||
| | ^^^^^^^^^ exceeded interpreter step limit (see `#[const_eval_limit]`)
|
| |_____^
|
||||||
|
LL | ||
|
||||||
|
LL | || x += 1;
|
||||||
|
LL | || }
|
||||||
|
| ||_____^ exceeded interpreter step limit (see `#[const_eval_limit]`)
|
||||||
LL | |
|
LL | |
|
||||||
... |
|
|
||||||
LL | | x
|
LL | | x
|
||||||
LL | | };
|
LL | | };
|
||||||
| |__-
|
| |__-
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error[E0391]: cycle detected when const-evaluating `FOO`
|
error[E0391]: cycle detected when const-evaluating `FOO`
|
||||||
--> $DIR/recursive-zst-static.rs:10:18
|
--> $DIR/recursive-zst-static.rs:10:1
|
||||||
|
|
|
|
||||||
LL | static FOO: () = FOO;
|
LL | static FOO: () = FOO;
|
||||||
| ^^^
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: ...which requires const-evaluating `FOO`...
|
note: ...which requires const-evaluating `FOO`...
|
||||||
--> $DIR/recursive-zst-static.rs:10:1
|
--> $DIR/recursive-zst-static.rs:10:1
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error[E0391]: cycle detected when const-evaluating `FOO`
|
error[E0391]: cycle detected when const-evaluating `FOO`
|
||||||
--> $DIR/recursive-zst-static.rs:10:18
|
--> $DIR/recursive-zst-static.rs:10:1
|
||||||
|
|
|
|
||||||
LL | static FOO: () = FOO;
|
LL | static FOO: () = FOO;
|
||||||
| ^^^
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: ...which requires const-evaluating `FOO`...
|
note: ...which requires const-evaluating `FOO`...
|
||||||
--> $DIR/recursive-zst-static.rs:10:1
|
--> $DIR/recursive-zst-static.rs:10:1
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
// build-fail
|
// build-fail
|
||||||
|
|
||||||
pub const unsafe fn fake_type<T>() -> T {
|
pub const unsafe fn fake_type<T>() -> T {
|
||||||
hint_unreachable()
|
hint_unreachable() //~ ERROR evaluation of constant value failed
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const unsafe fn hint_unreachable() -> ! {
|
pub const unsafe fn hint_unreachable() -> ! {
|
||||||
fake_type() //~ ERROR evaluation of constant value failed
|
fake_type()
|
||||||
}
|
}
|
||||||
|
|
||||||
trait Const {
|
trait Const {
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
error[E0080]: evaluation of constant value failed
|
error[E0080]: evaluation of constant value failed
|
||||||
--> $DIR/uninhabited-const-issue-61744.rs:8:5
|
--> $DIR/uninhabited-const-issue-61744.rs:4:5
|
||||||
|
|
|
|
||||||
LL | hint_unreachable()
|
LL | hint_unreachable()
|
||||||
| ------------------
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
| |
|
| |
|
||||||
|
| reached the configured maximum number of stack frames
|
||||||
| inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
|
| inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
|
||||||
| inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
|
| inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
|
||||||
| inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
|
| inside `fake_type::<!>` at $DIR/uninhabited-const-issue-61744.rs:4:5
|
||||||
|
@ -71,9 +72,8 @@ LL | hint_unreachable()
|
||||||
| inside `fake_type::<i32>` at $DIR/uninhabited-const-issue-61744.rs:4:5
|
| inside `fake_type::<i32>` at $DIR/uninhabited-const-issue-61744.rs:4:5
|
||||||
...
|
...
|
||||||
LL | fake_type()
|
LL | fake_type()
|
||||||
| ^^^^^^^^^^^
|
| -----------
|
||||||
| |
|
| |
|
||||||
| reached the configured maximum number of stack frames
|
|
||||||
| inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
|
| inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
|
||||||
| inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
|
| inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
|
||||||
| inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
|
| inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:8:5
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error[E0391]: cycle detected when const-evaluating `FOO`
|
error[E0391]: cycle detected when const-evaluating `FOO`
|
||||||
--> $DIR/recursive-static-definition.rs:1:23
|
--> $DIR/recursive-static-definition.rs:1:1
|
||||||
|
|
|
|
||||||
LL | pub static FOO: u32 = FOO;
|
LL | pub static FOO: u32 = FOO;
|
||||||
| ^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: ...which requires const-evaluating `FOO`...
|
note: ...which requires const-evaluating `FOO`...
|
||||||
--> $DIR/recursive-static-definition.rs:1:1
|
--> $DIR/recursive-static-definition.rs:1:1
|
||||||
|
|
|
@ -5,10 +5,10 @@ LL | pub static mut B: () = unsafe { A = 1; };
|
||||||
| ^^^^^ modifying a static's initial value from another static's initializer
|
| ^^^^^ modifying a static's initial value from another static's initializer
|
||||||
|
|
||||||
error[E0391]: cycle detected when const-evaluating `C`
|
error[E0391]: cycle detected when const-evaluating `C`
|
||||||
--> $DIR/write-to-static-mut-in-static.rs:5:34
|
--> $DIR/write-to-static-mut-in-static.rs:5:1
|
||||||
|
|
|
|
||||||
LL | pub static mut C: u32 = unsafe { C = 1; 0 };
|
LL | pub static mut C: u32 = unsafe { C = 1; 0 };
|
||||||
| ^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: ...which requires const-evaluating `C`...
|
note: ...which requires const-evaluating `C`...
|
||||||
--> $DIR/write-to-static-mut-in-static.rs:5:1
|
--> $DIR/write-to-static-mut-in-static.rs:5:1
|
||||||
|
|
Loading…
Reference in New Issue