Skip to content

Commit f5f93d0

Browse files
committed
Auto merge of #109836 - clubby789:param-non-exhaustive, r=Nilstrieb
Fix `non_exhaustive_omitted_patterns` on arguments and locals Fixes #99815 r? `@Nilstrieb`
2 parents 63fdb82 + 46f7d3d commit f5f93d0

File tree

3 files changed

+35
-1
lines changed

3 files changed

+35
-1
lines changed

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

+3
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@ 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;
303304
use rustc_middle::ty::{self, Ty, TyCtxt};
304305
use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS;
305306
use rustc_span::{Span, DUMMY_SP};
@@ -867,6 +868,8 @@ fn is_useful<'p, 'tcx>(
867868
&ctor,
868869
Constructor::Missing { nonexhaustive_enum_missing_real_variants: true }
869870
)
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(_)))
870873
{
871874
let patterns = {
872875
let mut split_wildcard = SplitWildcard::new(pcx);

tests/ui/rfc-2008-non-exhaustive/omitted-patterns.rs

+16
Original file line numberDiff line numberDiff line change
@@ -184,4 +184,20 @@ fn main() {
184184
// OK: both unstable and stable fields are matched with feature on
185185
#[warn(non_exhaustive_omitted_patterns)]
186186
let UnstableStruct { stable, stable2, unstable, .. } = UnstableStruct::default();
187+
188+
// Ok: local bindings are allowed
189+
#[deny(non_exhaustive_omitted_patterns)]
190+
let local = NonExhaustiveEnum::Unit;
191+
192+
// Ok: missing patterns will be blocked by the pattern being refutable
193+
#[deny(non_exhaustive_omitted_patterns)]
194+
let local_refutable @ NonExhaustiveEnum::Unit = NonExhaustiveEnum::Unit;
195+
//~^ refutable pattern in local binding
196+
197+
}
198+
199+
#[deny(non_exhaustive_omitted_patterns)]
200+
// Ok: Pattern in a param is always wildcard
201+
pub fn takes_non_exhaustive(_: NonExhaustiveEnum) {
202+
let _closure = |_: NonExhaustiveEnum| {};
187203
}

tests/ui/rfc-2008-non-exhaustive/omitted-patterns.stderr

+16-1
Original file line numberDiff line numberDiff line change
@@ -184,5 +184,20 @@ note: the lint level is defined here
184184
LL | #[deny(non_exhaustive_omitted_patterns)]
185185
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
186186

187-
error: aborting due to 8 previous errors; 6 warnings emitted
187+
error[E0005]: refutable pattern in local binding
188+
--> $DIR/omitted-patterns.rs:194:9
189+
|
190+
LL | let local_refutable @ NonExhaustiveEnum::Unit = NonExhaustiveEnum::Unit;
191+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `_` not covered
192+
|
193+
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
194+
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
195+
= note: the matched value is of type `NonExhaustiveEnum`
196+
help: you might want to use `let else` to handle the variant that isn't matched
197+
|
198+
LL | let local_refutable @ NonExhaustiveEnum::Unit = NonExhaustiveEnum::Unit else { todo!() };
199+
| ++++++++++++++++
200+
201+
error: aborting due to 9 previous errors; 6 warnings emitted
188202

203+
For more information about this error, try `rustc --explain E0005`.

0 commit comments

Comments
 (0)