1use std::any::Any;
2use std::backtrace::Backtrace;
3use std::borrow::Cow;
4use std::{convert, fmt, mem, ops};
5
6use either::Either;
7use rustc_abi::{Align, Size, VariantIdx, WrappingRange};
8use rustc_data_structures::sync::Lock;
9use rustc_errors::{DiagArgName, DiagArgValue, DiagMessage, ErrorGuaranteed, IntoDiagArg};
10use rustc_macros::{HashStable, TyDecodable, TyEncodable};
11use rustc_session::CtfeBacktrace;
12use rustc_span::def_id::DefId;
13use rustc_span::{DUMMY_SP, Span, Symbol};
14
15use super::{AllocId, AllocRange, ConstAllocation, Pointer, Scalar};
16use crate::error;
17use crate::mir::{ConstAlloc, ConstValue};
18use crate::ty::{self, Mutability, Ty, TyCtxt, ValTree, layout, tls};
19
20#[derive(#[automatically_derived]
impl ::core::fmt::Debug for ErrorHandled {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
ErrorHandled::Reported(__self_0, __self_1) =>
::core::fmt::Formatter::debug_tuple_field2_finish(f,
"Reported", __self_0, &__self_1),
ErrorHandled::TooGeneric(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"TooGeneric", &__self_0),
}
}
}Debug, #[automatically_derived]
impl ::core::marker::Copy for ErrorHandled { }Copy, #[automatically_derived]
impl ::core::clone::Clone for ErrorHandled {
#[inline]
fn clone(&self) -> ErrorHandled {
let _: ::core::clone::AssertParamIsClone<ReportedErrorInfo>;
let _: ::core::clone::AssertParamIsClone<Span>;
*self
}
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for ErrorHandled {
#[inline]
fn eq(&self, other: &ErrorHandled) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr &&
match (self, other) {
(ErrorHandled::Reported(__self_0, __self_1),
ErrorHandled::Reported(__arg1_0, __arg1_1)) =>
__self_0 == __arg1_0 && __self_1 == __arg1_1,
(ErrorHandled::TooGeneric(__self_0),
ErrorHandled::TooGeneric(__arg1_0)) => __self_0 == __arg1_0,
_ => unsafe { ::core::intrinsics::unreachable() }
}
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for ErrorHandled {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<ReportedErrorInfo>;
let _: ::core::cmp::AssertParamIsEq<Span>;
}
}Eq, const _: () =
{
impl<'__ctx>
::rustc_data_structures::stable_hasher::HashStable<::rustc_middle::ich::StableHashingContext<'__ctx>>
for ErrorHandled {
#[inline]
fn hash_stable(&self,
__hcx: &mut ::rustc_middle::ich::StableHashingContext<'__ctx>,
__hasher:
&mut ::rustc_data_structures::stable_hasher::StableHasher) {
::std::mem::discriminant(self).hash_stable(__hcx, __hasher);
match *self {
ErrorHandled::Reported(ref __binding_0, ref __binding_1) =>
{
{ __binding_0.hash_stable(__hcx, __hasher); }
{ __binding_1.hash_stable(__hcx, __hasher); }
}
ErrorHandled::TooGeneric(ref __binding_0) => {
{ __binding_0.hash_stable(__hcx, __hasher); }
}
}
}
}
};HashStable, const _: () =
{
impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
::rustc_serialize::Encodable<__E> for ErrorHandled {
fn encode(&self, __encoder: &mut __E) {
let disc =
match *self {
ErrorHandled::Reported(ref __binding_0, ref __binding_1) =>
{
0usize
}
ErrorHandled::TooGeneric(ref __binding_0) => { 1usize }
};
::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
match *self {
ErrorHandled::Reported(ref __binding_0, ref __binding_1) =>
{
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_1,
__encoder);
}
ErrorHandled::TooGeneric(ref __binding_0) => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
}
}
}
};TyEncodable, const _: () =
{
impl<'tcx, __D: ::rustc_middle::ty::codec::TyDecoder<'tcx>>
::rustc_serialize::Decodable<__D> for ErrorHandled {
fn decode(__decoder: &mut __D) -> Self {
match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
{
0usize => {
ErrorHandled::Reported(::rustc_serialize::Decodable::decode(__decoder),
::rustc_serialize::Decodable::decode(__decoder))
}
1usize => {
ErrorHandled::TooGeneric(::rustc_serialize::Decodable::decode(__decoder))
}
n => {
::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `ErrorHandled`, expected 0..2, actual {0}",
n));
}
}
}
}
};TyDecodable)]
21pub enum ErrorHandled {
22 Reported(ReportedErrorInfo, Span),
25 TooGeneric(Span),
28}
29
30impl From<ReportedErrorInfo> for ErrorHandled {
31 #[inline]
32 fn from(error: ReportedErrorInfo) -> ErrorHandled {
33 ErrorHandled::Reported(error, DUMMY_SP)
34 }
35}
36
37impl ErrorHandled {
38 pub(crate) fn with_span(self, span: Span) -> Self {
39 match self {
40 ErrorHandled::Reported(err, _span) => ErrorHandled::Reported(err, span),
41 ErrorHandled::TooGeneric(_span) => ErrorHandled::TooGeneric(span),
42 }
43 }
44
45 pub fn emit_note(&self, tcx: TyCtxt<'_>) {
46 match self {
47 &ErrorHandled::Reported(err, span) => {
48 if !err.allowed_in_infallible && !span.is_dummy() {
49 tcx.dcx().emit_note(error::ErroneousConstant { span });
50 }
51 }
52 &ErrorHandled::TooGeneric(_) => {}
53 }
54 }
55}
56
57#[derive(#[automatically_derived]
impl ::core::fmt::Debug for ReportedErrorInfo {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f,
"ReportedErrorInfo", "error", &self.error,
"allowed_in_infallible", &&self.allowed_in_infallible)
}
}Debug, #[automatically_derived]
impl ::core::marker::Copy for ReportedErrorInfo { }Copy, #[automatically_derived]
impl ::core::clone::Clone for ReportedErrorInfo {
#[inline]
fn clone(&self) -> ReportedErrorInfo {
let _: ::core::clone::AssertParamIsClone<ErrorGuaranteed>;
let _: ::core::clone::AssertParamIsClone<bool>;
*self
}
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for ReportedErrorInfo {
#[inline]
fn eq(&self, other: &ReportedErrorInfo) -> bool {
self.allowed_in_infallible == other.allowed_in_infallible &&
self.error == other.error
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for ReportedErrorInfo {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<ErrorGuaranteed>;
let _: ::core::cmp::AssertParamIsEq<bool>;
}
}Eq, const _: () =
{
impl<'__ctx>
::rustc_data_structures::stable_hasher::HashStable<::rustc_middle::ich::StableHashingContext<'__ctx>>
for ReportedErrorInfo {
#[inline]
fn hash_stable(&self,
__hcx: &mut ::rustc_middle::ich::StableHashingContext<'__ctx>,
__hasher:
&mut ::rustc_data_structures::stable_hasher::StableHasher) {
match *self {
ReportedErrorInfo {
error: ref __binding_0,
allowed_in_infallible: ref __binding_1 } => {
{ __binding_0.hash_stable(__hcx, __hasher); }
{ __binding_1.hash_stable(__hcx, __hasher); }
}
}
}
}
};HashStable, const _: () =
{
impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
::rustc_serialize::Encodable<__E> for ReportedErrorInfo {
fn encode(&self, __encoder: &mut __E) {
match *self {
ReportedErrorInfo {
error: ref __binding_0,
allowed_in_infallible: ref __binding_1 } => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_1,
__encoder);
}
}
}
}
};TyEncodable, const _: () =
{
impl<'tcx, __D: ::rustc_middle::ty::codec::TyDecoder<'tcx>>
::rustc_serialize::Decodable<__D> for ReportedErrorInfo {
fn decode(__decoder: &mut __D) -> Self {
ReportedErrorInfo {
error: ::rustc_serialize::Decodable::decode(__decoder),
allowed_in_infallible: ::rustc_serialize::Decodable::decode(__decoder),
}
}
}
};TyDecodable)]
58pub struct ReportedErrorInfo {
59 error: ErrorGuaranteed,
60 allowed_in_infallible: bool,
63}
64
65impl ReportedErrorInfo {
66 #[inline]
67 pub fn const_eval_error(error: ErrorGuaranteed) -> ReportedErrorInfo {
68 ReportedErrorInfo { allowed_in_infallible: false, error }
69 }
70
71 #[inline]
74 pub fn non_const_eval_error(error: ErrorGuaranteed) -> ReportedErrorInfo {
75 ReportedErrorInfo { allowed_in_infallible: true, error }
76 }
77
78 #[inline]
81 pub fn allowed_in_infallible(error: ErrorGuaranteed) -> ReportedErrorInfo {
82 ReportedErrorInfo { allowed_in_infallible: true, error }
83 }
84
85 pub fn is_allowed_in_infallible(&self) -> bool {
86 self.allowed_in_infallible
87 }
88}
89
90impl From<ReportedErrorInfo> for ErrorGuaranteed {
91 #[inline]
92 fn from(val: ReportedErrorInfo) -> Self {
93 val.error
94 }
95}
96
97#[derive(#[automatically_derived]
impl<'tcx> ::core::fmt::Debug for ValTreeCreationError<'tcx> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
ValTreeCreationError::NodesOverflow =>
::core::fmt::Formatter::write_str(f, "NodesOverflow"),
ValTreeCreationError::InvalidConst =>
::core::fmt::Formatter::write_str(f, "InvalidConst"),
ValTreeCreationError::NonSupportedType(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"NonSupportedType", &__self_0),
ValTreeCreationError::ErrorHandled(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"ErrorHandled", &__self_0),
}
}
}Debug, #[automatically_derived]
impl<'tcx> ::core::marker::Copy for ValTreeCreationError<'tcx> { }Copy, #[automatically_derived]
impl<'tcx> ::core::clone::Clone for ValTreeCreationError<'tcx> {
#[inline]
fn clone(&self) -> ValTreeCreationError<'tcx> {
let _: ::core::clone::AssertParamIsClone<Ty<'tcx>>;
let _: ::core::clone::AssertParamIsClone<ErrorHandled>;
*self
}
}Clone, #[automatically_derived]
impl<'tcx> ::core::cmp::PartialEq for ValTreeCreationError<'tcx> {
#[inline]
fn eq(&self, other: &ValTreeCreationError<'tcx>) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr &&
match (self, other) {
(ValTreeCreationError::NonSupportedType(__self_0),
ValTreeCreationError::NonSupportedType(__arg1_0)) =>
__self_0 == __arg1_0,
(ValTreeCreationError::ErrorHandled(__self_0),
ValTreeCreationError::ErrorHandled(__arg1_0)) =>
__self_0 == __arg1_0,
_ => true,
}
}
}PartialEq, #[automatically_derived]
impl<'tcx> ::core::cmp::Eq for ValTreeCreationError<'tcx> {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Ty<'tcx>>;
let _: ::core::cmp::AssertParamIsEq<ErrorHandled>;
}
}Eq, const _: () =
{
impl<'tcx, '__ctx>
::rustc_data_structures::stable_hasher::HashStable<::rustc_middle::ich::StableHashingContext<'__ctx>>
for ValTreeCreationError<'tcx> {
#[inline]
fn hash_stable(&self,
__hcx: &mut ::rustc_middle::ich::StableHashingContext<'__ctx>,
__hasher:
&mut ::rustc_data_structures::stable_hasher::StableHasher) {
::std::mem::discriminant(self).hash_stable(__hcx, __hasher);
match *self {
ValTreeCreationError::NodesOverflow => {}
ValTreeCreationError::InvalidConst => {}
ValTreeCreationError::NonSupportedType(ref __binding_0) => {
{ __binding_0.hash_stable(__hcx, __hasher); }
}
ValTreeCreationError::ErrorHandled(ref __binding_0) => {
{ __binding_0.hash_stable(__hcx, __hasher); }
}
}
}
}
};HashStable, const _: () =
{
impl<'tcx, __E: ::rustc_middle::ty::codec::TyEncoder<'tcx>>
::rustc_serialize::Encodable<__E> for ValTreeCreationError<'tcx> {
fn encode(&self, __encoder: &mut __E) {
let disc =
match *self {
ValTreeCreationError::NodesOverflow => { 0usize }
ValTreeCreationError::InvalidConst => { 1usize }
ValTreeCreationError::NonSupportedType(ref __binding_0) => {
2usize
}
ValTreeCreationError::ErrorHandled(ref __binding_0) => {
3usize
}
};
::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
match *self {
ValTreeCreationError::NodesOverflow => {}
ValTreeCreationError::InvalidConst => {}
ValTreeCreationError::NonSupportedType(ref __binding_0) => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
ValTreeCreationError::ErrorHandled(ref __binding_0) => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
}
}
}
};TyEncodable, const _: () =
{
impl<'tcx, __D: ::rustc_middle::ty::codec::TyDecoder<'tcx>>
::rustc_serialize::Decodable<__D> for ValTreeCreationError<'tcx> {
fn decode(__decoder: &mut __D) -> Self {
match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
{
0usize => { ValTreeCreationError::NodesOverflow }
1usize => { ValTreeCreationError::InvalidConst }
2usize => {
ValTreeCreationError::NonSupportedType(::rustc_serialize::Decodable::decode(__decoder))
}
3usize => {
ValTreeCreationError::ErrorHandled(::rustc_serialize::Decodable::decode(__decoder))
}
n => {
::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `ValTreeCreationError`, expected 0..4, actual {0}",
n));
}
}
}
}
};TyDecodable)]
100pub enum ValTreeCreationError<'tcx> {
101 NodesOverflow,
103 InvalidConst,
105 NonSupportedType(Ty<'tcx>),
107 ErrorHandled(ErrorHandled),
109}
110
111impl<'tcx> From<ErrorHandled> for ValTreeCreationError<'tcx> {
112 fn from(err: ErrorHandled) -> Self {
113 ValTreeCreationError::ErrorHandled(err)
114 }
115}
116
117impl<'tcx> From<InterpErrorInfo<'tcx>> for ValTreeCreationError<'tcx> {
118 fn from(err: InterpErrorInfo<'tcx>) -> Self {
119 let (_kind, backtrace) = err.into_parts();
123 backtrace.print_backtrace();
124 ValTreeCreationError::InvalidConst
125 }
126}
127
128impl<'tcx> ValTreeCreationError<'tcx> {
129 pub(crate) fn with_span(self, span: Span) -> Self {
130 use ValTreeCreationError::*;
131 match self {
132 ErrorHandled(handled) => ErrorHandled(handled.with_span(span)),
133 other => other,
134 }
135 }
136}
137
138pub type EvalToAllocationRawResult<'tcx> = Result<ConstAlloc<'tcx>, ErrorHandled>;
139pub type EvalStaticInitializerRawResult<'tcx> = Result<ConstAllocation<'tcx>, ErrorHandled>;
140pub type EvalToConstValueResult<'tcx> = Result<ConstValue, ErrorHandled>;
141pub type EvalToValTreeResult<'tcx> = Result<ValTree<'tcx>, ValTreeCreationError<'tcx>>;
142
143#[cfg(target_pointer_width = "64")]
144const _: [(); 8] = [(); ::std::mem::size_of::<InterpErrorInfo<'_>>()];rustc_data_structures::static_assert_size!(InterpErrorInfo<'_>, 8);
145
146#[derive(#[automatically_derived]
impl<'tcx> ::core::fmt::Debug for InterpErrorInfo<'tcx> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"InterpErrorInfo", &&self.0)
}
}Debug)]
156pub struct InterpErrorInfo<'tcx>(Box<InterpErrorInfoInner<'tcx>>);
157
158#[derive(#[automatically_derived]
impl<'tcx> ::core::fmt::Debug for InterpErrorInfoInner<'tcx> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f,
"InterpErrorInfoInner", "kind", &self.kind, "backtrace",
&&self.backtrace)
}
}Debug)]
159struct InterpErrorInfoInner<'tcx> {
160 kind: InterpErrorKind<'tcx>,
161 backtrace: InterpErrorBacktrace,
162}
163
164#[derive(#[automatically_derived]
impl ::core::fmt::Debug for InterpErrorBacktrace {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(f,
"InterpErrorBacktrace", "backtrace", &&self.backtrace)
}
}Debug)]
165pub struct InterpErrorBacktrace {
166 backtrace: Option<Box<Backtrace>>,
167}
168
169impl InterpErrorBacktrace {
170 pub fn new() -> InterpErrorBacktrace {
171 let capture_backtrace = tls::with_opt(|tcx| {
172 if let Some(tcx) = tcx {
173 *Lock::borrow(&tcx.sess.ctfe_backtrace)
174 } else {
175 CtfeBacktrace::Disabled
176 }
177 });
178
179 let backtrace = match capture_backtrace {
180 CtfeBacktrace::Disabled => None,
181 CtfeBacktrace::Capture => Some(Box::new(Backtrace::force_capture())),
182 CtfeBacktrace::Immediate => {
183 let backtrace = Backtrace::force_capture();
185 print_backtrace(&backtrace);
186 None
187 }
188 };
189
190 InterpErrorBacktrace { backtrace }
191 }
192
193 pub fn print_backtrace(&self) {
194 if let Some(backtrace) = self.backtrace.as_ref() {
195 print_backtrace(backtrace);
196 }
197 }
198}
199
200impl<'tcx> InterpErrorInfo<'tcx> {
201 pub fn into_parts(self) -> (InterpErrorKind<'tcx>, InterpErrorBacktrace) {
202 let InterpErrorInfo(box InterpErrorInfoInner { kind, backtrace }) = self;
203 (kind, backtrace)
204 }
205
206 pub fn into_kind(self) -> InterpErrorKind<'tcx> {
207 self.0.kind
208 }
209
210 pub fn from_parts(kind: InterpErrorKind<'tcx>, backtrace: InterpErrorBacktrace) -> Self {
211 Self(Box::new(InterpErrorInfoInner { kind, backtrace }))
212 }
213
214 #[inline]
215 pub fn kind(&self) -> &InterpErrorKind<'tcx> {
216 &self.0.kind
217 }
218}
219
220fn print_backtrace(backtrace: &Backtrace) {
221 {
::std::io::_eprint(format_args!("\n\nAn error occurred in the MIR interpreter:\n{0}\n",
backtrace));
};eprintln!("\n\nAn error occurred in the MIR interpreter:\n{backtrace}");
222}
223
224impl From<ErrorHandled> for InterpErrorInfo<'_> {
225 fn from(err: ErrorHandled) -> Self {
226 InterpErrorKind::InvalidProgram(match err {
227 ErrorHandled::Reported(r, _span) => InvalidProgramInfo::AlreadyReported(r),
228 ErrorHandled::TooGeneric(_span) => InvalidProgramInfo::TooGeneric,
229 })
230 .into()
231 }
232}
233
234impl<'tcx> From<InterpErrorKind<'tcx>> for InterpErrorInfo<'tcx> {
235 fn from(kind: InterpErrorKind<'tcx>) -> Self {
236 InterpErrorInfo(Box::new(InterpErrorInfoInner {
237 kind,
238 backtrace: InterpErrorBacktrace::new(),
239 }))
240 }
241}
242
243#[derive(#[automatically_derived]
impl<'tcx> ::core::fmt::Debug for InvalidProgramInfo<'tcx> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
InvalidProgramInfo::TooGeneric =>
::core::fmt::Formatter::write_str(f, "TooGeneric"),
InvalidProgramInfo::AlreadyReported(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"AlreadyReported", &__self_0),
InvalidProgramInfo::Layout(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Layout",
&__self_0),
}
}
}Debug)]
248pub enum InvalidProgramInfo<'tcx> {
249 TooGeneric,
251 AlreadyReported(ReportedErrorInfo),
253 Layout(layout::LayoutError<'tcx>),
255}
256
257#[derive(#[automatically_derived]
impl ::core::fmt::Debug for CheckInAllocMsg {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
CheckInAllocMsg::MemoryAccess => "MemoryAccess",
CheckInAllocMsg::InboundsPointerArithmetic =>
"InboundsPointerArithmetic",
CheckInAllocMsg::Dereferenceable => "Dereferenceable",
})
}
}Debug, #[automatically_derived]
impl ::core::marker::Copy for CheckInAllocMsg { }Copy, #[automatically_derived]
impl ::core::clone::Clone for CheckInAllocMsg {
#[inline]
fn clone(&self) -> CheckInAllocMsg { *self }
}Clone)]
259pub enum CheckInAllocMsg {
260 MemoryAccess,
262 InboundsPointerArithmetic,
264 Dereferenceable,
266}
267
268#[derive(#[automatically_derived]
impl ::core::fmt::Debug for CheckAlignMsg {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
CheckAlignMsg::AccessedPtr => "AccessedPtr",
CheckAlignMsg::BasedOn => "BasedOn",
})
}
}Debug, #[automatically_derived]
impl ::core::marker::Copy for CheckAlignMsg { }Copy, #[automatically_derived]
impl ::core::clone::Clone for CheckAlignMsg {
#[inline]
fn clone(&self) -> CheckAlignMsg { *self }
}Clone)]
270pub enum CheckAlignMsg {
271 AccessedPtr,
273 BasedOn,
275}
276
277#[derive(#[automatically_derived]
impl ::core::fmt::Debug for InvalidMetaKind {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
InvalidMetaKind::SliceTooBig => "SliceTooBig",
InvalidMetaKind::TooBig => "TooBig",
})
}
}Debug, #[automatically_derived]
impl ::core::marker::Copy for InvalidMetaKind { }Copy, #[automatically_derived]
impl ::core::clone::Clone for InvalidMetaKind {
#[inline]
fn clone(&self) -> InvalidMetaKind { *self }
}Clone)]
278pub enum InvalidMetaKind {
279 SliceTooBig,
281 TooBig,
283}
284
285impl IntoDiagArg for InvalidMetaKind {
286 fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
287 DiagArgValue::Str(Cow::Borrowed(match self {
288 InvalidMetaKind::SliceTooBig => "slice_too_big",
289 InvalidMetaKind::TooBig => "too_big",
290 }))
291 }
292}
293
294#[derive(#[automatically_derived]
impl ::core::fmt::Debug for BadBytesAccess {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f,
"BadBytesAccess", "access", &self.access, "bad", &&self.bad)
}
}Debug, #[automatically_derived]
impl ::core::clone::Clone for BadBytesAccess {
#[inline]
fn clone(&self) -> BadBytesAccess {
let _: ::core::clone::AssertParamIsClone<AllocRange>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for BadBytesAccess { }Copy)]
296pub struct BadBytesAccess {
297 pub access: AllocRange,
299 pub bad: AllocRange,
301}
302
303#[derive(#[automatically_derived]
impl ::core::fmt::Debug for ScalarSizeMismatch {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f,
"ScalarSizeMismatch", "target_size", &self.target_size,
"data_size", &&self.data_size)
}
}Debug)]
305pub struct ScalarSizeMismatch {
306 pub target_size: u64,
307 pub data_size: u64,
308}
309
310#[derive(#[automatically_derived]
impl ::core::marker::Copy for Misalignment { }Copy, #[automatically_derived]
impl ::core::clone::Clone for Misalignment {
#[inline]
fn clone(&self) -> Misalignment {
let _: ::core::clone::AssertParamIsClone<Align>;
*self
}
}Clone, #[automatically_derived]
impl ::core::hash::Hash for Misalignment {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.has, state);
::core::hash::Hash::hash(&self.required, state)
}
}Hash, #[automatically_derived]
impl ::core::cmp::PartialEq for Misalignment {
#[inline]
fn eq(&self, other: &Misalignment) -> bool {
self.has == other.has && self.required == other.required
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for Misalignment {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Align>;
}
}Eq, #[automatically_derived]
impl ::core::fmt::Debug for Misalignment {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f, "Misalignment",
"has", &self.has, "required", &&self.required)
}
}Debug)]
312pub struct Misalignment {
313 pub has: Align,
314 pub required: Align,
315}
316
317macro_rules! impl_into_diag_arg_through_debug {
318 ($($ty:ty),*$(,)?) => {$(
319 impl IntoDiagArg for $ty {
320 fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
321 DiagArgValue::Str(Cow::Owned(format!("{self:?}")))
322 }
323 }
324 )*}
325}
326
327impl IntoDiagArg for AllocRange {
fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>)
-> DiagArgValue {
DiagArgValue::Str(Cow::Owned(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0:?}", self))
})))
}
}impl_into_diag_arg_through_debug! {
329 AllocId,
330 Pointer<AllocId>,
331 AllocRange,
332}
333
334#[derive(#[automatically_derived]
impl<'tcx> ::core::fmt::Debug for UndefinedBehaviorInfo<'tcx> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
UndefinedBehaviorInfo::Ub(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Ub",
&__self_0),
UndefinedBehaviorInfo::Custom(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Custom",
&__self_0),
UndefinedBehaviorInfo::ValidationError(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"ValidationError", &__self_0),
UndefinedBehaviorInfo::Unreachable =>
::core::fmt::Formatter::write_str(f, "Unreachable"),
UndefinedBehaviorInfo::BoundsCheckFailed {
len: __self_0, index: __self_1 } =>
::core::fmt::Formatter::debug_struct_field2_finish(f,
"BoundsCheckFailed", "len", __self_0, "index", &__self_1),
UndefinedBehaviorInfo::DivisionByZero =>
::core::fmt::Formatter::write_str(f, "DivisionByZero"),
UndefinedBehaviorInfo::RemainderByZero =>
::core::fmt::Formatter::write_str(f, "RemainderByZero"),
UndefinedBehaviorInfo::DivisionOverflow =>
::core::fmt::Formatter::write_str(f, "DivisionOverflow"),
UndefinedBehaviorInfo::RemainderOverflow =>
::core::fmt::Formatter::write_str(f, "RemainderOverflow"),
UndefinedBehaviorInfo::PointerArithOverflow =>
::core::fmt::Formatter::write_str(f, "PointerArithOverflow"),
UndefinedBehaviorInfo::ArithOverflow { intrinsic: __self_0 } =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"ArithOverflow", "intrinsic", &__self_0),
UndefinedBehaviorInfo::ShiftOverflow {
intrinsic: __self_0, shift_amount: __self_1 } =>
::core::fmt::Formatter::debug_struct_field2_finish(f,
"ShiftOverflow", "intrinsic", __self_0, "shift_amount",
&__self_1),
UndefinedBehaviorInfo::InvalidMeta(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"InvalidMeta", &__self_0),
UndefinedBehaviorInfo::UnterminatedCString(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"UnterminatedCString", &__self_0),
UndefinedBehaviorInfo::PointerUseAfterFree(__self_0, __self_1) =>
::core::fmt::Formatter::debug_tuple_field2_finish(f,
"PointerUseAfterFree", __self_0, &__self_1),
UndefinedBehaviorInfo::PointerOutOfBounds {
alloc_id: __self_0,
alloc_size: __self_1,
ptr_offset: __self_2,
inbounds_size: __self_3,
msg: __self_4 } =>
::core::fmt::Formatter::debug_struct_field5_finish(f,
"PointerOutOfBounds", "alloc_id", __self_0, "alloc_size",
__self_1, "ptr_offset", __self_2, "inbounds_size", __self_3,
"msg", &__self_4),
UndefinedBehaviorInfo::DanglingIntPointer {
addr: __self_0, inbounds_size: __self_1, msg: __self_2 } =>
::core::fmt::Formatter::debug_struct_field3_finish(f,
"DanglingIntPointer", "addr", __self_0, "inbounds_size",
__self_1, "msg", &__self_2),
UndefinedBehaviorInfo::AlignmentCheckFailed(__self_0, __self_1) =>
::core::fmt::Formatter::debug_tuple_field2_finish(f,
"AlignmentCheckFailed", __self_0, &__self_1),
UndefinedBehaviorInfo::WriteToReadOnly(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"WriteToReadOnly", &__self_0),
UndefinedBehaviorInfo::DerefFunctionPointer(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"DerefFunctionPointer", &__self_0),
UndefinedBehaviorInfo::DerefVTablePointer(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"DerefVTablePointer", &__self_0),
UndefinedBehaviorInfo::DerefVaListPointer(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"DerefVaListPointer", &__self_0),
UndefinedBehaviorInfo::DerefTypeIdPointer(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"DerefTypeIdPointer", &__self_0),
UndefinedBehaviorInfo::InvalidBool(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"InvalidBool", &__self_0),
UndefinedBehaviorInfo::InvalidChar(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"InvalidChar", &__self_0),
UndefinedBehaviorInfo::InvalidTag(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"InvalidTag", &__self_0),
UndefinedBehaviorInfo::InvalidFunctionPointer(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"InvalidFunctionPointer", &__self_0),
UndefinedBehaviorInfo::InvalidVaListPointer(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"InvalidVaListPointer", &__self_0),
UndefinedBehaviorInfo::InvalidVTablePointer(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"InvalidVTablePointer", &__self_0),
UndefinedBehaviorInfo::InvalidVTableTrait {
vtable_dyn_type: __self_0, expected_dyn_type: __self_1 } =>
::core::fmt::Formatter::debug_struct_field2_finish(f,
"InvalidVTableTrait", "vtable_dyn_type", __self_0,
"expected_dyn_type", &__self_1),
UndefinedBehaviorInfo::InvalidStr(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"InvalidStr", &__self_0),
UndefinedBehaviorInfo::InvalidUninitBytes(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"InvalidUninitBytes", &__self_0),
UndefinedBehaviorInfo::DeadLocal =>
::core::fmt::Formatter::write_str(f, "DeadLocal"),
UndefinedBehaviorInfo::ScalarSizeMismatch(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"ScalarSizeMismatch", &__self_0),
UndefinedBehaviorInfo::UninhabitedEnumVariantWritten(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"UninhabitedEnumVariantWritten", &__self_0),
UndefinedBehaviorInfo::UninhabitedEnumVariantRead(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"UninhabitedEnumVariantRead", &__self_0),
UndefinedBehaviorInfo::InvalidNichedEnumVariantWritten {
enum_ty: __self_0 } =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"InvalidNichedEnumVariantWritten", "enum_ty", &__self_0),
UndefinedBehaviorInfo::AbiMismatchArgument {
arg_idx: __self_0, caller_ty: __self_1, callee_ty: __self_2 }
=>
::core::fmt::Formatter::debug_struct_field3_finish(f,
"AbiMismatchArgument", "arg_idx", __self_0, "caller_ty",
__self_1, "callee_ty", &__self_2),
UndefinedBehaviorInfo::AbiMismatchReturn {
caller_ty: __self_0, callee_ty: __self_1 } =>
::core::fmt::Formatter::debug_struct_field2_finish(f,
"AbiMismatchReturn", "caller_ty", __self_0, "callee_ty",
&__self_1),
UndefinedBehaviorInfo::VaArgOutOfBounds =>
::core::fmt::Formatter::write_str(f, "VaArgOutOfBounds"),
UndefinedBehaviorInfo::CVariadicMismatch {
caller_is_c_variadic: __self_0, callee_is_c_variadic: __self_1
} =>
::core::fmt::Formatter::debug_struct_field2_finish(f,
"CVariadicMismatch", "caller_is_c_variadic", __self_0,
"callee_is_c_variadic", &__self_1),
UndefinedBehaviorInfo::CVariadicFixedCountMismatch {
caller: __self_0, callee: __self_1 } =>
::core::fmt::Formatter::debug_struct_field2_finish(f,
"CVariadicFixedCountMismatch", "caller", __self_0, "callee",
&__self_1),
}
}
}Debug)]
336pub enum UndefinedBehaviorInfo<'tcx> {
337 Ub(String),
339 Custom(crate::error::CustomSubdiagnostic<'tcx>),
343 ValidationError(ValidationErrorInfo<'tcx>),
345
346 Unreachable,
348 BoundsCheckFailed { len: u64, index: u64 },
350 DivisionByZero,
352 RemainderByZero,
354 DivisionOverflow,
356 RemainderOverflow,
358 PointerArithOverflow,
360 ArithOverflow { intrinsic: Symbol },
362 ShiftOverflow { intrinsic: Symbol, shift_amount: Either<u128, i128> },
364 InvalidMeta(InvalidMetaKind),
366 UnterminatedCString(Pointer<AllocId>),
368 PointerUseAfterFree(AllocId, CheckInAllocMsg),
370 PointerOutOfBounds {
372 alloc_id: AllocId,
373 alloc_size: Size,
374 ptr_offset: i64,
375 inbounds_size: i64,
377 msg: CheckInAllocMsg,
378 },
379 DanglingIntPointer {
381 addr: u64,
382 inbounds_size: i64,
385 msg: CheckInAllocMsg,
386 },
387 AlignmentCheckFailed(Misalignment, CheckAlignMsg),
389 WriteToReadOnly(AllocId),
391 DerefFunctionPointer(AllocId),
393 DerefVTablePointer(AllocId),
395 DerefVaListPointer(AllocId),
397 DerefTypeIdPointer(AllocId),
399 InvalidBool(u8),
401 InvalidChar(u32),
403 InvalidTag(Scalar<AllocId>),
405 InvalidFunctionPointer(Pointer<AllocId>),
407 InvalidVaListPointer(Pointer<AllocId>),
409 InvalidVTablePointer(Pointer<AllocId>),
411 InvalidVTableTrait {
413 vtable_dyn_type: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
415 expected_dyn_type: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
417 },
418 InvalidStr(std::str::Utf8Error),
420 InvalidUninitBytes(Option<(AllocId, BadBytesAccess)>),
422 DeadLocal,
424 ScalarSizeMismatch(ScalarSizeMismatch),
426 UninhabitedEnumVariantWritten(VariantIdx),
428 UninhabitedEnumVariantRead(Option<VariantIdx>),
430 InvalidNichedEnumVariantWritten { enum_ty: Ty<'tcx> },
432 AbiMismatchArgument {
434 arg_idx: usize,
436 caller_ty: Ty<'tcx>,
437 callee_ty: Ty<'tcx>,
438 },
439 AbiMismatchReturn { caller_ty: Ty<'tcx>, callee_ty: Ty<'tcx> },
441 VaArgOutOfBounds,
443 CVariadicMismatch { caller_is_c_variadic: bool, callee_is_c_variadic: bool },
445 CVariadicFixedCountMismatch { caller: u32, callee: u32 },
447}
448
449#[derive(#[automatically_derived]
impl ::core::fmt::Debug for PointerKind {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
PointerKind::Ref(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Ref",
&__self_0),
PointerKind::Box => ::core::fmt::Formatter::write_str(f, "Box"),
}
}
}Debug, #[automatically_derived]
impl ::core::clone::Clone for PointerKind {
#[inline]
fn clone(&self) -> PointerKind {
let _: ::core::clone::AssertParamIsClone<Mutability>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for PointerKind { }Copy)]
450pub enum PointerKind {
451 Ref(Mutability),
452 Box,
453}
454
455impl IntoDiagArg for PointerKind {
456 fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
457 DiagArgValue::Str(
458 match self {
459 Self::Ref(_) => "ref",
460 Self::Box => "box",
461 }
462 .into(),
463 )
464 }
465}
466
467#[derive(#[automatically_derived]
impl<'tcx> ::core::fmt::Debug for ValidationErrorInfo<'tcx> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f,
"ValidationErrorInfo", "path", &self.path, "kind", &&self.kind)
}
}Debug)]
468pub struct ValidationErrorInfo<'tcx> {
469 pub path: Option<String>,
470 pub kind: ValidationErrorKind<'tcx>,
471}
472
473#[derive(#[automatically_derived]
impl ::core::fmt::Debug for ExpectedKind {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
ExpectedKind::Reference => "Reference",
ExpectedKind::Box => "Box",
ExpectedKind::RawPtr => "RawPtr",
ExpectedKind::InitScalar => "InitScalar",
ExpectedKind::Bool => "Bool",
ExpectedKind::Char => "Char",
ExpectedKind::Float => "Float",
ExpectedKind::Int => "Int",
ExpectedKind::FnPtr => "FnPtr",
ExpectedKind::EnumTag => "EnumTag",
ExpectedKind::Str => "Str",
})
}
}Debug)]
474pub enum ExpectedKind {
475 Reference,
476 Box,
477 RawPtr,
478 InitScalar,
479 Bool,
480 Char,
481 Float,
482 Int,
483 FnPtr,
484 EnumTag,
485 Str,
486}
487
488impl From<PointerKind> for ExpectedKind {
489 fn from(x: PointerKind) -> ExpectedKind {
490 match x {
491 PointerKind::Box => ExpectedKind::Box,
492 PointerKind::Ref(_) => ExpectedKind::Reference,
493 }
494 }
495}
496
497#[derive(#[automatically_derived]
impl<'tcx> ::core::fmt::Debug for ValidationErrorKind<'tcx> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
ValidationErrorKind::PointerAsInt { expected: __self_0 } =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"PointerAsInt", "expected", &__self_0),
ValidationErrorKind::PartialPointer =>
::core::fmt::Formatter::write_str(f, "PartialPointer"),
ValidationErrorKind::PtrToUninhabited {
ptr_kind: __self_0, ty: __self_1 } =>
::core::fmt::Formatter::debug_struct_field2_finish(f,
"PtrToUninhabited", "ptr_kind", __self_0, "ty", &__self_1),
ValidationErrorKind::MutableRefToImmutable =>
::core::fmt::Formatter::write_str(f, "MutableRefToImmutable"),
ValidationErrorKind::UnsafeCellInImmutable =>
::core::fmt::Formatter::write_str(f, "UnsafeCellInImmutable"),
ValidationErrorKind::NullFnPtr { maybe: __self_0 } =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"NullFnPtr", "maybe", &__self_0),
ValidationErrorKind::NeverVal =>
::core::fmt::Formatter::write_str(f, "NeverVal"),
ValidationErrorKind::NonnullPtrMaybeNull =>
::core::fmt::Formatter::write_str(f, "NonnullPtrMaybeNull"),
ValidationErrorKind::PtrOutOfRange {
range: __self_0, max_value: __self_1 } =>
::core::fmt::Formatter::debug_struct_field2_finish(f,
"PtrOutOfRange", "range", __self_0, "max_value", &__self_1),
ValidationErrorKind::OutOfRange {
value: __self_0, range: __self_1, max_value: __self_2 } =>
::core::fmt::Formatter::debug_struct_field3_finish(f,
"OutOfRange", "value", __self_0, "range", __self_1,
"max_value", &__self_2),
ValidationErrorKind::UninhabitedVal { ty: __self_0 } =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"UninhabitedVal", "ty", &__self_0),
ValidationErrorKind::InvalidEnumTag { value: __self_0 } =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"InvalidEnumTag", "value", &__self_0),
ValidationErrorKind::UninhabitedEnumVariant =>
::core::fmt::Formatter::write_str(f,
"UninhabitedEnumVariant"),
ValidationErrorKind::Uninit { expected: __self_0 } =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"Uninit", "expected", &__self_0),
ValidationErrorKind::InvalidVTablePtr { value: __self_0 } =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"InvalidVTablePtr", "value", &__self_0),
ValidationErrorKind::InvalidMetaWrongTrait {
vtable_dyn_type: __self_0, expected_dyn_type: __self_1 } =>
::core::fmt::Formatter::debug_struct_field2_finish(f,
"InvalidMetaWrongTrait", "vtable_dyn_type", __self_0,
"expected_dyn_type", &__self_1),
ValidationErrorKind::InvalidMetaSliceTooLarge { ptr_kind: __self_0
} =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"InvalidMetaSliceTooLarge", "ptr_kind", &__self_0),
ValidationErrorKind::InvalidMetaTooLarge { ptr_kind: __self_0 } =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"InvalidMetaTooLarge", "ptr_kind", &__self_0),
ValidationErrorKind::UnalignedPtr {
ptr_kind: __self_0,
required_bytes: __self_1,
found_bytes: __self_2 } =>
::core::fmt::Formatter::debug_struct_field3_finish(f,
"UnalignedPtr", "ptr_kind", __self_0, "required_bytes",
__self_1, "found_bytes", &__self_2),
ValidationErrorKind::NullPtr { ptr_kind: __self_0, maybe: __self_1
} =>
::core::fmt::Formatter::debug_struct_field2_finish(f,
"NullPtr", "ptr_kind", __self_0, "maybe", &__self_1),
ValidationErrorKind::DanglingPtrNoProvenance {
ptr_kind: __self_0, pointer: __self_1 } =>
::core::fmt::Formatter::debug_struct_field2_finish(f,
"DanglingPtrNoProvenance", "ptr_kind", __self_0, "pointer",
&__self_1),
ValidationErrorKind::DanglingPtrOutOfBounds { ptr_kind: __self_0 }
=>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"DanglingPtrOutOfBounds", "ptr_kind", &__self_0),
ValidationErrorKind::DanglingPtrUseAfterFree { ptr_kind: __self_0
} =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"DanglingPtrUseAfterFree", "ptr_kind", &__self_0),
ValidationErrorKind::InvalidBool { value: __self_0 } =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"InvalidBool", "value", &__self_0),
ValidationErrorKind::InvalidChar { value: __self_0 } =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"InvalidChar", "value", &__self_0),
ValidationErrorKind::InvalidFnPtr { value: __self_0 } =>
::core::fmt::Formatter::debug_struct_field1_finish(f,
"InvalidFnPtr", "value", &__self_0),
}
}
}Debug)]
498pub enum ValidationErrorKind<'tcx> {
499 PointerAsInt {
500 expected: ExpectedKind,
501 },
502 PartialPointer,
503 PtrToUninhabited {
504 ptr_kind: PointerKind,
505 ty: Ty<'tcx>,
506 },
507 MutableRefToImmutable,
508 UnsafeCellInImmutable,
509 NullFnPtr {
510 maybe: bool,
512 },
513 NeverVal,
514 NonnullPtrMaybeNull,
515 PtrOutOfRange {
516 range: WrappingRange,
517 max_value: u128,
518 },
519 OutOfRange {
520 value: String,
521 range: WrappingRange,
522 max_value: u128,
523 },
524 UninhabitedVal {
525 ty: Ty<'tcx>,
526 },
527 InvalidEnumTag {
528 value: String,
529 },
530 UninhabitedEnumVariant,
531 Uninit {
532 expected: ExpectedKind,
533 },
534 InvalidVTablePtr {
535 value: String,
536 },
537 InvalidMetaWrongTrait {
538 vtable_dyn_type: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
540 expected_dyn_type: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
542 },
543 InvalidMetaSliceTooLarge {
544 ptr_kind: PointerKind,
545 },
546 InvalidMetaTooLarge {
547 ptr_kind: PointerKind,
548 },
549 UnalignedPtr {
550 ptr_kind: PointerKind,
551 required_bytes: u64,
552 found_bytes: u64,
553 },
554 NullPtr {
555 ptr_kind: PointerKind,
556 maybe: bool,
558 },
559 DanglingPtrNoProvenance {
560 ptr_kind: PointerKind,
561 pointer: String,
562 },
563 DanglingPtrOutOfBounds {
564 ptr_kind: PointerKind,
565 },
566 DanglingPtrUseAfterFree {
567 ptr_kind: PointerKind,
568 },
569 InvalidBool {
570 value: String,
571 },
572 InvalidChar {
573 value: String,
574 },
575 InvalidFnPtr {
576 value: String,
577 },
578}
579
580#[derive(#[automatically_derived]
impl ::core::fmt::Debug for UnsupportedOpInfo {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
UnsupportedOpInfo::Unsupported(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"Unsupported", &__self_0),
UnsupportedOpInfo::UnsizedLocal =>
::core::fmt::Formatter::write_str(f, "UnsizedLocal"),
UnsupportedOpInfo::ExternTypeField =>
::core::fmt::Formatter::write_str(f, "ExternTypeField"),
UnsupportedOpInfo::ReadPartialPointer(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"ReadPartialPointer", &__self_0),
UnsupportedOpInfo::ReadPointerAsInt(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"ReadPointerAsInt", &__self_0),
UnsupportedOpInfo::ThreadLocalStatic(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"ThreadLocalStatic", &__self_0),
UnsupportedOpInfo::ExternStatic(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"ExternStatic", &__self_0),
}
}
}Debug)]
585pub enum UnsupportedOpInfo {
586 Unsupported(String),
589 UnsizedLocal,
591 ExternTypeField,
593 ReadPartialPointer(Pointer<AllocId>),
599 ReadPointerAsInt(Option<(AllocId, BadBytesAccess)>),
601 ThreadLocalStatic(DefId),
603 ExternStatic(DefId),
605}
606
607#[derive(#[automatically_derived]
impl ::core::fmt::Debug for ResourceExhaustionInfo {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
ResourceExhaustionInfo::StackFrameLimitReached =>
"StackFrameLimitReached",
ResourceExhaustionInfo::MemoryExhausted => "MemoryExhausted",
ResourceExhaustionInfo::AddressSpaceFull =>
"AddressSpaceFull",
ResourceExhaustionInfo::Interrupted => "Interrupted",
})
}
}Debug)]
610pub enum ResourceExhaustionInfo {
611 StackFrameLimitReached,
613 MemoryExhausted,
615 AddressSpaceFull,
617 Interrupted,
619}
620
621pub trait MachineStopType: Any + fmt::Debug + Send {
623 fn diagnostic_message(&self) -> DiagMessage;
625 fn add_args(self: Box<Self>, adder: &mut dyn FnMut(DiagArgName, DiagArgValue));
628}
629
630impl dyn MachineStopType {
631 #[inline(always)]
632 pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
633 let x: &dyn Any = self;
634 x.downcast_ref()
635 }
636}
637
638#[derive(#[automatically_derived]
impl<'tcx> ::core::fmt::Debug for InterpErrorKind<'tcx> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
InterpErrorKind::UndefinedBehavior(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"UndefinedBehavior", &__self_0),
InterpErrorKind::Unsupported(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"Unsupported", &__self_0),
InterpErrorKind::InvalidProgram(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"InvalidProgram", &__self_0),
InterpErrorKind::ResourceExhaustion(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"ResourceExhaustion", &__self_0),
InterpErrorKind::MachineStop(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"MachineStop", &__self_0),
}
}
}Debug)]
639pub enum InterpErrorKind<'tcx> {
640 UndefinedBehavior(UndefinedBehaviorInfo<'tcx>),
642 Unsupported(UnsupportedOpInfo),
645 InvalidProgram(InvalidProgramInfo<'tcx>),
647 ResourceExhaustion(ResourceExhaustionInfo),
650 MachineStop(Box<dyn MachineStopType>),
653}
654
655impl InterpErrorKind<'_> {
656 pub fn formatted_string(&self) -> bool {
660 #[allow(non_exhaustive_omitted_patterns)] match self {
InterpErrorKind::Unsupported(UnsupportedOpInfo::Unsupported(_)) |
InterpErrorKind::UndefinedBehavior(UndefinedBehaviorInfo::ValidationError {
.. }) |
InterpErrorKind::UndefinedBehavior(UndefinedBehaviorInfo::Ub(_)) =>
true,
_ => false,
}matches!(
661 self,
662 InterpErrorKind::Unsupported(UnsupportedOpInfo::Unsupported(_))
663 | InterpErrorKind::UndefinedBehavior(UndefinedBehaviorInfo::ValidationError { .. })
664 | InterpErrorKind::UndefinedBehavior(UndefinedBehaviorInfo::Ub(_))
665 )
666 }
667}
668
669#[macro_export]
671macro_rules! err_unsup {
672 ($($tt:tt)*) => {
673 $crate::mir::interpret::InterpErrorKind::Unsupported(
674 $crate::mir::interpret::UnsupportedOpInfo::$($tt)*
675 )
676 };
677}
678
679#[macro_export]
680macro_rules! err_unsup_format {
681 ($($tt:tt)*) => { $crate::err_unsup!(Unsupported(format!($($tt)*))) };
682}
683
684#[macro_export]
685macro_rules! err_inval {
686 ($($tt:tt)*) => {
687 $crate::mir::interpret::InterpErrorKind::InvalidProgram(
688 $crate::mir::interpret::InvalidProgramInfo::$($tt)*
689 )
690 };
691}
692
693#[macro_export]
694macro_rules! err_ub {
695 ($($tt:tt)*) => {
696 $crate::mir::interpret::InterpErrorKind::UndefinedBehavior(
697 $crate::mir::interpret::UndefinedBehaviorInfo::$($tt)*
698 )
699 };
700}
701
702#[macro_export]
703macro_rules! err_ub_format {
704 ($($tt:tt)*) => { $crate::err_ub!(Ub(format!($($tt)*))) };
705}
706
707#[macro_export]
708macro_rules! err_ub_custom {
709 ($msg:expr $(, $($name:ident = $value:expr),* $(,)?)?) => {{
710 $(
711 let ($($name,)*) = ($($value,)*);
712 )?
713 $crate::err_ub!(Custom(
714 $crate::error::CustomSubdiagnostic {
715 msg: || $msg,
716 add_args: Box::new(move |mut set_arg| {
717 $($(
718 set_arg(stringify!($name).into(), rustc_errors::IntoDiagArg::into_diag_arg($name, &mut None));
719 )*)?
720 })
721 }
722 ))
723 }};
724}
725
726#[macro_export]
727macro_rules! err_exhaust {
728 ($($tt:tt)*) => {
729 $crate::mir::interpret::InterpErrorKind::ResourceExhaustion(
730 $crate::mir::interpret::ResourceExhaustionInfo::$($tt)*
731 )
732 };
733}
734
735#[macro_export]
736macro_rules! err_machine_stop {
737 ($($tt:tt)*) => {
738 $crate::mir::interpret::InterpErrorKind::MachineStop(Box::new($($tt)*))
739 };
740}
741
742#[macro_export]
744macro_rules! throw_unsup {
745 ($($tt:tt)*) => { do yeet $crate::err_unsup!($($tt)*) };
746}
747
748#[macro_export]
749macro_rules! throw_unsup_format {
750 ($($tt:tt)*) => { do yeet $crate::err_unsup_format!($($tt)*) };
751}
752
753#[macro_export]
754macro_rules! throw_inval {
755 ($($tt:tt)*) => { do yeet $crate::err_inval!($($tt)*) };
756}
757
758#[macro_export]
759macro_rules! throw_ub {
760 ($($tt:tt)*) => { do yeet $crate::err_ub!($($tt)*) };
761}
762
763#[macro_export]
764macro_rules! throw_ub_format {
765 ($($tt:tt)*) => { do yeet $crate::err_ub_format!($($tt)*) };
766}
767
768#[macro_export]
769macro_rules! throw_ub_custom {
770 ($($tt:tt)*) => { do yeet $crate::err_ub_custom!($($tt)*) };
771}
772
773#[macro_export]
774macro_rules! throw_exhaust {
775 ($($tt:tt)*) => { do yeet $crate::err_exhaust!($($tt)*) };
776}
777
778#[macro_export]
779macro_rules! throw_machine_stop {
780 ($($tt:tt)*) => { do yeet $crate::err_machine_stop!($($tt)*) };
781}
782
783#[derive(#[automatically_derived]
impl ::core::fmt::Debug for Guard {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f, "Guard")
}
}Debug)]
785struct Guard;
786
787impl Drop for Guard {
788 fn drop(&mut self) {
789 if !std::thread::panicking() {
791 {
::core::panicking::panic_fmt(format_args!("an interpreter error got improperly discarded; use `discard_err()` if this is intentional"));
};panic!(
792 "an interpreter error got improperly discarded; use `discard_err()` if this is intentional"
793 );
794 }
795 }
796}
797
798#[derive(#[automatically_derived]
impl<'tcx, T: ::core::fmt::Debug> ::core::fmt::Debug for InterpResult<'tcx, T>
{
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f, "InterpResult",
"res", &self.res, "guard", &&self.guard)
}
}Debug)]
803#[must_use]
804pub struct InterpResult<'tcx, T = ()> {
805 res: Result<T, InterpErrorInfo<'tcx>>,
806 guard: Guard,
807}
808
809impl<'tcx, T> ops::Try for InterpResult<'tcx, T> {
810 type Output = T;
811 type Residual = InterpResult<'tcx, convert::Infallible>;
812
813 #[inline]
814 fn from_output(output: Self::Output) -> Self {
815 InterpResult::new(Ok(output))
816 }
817
818 #[inline]
819 fn branch(self) -> ops::ControlFlow<Self::Residual, Self::Output> {
820 match self.disarm() {
821 Ok(v) => ops::ControlFlow::Continue(v),
822 Err(e) => ops::ControlFlow::Break(InterpResult::new(Err(e))),
823 }
824 }
825}
826
827impl<'tcx, T> ops::Residual<T> for InterpResult<'tcx, convert::Infallible> {
828 type TryType = InterpResult<'tcx, T>;
829}
830
831impl<'tcx, T> ops::FromResidual for InterpResult<'tcx, T> {
832 #[inline]
833 #[track_caller]
834 fn from_residual(residual: InterpResult<'tcx, convert::Infallible>) -> Self {
835 match residual.disarm() {
836 Err(e) => Self::new(Err(e)),
837 }
838 }
839}
840
841impl<'tcx, T> ops::FromResidual<ops::Yeet<InterpErrorKind<'tcx>>> for InterpResult<'tcx, T> {
843 #[inline]
844 fn from_residual(ops::Yeet(e): ops::Yeet<InterpErrorKind<'tcx>>) -> Self {
845 Self::new(Err(e.into()))
846 }
847}
848
849impl<'tcx, T, E: Into<InterpErrorInfo<'tcx>>> ops::FromResidual<Result<convert::Infallible, E>>
852 for InterpResult<'tcx, T>
853{
854 #[inline]
855 fn from_residual(residual: Result<convert::Infallible, E>) -> Self {
856 match residual {
857 Err(e) => Self::new(Err(e.into())),
858 }
859 }
860}
861
862impl<'tcx, T, E: Into<InterpErrorInfo<'tcx>>> From<Result<T, E>> for InterpResult<'tcx, T> {
863 #[inline]
864 fn from(value: Result<T, E>) -> Self {
865 Self::new(value.map_err(|e| e.into()))
866 }
867}
868
869impl<'tcx, T, V: FromIterator<T>> FromIterator<InterpResult<'tcx, T>> for InterpResult<'tcx, V> {
870 fn from_iter<I: IntoIterator<Item = InterpResult<'tcx, T>>>(iter: I) -> Self {
871 Self::new(iter.into_iter().map(|x| x.disarm()).collect())
872 }
873}
874
875impl<'tcx, T> InterpResult<'tcx, T> {
876 #[inline(always)]
877 fn new(res: Result<T, InterpErrorInfo<'tcx>>) -> Self {
878 Self { res, guard: Guard }
879 }
880
881 #[inline(always)]
882 fn disarm(self) -> Result<T, InterpErrorInfo<'tcx>> {
883 mem::forget(self.guard);
884 self.res
885 }
886
887 #[inline]
889 pub fn discard_err(self) -> Option<T> {
890 self.disarm().ok()
891 }
892
893 #[inline]
896 pub fn report_err(self) -> Result<T, InterpErrorInfo<'tcx>> {
897 self.disarm()
898 }
899
900 #[inline]
901 pub fn map<U>(self, f: impl FnOnce(T) -> U) -> InterpResult<'tcx, U> {
902 InterpResult::new(self.disarm().map(f))
903 }
904
905 #[inline]
906 pub fn map_err_info(
907 self,
908 f: impl FnOnce(InterpErrorInfo<'tcx>) -> InterpErrorInfo<'tcx>,
909 ) -> InterpResult<'tcx, T> {
910 InterpResult::new(self.disarm().map_err(f))
911 }
912
913 #[inline]
914 pub fn map_err_kind(
915 self,
916 f: impl FnOnce(InterpErrorKind<'tcx>) -> InterpErrorKind<'tcx>,
917 ) -> InterpResult<'tcx, T> {
918 InterpResult::new(self.disarm().map_err(|mut e| {
919 e.0.kind = f(e.0.kind);
920 e
921 }))
922 }
923
924 #[inline]
925 pub fn inspect_err_kind(self, f: impl FnOnce(&InterpErrorKind<'tcx>)) -> InterpResult<'tcx, T> {
926 InterpResult::new(self.disarm().inspect_err(|e| f(&e.0.kind)))
927 }
928
929 #[inline]
930 #[track_caller]
931 pub fn unwrap(self) -> T {
932 self.disarm().unwrap()
933 }
934
935 #[inline]
936 #[track_caller]
937 pub fn unwrap_or_else(self, f: impl FnOnce(InterpErrorInfo<'tcx>) -> T) -> T {
938 self.disarm().unwrap_or_else(f)
939 }
940
941 #[inline]
942 #[track_caller]
943 pub fn expect(self, msg: &str) -> T {
944 self.disarm().expect(msg)
945 }
946
947 #[inline]
948 pub fn and_then<U>(self, f: impl FnOnce(T) -> InterpResult<'tcx, U>) -> InterpResult<'tcx, U> {
949 InterpResult::new(self.disarm().and_then(|t| f(t).disarm()))
950 }
951
952 #[inline]
957 pub fn and<U>(self, other: InterpResult<'tcx, U>) -> InterpResult<'tcx, (T, U)> {
958 match self.disarm() {
959 Ok(t) => interp_ok((t, other?)),
960 Err(e) => {
961 drop(other.disarm());
963 InterpResult::new(Err(e))
965 }
966 }
967 }
968}
969
970#[inline(always)]
971pub fn interp_ok<'tcx, T>(x: T) -> InterpResult<'tcx, T> {
972 InterpResult::new(Ok(x))
973}