|
308 | 308 | use self::ArmType::*;
|
309 | 309 | use self::Usefulness::*;
|
310 | 310 | use super::deconstruct_pat::{Constructor, ConstructorSet, DeconstructedPat, WitnessPat};
|
311 |
| -use crate::errors::{NonExhaustiveOmittedPattern, Uncovered}; |
| 311 | +use crate::errors::{NonExhaustiveOmittedPattern, NonExhaustiveOmittedPatternLintOnArm, Uncovered}; |
312 | 312 |
|
313 | 313 | use rustc_data_structures::captures::Captures;
|
314 | 314 |
|
@@ -1021,30 +1021,47 @@ pub(crate) fn compute_match_usefulness<'p, 'tcx>(
|
1021 | 1021 |
|
1022 | 1022 | // Run the non_exhaustive_omitted_patterns lint. Only run on refutable patterns to avoid hitting
|
1023 | 1023 | // `if let`s. Only run if the match is exhaustive otherwise the error is redundant.
|
1024 |
| - if cx.refutable |
1025 |
| - && non_exhaustiveness_witnesses.is_empty() |
1026 |
| - && !matches!( |
| 1024 | + if cx.refutable && non_exhaustiveness_witnesses.is_empty() { |
| 1025 | + if !matches!( |
1027 | 1026 | cx.tcx.lint_level_at_node(NON_EXHAUSTIVE_OMITTED_PATTERNS, lint_root).0,
|
1028 | 1027 | rustc_session::lint::Level::Allow
|
1029 |
| - ) |
1030 |
| - { |
1031 |
| - let pat_column = arms.iter().flat_map(|arm| arm.pat.flatten_or_pat()).collect::<Vec<_>>(); |
1032 |
| - let witnesses = collect_nonexhaustive_missing_variants(cx, &pat_column); |
1033 |
| - |
1034 |
| - if !witnesses.is_empty() { |
1035 |
| - // Report that a match of a `non_exhaustive` enum marked with `non_exhaustive_omitted_patterns` |
1036 |
| - // is not exhaustive enough. |
1037 |
| - // |
1038 |
| - // NB: The partner lint for structs lives in `compiler/rustc_hir_analysis/src/check/pat.rs`. |
1039 |
| - cx.tcx.emit_spanned_lint( |
1040 |
| - NON_EXHAUSTIVE_OMITTED_PATTERNS, |
1041 |
| - lint_root, |
1042 |
| - scrut_span, |
1043 |
| - NonExhaustiveOmittedPattern { |
1044 |
| - scrut_ty, |
1045 |
| - uncovered: Uncovered::new(scrut_span, cx, witnesses), |
1046 |
| - }, |
1047 |
| - ); |
| 1028 | + ) { |
| 1029 | + let pat_column = |
| 1030 | + arms.iter().flat_map(|arm| arm.pat.flatten_or_pat()).collect::<Vec<_>>(); |
| 1031 | + let witnesses = collect_nonexhaustive_missing_variants(cx, &pat_column); |
| 1032 | + |
| 1033 | + if !witnesses.is_empty() { |
| 1034 | + // Report that a match of a `non_exhaustive` enum marked with `non_exhaustive_omitted_patterns` |
| 1035 | + // is not exhaustive enough. |
| 1036 | + // |
| 1037 | + // NB: The partner lint for structs lives in `compiler/rustc_hir_analysis/src/check/pat.rs`. |
| 1038 | + cx.tcx.emit_spanned_lint( |
| 1039 | + NON_EXHAUSTIVE_OMITTED_PATTERNS, |
| 1040 | + lint_root, |
| 1041 | + scrut_span, |
| 1042 | + NonExhaustiveOmittedPattern { |
| 1043 | + scrut_ty, |
| 1044 | + uncovered: Uncovered::new(scrut_span, cx, witnesses), |
| 1045 | + }, |
| 1046 | + ); |
| 1047 | + } |
| 1048 | + } else { |
| 1049 | + // We used to allow putting the `#[allow(non_exhaustive_omitted_patterns)]` on a match |
| 1050 | + // arm. This no longer makes sense so we warn users, to avoid silently breaking their |
| 1051 | + // usage of the lint. |
| 1052 | + for arm in arms { |
| 1053 | + if !matches!( |
| 1054 | + cx.tcx.lint_level_at_node(NON_EXHAUSTIVE_OMITTED_PATTERNS, arm.hir_id).0, |
| 1055 | + rustc_session::lint::Level::Allow |
| 1056 | + ) { |
| 1057 | + cx.tcx.emit_spanned_lint( |
| 1058 | + NON_EXHAUSTIVE_OMITTED_PATTERNS, |
| 1059 | + arm.hir_id, |
| 1060 | + arm.pat.span(), |
| 1061 | + NonExhaustiveOmittedPatternLintOnArm, |
| 1062 | + ); |
| 1063 | + } |
| 1064 | + } |
1048 | 1065 | }
|
1049 | 1066 | }
|
1050 | 1067 |
|
|
0 commit comments