From 998bf0ab88a372c1b19dd367c1fe6f51728b87eb Mon Sep 17 00:00:00 2001 From: Daniel Noom Date: Sun, 3 Jan 2021 14:13:33 +0100 Subject: [PATCH 1/3] Add note to non-exhaustive match on reference to empty Rust prints "type `&A` is non-empty" even is A is empty. This is the intended behavior, but can be confusing. This commit adds a note to non-exhaustive pattern errors if they are a reference to something uninhabited. I did not add tests to check that the note is not shown for non-references or inhabited references, because this is already done in other tests. Maybe the added test is superfluous, because `always-inhabited-union-ref` already checks for this case. This does not handle &&Void or &&&void etc. I could add those as special cases as well and ignore people who need quadruple references. Fixes #78123 --- .../src/thir/pattern/check_match.rs | 5 +++++ .../usefulness/always-inhabited-union-ref.stderr | 1 + .../issue-78123-non-exhaustive-reference.rs | 7 +++++++ .../issue-78123-non-exhaustive-reference.stderr | 16 ++++++++++++++++ 4 files changed, 29 insertions(+) create mode 100644 src/test/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.rs create mode 100644 src/test/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.stderr diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index db817b378f9..a70c1a28176 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -503,6 +503,11 @@ fn non_exhaustive_match<'p, 'tcx>( )); } } + if let ty::Ref(_, sub_ty, _) = scrut_ty.kind() { + if cx.tcx.is_ty_uninhabited_from(cx.module, sub_ty, cx.param_env) { + err.note("references are always considered inhabited"); + } + } err.emit(); } diff --git a/src/test/ui/pattern/usefulness/always-inhabited-union-ref.stderr b/src/test/ui/pattern/usefulness/always-inhabited-union-ref.stderr index 0fa77fb73da..2ca774a48b6 100644 --- a/src/test/ui/pattern/usefulness/always-inhabited-union-ref.stderr +++ b/src/test/ui/pattern/usefulness/always-inhabited-union-ref.stderr @@ -6,6 +6,7 @@ LL | match uninhab_ref() { | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms = note: the matched value is of type `&!` + = note: references are always considered inhabited error[E0004]: non-exhaustive patterns: type `Foo` is non-empty --> $DIR/always-inhabited-union-ref.rs:27:11 diff --git a/src/test/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.rs b/src/test/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.rs new file mode 100644 index 00000000000..517678560c5 --- /dev/null +++ b/src/test/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.rs @@ -0,0 +1,7 @@ +enum A {} + +fn f(a: &A) { + match a {} //~ ERROR non-exhaustive patterns: type `&A` is non-empty +} + +fn main() {} diff --git a/src/test/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.stderr b/src/test/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.stderr new file mode 100644 index 00000000000..7cd04629aaf --- /dev/null +++ b/src/test/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.stderr @@ -0,0 +1,16 @@ +error[E0004]: non-exhaustive patterns: type `&A` is non-empty + --> $DIR/issue-78123-non-exhaustive-reference.rs:4:11 + | +LL | enum A {} + | --------- `A` defined here +... +LL | match a {} + | ^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + = note: the matched value is of type `&A` + = note: references are always considered inhabited + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0004`. From 9cba8a37f92d87ef5b5c2c7f109345b6c7634874 Mon Sep 17 00:00:00 2001 From: Daniel Noom Date: Sun, 3 Jan 2021 20:49:35 +0100 Subject: [PATCH 2/3] Add note on void reference test This test is also changed by adding a note about uninhabited references still counting as inhabited. --- src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr b/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr index 960c4792e65..7b999f50773 100644 --- a/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr +++ b/src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr @@ -23,6 +23,7 @@ LL | let _ = match x {}; | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms = note: the matched value is of type `&Void` + = note: references are always considered inhabited error[E0004]: non-exhaustive patterns: type `(Void,)` is non-empty --> $DIR/uninhabited-matches-feature-gated.rs:18:19 From 914bc1717877b7f2520e7b95435ee70742a14ba3 Mon Sep 17 00:00:00 2001 From: Daniel Noom Date: Sun, 3 Jan 2021 21:12:27 +0100 Subject: [PATCH 3/3] Add notes to stderr of non-exhaustive-reference test --- .../usefulness/issue-78123-non-exhaustive-reference.rs | 6 +++++- .../usefulness/issue-78123-non-exhaustive-reference.stderr | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/test/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.rs b/src/test/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.rs index 517678560c5..6c5a331b4b5 100644 --- a/src/test/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.rs +++ b/src/test/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.rs @@ -1,7 +1,11 @@ enum A {} + //~^ NOTE `A` defined here fn f(a: &A) { - match a {} //~ ERROR non-exhaustive patterns: type `&A` is non-empty + match a {} + //~^ ERROR non-exhaustive patterns: type `&A` is non-empty + //~| NOTE the matched value is of type `&A` + //~| NOTE references are always considered inhabited } fn main() {} diff --git a/src/test/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.stderr b/src/test/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.stderr index 7cd04629aaf..e992632a91f 100644 --- a/src/test/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.stderr +++ b/src/test/ui/pattern/usefulness/issue-78123-non-exhaustive-reference.stderr @@ -1,5 +1,5 @@ error[E0004]: non-exhaustive patterns: type `&A` is non-empty - --> $DIR/issue-78123-non-exhaustive-reference.rs:4:11 + --> $DIR/issue-78123-non-exhaustive-reference.rs:5:11 | LL | enum A {} | --------- `A` defined here