Skip to main content

rustc_pattern_analysis/
errors.rs

1use rustc_errors::{Diag, EmissionGuarantee, Subdiagnostic};
2use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
3use rustc_middle::ty::Ty;
4use rustc_span::Span;
5
6use crate::rustc::{RustcPatCtxt, WitnessPat};
7
8#[derive(const _: () =
    {
        impl rustc_errors::Subdiagnostic for Uncovered {
            fn add_to_diag<__G>(self, diag: &mut rustc_errors::Diag<'_, __G>)
                where __G: rustc_errors::EmissionGuarantee {
                match self {
                    Uncovered {
                        span: __binding_0,
                        count: __binding_1,
                        witness_1: __binding_2,
                        witness_2: __binding_3,
                        witness_3: __binding_4,
                        remainder: __binding_5 } => {
                        diag.store_args();
                        diag.arg("count", __binding_1);
                        diag.arg("witness_1", __binding_2);
                        diag.arg("witness_2", __binding_3);
                        diag.arg("witness_3", __binding_4);
                        diag.arg("remainder", __binding_5);
                        let __message =
                            diag.eagerly_translate(crate::fluent_generated::pattern_analysis_uncovered);
                        diag.span_label(__binding_0, __message);
                        diag.restore_args();
                    }
                }
            }
        }
    };Subdiagnostic)]
9#[label(pattern_analysis_uncovered)]
10pub struct Uncovered {
11    #[primary_span]
12    span: Span,
13    count: usize,
14    witness_1: String, // a printed pattern
15    witness_2: String, // a printed pattern
16    witness_3: String, // a printed pattern
17    remainder: usize,
18}
19
20impl Uncovered {
21    pub fn new<'p, 'tcx>(
22        span: Span,
23        cx: &RustcPatCtxt<'p, 'tcx>,
24        witnesses: Vec<WitnessPat<'p, 'tcx>>,
25    ) -> Self
26    where
27        'tcx: 'p,
28    {
29        let witness_1 = cx.print_witness_pat(witnesses.get(0).unwrap());
30        Self {
31            span,
32            count: witnesses.len(),
33            // Substitute dummy values if witnesses is smaller than 3. These will never be read.
34            witness_2: witnesses.get(1).map(|w| cx.print_witness_pat(w)).unwrap_or_default(),
35            witness_3: witnesses.get(2).map(|w| cx.print_witness_pat(w)).unwrap_or_default(),
36            witness_1,
37            remainder: witnesses.len().saturating_sub(3),
38        }
39    }
40}
41
42#[derive(const _: () =
    {
        impl<'__a> rustc_errors::LintDiagnostic<'__a, ()> for
            OverlappingRangeEndpoints {
            #[track_caller]
            fn decorate_lint<'__b>(self,
                diag: &'__b mut rustc_errors::Diag<'__a, ()>) {
                match self {
                    OverlappingRangeEndpoints {
                        range: __binding_0, overlap: __binding_1 } => {
                        diag.primary_message(crate::fluent_generated::pattern_analysis_overlapping_range_endpoints);
                        diag.note(crate::fluent_generated::_subdiag::note);
                        ;
                        diag.span_label(__binding_0,
                            crate::fluent_generated::_subdiag::label);
                        for __binding_1 in __binding_1 {
                            diag.subdiagnostic(__binding_1);
                        }
                        diag
                    }
                };
            }
        }
    };LintDiagnostic)]
43#[diag(pattern_analysis_overlapping_range_endpoints)]
44#[note]
45pub struct OverlappingRangeEndpoints {
46    #[label]
47    pub range: Span,
48    #[subdiagnostic]
49    pub overlap: Vec<Overlap>,
50}
51
52pub struct Overlap {
53    pub span: Span,
54    pub range: String, // a printed pattern
55}
56
57impl Subdiagnostic for Overlap {
58    fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
59        let Overlap { span, range } = self;
60
61        // FIXME(mejrs) unfortunately `#[derive(LintDiagnostic)]`
62        // does not support `#[subdiagnostic(eager)]`...
63        let message = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("this range overlaps on `{0}`...",
                range))
    })format!("this range overlaps on `{range}`...");
