mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-02 07:22:42 +00:00
Only emit lint on refutable patterns.
This commit is contained in:
parent
03fbb3db1e
commit
03a6ef67fe
@ -199,12 +199,13 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
|
||||
cx.pattern_arena.alloc(DeconstructedPat::from_pat(cx, &pattern))
|
||||
}
|
||||
|
||||
fn new_cx(&self, hir_id: HirId) -> MatchCheckCtxt<'p, 'tcx> {
|
||||
fn new_cx(&self, hir_id: HirId, refutable: bool) -> MatchCheckCtxt<'p, 'tcx> {
|
||||
MatchCheckCtxt {
|
||||
tcx: self.tcx,
|
||||
param_env: self.param_env,
|
||||
module: self.tcx.parent_module(hir_id).to_def_id(),
|
||||
pattern_arena: &self.pattern_arena,
|
||||
refutable,
|
||||
}
|
||||
}
|
||||
|
||||
@ -214,7 +215,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
|
||||
return;
|
||||
}
|
||||
self.check_patterns(pat, Refutable);
|
||||
let mut cx = self.new_cx(self.lint_level);
|
||||
let mut cx = self.new_cx(self.lint_level, true);
|
||||
let tpat = self.lower_pattern(&mut cx, pat);
|
||||
self.check_let_reachability(&mut cx, self.lint_level, source, tpat, span);
|
||||
}
|
||||
@ -226,7 +227,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
|
||||
source: hir::MatchSource,
|
||||
expr_span: Span,
|
||||
) {
|
||||
let mut cx = self.new_cx(self.lint_level);
|
||||
let mut cx = self.new_cx(self.lint_level, true);
|
||||
|
||||
for &arm in arms {
|
||||
// Check the arm for some things unrelated to exhaustiveness.
|
||||
@ -328,7 +329,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
|
||||
debug!(?expr, ?local_lint_level, "after scopes");
|
||||
match expr.kind {
|
||||
ExprKind::Let { box ref pat, expr: _ } => {
|
||||
let mut ncx = self.new_cx(local_lint_level);
|
||||
let mut ncx = self.new_cx(local_lint_level, true);
|
||||
let tpat = self.lower_pattern(&mut ncx, pat);
|
||||
let refutable = !is_let_irrefutable(&mut ncx, local_lint_level, tpat);
|
||||
Some((expr.span, refutable))
|
||||
@ -409,7 +410,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
|
||||
|
||||
#[instrument(level = "trace", skip(self))]
|
||||
fn check_irrefutable(&self, pat: &Pat<'tcx>, origin: &str, sp: Option<Span>) {
|
||||
let mut cx = self.new_cx(self.lint_level);
|
||||
let mut cx = self.new_cx(self.lint_level, false);
|
||||
|
||||
let pattern = self.lower_pattern(&mut cx, pat);
|
||||
let pattern_ty = pattern.ty();
|
||||
|
@ -300,7 +300,6 @@ use rustc_arena::TypedArena;
|
||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::HirId;
|
||||
use rustc_hir::Node;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS;
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
@ -319,6 +318,8 @@ pub(crate) struct MatchCheckCtxt<'p, 'tcx> {
|
||||
pub(crate) module: DefId,
|
||||
pub(crate) param_env: ty::ParamEnv<'tcx>,
|
||||
pub(crate) pattern_arena: &'p TypedArena<DeconstructedPat<'p, 'tcx>>,
|
||||
/// Only produce `NON_EXHAUSTIVE_OMITTED_PATTERNS` lint on refutable patterns.
|
||||
pub(crate) refutable: bool,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> {
|
||||
@ -860,6 +861,8 @@ fn is_useful<'p, 'tcx>(
|
||||
// that has the potential to trigger the `non_exhaustive_omitted_patterns` lint.
|
||||
// To understand the workings checkout `Constructor::split` and `SplitWildcard::new/into_ctors`
|
||||
if is_non_exhaustive_and_wild
|
||||
// Only emit a lint on refutable patterns.
|
||||
&& cx.refutable
|
||||
// We check that the match has a wildcard pattern and that wildcard is useful,
|
||||
// meaning there are variants that are covered by the wildcard. Without the check
|
||||
// for `witness_preference` the lint would trigger on `if let NonExhaustiveEnum::A = foo {}`
|
||||
@ -868,8 +871,6 @@ fn is_useful<'p, 'tcx>(
|
||||
&ctor,
|
||||
Constructor::Missing { nonexhaustive_enum_missing_real_variants: true }
|
||||
)
|
||||
// We don't want to lint patterns which are function arguments or locals
|
||||
&& !matches!(cx.tcx.hir().find_parent(hir_id), Some(Node::Param(_)|Node::Local(_)))
|
||||
{
|
||||
let patterns = {
|
||||
let mut split_wildcard = SplitWildcard::new(pcx);
|
||||
|
Loading…
Reference in New Issue
Block a user