|
| 1 | +use crate::thir::pattern::deconstruct_pat::DeconstructedPat; |
1 | 2 | use crate::thir::pattern::MatchCheckCtxt;
|
2 | 3 | use rustc_errors::Handler;
|
3 | 4 | use rustc_errors::{
|
4 |
| - error_code, Applicability, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic, MultiSpan, |
| 5 | + error_code, AddToDiagnostic, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, |
| 6 | + IntoDiagnostic, MultiSpan, SubdiagnosticMessage, |
5 | 7 | };
|
| 8 | +use rustc_hir::def::Res; |
6 | 9 | use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
|
| 10 | +use rustc_middle::thir::Pat; |
7 | 11 | use rustc_middle::ty::{self, Ty};
|
8 | 12 | use rustc_span::{symbol::Ident, Span};
|
9 | 13 |
|
@@ -624,3 +628,223 @@ pub enum MultipleMutBorrowOccurence {
|
624 | 628 | name_moved: Ident,
|
625 | 629 | },
|
626 | 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 res_defined_here: Option<ResDefinedHere>, |
| 774 | +} |
| 775 | + |
| 776 | +#[derive(Subdiagnostic)] |
| 777 | +#[note(mir_build_inform_irrefutable)] |
| 778 | +#[note(mir_build_more_information)] |
| 779 | +pub struct Inform; |
| 780 | + |
| 781 | +pub struct AdtDefinedHere<'tcx> { |
| 782 | + pub adt_def_span: Span, |
| 783 | + pub ty: Ty<'tcx>, |
| 784 | + pub variants: Vec<Variant>, |
| 785 | +} |
| 786 | + |
| 787 | +pub struct Variant { |
| 788 | + pub span: Span, |
| 789 | +} |
| 790 | + |
| 791 | +impl<'tcx> AddToDiagnostic for AdtDefinedHere<'tcx> { |
| 792 | + fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F) |
| 793 | + where |
| 794 | + F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, |
| 795 | + { |
| 796 | + diag.set_arg("ty", self.ty); |
| 797 | + let mut spans = MultiSpan::from(self.adt_def_span); |
| 798 | + |
| 799 | + for Variant { span } in self.variants { |
| 800 | + spans.push_span_label(span, rustc_errors::fluent::mir_build_variant_defined_here); |
| 801 | + } |
| 802 | + |
| 803 | + diag.span_note(spans, rustc_errors::fluent::mir_build_adt_defined_here); |
| 804 | + } |
| 805 | +} |
| 806 | + |
| 807 | +#[derive(Subdiagnostic)] |
| 808 | +#[label(mir_build_res_defined_here)] |
| 809 | +pub struct ResDefinedHere { |
| 810 | + #[primary_span] |
| 811 | + pub def_span: Span, |
| 812 | + pub res: Res, |
| 813 | +} |
| 814 | + |
| 815 | +#[derive(Subdiagnostic)] |
| 816 | +#[suggestion( |
| 817 | + mir_build_interpreted_as_const, |
| 818 | + code = "{variable}_var", |
| 819 | + applicability = "maybe-incorrect" |
| 820 | +)] |
| 821 | +#[label(mir_build_confused)] |
| 822 | +pub struct InterpretedAsConst { |
| 823 | + #[primary_span] |
| 824 | + pub span: Span, |
| 825 | + pub article: &'static str, |
| 826 | + pub variable: String, |
| 827 | + pub res: Res, |
| 828 | +} |
| 829 | + |
| 830 | +#[derive(Subdiagnostic)] |
| 831 | +pub enum SuggestLet { |
| 832 | + #[multipart_suggestion(mir_build_suggest_if_let, applicability = "has-placeholders")] |
| 833 | + If { |
| 834 | + #[suggestion_part(code = "if ")] |
| 835 | + start_span: Span, |
| 836 | + #[suggestion_part(code = " {{ todo!() }}")] |
| 837 | + semi_span: Span, |
| 838 | + count: usize, |
| 839 | + }, |
| 840 | + #[suggestion( |
| 841 | + mir_build_suggest_let_else, |
| 842 | + code = " else {{ todo!() }}", |
| 843 | + applicability = "has-placeholders" |
| 844 | + )] |
| 845 | + Else { |
| 846 | + #[primary_span] |
| 847 | + end_span: Span, |
| 848 | + count: usize, |
| 849 | + }, |
| 850 | +} |
0 commit comments