• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use rustc_errors::{
2     DiagnosticArgValue, DiagnosticBuilder, DiagnosticMessage, EmissionGuarantee, Handler,
3     IntoDiagnostic,
4 };
5 use rustc_hir::ConstContext;
6 use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
7 use rustc_middle::mir::interpret::{
8     CheckInAllocMsg, ExpectedKind, InterpError, InvalidMetaKind, InvalidProgramInfo, PointerKind,
9     ResourceExhaustionInfo, UndefinedBehaviorInfo, UnsupportedOpInfo, ValidationErrorInfo,
10 };
11 use rustc_middle::ty::{self, Ty};
12 use rustc_span::Span;
13 use rustc_target::abi::call::AdjustForForeignAbiError;
14 use rustc_target::abi::{Size, WrappingRange};
15 
16 #[derive(Diagnostic)]
17 #[diag(const_eval_dangling_ptr_in_final)]
18 pub(crate) struct DanglingPtrInFinal {
19     #[primary_span]
20     pub span: Span,
21 }
22 
23 #[derive(Diagnostic)]
24 #[diag(const_eval_unstable_in_stable)]
25 pub(crate) struct UnstableInStable {
26     pub gate: String,
27     #[primary_span]
28     pub span: Span,
29     #[suggestion(
30         const_eval_unstable_sugg,
31         code = "#[rustc_const_unstable(feature = \"...\", issue = \"...\")]\n",
32         applicability = "has-placeholders"
33     )]
34     #[suggestion(
35         const_eval_bypass_sugg,
36         code = "#[rustc_allow_const_fn_unstable({gate})]\n",
37         applicability = "has-placeholders"
38     )]
39     pub attr_span: Span,
40 }
41 
42 #[derive(Diagnostic)]
43 #[diag(const_eval_thread_local_access, code = "E0625")]
44 pub(crate) struct NonConstOpErr {
45     #[primary_span]
46     pub span: Span,
47 }
48 
49 #[derive(Diagnostic)]
50 #[diag(const_eval_static_access, code = "E0013")]
51 #[help]
52 pub(crate) struct StaticAccessErr {
53     #[primary_span]
54     pub span: Span,
55     pub kind: ConstContext,
56     #[note(const_eval_teach_note)]
57     #[help(const_eval_teach_help)]
58     pub teach: Option<()>,
59 }
60 
61 #[derive(Diagnostic)]
62 #[diag(const_eval_raw_ptr_to_int)]
63 #[note]
64 #[note(const_eval_note2)]
65 pub(crate) struct RawPtrToIntErr {
66     #[primary_span]
67     pub span: Span,
68 }
69 
70 #[derive(Diagnostic)]
71 #[diag(const_eval_raw_ptr_comparison)]
72 #[note]
73 pub(crate) struct RawPtrComparisonErr {
74     #[primary_span]
75     pub span: Span,
76 }
77 
78 #[derive(Diagnostic)]
79 #[diag(const_eval_panic_non_str)]
80 pub(crate) struct PanicNonStrErr {
81     #[primary_span]
82     pub span: Span,
83 }
84 
85 #[derive(Diagnostic)]
86 #[diag(const_eval_mut_deref, code = "E0658")]
87 pub(crate) struct MutDerefErr {
88     #[primary_span]
89     pub span: Span,
90     pub kind: ConstContext,
91 }
92 
93 #[derive(Diagnostic)]
94 #[diag(const_eval_transient_mut_borrow, code = "E0658")]
95 pub(crate) struct TransientMutBorrowErr {
96     #[primary_span]
97     pub span: Span,
98     pub kind: ConstContext,
99 }
100 
101 #[derive(Diagnostic)]
102 #[diag(const_eval_transient_mut_borrow_raw, code = "E0658")]
103 pub(crate) struct TransientMutBorrowErrRaw {
104     #[primary_span]
105     pub span: Span,
106     pub kind: ConstContext,
107 }
108 
109 #[derive(Diagnostic)]
110 #[diag(const_eval_max_num_nodes_in_const)]
111 pub(crate) struct MaxNumNodesInConstErr {
112     #[primary_span]
113     pub span: Option<Span>,
114     pub global_const_id: String,
115 }
116 
117 #[derive(Diagnostic)]
118 #[diag(const_eval_unallowed_fn_pointer_call)]
119 pub(crate) struct UnallowedFnPointerCall {
120     #[primary_span]
121     pub span: Span,
122     pub kind: ConstContext,
123 }
124 
125 #[derive(Diagnostic)]
126 #[diag(const_eval_unstable_const_fn)]
127 pub(crate) struct UnstableConstFn {
128     #[primary_span]
129     pub span: Span,
130     pub def_path: String,
131 }
132 
133 #[derive(Diagnostic)]
134 #[diag(const_eval_unallowed_mutable_refs, code = "E0764")]
135 pub(crate) struct UnallowedMutableRefs {
136     #[primary_span]
137     pub span: Span,
138     pub kind: ConstContext,
139     #[note(const_eval_teach_note)]
140     pub teach: Option<()>,
141 }
142 
143 #[derive(Diagnostic)]
144 #[diag(const_eval_unallowed_mutable_refs_raw, code = "E0764")]
145 pub(crate) struct UnallowedMutableRefsRaw {
146     #[primary_span]
147     pub span: Span,
148     pub kind: ConstContext,
149     #[note(const_eval_teach_note)]
150     pub teach: Option<()>,
151 }
152 #[derive(Diagnostic)]
153 #[diag(const_eval_non_const_fmt_macro_call, code = "E0015")]
154 pub(crate) struct NonConstFmtMacroCall {
155     #[primary_span]
156     pub span: Span,
157     pub kind: ConstContext,
158 }
159 
160 #[derive(Diagnostic)]
161 #[diag(const_eval_non_const_fn_call, code = "E0015")]
162 pub(crate) struct NonConstFnCall {
163     #[primary_span]
164     pub span: Span,
165     pub def_path_str: String,
166     pub kind: ConstContext,
167 }
168 
169 #[derive(Diagnostic)]
170 #[diag(const_eval_unallowed_op_in_const_context)]
171 pub(crate) struct UnallowedOpInConstContext {
172     #[primary_span]
173     pub span: Span,
174     pub msg: String,
175 }
176 
177 #[derive(Diagnostic)]
178 #[diag(const_eval_unallowed_heap_allocations, code = "E0010")]
179 pub(crate) struct UnallowedHeapAllocations {
180     #[primary_span]
181     #[label]
182     pub span: Span,
183     pub kind: ConstContext,
184     #[note(const_eval_teach_note)]
185     pub teach: Option<()>,
186 }
187 
188 #[derive(Diagnostic)]
189 #[diag(const_eval_unallowed_inline_asm, code = "E0015")]
190 pub(crate) struct UnallowedInlineAsm {
191     #[primary_span]
192     pub span: Span,
193     pub kind: ConstContext,
194 }
195 
196 #[derive(Diagnostic)]
197 #[diag(const_eval_unsupported_untyped_pointer)]
198 #[note]
199 pub(crate) struct UnsupportedUntypedPointer {
200     #[primary_span]
201     pub span: Span,
202 }
203 
204 #[derive(Diagnostic)]
205 #[diag(const_eval_interior_mutable_data_refer, code = "E0492")]
206 pub(crate) struct InteriorMutableDataRefer {
207     #[primary_span]
208     #[label]
209     pub span: Span,
210     #[help]
211     pub opt_help: Option<()>,
212     pub kind: ConstContext,
213     #[note(const_eval_teach_note)]
214     pub teach: Option<()>,
215 }
216 
217 #[derive(Diagnostic)]
218 #[diag(const_eval_interior_mutability_borrow)]
219 pub(crate) struct InteriorMutabilityBorrow {
220     #[primary_span]
221     pub span: Span,
222 }
223 
224 #[derive(LintDiagnostic)]
225 #[diag(const_eval_long_running)]
226 #[note]
227 pub struct LongRunning {
228     #[help]
229     pub item_span: Span,
230 }
231 
232 #[derive(Diagnostic)]
233 #[diag(const_eval_long_running)]
234 pub struct LongRunningWarn {
235     #[primary_span]
236     #[label]
237     pub span: Span,
238     #[help]
239     pub item_span: Span,
240 }
241 
242 #[derive(Diagnostic)]
243 #[diag(const_eval_erroneous_constant)]
244 pub(crate) struct ErroneousConstUsed {
245     #[primary_span]
246     pub span: Span,
247 }
248 
249 #[derive(Subdiagnostic)]
250 #[note(const_eval_non_const_impl)]
251 pub(crate) struct NonConstImplNote {
252     #[primary_span]
253     pub span: Span,
254 }
255 
256 #[derive(Subdiagnostic, PartialEq, Eq, Clone)]
257 #[note(const_eval_frame_note)]
258 pub struct FrameNote {
259     #[primary_span]
260     pub span: Span,
261     pub times: i32,
262     pub where_: &'static str,
263     pub instance: String,
264 }
265 
266 #[derive(Subdiagnostic)]
267 #[note(const_eval_raw_bytes)]
268 pub struct RawBytesNote {
269     pub size: u64,
270     pub align: u64,
271     pub bytes: String,
272 }
273 
274 // FIXME(fee1-dead) do not use stringly typed `ConstContext`
275 
276 #[derive(Diagnostic)]
277 #[diag(const_eval_match_eq_non_const, code = "E0015")]
278 #[note]
279 pub struct NonConstMatchEq<'tcx> {
280     #[primary_span]
281     pub span: Span,
282     pub ty: Ty<'tcx>,
283     pub kind: ConstContext,
284 }
285 
286 #[derive(Diagnostic)]
287 #[diag(const_eval_for_loop_into_iter_non_const, code = "E0015")]
288 pub struct NonConstForLoopIntoIter<'tcx> {
289     #[primary_span]
290     pub span: Span,
291     pub ty: Ty<'tcx>,
292     pub kind: ConstContext,
293 }
294 
295 #[derive(Diagnostic)]
296 #[diag(const_eval_question_branch_non_const, code = "E0015")]
297 pub struct NonConstQuestionBranch<'tcx> {
298     #[primary_span]
299     pub span: Span,
300     pub ty: Ty<'tcx>,
301     pub kind: ConstContext,
302 }
303 
304 #[derive(Diagnostic)]
305 #[diag(const_eval_question_from_residual_non_const, code = "E0015")]
306 pub struct NonConstQuestionFromResidual<'tcx> {
307     #[primary_span]
308     pub span: Span,
309     pub ty: Ty<'tcx>,
310     pub kind: ConstContext,
311 }
312 
313 #[derive(Diagnostic)]
314 #[diag(const_eval_try_block_from_output_non_const, code = "E0015")]
315 pub struct NonConstTryBlockFromOutput<'tcx> {
316     #[primary_span]
317     pub span: Span,
318     pub ty: Ty<'tcx>,
319     pub kind: ConstContext,
320 }
321 
322 #[derive(Diagnostic)]
323 #[diag(const_eval_await_non_const, code = "E0015")]
324 pub struct NonConstAwait<'tcx> {
325     #[primary_span]
326     pub span: Span,
327     pub ty: Ty<'tcx>,
328     pub kind: ConstContext,
329 }
330 
331 #[derive(Diagnostic)]
332 #[diag(const_eval_closure_non_const, code = "E0015")]
333 pub struct NonConstClosure {
334     #[primary_span]
335     pub span: Span,
336     pub kind: ConstContext,
337     #[subdiagnostic]
338     pub note: Option<NonConstClosureNote>,
339 }
340 
341 #[derive(Subdiagnostic)]
342 pub enum NonConstClosureNote {
343     #[note(const_eval_closure_fndef_not_const)]
344     FnDef {
345         #[primary_span]
346         span: Span,
347     },
348     #[note(const_eval_fn_ptr_call)]
349     FnPtr,
350     #[note(const_eval_closure_call)]
351     Closure,
352 }
353 
354 #[derive(Subdiagnostic)]
355 #[multipart_suggestion(const_eval_consider_dereferencing, applicability = "machine-applicable")]
356 pub struct ConsiderDereferencing {
357     pub deref: String,
358     #[suggestion_part(code = "{deref}")]
359     pub span: Span,
360     #[suggestion_part(code = "{deref}")]
361     pub rhs_span: Span,
362 }
363 
364 #[derive(Diagnostic)]
365 #[diag(const_eval_operator_non_const, code = "E0015")]
366 pub struct NonConstOperator {
367     #[primary_span]
368     pub span: Span,
369     pub kind: ConstContext,
370     #[subdiagnostic]
371     pub sugg: Option<ConsiderDereferencing>,
372 }
373 
374 #[derive(Diagnostic)]
375 #[diag(const_eval_deref_coercion_non_const, code = "E0015")]
376 #[note]
377 pub struct NonConstDerefCoercion<'tcx> {
378     #[primary_span]
379     pub span: Span,
380     pub ty: Ty<'tcx>,
381     pub kind: ConstContext,
382     pub target_ty: Ty<'tcx>,
383     #[note(const_eval_target_note)]
384     pub deref_target: Option<Span>,
385 }
386 
387 #[derive(Diagnostic)]
388 #[diag(const_eval_live_drop, code = "E0493")]
389 pub struct LiveDrop<'tcx> {
390     #[primary_span]
391     #[label]
392     pub span: Span,
393     pub kind: ConstContext,
394     pub dropped_ty: Ty<'tcx>,
395     #[label(const_eval_dropped_at_label)]
396     pub dropped_at: Option<Span>,
397 }
398 
399 #[derive(LintDiagnostic)]
400 #[diag(const_eval_align_check_failed)]
401 pub struct AlignmentCheckFailed {
402     pub has: u64,
403     pub required: u64,
404     #[subdiagnostic]
405     pub frames: Vec<FrameNote>,
406 }
407 
408 #[derive(Diagnostic)]
409 #[diag(const_eval_error, code = "E0080")]
410 pub struct ConstEvalError {
411     #[primary_span]
412     pub span: Span,
413     /// One of "const", "const_with_path", and "static"
414     pub error_kind: &'static str,
415     pub instance: String,
416     #[subdiagnostic]
417     pub frame_notes: Vec<FrameNote>,
418 }
419 
420 #[derive(Diagnostic)]
421 #[diag(const_eval_nullary_intrinsic_fail)]
422 pub struct NullaryIntrinsicError {
423     #[primary_span]
424     pub span: Span,
425 }
426 
427 #[derive(Diagnostic)]
428 #[diag(const_eval_undefined_behavior, code = "E0080")]
429 pub struct UndefinedBehavior {
430     #[primary_span]
431     pub span: Span,
432     #[note(const_eval_undefined_behavior_note)]
433     pub ub_note: Option<()>,
434     #[subdiagnostic]
435     pub frames: Vec<FrameNote>,
436     #[subdiagnostic]
437     pub raw_bytes: RawBytesNote,
438 }
439 
440 pub trait ReportErrorExt {
441     /// Returns the diagnostic message for this error.
diagnostic_message(&self) -> DiagnosticMessage442     fn diagnostic_message(&self) -> DiagnosticMessage;
add_args<G: EmissionGuarantee>( self, handler: &Handler, builder: &mut DiagnosticBuilder<'_, G>, )443     fn add_args<G: EmissionGuarantee>(
444         self,
445         handler: &Handler,
446         builder: &mut DiagnosticBuilder<'_, G>,
447     );
448 
debug(self) -> String where Self: Sized,449     fn debug(self) -> String
450     where
451         Self: Sized,
452     {
453         ty::tls::with(move |tcx| {
454             let mut builder = tcx.sess.struct_allow(DiagnosticMessage::Str(String::new().into()));
455             let handler = &tcx.sess.parse_sess.span_diagnostic;
456             let message = self.diagnostic_message();
457             self.add_args(handler, &mut builder);
458             let s = handler.eagerly_translate_to_string(message, builder.args());
459             builder.cancel();
460             s
461         })
462     }
463 }
464 
bad_pointer_message(msg: CheckInAllocMsg, handler: &Handler) -> String465 fn bad_pointer_message(msg: CheckInAllocMsg, handler: &Handler) -> String {
466     use crate::fluent_generated::*;
467 
468     let msg = match msg {
469         CheckInAllocMsg::DerefTest => const_eval_deref_test,
470         CheckInAllocMsg::MemoryAccessTest => const_eval_memory_access_test,
471         CheckInAllocMsg::PointerArithmeticTest => const_eval_pointer_arithmetic_test,
472         CheckInAllocMsg::OffsetFromTest => const_eval_offset_from_test,
473         CheckInAllocMsg::InboundsTest => const_eval_in_bounds_test,
474     };
475 
476     handler.eagerly_translate_to_string(msg, [].into_iter())
477 }
478 
479 impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> {
diagnostic_message(&self) -> DiagnosticMessage480     fn diagnostic_message(&self) -> DiagnosticMessage {
481         use crate::fluent_generated::*;
482         use UndefinedBehaviorInfo::*;
483         match self {
484             Ub(msg) => msg.clone().into(),
485             Unreachable => const_eval_unreachable,
486             BoundsCheckFailed { .. } => const_eval_bounds_check_failed,
487             DivisionByZero => const_eval_division_by_zero,
488             RemainderByZero => const_eval_remainder_by_zero,
489             DivisionOverflow => const_eval_division_overflow,
490             RemainderOverflow => const_eval_remainder_overflow,
491             PointerArithOverflow => const_eval_pointer_arithmetic_overflow,
492             InvalidMeta(InvalidMetaKind::SliceTooBig) => const_eval_invalid_meta_slice,
493             InvalidMeta(InvalidMetaKind::TooBig) => const_eval_invalid_meta,
494             UnterminatedCString(_) => const_eval_unterminated_c_string,
495             PointerUseAfterFree(_) => const_eval_pointer_use_after_free,
496             PointerOutOfBounds { ptr_size: Size::ZERO, .. } => const_eval_zst_pointer_out_of_bounds,
497             PointerOutOfBounds { .. } => const_eval_pointer_out_of_bounds,
498             DanglingIntPointer(0, _) => const_eval_dangling_null_pointer,
499             DanglingIntPointer(_, _) => const_eval_dangling_int_pointer,
500             AlignmentCheckFailed { .. } => const_eval_alignment_check_failed,
501             WriteToReadOnly(_) => const_eval_write_to_read_only,
502             DerefFunctionPointer(_) => const_eval_deref_function_pointer,
503             DerefVTablePointer(_) => const_eval_deref_vtable_pointer,
504             InvalidBool(_) => const_eval_invalid_bool,
505             InvalidChar(_) => const_eval_invalid_char,
506             InvalidTag(_) => const_eval_invalid_tag,
507             InvalidFunctionPointer(_) => const_eval_invalid_function_pointer,
508             InvalidVTablePointer(_) => const_eval_invalid_vtable_pointer,
509             InvalidStr(_) => const_eval_invalid_str,
510             InvalidUninitBytes(None) => const_eval_invalid_uninit_bytes_unknown,
511             InvalidUninitBytes(Some(_)) => const_eval_invalid_uninit_bytes,
512             DeadLocal => const_eval_dead_local,
513             ScalarSizeMismatch(_) => const_eval_scalar_size_mismatch,
514             UninhabitedEnumVariantWritten => const_eval_uninhabited_enum_variant_written,
515             Validation(e) => e.diagnostic_message(),
516             Custom(x) => (x.msg)(),
517         }
518     }
519 
add_args<G: EmissionGuarantee>( self, handler: &Handler, builder: &mut DiagnosticBuilder<'_, G>, )520     fn add_args<G: EmissionGuarantee>(
521         self,
522         handler: &Handler,
523         builder: &mut DiagnosticBuilder<'_, G>,
524     ) {
525         use UndefinedBehaviorInfo::*;
526         match self {
527             Ub(_)
528             | Unreachable
529             | DivisionByZero
530             | RemainderByZero
531             | DivisionOverflow
532             | RemainderOverflow
533             | PointerArithOverflow
534             | InvalidMeta(InvalidMetaKind::SliceTooBig)
535             | InvalidMeta(InvalidMetaKind::TooBig)
536             | InvalidUninitBytes(None)
537             | DeadLocal
538             | UninhabitedEnumVariantWritten => {}
539             BoundsCheckFailed { len, index } => {
540                 builder.set_arg("len", len);
541                 builder.set_arg("index", index);
542             }
543             UnterminatedCString(ptr) | InvalidFunctionPointer(ptr) | InvalidVTablePointer(ptr) => {
544                 builder.set_arg("pointer", ptr);
545             }
546             PointerUseAfterFree(allocation) => {
547                 builder.set_arg("allocation", allocation);
548             }
549             PointerOutOfBounds { alloc_id, alloc_size, ptr_offset, ptr_size, msg } => {
550                 builder
551                     .set_arg("alloc_id", alloc_id)
552                     .set_arg("alloc_size", alloc_size.bytes())
553                     .set_arg("ptr_offset", ptr_offset)
554                     .set_arg("ptr_size", ptr_size.bytes())
555                     .set_arg("bad_pointer_message", bad_pointer_message(msg, handler));
556             }
557             DanglingIntPointer(ptr, msg) => {
558                 if ptr != 0 {
559                     builder.set_arg("pointer", format!("{ptr:#x}[noalloc]"));
560                 }
561 
562                 builder.set_arg("bad_pointer_message", bad_pointer_message(msg, handler));
563             }
564             AlignmentCheckFailed { required, has } => {
565                 builder.set_arg("required", required.bytes());
566                 builder.set_arg("has", has.bytes());
567             }
568             WriteToReadOnly(alloc) | DerefFunctionPointer(alloc) | DerefVTablePointer(alloc) => {
569                 builder.set_arg("allocation", alloc);
570             }
571             InvalidBool(b) => {
572                 builder.set_arg("value", format!("{b:02x}"));
573             }
574             InvalidChar(c) => {
575                 builder.set_arg("value", format!("{c:08x}"));
576             }
577             InvalidTag(tag) => {
578                 builder.set_arg("tag", format!("{tag:x}"));
579             }
580             InvalidStr(err) => {
581                 builder.set_arg("err", format!("{err}"));
582             }
583             InvalidUninitBytes(Some((alloc, info))) => {
584                 builder.set_arg("alloc", alloc);
585                 builder.set_arg("access", info.access);
586                 builder.set_arg("uninit", info.uninit);
587             }
588             ScalarSizeMismatch(info) => {
589                 builder.set_arg("target_size", info.target_size);
590                 builder.set_arg("data_size", info.data_size);
591             }
592             Validation(e) => e.add_args(handler, builder),
593             Custom(custom) => {
594                 (custom.add_args)(&mut |name, value| {
595                     builder.set_arg(name, value);
596                 });
597             }
598         }
599     }
600 }
601 
602 impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> {
diagnostic_message(&self) -> DiagnosticMessage603     fn diagnostic_message(&self) -> DiagnosticMessage {
604         use crate::fluent_generated::*;
605         use rustc_middle::mir::interpret::ValidationErrorKind::*;
606         match self.kind {
607             PtrToUninhabited { ptr_kind: PointerKind::Box, .. } => const_eval_box_to_uninhabited,
608             PtrToUninhabited { ptr_kind: PointerKind::Ref, .. } => const_eval_ref_to_uninhabited,
609 
610             PtrToStatic { ptr_kind: PointerKind::Box } => const_eval_box_to_static,
611             PtrToStatic { ptr_kind: PointerKind::Ref } => const_eval_ref_to_static,
612 
613             PtrToMut { ptr_kind: PointerKind::Box } => const_eval_box_to_mut,
614             PtrToMut { ptr_kind: PointerKind::Ref } => const_eval_ref_to_mut,
615 
616             ExpectedNonPtr { .. } => const_eval_expected_non_ptr,
617             MutableRefInConst => const_eval_mutable_ref_in_const,
618             NullFnPtr => const_eval_null_fn_ptr,
619             NeverVal => const_eval_never_val,
620             NullablePtrOutOfRange { .. } => const_eval_nullable_ptr_out_of_range,
621             PtrOutOfRange { .. } => const_eval_ptr_out_of_range,
622             OutOfRange { .. } => const_eval_out_of_range,
623             UnsafeCell => const_eval_unsafe_cell,
624             UninhabitedVal { .. } => const_eval_uninhabited_val,
625             InvalidEnumTag { .. } => const_eval_invalid_enum_tag,
626             UninitEnumTag => const_eval_uninit_enum_tag,
627             UninitStr => const_eval_uninit_str,
628             Uninit { expected: ExpectedKind::Bool } => const_eval_uninit_bool,
629             Uninit { expected: ExpectedKind::Reference } => const_eval_uninit_ref,
630             Uninit { expected: ExpectedKind::Box } => const_eval_uninit_box,
631             Uninit { expected: ExpectedKind::RawPtr } => const_eval_uninit_raw_ptr,
632             Uninit { expected: ExpectedKind::InitScalar } => const_eval_uninit_init_scalar,
633             Uninit { expected: ExpectedKind::Char } => const_eval_uninit_char,
634             Uninit { expected: ExpectedKind::Float } => const_eval_uninit_float,
635             Uninit { expected: ExpectedKind::Int } => const_eval_uninit_int,
636             Uninit { expected: ExpectedKind::FnPtr } => const_eval_uninit_fn_ptr,
637             UninitVal => const_eval_uninit,
638             InvalidVTablePtr { .. } => const_eval_invalid_vtable_ptr,
639             InvalidMetaSliceTooLarge { ptr_kind: PointerKind::Box } => {
640                 const_eval_invalid_box_slice_meta
641             }
642             InvalidMetaSliceTooLarge { ptr_kind: PointerKind::Ref } => {
643                 const_eval_invalid_ref_slice_meta
644             }
645 
646             InvalidMetaTooLarge { ptr_kind: PointerKind::Box } => const_eval_invalid_box_meta,
647             InvalidMetaTooLarge { ptr_kind: PointerKind::Ref } => const_eval_invalid_ref_meta,
648             UnalignedPtr { ptr_kind: PointerKind::Ref, .. } => const_eval_unaligned_ref,
649             UnalignedPtr { ptr_kind: PointerKind::Box, .. } => const_eval_unaligned_box,
650 
651             NullPtr { ptr_kind: PointerKind::Box } => const_eval_null_box,
652             NullPtr { ptr_kind: PointerKind::Ref } => const_eval_null_ref,
653             DanglingPtrNoProvenance { ptr_kind: PointerKind::Box, .. } => {
654                 const_eval_dangling_box_no_provenance
655             }
656             DanglingPtrNoProvenance { ptr_kind: PointerKind::Ref, .. } => {
657                 const_eval_dangling_ref_no_provenance
658             }
659             DanglingPtrOutOfBounds { ptr_kind: PointerKind::Box } => {
660                 const_eval_dangling_box_out_of_bounds
661             }
662             DanglingPtrOutOfBounds { ptr_kind: PointerKind::Ref } => {
663                 const_eval_dangling_ref_out_of_bounds
664             }
665             DanglingPtrUseAfterFree { ptr_kind: PointerKind::Box } => {
666                 const_eval_dangling_box_use_after_free
667             }
668             DanglingPtrUseAfterFree { ptr_kind: PointerKind::Ref } => {
669                 const_eval_dangling_ref_use_after_free
670             }
671             InvalidBool { .. } => const_eval_validation_invalid_bool,
672             InvalidChar { .. } => const_eval_validation_invalid_char,
673             InvalidFnPtr { .. } => const_eval_invalid_fn_ptr,
674         }
675     }
676 
add_args<G: EmissionGuarantee>(self, handler: &Handler, err: &mut DiagnosticBuilder<'_, G>)677     fn add_args<G: EmissionGuarantee>(self, handler: &Handler, err: &mut DiagnosticBuilder<'_, G>) {
678         use crate::fluent_generated as fluent;
679         use rustc_middle::mir::interpret::ValidationErrorKind::*;
680 
681         let message = if let Some(path) = self.path {
682             handler.eagerly_translate_to_string(
683                 fluent::const_eval_invalid_value_with_path,
684                 [("path".into(), DiagnosticArgValue::Str(path.into()))].iter().map(|(a, b)| (a, b)),
685             )
686         } else {
687             handler.eagerly_translate_to_string(fluent::const_eval_invalid_value, [].into_iter())
688         };
689 
690         err.set_arg("front_matter", message);
691 
692         fn add_range_arg<G: EmissionGuarantee>(
693             r: WrappingRange,
694             max_hi: u128,
695             handler: &Handler,
696             err: &mut DiagnosticBuilder<'_, G>,
697         ) {
698             let WrappingRange { start: lo, end: hi } = r;
699             assert!(hi <= max_hi);
700             let msg = if lo > hi {
701                 fluent::const_eval_range_wrapping
702             } else if lo == hi {
703                 fluent::const_eval_range_singular
704             } else if lo == 0 {
705                 assert!(hi < max_hi, "should not be printing if the range covers everything");
706                 fluent::const_eval_range_upper
707             } else if hi == max_hi {
708                 assert!(lo > 0, "should not be printing if the range covers everything");
709                 fluent::const_eval_range_lower
710             } else {
711                 fluent::const_eval_range
712             };
713 
714             let args = [
715                 ("lo".into(), DiagnosticArgValue::Str(lo.to_string().into())),
716                 ("hi".into(), DiagnosticArgValue::Str(hi.to_string().into())),
717             ];
718             let args = args.iter().map(|(a, b)| (a, b));
719             let message = handler.eagerly_translate_to_string(msg, args);
720             err.set_arg("in_range", message);
721         }
722 
723         match self.kind {
724             PtrToUninhabited { ty, .. } | UninhabitedVal { ty } => {
725                 err.set_arg("ty", ty);
726             }
727             ExpectedNonPtr { value }
728             | InvalidEnumTag { value }
729             | InvalidVTablePtr { value }
730             | InvalidBool { value }
731             | InvalidChar { value }
732             | InvalidFnPtr { value } => {
733                 err.set_arg("value", value);
734             }
735             NullablePtrOutOfRange { range, max_value } | PtrOutOfRange { range, max_value } => {
736                 add_range_arg(range, max_value, handler, err)
737             }
738             OutOfRange { range, max_value, value } => {
739                 err.set_arg("value", value);
740                 add_range_arg(range, max_value, handler, err);
741             }
742             UnalignedPtr { required_bytes, found_bytes, .. } => {
743                 err.set_arg("required_bytes", required_bytes);
744                 err.set_arg("found_bytes", found_bytes);
745             }
746             DanglingPtrNoProvenance { pointer, .. } => {
747                 err.set_arg("pointer", pointer);
748             }
749             NullPtr { .. }
750             | PtrToStatic { .. }
751             | PtrToMut { .. }
752             | MutableRefInConst
753             | NullFnPtr
754             | NeverVal
755             | UnsafeCell
756             | UninitEnumTag
757             | UninitStr
758             | Uninit { .. }
759             | UninitVal
760             | InvalidMetaSliceTooLarge { .. }
761             | InvalidMetaTooLarge { .. }
762             | DanglingPtrUseAfterFree { .. }
763             | DanglingPtrOutOfBounds { .. } => {}
764         }
765     }
766 }
767 
768 impl ReportErrorExt for UnsupportedOpInfo {
diagnostic_message(&self) -> DiagnosticMessage769     fn diagnostic_message(&self) -> DiagnosticMessage {
770         use crate::fluent_generated::*;
771         match self {
772             UnsupportedOpInfo::Unsupported(s) => s.clone().into(),
773             UnsupportedOpInfo::PartialPointerOverwrite(_) => const_eval_partial_pointer_overwrite,
774             UnsupportedOpInfo::PartialPointerCopy(_) => const_eval_partial_pointer_copy,
775             UnsupportedOpInfo::ReadPointerAsBytes => const_eval_read_pointer_as_bytes,
776             UnsupportedOpInfo::ThreadLocalStatic(_) => const_eval_thread_local_static,
777             UnsupportedOpInfo::ReadExternStatic(_) => const_eval_read_extern_static,
778         }
779     }
add_args<G: EmissionGuarantee>(self, _: &Handler, builder: &mut DiagnosticBuilder<'_, G>)780     fn add_args<G: EmissionGuarantee>(self, _: &Handler, builder: &mut DiagnosticBuilder<'_, G>) {
781         use crate::fluent_generated::*;
782 
783         use UnsupportedOpInfo::*;
784         if let ReadPointerAsBytes | PartialPointerOverwrite(_) | PartialPointerCopy(_) = self {
785             builder.help(const_eval_ptr_as_bytes_1);
786             builder.help(const_eval_ptr_as_bytes_2);
787         }
788         match self {
789             Unsupported(_) | ReadPointerAsBytes => {}
790             PartialPointerOverwrite(ptr) | PartialPointerCopy(ptr) => {
791                 builder.set_arg("ptr", ptr);
792             }
793             ThreadLocalStatic(did) | ReadExternStatic(did) => {
794                 builder.set_arg("did", format!("{did:?}"));
795             }
796         }
797     }
798 }
799 
800 impl<'tcx> ReportErrorExt for InterpError<'tcx> {
diagnostic_message(&self) -> DiagnosticMessage801     fn diagnostic_message(&self) -> DiagnosticMessage {
802         match self {
803             InterpError::UndefinedBehavior(ub) => ub.diagnostic_message(),
804             InterpError::Unsupported(e) => e.diagnostic_message(),
805             InterpError::InvalidProgram(e) => e.diagnostic_message(),
806             InterpError::ResourceExhaustion(e) => e.diagnostic_message(),
807             InterpError::MachineStop(e) => e.diagnostic_message(),
808         }
809     }
add_args<G: EmissionGuarantee>( self, handler: &Handler, builder: &mut DiagnosticBuilder<'_, G>, )810     fn add_args<G: EmissionGuarantee>(
811         self,
812         handler: &Handler,
813         builder: &mut DiagnosticBuilder<'_, G>,
814     ) {
815         match self {
816             InterpError::UndefinedBehavior(ub) => ub.add_args(handler, builder),
817             InterpError::Unsupported(e) => e.add_args(handler, builder),
818             InterpError::InvalidProgram(e) => e.add_args(handler, builder),
819             InterpError::ResourceExhaustion(e) => e.add_args(handler, builder),
820             InterpError::MachineStop(e) => e.add_args(&mut |name, value| {
821                 builder.set_arg(name, value);
822             }),
823         }
824     }
825 }
826 
827 impl<'tcx> ReportErrorExt for InvalidProgramInfo<'tcx> {
diagnostic_message(&self) -> DiagnosticMessage828     fn diagnostic_message(&self) -> DiagnosticMessage {
829         use crate::fluent_generated::*;
830         match self {
831             InvalidProgramInfo::TooGeneric => const_eval_too_generic,
832             InvalidProgramInfo::AlreadyReported(_) => const_eval_already_reported,
833             InvalidProgramInfo::Layout(e) => e.diagnostic_message(),
834             InvalidProgramInfo::FnAbiAdjustForForeignAbi(_) => {
835                 rustc_middle::error::middle_adjust_for_foreign_abi_error
836             }
837             InvalidProgramInfo::SizeOfUnsizedType(_) => const_eval_size_of_unsized,
838             InvalidProgramInfo::UninitUnsizedLocal => const_eval_uninit_unsized_local,
839         }
840     }
add_args<G: EmissionGuarantee>( self, handler: &Handler, builder: &mut DiagnosticBuilder<'_, G>, )841     fn add_args<G: EmissionGuarantee>(
842         self,
843         handler: &Handler,
844         builder: &mut DiagnosticBuilder<'_, G>,
845     ) {
846         match self {
847             InvalidProgramInfo::TooGeneric
848             | InvalidProgramInfo::AlreadyReported(_)
849             | InvalidProgramInfo::UninitUnsizedLocal => {}
850             InvalidProgramInfo::Layout(e) => {
851                 let diag: DiagnosticBuilder<'_, ()> = e.into_diagnostic().into_diagnostic(handler);
852                 for (name, val) in diag.args() {
853                     builder.set_arg(name.clone(), val.clone());
854                 }
855                 diag.cancel();
856             }
857             InvalidProgramInfo::FnAbiAdjustForForeignAbi(
858                 AdjustForForeignAbiError::Unsupported { arch, abi },
859             ) => {
860                 builder.set_arg("arch", arch);
861                 builder.set_arg("abi", abi.name());
862             }
863             InvalidProgramInfo::SizeOfUnsizedType(ty) => {
864                 builder.set_arg("ty", ty);
865             }
866         }
867     }
868 }
869 
870 impl ReportErrorExt for ResourceExhaustionInfo {
diagnostic_message(&self) -> DiagnosticMessage871     fn diagnostic_message(&self) -> DiagnosticMessage {
872         use crate::fluent_generated::*;
873         match self {
874             ResourceExhaustionInfo::StackFrameLimitReached => const_eval_stack_frame_limit_reached,
875             ResourceExhaustionInfo::MemoryExhausted => const_eval_memory_exhausted,
876             ResourceExhaustionInfo::AddressSpaceFull => const_eval_address_space_full,
877         }
878     }
add_args<G: EmissionGuarantee>(self, _: &Handler, _: &mut DiagnosticBuilder<'_, G>)879     fn add_args<G: EmissionGuarantee>(self, _: &Handler, _: &mut DiagnosticBuilder<'_, G>) {}
880 }
881