Skip to main content

rustc_const_eval/
errors.rs

1use std::borrow::Cow;
2use std::fmt::Write;
3
4use either::Either;
5use rustc_abi::WrappingRange;
6use rustc_errors::codes::*;
7use rustc_errors::{
8    Diag, DiagArgValue, DiagMessage, Diagnostic, EmissionGuarantee, Level, MultiSpan,
9    Subdiagnostic, msg,
10};
11use rustc_hir::ConstContext;
12use rustc_macros::{Diagnostic, Subdiagnostic};
13use rustc_middle::mir::interpret::{
14    CtfeProvenance, ExpectedKind, InterpErrorKind, InvalidMetaKind, InvalidProgramInfo,
15    Misalignment, Pointer, PointerKind, ResourceExhaustionInfo, UndefinedBehaviorInfo,
16    UnsupportedOpInfo, ValidationErrorInfo,
17};
18use rustc_middle::ty::{self, Mutability, Ty};
19use rustc_span::{Span, Symbol};
20
21use crate::interpret::InternKind;
22
23#[derive(const _: () =
    {
        impl<'_sess, G> rustc_errors::Diagnostic<'_sess, G> for
            DanglingPtrInFinal where G: rustc_errors::EmissionGuarantee {
            #[track_caller]
            fn into_diag(self, dcx: rustc_errors::DiagCtxtHandle<'_sess>,
                level: rustc_errors::Level) -> rustc_errors::Diag<'_sess, G> {
                match self {
                    DanglingPtrInFinal { span: __binding_0, kind: __binding_1 }
                        => {
                        let mut diag =
                            rustc_errors::Diag::new(dcx, level,
                                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("encountered dangling pointer in final value of {$kind ->\n    [static] static\n    [static_mut] mutable static\n    [const] constant\n    [promoted] promoted\n    *[other] {\"\"}\n}")));
                        ;
                        diag.arg("kind", __binding_1);
                        diag.span(__binding_0);
                        diag
                    }
                }
            }
        }
    };Diagnostic)]
24#[diag(
25    r#"encountered dangling pointer in final value of {$kind ->
26    [static] static
27    [static_mut] mutable static
28    [const] constant
29    [promoted] promoted
30    *[other] {""}
31}"#
32)]
33pub(crate) struct DanglingPtrInFinal {
34    #[primary_span]
35    pub span: Span,
36    pub kind: InternKind,
37}
38
39#[derive(const _: () =
    {
        impl<'_sess, G> rustc_errors::Diagnostic<'_sess, G> for
            NestedStaticInThreadLocal where G: rustc_errors::EmissionGuarantee
            {
            #[track_caller]
            fn into_diag(self, dcx: rustc_errors::DiagCtxtHandle<'_sess>,
                level: rustc_errors::Level) -> rustc_errors::Diag<'_sess, G> {
                match self {
                    NestedStaticInThreadLocal { span: __binding_0 } => {
                        let mut diag =
                            rustc_errors::Diag::new(dcx, level,
                                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("#[thread_local] does not support implicit nested statics, please create explicit static items and refer to them instead")));
                        ;
                        diag.span(__binding_0);
                        diag
                    }
                }
            }
        }
    };Diagnostic)]
40#[diag(
41    "#[thread_local] does not support implicit nested statics, please create explicit static items and refer to them instead"
42)]
43pub(crate) struct NestedStaticInThreadLocal {
44    #[primary_span]
45    pub span: Span,
46}
47
48#[derive(const _: () =
    {
        impl<'_sess, G> rustc_errors::Diagnostic<'_sess, G> for
            MutablePtrInFinal where G: rustc_errors::EmissionGuarantee {
            #[track_caller]
            fn into_diag(self, dcx: rustc_errors::DiagCtxtHandle<'_sess>,
                level: rustc_errors::Level) -> rustc_errors::Diag<'_sess, G> {
                match self {
                    MutablePtrInFinal { span: __binding_0, kind: __binding_1 }
                        => {
                        let mut diag =
                            rustc_errors::Diag::new(dcx, level,
                                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("encountered mutable pointer in final value of {$kind ->\n    [static] static\n    [static_mut] mutable static\n    [const] constant\n    [promoted] promoted\n    *[other] {\"\"}\n}")));
                        ;
                        diag.arg("kind", __binding_1);
                        diag.span(__binding_0);
                        diag
                    }
                }
            }
        }
    };Diagnostic)]
49#[diag(
50    r#"encountered mutable pointer in final value of {$kind ->
51    [static] static
52    [static_mut] mutable static
53    [const] constant
54    [promoted] promoted
55    *[other] {""}
56}"#
57)]
58pub(crate) struct MutablePtrInFinal {
59    #[primary_span]
60    pub span: Span,
61    pub kind: InternKind,
62}
63
64#[derive(const _: () =
    {
        impl<'_sess, G> rustc_errors::Diagnostic<'_sess, G> for
            ConstHeapPtrInFinal where G: rustc_errors::EmissionGuarantee {
            #[track_caller]
            fn into_diag(self, dcx: rustc_errors::DiagCtxtHandle<'_sess>,
                level: rustc_errors::Level) -> rustc_errors::Diag<'_sess, G> {
                match self {
                    ConstHeapPtrInFinal { span: __binding_0 } => {
                        let mut diag =
                            rustc_errors::Diag::new(dcx, level,
                                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("encountered `const_allocate` pointer in final value that was not made global")));
                        diag.note(rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("use `const_make_global` to turn allocated pointers into immutable globals before returning")));
                        ;
                        diag.span(__binding_0);
                        diag
                    }
                }
            }
        }
    };Diagnostic)]
65#[diag("encountered `const_allocate` pointer in final value that was not made global")]
66#[note(
67    "use `const_make_global` to turn allocated pointers into immutable globals before returning"
68)]
69pub(crate) struct ConstHeapPtrInFinal {
70    #[primary_span]
71    pub span: Span,
72}
73
74#[derive(const _: () =
    {
        impl<'_sess, G> rustc_errors::Diagnostic<'_sess, G> for
            PartialPtrInFinal where G: rustc_errors::EmissionGuarantee {
            #[track_caller]
            fn into_diag(self, dcx: rustc_errors::DiagCtxtHandle<'_sess>,
                level: rustc_errors::Level) -> rustc_errors::Diag<'_sess, G> {
                match self {
                    PartialPtrInFinal { span: __binding_0, kind: __binding_1 }
                        => {
                        let mut diag =
                            rustc_errors::Diag::new(dcx, level,
                                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("encountered partial pointer in final value of {$kind ->\n    [static] static\n    [static_mut] mutable static\n    [const] constant\n    [promoted] promoted\n    *[other] {\"\"}\n}")));
                        diag.note(rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("while pointers can be broken apart into individual bytes during const-evaluation, only complete pointers (with all their bytes in the right order) are supported in the final value")));
                        ;
                        diag.arg("kind", __binding_1);
                        diag.span(__binding_0);
                        diag
                    }
                }
            }
        }
    };Diagnostic)]
75#[diag(
76    r#"encountered partial pointer in final value of {$kind ->
77    [static] static
78    [static_mut] mutable static
79    [const] constant
80    [promoted] promoted
81    *[other] {""}
82}"#
83)]
84#[note(
85    "while pointers can be broken apart into individual bytes during const-evaluation, only complete pointers (with all their bytes in the right order) are supported in the final value"
86)]
87pub(crate) struct PartialPtrInFinal {
88    #[primary_span]
89    pub span: Span,
90    pub kind: InternKind,
91}
92
93#[derive(const _: () =
    {
        impl<'_sess, G> rustc_errors::Diagnostic<'_sess, G> for
            UnstableInStableExposed where G: rustc_errors::EmissionGuarantee {
            #[track_caller]
            fn into_diag(self, dcx: rustc_errors::DiagCtxtHandle<'_sess>,
                level: rustc_errors::Level) -> rustc_errors::Diag<'_sess, G> {
                match self {
                    UnstableInStableExposed {
                        gate: __binding_0,
                        span: __binding_1,
                        is_function_call: __binding_2,
                        is_function_call2: __binding_3,
                        attr_span: __binding_4 } => {
                        let mut diag =
                            rustc_errors::Diag::new(dcx, level,
                                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("const function that might be (indirectly) exposed to stable cannot use `#[feature({$gate})]`")));
                        let __code_0 =
                            [::alloc::__export::must_use({
                                                ::alloc::fmt::format(format_args!("#[rustc_const_unstable(feature = \"...\", issue = \"...\")]\n"))
                                            })].into_iter();
                        ;
                        diag.arg("gate", __binding_0);
                        diag.arg("is_function_call2", __binding_3);
                        diag.span(__binding_1);
                        if __binding_2 {
                            diag.help(rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("mark the callee as `#[rustc_const_stable_indirect]` if it does not itself require any unstable features")));
                        }
                        diag.span_suggestions_with_style(__binding_4,
                            rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("if the {$is_function_call2 ->\n            [true] caller\n            *[false] function\n        } is not (yet) meant to be exposed to stable const contexts, add `#[rustc_const_unstable]`")),
                            __code_0, rustc_errors::Applicability::HasPlaceholders,
                            rustc_errors::SuggestionStyle::ShowCode);
                        diag
                    }
                }
            }
        }
    };Diagnostic)]
94#[diag(
95    "const function that might be (indirectly) exposed to stable cannot use `#[feature({$gate})]`"
96)]
97pub(crate) struct UnstableInStableExposed {
98    pub gate: String,
99    #[primary_span]
100    pub span: Span,
101    #[help(
102        "mark the callee as `#[rustc_const_stable_indirect]` if it does not itself require any unstable features"
103    )]
104    pub is_function_call: bool,
105    /// Need to duplicate the field so that fluent also provides it as a variable...
106    pub is_function_call2: bool,
107    #[suggestion(
108        "if the {$is_function_call2 ->
109            [true] caller
110            *[false] function
111        } is not (yet) meant to be exposed to stable const contexts, add `#[rustc_const_unstable]`",
112        code = "#[rustc_const_unstable(feature = \"...\", issue = \"...\")]\n",
113        applicability = "has-placeholders"
114    )]
115    pub attr_span: Span,
116}
117
118#[derive(const _: () =
    {
        impl<'_sess, G> rustc_errors::Diagnostic<'_sess, G> for
            ThreadLocalAccessErr where G: rustc_errors::EmissionGuarantee {
            #[track_caller]
            fn into_diag(self, dcx: rustc_errors::DiagCtxtHandle<'_sess>,
                level: rustc_errors::Level) -> rustc_errors::Diag<'_sess, G> {
                match self {
                    ThreadLocalAccessErr { span: __binding_0 } => {
                        let mut diag =
                            rustc_errors::Diag::new(dcx, level,
                                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("thread-local statics cannot be accessed at compile-time")));
                        diag.code(E0625);
                        ;
                        diag.span(__binding_0);
                        diag
                    }
                }
            }
        }
    };Diagnostic)]
119#[diag("thread-local statics cannot be accessed at compile-time", code = E0625)]
120pub(crate) struct ThreadLocalAccessErr {
121    #[primary_span]
122    pub span: Span,
123}
124
125#[derive(const _: () =
    {
        impl<'_sess, G> rustc_errors::Diagnostic<'_sess, G> for RawPtrToIntErr
            where G: rustc_errors::EmissionGuarantee {
            #[track_caller]
            fn into_diag(self, dcx: rustc_errors::DiagCtxtHandle<'_sess>,
                level: rustc_errors::Level) -> rustc_errors::Diag<'_sess, G> {
                match self {
                    RawPtrToIntErr { span: __binding_0 } => {
                        let mut diag =
                            rustc_errors::Diag::new(dcx, level,
                                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("pointers cannot be cast to integers during const eval")));
                        diag.note(rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("at compile-time, pointers do not have an integer value")));
                        diag.note(rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("avoiding this restriction via `transmute`, `union`, or raw pointers leads to compile-time undefined behavior")));
                        ;
                        diag.span(__binding_0);
                        diag
                    }
                }
            }
        }
    };Diagnostic)]
126#[diag("pointers cannot be cast to integers during const eval")]
127#[note("at compile-time, pointers do not have an integer value")]
128#[note(
129    "avoiding this restriction via `transmute`, `union`, or raw pointers leads to compile-time undefined behavior"
130)]
131pub(crate) struct RawPtrToIntErr {
132    #[primary_span]
133    pub span: Span,
134}
135
136#[derive(const _: () =
    {
        impl<'_sess, G> rustc_errors::Diagnostic<'_sess, G> for
            RawPtrComparisonErr where G: rustc_errors::EmissionGuarantee {
            #[track_caller]
            fn into_diag(self, dcx: rustc_errors::DiagCtxtHandle<'_sess>,
                level: rustc_errors::Level) -> rustc_errors::Diag<'_sess, G> {
                match self {
                    RawPtrComparisonErr { span: __binding_0 } => {
                        let mut diag =
                            rustc_errors::Diag::new(dcx, level,
                                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("pointers cannot be reliably compared during const eval")));
                        diag.note(rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("see issue #53020 <https://github.com/rust-lang/rust/issues/53020> for more information")));
                        ;
                        diag.span(__binding_0);
                        diag
                    }
                }
            }
        }
    };Diagnostic)]
