]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_mir_build/src/errors.rs
Auto merge of #107843 - bjorn3:sync_cg_clif-2023-02-09, r=bjorn3
[rust.git] / compiler / rustc_mir_build / src / errors.rs
1 use crate::thir::pattern::deconstruct_pat::DeconstructedPat;
2 use crate::thir::pattern::MatchCheckCtxt;
3 use rustc_errors::Handler;
4 use rustc_errors::{
5     error_code, AddToDiagnostic, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed,
6     IntoDiagnostic, MultiSpan, SubdiagnosticMessage,
7 };
8 use rustc_hir::def::Res;
9 use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
10 use rustc_middle::thir::Pat;
11 use rustc_middle::ty::{self, Ty};
12 use rustc_span::{symbol::Ident, Span};
13
14 #[derive(LintDiagnostic)]
15 #[diag(mir_build_unconditional_recursion)]
16 #[help]
17 pub struct UnconditionalRecursion {
18     #[label]
19     pub span: Span,
20     #[label(mir_build_unconditional_recursion_call_site_label)]
21     pub call_sites: Vec<Span>,
22 }
23
24 #[derive(LintDiagnostic)]
25 #[diag(mir_build_unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe)]
26 #[note]
27 pub struct UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafe<'a> {
28     #[label]
29     pub span: Span,
30     pub function: &'a str,
31 }
32
33 #[derive(LintDiagnostic)]
34 #[diag(mir_build_unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe_nameless)]
35 #[note]
36 pub struct UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafeNameless {
37     #[label]
38     pub span: Span,
39 }
40
41 #[derive(LintDiagnostic)]
42 #[diag(mir_build_unsafe_op_in_unsafe_fn_inline_assembly_requires_unsafe)]
43 #[note]
44 pub struct UnsafeOpInUnsafeFnUseOfInlineAssemblyRequiresUnsafe {
45     #[label]
46     pub span: Span,
47 }
48
49 #[derive(LintDiagnostic)]
50 #[diag(mir_build_unsafe_op_in_unsafe_fn_initializing_type_with_requires_unsafe)]
51 #[note]
52 pub struct UnsafeOpInUnsafeFnInitializingTypeWithRequiresUnsafe {
53     #[label]
54     pub span: Span,
55 }
56
57 #[derive(LintDiagnostic)]
58 #[diag(mir_build_unsafe_op_in_unsafe_fn_mutable_static_requires_unsafe)]
59 #[note]
60 pub struct UnsafeOpInUnsafeFnUseOfMutableStaticRequiresUnsafe {
61     #[label]
62     pub span: Span,
63 }
64
65 #[derive(LintDiagnostic)]
66 #[diag(mir_build_unsafe_op_in_unsafe_fn_extern_static_requires_unsafe)]
67 #[note]
68 pub struct UnsafeOpInUnsafeFnUseOfExternStaticRequiresUnsafe {
69     #[label]
70     pub span: Span,
71 }
72
73 #[derive(LintDiagnostic)]
74 #[diag(mir_build_unsafe_op_in_unsafe_fn_deref_raw_pointer_requires_unsafe)]
75 #[note]
76 pub struct UnsafeOpInUnsafeFnDerefOfRawPointerRequiresUnsafe {
77     #[label]
78     pub span: Span,
79 }
80
81 #[derive(LintDiagnostic)]
82 #[diag(mir_build_unsafe_op_in_unsafe_fn_union_field_requires_unsafe)]
83 #[note]
84 pub struct UnsafeOpInUnsafeFnAccessToUnionFieldRequiresUnsafe {
85     #[label]
86     pub span: Span,
87 }
88
89 #[derive(LintDiagnostic)]
90 #[diag(mir_build_unsafe_op_in_unsafe_fn_mutation_of_layout_constrained_field_requires_unsafe)]
91 #[note]
92 pub struct UnsafeOpInUnsafeFnMutationOfLayoutConstrainedFieldRequiresUnsafe {
93     #[label]
94     pub span: Span,
95 }
96
97 #[derive(LintDiagnostic)]
98 #[diag(mir_build_unsafe_op_in_unsafe_fn_borrow_of_layout_constrained_field_requires_unsafe)]
99 pub struct UnsafeOpInUnsafeFnBorrowOfLayoutConstrainedFieldRequiresUnsafe {
100     #[label]
101     pub span: Span,
102 }
103
104 #[derive(LintDiagnostic)]
105 #[diag(mir_build_unsafe_op_in_unsafe_fn_call_to_fn_with_requires_unsafe)]
106 #[note]
107 pub struct UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe<'a> {
108     #[label]
109     pub span: Span,
110     pub function: &'a str,
111 }
112
113 #[derive(Diagnostic)]
114 #[diag(mir_build_call_to_unsafe_fn_requires_unsafe, code = "E0133")]
115 #[note]
116 pub struct CallToUnsafeFunctionRequiresUnsafe<'a> {
117     #[primary_span]
118     #[label]
119     pub span: Span,
120     pub function: &'a str,
121 }
122
123 #[derive(Diagnostic)]
124 #[diag(mir_build_call_to_unsafe_fn_requires_unsafe_nameless, code = "E0133")]
125 #[note]
126 pub struct CallToUnsafeFunctionRequiresUnsafeNameless {
127     #[primary_span]
128     #[label]
129     pub span: Span,
130 }
131
132 #[derive(Diagnostic)]
133 #[diag(mir_build_call_to_unsafe_fn_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")]
134 #[note]
135 pub struct CallToUnsafeFunctionRequiresUnsafeUnsafeOpInUnsafeFnAllowed<'a> {
136     #[primary_span]
137     #[label]
138     pub span: Span,
139     pub function: &'a str,
140 }
141
142 #[derive(Diagnostic)]
143 #[diag(
144     mir_build_call_to_unsafe_fn_requires_unsafe_nameless_unsafe_op_in_unsafe_fn_allowed,
145     code = "E0133"
146 )]
147 #[note]
148 pub struct CallToUnsafeFunctionRequiresUnsafeNamelessUnsafeOpInUnsafeFnAllowed {
149     #[primary_span]
150     #[label]
151     pub span: Span,
152 }
153
154 #[derive(Diagnostic)]
155 #[diag(mir_build_inline_assembly_requires_unsafe, code = "E0133")]
156 #[note]
157 pub struct UseOfInlineAssemblyRequiresUnsafe {
158     #[primary_span]
159     #[label]
160     pub span: Span,
161 }
162
163 #[derive(Diagnostic)]
164 #[diag(mir_build_inline_assembly_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")]
165 #[note]
166 pub struct UseOfInlineAssemblyRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
167     #[primary_span]
168     #[label]
169     pub span: Span,
170 }
171
172 #[derive(Diagnostic)]
173 #[diag(mir_build_initializing_type_with_requires_unsafe, code = "E0133")]
174 #[note]
175 pub struct InitializingTypeWithRequiresUnsafe {
176     #[primary_span]
177     #[label]
178     pub span: Span,
179 }
180
181 #[derive(Diagnostic)]
182 #[diag(
183     mir_build_initializing_type_with_requires_unsafe_unsafe_op_in_unsafe_fn_allowed,
184     code = "E0133"
185 )]
186 #[note]
187 pub struct InitializingTypeWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
188     #[primary_span]
189     #[label]
190     pub span: Span,
191 }
192
193 #[derive(Diagnostic)]
194 #[diag(mir_build_mutable_static_requires_unsafe, code = "E0133")]
195 #[note]
196 pub struct UseOfMutableStaticRequiresUnsafe {
197     #[primary_span]
198     #[label]
199     pub span: Span,
200 }
201
202 #[derive(Diagnostic)]
203 #[diag(mir_build_mutable_static_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")]
204 #[note]
205 pub struct UseOfMutableStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
206     #[primary_span]
207     #[label]
208     pub span: Span,
209 }
210
211 #[derive(Diagnostic)]
212 #[diag(mir_build_extern_static_requires_unsafe, code = "E0133")]
213 #[note]
214 pub struct UseOfExternStaticRequiresUnsafe {
215     #[primary_span]
216     #[label]
217     pub span: Span,
218 }
219
220 #[derive(Diagnostic)]
221 #[diag(mir_build_extern_static_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")]
222 #[note]
223 pub struct UseOfExternStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
224     #[primary_span]
225     #[label]
226     pub span: Span,
227 }
228
229 #[derive(Diagnostic)]
230 #[diag(mir_build_deref_raw_pointer_requires_unsafe, code = "E0133")]
231 #[note]
232 pub struct DerefOfRawPointerRequiresUnsafe {
233     #[primary_span]
234     #[label]
235     pub span: Span,
236 }
237
238 #[derive(Diagnostic)]
239 #[diag(mir_build_deref_raw_pointer_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")]
240 #[note]
241 pub struct DerefOfRawPointerRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
242     #[primary_span]
243     #[label]
244     pub span: Span,
245 }
246
247 #[derive(Diagnostic)]
248 #[diag(mir_build_union_field_requires_unsafe, code = "E0133")]
249 #[note]
250 pub struct AccessToUnionFieldRequiresUnsafe {
251     #[primary_span]
252     #[label]
253     pub span: Span,
254 }
255
256 #[derive(Diagnostic)]
257 #[diag(mir_build_union_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")]
258 #[note]
259 pub struct AccessToUnionFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
260     #[primary_span]
261     #[label]
262     pub span: Span,
263 }
264
265 #[derive(Diagnostic)]
266 #[diag(mir_build_mutation_of_layout_constrained_field_requires_unsafe, code = "E0133")]
267 #[note]
268 pub struct MutationOfLayoutConstrainedFieldRequiresUnsafe {
269     #[primary_span]
270     #[label]
271     pub span: Span,
272 }
273
274 #[derive(Diagnostic)]
275 #[diag(
276     mir_build_mutation_of_layout_constrained_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed,
277     code = "E0133"
278 )]
279 #[note]
280 pub struct MutationOfLayoutConstrainedFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
281     #[primary_span]
282     #[label]
283     pub span: Span,
284 }
285
286 #[derive(Diagnostic)]
287 #[diag(mir_build_borrow_of_layout_constrained_field_requires_unsafe, code = "E0133")]
288 #[note]
289 pub struct BorrowOfLayoutConstrainedFieldRequiresUnsafe {
290     #[primary_span]
291     #[label]
292     pub span: Span,
293 }
294
295 #[derive(Diagnostic)]
296 #[diag(
297     mir_build_borrow_of_layout_constrained_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed,
298     code = "E0133"
299 )]
300 #[note]
301 pub struct BorrowOfLayoutConstrainedFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed {
302     #[primary_span]
303     #[label]
304     pub span: Span,
305 }
306
307 #[derive(Diagnostic)]
308 #[diag(mir_build_call_to_fn_with_requires_unsafe, code = "E0133")]
309 #[note]
310 pub struct CallToFunctionWithRequiresUnsafe<'a> {
311     #[primary_span]
312     #[label]
313     pub span: Span,
314     pub function: &'a str,
315 }
316
317 #[derive(Diagnostic)]
318 #[diag(mir_build_call_to_fn_with_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = "E0133")]
319 #[note]
320 pub struct CallToFunctionWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed<'a> {
321     #[primary_span]
322     #[label]
323     pub span: Span,
324     pub function: &'a str,
325 }
326
327 #[derive(LintDiagnostic)]
328 #[diag(mir_build_unused_unsafe)]
329 pub struct UnusedUnsafe {
330     #[label]
331     pub span: Span,
332     #[subdiagnostic]
333     pub enclosing: Option<UnusedUnsafeEnclosing>,
334 }
335
336 #[derive(Subdiagnostic)]
337 pub enum UnusedUnsafeEnclosing {
338     #[label(mir_build_unused_unsafe_enclosing_block_label)]
339     Block {
340         #[primary_span]
341         span: Span,
342     },
343     #[label(mir_build_unused_unsafe_enclosing_fn_label)]
344     Function {
345         #[primary_span]
346         span: Span,
347     },
348 }
349
350 pub(crate) struct NonExhaustivePatternsTypeNotEmpty<'p, 'tcx, 'm> {
351     pub cx: &'m MatchCheckCtxt<'p, 'tcx>,
352     pub expr_span: Span,
353     pub span: Span,
354     pub ty: Ty<'tcx>,
355 }
356
357 impl<'a> IntoDiagnostic<'a> for NonExhaustivePatternsTypeNotEmpty<'_, '_, '_> {
358     fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
359         let mut diag = handler.struct_span_err_with_code(
360             self.span,
361             rustc_errors::fluent::mir_build_non_exhaustive_patterns_type_not_empty,
362             error_code!(E0004),
363         );
364
365         let peeled_ty = self.ty.peel_refs();
366         diag.set_arg("ty", self.ty);
367         diag.set_arg("peeled_ty", peeled_ty);
368
369         if let ty::Adt(def, _) = peeled_ty.kind() {
370             let def_span = self
371                 .cx
372                 .tcx
373                 .hir()
374                 .get_if_local(def.did())
375                 .and_then(|node| node.ident())
376                 .map(|ident| ident.span)
377                 .unwrap_or_else(|| self.cx.tcx.def_span(def.did()));
378
379             // workaround to make test pass
380             let mut span: MultiSpan = def_span.into();
381             span.push_span_label(def_span, "");
382
383             diag.span_note(span, rustc_errors::fluent::def_note);
384         }
385
386         let is_variant_list_non_exhaustive = match self.ty.kind() {
387             ty::Adt(def, _) if def.is_variant_list_non_exhaustive() && !def.did().is_local() => {
388                 true
389             }
390             _ => false,
391         };
392
393         if is_variant_list_non_exhaustive {
394             diag.note(rustc_errors::fluent::non_exhaustive_type_note);
395         } else {
396             diag.note(rustc_errors::fluent::type_note);
397         }
398
399         if let ty::Ref(_, sub_ty, _) = self.ty.kind() {
400             if !sub_ty.is_inhabited_from(self.cx.tcx, self.cx.module, self.cx.param_env) {
401                 diag.note(rustc_errors::fluent::reference_note);
402             }
403         }
404
405         let mut suggestion = None;
406         let sm = self.cx.tcx.sess.source_map();
407         if self.span.eq_ctxt(self.expr_span) {
408             // Get the span for the empty match body `{}`.
409             let (indentation, more) = if let Some(snippet) = sm.indentation_before(self.span) {
410                 (format!("\n{}", snippet), "    ")
411             } else {
412                 (" ".to_string(), "")
413             };
414             suggestion = Some((
415                 self.span.shrink_to_hi().with_hi(self.expr_span.hi()),
416                 format!(
417                     " {{{indentation}{more}_ => todo!(),{indentation}}}",
418                     indentation = indentation,
419                     more = more,
420                 ),
421             ));
422         }
423
424         if let Some((span, sugg)) = suggestion {
425             diag.span_suggestion_verbose(
426                 span,
427                 rustc_errors::fluent::suggestion,
428                 sugg,
429                 Applicability::HasPlaceholders,
430             );
431         } else {
432             diag.help(rustc_errors::fluent::help);
433         }
434
435         diag
436     }
437 }
438
439 #[derive(Diagnostic)]
440 #[diag(mir_build_static_in_pattern, code = "E0158")]
441 pub struct StaticInPattern {
442     #[primary_span]
443     pub span: Span,
444 }
445
446 #[derive(Diagnostic)]
447 #[diag(mir_build_assoc_const_in_pattern, code = "E0158")]
448 pub struct AssocConstInPattern {
449     #[primary_span]
450     pub span: Span,
451 }
452
453 #[derive(Diagnostic)]
454 #[diag(mir_build_const_param_in_pattern, code = "E0158")]
455 pub struct ConstParamInPattern {
456     #[primary_span]
457     pub span: Span,
458 }
459
460 #[derive(Diagnostic)]
461 #[diag(mir_build_non_const_path, code = "E0080")]
462 pub struct NonConstPath {
463     #[primary_span]
464     pub span: Span,
465 }
466
467 #[derive(LintDiagnostic)]
468 #[diag(mir_build_unreachable_pattern)]
469 pub struct UnreachablePattern {
470     #[label]
471     pub span: Option<Span>,
472     #[label(catchall_label)]
473     pub catchall: Option<Span>,
474 }
475
476 #[derive(Diagnostic)]
477 #[diag(mir_build_const_pattern_depends_on_generic_parameter)]
478 pub struct ConstPatternDependsOnGenericParameter {
479     #[primary_span]
480     pub span: Span,
481 }
482
483 #[derive(Diagnostic)]
484 #[diag(mir_build_could_not_eval_const_pattern)]
485 pub struct CouldNotEvalConstPattern {
486     #[primary_span]
487     pub span: Span,
488 }
489
490 #[derive(Diagnostic)]
491 #[diag(mir_build_lower_range_bound_must_be_less_than_or_equal_to_upper, code = "E0030")]
492 pub struct LowerRangeBoundMustBeLessThanOrEqualToUpper {
493     #[primary_span]
494     #[label]
495     pub span: Span,
496     #[note(teach_note)]
497     pub teach: Option<()>,
498 }
499
500 #[derive(Diagnostic)]
501 #[diag(mir_build_literal_in_range_out_of_bounds)]
502 pub struct LiteralOutOfRange<'tcx> {
503     #[primary_span]
504     #[label]
505     pub span: Span,
506     pub ty: Ty<'tcx>,
507     pub max: u128,
508 }
509
510 #[derive(Diagnostic)]
511 #[diag(mir_build_lower_range_bound_must_be_less_than_upper, code = "E0579")]
512 pub struct LowerRangeBoundMustBeLessThanUpper {
513     #[primary_span]
514     pub span: Span,
515 }
516
517 #[derive(LintDiagnostic)]
518 #[diag(mir_build_leading_irrefutable_let_patterns)]
519 #[note]
520 #[help]
521 pub struct LeadingIrrefutableLetPatterns {
522     pub count: usize,
523 }
524
525 #[derive(LintDiagnostic)]
526 #[diag(mir_build_trailing_irrefutable_let_patterns)]
527 #[note]
528 #[help]
529 pub struct TrailingIrrefutableLetPatterns {
530     pub count: usize,
531 }
532
533 #[derive(LintDiagnostic)]
534 #[diag(mir_build_bindings_with_variant_name, code = "E0170")]
535 pub struct BindingsWithVariantName {
536     #[suggestion(code = "{ty_path}::{ident}", applicability = "machine-applicable")]
537     pub suggestion: Option<Span>,
538     pub ty_path: String,
539     pub ident: Ident,
540 }
541
542 #[derive(LintDiagnostic)]
543 #[diag(mir_build_irrefutable_let_patterns_generic_let)]
544 #[note]
545 #[help]
546 pub struct IrrefutableLetPatternsGenericLet {
547     pub count: usize,
548 }
549
550 #[derive(LintDiagnostic)]
551 #[diag(mir_build_irrefutable_let_patterns_if_let)]
552 #[note]
553 #[help]
554 pub struct IrrefutableLetPatternsIfLet {
555     pub count: usize,
556 }
557
558 #[derive(LintDiagnostic)]
559 #[diag(mir_build_irrefutable_let_patterns_if_let_guard)]
560 #[note]
561 #[help]
562 pub struct IrrefutableLetPatternsIfLetGuard {
563     pub count: usize,
564 }
565
566 #[derive(LintDiagnostic)]
567 #[diag(mir_build_irrefutable_let_patterns_let_else)]
568 #[note]
569 #[help]
570 pub struct IrrefutableLetPatternsLetElse {
571     pub count: usize,
572 }
573
574 #[derive(LintDiagnostic)]
575 #[diag(mir_build_irrefutable_let_patterns_while_let)]
576 #[note]
577 #[help]
578 pub struct IrrefutableLetPatternsWhileLet {
579     pub count: usize,
580 }
581
582 #[derive(Diagnostic)]
583 #[diag(mir_build_borrow_of_moved_value)]
584 pub struct BorrowOfMovedValue<'tcx> {
585     #[primary_span]
586     pub span: Span,
587     #[label]
588     #[label(occurs_because_label)]
589     pub binding_span: Span,
590     #[label(value_borrowed_label)]
591     pub conflicts_ref: Vec<Span>,
592     pub name: Ident,
593     pub ty: Ty<'tcx>,
594     #[suggestion(code = "ref ", applicability = "machine-applicable")]
595     pub suggest_borrowing: Option<Span>,
596 }
597
598 #[derive(Diagnostic)]
599 #[diag(mir_build_multiple_mut_borrows)]
600 pub struct MultipleMutBorrows {
601     #[primary_span]
602     pub span: Span,
603     #[subdiagnostic]
604     pub occurences: Vec<Conflict>,
605 }
606
607 #[derive(Diagnostic)]
608 #[diag(mir_build_already_borrowed)]
609 pub struct AlreadyBorrowed {
610     #[primary_span]
611     pub span: Span,
612     #[subdiagnostic]
613     pub occurences: Vec<Conflict>,
614 }
615
616 #[derive(Diagnostic)]
617 #[diag(mir_build_already_mut_borrowed)]
618 pub struct AlreadyMutBorrowed {
619     #[primary_span]
620     pub span: Span,
621     #[subdiagnostic]
622     pub occurences: Vec<Conflict>,
623 }
624
625 #[derive(Diagnostic)]
626 #[diag(mir_build_moved_while_borrowed)]
627 pub struct MovedWhileBorrowed {
628     #[primary_span]
629     pub span: Span,
630     #[subdiagnostic]
631     pub occurences: Vec<Conflict>,
632 }
633
634 #[derive(Subdiagnostic)]
635 pub enum Conflict {
636     #[label(mir_build_mutable_borrow)]
637     Mut {
638         #[primary_span]
639         span: Span,
640         name: Ident,
641     },
642     #[label(mir_build_borrow)]
643     Ref {
644         #[primary_span]
645         span: Span,
646         name: Ident,
647     },
648     #[label(mir_build_moved)]
649     Moved {
650         #[primary_span]
651         span: Span,
652         name: Ident,
653     },
654 }
655
656 #[derive(Diagnostic)]
657 #[diag(mir_build_union_pattern)]
658 pub struct UnionPattern {
659     #[primary_span]
660     pub span: Span,
661 }
662
663 #[derive(Diagnostic)]
664 #[diag(mir_build_type_not_structural)]
665 pub struct TypeNotStructural<'tcx> {
666     #[primary_span]
667     pub span: Span,
668     pub non_sm_ty: Ty<'tcx>,
669 }
670
671 #[derive(Diagnostic)]
672 #[diag(mir_build_invalid_pattern)]
673 pub struct InvalidPattern<'tcx> {
674     #[primary_span]
675     pub span: Span,
676     pub non_sm_ty: Ty<'tcx>,
677 }
678
679 #[derive(Diagnostic)]
680 #[diag(mir_build_unsized_pattern)]
681 pub struct UnsizedPattern<'tcx> {
682     #[primary_span]
683     pub span: Span,
684     pub non_sm_ty: Ty<'tcx>,
685 }
686
687 #[derive(LintDiagnostic)]
688 #[diag(mir_build_float_pattern)]
689 pub struct FloatPattern;
690
691 #[derive(LintDiagnostic)]
692 #[diag(mir_build_pointer_pattern)]
693 pub struct PointerPattern;
694
695 #[derive(LintDiagnostic)]
696 #[diag(mir_build_indirect_structural_match)]
697 pub struct IndirectStructuralMatch<'tcx> {
698     pub non_sm_ty: Ty<'tcx>,
699 }
700
701 #[derive(LintDiagnostic)]
702 #[diag(mir_build_nontrivial_structural_match)]
703 pub struct NontrivialStructuralMatch<'tcx> {
704     pub non_sm_ty: Ty<'tcx>,
705 }
706
707 #[derive(LintDiagnostic)]
708 #[diag(mir_build_overlapping_range_endpoints)]
709 #[note]
710 pub struct OverlappingRangeEndpoints<'tcx> {
711     #[label(range)]
712     pub range: Span,
713     #[subdiagnostic]
714     pub overlap: Vec<Overlap<'tcx>>,
715 }
716
717 pub struct Overlap<'tcx> {
718     pub span: Span,
719     pub range: Pat<'tcx>,
720 }
721
722 impl<'tcx> AddToDiagnostic for Overlap<'tcx> {
723     fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
724     where
725         F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
726     {
727         let Overlap { span, range } = self;
728
729         // FIXME(mejrs) unfortunately `#[derive(LintDiagnostic)]`
730         // does not support `#[subdiagnostic(eager)]`...
731         let message = format!("this range overlaps on `{range}`...");
732         diag.span_label(span, message);
733     }
734 }
735
736 #[derive(LintDiagnostic)]
737 #[diag(mir_build_non_exhaustive_omitted_pattern)]
738 #[help]
739 #[note]
740 pub(crate) struct NonExhaustiveOmittedPattern<'tcx> {
741     pub scrut_ty: Ty<'tcx>,
742     #[subdiagnostic]
743     pub uncovered: Uncovered<'tcx>,
744 }
745
746 #[derive(Subdiagnostic)]
747 #[label(mir_build_uncovered)]
748 pub(crate) struct Uncovered<'tcx> {
749     #[primary_span]
750     span: Span,
751     count: usize,
752     witness_1: Pat<'tcx>,
753     witness_2: Pat<'tcx>,
754     witness_3: Pat<'tcx>,
755     remainder: usize,
756 }
757
758 impl<'tcx> Uncovered<'tcx> {
759     pub fn new<'p>(
760         span: Span,
761         cx: &MatchCheckCtxt<'p, 'tcx>,
762         witnesses: Vec<DeconstructedPat<'p, 'tcx>>,
763     ) -> Self {
764         let witness_1 = witnesses.get(0).unwrap().to_pat(cx);
765         Self {
766             span,
767             count: witnesses.len(),
768             // Substitute dummy values if witnesses is smaller than 3. These will never be read.
769             witness_2: witnesses.get(1).map(|w| w.to_pat(cx)).unwrap_or_else(|| witness_1.clone()),
770             witness_3: witnesses.get(2).map(|w| w.to_pat(cx)).unwrap_or_else(|| witness_1.clone()),
771             witness_1,
772             remainder: witnesses.len().saturating_sub(3),
773         }
774     }
775 }
776
777 #[derive(Diagnostic)]
778 #[diag(mir_build_pattern_not_covered, code = "E0005")]
779 pub(crate) struct PatternNotCovered<'s, 'tcx> {
780     #[primary_span]
781     pub span: Span,
782     pub origin: &'s str,
783     #[subdiagnostic]
784     pub uncovered: Uncovered<'tcx>,
785     #[subdiagnostic]
786     pub inform: Option<Inform>,
787     #[subdiagnostic]
788     pub interpreted_as_const: Option<InterpretedAsConst>,
789     #[subdiagnostic]
790     pub adt_defined_here: Option<AdtDefinedHere<'tcx>>,
791     #[note(pattern_ty)]
792     pub _p: (),
793     pub pattern_ty: Ty<'tcx>,
794     #[subdiagnostic]
795     pub let_suggestion: Option<SuggestLet>,
796     #[subdiagnostic]
797     pub misc_suggestion: Option<MiscPatternSuggestion>,
798     #[subdiagnostic]
799     pub res_defined_here: Option<ResDefinedHere>,
800 }
801
802 #[derive(Subdiagnostic)]
803 #[note(mir_build_inform_irrefutable)]
804 #[note(mir_build_more_information)]
805 pub struct Inform;
806
807 pub struct AdtDefinedHere<'tcx> {
808     pub adt_def_span: Span,
809     pub ty: Ty<'tcx>,
810     pub variants: Vec<Variant>,
811 }
812
813 pub struct Variant {
814     pub span: Span,
815 }
816
817 impl<'tcx> AddToDiagnostic for AdtDefinedHere<'tcx> {
818     fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
819     where
820         F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
821     {
822         diag.set_arg("ty", self.ty);
823         let mut spans = MultiSpan::from(self.adt_def_span);
824
825         for Variant { span } in self.variants {
826             spans.push_span_label(span, rustc_errors::fluent::mir_build_variant_defined_here);
827         }
828
829         diag.span_note(spans, rustc_errors::fluent::mir_build_adt_defined_here);
830     }
831 }
832
833 #[derive(Subdiagnostic)]
834 #[label(mir_build_res_defined_here)]
835 pub struct ResDefinedHere {
836     #[primary_span]
837     pub def_span: Span,
838     pub res: Res,
839 }
840
841 #[derive(Subdiagnostic)]
842 #[suggestion(
843     mir_build_interpreted_as_const,
844     code = "{variable}_var",
845     applicability = "maybe-incorrect"
846 )]
847 #[label(mir_build_confused)]
848 pub struct InterpretedAsConst {
849     #[primary_span]
850     pub span: Span,
851     pub article: &'static str,
852     pub variable: String,
853     pub res: Res,
854 }
855
856 #[derive(Subdiagnostic)]
857 pub enum SuggestLet {
858     #[multipart_suggestion(mir_build_suggest_if_let, applicability = "has-placeholders")]
859     If {
860         #[suggestion_part(code = "if ")]
861         start_span: Span,
862         #[suggestion_part(code = " {{ todo!() }}")]
863         semi_span: Span,
864         count: usize,
865     },
866     #[suggestion(
867         mir_build_suggest_let_else,
868         code = " else {{ todo!() }}",
869         applicability = "has-placeholders"
870     )]
871     Else {
872         #[primary_span]
873         end_span: Span,
874         count: usize,
875     },
876 }
877
878 #[derive(Subdiagnostic)]
879 pub enum MiscPatternSuggestion {
880     #[suggestion(
881         mir_build_suggest_attempted_int_lit,
882         code = "_",
883         applicability = "maybe-incorrect"
884     )]
885     AttemptedIntegerLiteral {
886         #[primary_span]
887         start_span: Span,
888     },
889 }