64        diag.span_label(span, message);
65    }
66}
67
68#[derive(const _: () =
    {
        impl<'__a> rustc_errors::LintDiagnostic<'__a, ()> for
            ExclusiveRangeMissingMax {
            #[track_caller]
            fn decorate_lint<'__b>(self,
                diag: &'__b mut rustc_errors::Diag<'__a, ()>) {
                match self {
                    ExclusiveRangeMissingMax {
                        first_range: __binding_0,
                        suggestion: __binding_1,
                        max: __binding_2 } => {
                        diag.primary_message(crate::fluent_generated::pattern_analysis_excluside_range_missing_max);
                        ;
                        let __code_0 =
                            [::alloc::__export::must_use({
                                                ::alloc::fmt::format(format_args!("{0}", __binding_1))
                                            })].into_iter();
                        diag.arg("suggestion", __binding_1);
                        diag.arg("max", __binding_2);
                        diag.span_label(__binding_0,
                            crate::fluent_generated::_subdiag::label);
                        diag.span_suggestions_with_style(__binding_0,
                            crate::fluent_generated::_subdiag::suggestion, __code_0,
                            rustc_errors::Applicability::MaybeIncorrect,
                            rustc_errors::SuggestionStyle::ShowCode);
                        diag
                    }
                };
            }
        }
    };LintDiagnostic)]
69#[diag(pattern_analysis_excluside_range_missing_max)]
70pub struct ExclusiveRangeMissingMax {
71    #[label]
72    #[suggestion(code = "{suggestion}", applicability = "maybe-incorrect")]
73    /// This is an exclusive range that looks like `lo..max` (i.e. doesn't match `max`).
74    pub first_range: Span,
75    /// Suggest `lo..=max` instead.
76    pub suggestion: String,
77    pub max: String, // a printed pattern
78}
79
80#[derive(const _: () =
    {
        impl<'__a> rustc_errors::LintDiagnostic<'__a, ()> for
            ExclusiveRangeMissingGap {
            #[track_caller]
            fn decorate_lint<'__b>(self,
                diag: &'__b mut rustc_errors::Diag<'__a, ()>) {
                match self {
                    ExclusiveRangeMissingGap {
                        first_range: __binding_0,
                        gap: __binding_1,
                        suggestion: __binding_2,
                        gap_with: __binding_3 } => {
                        diag.primary_message(crate::fluent_generated::pattern_analysis_excluside_range_missing_gap);
                        ;
                        let __code_1 =
                            [::alloc::__export::must_use({
                                                ::alloc::fmt::format(format_args!("{0}", __binding_2))
                                            })].into_iter();
                        diag.arg("gap", __binding_1);
                        diag.arg("suggestion", __binding_2);
                        diag.span_label(__binding_0,
                            crate::fluent_generated::_subdiag::label);
                        diag.span_suggestions_with_style(__binding_0,
                            crate::fluent_generated::_subdiag::suggestion, __code_1,
                            rustc_errors::Applicability::MaybeIncorrect,
                            rustc_errors::SuggestionStyle::ShowCode);
                        for __binding_3 in __binding_3 {
                            diag.subdiagnostic(__binding_3);
                        }
                        diag
                    }
                };
            }
        }
    };LintDiagnostic)]
81#[diag(pattern_analysis_excluside_range_missing_gap)]
82pub struct ExclusiveRangeMissingGap {
83    #[label]
84    #[suggestion(code = "{suggestion}", applicability = "maybe-incorrect")]
85    /// This is an exclusive range that looks like `lo..gap` (i.e. doesn't match `gap`).
86    pub first_range: Span,
87    pub gap: String, // a printed pattern
88    /// Suggest `lo..=gap` instead.
89    pub suggestion: String,
90    #[subdiagnostic]
91    /// All these ranges skipped over `gap` which we think is probably a mistake.
92    pub gap_with: Vec<GappedRange>,
93}
94
95pub struct GappedRange {
96    pub span: Span,
97    pub gap: String,         // a printed pattern
98    pub first_range: String, // a printed pattern
99}
100
101impl Subdiagnostic for GappedRange {
102    fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
103        let GappedRange { span, gap, first_range } = self;
104
105        // FIXME(mejrs) unfortunately `#[derive(LintDiagnostic)]`
106        // does not support `#[subdiagnostic(eager)]`...
107        let message = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("this could appear to continue range `{0}`, but `{1}` isn\'t matched by either of them",
                first_range, gap))
    })format!(
108            "this could appear to continue range `{first_range}`, but `{gap}` isn't matched by \
109            either of them"
110        );
111        diag.span_label(span, message);
112    }
113}
114
115#[derive(const _: () =
    {
        impl<'__a, 'tcx> rustc_errors::LintDiagnostic<'__a, ()> for
            NonExhaustiveOmittedPattern<'tcx> {
            #[track_caller]
            fn decorate_lint<'__b>(self,
                diag: &'__b mut rustc_errors::Diag<'__a, ()>) {
                match self {
                    NonExhaustiveOmittedPattern {
                        scrut_ty: __binding_0, uncovered: __binding_1 } => {
                        diag.primary_message(crate::fluent_generated::pattern_analysis_non_exhaustive_omitted_pattern);
                        diag.help(crate::fluent_generated::_subdiag::help);
                        diag.note(crate::fluent_generated::_subdiag::note);
                        ;
                        diag.arg("scrut_ty", __binding_0);
                        diag.subdiagnostic(__binding_1);
                        diag
                    }
                };
            }
        }
    };LintDiagnostic)]
