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