const validation: point at where we found a pointer but expected an integer
This commit is contained in:
parent
7637653b9f
commit
7767cbb3b0
34 changed files with 544 additions and 408 deletions
|
@ -15,9 +15,6 @@ const_eval_await_non_const =
|
|||
cannot convert `{$ty}` into a future in {const_eval_const_context}s
|
||||
const_eval_bounds_check_failed =
|
||||
indexing out of bounds: the len is {$len} but the index is {$index}
|
||||
const_eval_box_to_mut = {$front_matter}: encountered a box pointing to mutable memory in a constant
|
||||
const_eval_box_to_static = {$front_matter}: encountered a box pointing to a static variable in a constant
|
||||
const_eval_box_to_uninhabited = {$front_matter}: encountered a box pointing to uninhabited type {$ty}
|
||||
const_eval_call_nonzero_intrinsic =
|
||||
`{$name}` called on 0
|
||||
|
||||
|
@ -41,18 +38,12 @@ const_eval_const_context = {$kind ->
|
|||
const_eval_copy_nonoverlapping_overlapping =
|
||||
`copy_nonoverlapping` called on overlapping ranges
|
||||
|
||||
const_eval_dangling_box_no_provenance = {$front_matter}: encountered a dangling box ({$pointer} has no provenance)
|
||||
const_eval_dangling_box_out_of_bounds = {$front_matter}: encountered a dangling box (going beyond the bounds of its allocation)
|
||||
const_eval_dangling_box_use_after_free = {$front_matter}: encountered a dangling box (use-after-free)
|
||||
const_eval_dangling_int_pointer =
|
||||
{$bad_pointer_message}: {$pointer} is a dangling pointer (it has no provenance)
|
||||
const_eval_dangling_null_pointer =
|
||||
{$bad_pointer_message}: null pointer is a dangling pointer (it has no provenance)
|
||||
const_eval_dangling_ptr_in_final = encountered dangling pointer in final constant
|
||||
|
||||
const_eval_dangling_ref_no_provenance = {$front_matter}: encountered a dangling reference ({$pointer} has no provenance)
|
||||
const_eval_dangling_ref_out_of_bounds = {$front_matter}: encountered a dangling reference (going beyond the bounds of its allocation)
|
||||
const_eval_dangling_ref_use_after_free = {$front_matter}: encountered a dangling reference (use-after-free)
|
||||
const_eval_dead_local =
|
||||
accessing a dead local variable
|
||||
const_eval_dealloc_immutable =
|
||||
|
@ -105,7 +96,6 @@ const_eval_error = {$error_kind ->
|
|||
const_eval_exact_div_has_remainder =
|
||||
exact_div: {$a} cannot be divided by {$b} without remainder
|
||||
|
||||
const_eval_expected_non_ptr = {$front_matter}: encountered `{$value}`, but expected plain (non-pointer) bytes
|
||||
const_eval_fn_ptr_call =
|
||||
function pointers need an RFC before allowed to be called in {const_eval_const_context}s
|
||||
const_eval_for_loop_into_iter_non_const =
|
||||
|
@ -156,8 +146,6 @@ const_eval_invalid_align_details =
|
|||
|
||||
const_eval_invalid_bool =
|
||||
interpreting an invalid 8-bit value as a bool: 0x{$value}
|
||||
const_eval_invalid_box_meta = {$front_matter}: encountered invalid box metadata: total size is bigger than largest supported object
|
||||
const_eval_invalid_box_slice_meta = {$front_matter}: encountered invalid box metadata: slice is bigger than largest supported object
|
||||
const_eval_invalid_char =
|
||||
interpreting an invalid 32-bit value as a char: 0x{$value}
|
||||
const_eval_invalid_dealloc =
|
||||
|
@ -168,16 +156,12 @@ const_eval_invalid_dealloc =
|
|||
*[other] {""}
|
||||
}
|
||||
|
||||
const_eval_invalid_enum_tag = {$front_matter}: encountered {$value}, but expected a valid enum tag
|
||||
const_eval_invalid_fn_ptr = {$front_matter}: encountered {$value}, but expected a function pointer
|
||||
const_eval_invalid_function_pointer =
|
||||
using {$pointer} as function pointer but it does not point to a function
|
||||
const_eval_invalid_meta =
|
||||
invalid metadata in wide pointer: total size is bigger than largest supported object
|
||||
const_eval_invalid_meta_slice =
|
||||
invalid metadata in wide pointer: slice is bigger than largest supported object
|
||||
const_eval_invalid_ref_meta = {$front_matter}: encountered invalid reference metadata: total size is bigger than largest supported object
|
||||
const_eval_invalid_ref_slice_meta = {$front_matter}: encountered invalid reference metadata: slice is bigger than largest supported object
|
||||
const_eval_invalid_str =
|
||||
this string is not valid UTF-8: {$err}
|
||||
const_eval_invalid_tag =
|
||||
|
@ -189,14 +173,10 @@ const_eval_invalid_uninit_bytes =
|
|||
reading memory at {$alloc}{$access}, but memory is uninitialized at {$uninit}, and this operation requires initialized memory
|
||||
const_eval_invalid_uninit_bytes_unknown =
|
||||
using uninitialized data, but this operation requires initialized memory
|
||||
const_eval_invalid_value = constructing invalid value
|
||||
const_eval_invalid_value_with_path = constructing invalid value at {$path}
|
||||
## The `front_matter`s here refer to either `middle_invalid_value` or `middle_invalid_value_with_path`.
|
||||
|
||||
const_eval_invalid_vtable_pointer =
|
||||
using {$pointer} as vtable pointer but it does not point to a vtable
|
||||
|
||||
const_eval_invalid_vtable_ptr = {$front_matter}: encountered {$value}, but expected a vtable pointer
|
||||
|
||||
const_eval_live_drop =
|
||||
destructor of `{$dropped_ty}` cannot be evaluated at compile-time
|
||||
|
@ -218,14 +198,13 @@ const_eval_max_num_nodes_in_const = maximum number of nodes exceeded in constant
|
|||
const_eval_memory_access_test = memory access failed
|
||||
const_eval_memory_exhausted =
|
||||
tried to allocate more memory than available to compiler
|
||||
|
||||
const_eval_modified_global =
|
||||
modifying a static's initial value from another static's initializer
|
||||
|
||||
const_eval_mut_deref =
|
||||
mutation through a reference is not allowed in {const_eval_const_context}s
|
||||
|
||||
const_eval_mutable_ref_in_const = {$front_matter}: encountered mutable reference in a `const`
|
||||
const_eval_never_val = {$front_matter}: encountered a value of the never type `!`
|
||||
const_eval_non_const_fmt_macro_call =
|
||||
cannot call non-const formatting macro in {const_eval_const_context}s
|
||||
|
||||
|
@ -241,10 +220,6 @@ const_eval_noreturn_asm_returned =
|
|||
const_eval_not_enough_caller_args =
|
||||
calling a function with fewer arguments than it requires
|
||||
|
||||
const_eval_null_box = {$front_matter}: encountered a null box
|
||||
const_eval_null_fn_ptr = {$front_matter}: encountered a null function pointer
|
||||
const_eval_null_ref = {$front_matter}: encountered a null reference
|
||||
const_eval_nullable_ptr_out_of_range = {$front_matter}: encountered a potentially null pointer, but expected something that cannot possibly fail to be {$in_range}
|
||||
const_eval_nullary_intrinsic_fail =
|
||||
could not evaluate nullary intrinsic
|
||||
|
||||
|
@ -257,7 +232,6 @@ const_eval_offset_from_underflow =
|
|||
|
||||
const_eval_operator_non_const =
|
||||
cannot call non-const operator in {const_eval_const_context}s
|
||||
const_eval_out_of_range = {$front_matter}: encountered {$value}, but expected something {$in_range}
|
||||
const_eval_overflow =
|
||||
overflow executing `{$name}`
|
||||
|
||||
|
@ -287,7 +261,6 @@ const_eval_ptr_as_bytes_1 =
|
|||
this code performed an operation that depends on the underlying bytes representing a pointer
|
||||
const_eval_ptr_as_bytes_2 =
|
||||
the absolute address of a pointer is not known at compile-time, so such operations are not supported
|
||||
const_eval_ptr_out_of_range = {$front_matter}: encountered a pointer, but expected something that cannot possibly fail to be {$in_range}
|
||||
const_eval_question_branch_non_const =
|
||||
`?` cannot determine the branch of `{$ty}` in {const_eval_const_context}s
|
||||
|
||||
|
@ -315,8 +288,8 @@ const_eval_raw_ptr_to_int =
|
|||
|
||||
const_eval_read_extern_static =
|
||||
cannot read from extern static ({$did})
|
||||
const_eval_read_pointer_as_bytes =
|
||||
unable to turn pointer into raw bytes
|
||||
const_eval_read_pointer_as_int =
|
||||
unable to turn pointer into integer
|
||||
const_eval_realloc_or_alloc_with_offset =
|
||||
{$kind ->
|
||||
[dealloc] deallocating
|
||||
|
@ -324,9 +297,6 @@ const_eval_realloc_or_alloc_with_offset =
|
|||
*[other] {""}
|
||||
} {$ptr} which does not point to the beginning of an object
|
||||
|
||||
const_eval_ref_to_mut = {$front_matter}: encountered a reference pointing to mutable memory in a constant
|
||||
const_eval_ref_to_static = {$front_matter}: encountered a reference pointing to a static variable in a constant
|
||||
const_eval_ref_to_uninhabited = {$front_matter}: encountered a reference pointing to uninhabited type {$ty}
|
||||
const_eval_remainder_by_zero =
|
||||
calculating the remainder with a divisor of zero
|
||||
const_eval_remainder_overflow =
|
||||
|
@ -363,8 +333,6 @@ const_eval_transient_mut_borrow_raw = raw mutable references are not allowed in
|
|||
|
||||
const_eval_try_block_from_output_non_const =
|
||||
`try` block cannot convert `{$ty}` to the result in {const_eval_const_context}s
|
||||
const_eval_unaligned_box = {$front_matter}: encountered an unaligned box (required {$required_bytes} byte alignment but found {$found_bytes})
|
||||
const_eval_unaligned_ref = {$front_matter}: encountered an unaligned reference (required {$required_bytes} byte alignment but found {$found_bytes})
|
||||
const_eval_unallowed_fn_pointer_call = function pointer calls are not allowed in {const_eval_const_context}s
|
||||
|
||||
const_eval_unallowed_heap_allocations =
|
||||
|
@ -408,29 +376,14 @@ const_eval_undefined_behavior =
|
|||
const_eval_undefined_behavior_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.
|
||||
|
||||
const_eval_uninhabited_enum_tag = {$front_matter}: encountered an uninhabited enum variant
|
||||
const_eval_uninhabited_enum_variant_read =
|
||||
read discriminant of an uninhabited enum variant
|
||||
const_eval_uninhabited_enum_variant_written =
|
||||
writing discriminant of an uninhabited enum variant
|
||||
const_eval_uninhabited_val = {$front_matter}: encountered a value of uninhabited type `{$ty}`
|
||||
const_eval_uninit = {$front_matter}: encountered uninitialized bytes
|
||||
const_eval_uninit_bool = {$front_matter}: encountered uninitialized memory, but expected a boolean
|
||||
const_eval_uninit_box = {$front_matter}: encountered uninitialized memory, but expected a box
|
||||
const_eval_uninit_char = {$front_matter}: encountered uninitialized memory, but expected a unicode scalar value
|
||||
const_eval_uninit_enum_tag = {$front_matter}: encountered uninitialized bytes, but expected a valid enum tag
|
||||
const_eval_uninit_float = {$front_matter}: encountered uninitialized memory, but expected a floating point number
|
||||
const_eval_uninit_fn_ptr = {$front_matter}: encountered uninitialized memory, but expected a function pointer
|
||||
const_eval_uninit_init_scalar = {$front_matter}: encountered uninitialized memory, but expected initialized scalar value
|
||||
const_eval_uninit_int = {$front_matter}: encountered uninitialized memory, but expected an integer
|
||||
const_eval_uninit_raw_ptr = {$front_matter}: encountered uninitialized memory, but expected a raw pointer
|
||||
const_eval_uninit_ref = {$front_matter}: encountered uninitialized memory, but expected a reference
|
||||
const_eval_uninit_str = {$front_matter}: encountered uninitialized data in `str`
|
||||
const_eval_unreachable = entering unreachable code
|
||||
const_eval_unreachable_unwind =
|
||||
unwinding past a stack frame that does not allow unwinding
|
||||
|
||||
const_eval_unsafe_cell = {$front_matter}: encountered `UnsafeCell` in a `const`
|
||||
const_eval_unsigned_offset_from_overflow =
|
||||
`ptr_offset_from_unsigned` called when first pointer has smaller offset than second: {$a_offset} < {$b_offset}
|
||||
|
||||
|
@ -453,8 +406,63 @@ const_eval_unwind_past_top =
|
|||
const_eval_upcast_mismatch =
|
||||
upcast on a pointer whose vtable does not match its type
|
||||
|
||||
## The `front_matter`s here refer to either `const_eval_front_matter_invalid_value` or `const_eval_front_matter_invalid_value_with_path`.
|
||||
## (We'd love to sort this differently to make that more clear but tidy won't let us...)
|
||||
const_eval_validation_box_to_mut = {$front_matter}: encountered a box pointing to mutable memory in a constant
|
||||
const_eval_validation_box_to_static = {$front_matter}: encountered a box pointing to a static variable in a constant
|
||||
const_eval_validation_box_to_uninhabited = {$front_matter}: encountered a box pointing to uninhabited type {$ty}
|
||||
const_eval_validation_dangling_box_no_provenance = {$front_matter}: encountered a dangling box ({$pointer} has no provenance)
|
||||
const_eval_validation_dangling_box_out_of_bounds = {$front_matter}: encountered a dangling box (going beyond the bounds of its allocation)
|
||||
const_eval_validation_dangling_box_use_after_free = {$front_matter}: encountered a dangling box (use-after-free)
|
||||
const_eval_validation_dangling_ref_no_provenance = {$front_matter}: encountered a dangling reference ({$pointer} has no provenance)
|
||||
const_eval_validation_dangling_ref_out_of_bounds = {$front_matter}: encountered a dangling reference (going beyond the bounds of its allocation)
|
||||
const_eval_validation_dangling_ref_use_after_free = {$front_matter}: encountered a dangling reference (use-after-free)
|
||||
|
||||
const_eval_validation_expected_bool = expected a boolean
|
||||
const_eval_validation_expected_box = expected a box
|
||||
const_eval_validation_expected_char = expected a unicode scalar value
|
||||
const_eval_validation_expected_enum_tag = expected a valid enum tag
|
||||
const_eval_validation_expected_float = expected a floating point number
|
||||
const_eval_validation_expected_fn_ptr = expected a function pointer
|
||||
const_eval_validation_expected_init_scalar = expected initialized scalar value
|
||||
const_eval_validation_expected_int = expected an integer
|
||||
const_eval_validation_expected_raw_ptr = expected a raw pointer
|
||||
const_eval_validation_expected_ref = expected a reference
|
||||
const_eval_validation_expected_str = expected a string
|
||||
|
||||
const_eval_validation_front_matter_invalid_value = constructing invalid value
|
||||
const_eval_validation_front_matter_invalid_value_with_path = constructing invalid value at {$path}
|
||||
|
||||
const_eval_validation_invalid_bool = {$front_matter}: encountered {$value}, but expected a boolean
|
||||
const_eval_validation_invalid_box_meta = {$front_matter}: encountered invalid box metadata: total size is bigger than largest supported object
|
||||
const_eval_validation_invalid_box_slice_meta = {$front_matter}: encountered invalid box metadata: slice is bigger than largest supported object
|
||||
const_eval_validation_invalid_char = {$front_matter}: encountered {$value}, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`)
|
||||
|
||||
const_eval_validation_invalid_enum_tag = {$front_matter}: encountered {$value}, but expected a valid enum tag
|
||||
const_eval_validation_invalid_fn_ptr = {$front_matter}: encountered {$value}, but expected a function pointer
|
||||
const_eval_validation_invalid_ref_meta = {$front_matter}: encountered invalid reference metadata: total size is bigger than largest supported object
|
||||
const_eval_validation_invalid_ref_slice_meta = {$front_matter}: encountered invalid reference metadata: slice is bigger than largest supported object
|
||||
const_eval_validation_invalid_vtable_ptr = {$front_matter}: encountered {$value}, but expected a vtable pointer
|
||||
const_eval_validation_mutable_ref_in_const = {$front_matter}: encountered mutable reference in a `const`
|
||||
const_eval_validation_never_val = {$front_matter}: encountered a value of the never type `!`
|
||||
const_eval_validation_null_box = {$front_matter}: encountered a null box
|
||||
const_eval_validation_null_fn_ptr = {$front_matter}: encountered a null function pointer
|
||||
const_eval_validation_null_ref = {$front_matter}: encountered a null reference
|
||||
const_eval_validation_nullable_ptr_out_of_range = {$front_matter}: encountered a potentially null pointer, but expected something that cannot possibly fail to be {$in_range}
|
||||
const_eval_validation_out_of_range = {$front_matter}: encountered {$value}, but expected something {$in_range}
|
||||
const_eval_validation_partial_pointer = {$front_matter}: encountered a partial pointer or a mix of pointers
|
||||
const_eval_validation_pointer_as_int = {$front_matter}: encountered a pointer, but {$expected}
|
||||
const_eval_validation_ptr_out_of_range = {$front_matter}: encountered a pointer, but expected something that cannot possibly fail to be {$in_range}
|
||||
const_eval_validation_ref_to_mut = {$front_matter}: encountered a reference pointing to mutable memory in a constant
|
||||
const_eval_validation_ref_to_static = {$front_matter}: encountered a reference pointing to a static variable in a constant
|
||||
const_eval_validation_ref_to_uninhabited = {$front_matter}: encountered a reference pointing to uninhabited type {$ty}
|
||||
const_eval_validation_unaligned_box = {$front_matter}: encountered an unaligned box (required {$required_bytes} byte alignment but found {$found_bytes})
|
||||
const_eval_validation_unaligned_ref = {$front_matter}: encountered an unaligned reference (required {$required_bytes} byte alignment but found {$found_bytes})
|
||||
const_eval_validation_uninhabited_enum_variant = {$front_matter}: encountered an uninhabited enum variant
|
||||
const_eval_validation_uninhabited_val = {$front_matter}: encountered a value of uninhabited type `{$ty}`
|
||||
const_eval_validation_uninit = {$front_matter}: encountered uninitialized memory, but {$expected}
|
||||
const_eval_validation_unsafe_cell = {$front_matter}: encountered `UnsafeCell` in a `const`
|
||||
|
||||
const_eval_write_to_read_only =
|
||||
writing to {$allocation} which is read-only
|
||||
const_eval_zst_pointer_out_of_bounds =
|
||||
|
|
|
@ -513,7 +513,7 @@ impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> {
|
|||
ScalarSizeMismatch(_) => const_eval_scalar_size_mismatch,
|
||||
UninhabitedEnumVariantWritten(_) => const_eval_uninhabited_enum_variant_written,
|
||||
UninhabitedEnumVariantRead(_) => const_eval_uninhabited_enum_variant_read,
|
||||
Validation(e) => e.diagnostic_message(),
|
||||
ValidationError(e) => e.diagnostic_message(),
|
||||
Custom(x) => (x.msg)(),
|
||||
}
|
||||
}
|
||||
|
@ -587,13 +587,13 @@ impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> {
|
|||
InvalidUninitBytes(Some((alloc, info))) => {
|
||||
builder.set_arg("alloc", alloc);
|
||||
builder.set_arg("access", info.access);
|
||||
builder.set_arg("uninit", info.uninit);
|
||||
builder.set_arg("uninit", info.bad);
|
||||
}
|
||||
ScalarSizeMismatch(info) => {
|
||||
builder.set_arg("target_size", info.target_size);
|
||||
builder.set_arg("data_size", info.data_size);
|
||||
}
|
||||
Validation(e) => e.add_args(handler, builder),
|
||||
ValidationError(e) => e.add_args(handler, builder),
|
||||
Custom(custom) => {
|
||||
(custom.add_args)(&mut |name, value| {
|
||||
builder.set_arg(name, value);
|
||||
|
@ -608,74 +608,72 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> {
|
|||
use crate::fluent_generated::*;
|
||||
use rustc_middle::mir::interpret::ValidationErrorKind::*;
|
||||
match self.kind {
|
||||
PtrToUninhabited { ptr_kind: PointerKind::Box, .. } => const_eval_box_to_uninhabited,
|
||||
PtrToUninhabited { ptr_kind: PointerKind::Ref, .. } => const_eval_ref_to_uninhabited,
|
||||
PtrToUninhabited { ptr_kind: PointerKind::Box, .. } => {
|
||||
const_eval_validation_box_to_uninhabited
|
||||
}
|
||||
PtrToUninhabited { ptr_kind: PointerKind::Ref, .. } => {
|
||||
const_eval_validation_ref_to_uninhabited
|
||||
}
|
||||
|
||||
PtrToStatic { ptr_kind: PointerKind::Box } => const_eval_box_to_static,
|
||||
PtrToStatic { ptr_kind: PointerKind::Ref } => const_eval_ref_to_static,
|
||||
PtrToStatic { ptr_kind: PointerKind::Box } => const_eval_validation_box_to_static,
|
||||
PtrToStatic { ptr_kind: PointerKind::Ref } => const_eval_validation_ref_to_static,
|
||||
|
||||
PtrToMut { ptr_kind: PointerKind::Box } => const_eval_box_to_mut,
|
||||
PtrToMut { ptr_kind: PointerKind::Ref } => const_eval_ref_to_mut,
|
||||
PtrToMut { ptr_kind: PointerKind::Box } => const_eval_validation_box_to_mut,
|
||||
PtrToMut { ptr_kind: PointerKind::Ref } => const_eval_validation_ref_to_mut,
|
||||
|
||||
ExpectedNonPtr { .. } => const_eval_expected_non_ptr,
|
||||
MutableRefInConst => const_eval_mutable_ref_in_const,
|
||||
NullFnPtr => const_eval_null_fn_ptr,
|
||||
NeverVal => const_eval_never_val,
|
||||
NullablePtrOutOfRange { .. } => const_eval_nullable_ptr_out_of_range,
|
||||
PtrOutOfRange { .. } => const_eval_ptr_out_of_range,
|
||||
OutOfRange { .. } => const_eval_out_of_range,
|
||||
UnsafeCell => const_eval_unsafe_cell,
|
||||
UninhabitedVal { .. } => const_eval_uninhabited_val,
|
||||
InvalidEnumTag { .. } => const_eval_invalid_enum_tag,
|
||||
UninhabitedEnumTag => const_eval_uninhabited_enum_tag,
|
||||
UninitEnumTag => const_eval_uninit_enum_tag,
|
||||
UninitStr => const_eval_uninit_str,
|
||||
Uninit { expected: ExpectedKind::Bool } => const_eval_uninit_bool,
|
||||
Uninit { expected: ExpectedKind::Reference } => const_eval_uninit_ref,
|
||||
Uninit { expected: ExpectedKind::Box } => const_eval_uninit_box,
|
||||
Uninit { expected: ExpectedKind::RawPtr } => const_eval_uninit_raw_ptr,
|
||||
Uninit { expected: ExpectedKind::InitScalar } => const_eval_uninit_init_scalar,
|
||||
Uninit { expected: ExpectedKind::Char } => const_eval_uninit_char,
|
||||
Uninit { expected: ExpectedKind::Float } => const_eval_uninit_float,
|
||||
Uninit { expected: ExpectedKind::Int } => const_eval_uninit_int,
|
||||
Uninit { expected: ExpectedKind::FnPtr } => const_eval_uninit_fn_ptr,
|
||||
UninitVal => const_eval_uninit,
|
||||
InvalidVTablePtr { .. } => const_eval_invalid_vtable_ptr,
|
||||
PointerAsInt { .. } => const_eval_validation_pointer_as_int,
|
||||
PartialPointer => const_eval_validation_partial_pointer,
|
||||
MutableRefInConst => const_eval_validation_mutable_ref_in_const,
|
||||
NullFnPtr => const_eval_validation_null_fn_ptr,
|
||||
NeverVal => const_eval_validation_never_val,
|
||||
NullablePtrOutOfRange { .. } => const_eval_validation_nullable_ptr_out_of_range,
|
||||
PtrOutOfRange { .. } => const_eval_validation_ptr_out_of_range,
|
||||
OutOfRange { .. } => const_eval_validation_out_of_range,
|
||||
UnsafeCell => const_eval_validation_unsafe_cell,
|
||||
UninhabitedVal { .. } => const_eval_validation_uninhabited_val,
|
||||
InvalidEnumTag { .. } => const_eval_validation_invalid_enum_tag,
|
||||
UninhabitedEnumVariant => const_eval_validation_uninhabited_enum_variant,
|
||||
Uninit { .. } => const_eval_validation_uninit,
|
||||
InvalidVTablePtr { .. } => const_eval_validation_invalid_vtable_ptr,
|
||||
InvalidMetaSliceTooLarge { ptr_kind: PointerKind::Box } => {
|
||||
const_eval_invalid_box_slice_meta
|
||||
const_eval_validation_invalid_box_slice_meta
|
||||
}
|
||||
InvalidMetaSliceTooLarge { ptr_kind: PointerKind::Ref } => {
|
||||
const_eval_invalid_ref_slice_meta
|
||||
const_eval_validation_invalid_ref_slice_meta
|
||||
}
|
||||
|
||||
InvalidMetaTooLarge { ptr_kind: PointerKind::Box } => const_eval_invalid_box_meta,
|
||||
InvalidMetaTooLarge { ptr_kind: PointerKind::Ref } => const_eval_invalid_ref_meta,
|
||||
UnalignedPtr { ptr_kind: PointerKind::Ref, .. } => const_eval_unaligned_ref,
|
||||
UnalignedPtr { ptr_kind: PointerKind::Box, .. } => const_eval_unaligned_box,
|
||||
InvalidMetaTooLarge { ptr_kind: PointerKind::Box } => {
|
||||
const_eval_validation_invalid_box_meta
|
||||
}
|
||||
InvalidMetaTooLarge { ptr_kind: PointerKind::Ref } => {
|
||||
const_eval_validation_invalid_ref_meta
|
||||
}
|
||||
UnalignedPtr { ptr_kind: PointerKind::Ref, .. } => const_eval_validation_unaligned_ref,
|
||||
UnalignedPtr { ptr_kind: PointerKind::Box, .. } => const_eval_validation_unaligned_box,
|
||||
|
||||
NullPtr { ptr_kind: PointerKind::Box } => const_eval_null_box,
|
||||
NullPtr { ptr_kind: PointerKind::Ref } => const_eval_null_ref,
|
||||
NullPtr { ptr_kind: PointerKind::Box } => const_eval_validation_null_box,
|
||||
NullPtr { ptr_kind: PointerKind::Ref } => const_eval_validation_null_ref,
|
||||
DanglingPtrNoProvenance { ptr_kind: PointerKind::Box, .. } => {
|
||||
const_eval_dangling_box_no_provenance
|
||||
const_eval_validation_dangling_box_no_provenance
|
||||
}
|
||||
DanglingPtrNoProvenance { ptr_kind: PointerKind::Ref, .. } => {
|
||||
const_eval_dangling_ref_no_provenance
|
||||
const_eval_validation_dangling_ref_no_provenance
|
||||
}
|
||||
DanglingPtrOutOfBounds { ptr_kind: PointerKind::Box } => {
|
||||
const_eval_dangling_box_out_of_bounds
|
||||
const_eval_validation_dangling_box_out_of_bounds
|
||||
}
|
||||
DanglingPtrOutOfBounds { ptr_kind: PointerKind::Ref } => {
|
||||
const_eval_dangling_ref_out_of_bounds
|
||||
const_eval_validation_dangling_ref_out_of_bounds
|
||||
}
|
||||
DanglingPtrUseAfterFree { ptr_kind: PointerKind::Box } => {
|
||||
const_eval_dangling_box_use_after_free
|
||||
const_eval_validation_dangling_box_use_after_free
|
||||
}
|
||||
DanglingPtrUseAfterFree { ptr_kind: PointerKind::Ref } => {
|
||||
const_eval_dangling_ref_use_after_free
|
||||
const_eval_validation_dangling_ref_use_after_free
|
||||
}
|
||||
InvalidBool { .. } => const_eval_validation_invalid_bool,
|
||||
InvalidChar { .. } => const_eval_validation_invalid_char,
|
||||
InvalidFnPtr { .. } => const_eval_invalid_fn_ptr,
|
||||
InvalidFnPtr { .. } => const_eval_validation_invalid_fn_ptr,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -683,13 +681,21 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> {
|
|||
use crate::fluent_generated as fluent;
|
||||
use rustc_middle::mir::interpret::ValidationErrorKind::*;
|
||||
|
||||
if let PointerAsInt { .. } | PartialPointer = self.kind {
|
||||
err.help(fluent::const_eval_ptr_as_bytes_1);
|
||||
err.help(fluent::const_eval_ptr_as_bytes_2);
|
||||
}
|
||||
|
||||
let message = if let Some(path) = self.path {
|
||||
handler.eagerly_translate_to_string(
|
||||
fluent::const_eval_invalid_value_with_path,
|
||||
fluent::const_eval_validation_front_matter_invalid_value_with_path,
|
||||
[("path".into(), DiagnosticArgValue::Str(path.into()))].iter().map(|(a, b)| (a, b)),
|
||||
)
|
||||
} else {
|
||||
handler.eagerly_translate_to_string(fluent::const_eval_invalid_value, [].into_iter())
|
||||
handler.eagerly_translate_to_string(
|
||||
fluent::const_eval_validation_front_matter_invalid_value,
|
||||
[].into_iter(),
|
||||
)
|
||||
};
|
||||
|
||||
err.set_arg("front_matter", message);
|
||||
|
@ -729,8 +735,24 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> {
|
|||
PtrToUninhabited { ty, .. } | UninhabitedVal { ty } => {
|
||||
err.set_arg("ty", ty);
|
||||
}
|
||||
ExpectedNonPtr { value }
|
||||
| InvalidEnumTag { value }
|
||||
PointerAsInt { expected } | Uninit { expected } => {
|
||||
let msg = match expected {
|
||||
ExpectedKind::Reference => fluent::const_eval_validation_expected_ref,
|
||||
ExpectedKind::Box => fluent::const_eval_validation_expected_box,
|
||||
ExpectedKind::RawPtr => fluent::const_eval_validation_expected_raw_ptr,
|
||||
ExpectedKind::InitScalar => fluent::const_eval_validation_expected_init_scalar,
|
||||
ExpectedKind::Bool => fluent::const_eval_validation_expected_bool,
|
||||
ExpectedKind::Char => fluent::const_eval_validation_expected_char,
|
||||
ExpectedKind::Float => fluent::const_eval_validation_expected_float,
|
||||
ExpectedKind::Int => fluent::const_eval_validation_expected_int,
|
||||
ExpectedKind::FnPtr => fluent::const_eval_validation_expected_fn_ptr,
|
||||
ExpectedKind::EnumTag => fluent::const_eval_validation_expected_enum_tag,
|
||||
ExpectedKind::Str => fluent::const_eval_validation_expected_str,
|
||||
};
|
||||
let msg = handler.eagerly_translate_to_string(msg, [].into_iter());
|
||||
err.set_arg("expected", msg);
|
||||
}
|
||||
InvalidEnumTag { value }
|
||||
| InvalidVTablePtr { value }
|
||||
| InvalidBool { value }
|
||||
| InvalidChar { value }
|
||||
|
@ -758,15 +780,12 @@ impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> {
|
|||
| NullFnPtr
|
||||
| NeverVal
|
||||
| UnsafeCell
|
||||
| UninitEnumTag
|
||||
| UninitStr
|
||||
| Uninit { .. }
|
||||
| UninitVal
|
||||
| InvalidMetaSliceTooLarge { .. }
|
||||
| InvalidMetaTooLarge { .. }
|
||||
| DanglingPtrUseAfterFree { .. }
|
||||
| DanglingPtrOutOfBounds { .. }
|
||||
| UninhabitedEnumTag => {}
|
||||
| UninhabitedEnumVariant
|
||||
| PartialPointer => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -776,9 +795,9 @@ impl ReportErrorExt for UnsupportedOpInfo {
|
|||
use crate::fluent_generated::*;
|
||||
match self {
|
||||
UnsupportedOpInfo::Unsupported(s) => s.clone().into(),
|
||||
UnsupportedOpInfo::PartialPointerOverwrite(_) => const_eval_partial_pointer_overwrite,
|
||||
UnsupportedOpInfo::PartialPointerCopy(_) => const_eval_partial_pointer_copy,
|
||||
UnsupportedOpInfo::ReadPointerAsBytes => const_eval_read_pointer_as_bytes,
|
||||
UnsupportedOpInfo::OverwritePartialPointer(_) => const_eval_partial_pointer_overwrite,
|
||||
UnsupportedOpInfo::ReadPartialPointer(_) => const_eval_partial_pointer_copy,
|
||||
UnsupportedOpInfo::ReadPointerAsInt(_) => const_eval_read_pointer_as_int,
|
||||
UnsupportedOpInfo::ThreadLocalStatic(_) => const_eval_thread_local_static,
|
||||
UnsupportedOpInfo::ReadExternStatic(_) => const_eval_read_extern_static,
|
||||
}
|
||||
|
@ -787,13 +806,16 @@ impl ReportErrorExt for UnsupportedOpInfo {
|
|||
use crate::fluent_generated::*;
|
||||
|
||||
use UnsupportedOpInfo::*;
|
||||
if let ReadPointerAsBytes | PartialPointerOverwrite(_) | PartialPointerCopy(_) = self {
|
||||
if let ReadPointerAsInt(_) | OverwritePartialPointer(_) | ReadPartialPointer(_) = self {
|
||||
builder.help(const_eval_ptr_as_bytes_1);
|
||||
builder.help(const_eval_ptr_as_bytes_2);
|
||||
}
|
||||
match self {
|
||||
Unsupported(_) | ReadPointerAsBytes => {}
|
||||
PartialPointerOverwrite(ptr) | PartialPointerCopy(ptr) => {
|
||||
// `ReadPointerAsInt(Some(info))` is never printed anyway, it only serves as an error to
|
||||
// be further processed by validity checking which then turns it into something nice to
|
||||
// print. So it's not worth the effort of having diagnostics that can print the `info`.
|
||||
Unsupported(_) | ReadPointerAsInt(_) => {}
|
||||
OverwritePartialPointer(ptr) | ReadPartialPointer(ptr) => {
|
||||
builder.set_arg("ptr", ptr);
|
||||
}
|
||||
ThreadLocalStatic(did) | ReadExternStatic(did) => {
|
||||
|
|
|
@ -25,13 +25,17 @@ use rustc_target::abi::{
|
|||
|
||||
use std::hash::Hash;
|
||||
|
||||
// for the validation errors
|
||||
use super::UndefinedBehaviorInfo::*;
|
||||
use super::{
|
||||
AllocId, CheckInAllocMsg, GlobalAlloc, ImmTy, Immediate, InterpCx, InterpResult, MPlaceTy,
|
||||
Machine, MemPlaceMeta, OpTy, Pointer, Projectable, Scalar, ValueVisitor,
|
||||
};
|
||||
|
||||
// for the validation errors
|
||||
use super::InterpError::UndefinedBehavior as Ub;
|
||||
use super::InterpError::Unsupported as Unsup;
|
||||
use super::UndefinedBehaviorInfo::*;
|
||||
use super::UnsupportedOpInfo::*;
|
||||
|
||||
macro_rules! throw_validation_failure {
|
||||
($where:expr, $kind: expr) => {{
|
||||
let where_ = &$where;
|
||||
|
@ -43,7 +47,7 @@ macro_rules! throw_validation_failure {
|
|||
None
|
||||
};
|
||||
|
||||
throw_ub!(Validation(ValidationErrorInfo { path, kind: $kind }))
|
||||
throw_ub!(ValidationError(ValidationErrorInfo { path, kind: $kind }))
|
||||
}};
|
||||
}
|
||||
|
||||
|
@ -85,16 +89,16 @@ macro_rules! try_validation {
|
|||
Ok(x) => x,
|
||||
// We catch the error and turn it into a validation failure. We are okay with
|
||||
// allocation here as this can only slow down builds that fail anyway.
|
||||
Err(e) => match e.into_parts() {
|
||||
Err(e) => match e.kind() {
|
||||
$(
|
||||
(InterpError::UndefinedBehavior($($p)|+), _) =>
|
||||
$($p)|+ =>
|
||||
throw_validation_failure!(
|
||||
$where,
|
||||
$kind
|
||||
)
|
||||
),+,
|
||||
#[allow(unreachable_patterns)]
|
||||
(e, rest) => Err::<!, _>($crate::interpret::InterpErrorInfo::from_parts(e, rest))?,
|
||||
_ => Err::<!, _>(e)?,
|
||||
}
|
||||
}
|
||||
}};
|
||||
|
@ -294,7 +298,13 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
|
|||
Ok(try_validation!(
|
||||
self.ecx.read_immediate(op),
|
||||
self.path,
|
||||
InvalidUninitBytes(None) => Uninit { expected }
|
||||
Ub(InvalidUninitBytes(None)) =>
|
||||
Uninit { expected },
|
||||
// The `Unsup` cases can only occur during CTFE
|
||||
Unsup(ReadPointerAsInt(_)) =>
|
||||
PointerAsInt { expected },
|
||||
Unsup(ReadPartialPointer(_)) =>
|
||||
PartialPointer,
|
||||
))
|
||||
}
|
||||
|
||||
|
@ -319,8 +329,8 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
|
|||
let (_ty, _trait) = try_validation!(
|
||||
self.ecx.get_ptr_vtable(vtable),
|
||||
self.path,
|
||||
DanglingIntPointer(..) |
|
||||
InvalidVTablePointer(..) => InvalidVTablePtr { value: format!("{vtable}") }
|
||||
Ub(DanglingIntPointer(..) | InvalidVTablePointer(..)) =>
|
||||
InvalidVTablePtr { value: format!("{vtable}") }
|
||||
);
|
||||
// FIXME: check if the type/trait match what ty::Dynamic says?
|
||||
}
|
||||
|
@ -356,7 +366,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
|
|||
let size_and_align = try_validation!(
|
||||
self.ecx.size_and_align_of_mplace(&place),
|
||||
self.path,
|
||||
InvalidMeta(msg) => match msg {
|
||||
Ub(InvalidMeta(msg)) => match msg {
|
||||
InvalidMetaKind::SliceTooBig => InvalidMetaSliceTooLarge { ptr_kind },
|
||||
InvalidMetaKind::TooBig => InvalidMetaTooLarge { ptr_kind },
|
||||
}
|
||||
|
@ -375,23 +385,23 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
|
|||
CheckInAllocMsg::InboundsTest, // will anyway be replaced by validity message
|
||||
),
|
||||
self.path,
|
||||
AlignmentCheckFailed { required, has } => UnalignedPtr {
|
||||
Ub(AlignmentCheckFailed { required, has }) => UnalignedPtr {
|
||||
ptr_kind,
|
||||
required_bytes: required.bytes(),
|
||||
found_bytes: has.bytes()
|
||||
},
|
||||
DanglingIntPointer(0, _) => NullPtr { ptr_kind },
|
||||
DanglingIntPointer(i, _) => DanglingPtrNoProvenance {
|
||||
Ub(DanglingIntPointer(0, _)) => NullPtr { ptr_kind },
|
||||
Ub(DanglingIntPointer(i, _)) => DanglingPtrNoProvenance {
|
||||
ptr_kind,
|
||||
// FIXME this says "null pointer" when null but we need translate
|
||||
pointer: format!("{}", Pointer::<Option<AllocId>>::from_addr_invalid(i))
|
||||
pointer: format!("{}", Pointer::<Option<AllocId>>::from_addr_invalid(*i))
|
||||
},
|
||||
PointerOutOfBounds { .. } => DanglingPtrOutOfBounds {
|
||||
Ub(PointerOutOfBounds { .. }) => DanglingPtrOutOfBounds {
|
||||
ptr_kind
|
||||
},
|
||||
// This cannot happen during const-eval (because interning already detects
|
||||
// dangling pointers), but it can happen in Miri.
|
||||
PointerUseAfterFree(..) => DanglingPtrUseAfterFree {
|
||||
Ub(PointerUseAfterFree(..)) => DanglingPtrUseAfterFree {
|
||||
ptr_kind,
|
||||
},
|
||||
);
|
||||
|
@ -477,7 +487,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
|
|||
try_validation!(
|
||||
value.to_bool(),
|
||||
self.path,
|
||||
InvalidBool(..) => ValidationErrorKind::InvalidBool {
|
||||
Ub(InvalidBool(..)) => ValidationErrorKind::InvalidBool {
|
||||
value: format!("{value:x}"),
|
||||
}
|
||||
);
|
||||
|
@ -488,7 +498,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
|
|||
try_validation!(
|
||||
value.to_char(),
|
||||
self.path,
|
||||
InvalidChar(..) => ValidationErrorKind::InvalidChar {
|
||||
Ub(InvalidChar(..)) => ValidationErrorKind::InvalidChar {
|
||||
value: format!("{value:x}"),
|
||||
}
|
||||
);
|
||||
|
@ -497,7 +507,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
|
|||
ty::Float(_) | ty::Int(_) | ty::Uint(_) => {
|
||||
// NOTE: Keep this in sync with the array optimization for int/float
|
||||
// types below!
|
||||
let value = self.read_scalar(
|
||||
self.read_scalar(
|
||||
value,
|
||||
if matches!(ty.kind(), ty::Float(..)) {
|
||||
ExpectedKind::Float
|
||||
|
@ -505,14 +515,6 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
|
|||
ExpectedKind::Int
|
||||
},
|
||||
)?;
|
||||
// As a special exception we *do* match on a `Scalar` here, since we truly want
|
||||
// to know its underlying representation (and *not* cast it to an integer).
|
||||
if matches!(value, Scalar::Ptr(..)) {
|
||||
throw_validation_failure!(
|
||||
self.path,
|
||||
ExpectedNonPtr { value: format!("{value:x}") }
|
||||
)
|
||||
}
|
||||
Ok(true)
|
||||
}
|
||||
ty::RawPtr(..) => {
|
||||
|
@ -546,10 +548,8 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
|
|||
let _fn = try_validation!(
|
||||
self.ecx.get_ptr_fn(ptr),
|
||||
self.path,
|
||||
DanglingIntPointer(..) |
|
||||
InvalidFunctionPointer(..) => InvalidFnPtr {
|
||||
value: format!("{ptr}"),
|
||||
},
|
||||
Ub(DanglingIntPointer(..) | InvalidFunctionPointer(..)) =>
|
||||
InvalidFnPtr { value: format!("{ptr}") },
|
||||
);
|
||||
// FIXME: Check if the signature matches
|
||||
} else {
|
||||
|
@ -657,11 +657,12 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
|
|||
Ok(try_validation!(
|
||||
this.ecx.read_discriminant(op),
|
||||
this.path,
|
||||
InvalidTag(val) => InvalidEnumTag {
|
||||
Ub(InvalidTag(val)) => InvalidEnumTag {
|
||||
value: format!("{val:x}"),
|
||||
},
|
||||
UninhabitedEnumVariantRead(_) => UninhabitedEnumTag,
|
||||
InvalidUninitBytes(None) => UninitEnumTag,
|
||||
Ub(UninhabitedEnumVariantRead(_)) => UninhabitedEnumVariant,
|
||||
// Uninit / bad provenance are not possible since the field was already previously
|
||||
// checked at its integer type.
|
||||
))
|
||||
})
|
||||
}
|
||||
|
@ -740,7 +741,8 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
|
|||
try_validation!(
|
||||
self.ecx.read_bytes_ptr_strip_provenance(mplace.ptr, Size::from_bytes(len)),
|
||||
self.path,
|
||||
InvalidUninitBytes(..) => { UninitStr },
|
||||
Ub(InvalidUninitBytes(..)) => Uninit { expected: ExpectedKind::Str },
|
||||
Unsup(ReadPointerAsInt(_)) => PointerAsInt { expected: ExpectedKind::Str }
|
||||
);
|
||||
}
|
||||
ty::Array(tys, ..) | ty::Slice(tys)
|
||||
|
@ -752,6 +754,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
|
|||
if matches!(tys.kind(), ty::Int(..) | ty::Uint(..) | ty::Float(..))
|
||||
=>
|
||||
{
|
||||
let expected = if tys.is_integral() { ExpectedKind::Int } else { ExpectedKind::Float };
|
||||
// Optimized handling for arrays of integer/float type.
|
||||
|
||||
// This is the length of the array/slice.
|
||||
|
@ -770,7 +773,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
|
|||
Left(mplace) => mplace,
|
||||
Right(imm) => match *imm {
|
||||
Immediate::Uninit =>
|
||||
throw_validation_failure!(self.path, UninitVal),
|
||||
throw_validation_failure!(self.path, Uninit { expected }),
|
||||
Immediate::Scalar(..) | Immediate::ScalarPair(..) =>
|
||||
bug!("arrays/slices can never have Scalar/ScalarPair layout"),
|
||||
}
|
||||
|
@ -796,17 +799,21 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
|
|||
// For some errors we might be able to provide extra information.
|
||||
// (This custom logic does not fit the `try_validation!` macro.)
|
||||
match err.kind() {
|
||||
err_ub!(InvalidUninitBytes(Some((_alloc_id, access)))) => {
|
||||
Ub(InvalidUninitBytes(Some((_alloc_id, access)))) | Unsup(ReadPointerAsInt(Some((_alloc_id, access)))) => {
|
||||
// Some byte was uninitialized, determine which
|
||||
// element that byte belongs to so we can
|
||||
// provide an index.
|
||||
let i = usize::try_from(
|
||||
access.uninit.start.bytes() / layout.size.bytes(),
|
||||
access.bad.start.bytes() / layout.size.bytes(),
|
||||
)
|
||||
.unwrap();
|
||||
self.path.push(PathElem::ArrayElem(i));
|
||||
|
||||
throw_validation_failure!(self.path, UninitVal)
|
||||
if matches!(err.kind(), Ub(InvalidUninitBytes(_))) {
|
||||
throw_validation_failure!(self.path, Uninit { expected })
|
||||
} else {
|
||||
throw_validation_failure!(self.path, PointerAsInt { expected })
|
||||
}
|
||||
}
|
||||
|
||||
// Propagate upwards (that will also check for unexpected errors).
|
||||
|
@ -892,17 +899,22 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
// Run it.
|
||||
match visitor.visit_value(&op) {
|
||||
Ok(()) => Ok(()),
|
||||
// Pass through validation failures.
|
||||
Err(err) if matches!(err.kind(), err_ub!(Validation { .. })) => Err(err),
|
||||
// Complain about any other kind of UB error -- those are bad because we'd like to
|
||||
// Pass through validation failures and "invalid program" issues.
|
||||
Err(err)
|
||||
if matches!(
|
||||
err.kind(),
|
||||
err_ub!(ValidationError { .. }) | InterpError::InvalidProgram(_)
|
||||
) =>
|
||||
{
|
||||
Err(err)
|
||||
}
|
||||
// Complain about any other kind of error -- those are bad because we'd like to
|
||||
// report them in a way that shows *where* in the value the issue lies.
|
||||
Err(err) if matches!(err.kind(), InterpError::UndefinedBehavior(_)) => {
|
||||
Err(err) => {
|
||||
let (err, backtrace) = err.into_parts();
|
||||
backtrace.print_backtrace();
|
||||
bug!("Unexpected Undefined Behavior error during validation: {err:?}");
|
||||
}
|
||||
// Pass through everything else.
|
||||
Err(err) => Err(err),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue