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