]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_const_eval/src/errors.rs
New upstream version 1.73.0+dfsg1
[rustc.git] / compiler / rustc_const_eval / src / errors.rs
CommitLineData
fe692bf9
FG
1use rustc_errors::{
2 DiagnosticArgValue, DiagnosticBuilder, DiagnosticMessage, EmissionGuarantee, Handler,
3 IntoDiagnostic,
4};
064997fb 5use rustc_hir::ConstContext;
fe692bf9
FG
6use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
7use rustc_middle::mir::interpret::{
8 CheckInAllocMsg, ExpectedKind, InterpError, InvalidMetaKind, InvalidProgramInfo, PointerKind,
9 ResourceExhaustionInfo, UndefinedBehaviorInfo, UnsupportedOpInfo, ValidationErrorInfo,
10};
11use rustc_middle::ty::{self, Ty};
064997fb 12use rustc_span::Span;
fe692bf9
FG
13use rustc_target::abi::call::AdjustForForeignAbiError;
14use rustc_target::abi::{Size, WrappingRange};
15
16#[derive(Diagnostic)]
17#[diag(const_eval_dangling_ptr_in_final)]
18pub(crate) struct DanglingPtrInFinal {
19 #[primary_span]
20 pub span: Span,
21}
064997fb 22
2b03887a
FG
23#[derive(Diagnostic)]
24#[diag(const_eval_unstable_in_stable)]
064997fb
FG
25pub(crate) struct UnstableInStable {
26 pub gate: String,
27 #[primary_span]
28 pub span: Span,
29 #[suggestion(
9ffffee4 30 const_eval_unstable_sugg,
064997fb
FG
31 code = "#[rustc_const_unstable(feature = \"...\", issue = \"...\")]\n",
32 applicability = "has-placeholders"
33 )]
34 #[suggestion(
9ffffee4 35 const_eval_bypass_sugg,
064997fb
FG
36 code = "#[rustc_allow_const_fn_unstable({gate})]\n",
37 applicability = "has-placeholders"
38 )]
39 pub attr_span: Span,
40}
41
2b03887a
FG
42#[derive(Diagnostic)]
43#[diag(const_eval_thread_local_access, code = "E0625")]
064997fb
FG
44pub(crate) struct NonConstOpErr {
45 #[primary_span]
46 pub span: Span,
47}
48
2b03887a
FG
49#[derive(Diagnostic)]
50#[diag(const_eval_static_access, code = "E0013")]
064997fb
FG
51#[help]
52pub(crate) struct StaticAccessErr {
53 #[primary_span]
54 pub span: Span,
55 pub kind: ConstContext,
9ffffee4
FG
56 #[note(const_eval_teach_note)]
57 #[help(const_eval_teach_help)]
064997fb
FG
58 pub teach: Option<()>,
59}
60
2b03887a
FG
61#[derive(Diagnostic)]
62#[diag(const_eval_raw_ptr_to_int)]
064997fb 63#[note]
9ffffee4 64#[note(const_eval_note2)]
064997fb
FG
65pub(crate) struct RawPtrToIntErr {
66 #[primary_span]
67 pub span: Span,
68}
69
2b03887a
FG
70#[derive(Diagnostic)]
71#[diag(const_eval_raw_ptr_comparison)]
064997fb
FG
72#[note]
73pub(crate) struct RawPtrComparisonErr {
74 #[primary_span]
75 pub span: Span,
76}
77
2b03887a
FG
78#[derive(Diagnostic)]
79#[diag(const_eval_panic_non_str)]
064997fb
FG
80pub(crate) struct PanicNonStrErr {
81 #[primary_span]
82 pub span: Span,
83}
84
2b03887a
FG
85#[derive(Diagnostic)]
86#[diag(const_eval_mut_deref, code = "E0658")]
064997fb
FG
87pub(crate) struct MutDerefErr {
88 #[primary_span]
89 pub span: Span,
90 pub kind: ConstContext,
91}
92
2b03887a
FG
93#[derive(Diagnostic)]
94#[diag(const_eval_transient_mut_borrow, code = "E0658")]
064997fb
FG
95pub(crate) struct TransientMutBorrowErr {
96 #[primary_span]
97 pub span: Span,
98 pub kind: ConstContext,
99}
100
2b03887a
FG
101#[derive(Diagnostic)]
102#[diag(const_eval_transient_mut_borrow_raw, code = "E0658")]
064997fb
FG
103pub(crate) struct TransientMutBorrowErrRaw {
104 #[primary_span]
105 pub span: Span,
106 pub kind: ConstContext,
107}
f2b60f7d 108
2b03887a
FG
109#[derive(Diagnostic)]
110#[diag(const_eval_max_num_nodes_in_const)]
f2b60f7d
FG
111pub(crate) struct MaxNumNodesInConstErr {
112 #[primary_span]
fe692bf9 113 pub span: Option<Span>,
f2b60f7d
FG
114 pub global_const_id: String,
115}
116
2b03887a
FG
117#[derive(Diagnostic)]
118#[diag(const_eval_unallowed_fn_pointer_call)]
f2b60f7d
FG
119pub(crate) struct UnallowedFnPointerCall {
120 #[primary_span]
121 pub span: Span,
122 pub kind: ConstContext,
123}
124
2b03887a
FG
125#[derive(Diagnostic)]
126#[diag(const_eval_unstable_const_fn)]
f2b60f7d
FG
127pub(crate) struct UnstableConstFn {
128 #[primary_span]
129 pub span: Span,
130 pub def_path: String,
131}
132
2b03887a
FG
133#[derive(Diagnostic)]
134#[diag(const_eval_unallowed_mutable_refs, code = "E0764")]
f2b60f7d
FG
135pub(crate) struct UnallowedMutableRefs {
136 #[primary_span]
137 pub span: Span,
138 pub kind: ConstContext,
9ffffee4 139 #[note(const_eval_teach_note)]
f2b60f7d
FG
140 pub teach: Option<()>,
141}
142
2b03887a
FG
143#[derive(Diagnostic)]
144#[diag(const_eval_unallowed_mutable_refs_raw, code = "E0764")]
f2b60f7d
FG
145pub(crate) struct UnallowedMutableRefsRaw {
146 #[primary_span]
147 pub span: Span,
148 pub kind: ConstContext,
9ffffee4 149 #[note(const_eval_teach_note)]
f2b60f7d
FG
150 pub teach: Option<()>,
151}
2b03887a
FG
152#[derive(Diagnostic)]
153#[diag(const_eval_non_const_fmt_macro_call, code = "E0015")]
f2b60f7d
FG
154pub(crate) struct NonConstFmtMacroCall {
155 #[primary_span]
156 pub span: Span,
157 pub kind: ConstContext,
158}
159
2b03887a
FG
160#[derive(Diagnostic)]
161#[diag(const_eval_non_const_fn_call, code = "E0015")]
f2b60f7d
FG
162pub(crate) struct NonConstFnCall {
163 #[primary_span]
164 pub span: Span,
165 pub def_path_str: String,
166 pub kind: ConstContext,
167}
168
2b03887a
FG
169#[derive(Diagnostic)]
170#[diag(const_eval_unallowed_op_in_const_context)]
f2b60f7d
FG
171pub(crate) struct UnallowedOpInConstContext {
172 #[primary_span]
173 pub span: Span,
174 pub msg: String,
175}
176
2b03887a
FG
177#[derive(Diagnostic)]
178#[diag(const_eval_unallowed_heap_allocations, code = "E0010")]
f2b60f7d
FG
179pub(crate) struct UnallowedHeapAllocations {
180 #[primary_span]
181 #[label]
182 pub span: Span,
183 pub kind: ConstContext,
9ffffee4 184 #[note(const_eval_teach_note)]
f2b60f7d
FG
185 pub teach: Option<()>,
186}
187
2b03887a
FG
188#[derive(Diagnostic)]
189#[diag(const_eval_unallowed_inline_asm, code = "E0015")]
f2b60f7d
FG
190pub(crate) struct UnallowedInlineAsm {
191 #[primary_span]
192 pub span: Span,
193 pub kind: ConstContext,
194}
195
fe692bf9
FG
196#[derive(Diagnostic)]
197#[diag(const_eval_unsupported_untyped_pointer)]
198#[note]
199pub(crate) struct UnsupportedUntypedPointer {
200 #[primary_span]
201 pub span: Span,
202}
203
2b03887a
FG
204#[derive(Diagnostic)]
205#[diag(const_eval_interior_mutable_data_refer, code = "E0492")]
f2b60f7d
FG
206pub(crate) struct InteriorMutableDataRefer {
207 #[primary_span]
208 #[label]
209 pub span: Span,
210 #[help]
211 pub opt_help: Option<()>,
212 pub kind: ConstContext,
9ffffee4 213 #[note(const_eval_teach_note)]
f2b60f7d
FG
214 pub teach: Option<()>,
215}
216
2b03887a
FG
217#[derive(Diagnostic)]
218#[diag(const_eval_interior_mutability_borrow)]
f2b60f7d
FG
219pub(crate) struct InteriorMutabilityBorrow {
220 #[primary_span]
221 pub span: Span,
222}
fe692bf9
FG
223
224#[derive(LintDiagnostic)]
225#[diag(const_eval_long_running)]
226#[note]
227pub struct LongRunning {
228 #[help]
229 pub item_span: Span,
230}
231
232#[derive(Diagnostic)]
233#[diag(const_eval_long_running)]
234pub 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)]
244pub(crate) struct ErroneousConstUsed {
245 #[primary_span]
246 pub span: Span,
247}
248
249#[derive(Subdiagnostic)]
250#[note(const_eval_non_const_impl)]
251pub(crate) struct NonConstImplNote {
252 #[primary_span]
253 pub span: Span,
254}
255
256#[derive(Subdiagnostic, PartialEq, Eq, Clone)]
257#[note(const_eval_frame_note)]
258pub 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)]
268pub 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]
279pub 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")]
288pub 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")]
297pub 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")]
306pub 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")]
315pub 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")]
324pub 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")]
333pub 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)]
342pub 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")]
356pub 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")]
366pub 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]
377pub 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")]
389pub 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)]
401pub 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")]
410pub 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)]
422pub struct NullaryIntrinsicError {
423 #[primary_span]
424 pub span: Span,
425}
426
427#[derive(Diagnostic)]
428#[diag(const_eval_undefined_behavior, code = "E0080")]
429pub 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
440pub trait ReportErrorExt {
441 /// Returns the diagnostic message for this error.
442 fn diagnostic_message(&self) -> DiagnosticMessage;
443 fn add_args<G: EmissionGuarantee>(
444 self,
445 handler: &Handler,
446 builder: &mut DiagnosticBuilder<'_, G>,
447 );
448
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
465fn 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
479impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> {
480 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,
add651ee 495 PointerUseAfterFree(_, _) => const_eval_pointer_use_after_free,
fe692bf9
FG
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,
add651ee
FG
514 UninhabitedEnumVariantWritten(_) => const_eval_uninhabited_enum_variant_written,
515 UninhabitedEnumVariantRead(_) => const_eval_uninhabited_enum_variant_read,
516 ValidationError(e) => e.diagnostic_message(),
fe692bf9
FG
517 Custom(x) => (x.msg)(),
518 }
519 }
520
521 fn add_args<G: EmissionGuarantee>(
522 self,
523 handler: &Handler,
524 builder: &mut DiagnosticBuilder<'_, G>,
525 ) {
526 use UndefinedBehaviorInfo::*;
527 match self {
528 Ub(_)
529 | Unreachable
530 | DivisionByZero
531 | RemainderByZero
532 | DivisionOverflow
533 | RemainderOverflow
534 | PointerArithOverflow
535 | InvalidMeta(InvalidMetaKind::SliceTooBig)
536 | InvalidMeta(InvalidMetaKind::TooBig)
537 | InvalidUninitBytes(None)
538 | DeadLocal
add651ee
FG
539 | UninhabitedEnumVariantWritten(_)
540 | UninhabitedEnumVariantRead(_) => {}
fe692bf9
FG
541 BoundsCheckFailed { len, index } => {
542 builder.set_arg("len", len);
543 builder.set_arg("index", index);
544 }
545 UnterminatedCString(ptr) | InvalidFunctionPointer(ptr) | InvalidVTablePointer(ptr) => {
546 builder.set_arg("pointer", ptr);
547 }
add651ee
FG
548 PointerUseAfterFree(alloc_id, msg) => {
549 builder
550 .set_arg("alloc_id", alloc_id)
551 .set_arg("bad_pointer_message", bad_pointer_message(msg, handler));
fe692bf9
FG
552 }
553 PointerOutOfBounds { alloc_id, alloc_size, ptr_offset, ptr_size, msg } => {
554 builder
555 .set_arg("alloc_id", alloc_id)
556 .set_arg("alloc_size", alloc_size.bytes())
557 .set_arg("ptr_offset", ptr_offset)
558 .set_arg("ptr_size", ptr_size.bytes())
559 .set_arg("bad_pointer_message", bad_pointer_message(msg, handler));
560 }
561 DanglingIntPointer(ptr, msg) => {
562 if ptr != 0 {
563 builder.set_arg("pointer", format!("{ptr:#x}[noalloc]"));
564 }
565
566 builder.set_arg("bad_pointer_message", bad_pointer_message(msg, handler));
567 }
568 AlignmentCheckFailed { required, has } => {
569 builder.set_arg("required", required.bytes());
570 builder.set_arg("has", has.bytes());
571 }
572 WriteToReadOnly(alloc) | DerefFunctionPointer(alloc) | DerefVTablePointer(alloc) => {
573 builder.set_arg("allocation", alloc);
574 }
575 InvalidBool(b) => {
576 builder.set_arg("value", format!("{b:02x}"));
577 }
578 InvalidChar(c) => {
579 builder.set_arg("value", format!("{c:08x}"));
580 }
581 InvalidTag(tag) => {
582 builder.set_arg("tag", format!("{tag:x}"));
583 }
584 InvalidStr(err) => {
585 builder.set_arg("err", format!("{err}"));
586 }
587 InvalidUninitBytes(Some((alloc, info))) => {
588 builder.set_arg("alloc", alloc);
589 builder.set_arg("access", info.access);
add651ee 590 builder.set_arg("uninit", info.bad);
fe692bf9
FG
591 }
592 ScalarSizeMismatch(info) => {
593 builder.set_arg("target_size", info.target_size);
594 builder.set_arg("data_size", info.data_size);
595 }
add651ee 596 ValidationError(e) => e.add_args(handler, builder),
fe692bf9
FG
597 Custom(custom) => {
598 (custom.add_args)(&mut |name, value| {
599 builder.set_arg(name, value);
600 });
601 }
602 }
603 }
604}
605
606impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> {
607 fn diagnostic_message(&self) -> DiagnosticMessage {
608 use crate::fluent_generated::*;
609 use rustc_middle::mir::interpret::ValidationErrorKind::*;
610 match self.kind {
add651ee
FG
611 PtrToUninhabited { ptr_kind: PointerKind::Box, .. } => {
612 const_eval_validation_box_to_uninhabited
613 }
614 PtrToUninhabited { ptr_kind: PointerKind::Ref, .. } => {
615 const_eval_validation_ref_to_uninhabited
616 }
617
618 PtrToStatic { ptr_kind: PointerKind::Box } => const_eval_validation_box_to_static,
619 PtrToStatic { ptr_kind: PointerKind::Ref } => const_eval_validation_ref_to_static,
620
621 PtrToMut { ptr_kind: PointerKind::Box } => const_eval_validation_box_to_mut,
622 PtrToMut { ptr_kind: PointerKind::Ref } => const_eval_validation_ref_to_mut,
623
624 PointerAsInt { .. } => const_eval_validation_pointer_as_int,
625 PartialPointer => const_eval_validation_partial_pointer,
626 MutableRefInConst => const_eval_validation_mutable_ref_in_const,
627 NullFnPtr => const_eval_validation_null_fn_ptr,
628 NeverVal => const_eval_validation_never_val,
629 NullablePtrOutOfRange { .. } => const_eval_validation_nullable_ptr_out_of_range,
630 PtrOutOfRange { .. } => const_eval_validation_ptr_out_of_range,
631 OutOfRange { .. } => const_eval_validation_out_of_range,
632 UnsafeCell => const_eval_validation_unsafe_cell,
633 UninhabitedVal { .. } => const_eval_validation_uninhabited_val,
634 InvalidEnumTag { .. } => const_eval_validation_invalid_enum_tag,
635 UninhabitedEnumVariant => const_eval_validation_uninhabited_enum_variant,
636 Uninit { .. } => const_eval_validation_uninit,
637 InvalidVTablePtr { .. } => const_eval_validation_invalid_vtable_ptr,
fe692bf9 638 InvalidMetaSliceTooLarge { ptr_kind: PointerKind::Box } => {
add651ee 639 const_eval_validation_invalid_box_slice_meta
fe692bf9
FG
640 }
641 InvalidMetaSliceTooLarge { ptr_kind: PointerKind::Ref } => {
add651ee 642 const_eval_validation_invalid_ref_slice_meta
fe692bf9
FG
643 }
644
add651ee
FG
645 InvalidMetaTooLarge { ptr_kind: PointerKind::Box } => {
646 const_eval_validation_invalid_box_meta
647 }
648 InvalidMetaTooLarge { ptr_kind: PointerKind::Ref } => {
649 const_eval_validation_invalid_ref_meta
650 }
651 UnalignedPtr { ptr_kind: PointerKind::Ref, .. } => const_eval_validation_unaligned_ref,
652 UnalignedPtr { ptr_kind: PointerKind::Box, .. } => const_eval_validation_unaligned_box,
fe692bf9 653
add651ee
FG
654 NullPtr { ptr_kind: PointerKind::Box } => const_eval_validation_null_box,
655 NullPtr { ptr_kind: PointerKind::Ref } => const_eval_validation_null_ref,
fe692bf9 656 DanglingPtrNoProvenance { ptr_kind: PointerKind::Box, .. } => {
add651ee 657 const_eval_validation_dangling_box_no_provenance
fe692bf9
FG
658 }
659 DanglingPtrNoProvenance { ptr_kind: PointerKind::Ref, .. } => {
add651ee 660 const_eval_validation_dangling_ref_no_provenance
fe692bf9
FG
661 }
662 DanglingPtrOutOfBounds { ptr_kind: PointerKind::Box } => {
add651ee 663 const_eval_validation_dangling_box_out_of_bounds
fe692bf9
FG
664 }
665 DanglingPtrOutOfBounds { ptr_kind: PointerKind::Ref } => {
add651ee 666 const_eval_validation_dangling_ref_out_of_bounds
fe692bf9
FG
667 }
668 DanglingPtrUseAfterFree { ptr_kind: PointerKind::Box } => {
add651ee 669 const_eval_validation_dangling_box_use_after_free
fe692bf9
FG
670 }
671 DanglingPtrUseAfterFree { ptr_kind: PointerKind::Ref } => {
add651ee 672 const_eval_validation_dangling_ref_use_after_free
fe692bf9
FG
673 }
674 InvalidBool { .. } => const_eval_validation_invalid_bool,
675 InvalidChar { .. } => const_eval_validation_invalid_char,
add651ee 676 InvalidFnPtr { .. } => const_eval_validation_invalid_fn_ptr,
fe692bf9
FG
677 }
678 }
679
680 fn add_args<G: EmissionGuarantee>(self, handler: &Handler, err: &mut DiagnosticBuilder<'_, G>) {
681 use crate::fluent_generated as fluent;
682 use rustc_middle::mir::interpret::ValidationErrorKind::*;
683
add651ee
FG
684 if let PointerAsInt { .. } | PartialPointer = self.kind {
685 err.help(fluent::const_eval_ptr_as_bytes_1);
686 err.help(fluent::const_eval_ptr_as_bytes_2);
687 }
688
fe692bf9
FG
689 let message = if let Some(path) = self.path {
690 handler.eagerly_translate_to_string(
add651ee 691 fluent::const_eval_validation_front_matter_invalid_value_with_path,
fe692bf9
FG
692 [("path".into(), DiagnosticArgValue::Str(path.into()))].iter().map(|(a, b)| (a, b)),
693 )
694 } else {
add651ee
FG
695 handler.eagerly_translate_to_string(
696 fluent::const_eval_validation_front_matter_invalid_value,
697 [].into_iter(),
698 )
fe692bf9
FG
699 };
700
701 err.set_arg("front_matter", message);
702
703 fn add_range_arg<G: EmissionGuarantee>(
704 r: WrappingRange,
705 max_hi: u128,
706 handler: &Handler,
707 err: &mut DiagnosticBuilder<'_, G>,
708 ) {
709 let WrappingRange { start: lo, end: hi } = r;
710 assert!(hi <= max_hi);
711 let msg = if lo > hi {
712 fluent::const_eval_range_wrapping
713 } else if lo == hi {
714 fluent::const_eval_range_singular
715 } else if lo == 0 {
716 assert!(hi < max_hi, "should not be printing if the range covers everything");
717 fluent::const_eval_range_upper
718 } else if hi == max_hi {
719 assert!(lo > 0, "should not be printing if the range covers everything");
720 fluent::const_eval_range_lower
721 } else {
722 fluent::const_eval_range
723 };
724
725 let args = [
726 ("lo".into(), DiagnosticArgValue::Str(lo.to_string().into())),
727 ("hi".into(), DiagnosticArgValue::Str(hi.to_string().into())),
728 ];
729 let args = args.iter().map(|(a, b)| (a, b));
730 let message = handler.eagerly_translate_to_string(msg, args);
731 err.set_arg("in_range", message);
732 }
733
734 match self.kind {
735 PtrToUninhabited { ty, .. } | UninhabitedVal { ty } => {
736 err.set_arg("ty", ty);
737 }
add651ee
FG
738 PointerAsInt { expected } | Uninit { expected } => {
739 let msg = match expected {
740 ExpectedKind::Reference => fluent::const_eval_validation_expected_ref,
741 ExpectedKind::Box => fluent::const_eval_validation_expected_box,
742 ExpectedKind::RawPtr => fluent::const_eval_validation_expected_raw_ptr,
743 ExpectedKind::InitScalar => fluent::const_eval_validation_expected_init_scalar,
744 ExpectedKind::Bool => fluent::const_eval_validation_expected_bool,
745 ExpectedKind::Char => fluent::const_eval_validation_expected_char,
746 ExpectedKind::Float => fluent::const_eval_validation_expected_float,
747 ExpectedKind::Int => fluent::const_eval_validation_expected_int,
748 ExpectedKind::FnPtr => fluent::const_eval_validation_expected_fn_ptr,
749 ExpectedKind::EnumTag => fluent::const_eval_validation_expected_enum_tag,
750 ExpectedKind::Str => fluent::const_eval_validation_expected_str,
751 };
752 let msg = handler.eagerly_translate_to_string(msg, [].into_iter());
753 err.set_arg("expected", msg);
754 }
755 InvalidEnumTag { value }
fe692bf9
FG
756 | InvalidVTablePtr { value }
757 | InvalidBool { value }
758 | InvalidChar { value }
759 | InvalidFnPtr { value } => {
760 err.set_arg("value", value);
761 }
762 NullablePtrOutOfRange { range, max_value } | PtrOutOfRange { range, max_value } => {
763 add_range_arg(range, max_value, handler, err)
764 }
765 OutOfRange { range, max_value, value } => {
766 err.set_arg("value", value);
767 add_range_arg(range, max_value, handler, err);
768 }
769 UnalignedPtr { required_bytes, found_bytes, .. } => {
770 err.set_arg("required_bytes", required_bytes);
771 err.set_arg("found_bytes", found_bytes);
772 }
773 DanglingPtrNoProvenance { pointer, .. } => {
774 err.set_arg("pointer", pointer);
775 }
776 NullPtr { .. }
777 | PtrToStatic { .. }
778 | PtrToMut { .. }
779 | MutableRefInConst
780 | NullFnPtr
781 | NeverVal
782 | UnsafeCell
fe692bf9
FG
783 | InvalidMetaSliceTooLarge { .. }
784 | InvalidMetaTooLarge { .. }
785 | DanglingPtrUseAfterFree { .. }
add651ee
FG
786 | DanglingPtrOutOfBounds { .. }
787 | UninhabitedEnumVariant
788 | PartialPointer => {}
fe692bf9
FG
789 }
790 }
791}
792
793impl ReportErrorExt for UnsupportedOpInfo {
794 fn diagnostic_message(&self) -> DiagnosticMessage {
795 use crate::fluent_generated::*;
796 match self {
797 UnsupportedOpInfo::Unsupported(s) => s.clone().into(),
add651ee
FG
798 UnsupportedOpInfo::OverwritePartialPointer(_) => const_eval_partial_pointer_overwrite,
799 UnsupportedOpInfo::ReadPartialPointer(_) => const_eval_partial_pointer_copy,
800 UnsupportedOpInfo::ReadPointerAsInt(_) => const_eval_read_pointer_as_int,
fe692bf9
FG
801 UnsupportedOpInfo::ThreadLocalStatic(_) => const_eval_thread_local_static,
802 UnsupportedOpInfo::ReadExternStatic(_) => const_eval_read_extern_static,
803 }
804 }
805 fn add_args<G: EmissionGuarantee>(self, _: &Handler, builder: &mut DiagnosticBuilder<'_, G>) {
806 use crate::fluent_generated::*;
807
808 use UnsupportedOpInfo::*;
add651ee 809 if let ReadPointerAsInt(_) | OverwritePartialPointer(_) | ReadPartialPointer(_) = self {
fe692bf9
FG
810 builder.help(const_eval_ptr_as_bytes_1);
811 builder.help(const_eval_ptr_as_bytes_2);
812 }
813 match self {
add651ee
FG
814 // `ReadPointerAsInt(Some(info))` is never printed anyway, it only serves as an error to
815 // be further processed by validity checking which then turns it into something nice to
816 // print. So it's not worth the effort of having diagnostics that can print the `info`.
817 Unsupported(_) | ReadPointerAsInt(_) => {}
818 OverwritePartialPointer(ptr) | ReadPartialPointer(ptr) => {
fe692bf9
FG
819 builder.set_arg("ptr", ptr);
820 }
821 ThreadLocalStatic(did) | ReadExternStatic(did) => {
822 builder.set_arg("did", format!("{did:?}"));
823 }
824 }
825 }
826}
827
828impl<'tcx> ReportErrorExt for InterpError<'tcx> {
829 fn diagnostic_message(&self) -> DiagnosticMessage {
830 match self {
831 InterpError::UndefinedBehavior(ub) => ub.diagnostic_message(),
832 InterpError::Unsupported(e) => e.diagnostic_message(),
833 InterpError::InvalidProgram(e) => e.diagnostic_message(),
834 InterpError::ResourceExhaustion(e) => e.diagnostic_message(),
835 InterpError::MachineStop(e) => e.diagnostic_message(),
836 }
837 }
838 fn add_args<G: EmissionGuarantee>(
839 self,
840 handler: &Handler,
841 builder: &mut DiagnosticBuilder<'_, G>,
842 ) {
843 match self {
844 InterpError::UndefinedBehavior(ub) => ub.add_args(handler, builder),
845 InterpError::Unsupported(e) => e.add_args(handler, builder),
846 InterpError::InvalidProgram(e) => e.add_args(handler, builder),
847 InterpError::ResourceExhaustion(e) => e.add_args(handler, builder),
848 InterpError::MachineStop(e) => e.add_args(&mut |name, value| {
849 builder.set_arg(name, value);
850 }),
851 }
852 }
853}
854
855impl<'tcx> ReportErrorExt for InvalidProgramInfo<'tcx> {
856 fn diagnostic_message(&self) -> DiagnosticMessage {
857 use crate::fluent_generated::*;
858 match self {
859 InvalidProgramInfo::TooGeneric => const_eval_too_generic,
860 InvalidProgramInfo::AlreadyReported(_) => const_eval_already_reported,
861 InvalidProgramInfo::Layout(e) => e.diagnostic_message(),
862 InvalidProgramInfo::FnAbiAdjustForForeignAbi(_) => {
863 rustc_middle::error::middle_adjust_for_foreign_abi_error
864 }
add651ee
FG
865 InvalidProgramInfo::ConstPropNonsense => {
866 panic!("We had const-prop nonsense, this should never be printed")
867 }
fe692bf9
FG
868 }
869 }
870 fn add_args<G: EmissionGuarantee>(
871 self,
872 handler: &Handler,
873 builder: &mut DiagnosticBuilder<'_, G>,
874 ) {
875 match self {
876 InvalidProgramInfo::TooGeneric
877 | InvalidProgramInfo::AlreadyReported(_)
add651ee 878 | InvalidProgramInfo::ConstPropNonsense => {}
fe692bf9
FG
879 InvalidProgramInfo::Layout(e) => {
880 let diag: DiagnosticBuilder<'_, ()> = e.into_diagnostic().into_diagnostic(handler);
881 for (name, val) in diag.args() {
882 builder.set_arg(name.clone(), val.clone());
883 }
884 diag.cancel();
885 }
886 InvalidProgramInfo::FnAbiAdjustForForeignAbi(
887 AdjustForForeignAbiError::Unsupported { arch, abi },
888 ) => {
889 builder.set_arg("arch", arch);
890 builder.set_arg("abi", abi.name());
891 }
fe692bf9
FG
892 }
893 }
894}
895
896impl ReportErrorExt for ResourceExhaustionInfo {
897 fn diagnostic_message(&self) -> DiagnosticMessage {
898 use crate::fluent_generated::*;
899 match self {
900 ResourceExhaustionInfo::StackFrameLimitReached => const_eval_stack_frame_limit_reached,
901 ResourceExhaustionInfo::MemoryExhausted => const_eval_memory_exhausted,
902 ResourceExhaustionInfo::AddressSpaceFull => const_eval_address_space_full,
903 }
904 }
905 fn add_args<G: EmissionGuarantee>(self, _: &Handler, _: &mut DiagnosticBuilder<'_, G>) {}
906}