Skip to content

Commit 03a6ef6

Browse files
committed
Only emit lint on refutable patterns.
1 parent 03fbb3d commit 03a6ef6

File tree

2 files changed

+10
-8
lines changed

2 files changed

+10
-8
lines changed

compiler/rustc_mir_build/src/thir/pattern/check_match.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -199,12 +199,13 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
199199
cx.pattern_arena.alloc(DeconstructedPat::from_pat(cx, &pattern))
200200
}
201201

202-
fn new_cx(&self, hir_id: HirId) -> MatchCheckCtxt<'p, 'tcx> {
202+
fn new_cx(&self, hir_id: HirId, refutable: bool) -> MatchCheckCtxt<'p, 'tcx> {
203203
MatchCheckCtxt {
204204
tcx: self.tcx,
205205
param_env: self.param_env,
206206
module: self.tcx.parent_module(hir_id).to_def_id(),
207207
pattern_arena: &self.pattern_arena,
208+
refutable,
208209
}
209210
}
210211

@@ -214,7 +215,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
214215
return;
215216
}
216217
self.check_patterns(pat, Refutable);
217-
let mut cx = self.new_cx(self.lint_level);
218+
let mut cx = self.new_cx(self.lint_level, true);
218219
let tpat = self.lower_pattern(&mut cx, pat);
219220
self.check_let_reachability(&mut cx, self.lint_level, source, tpat, span);
220221
}
@@ -226,7 +227,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
226227
source: hir::MatchSource,
227228
expr_span: Span,
228229
) {
229-
let mut cx = self.new_cx(self.lint_level);
230+
let mut cx = self.new_cx(self.lint_level, true);
230231

231232
for &arm in arms {
232233
// Check the arm for some things unrelated to exhaustiveness.
@@ -328,7 +329,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
328329
debug!(?expr, ?local_lint_level, "after scopes");
329330
match expr.kind {
330331
ExprKind::Let { box ref pat, expr: _ } => {
331-
let mut ncx = self.new_cx(local_lint_level);
332+
let mut ncx = self.new_cx(local_lint_level, true);
332333
let tpat = self.lower_pattern(&mut ncx, pat);
333334
let refutable = !is_let_irrefutable(&mut ncx, local_lint_level, tpat);
334335
Some((expr.span, refutable))
@@ -409,7 +410,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
409410

410411
#[instrument(level = "trace", skip(self))]
411412
fn check_irrefutable(&self, pat: &Pat<'tcx>, origin: &str, sp: Option<Span>) {
412-
let mut cx = self.new_cx(self.lint_level);
413+
let mut cx = self.new_cx(self.lint_level, false);
413414

414415
let pattern = self.lower_pattern(&mut cx, pat);
415416
let pattern_ty = pattern.ty();

compiler/rustc_mir_build/src/thir/pattern/usefulness.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,6 @@ use rustc_arena::TypedArena;
300300
use rustc_data_structures::stack::ensure_sufficient_stack;
301301
use rustc_hir::def_id::DefId;
302302
use rustc_hir::HirId;
303-
use rustc_hir::Node;
304303
use rustc_middle::ty::{self, Ty, TyCtxt};
305304
use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS;
306305
use rustc_span::{Span, DUMMY_SP};
@@ -319,6 +318,8 @@ pub(crate) struct MatchCheckCtxt<'p, 'tcx> {
319318
pub(crate) module: DefId,
320319
pub(crate) param_env: ty::ParamEnv<'tcx>,
321320
pub(crate) pattern_arena: &'p TypedArena<DeconstructedPat<'p, 'tcx>>,
321+
/// Only produce `NON_EXHAUSTIVE_OMITTED_PATTERNS` lint on refutable patterns.
322+
pub(crate) refutable: bool,
322323
}
323324

324325
impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> {
@@ -860,6 +861,8 @@ fn is_useful<'p, 'tcx>(
860861
// that has the potential to trigger the `non_exhaustive_omitted_patterns` lint.
861862
// To understand the workings checkout `Constructor::split` and `SplitWildcard::new/into_ctors`
862863
if is_non_exhaustive_and_wild
864+
// Only emit a lint on refutable patterns.
865+
&& cx.refutable
863866
// We check that the match has a wildcard pattern and that wildcard is useful,
864867
// meaning there are variants that are covered by the wildcard. Without the check
865868
// for `witness_preference` the lint would trigger on `if let NonExhaustiveEnum::A = foo {}`
@@ -868,8 +871,6 @@ fn is_useful<'p, 'tcx>(
868871
&ctor,
869872
Constructor::Missing { nonexhaustive_enum_missing_real_variants: true }
870873
)
871-
// We don't want to lint patterns which are function arguments or locals
872-
&& !matches!(cx.tcx.hir().find_parent(hir_id), Some(Node::Param(_)|Node::Local(_)))
873874
{
874875
let patterns = {
875876
let mut split_wildcard = SplitWildcard::new(pcx);

0 commit comments

Comments
 (0)