]>
Commit | Line | Data |
---|---|---|
fe692bf9 FG |
1 | use rustc_errors::{ |
2 | DiagnosticArgValue, DiagnosticBuilder, DiagnosticMessage, EmissionGuarantee, Handler, | |
3 | IntoDiagnostic, | |
4 | }; | |
064997fb | 5 | use rustc_hir::ConstContext; |
fe692bf9 FG |
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}; | |
064997fb | 12 | use rustc_span::Span; |
fe692bf9 FG |
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 | } | |
064997fb | 22 | |
2b03887a FG |
23 | #[derive(Diagnostic)] |
24 | #[diag(const_eval_unstable_in_stable)] | |
064997fb FG |
25 | pub(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 |
44 | pub(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] |
52 | pub(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 |
65 | pub(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] |
73 | pub(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 |
80 | pub(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 |
87 | pub(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 |
95 | pub(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 |
103 | pub(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 |
111 | pub(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 |
119 | pub(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 |
127 | pub(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 |
135 | pub(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 |
145 | pub(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 |
154 | pub(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 |
162 | pub(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 |
171 | pub(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 |
179 | pub(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 |
190 | pub(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] | |
199 | pub(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 |
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, | |
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 |
219 | pub(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] | |
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. | |
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 | ||
465 | 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> { | |
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 | ||
606 | impl<'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 | ||
793 | impl 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 | ||
828 | impl<'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 | ||
855 | impl<'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 | ||
896 | impl 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 | } |