137#[diag("pointers cannot be reliably compared during const eval")]
138#[note("see issue #53020 <https://github.com/rust-lang/rust/issues/53020> for more information")]
139pub(crate) struct RawPtrComparisonErr {
140    #[primary_span]
141    pub span: Span,
142}
143
144#[derive(const _: () =
    {
        impl<'_sess, G> rustc_errors::Diagnostic<'_sess, G> for PanicNonStrErr
            where G: rustc_errors::EmissionGuarantee {
            #[track_caller]
            fn into_diag(self, dcx: rustc_errors::DiagCtxtHandle<'_sess>,
                level: rustc_errors::Level) -> rustc_errors::Diag<'_sess, G> {
                match self {
                    PanicNonStrErr { span: __binding_0 } => {
                        let mut diag =
                            rustc_errors::Diag::new(dcx, level,
                                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("argument to `panic!()` in a const context must have type `&str`")));
                        ;
                        diag.span(__binding_0);
                        diag
                    }
                }
            }
        }
    };Diagnostic)]
145#[diag("argument to `panic!()` in a const context must have type `&str`")]
146pub(crate) struct PanicNonStrErr {
147    #[primary_span]
148    pub span: Span,
149}
150
151#[derive(const _: () =
    {
        impl<'_sess, G> rustc_errors::Diagnostic<'_sess, G> for
            UnallowedFnPointerCall where G: rustc_errors::EmissionGuarantee {
            #[track_caller]
            fn into_diag(self, dcx: rustc_errors::DiagCtxtHandle<'_sess>,
                level: rustc_errors::Level) -> rustc_errors::Diag<'_sess, G> {
                match self {
                    UnallowedFnPointerCall {
                        span: __binding_0, kind: __binding_1 } => {
                        let mut diag =
                            rustc_errors::Diag::new(dcx, level,
                                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("function pointer calls are not allowed in {$kind ->\n    [const] constant\n    [static] static\n    [const_fn] constant function\n    *[other] {\"\"}\n}s")));
                        ;
                        diag.arg("kind", __binding_1);
                        diag.span(__binding_0);
                        diag
                    }
                }
            }
        }
    };Diagnostic)]
152#[diag(
153    r#"function pointer calls are not allowed in {$kind ->
154    [const] constant
155    [static] static
156    [const_fn] constant function
157    *[other] {""}
158}s"#
159)]
160pub(crate) struct UnallowedFnPointerCall {
161    #[primary_span]
162    pub span: Span,
163    pub kind: ConstContext,
164}
165
166#[derive(const _: () =
    {
        impl<'_sess, G> rustc_errors::Diagnostic<'_sess, G> for
            UnstableConstFn where G: rustc_errors::EmissionGuarantee {
            #[track_caller]
            fn into_diag(self, dcx: rustc_errors::DiagCtxtHandle<'_sess>,
                level: rustc_errors::Level) -> rustc_errors::Diag<'_sess, G> {
                match self {
                    UnstableConstFn { span: __binding_0, def_path: __binding_1 }
                        => {
                        let mut diag =
                            rustc_errors::Diag::new(dcx, level,
                                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("`{$def_path}` is not yet stable as a const fn")));
                        ;
                        diag.arg("def_path", __binding_1);
                        diag.span(__binding_0);
                        diag
                    }
                }
            }
        }
    };Diagnostic)]
167#[diag("`{$def_path}` is not yet stable as a const fn")]
168pub(crate) struct UnstableConstFn {
169    #[primary_span]
170    pub span: Span,
171    pub def_path: String,
172}
173
174#[derive(const _: () =
    {
        impl<'_sess, G> rustc_errors::Diagnostic<'_sess, G> for
            UnstableConstTrait where G: rustc_errors::EmissionGuarantee {
            #[track_caller]
            fn into_diag(self, dcx: rustc_errors::DiagCtxtHandle<'_sess>,
                level: rustc_errors::Level) -> rustc_errors::Diag<'_sess, G> {
                match self {
                    UnstableConstTrait {
                        span: __binding_0, def_path: __binding_1 } => {
                        let mut diag =
                            rustc_errors::Diag::new(dcx, level,
                                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("`{$def_path}` is not yet stable as a const trait")));
                        ;
                        diag.arg("def_path", __binding_1);
                        diag.span(__binding_0);
                        diag
                    }
                }
            }
        }
    };Diagnostic)]
175#[diag("`{$def_path}` is not yet stable as a const trait")]
176pub(crate) struct UnstableConstTrait {
177    #[primary_span]
178    pub span: Span,
179    pub def_path: String,
180}
181
182#[derive(const _: () =
    {
        impl<'_sess, G> rustc_errors::Diagnostic<'_sess, G> for
            UnstableIntrinsic where G: rustc_errors::EmissionGuarantee {
            #[track_caller]
            fn into_diag(self, dcx: rustc_errors::DiagCtxtHandle<'_sess>,
                level: rustc_errors::Level) -> rustc_errors::Diag<'_sess, G> {
                match self {
                    UnstableIntrinsic {
                        span: __binding_0,
                        name: __binding_1,
                        feature: __binding_2,
                        suggestion: __binding_3 } => {
                        let mut diag =
                            rustc_errors::Diag::new(dcx, level,
                                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("`{$name}` is not yet stable as a const intrinsic")));
                        let __code_1 =
                            [::alloc::__export::must_use({
                                                ::alloc::fmt::format(format_args!("#![feature({0})]\n",
                                                        __binding_2))
                                            })].into_iter();
                        ;
                        diag.arg("name", __binding_1);
                        diag.arg("feature", __binding_2);
                        diag.span(__binding_0);
                        diag.span_suggestions_with_style(__binding_3,
                            rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("add `#![feature({$feature})]` to the crate attributes to enable")),
                            __code_1, rustc_errors::Applicability::MachineApplicable,
                            rustc_errors::SuggestionStyle::ShowCode);
                        diag
                    }
                }
            }
        }
    };Diagnostic)]
183#[diag("`{$name}` is not yet stable as a const intrinsic")]
184pub(crate) struct UnstableIntrinsic {
185    #[primary_span]
186    pub span: Span,
187    pub name: Symbol,
188    pub feature: Symbol,
189    #[suggestion(
190        "add `#![feature({$feature})]` to the crate attributes to enable",
191        code = "#![feature({feature})]\n",
192        applicability = "machine-applicable"
193    )]
194    pub suggestion: Span,
195}
196
197#[derive(const _: () =
    {
        impl<'_sess, G> rustc_errors::Diagnostic<'_sess, G> for
            UnmarkedConstItemExposed where G: rustc_errors::EmissionGuarantee
            {
            #[track_caller]
            fn into_diag(self, dcx: rustc_errors::DiagCtxtHandle<'_sess>,
                level: rustc_errors::Level) -> rustc_errors::Diag<'_sess, G> {
                match self {
                    UnmarkedConstItemExposed {
                        span: __binding_0, def_path: __binding_1 } => {
                        let mut diag =
                            rustc_errors::Diag::new(dcx, level,
                                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("`{$def_path}` cannot be (indirectly) exposed to stable")));
                        diag.help(rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("either mark the callee as `#[rustc_const_stable_indirect]`, or the caller as `#[rustc_const_unstable]`")));
                        ;
                        diag.arg("def_path", __binding_1);
                        diag.span(__binding_0);
                        diag
                    }
                }
            }
        }
    };Diagnostic)]
198#[diag("`{$def_path}` cannot be (indirectly) exposed to stable")]
199#[help(
200    "either mark the callee as `#[rustc_const_stable_indirect]`, or the caller as `#[rustc_const_unstable]`"
201)]
202pub(crate) struct UnmarkedConstItemExposed {
203    #[primary_span]
204    pub span: Span,
205    pub def_path: String,
206}
207
208#[derive(const _: () =
    {
        impl<'_sess, G> rustc_errors::Diagnostic<'_sess, G> for
            UnmarkedIntrinsicExposed where G: rustc_errors::EmissionGuarantee
            {
            #[track_caller]
            fn into_diag(self, dcx: rustc_errors::DiagCtxtHandle<'_sess>,
                level: rustc_errors::Level) -> rustc_errors::Diag<'_sess, G> {
                match self {
                    UnmarkedIntrinsicExposed {
                        span: __binding_0, def_path: __binding_1 } => {
                        let mut diag =
                            rustc_errors::Diag::new(dcx, level,
                                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("intrinsic `{$def_path}` cannot be (indirectly) exposed to stable")));
                        diag.help(rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("mark the caller as `#[rustc_const_unstable]`, or mark the intrinsic `#[rustc_intrinsic_const_stable_indirect]` (but this requires team approval)")));
                        ;
                        diag.arg("def_path", __binding_1);
                        diag.span(__binding_0);
                        diag
                    }
                }
            }
        }
    };Diagnostic)]
209#[diag("intrinsic `{$def_path}` cannot be (indirectly) exposed to stable")]
210#[help(
211    "mark the caller as `#[rustc_const_unstable]`, or mark the intrinsic `#[rustc_intrinsic_const_stable_indirect]` (but this requires team approval)"
212)]
213pub(crate) struct UnmarkedIntrinsicExposed {
214    #[primary_span]
215    pub span: Span,
216    pub def_path: String,
217}
218
219#[derive(const _: () =
    {
        impl<'_sess, G> rustc_errors::Diagnostic<'_sess, G> for
            MutableBorrowEscaping where G: rustc_errors::EmissionGuarantee {
            #[track_caller]
            fn into_diag(self, dcx: rustc_errors::DiagCtxtHandle<'_sess>,
                level: rustc_errors::Level) -> rustc_errors::Diag<'_sess, G> {
                match self {
                    MutableBorrowEscaping { span: __binding_0, kind: __binding_1
                        } => {
                        let mut diag =
                            rustc_errors::Diag::new(dcx, level,
                                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("mutable borrows of temporaries that have their lifetime extended until the end of the program are not allowed")));
                        diag.code(E0764);
                        diag.note(rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("temporaries in constants and statics can have their lifetime extended until the end of the program")));
                        diag.note(rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("to avoid accidentally creating global mutable state, such temporaries must be immutable")));
                        diag.help(rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut`")));
                        ;
                        diag.arg("kind", __binding_1);
                        diag.span(__binding_0);
                        diag.span_label(__binding_0,
                            rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("this mutable borrow refers to such a temporary")));
                        diag
                    }
                }
            }
        }
    };Diagnostic)]
220#[diag("mutable borrows of temporaries that have their lifetime extended until the end of the program are not allowed", code = E0764)]
221#[note(
222    "temporaries in constants and statics can have their lifetime extended until the end of the program"
223)]
224#[note("to avoid accidentally creating global mutable state, such temporaries must be immutable")]
225#[help(
226    "if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut`"
227)]
228pub(crate) struct MutableBorrowEscaping {
229    #[primary_span]
230    #[label("this mutable borrow refers to such a temporary")]
231    pub span: Span,
232    pub kind: ConstContext,
233}
234
235#[derive(const _: () =
    {
        impl<'_sess, G> rustc_errors::Diagnostic<'_sess, G> for
            NonConstFmtMacroCall where G: rustc_errors::EmissionGuarantee {
            #[track_caller]
            fn into_diag(self, dcx: rustc_errors::DiagCtxtHandle<'_sess>,
                level: rustc_errors::Level) -> rustc_errors::Diag<'_sess, G> {
                match self {
                    NonConstFmtMacroCall {
                        span: __binding_0,
                        kind: __binding_1,
                        non_or_conditionally: __binding_2 } => {
                        let mut diag =
                            rustc_errors::Diag::new(dcx, level,
                                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("cannot call {$non_or_conditionally}-const formatting macro in {$kind ->\n    [const] constant\n    [static] static\n    [const_fn] constant function\n    *[other] {\"\"}\n}s")));
                        diag.code(E0015);
                        ;
                        diag.arg("kind", __binding_1);
                        diag.arg("non_or_conditionally", __binding_2);
                        diag.span(__binding_0);
                        diag
                    }
                }
            }
        }
    };Diagnostic)]
236#[diag(
237    r#"cannot call {$non_or_conditionally}-const formatting macro in {$kind ->
238    [const] constant
239    [static] static
240    [const_fn] constant function
241    *[other] {""}
242}s"#,
243    code = E0015,
244)]
245pub(crate) struct NonConstFmtMacroCall {
246    #[primary_span]
247    pub span: Span,
248    pub kind: ConstContext,
249    pub non_or_conditionally: &'static str,
250}
251
252#[derive(const _: () =
    {
        impl<'_sess, G> rustc_errors::Diagnostic<'_sess, G> for NonConstFnCall
            where G: rustc_errors::EmissionGuarantee {
            #[track_caller]
            fn into_diag(self, dcx: rustc_errors::DiagCtxtHandle<'_sess>,
                level: rustc_errors::Level) -> rustc_errors::Diag<'_sess, G> {
                match self {
                    NonConstFnCall {
                        span: __binding_0,
                        def_path_str: __binding_1,
                        def_descr: __binding_2,
                        kind: __binding_3,
                        non_or_conditionally: __binding_4 } => {
                        let mut diag =
                            rustc_errors::Diag::new(dcx, level,
                                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("cannot call {$non_or_conditionally}-const {$def_descr} `{$def_path_str}` in {$kind ->\n    [const] constant\n    [static] static\n    [const_fn] constant function\n    *[other] {\"\"}\n}s")));
                        diag.code(E0015);
                        ;
                        diag.arg("def_path_str", __binding_1);
                        diag.arg("def_descr", __binding_2);
                        diag.arg("kind", __binding_3);
                        diag.arg("non_or_conditionally", __binding_4);
                        diag.span(__binding_0);
                        diag
                    }
                }
            }
        }
    };Diagnostic)]
