From 7e4924b55d25847bad6d4760a8484456c758ff52 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sun, 29 Oct 2023 21:14:52 +0100 Subject: [PATCH] Add tests --- tests/ui/pattern/usefulness/impl-trait.rs | 146 ++++++++++++++++++ tests/ui/pattern/usefulness/impl-trait.stderr | 71 +++++++++ 2 files changed, 217 insertions(+) create mode 100644 tests/ui/pattern/usefulness/impl-trait.rs create mode 100644 tests/ui/pattern/usefulness/impl-trait.stderr diff --git a/tests/ui/pattern/usefulness/impl-trait.rs b/tests/ui/pattern/usefulness/impl-trait.rs new file mode 100644 index 00000000000..6fa28877b3e --- /dev/null +++ b/tests/ui/pattern/usefulness/impl-trait.rs @@ -0,0 +1,146 @@ +#![feature(never_type)] +#![feature(exhaustive_patterns)] +#![feature(type_alias_impl_trait)] +#![feature(non_exhaustive_omitted_patterns_lint)] +#![deny(unreachable_patterns)] +// Test that the lint traversal handles opaques correctly +#![deny(non_exhaustive_omitted_patterns)] + +fn main() {} + +#[derive(Copy, Clone)] +enum Void {} + +fn return_never_rpit(x: Void) -> impl Copy { + if false { + match return_never_rpit(x) { + _ => {} + } + } + x +} +fn friend_of_return_never_rpit(x: Void) { + match return_never_rpit(x) {} + //~^ ERROR non-empty +} + +type T = impl Copy; +fn return_never_tait(x: Void) -> T { + if false { + match return_never_tait(x) { + _ => {} + } + } + x +} +fn friend_of_return_never_tait(x: Void) { + match return_never_tait(x) {} + //~^ ERROR non-empty +} + +fn option_never(x: Void) -> Option { + if false { + match option_never(x) { + None => {} + Some(_) => {} + } + match option_never(x) { + None => {} + // FIXME: Unreachable not detected because `is_uninhabited` does not look into opaque + // types. + _ => {} + } + } + Some(x) +} + +fn option_never2(x: Void) -> impl Copy { + if false { + match option_never2(x) { + None => {} + Some(_) => {} //~ ERROR unreachable + } + match option_never2(x) { + None => {} + _ => {} //~ ERROR unreachable + } + match option_never2(x) { + None => {} + } + } + Some(x) +} + +fn inner_never(x: Void) { + type T = impl Copy; + let y: T = x; + match y { + _ => {} + } +} + +// This one caused ICE https://github.com/rust-lang/rust/issues/117100. +fn inner_tuple() { + type T = impl Copy; + let foo: T = Some((1u32, 2u32)); + match foo { + _ => {} + Some((a, b)) => {} //~ ERROR unreachable + } +} + +type U = impl Copy; +fn unify_never(x: Void, u: U) -> U { + if false { + match u { + _ => {} + } + } + x +} + +type V = impl Copy; +fn infer_in_match(x: Option) { + match x { + None => {} + Some((a, b)) => {} + Some((mut x, mut y)) => { + //~^ ERROR unreachable + x = 42; + y = "foo"; + } + } +} + +type W = impl Copy; +#[derive(Copy, Clone)] +struct Rec<'a> { + n: u32, + w: Option<&'a W>, +} +fn recursive_opaque() -> W { + if false { + match recursive_opaque() { + // Check for the ol' ICE when the type is recursively opaque. + _ => {} + Rec { n: 0, w: Some(Rec { n: 0, w: _ }) } => {} //~ ERROR unreachable + } + } + let w: Option<&'static W> = None; + Rec { n: 0, w } +} + +type X = impl Copy; +struct SecretelyVoid(X); +fn nested_empty_opaque(x: Void) -> X { + if false { + let opaque_void = nested_empty_opaque(x); + let secretely_void = SecretelyVoid(opaque_void); + match secretely_void { + // FIXME: Unreachable not detected because `is_uninhabited` does not look into opaque + // types. + _ => {} + } + } + x +} diff --git a/tests/ui/pattern/usefulness/impl-trait.stderr b/tests/ui/pattern/usefulness/impl-trait.stderr new file mode 100644 index 00000000000..6d7cef88d4f --- /dev/null +++ b/tests/ui/pattern/usefulness/impl-trait.stderr @@ -0,0 +1,71 @@ +error: unreachable pattern + --> $DIR/impl-trait.rs:61:13 + | +LL | Some(_) => {} + | ^^^^^^^ + | +note: the lint level is defined here + --> $DIR/impl-trait.rs:5:9 + | +LL | #![deny(unreachable_patterns)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: unreachable pattern + --> $DIR/impl-trait.rs:65:13 + | +LL | _ => {} + | ^ + +error: unreachable pattern + --> $DIR/impl-trait.rs:88:9 + | +LL | _ => {} + | - matches any value +LL | Some((a, b)) => {} + | ^^^^^^^^^^^^ unreachable pattern + +error: unreachable pattern + --> $DIR/impl-trait.rs:107:9 + | +LL | Some((mut x, mut y)) => { + | ^^^^^^^^^^^^^^^^^^^^ + +error: unreachable pattern + --> $DIR/impl-trait.rs:126:13 + | +LL | _ => {} + | - matches any value +LL | Rec { n: 0, w: Some(Rec { n: 0, w: _ }) } => {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unreachable pattern + +error[E0004]: non-exhaustive patterns: type `impl Copy` is non-empty + --> $DIR/impl-trait.rs:23:11 + | +LL | match return_never_rpit(x) {} + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: the matched value is of type `impl Copy` +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown + | +LL ~ match return_never_rpit(x) { +LL + _ => todo!(), +LL + } + | + +error[E0004]: non-exhaustive patterns: type `T` is non-empty + --> $DIR/impl-trait.rs:37:11 + | +LL | match return_never_tait(x) {} + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: the matched value is of type `T` +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown + | +LL ~ match return_never_tait(x) { +LL + _ => todo!(), +LL + } + | + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0004`.