]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_const_eval/src/errors.rs
bump version to 1.79.0+dfsg1-1~bpo12+pve2
[rustc.git] / compiler / rustc_const_eval / src / errors.rs
CommitLineData
c0240ec0
FG
1use std::borrow::Cow;
2
fe692bf9 3use rustc_errors::{
c620b35d 4 codes::*, Diag, DiagArgValue, DiagCtxt, DiagMessage, Diagnostic, EmissionGuarantee, Level,
fe692bf9 5};
064997fb 6use rustc_hir::ConstContext;
fe692bf9
FG
7use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
8use rustc_middle::mir::interpret::{
ed00b5ec
FG
9 CheckInAllocMsg, ExpectedKind, InterpError, InvalidMetaKind, InvalidProgramInfo, Misalignment,
10 PointerKind, ResourceExhaustionInfo, UndefinedBehaviorInfo, UnsupportedOpInfo,
11 ValidationErrorInfo,
fe692bf9 12};
c620b35d 13use rustc_middle::ty::{self, Mutability, Ty};
064997fb 14use rustc_span::Span;
fe692bf9
FG
15use rustc_target::abi::call::AdjustForForeignAbiError;
16use rustc_target::abi::{Size, WrappingRange};
c0240ec0
FG
17
18use crate::interpret::InternKind;
fe692bf9
FG
19
20#[derive(Diagnostic)]
21#[diag(const_eval_dangling_ptr_in_final)]
22pub(crate) struct DanglingPtrInFinal {
23 #[primary_span]
24 pub span: Span,
c0240ec0
FG
25 pub kind: InternKind,
26}
27
e8be2606
FG
28#[derive(Diagnostic)]
29#[diag(const_eval_nested_static_in_thread_local)]
30pub(crate) struct NestedStaticInThreadLocal {
31 #[primary_span]
32 pub span: Span,
33}
34
c0240ec0
FG
35#[derive(LintDiagnostic)]
36#[diag(const_eval_mutable_ptr_in_final)]
37pub(crate) struct MutablePtrInFinal {
38 // rust-lang/rust#122153: This was marked as `#[primary_span]` under
39 // `derive(Diagnostic)`. Since we expect we may hard-error in future, we are
40 // keeping the field (and skipping it under `derive(LintDiagnostic)`).
41 #[skip_arg]
42 pub span: Span,
43 pub kind: InternKind,
fe692bf9 44}
064997fb 45
2b03887a
FG
46#[derive(Diagnostic)]
47#[diag(const_eval_unstable_in_stable)]
064997fb
FG
48pub(crate) struct UnstableInStable {
49 pub gate: String,
50 #[primary_span]
51 pub span: Span,
52 #[suggestion(
9ffffee4 53 const_eval_unstable_sugg,
064997fb
FG
54 code = "#[rustc_const_unstable(feature = \"...\", issue = \"...\")]\n",
55 applicability = "has-placeholders"
56 )]
57 #[suggestion(
9ffffee4 58 const_eval_bypass_sugg,
064997fb
FG
59 code = "#[rustc_allow_const_fn_unstable({gate})]\n",
60 applicability = "has-placeholders"
61 )]
62 pub attr_span: Span,
63}
64
2b03887a 65#[derive(Diagnostic)]
c0240ec0 66#[diag(const_eval_thread_local_access, code = E0625)]
c620b35d 67pub(crate) struct ThreadLocalAccessErr {
064997fb
FG
68 #[primary_span]
69 pub span: Span,
70}
71
2b03887a
FG
72#[derive(Diagnostic)]
73#[diag(const_eval_raw_ptr_to_int)]
064997fb 74#[note]
9ffffee4 75#[note(const_eval_note2)]
064997fb
FG
76pub(crate) struct RawPtrToIntErr {
77 #[primary_span]
78 pub span: Span,
79}
80
2b03887a
FG
81#[derive(Diagnostic)]
82#[diag(const_eval_raw_ptr_comparison)]
064997fb
FG
83#[note]
84pub(crate) struct RawPtrComparisonErr {
85 #[primary_span]
86 pub span: Span,
87}
88
2b03887a
FG
89#[derive(Diagnostic)]
90#[diag(const_eval_panic_non_str)]
064997fb
FG
91pub(crate) struct PanicNonStrErr {
92 #[primary_span]
93 pub span: Span,
94}
95
2b03887a 96#[derive(Diagnostic)]
c0240ec0 97#[diag(const_eval_mut_deref, code = E0658)]
064997fb
FG
98pub(crate) struct MutDerefErr {
99 #[primary_span]
100 pub span: Span,
101 pub kind: ConstContext,
102}
103
2b03887a 104#[derive(Diagnostic)]
c0240ec0 105#[diag(const_eval_transient_mut_borrow, code = E0658)]
064997fb
FG
106pub(crate) struct TransientMutBorrowErr {
107 #[primary_span]
108 pub span: Span,
109 pub kind: ConstContext,
110}
111
2b03887a 112#[derive(Diagnostic)]
c0240ec0
FG
113#[diag(const_eval_transient_mut_raw, code = E0658)]
114pub(crate) struct TransientMutRawErr {
064997fb
FG
115 #[primary_span]
116 pub span: Span,
117 pub kind: ConstContext,
118}
f2b60f7d 119
2b03887a
FG
120#[derive(Diagnostic)]
121#[diag(const_eval_max_num_nodes_in_const)]
f2b60f7d
FG
122pub(crate) struct MaxNumNodesInConstErr {
123 #[primary_span]
fe692bf9 124 pub span: Option<Span>,
f2b60f7d
FG
125 pub global_const_id: String,
126}
127
2b03887a
FG
128#[derive(Diagnostic)]
129#[diag(const_eval_unallowed_fn_pointer_call)]
f2b60f7d
FG
130pub(crate) struct UnallowedFnPointerCall {
131 #[primary_span]
132 pub span: Span,
133 pub kind: ConstContext,
134}
135
2b03887a
FG
136#[derive(Diagnostic)]
137#[diag(const_eval_unstable_const_fn)]
f2b60f7d
FG
138pub(crate) struct UnstableConstFn {
139 #[primary_span]
140 pub span: Span,
141 pub def_path: String,
142}
143
2b03887a 144#[derive(Diagnostic)]
c0240ec0 145#[diag(const_eval_unallowed_mutable_refs, code = E0764)]
f2b60f7d
FG
146pub(crate) struct UnallowedMutableRefs {
147 #[primary_span]
148 pub span: Span,
149 pub kind: ConstContext,
9ffffee4 150 #[note(const_eval_teach_note)]
f2b60f7d
FG
151 pub teach: Option<()>,
152}
153
2b03887a 154#[derive(Diagnostic)]
c0240ec0
FG
155#[diag(const_eval_unallowed_mutable_raw, code = E0764)]
156pub(crate) struct UnallowedMutableRaw {
f2b60f7d
FG
157 #[primary_span]
158 pub span: Span,
159 pub kind: ConstContext,
9ffffee4 160 #[note(const_eval_teach_note)]
f2b60f7d
FG
161 pub teach: Option<()>,
162}
2b03887a 163#[derive(Diagnostic)]
c0240ec0 164#[diag(const_eval_non_const_fmt_macro_call, code = E0015)]
f2b60f7d
FG
165pub(crate) struct NonConstFmtMacroCall {
166 #[primary_span]
167 pub span: Span,
168 pub kind: ConstContext,
169}
170
2b03887a 171#[derive(Diagnostic)]
c0240ec0 172#[diag(const_eval_non_const_fn_call, code = E0015)]
f2b60f7d
FG
173pub(crate) struct NonConstFnCall {
174 #[primary_span]
175 pub span: Span,
176 pub def_path_str: String,
177 pub kind: ConstContext,
178}
179
2b03887a
FG
180#[derive(Diagnostic)]
181#[diag(const_eval_unallowed_op_in_const_context)]
f2b60f7d
FG
182pub(crate) struct UnallowedOpInConstContext {
183 #[primary_span]
184 pub span: Span,
185 pub msg: String,
186}
187
2b03887a 188#[derive(Diagnostic)]
c0240ec0 189#[diag(const_eval_unallowed_heap_allocations, code = E0010)]
f2b60f7d
FG
190pub(crate) struct UnallowedHeapAllocations {
191 #[primary_span]
192 #[label]
193 pub span: Span,
194 pub kind: ConstContext,
9ffffee4 195 #[note(const_eval_teach_note)]
f2b60f7d
FG
196 pub teach: Option<()>,
197}
198
2b03887a 199#[derive(Diagnostic)]
c0240ec0 200#[diag(const_eval_unallowed_inline_asm, code = E0015)]
f2b60f7d
FG
201pub(crate) struct UnallowedInlineAsm {
202 #[primary_span]
203 pub span: Span,
204 pub kind: ConstContext,
205}
206
fe692bf9 207#[derive(Diagnostic)]
c0240ec0 208#[diag(const_eval_interior_mutable_data_refer, code = E0492)]
f2b60f7d
FG
209pub(crate) struct InteriorMutableDataRefer {
210 #[primary_span]
211 #[label]
212 pub span: Span,
213 #[help]
214 pub opt_help: Option<()>,
215 pub kind: ConstContext,
9ffffee4 216 #[note(const_eval_teach_note)]
f2b60f7d
FG
217 pub teach: Option<()>,
218}
219
2b03887a
FG
220#[derive(Diagnostic)]
221#[diag(const_eval_interior_mutability_borrow)]
f2b60f7d
FG
222pub(crate) struct InteriorMutabilityBorrow {
223 #[primary_span]
224 pub span: Span,
225}
fe692bf9
FG
226
227#[derive(LintDiagnostic)]
228#[diag(const_eval_long_running)]
229#[note]
230pub struct LongRunning {
231 #[help]
232 pub item_span: Span,
233}
234
235#[derive(Diagnostic)]
236#[diag(const_eval_long_running)]
237pub struct LongRunningWarn {
238 #[primary_span]
239 #[label]
240 pub span: Span,
241 #[help]
242 pub item_span: Span,
243}
244
fe692bf9
FG
245#[derive(Subdiagnostic)]
246#[note(const_eval_non_const_impl)]
247pub(crate) struct NonConstImplNote {
248 #[primary_span]
249 pub span: Span,
250}
251
c620b35d 252#[derive(Subdiagnostic, Clone)]
fe692bf9
FG
253#[note(const_eval_frame_note)]
254pub struct FrameNote {
255 #[primary_span]
256 pub span: Span,
257 pub times: i32,
258 pub where_: &'static str,
259 pub instance: String,
260}
261
262#[derive(Subdiagnostic)]
263#[note(const_eval_raw_bytes)]
264pub struct RawBytesNote {
265 pub size: u64,
266 pub align: u64,
267 pub bytes: String,
268}
269
270// FIXME(fee1-dead) do not use stringly typed `ConstContext`
271
272#[derive(Diagnostic)]
c0240ec0 273#[diag(const_eval_match_eq_non_const, code = E0015)]
fe692bf9
FG
274#[note]
275pub struct NonConstMatchEq<'tcx> {
276 #[primary_span]
277 pub span: Span,
278 pub ty: Ty<'tcx>,
279 pub kind: ConstContext,
280}
281
282#[derive(Diagnostic)]
c0240ec0 283#[diag(const_eval_for_loop_into_iter_non_const, code = E0015)]
fe692bf9
FG
284pub struct NonConstForLoopIntoIter<'tcx> {
285 #[primary_span]
286 pub span: Span,
287 pub ty: Ty<'tcx>,
288 pub kind: ConstContext,
289}
290
291#[derive(Diagnostic)]
c0240ec0 292#[diag(const_eval_question_branch_non_const, code = E0015)]
fe692bf9
FG
293pub struct NonConstQuestionBranch<'tcx> {
294 #[primary_span]
295 pub span: Span,
296 pub ty: Ty<'tcx>,
297 pub kind: ConstContext,
298}
299
300#[derive(Diagnostic)]
c0240ec0 301#[diag(const_eval_question_from_residual_non_const, code = E0015)]
fe692bf9
FG
302pub struct NonConstQuestionFromResidual<'tcx> {
303 #[primary_span]
304 pub span: Span,
305 pub ty: Ty<'tcx>,
306 pub kind: ConstContext,
307}
308
309#[derive(Diagnostic)]
c0240ec0 310#[diag(const_eval_try_block_from_output_non_const, code = E0015)]
fe692bf9
FG
311pub struct NonConstTryBlockFromOutput<'tcx> {
312 #[primary_span]
313 pub span: Span,
314 pub ty: Ty<'tcx>,
315 pub kind: ConstContext,
316}
317
318#[derive(Diagnostic)]
c0240ec0 319#[diag(const_eval_await_non_const, code = E0015)]
fe692bf9
FG
320pub struct NonConstAwait<'tcx> {
321 #[primary_span]
322 pub span: Span,
323 pub ty: Ty<'tcx>,
324 pub kind: ConstContext,
325}
326
327#[derive(Diagnostic)]
c0240ec0 328#[diag(const_eval_closure_non_const, code = E0015)]
fe692bf9
FG
329pub struct NonConstClosure {
330 #[primary_span]
331 pub span: Span,
332 pub kind: ConstContext,
333 #[subdiagnostic]
334 pub note: Option<NonConstClosureNote>,
335}
336
337#[derive(Subdiagnostic)]
338pub enum NonConstClosureNote {
339 #[note(const_eval_closure_fndef_not_const)]
340 FnDef {
341 #[primary_span]
342 span: Span,
343 },
344 #[note(const_eval_fn_ptr_call)]
345 FnPtr,
346 #[note(const_eval_closure_call)]
347 Closure,
348}
349
350#[derive(Subdiagnostic)]
351#[multipart_suggestion(const_eval_consider_dereferencing, applicability = "machine-applicable")]
352pub struct ConsiderDereferencing {
353 pub deref: String,
354 #[suggestion_part(code = "{deref}")]
355 pub span: Span,
356 #[suggestion_part(code = "{deref}")]
357 pub rhs_span: Span,
358}
359
360#[derive(Diagnostic)]
c0240ec0 361#[diag(const_eval_operator_non_const, code = E0015)]
fe692bf9
FG
362pub struct NonConstOperator {
363 #[primary_span]
364 pub span: Span,
365 pub kind: ConstContext,
366 #[subdiagnostic]
367 pub sugg: Option<ConsiderDereferencing>,
368}
369
370#[derive(Diagnostic)]
c0240ec0 371#[diag(const_eval_deref_coercion_non_const, code = E0015)]
fe692bf9
FG
372#[note]
373pub struct NonConstDerefCoercion<'tcx> {
374 #[primary_span]
375 pub span: Span,
376 pub ty: Ty<'tcx>,
377 pub kind: ConstContext,
378 pub target_ty: Ty<'tcx>,
379 #[note(const_eval_target_note)]
380 pub deref_target: Option<Span>,
381}
382
383#[derive(Diagnostic)]
c0240ec0 384#[diag(const_eval_live_drop, code = E0493)]
fe692bf9
FG
385pub struct LiveDrop<'tcx> {
386 #[primary_span]
387 #[label]
388 pub span: Span,
389 pub kind: ConstContext,
390 pub dropped_ty: Ty<'tcx>,
391 #[label(const_eval_dropped_at_label)]
392 pub dropped_at: Option<Span>,
393}
394
fe692bf9 395#[derive(Diagnostic)]
c0240ec0 396#[diag(const_eval_error, code = E0080)]
fe692bf9
FG
397pub struct ConstEvalError {
398 #[primary_span]
399 pub span: Span,
400 /// One of "const", "const_with_path", and "static"
401 pub error_kind: &'static str,
402 pub instance: String,
403 #[subdiagnostic]
404 pub frame_notes: Vec<FrameNote>,
405}
406
4b012472
FG
407#[derive(LintDiagnostic)]
408#[diag(const_eval_write_through_immutable_pointer)]
409pub struct WriteThroughImmutablePointer {
410 #[subdiagnostic]
411 pub frames: Vec<FrameNote>,
412}
413
fe692bf9
FG
414#[derive(Diagnostic)]
415#[diag(const_eval_nullary_intrinsic_fail)]
416pub struct NullaryIntrinsicError {
417 #[primary_span]
418 pub span: Span,
419}
420
421#[derive(Diagnostic)]
c620b35d
FG
422#[diag(const_eval_validation_failure, code = E0080)]
423pub struct ValidationFailure {
fe692bf9
FG
424 #[primary_span]
425 pub span: Span,
c620b35d 426 #[note(const_eval_validation_failure_note)]
fe692bf9
FG
427 pub ub_note: Option<()>,
428 #[subdiagnostic]
429 pub frames: Vec<FrameNote>,
430 #[subdiagnostic]
431 pub raw_bytes: RawBytesNote,
432}
433
434pub trait ReportErrorExt {
435 /// Returns the diagnostic message for this error.
c620b35d
FG
436 fn diagnostic_message(&self) -> DiagMessage;
437 fn add_args<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>);
fe692bf9
FG
438
439 fn debug(self) -> String
440 where
441 Self: Sized,
442 {
443 ty::tls::with(move |tcx| {
c0240ec0 444 let dcx = tcx.dcx();
c620b35d 445 let mut diag = dcx.struct_allow(DiagMessage::Str(String::new().into()));
fe692bf9 446 let message = self.diagnostic_message();
c620b35d
FG
447 self.add_args(&mut diag);
448 let s = dcx.eagerly_translate_to_string(message, diag.args.iter());
449 diag.cancel();
fe692bf9
FG
450 s
451 })
452 }
453}
454
4b012472 455fn bad_pointer_message(msg: CheckInAllocMsg, dcx: &DiagCtxt) -> String {
fe692bf9
FG
456 use crate::fluent_generated::*;
457
458 let msg = match msg {
fe692bf9
FG
459 CheckInAllocMsg::MemoryAccessTest => const_eval_memory_access_test,
460 CheckInAllocMsg::PointerArithmeticTest => const_eval_pointer_arithmetic_test,
461 CheckInAllocMsg::OffsetFromTest => const_eval_offset_from_test,
462 CheckInAllocMsg::InboundsTest => const_eval_in_bounds_test,
463 };
464
4b012472 465 dcx.eagerly_translate_to_string(msg, [].into_iter())
fe692bf9
FG
466}
467
468impl<'a> ReportErrorExt for UndefinedBehaviorInfo<'a> {
c620b35d 469 fn diagnostic_message(&self) -> DiagMessage {
fe692bf9
FG
470 use crate::fluent_generated::*;
471 use UndefinedBehaviorInfo::*;
472 match self {
473 Ub(msg) => msg.clone().into(),
781aab86
FG
474 Custom(x) => (x.msg)(),
475 ValidationError(e) => e.diagnostic_message(),
476
fe692bf9
FG
477 Unreachable => const_eval_unreachable,
478 BoundsCheckFailed { .. } => const_eval_bounds_check_failed,
479 DivisionByZero => const_eval_division_by_zero,
480 RemainderByZero => const_eval_remainder_by_zero,
481 DivisionOverflow => const_eval_division_overflow,
482 RemainderOverflow => const_eval_remainder_overflow,
483 PointerArithOverflow => const_eval_pointer_arithmetic_overflow,
484 InvalidMeta(InvalidMetaKind::SliceTooBig) => const_eval_invalid_meta_slice,
485 InvalidMeta(InvalidMetaKind::TooBig) => const_eval_invalid_meta,
486 UnterminatedCString(_) => const_eval_unterminated_c_string,
add651ee 487 PointerUseAfterFree(_, _) => const_eval_pointer_use_after_free,
fe692bf9
FG
488 PointerOutOfBounds { ptr_size: Size::ZERO, .. } => const_eval_zst_pointer_out_of_bounds,
489 PointerOutOfBounds { .. } => const_eval_pointer_out_of_bounds,
490 DanglingIntPointer(0, _) => const_eval_dangling_null_pointer,
491 DanglingIntPointer(_, _) => const_eval_dangling_int_pointer,
492 AlignmentCheckFailed { .. } => const_eval_alignment_check_failed,
493 WriteToReadOnly(_) => const_eval_write_to_read_only,
494 DerefFunctionPointer(_) => const_eval_deref_function_pointer,
495 DerefVTablePointer(_) => const_eval_deref_vtable_pointer,
496 InvalidBool(_) => const_eval_invalid_bool,
497 InvalidChar(_) => const_eval_invalid_char,
498 InvalidTag(_) => const_eval_invalid_tag,
499 InvalidFunctionPointer(_) => const_eval_invalid_function_pointer,
500 InvalidVTablePointer(_) => const_eval_invalid_vtable_pointer,
e8be2606 501 InvalidVTableTrait { .. } => const_eval_invalid_vtable_trait,
fe692bf9
FG
502 InvalidStr(_) => const_eval_invalid_str,
503 InvalidUninitBytes(None) => const_eval_invalid_uninit_bytes_unknown,
504 InvalidUninitBytes(Some(_)) => const_eval_invalid_uninit_bytes,
505 DeadLocal => const_eval_dead_local,
506 ScalarSizeMismatch(_) => const_eval_scalar_size_mismatch,
add651ee
FG
507 UninhabitedEnumVariantWritten(_) => const_eval_uninhabited_enum_variant_written,
508 UninhabitedEnumVariantRead(_) => const_eval_uninhabited_enum_variant_read,
c620b35d
FG
509 InvalidNichedEnumVariantWritten { .. } => {
510 const_eval_invalid_niched_enum_variant_written
511 }
781aab86
FG
512 AbiMismatchArgument { .. } => const_eval_incompatible_types,
513 AbiMismatchReturn { .. } => const_eval_incompatible_return_types,
fe692bf9
FG
514 }
515 }
516
c620b35d 517 fn add_args<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
fe692bf9 518 use UndefinedBehaviorInfo::*;
c620b35d 519 let dcx = diag.dcx;
fe692bf9 520 match self {
781aab86
FG
521 Ub(_) => {}
522 Custom(custom) => {
523 (custom.add_args)(&mut |name, value| {
c620b35d 524 diag.arg(name, value);
781aab86
FG
525 });
526 }
c620b35d 527 ValidationError(e) => e.add_args(diag),
781aab86
FG
528
529 Unreachable
fe692bf9
FG
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(_) => {}
e8be2606 541
fe692bf9 542 BoundsCheckFailed { len, index } => {
c620b35d
FG
543 diag.arg("len", len);
544 diag.arg("index", index);
fe692bf9
FG
545 }
546 UnterminatedCString(ptr) | InvalidFunctionPointer(ptr) | InvalidVTablePointer(ptr) => {
c620b35d 547 diag.arg("pointer", ptr);
fe692bf9 548 }
e8be2606
FG
549 InvalidVTableTrait { expected_trait, vtable_trait } => {
550 diag.arg("expected_trait", expected_trait.to_string());
551 diag.arg(
552 "vtable_trait",
553 vtable_trait.map(|t| t.to_string()).unwrap_or_else(|| format!("<trivial>")),
554 );
555 }
add651ee 556 PointerUseAfterFree(alloc_id, msg) => {
c620b35d 557 diag.arg("alloc_id", alloc_id)
c0240ec0 558 .arg("bad_pointer_message", bad_pointer_message(msg, dcx));
fe692bf9
FG
559 }
560 PointerOutOfBounds { alloc_id, alloc_size, ptr_offset, ptr_size, msg } => {
c620b35d 561 diag.arg("alloc_id", alloc_id)
c0240ec0
FG
562 .arg("alloc_size", alloc_size.bytes())
563 .arg("ptr_offset", ptr_offset)
564 .arg("ptr_size", ptr_size.bytes())
565 .arg("bad_pointer_message", bad_pointer_message(msg, dcx));
fe692bf9
FG
566 }
567 DanglingIntPointer(ptr, msg) => {
568 if ptr != 0 {
c620b35d 569 diag.arg("pointer", format!("{ptr:#x}[noalloc]"));
fe692bf9
FG
570 }
571
c620b35d 572 diag.arg("bad_pointer_message", bad_pointer_message(msg, dcx));
fe692bf9 573 }
ed00b5ec 574 AlignmentCheckFailed(Misalignment { required, has }, msg) => {
c620b35d
FG
575 diag.arg("required", required.bytes());
576 diag.arg("has", has.bytes());
577 diag.arg("msg", format!("{msg:?}"));
fe692bf9
FG
578 }
579 WriteToReadOnly(alloc) | DerefFunctionPointer(alloc) | DerefVTablePointer(alloc) => {
c620b35d 580 diag.arg("allocation", alloc);
fe692bf9
FG
581 }
582 InvalidBool(b) => {
c620b35d 583 diag.arg("value", format!("{b:02x}"));
fe692bf9
FG
584 }
585 InvalidChar(c) => {
c620b35d 586 diag.arg("value", format!("{c:08x}"));
fe692bf9
FG
587 }
588 InvalidTag(tag) => {
c620b35d 589 diag.arg("tag", format!("{tag:x}"));
fe692bf9
FG
590 }
591 InvalidStr(err) => {
c620b35d 592 diag.arg("err", format!("{err}"));
fe692bf9
FG
593 }
594 InvalidUninitBytes(Some((alloc, info))) => {
c620b35d
FG
595 diag.arg("alloc", alloc);
596 diag.arg("access", info.access);
597 diag.arg("uninit", info.bad);
fe692bf9
FG
598 }
599 ScalarSizeMismatch(info) => {
c620b35d
FG
600 diag.arg("target_size", info.target_size);
601 diag.arg("data_size", info.data_size);
602 }
603 InvalidNichedEnumVariantWritten { enum_ty } => {
604 diag.arg("ty", enum_ty.to_string());
fe692bf9 605 }
781aab86
FG
606 AbiMismatchArgument { caller_ty, callee_ty }
607 | AbiMismatchReturn { caller_ty, callee_ty } => {
c620b35d
FG
608 diag.arg("caller_ty", caller_ty.to_string());
609 diag.arg("callee_ty", callee_ty.to_string());
fe692bf9
FG
610 }
611 }
612 }
613}
614
615impl<'tcx> ReportErrorExt for ValidationErrorInfo<'tcx> {
c620b35d 616 fn diagnostic_message(&self) -> DiagMessage {
fe692bf9
FG
617 use crate::fluent_generated::*;
618 use rustc_middle::mir::interpret::ValidationErrorKind::*;
619 match self.kind {
add651ee
FG
620 PtrToUninhabited { ptr_kind: PointerKind::Box, .. } => {
621 const_eval_validation_box_to_uninhabited
622 }
c620b35d 623 PtrToUninhabited { ptr_kind: PointerKind::Ref(_), .. } => {
add651ee
FG
624 const_eval_validation_ref_to_uninhabited
625 }
626
627 PtrToStatic { ptr_kind: PointerKind::Box } => const_eval_validation_box_to_static,
c620b35d 628 PtrToStatic { ptr_kind: PointerKind::Ref(_) } => const_eval_validation_ref_to_static,
add651ee 629
add651ee
FG
630 PointerAsInt { .. } => const_eval_validation_pointer_as_int,
631 PartialPointer => const_eval_validation_partial_pointer,
c620b35d
FG
632 ConstRefToMutable => const_eval_validation_const_ref_to_mutable,
633 ConstRefToExtern => const_eval_validation_const_ref_to_extern,
c0240ec0 634 MutableRefToImmutable => const_eval_validation_mutable_ref_to_immutable,
add651ee
FG
635 NullFnPtr => const_eval_validation_null_fn_ptr,
636 NeverVal => const_eval_validation_never_val,
637 NullablePtrOutOfRange { .. } => const_eval_validation_nullable_ptr_out_of_range,
638 PtrOutOfRange { .. } => const_eval_validation_ptr_out_of_range,
639 OutOfRange { .. } => const_eval_validation_out_of_range,
c0240ec0 640 UnsafeCellInImmutable => const_eval_validation_unsafe_cell,
add651ee
FG
641 UninhabitedVal { .. } => const_eval_validation_uninhabited_val,
642 InvalidEnumTag { .. } => const_eval_validation_invalid_enum_tag,
643 UninhabitedEnumVariant => const_eval_validation_uninhabited_enum_variant,
644 Uninit { .. } => const_eval_validation_uninit,
645 InvalidVTablePtr { .. } => const_eval_validation_invalid_vtable_ptr,
e8be2606 646 InvalidMetaWrongTrait { .. } => const_eval_validation_invalid_vtable_trait,
fe692bf9 647 InvalidMetaSliceTooLarge { ptr_kind: PointerKind::Box } => {
add651ee 648 const_eval_validation_invalid_box_slice_meta
fe692bf9 649 }
c620b35d 650 InvalidMetaSliceTooLarge { ptr_kind: PointerKind::Ref(_) } => {
add651ee 651 const_eval_validation_invalid_ref_slice_meta
fe692bf9
FG
652 }
653
add651ee
FG
654 InvalidMetaTooLarge { ptr_kind: PointerKind::Box } => {
655 const_eval_validation_invalid_box_meta
656 }
c620b35d 657 InvalidMetaTooLarge { ptr_kind: PointerKind::Ref(_) } => {
add651ee
FG
658 const_eval_validation_invalid_ref_meta
659 }
c620b35d
FG
660 UnalignedPtr { ptr_kind: PointerKind::Ref(_), .. } => {
661 const_eval_validation_unaligned_ref
662 }
add651ee 663 UnalignedPtr { ptr_kind: PointerKind::Box, .. } => const_eval_validation_unaligned_box,
fe692bf9 664
add651ee 665 NullPtr { ptr_kind: PointerKind::Box } => const_eval_validation_null_box,
c620b35d 666 NullPtr { ptr_kind: PointerKind::Ref(_) } => const_eval_validation_null_ref,
fe692bf9 667 DanglingPtrNoProvenance { ptr_kind: PointerKind::Box, .. } => {
add651ee 668 const_eval_validation_dangling_box_no_provenance
fe692bf9 669 }
c620b35d 670 DanglingPtrNoProvenance { ptr_kind: PointerKind::Ref(_), .. } => {
add651ee 671 const_eval_validation_dangling_ref_no_provenance
fe692bf9
FG
672 }
673 DanglingPtrOutOfBounds { ptr_kind: PointerKind::Box } => {
add651ee 674 const_eval_validation_dangling_box_out_of_bounds
fe692bf9 675 }
c620b35d 676 DanglingPtrOutOfBounds { ptr_kind: PointerKind::Ref(_) } => {
add651ee 677 const_eval_validation_dangling_ref_out_of_bounds
fe692bf9
FG
678 }
679 DanglingPtrUseAfterFree { ptr_kind: PointerKind::Box } => {
add651ee 680 const_eval_validation_dangling_box_use_after_free
fe692bf9 681 }
c620b35d 682 DanglingPtrUseAfterFree { ptr_kind: PointerKind::Ref(_) } => {
add651ee 683 const_eval_validation_dangling_ref_use_after_free
fe692bf9
FG
684 }
685 InvalidBool { .. } => const_eval_validation_invalid_bool,
686 InvalidChar { .. } => const_eval_validation_invalid_char,
add651ee 687 InvalidFnPtr { .. } => const_eval_validation_invalid_fn_ptr,
fe692bf9
FG
688 }
689 }
690
c620b35d 691 fn add_args<G: EmissionGuarantee>(self, err: &mut Diag<'_, G>) {
fe692bf9
FG
692 use crate::fluent_generated as fluent;
693 use rustc_middle::mir::interpret::ValidationErrorKind::*;
694
add651ee
FG
695 if let PointerAsInt { .. } | PartialPointer = self.kind {
696 err.help(fluent::const_eval_ptr_as_bytes_1);
697 err.help(fluent::const_eval_ptr_as_bytes_2);
698 }
699
fe692bf9 700 let message = if let Some(path) = self.path {
c620b35d 701 err.dcx.eagerly_translate_to_string(
add651ee 702 fluent::const_eval_validation_front_matter_invalid_value_with_path,
c620b35d 703 [("path".into(), DiagArgValue::Str(path.into()))].iter().map(|(a, b)| (a, b)),
fe692bf9
FG
704 )
705 } else {
c620b35d 706 err.dcx.eagerly_translate_to_string(
add651ee
FG
707 fluent::const_eval_validation_front_matter_invalid_value,
708 [].into_iter(),
709 )
fe692bf9
FG
710 };
711
c0240ec0 712 err.arg("front_matter", message);
fe692bf9
FG
713
714 fn add_range_arg<G: EmissionGuarantee>(
715 r: WrappingRange,
716 max_hi: u128,
c620b35d 717 err: &mut Diag<'_, G>,
fe692bf9
FG
718 ) {
719 let WrappingRange { start: lo, end: hi } = r;
720 assert!(hi <= max_hi);
721 let msg = if lo > hi {
722 fluent::const_eval_range_wrapping
723 } else if lo == hi {
724 fluent::const_eval_range_singular
725 } else if lo == 0 {
726 assert!(hi < max_hi, "should not be printing if the range covers everything");
727 fluent::const_eval_range_upper
728 } else if hi == max_hi {
729 assert!(lo > 0, "should not be printing if the range covers everything");
730 fluent::const_eval_range_lower
731 } else {
732 fluent::const_eval_range
733 };
734
735 let args = [
c620b35d
FG
736 ("lo".into(), DiagArgValue::Str(lo.to_string().into())),
737 ("hi".into(), DiagArgValue::Str(hi.to_string().into())),
fe692bf9
FG
738 ];
739 let args = args.iter().map(|(a, b)| (a, b));
c620b35d 740 let message = err.dcx.eagerly_translate_to_string(msg, args);
c0240ec0 741 err.arg("in_range", message);
fe692bf9
FG
742 }
743
744 match self.kind {
745 PtrToUninhabited { ty, .. } | UninhabitedVal { ty } => {
c0240ec0 746 err.arg("ty", ty);
fe692bf9 747 }
add651ee
FG
748 PointerAsInt { expected } | Uninit { expected } => {
749 let msg = match expected {
750 ExpectedKind::Reference => fluent::const_eval_validation_expected_ref,
751 ExpectedKind::Box => fluent::const_eval_validation_expected_box,
752 ExpectedKind::RawPtr => fluent::const_eval_validation_expected_raw_ptr,
753 ExpectedKind::InitScalar => fluent::const_eval_validation_expected_init_scalar,
754 ExpectedKind::Bool => fluent::const_eval_validation_expected_bool,
755 ExpectedKind::Char => fluent::const_eval_validation_expected_char,
756 ExpectedKind::Float => fluent::const_eval_validation_expected_float,
757 ExpectedKind::Int => fluent::const_eval_validation_expected_int,
758 ExpectedKind::FnPtr => fluent::const_eval_validation_expected_fn_ptr,
759 ExpectedKind::EnumTag => fluent::const_eval_validation_expected_enum_tag,
760 ExpectedKind::Str => fluent::const_eval_validation_expected_str,
761 };
c620b35d 762 let msg = err.dcx.eagerly_translate_to_string(msg, [].into_iter());
c0240ec0 763 err.arg("expected", msg);
add651ee
FG
764 }
765 InvalidEnumTag { value }
fe692bf9
FG
766 | InvalidVTablePtr { value }
767 | InvalidBool { value }
768 | InvalidChar { value }
769 | InvalidFnPtr { value } => {
c0240ec0 770 err.arg("value", value);
fe692bf9
FG
771 }
772 NullablePtrOutOfRange { range, max_value } | PtrOutOfRange { range, max_value } => {
c620b35d 773 add_range_arg(range, max_value, err)
fe692bf9
FG
774 }
775 OutOfRange { range, max_value, value } => {
c0240ec0 776 err.arg("value", value);
c620b35d 777 add_range_arg(range, max_value, err);
fe692bf9
FG
778 }
779 UnalignedPtr { required_bytes, found_bytes, .. } => {
c0240ec0
FG
780 err.arg("required_bytes", required_bytes);
781 err.arg("found_bytes", found_bytes);
fe692bf9
FG
782 }
783 DanglingPtrNoProvenance { pointer, .. } => {
c0240ec0 784 err.arg("pointer", pointer);
fe692bf9 785 }
e8be2606
FG
786 InvalidMetaWrongTrait { expected_trait: ref_trait, vtable_trait } => {
787 err.arg("ref_trait", ref_trait.to_string());
788 err.arg(
789 "vtable_trait",
790 vtable_trait.map(|t| t.to_string()).unwrap_or_else(|| format!("<trivial>")),
791 );
792 }
fe692bf9
FG
793 NullPtr { .. }
794 | PtrToStatic { .. }
c620b35d
FG
795 | ConstRefToMutable
796 | ConstRefToExtern
c0240ec0 797 | MutableRefToImmutable
fe692bf9
FG
798 | NullFnPtr
799 | NeverVal
c0240ec0 800 | UnsafeCellInImmutable
fe692bf9
FG
801 | InvalidMetaSliceTooLarge { .. }
802 | InvalidMetaTooLarge { .. }
803 | DanglingPtrUseAfterFree { .. }
add651ee
FG
804 | DanglingPtrOutOfBounds { .. }
805 | UninhabitedEnumVariant
806 | PartialPointer => {}
fe692bf9
FG
807 }
808 }
809}
810
811impl ReportErrorExt for UnsupportedOpInfo {
c620b35d 812 fn diagnostic_message(&self) -> DiagMessage {
fe692bf9
FG
813 use crate::fluent_generated::*;
814 match self {
815 UnsupportedOpInfo::Unsupported(s) => s.clone().into(),
781aab86 816 UnsupportedOpInfo::UnsizedLocal => const_eval_unsized_local,
add651ee
FG
817 UnsupportedOpInfo::OverwritePartialPointer(_) => const_eval_partial_pointer_overwrite,
818 UnsupportedOpInfo::ReadPartialPointer(_) => const_eval_partial_pointer_copy,
819 UnsupportedOpInfo::ReadPointerAsInt(_) => const_eval_read_pointer_as_int,
fe692bf9 820 UnsupportedOpInfo::ThreadLocalStatic(_) => const_eval_thread_local_static,
c620b35d 821 UnsupportedOpInfo::ExternStatic(_) => const_eval_extern_static,
fe692bf9
FG
822 }
823 }
c620b35d 824 fn add_args<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
fe692bf9
FG
825 use crate::fluent_generated::*;
826
827 use UnsupportedOpInfo::*;
add651ee 828 if let ReadPointerAsInt(_) | OverwritePartialPointer(_) | ReadPartialPointer(_) = self {
c620b35d
FG
829 diag.help(const_eval_ptr_as_bytes_1);
830 diag.help(const_eval_ptr_as_bytes_2);
fe692bf9
FG
831 }
832 match self {
add651ee
FG
833 // `ReadPointerAsInt(Some(info))` is never printed anyway, it only serves as an error to
834 // be further processed by validity checking which then turns it into something nice to
835 // print. So it's not worth the effort of having diagnostics that can print the `info`.
781aab86 836 UnsizedLocal | Unsupported(_) | ReadPointerAsInt(_) => {}
add651ee 837 OverwritePartialPointer(ptr) | ReadPartialPointer(ptr) => {
c620b35d 838 diag.arg("ptr", ptr);
fe692bf9 839 }
c620b35d
FG
840 ThreadLocalStatic(did) | ExternStatic(did) => {
841 diag.arg("did", format!("{did:?}"));
fe692bf9
FG
842 }
843 }
844 }
845}
846
847impl<'tcx> ReportErrorExt for InterpError<'tcx> {
c620b35d 848 fn diagnostic_message(&self) -> DiagMessage {
fe692bf9
FG
849 match self {
850 InterpError::UndefinedBehavior(ub) => ub.diagnostic_message(),
851 InterpError::Unsupported(e) => e.diagnostic_message(),
852 InterpError::InvalidProgram(e) => e.diagnostic_message(),
853 InterpError::ResourceExhaustion(e) => e.diagnostic_message(),
854 InterpError::MachineStop(e) => e.diagnostic_message(),
855 }
856 }
c620b35d 857 fn add_args<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
fe692bf9 858 match self {
c620b35d
FG
859 InterpError::UndefinedBehavior(ub) => ub.add_args(diag),
860 InterpError::Unsupported(e) => e.add_args(diag),
861 InterpError::InvalidProgram(e) => e.add_args(diag),
862 InterpError::ResourceExhaustion(e) => e.add_args(diag),
fe692bf9 863 InterpError::MachineStop(e) => e.add_args(&mut |name, value| {
c620b35d 864 diag.arg(name, value);
fe692bf9
FG
865 }),
866 }
867 }
868}
869
870impl<'tcx> ReportErrorExt for InvalidProgramInfo<'tcx> {
c620b35d 871 fn diagnostic_message(&self) -> DiagMessage {
fe692bf9
FG
872 use crate::fluent_generated::*;
873 match self {
874 InvalidProgramInfo::TooGeneric => const_eval_too_generic,
875 InvalidProgramInfo::AlreadyReported(_) => const_eval_already_reported,
876 InvalidProgramInfo::Layout(e) => e.diagnostic_message(),
877 InvalidProgramInfo::FnAbiAdjustForForeignAbi(_) => {
878 rustc_middle::error::middle_adjust_for_foreign_abi_error
879 }
fe692bf9
FG
880 }
881 }
c620b35d 882 fn add_args<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
fe692bf9 883 match self {
c0240ec0 884 InvalidProgramInfo::TooGeneric | InvalidProgramInfo::AlreadyReported(_) => {}
fe692bf9 885 InvalidProgramInfo::Layout(e) => {
c620b35d 886 // The level doesn't matter, `dummy_diag` is consumed without it being used.
c0240ec0 887 let dummy_level = Level::Bug;
c620b35d
FG
888 let dummy_diag: Diag<'_, ()> = e.into_diagnostic().into_diag(diag.dcx, dummy_level);
889 for (name, val) in dummy_diag.args.iter() {
890 diag.arg(name.clone(), val.clone());
fe692bf9 891 }
c620b35d 892 dummy_diag.cancel();
fe692bf9
FG
893 }
894 InvalidProgramInfo::FnAbiAdjustForForeignAbi(
895 AdjustForForeignAbiError::Unsupported { arch, abi },
896 ) => {
c620b35d
FG
897 diag.arg("arch", arch);
898 diag.arg("abi", abi.name());
fe692bf9 899 }
fe692bf9
FG
900 }
901 }
902}
903
904impl ReportErrorExt for ResourceExhaustionInfo {
c620b35d 905 fn diagnostic_message(&self) -> DiagMessage {
fe692bf9
FG
906 use crate::fluent_generated::*;
907 match self {
908 ResourceExhaustionInfo::StackFrameLimitReached => const_eval_stack_frame_limit_reached,
909 ResourceExhaustionInfo::MemoryExhausted => const_eval_memory_exhausted,
910 ResourceExhaustionInfo::AddressSpaceFull => const_eval_address_space_full,
e8be2606 911 ResourceExhaustionInfo::Interrupted => const_eval_interrupted,
fe692bf9
FG
912 }
913 }
c620b35d 914 fn add_args<G: EmissionGuarantee>(self, _: &mut Diag<'_, G>) {}
fe692bf9 915}
c0240ec0 916
c620b35d
FG
917impl rustc_errors::IntoDiagArg for InternKind {
918 fn into_diag_arg(self) -> DiagArgValue {
919 DiagArgValue::Str(Cow::Borrowed(match self {
c0240ec0
FG
920 InternKind::Static(Mutability::Not) => "static",
921 InternKind::Static(Mutability::Mut) => "static_mut",
922 InternKind::Constant => "const",
923 InternKind::Promoted => "promoted",
924 }))
925 }
926}