253#[diag(r#"cannot call {$non_or_conditionally}-const {$def_descr} `{$def_path_str}` in {$kind ->
254    [const] constant
255    [static] static
256    [const_fn] constant function
257    *[other] {""}
258}s"#, code = E0015)]
259pub(crate) struct NonConstFnCall {
260    #[primary_span]
261    pub span: Span,
262    pub def_path_str: String,
263    pub def_descr: &'static str,
264    pub kind: ConstContext,
265    pub non_or_conditionally: &'static str,
266}
267
268#[derive(const _: () =
    {
        impl<'_sess, G> rustc_errors::Diagnostic<'_sess, G> for
            NonConstIntrinsic where G: rustc_errors::EmissionGuarantee {
            #[track_caller]
            fn into_diag(self, dcx: rustc_errors::DiagCtxtHandle<'_sess>,
                level: rustc_errors::Level) -> rustc_errors::Diag<'_sess, G> {
                match self {
                    NonConstIntrinsic {
                        span: __binding_0, name: __binding_1, kind: __binding_2 } =>
                        {
                        let mut diag =
                            rustc_errors::Diag::new(dcx, level,
                                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("cannot call non-const intrinsic `{$name}` in {$kind ->\n    [const] constant\n    [static] static\n    [const_fn] constant function\n    *[other] {\"\"}\n}s")));
                        ;
                        diag.arg("name", __binding_1);
                        diag.arg("kind", __binding_2);
                        diag.span(__binding_0);
                        diag
                    }
                }
            }
        }
    };Diagnostic)]
269#[diag(
270    r#"cannot call non-const intrinsic `{$name}` in {$kind ->
271    [const] constant
272    [static] static
273    [const_fn] constant function
274    *[other] {""}
275}s"#
276)]
277pub(crate) struct NonConstIntrinsic {
278    #[primary_span]
279    pub span: Span,
280    pub name: Symbol,
281    pub kind: ConstContext,
282}
283
284#[derive(const _: () =
    {
        impl<'_sess, G> rustc_errors::Diagnostic<'_sess, G> for
            UnallowedOpInConstContext where G: rustc_errors::EmissionGuarantee
            {
            #[track_caller]
            fn into_diag(self, dcx: rustc_errors::DiagCtxtHandle<'_sess>,
                level: rustc_errors::Level) -> rustc_errors::Diag<'_sess, G> {
                match self {
                    UnallowedOpInConstContext {
                        span: __binding_0, msg: __binding_1 } => {
                        let mut diag =
                            rustc_errors::Diag::new(dcx, level,
                                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("{$msg}")));
                        ;
                        diag.arg("msg", __binding_1);
                        diag.span(__binding_0);
                        diag
                    }
                }
            }
        }
    };Diagnostic)]
285#[diag("{$msg}")]
286pub(crate) struct UnallowedOpInConstContext {
287    #[primary_span]
288    pub span: Span,
289    pub msg: String,
290}
291
292#[derive(const _: () =
    {
        impl<'_sess, G> rustc_errors::Diagnostic<'_sess, G> for
            UnallowedInlineAsm where G: rustc_errors::EmissionGuarantee {
            #[track_caller]
            fn into_diag(self, dcx: rustc_errors::DiagCtxtHandle<'_sess>,
                level: rustc_errors::Level) -> rustc_errors::Diag<'_sess, G> {
                match self {
                    UnallowedInlineAsm { span: __binding_0, kind: __binding_1 }
                        => {
                        let mut diag =
                            rustc_errors::Diag::new(dcx, level,
                                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("inline assembly is not allowed in {$kind ->\n    [const] constant\n    [static] static\n    [const_fn] constant function\n    *[other] {\"\"}\n}s")));
                        diag.code(E0015);
                        ;
                        diag.arg("kind", __binding_1);
                        diag.span(__binding_0);
                        diag
                    }
                }
            }
        }
    };Diagnostic)]
