]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_mir_build/src/errors.rs
Rollup merge of #106953 - kylematsuda:early-binder-docs, r=jackh726
[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     #[label]
604     pub binding_span: Span,
605     #[subdiagnostic]
606     pub occurences: Vec<MultipleMutBorrowOccurence>,
607     pub name: Ident,
608 }
609
610 #[derive(Subdiagnostic)]
611 pub enum MultipleMutBorrowOccurence {
612     #[label(mutable_borrow)]
613     Mutable {
614         #[primary_span]
615         span: Span,
616         name_mut: Ident,
617     },
618     #[label(immutable_borrow)]
619     Immutable {
620         #[primary_span]
621         span: Span,
622         name_immut: Ident,
623     },
624     #[label(moved)]
625     Moved {
626         #[primary_span]
627         span: Span,
628         name_moved: Ident,
629     },
630 }
631
632 #[derive(Diagnostic)]
633 #[diag(mir_build_union_pattern)]
634 pub struct UnionPattern {
635     #[primary_span]
636     pub span: Span,
637 }
638
639 #[derive(Diagnostic)]
640 #[diag(mir_build_type_not_structural)]
641 pub struct TypeNotStructural<'tcx> {
642     #[primary_span]
643     pub span: Span,
644     pub non_sm_ty: Ty<'tcx>,
645 }
646
647 #[derive(Diagnostic)]
648 #[diag(mir_build_invalid_pattern)]
649 pub struct InvalidPattern<'tcx> {
650     #[primary_span]
651     pub span: Span,
652     pub non_sm_ty: Ty<'tcx>,
653 }
654
655 #[derive(Diagnostic)]
656 #[diag(mir_build_unsized_pattern)]
657 pub struct UnsizedPattern<'tcx> {
658     #[primary_span]
659     pub span: Span,
660     pub non_sm_ty: Ty<'tcx>,
661 }
662
663 #[derive(LintDiagnostic)]
664 #[diag(mir_build_float_pattern)]
665 pub struct FloatPattern;
666
667 #[derive(LintDiagnostic)]
668 #[diag(mir_build_pointer_pattern)]
669 pub struct PointerPattern;
670
671 #[derive(LintDiagnostic)]
672 #[diag(mir_build_indirect_structural_match)]
673 pub struct IndirectStructuralMatch<'tcx> {
674     pub non_sm_ty: Ty<'tcx>,
675 }
676
677 #[derive(LintDiagnostic)]
678 #[diag(mir_build_nontrivial_structural_match)]
679 pub struct NontrivialStructuralMatch<'tcx> {
680     pub non_sm_ty: Ty<'tcx>,
681 }
682
683 #[derive(LintDiagnostic)]
684 #[diag(mir_build_overlapping_range_endpoints)]
685 #[note]
686 pub struct OverlappingRangeEndpoints<'tcx> {
687     #[label(range)]
688     pub range: Span,
689     #[subdiagnostic]
690     pub overlap: Vec<Overlap<'tcx>>,
691 }
692
693 pub struct Overlap<'tcx> {
694     pub span: Span,
695     pub range: Pat<'tcx>,
696 }
697
698 impl<'tcx> AddToDiagnostic for Overlap<'tcx> {
699     fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
700     where
701         F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
702     {
703         let Overlap { span, range } = self;
704
705         // FIXME(mejrs) unfortunately `#[derive(LintDiagnostic)]`
706         // does not support `#[subdiagnostic(eager)]`...
707         let message = format!("this range overlaps on `{range}`...");
708         diag.span_label(span, message);
709     }
710 }
711
712 #[derive(LintDiagnostic)]
713 #[diag(mir_build_non_exhaustive_omitted_pattern)]
714 #[help]
715 #[note]
716 pub(crate) struct NonExhaustiveOmittedPattern<'tcx> {
717     pub scrut_ty: Ty<'tcx>,
718     #[subdiagnostic]
719     pub uncovered: Uncovered<'tcx>,
720 }
721
722 #[derive(Subdiagnostic)]
723 #[label(mir_build_uncovered)]
724 pub(crate) struct Uncovered<'tcx> {
725     #[primary_span]
726     span: Span,
727     count: usize,
728     witness_1: Pat<'tcx>,
729     witness_2: Pat<'tcx>,
730     witness_3: Pat<'tcx>,
731     remainder: usize,
732 }
733
734 impl<'tcx> Uncovered<'tcx> {
735     pub fn new<'p>(
736         span: Span,
737         cx: &MatchCheckCtxt<'p, 'tcx>,
738         witnesses: Vec<DeconstructedPat<'p, 'tcx>>,
739     ) -> Self {
740         let witness_1 = witnesses.get(0).unwrap().to_pat(cx);
741         Self {
742             span,
743             count: witnesses.len(),
744             // Substitute dummy values if witnesses is smaller than 3. These will never be read.
745             witness_2: witnesses.get(1).map(|w| w.to_pat(cx)).unwrap_or_else(|| witness_1.clone()),
746             witness_3: witnesses.get(2).map(|w| w.to_pat(cx)).unwrap_or_else(|| witness_1.clone()),
747             witness_1,
748             remainder: witnesses.len().saturating_sub(3),
749         }
750     }
751 }
752
753 #[derive(Diagnostic)]
754 #[diag(mir_build_pattern_not_covered, code = "E0005")]
755 pub(crate) struct PatternNotCovered<'s, 'tcx> {
756     #[primary_span]
757     pub span: Span,
758     pub origin: &'s str,
759     #[subdiagnostic]
760     pub uncovered: Uncovered<'tcx>,
761     #[subdiagnostic]
762     pub inform: Option<Inform>,
763     #[subdiagnostic]
764     pub interpreted_as_const: Option<InterpretedAsConst>,
765     #[subdiagnostic]
766     pub adt_defined_here: Option<AdtDefinedHere<'tcx>>,
767     #[note(pattern_ty)]
768     pub _p: (),
769     pub pattern_ty: Ty<'tcx>,
770     #[subdiagnostic]
771     pub let_suggestion: Option<SuggestLet>,
772     #[subdiagnostic]
773     pub misc_suggestion: Option<MiscPatternSuggestion>,
774     #[subdiagnostic]
775     pub res_defined_here: Option<ResDefinedHere>,
776 }
777
778 #[derive(Subdiagnostic)]
779 #[note(mir_build_inform_irrefutable)]
780 #[note(mir_build_more_information)]
781 pub struct Inform;
782
783 pub struct AdtDefinedHere<'tcx> {
784     pub adt_def_span: Span,
785     pub ty: Ty<'tcx>,
786     pub variants: Vec<Variant>,
787 }
788
789 pub struct Variant {
790     pub span: Span,
791 }
792
793 impl<'tcx> AddToDiagnostic for AdtDefinedHere<'tcx> {
794     fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
795     where
796         F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
797     {
798         diag.set_arg("ty", self.ty);
799         let mut spans = MultiSpan::from(self.adt_def_span);
800
801         for Variant { span } in self.variants {
802             spans.push_span_label(span, rustc_errors::fluent::mir_build_variant_defined_here);
803         }
804
805         diag.span_note(spans, rustc_errors::fluent::mir_build_adt_defined_here);
806     }
807 }
808
809 #[derive(Subdiagnostic)]
810 #[label(mir_build_res_defined_here)]
811 pub struct ResDefinedHere {
812     #[primary_span]
813     pub def_span: Span,
814     pub res: Res,
815 }
816
817 #[derive(Subdiagnostic)]
818 #[suggestion(
819     mir_build_interpreted_as_const,
820     code = "{variable}_var",
821     applicability = "maybe-incorrect"
822 )]
823 #[label(mir_build_confused)]
824 pub struct InterpretedAsConst {
825     #[primary_span]
826     pub span: Span,
827     pub article: &'static str,
828     pub variable: String,
829     pub res: Res,
830 }
831
832 #[derive(Subdiagnostic)]
833 pub enum SuggestLet {
834     #[multipart_suggestion(mir_build_suggest_if_let, applicability = "has-placeholders")]
835     If {
836         #[suggestion_part(code = "if ")]
837         start_span: Span,
838         #[suggestion_part(code = " {{ todo!() }}")]
839         semi_span: Span,
840         count: usize,
841     },
842     #[suggestion(
843         mir_build_suggest_let_else,
844         code = " else {{ todo!() }}",
845         applicability = "has-placeholders"
846     )]
847     Else {
848         #[primary_span]
849         end_span: Span,
850         count: usize,
851     },
852 }
853
854 #[derive(Subdiagnostic)]
855 pub enum MiscPatternSuggestion {
856     #[suggestion(
857         mir_build_suggest_attempted_int_lit,
858         code = "_",
859         applicability = "maybe-incorrect"
860     )]
861     AttemptedIntegerLiteral {
862         #[primary_span]
863         start_span: Span,
864     },
865 }