116#[diag(pattern_analysis_non_exhaustive_omitted_pattern)]
117#[help]
118#[note]
119pub(crate) struct NonExhaustiveOmittedPattern<'tcx> {
120    pub scrut_ty: Ty<'tcx>,
121    #[subdiagnostic]
122    pub uncovered: Uncovered,
123}
124
125#[derive(const _: () =
    {
        impl<'__a> rustc_errors::LintDiagnostic<'__a, ()> for
            NonExhaustiveOmittedPatternLintOnArm {
            #[track_caller]
            fn decorate_lint<'__b>(self,
                diag: &'__b mut rustc_errors::Diag<'__a, ()>) {
                match self {
                    NonExhaustiveOmittedPatternLintOnArm {
                        lint_span: __binding_0,
                        suggest_lint_on_match: __binding_1,
                        lint_level: __binding_2,
                        lint_name: __binding_3 } => {
                        diag.primary_message(crate::fluent_generated::pattern_analysis_non_exhaustive_omitted_pattern_lint_on_arm);
                        diag.help(crate::fluent_generated::_subdiag::help);
                        ;
                        let __code_2 =
                            [::alloc::__export::must_use({
                                                ::alloc::fmt::format(format_args!("#[{0}({1})]\n",
                                                        __binding_2, __binding_3))
                                            })].into_iter();
                        diag.arg("lint_level", __binding_2);
                        diag.arg("lint_name", __binding_3);
                        diag.span_label(__binding_0,
                            crate::fluent_generated::_subdiag::label);
                        if let Some(__binding_1) = __binding_1 {
                            diag.span_suggestions_with_style(__binding_1,
                                crate::fluent_generated::_subdiag::suggestion, __code_2,
                                rustc_errors::Applicability::MaybeIncorrect,
                                rustc_errors::SuggestionStyle::ShowCode);
                        }
                        diag
                    }
                };
            }
        }
    };LintDiagnostic)]
126#[diag(pattern_analysis_non_exhaustive_omitted_pattern_lint_on_arm)]
127#[help]
128pub(crate) struct NonExhaustiveOmittedPatternLintOnArm {
129    #[label]
130    pub lint_span: Span,
131    #[suggestion(code = "#[{lint_level}({lint_name})]\n", applicability = "maybe-incorrect")]
132    pub suggest_lint_on_match: Option<Span>,
133    pub lint_level: &'static str,
134    pub lint_name: &'static str,
135}
136
137#[derive(const _: () =
    {
        impl<'_sess, 'tcx, G> rustc_errors::Diagnostic<'_sess, G> for
            MixedDerefPatternConstructors<'tcx> where
            G: rustc_errors::EmissionGuarantee {
            #[track_caller]
            fn into_diag(self, dcx: rustc_errors::DiagCtxtHandle<'_sess>,
                level: rustc_errors::Level) -> rustc_errors::Diag<'_sess, G> {
                match self {
                    MixedDerefPatternConstructors {
                        spans: __binding_0,
                        smart_pointer_ty: __binding_1,
                        deref_pattern_label: __binding_2,
                        normal_constructor_label: __binding_3 } => {
                        let mut diag =
                            rustc_errors::Diag::new(dcx, level,
                                crate::fluent_generated::pattern_analysis_mixed_deref_pattern_constructors);
                        ;
                        diag.arg("smart_pointer_ty", __binding_1);
                        diag.span(__binding_0.clone());
                        diag.span_label(__binding_2,
                            crate::fluent_generated::pattern_analysis_deref_pattern_label);
                        diag.span_label(__binding_3,
                            crate::fluent_generated::pattern_analysis_normal_constructor_label);
                        diag
                    }
                }
            }
        }
    };Diagnostic)]
138#[diag(pattern_analysis_mixed_deref_pattern_constructors)]
139pub(crate) struct MixedDerefPatternConstructors<'tcx> {
140    #[primary_span]
141    pub spans: Vec<Span>,
142    pub smart_pointer_ty: Ty<'tcx>,
143    #[label(pattern_analysis_deref_pattern_label)]
144    pub deref_pattern_label: Span,
145    #[label(pattern_analysis_normal_constructor_label)]
146    pub normal_constructor_label: Span,
147}