293#[diag(r#"inline assembly is not allowed in {$kind ->
294    [const] constant
295    [static] static
296    [const_fn] constant function
297    *[other] {""}
298}s"#, code = E0015)]
299pub(crate) struct UnallowedInlineAsm {
300    #[primary_span]
301    pub span: Span,
302    pub kind: ConstContext,
303}
304
305#[derive(const _: () =
    {
        impl<'_sess, G> rustc_errors::Diagnostic<'_sess, G> for
            InteriorMutableBorrowEscaping where
            G: rustc_errors::EmissionGuarantee {
            #[track_caller]
            fn into_diag(self, dcx: rustc_errors::DiagCtxtHandle<'_sess>,
                level: rustc_errors::Level) -> rustc_errors::Diag<'_sess, G> {
                match self {
                    InteriorMutableBorrowEscaping {
                        span: __binding_0, kind: __binding_1 } => {
                        let mut diag =
                            rustc_errors::Diag::new(dcx, level,
                                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("interior mutable shared borrows of temporaries that have their lifetime extended until the end of the program are not allowed")));
                        diag.code(E0492);
                        diag.note(rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("temporaries in constants and statics can have their lifetime extended until the end of the program")));
                        diag.note(rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("to avoid accidentally creating global mutable state, such temporaries must be immutable")));
                        diag.help(rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut`")));
                        ;
                        diag.arg("kind", __binding_1);
                        diag.span(__binding_0);
                        diag.span_label(__binding_0,
                            rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("this borrow of an interior mutable value refers to such a temporary")));
                        diag
                    }
                }
            }
        }
    };Diagnostic)]
306#[diag("interior mutable shared borrows of temporaries that have their lifetime extended until the end of the program are not allowed", code = E0492)]
307#[note(
308    "temporaries in constants and statics can have their lifetime extended until the end of the program"
309)]
310#[note("to avoid accidentally creating global mutable state, such temporaries must be immutable")]
311#[help(
312    "if you really want global mutable state, try replacing the temporary by an interior mutable `static` or a `static mut`"
313)]
314pub(crate) struct InteriorMutableBorrowEscaping {
315    #[primary_span]
316    #[label("this borrow of an interior mutable value refers to such a temporary")]
317    pub span: Span,
318    pub kind: ConstContext,
319}
320
321#[derive(const _: () =
    {
        impl<'_sess, G> rustc_errors::Diagnostic<'_sess, G> for LongRunning
            where G: rustc_errors::EmissionGuarantee {
            #[track_caller]
            fn into_diag(self, dcx: rustc_errors::DiagCtxtHandle<'_sess>,
                level: rustc_errors::Level) -> rustc_errors::Diag<'_sess, G> {
                match self {
                    LongRunning { item_span: __binding_0 } => {
                        let mut diag =
                            rustc_errors::Diag::new(dcx, level,
                                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("constant evaluation is taking a long time")));
                        diag.note(rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("this lint makes sure the compiler doesn't get stuck due to infinite loops in const eval.\n    If your compilation actually takes a long time, you can safely allow the lint")));
                        ;
                        diag.span_help(__binding_0,
                            rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("the constant being evaluated")));
                        diag
                    }
                }
            }
        }
    };Diagnostic)]
322#[diag("constant evaluation is taking a long time")]
323#[note(
324    "this lint makes sure the compiler doesn't get stuck due to infinite loops in const eval.
325    If your compilation actually takes a long time, you can safely allow the lint"
326)]
327pub struct LongRunning {
328    #[help("the constant being evaluated")]
329    pub item_span: Span,
330}
331
332#[derive(const _: () =
    {
        impl<'_sess, G> rustc_errors::Diagnostic<'_sess, G> for
            LongRunningWarn where G: rustc_errors::EmissionGuarantee {
            #[track_caller]
            fn into_diag(self, dcx: rustc_errors::DiagCtxtHandle<'_sess>,
                level: rustc_errors::Level) -> rustc_errors::Diag<'_sess, G> {
                match self {
                    LongRunningWarn {
                        span: __binding_0,
                        item_span: __binding_1,
                        force_duplicate: __binding_2 } => {
                        let mut diag =
                            rustc_errors::Diag::new(dcx, level,
                                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("constant evaluation is taking a long time")));
                        ;
                        diag.arg("force_duplicate", __binding_2);
                        diag.span(__binding_0);
                        diag.span_label(__binding_0,
                            rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("the const evaluator is currently interpreting this expression")));
                        diag.span_help(__binding_1,
                            rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("the constant being evaluated")));
                        diag
                    }
                }
            }
        }
    };Diagnostic)]
333#[diag("constant evaluation is taking a long time")]
334pub struct LongRunningWarn {
335    #[primary_span]
336    #[label("the const evaluator is currently interpreting this expression")]
337    pub span: Span,
338    #[help("the constant being evaluated")]
339    pub item_span: Span,
340    // Used for evading `-Z deduplicate-diagnostics`.
341    pub force_duplicate: usize,
342}
343
344#[derive(const _: () =
    {
        impl rustc_errors::Subdiagnostic for NonConstImplNote {
            fn add_to_diag<__G>(self, diag: &mut rustc_errors::Diag<'_, __G>)
                where __G: rustc_errors::EmissionGuarantee {
                match self {
                    NonConstImplNote { span: __binding_0 } => {
                        diag.store_args();
                        let __message =
                            diag.eagerly_translate(rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("impl defined here, but it is not `const`")));
                        diag.span_note(__binding_0, __message);
                        diag.restore_args();
                    }
                }
            }
        }
    };Subdiagnostic)]
345#[note("impl defined here, but it is not `const`")]
346pub(crate) struct NonConstImplNote {
347    #[primary_span]
348    pub span: Span,
349}
350
351#[derive(#[automatically_derived]
impl ::core::clone::Clone for FrameNote {
    #[inline]
    fn clone(&self) -> FrameNote {
        FrameNote {
            span: ::core::clone::Clone::clone(&self.span),
            times: ::core::clone::Clone::clone(&self.times),
            where_: ::core::clone::Clone::clone(&self.where_),
            instance: ::core::clone::Clone::clone(&self.instance),
            has_label: ::core::clone::Clone::clone(&self.has_label),
        }
    }
}Clone)]
352pub struct FrameNote {
353    pub span: Span,
354    pub times: i32,
355    pub where_: &'static str,
356    pub instance: String,
357    pub has_label: bool,
358}
359
360impl Subdiagnostic for FrameNote {
361    fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
362        diag.arg("times", self.times);
363        diag.arg("where_", self.where_);
364        diag.arg("instance", self.instance);
365        let mut span: MultiSpan = self.span.into();
366        if self.has_label && !self.span.is_dummy() {
367            span.push_span_label(self.span, rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("the failure occurred here"))msg!("the failure occurred here"));
368        }
369        let msg = diag.eagerly_translate(rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("{$times ->\n                [0] inside {$where_ ->\n                    [closure] closure\n                    [instance] `{$instance}`\n                    *[other] {\"\"}\n                }\n                *[other] [... {$times} additional calls inside {$where_ ->\n                    [closure] closure\n                    [instance] `{$instance}`\n                    *[other] {\"\"}\n                } ...]\n            }"))msg!(
370            r#"{$times ->
371                [0] inside {$where_ ->
372                    [closure] closure
373                    [instance] `{$instance}`
374                    *[other] {""}
375                }
376                *[other] [... {$times} additional calls inside {$where_ ->
377                    [closure] closure
378                    [instance] `{$instance}`
379                    *[other] {""}
380                } ...]
381            }"#
382        ));
383        diag.remove_arg("times");
384        diag.remove_arg("where_");
385        diag.remove_arg("instance");
386        diag.span_note(span, msg);
387    }
388}
389
390#[derive(const _: () =
    {
        impl rustc_errors::Subdiagnostic for RawBytesNote {
            fn add_to_diag<__G>(self, diag: &mut rustc_errors::Diag<'_, __G>)
                where __G: rustc_errors::EmissionGuarantee {
                match self {
                    RawBytesNote {
                        size: __binding_0, align: __binding_1, bytes: __binding_2 }
                        => {
                        diag.store_args();
                        diag.arg("size", __binding_0);
                        diag.arg("align", __binding_1);
                        diag.arg("bytes", __binding_2);
                        let __message =
                            diag.eagerly_translate(rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("the raw bytes of the constant (size: {$size}, align: {$align}) {\"{\"}{$bytes}{\"}\"}")));
                        diag.note(__message);
                        diag.restore_args();
                    }
                }
            }
        }
    };Subdiagnostic)]
391#[note(r#"the raw bytes of the constant (size: {$size}, align: {$align}) {"{"}{$bytes}{"}"}"#)]
392pub struct RawBytesNote {
393    pub size: u64,
394    pub align: u64,
395    pub bytes: String,
396}
397
398// FIXME(fee1-dead) do not use stringly typed `ConstContext`
399
400#[derive(const _: () =
    {
        impl<'_sess, 'tcx, G> rustc_errors::Diagnostic<'_sess, G> for
            NonConstMatchEq<'tcx> where G: rustc_errors::EmissionGuarantee {
            #[track_caller]
            fn into_diag(self, dcx: rustc_errors::DiagCtxtHandle<'_sess>,
                level: rustc_errors::Level) -> rustc_errors::Diag<'_sess, G> {
                match self {
                    NonConstMatchEq {
                        span: __binding_0,
                        ty: __binding_1,
                        kind: __binding_2,
                        non_or_conditionally: __binding_3 } => {
                        let mut diag =
                            rustc_errors::Diag::new(dcx, level,
                                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("cannot match on `{$ty}` in {$kind ->\n    [const] constant\n    [static] static\n    [const_fn] constant function\n    *[other] {\"\"}\n}s")));
                        diag.note(rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("`{$ty}` cannot be compared in compile-time, and therefore cannot be used in `match`es")));
                        ;
                        diag.arg("ty", __binding_1);
                        diag.arg("kind", __binding_2);
                        diag.arg("non_or_conditionally", __binding_3);
                        diag.span(__binding_0);
                        diag
                    }
                }
            }
        }
    };Diagnostic)]
401#[diag(
402    r#"cannot match on `{$ty}` in {$kind ->
403    [const] constant
404    [static] static
405    [const_fn] constant function
406    *[other] {""}
407}s"#
408)]
409#[note("`{$ty}` cannot be compared in compile-time, and therefore cannot be used in `match`es")]
410pub struct NonConstMatchEq<'tcx> {
411    #[primary_span]
412    pub span: Span,
413    pub ty: Ty<'tcx>,
414    pub kind: ConstContext,
415    pub non_or_conditionally: &'static str,
416}
417
418#[derive(const _: () =
    {
        impl<'_sess, 'tcx, G> rustc_errors::Diagnostic<'_sess, G> for
            NonConstForLoopIntoIter<'tcx> where
            G: rustc_errors::EmissionGuarantee {
            #[track_caller]
            fn into_diag(self, dcx: rustc_errors::DiagCtxtHandle<'_sess>,
                level: rustc_errors::Level) -> rustc_errors::Diag<'_sess, G> {
                match self {
                    NonConstForLoopIntoIter {
                        span: __binding_0,
                        ty: __binding_1,
                        kind: __binding_2,
                        non_or_conditionally: __binding_3 } => {
                        let mut diag =
                            rustc_errors::Diag::new(dcx, level,
                                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("cannot use `for` loop on `{$ty}` in {$kind ->\n    [const] constant\n    [static] static\n    [const_fn] constant function\n    *[other] {\"\"}\n}s")));
                        diag.code(E0015);
                        ;
                        diag.arg("ty", __binding_1);
                        diag.arg("kind", __binding_2);
                        diag.arg("non_or_conditionally", __binding_3);
                        diag.span(__binding_0);
                        diag
                    }
                }
            }
        }
    };Diagnostic)]
419#[diag(r#"cannot use `for` loop on `{$ty}` in {$kind ->
420    [const] constant
421    [static] static
422    [const_fn] constant function
423    *[other] {""}
424}s"#, code = E0015)]
425pub struct NonConstForLoopIntoIter<'tcx> {
426    #[primary_span]
427    pub span: Span,
428    pub ty: Ty<'tcx>,
429    pub kind: ConstContext,
430    pub non_or_conditionally: &'static str,
431}
432
433#[derive(const _: () =
    {
        impl<'_sess, 'tcx, G> rustc_errors::Diagnostic<'_sess, G> for
            NonConstQuestionBranch<'tcx> where
            G: rustc_errors::EmissionGuarantee {
            #[track_caller]
            fn into_diag(self, dcx: rustc_errors::DiagCtxtHandle<'_sess>,
                level: rustc_errors::Level) -> rustc_errors::Diag<'_sess, G> {
                match self {
                    NonConstQuestionBranch {
                        span: __binding_0,
                        ty: __binding_1,
                        kind: __binding_2,
                        non_or_conditionally: __binding_3 } => {
                        let mut diag =
                            rustc_errors::Diag::new(dcx, level,
                                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("`?` is not allowed on `{$ty}` in {$kind ->\n    [const] constant\n    [static] static\n    [const_fn] constant function\n    *[other] {\"\"}\n}s")));
                        diag.code(E0015);
                        ;
                        diag.arg("ty", __binding_1);
                        diag.arg("kind", __binding_2);
                        diag.arg("non_or_conditionally", __binding_3);
                        diag.span(__binding_0);
                        diag
                    }
                }
            }
        }
    };Diagnostic)]
434#[diag(r#"`?` is not allowed on `{$ty}` in {$kind ->
435    [const] constant
436    [static] static
437    [const_fn] constant function
438    *[other] {""}
439}s"#, code = E0015)]
440pub struct NonConstQuestionBranch<'tcx> {
441    #[primary_span]
442    pub span: Span,
443    pub ty: Ty<'tcx>,
444    pub kind: ConstContext,
445    pub non_or_conditionally: &'static str,
446}
447
448#[derive(const _: () =
    {
        impl<'_sess, 'tcx, G> rustc_errors::Diagnostic<'_sess, G> for
            NonConstQuestionFromResidual<'tcx> where
            G: rustc_errors::EmissionGuarantee {
            #[track_caller]
            fn into_diag(self, dcx: rustc_errors::DiagCtxtHandle<'_sess>,
                level: rustc_errors::Level) -> rustc_errors::Diag<'_sess, G> {
                match self {
                    NonConstQuestionFromResidual {
                        span: __binding_0,
                        ty: __binding_1,
                        kind: __binding_2,
                        non_or_conditionally: __binding_3 } => {
                        let mut diag =
                            rustc_errors::Diag::new(dcx, level,
                                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("`?` is not allowed on `{$ty}` in {$kind ->\n    [const] constant\n    [static] static\n    [const_fn] constant function\n    *[other] {\"\"}\n}s")));
                        diag.code(E0015);
                        ;
                        diag.arg("ty", __binding_1);
                        diag.arg("kind", __binding_2);
                        diag.arg("non_or_conditionally", __binding_3);
                        diag.span(__binding_0);
                        diag
                    }
                }
            }
        }
    };Diagnostic)]
449#[diag(r#"`?` is not allowed on `{$ty}` in {$kind ->
450    [const] constant
451    [static] static
452    [const_fn] constant function
453    *[other] {""}
454}s"#, code = E0015)]
455pub struct NonConstQuestionFromResidual<'tcx> {
456    #[primary_span]
457    pub span: Span,
458    pub ty: Ty<'tcx>,
459    pub kind: ConstContext,
460    pub non_or_conditionally: &'static str,
461}
462
463#[derive(const _: () =
    {
        impl<'_sess, 'tcx, G> rustc_errors::Diagnostic<'_sess, G> for
            NonConstTryBlockFromOutput<'tcx> where
            G: rustc_errors::EmissionGuarantee {
            #[track_caller]
            fn into_diag(self, dcx: rustc_errors::DiagCtxtHandle<'_sess>,
                level: rustc_errors::Level) -> rustc_errors::Diag<'_sess, G> {
                match self {
                    NonConstTryBlockFromOutput {
                        span: __binding_0,
                        ty: __binding_1,
                        kind: __binding_2,
                        non_or_conditionally: __binding_3 } => {
                        let mut diag =
                            rustc_errors::Diag::new(dcx, level,
                                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("`try` block cannot convert `{$ty}` to the result in {$kind ->\n    [const] constant\n    [static] static\n    [const_fn] constant function\n    *[other] {\"\"}\n}s")));
                        diag.code(E0015);
                        ;
                        diag.arg("ty", __binding_1);
                        diag.arg("kind", __binding_2);
                        diag.arg("non_or_conditionally", __binding_3);
                        diag.span(__binding_0);
                        diag
                    }
                }
            }
        }
    };Diagnostic)]
464#[diag(r#"`try` block cannot convert `{$ty}` to the result in {$kind ->
465    [const] constant
466    [static] static
467    [const_fn] constant function
468    *[other] {""}
469}s"#, code = E0015)]
470pub struct NonConstTryBlockFromOutput<'tcx> {
471    #[primary_span]
472    pub span: Span,
473    pub ty: Ty<'tcx>,
474    pub kind: ConstContext,
475    pub non_or_conditionally: &'static str,
476}
477
478#[derive(const _: () =
    {
        impl<'_sess, 'tcx, G> rustc_errors::Diagnostic<'_sess, G> for
            NonConstAwait<'tcx> where G: rustc_errors::EmissionGuarantee {
            #[track_caller]
            fn into_diag(self, dcx: rustc_errors::DiagCtxtHandle<'_sess>,
                level: rustc_errors::Level) -> rustc_errors::Diag<'_sess, G> {
                match self {
                    NonConstAwait {
                        span: __binding_0,
                        ty: __binding_1,
                        kind: __binding_2,
                        non_or_conditionally: __binding_3 } => {
                        let mut diag =
                            rustc_errors::Diag::new(dcx, level,
                                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("cannot convert `{$ty}` into a future in {$kind ->\n    [const] constant\n    [static] static\n    [const_fn] constant function\n    *[other] {\"\"}\n}s")));
                        diag.code(E0015);
                        ;
                        diag.arg("ty", __binding_1);
                        diag.arg("kind", __binding_2);
                        diag.arg("non_or_conditionally", __binding_3);
                        diag.span(__binding_0);
                        diag
                    }
                }
            }
        }
    };Diagnostic)]
479#[diag(r#"cannot convert `{$ty}` into a future in {$kind ->
480    [const] constant
481    [static] static
482    [const_fn] constant function
483    *[other] {""}
484}s"#, code = E0015)]
485pub struct NonConstAwait<'tcx> {
486    #[primary_span]
487    pub span: Span,
488    pub ty: Ty<'tcx>,
489    pub kind: ConstContext,
490    pub non_or_conditionally: &'static str,
491}
492
493#[derive(const _: () =
    {
        impl<'_sess, G> rustc_errors::Diagnostic<'_sess, G> for
            NonConstClosure where G: rustc_errors::EmissionGuarantee {
            #[track_caller]
            fn into_diag(self, dcx: rustc_errors::DiagCtxtHandle<'_sess>,
                level: rustc_errors::Level) -> rustc_errors::Diag<'_sess, G> {
                match self {
                    NonConstClosure {
                        span: __binding_0,
                        kind: __binding_1,
                        note: __binding_2,
                        non_or_conditionally: __binding_3 } => {
                        let mut diag =
                            rustc_errors::Diag::new(dcx, level,
                                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("cannot call {$non_or_conditionally}-const closure in {$kind ->\n    [const] constant\n    [static] static\n    [const_fn] constant function\n    *[other] {\"\"}\n}s")));
                        diag.code(E0015);
                        ;
                        diag.arg("kind", __binding_1);
                        diag.arg("non_or_conditionally", __binding_3);
                        diag.span(__binding_0);
                        if let Some(__binding_2) = __binding_2 {
                            diag.subdiagnostic(__binding_2);
                        }
                        diag
                    }
                }
            }
        }
    };Diagnostic)]
494#[diag(r#"cannot call {$non_or_conditionally}-const closure in {$kind ->
495    [const] constant
496    [static] static
497    [const_fn] constant function
498    *[other] {""}
499}s"#, code = E0015)]
500pub struct NonConstClosure {
501    #[primary_span]
502    pub span: Span,
503    pub kind: ConstContext,
504    #[subdiagnostic]
505    pub note: Option<NonConstClosureNote>,
506    pub non_or_conditionally: &'static str,
507}
508
509#[derive(const _: () =
    {
        impl<'_sess, G> rustc_errors::Diagnostic<'_sess, G> for
            NonConstCVariadicCall where G: rustc_errors::EmissionGuarantee {
            #[track_caller]
            fn into_diag(self, dcx: rustc_errors::DiagCtxtHandle<'_sess>,
                level: rustc_errors::Level) -> rustc_errors::Diag<'_sess, G> {
                match self {
                    NonConstCVariadicCall { span: __binding_0, kind: __binding_1
                        } => {
                        let mut diag =
                            rustc_errors::Diag::new(dcx, level,
                                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("calling const c-variadic functions is unstable in {$kind ->\n    [const] constant\n    [static] static\n    [const_fn] constant function\n    *[other] {\"\"}\n}s")));
                        diag.code(E0015);
                        ;
                        diag.arg("kind", __binding_1);
                        diag.span(__binding_0);
                        diag
                    }
                }
            }
        }
    };Diagnostic)]
510#[diag(r#"calling const c-variadic functions is unstable in {$kind ->
511    [const] constant
512    [static] static
513    [const_fn] constant function
514    *[other] {""}
515}s"#, code = E0015)]
516pub struct NonConstCVariadicCall {
517    #[primary_span]
518    pub span: Span,
519    pub kind: ConstContext,
520}
521
522#[derive(const _: () =
    {
        impl rustc_errors::Subdiagnostic for NonConstClosureNote {
            fn add_to_diag<__G>(self, diag: &mut rustc_errors::Diag<'_, __G>)
                where __G: rustc_errors::EmissionGuarantee {
                match self {
                    NonConstClosureNote::FnDef { span: __binding_0 } => {
                        diag.store_args();
                        let __message =
                            diag.eagerly_translate(rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("function defined here, but it is not `const`")));
                        diag.span_note(__binding_0, __message);
                        diag.restore_args();
                    }
                    NonConstClosureNote::FnPtr => {
                        diag.store_args();
                        let __message =
                            diag.eagerly_translate(rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("function pointers need an RFC before allowed to be called in {$kind ->\n            [const] constant\n            [static] static\n            [const_fn] constant function\n            *[other] {\"\"}\n        }s")));
                        diag.note(__message);
                        diag.restore_args();
                    }
                    NonConstClosureNote::Closure => {
                        diag.store_args();
                        let __message =
                            diag.eagerly_translate(rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("closures need an RFC before allowed to be called in {$kind ->\n            [const] constant\n            [static] static\n            [const_fn] constant function\n            *[other] {\"\"}\n        }s")));
                        diag.note(__message);
                        diag.restore_args();
                    }
                }
            }
        }
    };Subdiagnostic)]
523pub enum NonConstClosureNote {
524    #[note("function defined here, but it is not `const`")]
525    FnDef {
526        #[primary_span]
527        span: Span,
528    },
529    #[note(
530        r#"function pointers need an RFC before allowed to be called in {$kind ->
531            [const] constant
532            [static] static
533            [const_fn] constant function
534            *[other] {""}
535        }s"#
536    )]
537    FnPtr,
538    #[note(
539        r#"closures need an RFC before allowed to be called in {$kind ->
540            [const] constant
541            [static] static
542            [const_fn] constant function
543            *[other] {""}
544        }s"#
545    )]
546    Closure,
547}
548
549#[derive(const _: () =
    {
        impl rustc_errors::Subdiagnostic for ConsiderDereferencing {
            fn add_to_diag<__G>(self, diag: &mut rustc_errors::Diag<'_, __G>)
                where __G: rustc_errors::EmissionGuarantee {
                match self {
                    ConsiderDereferencing {
                        deref: __binding_0, span: __binding_1, rhs_span: __binding_2
                        } => {
                        let mut suggestions = Vec::new();
                        let __code_2 =
                            ::alloc::__export::must_use({
                                    ::alloc::fmt::format(format_args!("{0}", __binding_0))
                                });
                        let __code_3 =
                            ::alloc::__export::must_use({
                                    ::alloc::fmt::format(format_args!("{0}", __binding_0))
                                });
                        suggestions.push((__binding_1, __code_2));
                        suggestions.push((__binding_2, __code_3));
                        diag.store_args();
                        diag.arg("deref", __binding_0);
                        let __message =
                            diag.eagerly_translate(rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("consider dereferencing here")));
                        diag.multipart_suggestion_with_style(__message, suggestions,
                            rustc_errors::Applicability::MachineApplicable,
                            rustc_errors::SuggestionStyle::ShowCode);
                        diag.restore_args();
                    }
                }
            }
        }
    };Subdiagnostic)]
550#[multipart_suggestion("consider dereferencing here", applicability = "machine-applicable")]
551pub struct ConsiderDereferencing {
552    pub deref: String,
553    #[suggestion_part(code = "{deref}")]
554    pub span: Span,
555    #[suggestion_part(code = "{deref}")]
556    pub rhs_span: Span,
557}
558
559#[derive(const _: () =
    {
        impl<'_sess, G> rustc_errors::Diagnostic<'_sess, G> for
            NonConstOperator where G: rustc_errors::EmissionGuarantee {
            #[track_caller]
            fn into_diag(self, dcx: rustc_errors::DiagCtxtHandle<'_sess>,
                level: rustc_errors::Level) -> rustc_errors::Diag<'_sess, G> {
                match self {
                    NonConstOperator {
                        span: __binding_0,
                        kind: __binding_1,
                        sugg: __binding_2,
                        non_or_conditionally: __binding_3 } => {
                        let mut diag =
                            rustc_errors::Diag::new(dcx, level,
                                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("cannot call {$non_or_conditionally}-const operator in {$kind ->\n    [const] constant\n    [static] static\n    [const_fn] constant function\n    *[other] {\"\"}\n}s")));
                        diag.code(E0015);
                        ;
                        diag.arg("kind", __binding_1);
                        diag.arg("non_or_conditionally", __binding_3);
                        diag.span(__binding_0);
                        if let Some(__binding_2) = __binding_2 {
                            diag.subdiagnostic(__binding_2);
                        }
                        diag
                    }
                }
            }
        }
    };Diagnostic)]
560#[diag(r#"cannot call {$non_or_conditionally}-const operator in {$kind ->
561    [const] constant
562    [static] static
563    [const_fn] constant function
564    *[other] {""}
565}s"#, code = E0015)]
566pub struct NonConstOperator {
567    #[primary_span]
568    pub span: Span,
569    pub kind: ConstContext,
570    #[subdiagnostic]
571    pub sugg: Option<ConsiderDereferencing>,
572    pub non_or_conditionally: &'static str,
573}
574
575#[derive(const _: () =
    {
        impl<'_sess, 'tcx, G> rustc_errors::Diagnostic<'_sess, G> for
            NonConstDerefCoercion<'tcx> where
            G: rustc_errors::EmissionGuarantee {
            #[track_caller]
            fn into_diag(self, dcx: rustc_errors::DiagCtxtHandle<'_sess>,
                level: rustc_errors::Level) -> rustc_errors::Diag<'_sess, G> {
                match self {
                    NonConstDerefCoercion {
                        span: __binding_0,
                        ty: __binding_1,
                        kind: __binding_2,
                        target_ty: __binding_3,
                        deref_target: __binding_4,
                        non_or_conditionally: __binding_5 } => {
                        let mut diag =
                            rustc_errors::Diag::new(dcx, level,
                                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("cannot perform {$non_or_conditionally}-const deref coercion on `{$ty}` in {$kind ->\n    [const] constant\n    [static] static\n    [const_fn] constant function\n    *[other] {\"\"}\n}s")));
                        diag.code(E0015);
                        diag.note(rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("attempting to deref into `{$target_ty}`")));
                        ;
                        diag.arg("ty", __binding_1);
                        diag.arg("kind", __binding_2);
                        diag.arg("target_ty", __binding_3);
                        diag.arg("non_or_conditionally", __binding_5);
                        diag.span(__binding_0);
                        if let Some(__binding_4) = __binding_4 {
                            diag.span_note(__binding_4,
                                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("deref defined here")));
                        }
                        diag
                    }
                }
            }
        }
    };Diagnostic)]
576#[diag(r#"cannot perform {$non_or_conditionally}-const deref coercion on `{$ty}` in {$kind ->
577    [const] constant
578    [static] static
579    [const_fn] constant function
580    *[other] {""}
581}s"#, code = E0015)]
582#[note("attempting to deref into `{$target_ty}`")]
583pub struct NonConstDerefCoercion<'tcx> {
584    #[primary_span]
585    pub span: Span,
586    pub ty: Ty<'tcx>,
587    pub kind: ConstContext,
588    pub target_ty: Ty<'tcx>,
589    #[note("deref defined here")]
590    pub deref_target: Option<Span>,
591    pub non_or_conditionally: &'static str,
592}
593
594#[derive(const _: () =
    {
        impl<'_sess, 'tcx, G> rustc_errors::Diagnostic<'_sess, G> for
            LiveDrop<'tcx> where G: rustc_errors::EmissionGuarantee {
            #[track_caller]
            fn into_diag(self, dcx: rustc_errors::DiagCtxtHandle<'_sess>,
                level: rustc_errors::Level) -> rustc_errors::Diag<'_sess, G> {
                match self {
                    LiveDrop {
                        span: __binding_0,
                        kind: __binding_1,
                        dropped_ty: __binding_2,
                        dropped_at: __binding_3 } => {
                        let mut diag =
                            rustc_errors::Diag::new(dcx, level,
                                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("destructor of `{$dropped_ty}` cannot be evaluated at compile-time")));
                        diag.code(E0493);
                        ;
                        diag.arg("kind", __binding_1);
                        diag.arg("dropped_ty", __binding_2);
                        diag.span(__binding_0);
                        diag.span_label(__binding_0,
                            rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("the destructor for this type cannot be evaluated in {$kind ->\n            [const] constant\n            [static] static\n            [const_fn] constant function\n            *[other] {\"\"}\n        }s")));
                        diag.span_label(__binding_3,
                            rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("value is dropped here")));
                        diag
                    }
                }
            }
        }
    };Diagnostic)]
595#[diag("destructor of `{$dropped_ty}` cannot be evaluated at compile-time", code = E0493)]
596pub struct LiveDrop<'tcx> {
597    #[primary_span]
598    #[label(
599        r#"the destructor for this type cannot be evaluated in {$kind ->
600            [const] constant
601            [static] static
602            [const_fn] constant function
603            *[other] {""}
604        }s"#
605    )]
606    pub span: Span,
607    pub kind: ConstContext,
608    pub dropped_ty: Ty<'tcx>,
609    #[label("value is dropped here")]
610    pub dropped_at: Span,
611}
612
613pub trait ReportErrorExt {
614    /// Returns the diagnostic message for this error.
615    fn diagnostic_message(&self) -> DiagMessage;
616    fn add_args<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>);
617
618    fn debug(self) -> String
619    where
620        Self: Sized,
621    {
622        ty::tls::with(move |tcx| {
623            let dcx = tcx.dcx();
624            let mut diag = dcx.struct_allow(DiagMessage::Str(String::new().into()));
625            let message = self.diagnostic_message();
626            self.add_args(&mut diag);
627            let s = dcx.eagerly_translate_to_string(message, diag.args.iter());
628            diag.cancel();
629            s
630        })
631    }
632}
633
634impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> {
635    fn diagnostic_message(&self) -> DiagMessage {
636        use UndefinedBehaviorInfo::*;
637
638        match self {
639            Ub(msg) => msg.clone().into(),
640            Custom(x) => (x.msg)(),
641            ValidationError(e) => e.diagnostic_message(),
642
643            Unreachable => "entering unreachable code".into(),
644            BoundsCheckFailed { .. } => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("indexing out of bounds: the len is {$len} but the index is {$index}"))msg!("indexing out of bounds: the len is {$len} but the index is {$index}"),
645            DivisionByZero => "dividing by zero".into(),
646            RemainderByZero => "calculating the remainder with a divisor of zero".into(),
647            DivisionOverflow => "overflow in signed division (dividing MIN by -1)".into(),
648            RemainderOverflow => "overflow in signed remainder (dividing MIN by -1)".into(),
649            PointerArithOverflow => "overflowing pointer arithmetic: the total offset in bytes does not fit in an `isize`".into(),
650            ArithOverflow { .. } => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("arithmetic overflow in `{$intrinsic}`"))msg!("arithmetic overflow in `{$intrinsic}`"),
651            ShiftOverflow { .. } => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("overflowing shift by {$shift_amount} in `{$intrinsic}`"))msg!("overflowing shift by {$shift_amount} in `{$intrinsic}`"),
652            InvalidMeta(InvalidMetaKind::SliceTooBig) => "invalid metadata in wide pointer: slice is bigger than largest supported object".into(),
653            InvalidMeta(InvalidMetaKind::TooBig) => "invalid metadata in wide pointer: total size is bigger than largest supported object".into(),
654            UnterminatedCString(_) => "reading a null-terminated string starting at {$pointer} with no null found before end of allocation".into(),
655            PointerUseAfterFree(_, _) => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("{$operation ->\n                    [MemoryAccess] memory access failed\n                    [InboundsPointerArithmetic] in-bounds pointer arithmetic failed\n                    *[Dereferenceable] pointer not dereferenceable\n                }: {$alloc_id} has been freed, so this pointer is dangling"))msg!(
656                "{$operation ->
657                    [MemoryAccess] memory access failed
658                    [InboundsPointerArithmetic] in-bounds pointer arithmetic failed
659                    *[Dereferenceable] pointer not dereferenceable
660                }: {$alloc_id} has been freed, so this pointer is dangling"
661            ),
662            PointerOutOfBounds { .. } => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("{$operation ->\n                    [MemoryAccess] memory access failed\n                    [InboundsPointerArithmetic] in-bounds pointer arithmetic failed\n                    *[Dereferenceable] pointer not dereferenceable\n                }: {$operation ->\n                    [MemoryAccess] attempting to access {$inbounds_size ->\n                        [1] 1 byte\n                        *[x] {$inbounds_size} bytes\n                    }\n                    [InboundsPointerArithmetic] attempting to offset pointer by {$inbounds_size ->\n                        [1] 1 byte\n                        *[x] {$inbounds_size} bytes\n                    }\n                    *[Dereferenceable] pointer must {$inbounds_size ->\n                        [0] point to some allocation\n                        [1] be dereferenceable for 1 byte\n                        *[x] be dereferenceable for {$inbounds_size} bytes\n                    }\n                }, but got {$pointer} which {$ptr_offset_is_neg ->\n                    [true] points to before the beginning of the allocation\n                    *[false] {$inbounds_size_is_neg ->\n                        [false] {$alloc_size_minus_ptr_offset ->\n                            [0] is at or beyond the end of the allocation of size {$alloc_size ->\n                                [1] 1 byte\n                                *[x] {$alloc_size} bytes\n                            }\n                            [1] is only 1 byte from the end of the allocation\n                            *[x] is only {$alloc_size_minus_ptr_offset} bytes from the end of the allocation\n                        }\n                        *[true] {$ptr_offset_abs ->\n                            [0] is at the beginning of the allocation\n                            *[other] is only {$ptr_offset_abs} bytes from the beginning of the allocation\n                        }\n                    }\n                }"))msg!(
663                "{$operation ->
664                    [MemoryAccess] memory access failed
665                    [InboundsPointerArithmetic] in-bounds pointer arithmetic failed
666                    *[Dereferenceable] pointer not dereferenceable
667                }: {$operation ->
668                    [MemoryAccess] attempting to access {$inbounds_size ->
669                        [1] 1 byte
670                        *[x] {$inbounds_size} bytes
671                    }
672                    [InboundsPointerArithmetic] attempting to offset pointer by {$inbounds_size ->
673                        [1] 1 byte
674                        *[x] {$inbounds_size} bytes
675                    }
676                    *[Dereferenceable] pointer must {$inbounds_size ->
677                        [0] point to some allocation
678                        [1] be dereferenceable for 1 byte
679                        *[x] be dereferenceable for {$inbounds_size} bytes
680                    }
681                }, but got {$pointer} which {$ptr_offset_is_neg ->
682                    [true] points to before the beginning of the allocation
683                    *[false] {$inbounds_size_is_neg ->
684                        [false] {$alloc_size_minus_ptr_offset ->
685                            [0] is at or beyond the end of the allocation of size {$alloc_size ->
686                                [1] 1 byte
687                                *[x] {$alloc_size} bytes
688                            }
689                            [1] is only 1 byte from the end of the allocation
690                            *[x] is only {$alloc_size_minus_ptr_offset} bytes from the end of the allocation
691                        }
692                        *[true] {$ptr_offset_abs ->
693                            [0] is at the beginning of the allocation
694                            *[other] is only {$ptr_offset_abs} bytes from the beginning of the allocation
695                        }
696                    }
697                }"
698            ),
699            DanglingIntPointer { addr: 0, .. } => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("{$operation ->\n                    [MemoryAccess] memory access failed\n                    [InboundsPointerArithmetic] in-bounds pointer arithmetic failed\n                    *[Dereferenceable] pointer not dereferenceable\n                }: {$operation ->\n                    [MemoryAccess] attempting to access {$inbounds_size ->\n                        [1] 1 byte\n                        *[x] {$inbounds_size} bytes\n                    }\n                    [InboundsPointerArithmetic] attempting to offset pointer by {$inbounds_size ->\n                        [1] 1 byte\n                        *[x] {$inbounds_size} bytes\n                    }\n                    *[Dereferenceable] pointer must {$inbounds_size ->\n                        [0] point to some allocation\n                        [1] be dereferenceable for 1 byte\n                        *[x] be dereferenceable for {$inbounds_size} bytes\n                    }\n                }, but got null pointer"))msg!(
700                "{$operation ->
701                    [MemoryAccess] memory access failed
702                    [InboundsPointerArithmetic] in-bounds pointer arithmetic failed
703                    *[Dereferenceable] pointer not dereferenceable
704                }: {$operation ->
705                    [MemoryAccess] attempting to access {$inbounds_size ->
706                        [1] 1 byte
707                        *[x] {$inbounds_size} bytes
708                    }
709                    [InboundsPointerArithmetic] attempting to offset pointer by {$inbounds_size ->
710                        [1] 1 byte
711                        *[x] {$inbounds_size} bytes
712                    }
713                    *[Dereferenceable] pointer must {$inbounds_size ->
714                        [0] point to some allocation
715                        [1] be dereferenceable for 1 byte
716                        *[x] be dereferenceable for {$inbounds_size} bytes
717                    }
718                }, but got null pointer"),
719            DanglingIntPointer { .. } => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("{$operation ->\n                    [MemoryAccess] memory access failed\n                    [InboundsPointerArithmetic] in-bounds pointer arithmetic failed\n                    *[Dereferenceable] pointer not dereferenceable\n                }: {$operation ->\n                    [MemoryAccess] attempting to access {$inbounds_size ->\n                        [1] 1 byte\n                        *[x] {$inbounds_size} bytes\n                    }\n                    [InboundsPointerArithmetic] attempting to offset pointer by {$inbounds_size ->\n                        [1] 1 byte\n                        *[x] {$inbounds_size} bytes\n                    }\n                    *[Dereferenceable] pointer must {$inbounds_size ->\n                        [0] point to some allocation\n                        [1] be dereferenceable for 1 byte\n                        *[x] be dereferenceable for {$inbounds_size} bytes\n                    }\n                }, but got {$pointer} which is a dangling pointer (it has no provenance)"))msg!(
720                "{$operation ->
721                    [MemoryAccess] memory access failed
722                    [InboundsPointerArithmetic] in-bounds pointer arithmetic failed
723                    *[Dereferenceable] pointer not dereferenceable
724                }: {$operation ->
725                    [MemoryAccess] attempting to access {$inbounds_size ->
726                        [1] 1 byte
727                        *[x] {$inbounds_size} bytes
728                    }
729                    [InboundsPointerArithmetic] attempting to offset pointer by {$inbounds_size ->
730                        [1] 1 byte
731                        *[x] {$inbounds_size} bytes
732                    }
733                    *[Dereferenceable] pointer must {$inbounds_size ->
734                        [0] point to some allocation
735                        [1] be dereferenceable for 1 byte
736                        *[x] be dereferenceable for {$inbounds_size} bytes
737                    }
738                }, but got {$pointer} which is a dangling pointer (it has no provenance)"),
739            AlignmentCheckFailed { .. } => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("{$msg ->\n                    [AccessedPtr] accessing memory\n                    *[other] accessing memory based on pointer\n                } with alignment {$has}, but alignment {$required} is required"))msg!(
740                "{$msg ->
741                    [AccessedPtr] accessing memory
742                    *[other] accessing memory based on pointer
743                } with alignment {$has}, but alignment {$required} is required"
744            ),
745            WriteToReadOnly(_) => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("writing to {$allocation} which is read-only"))msg!("writing to {$allocation} which is read-only"),
746            DerefFunctionPointer(_) => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("accessing {$allocation} which contains a function"))msg!("accessing {$allocation} which contains a function"),
747            DerefVTablePointer(_) => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("accessing {$allocation} which contains a vtable"))msg!("accessing {$allocation} which contains a vtable"),
748            DerefVaListPointer(_) => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("accessing {$allocation} which contains a variable argument list"))msg!("accessing {$allocation} which contains a variable argument list"),
749            DerefTypeIdPointer(_) => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("accessing {$allocation} which contains a `TypeId`"))msg!("accessing {$allocation} which contains a `TypeId`"),
750            InvalidBool(_) => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("interpreting an invalid 8-bit value as a bool: 0x{$value}"))msg!("interpreting an invalid 8-bit value as a bool: 0x{$value}"),
751            InvalidChar(_) => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("interpreting an invalid 32-bit value as a char: 0x{$value}"))msg!("interpreting an invalid 32-bit value as a char: 0x{$value}"),
752            InvalidTag(_) => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("enum value has invalid tag: {$tag}"))msg!("enum value has invalid tag: {$tag}"),
753            InvalidFunctionPointer(_) => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("using {$pointer} as function pointer but it does not point to a function"))msg!("using {$pointer} as function pointer but it does not point to a function"),
754            InvalidVaListPointer(_) => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("using {$pointer} as variable argument list pointer but it does not point to a variable argument list"))msg!("using {$pointer} as variable argument list pointer but it does not point to a variable argument list"),
755            InvalidVTablePointer(_) => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("using {$pointer} as vtable pointer but it does not point to a vtable"))msg!("using {$pointer} as vtable pointer but it does not point to a vtable"),
756            InvalidVTableTrait { .. } => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("using vtable for `{$vtable_dyn_type}` but `{$expected_dyn_type}` was expected"))msg!("using vtable for `{$vtable_dyn_type}` but `{$expected_dyn_type}` was expected"),
757            InvalidStr(_) => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("this string is not valid UTF-8: {$err}"))msg!("this string is not valid UTF-8: {$err}"),
758            InvalidUninitBytes(None) => "using uninitialized data, but this operation requires initialized memory".into(),
759            InvalidUninitBytes(Some(_)) => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("reading memory at {$alloc}{$access}, but memory is uninitialized at {$uninit}, and this operation requires initialized memory"))msg!("reading memory at {$alloc}{$access}, but memory is uninitialized at {$uninit}, and this operation requires initialized memory"),
760            DeadLocal => "accessing a dead local variable".into(),
761            ScalarSizeMismatch(_) => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("scalar size mismatch: expected {$target_size} bytes but got {$data_size} bytes instead"))msg!("scalar size mismatch: expected {$target_size} bytes but got {$data_size} bytes instead"),
762            UninhabitedEnumVariantWritten(_) => "writing discriminant of an uninhabited enum variant".into(),
763            UninhabitedEnumVariantRead(_) => "read discriminant of an uninhabited enum variant".into(),
764            InvalidNichedEnumVariantWritten { .. } => {
765                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("trying to set discriminant of a {$ty} to the niched variant, but the value does not match"))msg!("trying to set discriminant of a {$ty} to the niched variant, but the value does not match")
766            }
767            AbiMismatchArgument { .. } => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("calling a function whose parameter #{$arg_idx} has type {$callee_ty} passing argument of type {$caller_ty}"))msg!("calling a function whose parameter #{$arg_idx} has type {$callee_ty} passing argument of type {$caller_ty}"),
768            AbiMismatchReturn { .. } => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("calling a function with return type {$callee_ty} passing return place of type {$caller_ty}"))msg!("calling a function with return type {$callee_ty} passing return place of type {$caller_ty}"),
769            VaArgOutOfBounds => "more C-variadic arguments read than were passed".into(),
770            CVariadicMismatch { ..} => "calling a function where the caller and callee disagree on whether the function is C-variadic".into(),
771            CVariadicFixedCountMismatch { .. } => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("calling a C-variadic function with {$caller} fixed arguments, but the function expects {$callee}"))msg!("calling a C-variadic function with {$caller} fixed arguments, but the function expects {$callee}"),
772        }
773    }
774
775    fn add_args<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
776        use UndefinedBehaviorInfo::*;
777        match self {
778            Ub(_) => {}
779            Custom(custom) => {
780                (custom.add_args)(&mut |name, value| {
781                    diag.arg(name, value);
782                });
783            }
784            ValidationError(e) => e.add_args(diag),
785
786            Unreachable
787            | DivisionByZero
788            | RemainderByZero
789            | DivisionOverflow
790            | RemainderOverflow
791            | PointerArithOverflow
792            | InvalidMeta(InvalidMetaKind::SliceTooBig)
793            | InvalidMeta(InvalidMetaKind::TooBig)
794            | InvalidUninitBytes(None)
795            | DeadLocal
796            | VaArgOutOfBounds
797            | UninhabitedEnumVariantWritten(_)
798            | UninhabitedEnumVariantRead(_) => {}
799
800            ArithOverflow { intrinsic } => {
801                diag.arg("intrinsic", intrinsic);
802            }
803            ShiftOverflow { intrinsic, shift_amount } => {
804                diag.arg("intrinsic", intrinsic);
805                diag.arg(
806                    "shift_amount",
807                    match shift_amount {
808                        Either::Left(v) => v.to_string(),
809                        Either::Right(v) => v.to_string(),
810                    },
811                );
812            }
813            BoundsCheckFailed { len, index } => {
814                diag.arg("len", len);
815                diag.arg("index", index);
816            }
817            UnterminatedCString(ptr)
818            | InvalidFunctionPointer(ptr)
819            | InvalidVaListPointer(ptr)
820            | InvalidVTablePointer(ptr) => {
821                diag.arg("pointer", ptr);
822            }
823            InvalidVTableTrait { expected_dyn_type, vtable_dyn_type } => {
824                diag.arg("expected_dyn_type", expected_dyn_type.to_string());
825                diag.arg("vtable_dyn_type", vtable_dyn_type.to_string());
826            }
827            PointerUseAfterFree(alloc_id, msg) => {
828                diag.arg("alloc_id", alloc_id).arg("operation", ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0:?}", msg))
    })format!("{:?}", msg));
829            }
830            PointerOutOfBounds { alloc_id, alloc_size, ptr_offset, inbounds_size, msg } => {
831                diag.arg("alloc_size", alloc_size.bytes());
832                diag.arg("pointer", {
833                    let mut out = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0:?}", alloc_id))
    })format!("{:?}", alloc_id);
834                    if ptr_offset > 0 {
835                        out.write_fmt(format_args!("+{0:#x}", ptr_offset))write!(out, "+{:#x}", ptr_offset).unwrap();
836                    } else if ptr_offset < 0 {
837                        out.write_fmt(format_args!("-{0:#x}", ptr_offset.unsigned_abs()))write!(out, "-{:#x}", ptr_offset.unsigned_abs()).unwrap();
838                    }
839                    out
840                });
841                diag.arg("inbounds_size", inbounds_size);
842                diag.arg("inbounds_size_is_neg", inbounds_size < 0);
843                diag.arg("inbounds_size_abs", inbounds_size.unsigned_abs());
844                diag.arg("ptr_offset", ptr_offset);
845                diag.arg("ptr_offset_is_neg", ptr_offset < 0);
846                diag.arg("ptr_offset_abs", ptr_offset.unsigned_abs());
847                diag.arg(
848                    "alloc_size_minus_ptr_offset",
849                    alloc_size.bytes().saturating_sub(ptr_offset as u64),
850                );
851                diag.arg("operation", ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0:?}", msg))
    })format!("{:?}", msg));
852            }
853            DanglingIntPointer { addr, inbounds_size, msg } => {
854                if addr != 0 {
855                    diag.arg(
856                        "pointer",
857                        Pointer::<Option<CtfeProvenance>>::without_provenance(addr).to_string(),
858                    );
859                }
860
861                diag.arg("inbounds_size", inbounds_size);
862                diag.arg("inbounds_size_is_neg", inbounds_size < 0);
863                diag.arg("inbounds_size_abs", inbounds_size.unsigned_abs());
864                diag.arg("operation", ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0:?}", msg))
    })format!("{:?}", msg));
865            }
866            AlignmentCheckFailed(Misalignment { required, has }, msg) => {
867                diag.arg("required", required.bytes());
868                diag.arg("has", has.bytes());
869                diag.arg("msg", ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0:?}", msg))
    })format!("{msg:?}"));
870            }
871            WriteToReadOnly(alloc)
872            | DerefFunctionPointer(alloc)
873            | DerefVTablePointer(alloc)
874            | DerefVaListPointer(alloc)
875            | DerefTypeIdPointer(alloc) => {
876                diag.arg("allocation", alloc);
877            }
878            InvalidBool(b) => {
879                diag.arg("value", ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0:02x}", b))
    })format!("{b:02x}"));
880            }
881            InvalidChar(c) => {
882                diag.arg("value", ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0:08x}", c))
    })format!("{c:08x}"));
883            }
884            InvalidTag(tag) => {
885                diag.arg("tag", ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0:x}", tag))
    })format!("{tag:x}"));
886            }
887            InvalidStr(err) => {
888                diag.arg("err", ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}", err))
    })format!("{err}"));
889            }
890            InvalidUninitBytes(Some((alloc, info))) => {
891                diag.arg("alloc", alloc);
892                diag.arg("access", info.access);
893                diag.arg("uninit", info.bad);
894            }
895            ScalarSizeMismatch(info) => {
896                diag.arg("target_size", info.target_size);
897                diag.arg("data_size", info.data_size);
898            }
899            InvalidNichedEnumVariantWritten { enum_ty } => {
900                diag.arg("ty", enum_ty);
901            }
902            AbiMismatchArgument { arg_idx, caller_ty, callee_ty } => {
903                diag.arg("arg_idx", arg_idx + 1); // adjust for 1-indexed lists in output
904                diag.arg("caller_ty", caller_ty);
905                diag.arg("callee_ty", callee_ty);
906            }
907            AbiMismatchReturn { caller_ty, callee_ty } => {
908                diag.arg("caller_ty", caller_ty);
909                diag.arg("callee_ty", callee_ty);
910            }
911            CVariadicMismatch { caller_is_c_variadic, callee_is_c_variadic } => {
912                diag.arg("caller_is_c_variadic", caller_is_c_variadic);
913                diag.arg("callee_is_c_variadic", callee_is_c_variadic);
914            }
915            CVariadicFixedCountMismatch { caller, callee } => {
916                diag.arg("caller", caller);
917                diag.arg("callee", callee);
918            }
919        }
920    }
921}
922
923impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> {
924    fn diagnostic_message(&self) -> DiagMessage {
925        use rustc_middle::mir::interpret::ValidationErrorKind::*;
926
927        match self.kind {
928            PtrToUninhabited { ptr_kind: PointerKind::Box, .. } => {
929                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("{$front_matter}: encountered a box pointing to uninhabited type {$ty}"))msg!("{$front_matter}: encountered a box pointing to uninhabited type {$ty}")
930            }
931            PtrToUninhabited { ptr_kind: PointerKind::Ref(_), .. } => {
932                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("{$front_matter}: encountered a reference pointing to uninhabited type {$ty}"))msg!("{$front_matter}: encountered a reference pointing to uninhabited type {$ty}")
933            }
934
935            PointerAsInt { .. } => {
936                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("{$front_matter}: encountered a pointer, but {$expected}"))msg!("{$front_matter}: encountered a pointer, but {$expected}")
937            }
938            PartialPointer => {
939                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("{$front_matter}: encountered a partial pointer or a mix of pointers"))msg!("{$front_matter}: encountered a partial pointer or a mix of pointers")
940            }
941            MutableRefToImmutable => {
942                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("{$front_matter}: encountered mutable reference or box pointing to read-only memory"))msg!(
943                    "{$front_matter}: encountered mutable reference or box pointing to read-only memory"
944                )
945            }
946            NullFnPtr { .. } => {
947                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("{$front_matter}: encountered a {$maybe ->\n                        [true] maybe-null\n                        *[false] null\n                    } function pointer"))msg!(
948                    "{$front_matter}: encountered a {$maybe ->
949                        [true] maybe-null
950                        *[false] null
951                    } function pointer"
952                )
953            }
954            NeverVal => {
955                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("{$front_matter}: encountered a value of the never type `!`"))msg!("{$front_matter}: encountered a value of the never type `!`")
956            }
957            NonnullPtrMaybeNull { .. } => {
958                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("{$front_matter}: encountered a maybe-null pointer, but expected something that is definitely non-zero"))msg!(
959                    "{$front_matter}: encountered a maybe-null pointer, but expected something that is definitely non-zero"
960                )
961            }
962            PtrOutOfRange { .. } => {
963                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("{$front_matter}: encountered a pointer with unknown absolute address, but expected something that is definitely {$in_range}"))msg!(
964                    "{$front_matter}: encountered a pointer with unknown absolute address, but expected something that is definitely {$in_range}"
965                )
966            }
967            OutOfRange { .. } => {
968                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("{$front_matter}: encountered {$value}, but expected something {$in_range}"))msg!("{$front_matter}: encountered {$value}, but expected something {$in_range}")
969            }
970            UnsafeCellInImmutable => {
971                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("{$front_matter}: encountered `UnsafeCell` in read-only memory"))msg!("{$front_matter}: encountered `UnsafeCell` in read-only memory")
972            }
973            UninhabitedVal { .. } => {
974                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("{$front_matter}: encountered a value of uninhabited type `{$ty}`"))msg!("{$front_matter}: encountered a value of uninhabited type `{$ty}`")
975            }
976            InvalidEnumTag { .. } => {
977                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("{$front_matter}: encountered {$value}, but expected a valid enum tag"))msg!("{$front_matter}: encountered {$value}, but expected a valid enum tag")
978            }
979            UninhabitedEnumVariant => {
980                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("{$front_matter}: encountered an uninhabited enum variant"))msg!("{$front_matter}: encountered an uninhabited enum variant")
981            }
982            Uninit { .. } => {
983                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("{$front_matter}: encountered uninitialized memory, but {$expected}"))msg!("{$front_matter}: encountered uninitialized memory, but {$expected}")
984            }
985            InvalidVTablePtr { .. } => {
986                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("{$front_matter}: encountered {$value}, but expected a vtable pointer"))msg!("{$front_matter}: encountered {$value}, but expected a vtable pointer")
987            }
988            InvalidMetaWrongTrait { .. } => {
989                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("{$front_matter}: wrong trait in wide pointer vtable: expected `{$expected_dyn_type}`, but encountered `{$vtable_dyn_type}`"))msg!(
990                    "{$front_matter}: wrong trait in wide pointer vtable: expected `{$expected_dyn_type}`, but encountered `{$vtable_dyn_type}`"
991                )
992            }
993            InvalidMetaSliceTooLarge { ptr_kind: PointerKind::Box } => {
994                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("{$front_matter}: encountered invalid box metadata: slice is bigger than largest supported object"))msg!(
995                    "{$front_matter}: encountered invalid box metadata: slice is bigger than largest supported object"
996                )
997            }
998            InvalidMetaSliceTooLarge { ptr_kind: PointerKind::Ref(_) } => {
999                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("{$front_matter}: encountered invalid reference metadata: slice is bigger than largest supported object"))msg!(
1000                    "{$front_matter}: encountered invalid reference metadata: slice is bigger than largest supported object"
1001                )
1002            }
1003
1004            InvalidMetaTooLarge { ptr_kind: PointerKind::Box } => {
1005                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("{$front_matter}: encountered invalid box metadata: total size is bigger than largest supported object"))msg!(
1006                    "{$front_matter}: encountered invalid box metadata: total size is bigger than largest supported object"
1007                )
1008            }
1009            InvalidMetaTooLarge { ptr_kind: PointerKind::Ref(_) } => {
1010                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("{$front_matter}: encountered invalid reference metadata: total size is bigger than largest supported object"))msg!(
1011                    "{$front_matter}: encountered invalid reference metadata: total size is bigger than largest supported object"
1012                )
1013            }
1014            UnalignedPtr { ptr_kind: PointerKind::Ref(_), .. } => {
1015                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("{$front_matter}: encountered an unaligned reference (required {$required_bytes} byte alignment but found {$found_bytes})"))msg!(
1016                    "{$front_matter}: encountered an unaligned reference (required {$required_bytes} byte alignment but found {$found_bytes})"
1017                )
1018            }
1019            UnalignedPtr { ptr_kind: PointerKind::Box, .. } => {
1020                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("{$front_matter}: encountered an unaligned box (required {$required_bytes} byte alignment but found {$found_bytes})"))msg!(
1021                    "{$front_matter}: encountered an unaligned box (required {$required_bytes} byte alignment but found {$found_bytes})"
1022                )
1023            }
1024
1025            NullPtr { ptr_kind: PointerKind::Box, .. } => {
1026                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("{$front_matter}: encountered a {$maybe ->\n                        [true] maybe-null\n                        *[false] null\n                    } box"))msg!(
1027                    "{$front_matter}: encountered a {$maybe ->
1028                        [true] maybe-null
1029                        *[false] null
1030                    } box"
1031                )
1032            }
1033            NullPtr { ptr_kind: PointerKind::Ref(_), .. } => {
1034                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("{$front_matter}: encountered a {$maybe ->\n                        [true] maybe-null\n                        *[false] null\n                    } reference"))msg!(
1035                    "{$front_matter}: encountered a {$maybe ->
1036                        [true] maybe-null
1037                        *[false] null
1038                    } reference"
1039                )
1040            }
1041            DanglingPtrNoProvenance { ptr_kind: PointerKind::Box, .. } => {
1042                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("{$front_matter}: encountered a dangling box ({$pointer} has no provenance)"))msg!("{$front_matter}: encountered a dangling box ({$pointer} has no provenance)")
1043            }
1044            DanglingPtrNoProvenance { ptr_kind: PointerKind::Ref(_), .. } => {
1045                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("{$front_matter}: encountered a dangling reference ({$pointer} has no provenance)"))msg!(
1046                    "{$front_matter}: encountered a dangling reference ({$pointer} has no provenance)"
1047                )
1048            }
1049            DanglingPtrOutOfBounds { ptr_kind: PointerKind::Box } => {
1050                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("{$front_matter}: encountered a dangling box (going beyond the bounds of its allocation)"))msg!(
1051                    "{$front_matter}: encountered a dangling box (going beyond the bounds of its allocation)"
1052                )
1053            }
1054            DanglingPtrOutOfBounds { ptr_kind: PointerKind::Ref(_) } => {
1055                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("{$front_matter}: encountered a dangling reference (going beyond the bounds of its allocation)"))msg!(
1056                    "{$front_matter}: encountered a dangling reference (going beyond the bounds of its allocation)"
1057                )
1058            }
1059            DanglingPtrUseAfterFree { ptr_kind: PointerKind::Box } => {
1060                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("{$front_matter}: encountered a dangling box (use-after-free)"))msg!("{$front_matter}: encountered a dangling box (use-after-free)")
1061            }
1062            DanglingPtrUseAfterFree { ptr_kind: PointerKind::Ref(_) } => {
1063                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("{$front_matter}: encountered a dangling reference (use-after-free)"))msg!("{$front_matter}: encountered a dangling reference (use-after-free)")
1064            }
1065            InvalidBool { .. } => {
1066                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("{$front_matter}: encountered {$value}, but expected a boolean"))msg!("{$front_matter}: encountered {$value}, but expected a boolean")
1067            }
1068            InvalidChar { .. } => {
1069                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("{$front_matter}: encountered {$value}, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`)"))msg!(
1070                    "{$front_matter}: encountered {$value}, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`)"
1071                )
1072            }
1073            InvalidFnPtr { .. } => {
1074                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("{$front_matter}: encountered {$value}, but expected a function pointer"))msg!("{$front_matter}: encountered {$value}, but expected a function pointer")
1075            }
1076        }
1077    }
1078
1079    fn add_args<G: EmissionGuarantee>(self, err: &mut Diag<'_, G>) {
1080        use rustc_errors::msg;
1081        use rustc_middle::mir::interpret::ValidationErrorKind::*;
1082
1083        if let PointerAsInt { .. } | PartialPointer = self.kind {
1084            err.help(rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("this code performed an operation that depends on the underlying bytes representing a pointer"))msg!("this code performed an operation that depends on the underlying bytes representing a pointer"));
1085            err.help(rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("the absolute address of a pointer is not known at compile-time, so such operations are not supported"))msg!("the absolute address of a pointer is not known at compile-time, so such operations are not supported"));
1086        }
1087
1088        let message = if let Some(path) = self.path {
1089            err.dcx.eagerly_translate_to_string(
1090                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("constructing invalid value at {$path}"))msg!("constructing invalid value at {$path}"),
1091                [("path".into(), DiagArgValue::Str(path.into()))].iter().map(|(a, b)| (a, b)),
1092            )
1093        } else {
1094            err.dcx.eagerly_translate_to_string(rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("constructing invalid value"))msg!("constructing invalid value"), [].into_iter())
1095        };
1096
1097        err.arg("front_matter", message);
1098
1099        fn add_range_arg<G: EmissionGuarantee>(
1100            r: WrappingRange,
1101            max_hi: u128,
1102            err: &mut Diag<'_, G>,
1103        ) {
1104            let WrappingRange { start: lo, end: hi } = r;
1105            if !(hi <= max_hi) {
    ::core::panicking::panic("assertion failed: hi <= max_hi")
};assert!(hi <= max_hi);
1106            let msg = if lo > hi {
1107                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("less or equal to {$hi}, or greater or equal to {$lo}"))msg!("less or equal to {$hi}, or greater or equal to {$lo}")
1108            } else if lo == hi {
1109                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("equal to {$lo}"))msg!("equal to {$lo}")
1110            } else if lo == 0 {
1111                if !(hi < max_hi) {
    {
        ::core::panicking::panic_fmt(format_args!("should not be printing if the range covers everything"));
    }
};assert!(hi < max_hi, "should not be printing if the range covers everything");
1112                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("less or equal to {$hi}"))msg!("less or equal to {$hi}")
1113            } else if hi == max_hi {
1114                if !(lo > 0) {
    {
        ::core::panicking::panic_fmt(format_args!("should not be printing if the range covers everything"));
    }
};assert!(lo > 0, "should not be printing if the range covers everything");
1115                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("greater or equal to {$lo}"))msg!("greater or equal to {$lo}")
1116            } else {
1117                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("in the range {$lo}..={$hi}"))msg!("in the range {$lo}..={$hi}")
1118            };
1119
1120            let args = [
1121                ("lo".into(), DiagArgValue::Str(lo.to_string().into())),
1122                ("hi".into(), DiagArgValue::Str(hi.to_string().into())),
1123            ];
1124            let args = args.iter().map(|(a, b)| (a, b));
1125            let message = err.dcx.eagerly_translate_to_string(msg, args);
1126            err.arg("in_range", message);
1127        }
1128
1129        match self.kind {
1130            PtrToUninhabited { ty, .. } | UninhabitedVal { ty } => {
1131                err.arg("ty", ty);
1132            }
1133            PointerAsInt { expected } | Uninit { expected } => {
1134                let msg = match expected {
1135                    ExpectedKind::Reference => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("expected a reference"))msg!("expected a reference"),
1136                    ExpectedKind::Box => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("expected a box"))msg!("expected a box"),
1137                    ExpectedKind::RawPtr => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("expected a raw pointer"))msg!("expected a raw pointer"),
1138                    ExpectedKind::InitScalar => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("expected initialized scalar value"))msg!("expected initialized scalar value"),
1139                    ExpectedKind::Bool => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("expected a boolean"))msg!("expected a boolean"),
1140                    ExpectedKind::Char => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("expected a unicode scalar value"))msg!("expected a unicode scalar value"),
1141                    ExpectedKind::Float => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("expected a floating point number"))msg!("expected a floating point number"),
1142                    ExpectedKind::Int => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("expected an integer"))msg!("expected an integer"),
1143                    ExpectedKind::FnPtr => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("expected a function pointer"))msg!("expected a function pointer"),
1144                    ExpectedKind::EnumTag => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("expected a valid enum tag"))msg!("expected a valid enum tag"),
1145                    ExpectedKind::Str => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("expected a string"))msg!("expected a string"),
1146                };
1147                let msg = err.dcx.eagerly_translate_to_string(msg, [].into_iter());
1148                err.arg("expected", msg);
1149            }
1150            InvalidEnumTag { value }
1151            | InvalidVTablePtr { value }
1152            | InvalidBool { value }
1153            | InvalidChar { value }
1154            | InvalidFnPtr { value } => {
1155                err.arg("value", value);
1156            }
1157            PtrOutOfRange { range, max_value } => add_range_arg(range, max_value, err),
1158            OutOfRange { range, max_value, value } => {
1159                err.arg("value", value);
1160                add_range_arg(range, max_value, err);
1161            }
1162            UnalignedPtr { required_bytes, found_bytes, .. } => {
1163                err.arg("required_bytes", required_bytes);
1164                err.arg("found_bytes", found_bytes);
1165            }
1166            DanglingPtrNoProvenance { pointer, .. } => {
1167                err.arg("pointer", pointer);
1168            }
1169            InvalidMetaWrongTrait { vtable_dyn_type, expected_dyn_type } => {
1170                err.arg("vtable_dyn_type", vtable_dyn_type.to_string());
1171                err.arg("expected_dyn_type", expected_dyn_type.to_string());
1172            }
1173            NullPtr { maybe, .. } | NullFnPtr { maybe } => {
1174                err.arg("maybe", maybe);
1175            }
1176            MutableRefToImmutable
1177            | NonnullPtrMaybeNull
1178            | NeverVal
1179            | UnsafeCellInImmutable
1180            | InvalidMetaSliceTooLarge { .. }
1181            | InvalidMetaTooLarge { .. }
1182            | DanglingPtrUseAfterFree { .. }
1183            | DanglingPtrOutOfBounds { .. }
1184            | UninhabitedEnumVariant
1185            | PartialPointer => {}
1186        }
1187    }
1188}
1189
1190impl ReportErrorExt for UnsupportedOpInfo {
1191    fn diagnostic_message(&self) -> DiagMessage {
1192        match self {
1193            UnsupportedOpInfo::Unsupported(s) => s.clone().into(),
1194            UnsupportedOpInfo::ExternTypeField => {
1195                "`extern type` field does not have a known offset".into()
1196            }
1197            UnsupportedOpInfo::UnsizedLocal => "unsized locals are not supported".into(),
1198            UnsupportedOpInfo::ReadPartialPointer(_) => {
1199                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("unable to read parts of a pointer from memory at {$ptr}"))msg!("unable to read parts of a pointer from memory at {$ptr}")
1200            }
1201            UnsupportedOpInfo::ReadPointerAsInt(_) => "unable to turn pointer into integer".into(),
1202            UnsupportedOpInfo::ThreadLocalStatic(_) => {
1203                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("cannot access thread local static `{$did}`"))msg!("cannot access thread local static `{$did}`")
1204            }
1205            UnsupportedOpInfo::ExternStatic(_) => {
1206                rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("cannot access extern static `{$did}`"))msg!("cannot access extern static `{$did}`")
1207            }
1208        }
1209        .into()
1210    }
1211
1212    fn add_args<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
1213        use UnsupportedOpInfo::*;
1214
1215        if let ReadPointerAsInt(_) | ReadPartialPointer(_) = self {
1216            diag.help("this code performed an operation that depends on the underlying bytes representing a pointer");
1217            diag.help("the absolute address of a pointer is not known at compile-time, so such operations are not supported");
1218        }
1219        match self {
1220            // `ReadPointerAsInt(Some(info))` is never printed anyway, it only serves as an error to
1221            // be further processed by validity checking which then turns it into something nice to
1222            // print. So it's not worth the effort of having diagnostics that can print the `info`.
1223            UnsizedLocal
1224            | UnsupportedOpInfo::ExternTypeField
1225            | Unsupported(_)
1226            | ReadPointerAsInt(_) => {}
1227            ReadPartialPointer(ptr) => {
1228                diag.arg("ptr", ptr);
1229            }
1230            ThreadLocalStatic(did) | ExternStatic(did) => rustc_middle::ty::tls::with(|tcx| {
1231                diag.arg("did", tcx.def_path_str(did));
1232            }),
1233        }
1234    }
1235}
1236
1237impl<'tcx> ReportErrorExt for InterpErrorKind<'tcx> {
1238    fn diagnostic_message(&self) -> DiagMessage {
1239        match self {
1240            InterpErrorKind::UndefinedBehavior(ub) => ub.diagnostic_message(),
1241            InterpErrorKind::Unsupported(e) => e.diagnostic_message(),
1242            InterpErrorKind::InvalidProgram(e) => e.diagnostic_message(),
1243            InterpErrorKind::ResourceExhaustion(e) => e.diagnostic_message(),
1244            InterpErrorKind::MachineStop(e) => e.diagnostic_message(),
1245        }
1246    }
1247    fn add_args<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
1248        match self {
1249            InterpErrorKind::UndefinedBehavior(ub) => ub.add_args(diag),
1250            InterpErrorKind::Unsupported(e) => e.add_args(diag),
1251            InterpErrorKind::InvalidProgram(e) => e.add_args(diag),
1252            InterpErrorKind::ResourceExhaustion(e) => e.add_args(diag),
1253            InterpErrorKind::MachineStop(e) => e.add_args(&mut |name, value| {
1254                diag.arg(name, value);
1255            }),
1256        }
1257    }
1258}
1259
1260impl<'tcx> ReportErrorExt for InvalidProgramInfo<'tcx> {
1261    fn diagnostic_message(&self) -> DiagMessage {
1262        match self {
1263            InvalidProgramInfo::TooGeneric => "encountered overly generic constant".into(),
1264            InvalidProgramInfo::AlreadyReported(_) => {
1265                "an error has already been reported elsewhere (this should not usually be printed)"
1266                    .into()
1267            }
1268            InvalidProgramInfo::Layout(e) => e.diagnostic_message(),
1269        }
1270    }
1271    fn add_args<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
1272        match self {
1273            InvalidProgramInfo::TooGeneric | InvalidProgramInfo::AlreadyReported(_) => {}
1274            InvalidProgramInfo::Layout(e) => {
1275                // The level doesn't matter, `dummy_diag` is consumed without it being used.
1276                let dummy_level = Level::Bug;
1277                let dummy_diag: Diag<'_, ()> = e.into_diagnostic().into_diag(diag.dcx, dummy_level);
1278                for (name, val) in dummy_diag.args.iter() {
1279                    diag.arg(name.clone(), val.clone());
1280                }
1281                dummy_diag.cancel();
1282            }
1283        }
1284    }
1285}
1286
1287impl ReportErrorExt for ResourceExhaustionInfo {
1288    fn diagnostic_message(&self) -> DiagMessage {
1289        match self {
1290            ResourceExhaustionInfo::StackFrameLimitReached => {
1291                "reached the configured maximum number of stack frames"
1292            }
1293            ResourceExhaustionInfo::MemoryExhausted => {
1294                "tried to allocate more memory than available to compiler"
1295            }
1296            ResourceExhaustionInfo::AddressSpaceFull => {
1297                "there are no more free addresses in the address space"
1298            }
1299            ResourceExhaustionInfo::Interrupted => "compilation was interrupted",
1300        }
1301        .into()
1302    }
1303    fn add_args<G: EmissionGuarantee>(self, _: &mut Diag<'_, G>) {}
1304}
1305
1306impl rustc_errors::IntoDiagArg for InternKind {
1307    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
1308        DiagArgValue::Str(Cow::Borrowed(match self {
1309            InternKind::Static(Mutability::Not) => "static",
1310            InternKind::Static(Mutability::Mut) => "static_mut",
1311            InternKind::Constant => "const",
1312            InternKind::Promoted => "promoted",
1313        }))
1314    }
1315}