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