diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl index 8dd337f0c525a..dda4debecec67 100644 --- a/compiler/rustc_mir_build/messages.ftl +++ b/compiler/rustc_mir_build/messages.ftl @@ -325,12 +325,16 @@ mir_build_union_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed = mir_build_union_pattern = cannot use unions in constant patterns +mir_build_unreachable_making_this_unreachable = collectively making this unreachable + +mir_build_unreachable_matches_same_values = matches some of the same values + mir_build_unreachable_pattern = unreachable pattern .label = unreachable pattern .unreachable_matches_no_values = this pattern matches no values because `{$ty}` is uninhabited .unreachable_covered_by_catchall = matches any value .unreachable_covered_by_one = matches all the values already - .unreachable_covered_by_many = matches some of the same values + .unreachable_covered_by_many = these patterns collectively make the last one unreachable mir_build_unsafe_fn_safe_body = an unsafe function restricts its caller, but its body is safe by default mir_build_unsafe_not_inherited = items do not inherit unsafety from separate enclosing items diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index cf2962d9fcf20..bdc4b0ea97d18 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -591,8 +591,8 @@ pub(crate) struct UnreachablePattern<'tcx> { pub(crate) covered_by_catchall: Option, #[label(mir_build_unreachable_covered_by_one)] pub(crate) covered_by_one: Option, - #[subdiagnostic] - pub(crate) covered_by_many: Option, + #[note(mir_build_unreachable_covered_by_many)] + pub(crate) covered_by_many: Option, } #[derive(Subdiagnostic)] @@ -601,20 +601,6 @@ pub(crate) struct UnreachableMatchesNoValues<'tcx> { pub(crate) ty: Ty<'tcx>, } -pub(crate) struct UnreachableCoveredByMany(pub(crate) Vec); - -impl Subdiagnostic for UnreachableCoveredByMany { - fn add_to_diag_with>( - self, - diag: &mut Diag<'_, G>, - _f: &F, - ) { - for span in self.0 { - diag.span_label(span, fluent::mir_build_unreachable_covered_by_many); - } - } -} - #[derive(Diagnostic)] #[diag(mir_build_const_pattern_depends_on_generic_parameter, code = E0158)] pub(crate) struct ConstPatternDependsOnGenericParameter { 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 3c476a7766cc2..5e904057e732c 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -1,4 +1,5 @@ use crate::errors::*; +use crate::fluent_generated as fluent; use rustc_arena::{DroplessArena, TypedArena}; use rustc_ast::Mutability; @@ -944,8 +945,16 @@ fn report_unreachable_pattern<'p, 'tcx>( lint.covered_by_one = Some(covering_pat.data().span); } covering_pats => { - let covering_spans = covering_pats.iter().map(|p| p.data().span).collect(); - lint.covered_by_many = Some(UnreachableCoveredByMany(covering_spans)); + let mut multispan = MultiSpan::from_span(pat_span); + for p in covering_pats { + multispan.push_span_label( + p.data().span, + fluent::mir_build_unreachable_matches_same_values, + ); + } + multispan + .push_span_label(pat_span, fluent::mir_build_unreachable_making_this_unreachable); + lint.covered_by_many = Some(multispan); } } cx.tcx.emit_node_span_lint(UNREACHABLE_PATTERNS, hir_id, pat_span, lint); diff --git a/tests/ui/error-codes/E0001.stderr b/tests/ui/error-codes/E0001.stderr index bf8c5235f70c5..40008230ec801 100644 --- a/tests/ui/error-codes/E0001.stderr +++ b/tests/ui/error-codes/E0001.stderr @@ -1,13 +1,18 @@ error: unreachable pattern --> $DIR/E0001.rs:8:9 | +LL | _ => {/* ... */} + | ^ unreachable pattern + | +note: these patterns collectively make the last one unreachable + --> $DIR/E0001.rs:8:9 + | LL | Some(_) => {/* ... */} | ------- matches some of the same values LL | None => {/* ... */} | ---- matches some of the same values LL | _ => {/* ... */} - | ^ unreachable pattern - | + | ^ collectively making this unreachable note: the lint level is defined here --> $DIR/E0001.rs:1:9 | diff --git a/tests/ui/or-patterns/exhaustiveness-unreachable-pattern.stderr b/tests/ui/or-patterns/exhaustiveness-unreachable-pattern.stderr index 5c7d9db1c9204..5570390b21c28 100644 --- a/tests/ui/or-patterns/exhaustiveness-unreachable-pattern.stderr +++ b/tests/ui/or-patterns/exhaustiveness-unreachable-pattern.stderr @@ -23,12 +23,18 @@ LL | (2,) => {} error: unreachable pattern --> $DIR/exhaustiveness-unreachable-pattern.rs:19:9 | +LL | (1 | 2,) => {} + | ^^^^^^^^ unreachable pattern + | +note: these patterns collectively make the last one unreachable + --> $DIR/exhaustiveness-unreachable-pattern.rs:19:9 + | LL | (1,) => {} | ---- matches some of the same values LL | (2,) => {} | ---- matches some of the same values LL | (1 | 2,) => {} - | ^^^^^^^^ unreachable pattern + | ^^^^^^^^ collectively making this unreachable error: unreachable pattern --> $DIR/exhaustiveness-unreachable-pattern.rs:24:9 @@ -68,13 +74,19 @@ LL | (2 | 1, 4) => {} error: unreachable pattern --> $DIR/exhaustiveness-unreachable-pattern.rs:29:9 | +LL | (1, 4 | 5) => {} + | ^^^^^^^^^^ unreachable pattern + | +note: these patterns collectively make the last one unreachable + --> $DIR/exhaustiveness-unreachable-pattern.rs:29:9 + | LL | (1 | 2, 3 | 4) => {} | -------------- matches some of the same values ... LL | (1, 5 | 6) => {} | ---------- matches some of the same values LL | (1, 4 | 5) => {} - | ^^^^^^^^^^ unreachable pattern + | ^^^^^^^^^^ collectively making this unreachable error: unreachable pattern --> $DIR/exhaustiveness-unreachable-pattern.rs:34:13 @@ -177,10 +189,16 @@ LL | (true, 0 | 0) => {} error: unreachable pattern --> $DIR/exhaustiveness-unreachable-pattern.rs:84:17 | +LL | (_, 0 | 0) => {} + | ^ unreachable pattern + | +note: these patterns collectively make the last one unreachable + --> $DIR/exhaustiveness-unreachable-pattern.rs:84:17 + | LL | (true, 0 | 0) => {} | - matches some of the same values LL | (_, 0 | 0) => {} - | - ^ unreachable pattern + | - ^ collectively making this unreachable | | | matches some of the same values @@ -203,12 +221,18 @@ LL | [true error: unreachable pattern --> $DIR/exhaustiveness-unreachable-pattern.rs:111:36 | +LL | (true | false, None | Some(true + | ^^^^ unreachable pattern + | +note: these patterns collectively make the last one unreachable + --> $DIR/exhaustiveness-unreachable-pattern.rs:111:36 + | LL | (true, Some(_)) => {} | - matches some of the same values LL | (false, Some(true)) => {} | ---- matches some of the same values LL | (true | false, None | Some(true - | ^^^^ unreachable pattern + | ^^^^ collectively making this unreachable error: unreachable pattern --> $DIR/exhaustiveness-unreachable-pattern.rs:116:14 @@ -216,13 +240,21 @@ error: unreachable pattern LL | (true | ^^^^ unreachable pattern ... +LL | (true | false, None | Some(t_or_f!())) => {} + | --------- in this macro invocation + | +note: these patterns collectively make the last one unreachable + --> $DIR/exhaustiveness-unreachable-pattern.rs:116:14 + | +LL | (true + | ^^^^ collectively making this unreachable +... LL | (true, Some(_)) => {} | - matches some of the same values LL | (false, Some(true)) => {} | ---- matches some of the same values LL | (true | false, None | Some(t_or_f!())) => {} | --------- in this macro invocation - | = note: this error originates in the macro `t_or_f` (in Nightly builds, run with -Z macro-backtrace for more info) error: unreachable pattern @@ -245,24 +277,36 @@ LL | | false) => {} error: unreachable pattern --> $DIR/exhaustiveness-unreachable-pattern.rs:154:15 | +LL | | true) => {} + | ^^^^ unreachable pattern + | +note: these patterns collectively make the last one unreachable + --> $DIR/exhaustiveness-unreachable-pattern.rs:154:15 + | LL | (false, true) => {} | ---- matches some of the same values LL | (true, true) => {} | ---- matches some of the same values LL | (false | true, false LL | | true) => {} - | ^^^^ unreachable pattern + | ^^^^ collectively making this unreachable error: unreachable pattern --> $DIR/exhaustiveness-unreachable-pattern.rs:160:15 | +LL | | true, + | ^^^^ unreachable pattern + | +note: these patterns collectively make the last one unreachable + --> $DIR/exhaustiveness-unreachable-pattern.rs:160:15 + | LL | (true, false) => {} | ---- matches some of the same values LL | (true, true) => {} | ---- matches some of the same values LL | (false LL | | true, - | ^^^^ unreachable pattern + | ^^^^ collectively making this unreachable error: unreachable pattern --> $DIR/exhaustiveness-unreachable-pattern.rs:165:15 diff --git a/tests/ui/pattern/usefulness/consts-opaque.stderr b/tests/ui/pattern/usefulness/consts-opaque.stderr index fdec3683c4a4e..9d3a35321caf0 100644 --- a/tests/ui/pattern/usefulness/consts-opaque.stderr +++ b/tests/ui/pattern/usefulness/consts-opaque.stderr @@ -122,12 +122,18 @@ LL | BAZ => {} error: unreachable pattern --> $DIR/consts-opaque.rs:87:9 | +LL | _ => {} // should not be emitting unreachable warning + | ^ unreachable pattern + | +note: these patterns collectively make the last one unreachable + --> $DIR/consts-opaque.rs:87:9 + | LL | BAZ => {} | --- matches some of the same values LL | Baz::Baz2 => {} | --------- matches some of the same values LL | _ => {} // should not be emitting unreachable warning - | ^ unreachable pattern + | ^ collectively making this unreachable error: aborting due to 17 previous errors diff --git a/tests/ui/pattern/usefulness/explain-unreachable-pats.rs b/tests/ui/pattern/usefulness/explain-unreachable-pats.rs index 6a27f7d4a8274..98f781b6a09f7 100644 --- a/tests/ui/pattern/usefulness/explain-unreachable-pats.rs +++ b/tests/ui/pattern/usefulness/explain-unreachable-pats.rs @@ -22,6 +22,8 @@ fn main() { (1 | 2,) => {} //~^ ERROR unreachable pattern //~| NOTE unreachable pattern + //~| NOTE these patterns collectively make the last one unreachable + //~| NOTE collectively making this unreachable _ => {} } @@ -69,6 +71,8 @@ fn main() { (_, true) => {} //~^ ERROR unreachable pattern //~| NOTE unreachable pattern + //~| NOTE these patterns collectively make the last one unreachable + //~| NOTE collectively making this unreachable } match (true, true) { diff --git a/tests/ui/pattern/usefulness/explain-unreachable-pats.stderr b/tests/ui/pattern/usefulness/explain-unreachable-pats.stderr index 7c2382c26b835..e2eecf4a9f386 100644 --- a/tests/ui/pattern/usefulness/explain-unreachable-pats.stderr +++ b/tests/ui/pattern/usefulness/explain-unreachable-pats.stderr @@ -16,6 +16,12 @@ LL | #![deny(unreachable_patterns)] error: unreachable pattern --> $DIR/explain-unreachable-pats.rs:22:9 | +LL | (1 | 2,) => {} + | ^^^^^^^^ unreachable pattern + | +note: these patterns collectively make the last one unreachable + --> $DIR/explain-unreachable-pats.rs:22:9 + | LL | (1,) => {} | ---- matches some of the same values LL | @@ -23,10 +29,10 @@ LL | (2,) => {} | ---- matches some of the same values LL | LL | (1 | 2,) => {} - | ^^^^^^^^ unreachable pattern + | ^^^^^^^^ collectively making this unreachable error: unreachable pattern - --> $DIR/explain-unreachable-pats.rs:31:9 + --> $DIR/explain-unreachable-pats.rs:33:9 | LL | Err(_) => {} | ^^^^^^ @@ -34,7 +40,7 @@ LL | Err(_) => {} = note: this pattern matches no values because `!` is uninhabited error: unreachable pattern - --> $DIR/explain-unreachable-pats.rs:44:9 + --> $DIR/explain-unreachable-pats.rs:46:9 | LL | (Err(_), Err(_)) => {} | ^^^^^^^^^^^^^^^^ @@ -42,7 +48,7 @@ LL | (Err(_), Err(_)) => {} = note: this pattern matches no values because `Void2` is uninhabited error: unreachable pattern - --> $DIR/explain-unreachable-pats.rs:50:9 + --> $DIR/explain-unreachable-pats.rs:52:9 | LL | (Err(_), Err(_)) => {} | ^^^^^^^^^^^^^^^^ @@ -50,7 +56,7 @@ LL | (Err(_), Err(_)) => {} = note: this pattern matches no values because `Void1` is uninhabited error: unreachable pattern - --> $DIR/explain-unreachable-pats.rs:59:11 + --> $DIR/explain-unreachable-pats.rs:61:11 | LL | if let (0 | - matches all the values already @@ -59,7 +65,13 @@ LL | | 0, _) = (0, 0) {} | ^ unreachable pattern error: unreachable pattern - --> $DIR/explain-unreachable-pats.rs:69:9 + --> $DIR/explain-unreachable-pats.rs:71:9 + | +LL | (_, true) => {} + | ^^^^^^^^^ unreachable pattern + | +note: these patterns collectively make the last one unreachable + --> $DIR/explain-unreachable-pats.rs:71:9 | LL | (true, _) => {} | --------- matches some of the same values @@ -68,10 +80,10 @@ LL | (false, _) => {} | ---------- matches some of the same values LL | LL | (_, true) => {} - | ^^^^^^^^^ unreachable pattern + | ^^^^^^^^^ collectively making this unreachable error: unreachable pattern - --> $DIR/explain-unreachable-pats.rs:80:9 + --> $DIR/explain-unreachable-pats.rs:84:9 | LL | (true, _) => {} | --------- matches all the values already @@ -80,7 +92,7 @@ LL | (true, true) => {} | ^^^^^^^^^^^^ unreachable pattern error: unreachable pattern - --> $DIR/explain-unreachable-pats.rs:92:9 + --> $DIR/explain-unreachable-pats.rs:96:9 | LL | (_, true, 0..10) => {} | ---------------- matches all the values already diff --git a/tests/ui/pattern/usefulness/integer-ranges/reachability.stderr b/tests/ui/pattern/usefulness/integer-ranges/reachability.stderr index 8cf8182265996..5d86007a853ec 100644 --- a/tests/ui/pattern/usefulness/integer-ranges/reachability.stderr +++ b/tests/ui/pattern/usefulness/integer-ranges/reachability.stderr @@ -135,6 +135,12 @@ LL | m!('a', 'A'..='z', 'a'..='z'); error: unreachable pattern --> $DIR/reachability.rs:50:9 | +LL | 5..=8 => {}, + | ^^^^^ unreachable pattern + | +note: these patterns collectively make the last one unreachable + --> $DIR/reachability.rs:50:9 + | LL | 5 => {}, | - matches some of the same values LL | 6 => {}, @@ -144,21 +150,33 @@ LL | 7 => {}, LL | 8 => {}, | - matches some of the same values LL | 5..=8 => {}, - | ^^^^^ unreachable pattern + | ^^^^^ collectively making this unreachable error: unreachable pattern --> $DIR/reachability.rs:56:9 | +LL | 5..15 => {}, + | ^^^^^ unreachable pattern + | +note: these patterns collectively make the last one unreachable + --> $DIR/reachability.rs:56:9 + | LL | 0..10 => {}, | ----- matches some of the same values LL | 10..20 => {}, | ------ matches some of the same values LL | 5..15 => {}, - | ^^^^^ unreachable pattern + | ^^^^^ collectively making this unreachable error: unreachable pattern --> $DIR/reachability.rs:63:9 | +LL | 5..25 => {}, + | ^^^^^ unreachable pattern + | +note: these patterns collectively make the last one unreachable + --> $DIR/reachability.rs:63:9 + | LL | 0..10 => {}, | ----- matches some of the same values LL | 10..20 => {}, @@ -166,11 +184,17 @@ LL | 10..20 => {}, LL | 20..30 => {}, | ------ matches some of the same values LL | 5..25 => {}, - | ^^^^^ unreachable pattern + | ^^^^^ collectively making this unreachable error: unreachable pattern --> $DIR/reachability.rs:71:9 | +LL | 5..25 => {}, + | ^^^^^ unreachable pattern + | +note: these patterns collectively make the last one unreachable + --> $DIR/reachability.rs:71:9 + | LL | 0..10 => {}, | ----- matches some of the same values LL | 10 => {}, @@ -180,17 +204,23 @@ LL | 11..=23 => {}, LL | 19..30 => {}, | ------ matches some of the same values LL | 5..25 => {}, - | ^^^^^ unreachable pattern + | ^^^^^ collectively making this unreachable error: unreachable pattern --> $DIR/reachability.rs:77:9 | +LL | 5..15 => {}, + | ^^^^^ unreachable pattern + | +note: these patterns collectively make the last one unreachable + --> $DIR/reachability.rs:77:9 + | LL | 0..10 => {}, | ----- matches some of the same values LL | 10..20 => {}, | ------ matches some of the same values LL | 5..15 => {}, - | ^^^^^ unreachable pattern + | ^^^^^ collectively making this unreachable error: unreachable pattern --> $DIR/reachability.rs:84:9 @@ -203,12 +233,18 @@ LL | '\u{D7FF}'..='\u{E000}' => {}, error: unreachable pattern --> $DIR/reachability.rs:89:9 | +LL | '\u{D7FF}'..='\u{E000}' => {}, + | ^^^^^^^^^^^^^^^^^^^^^^^ unreachable pattern + | +note: these patterns collectively make the last one unreachable + --> $DIR/reachability.rs:89:9 + | LL | '\u{0}'..='\u{D7FF}' => {}, | -------------------- matches some of the same values LL | '\u{E000}'..='\u{10_FFFF}' => {}, | -------------------------- matches some of the same values LL | '\u{D7FF}'..='\u{E000}' => {}, - | ^^^^^^^^^^^^^^^^^^^^^^^ unreachable pattern + | ^^^^^^^^^^^^^^^^^^^^^^^ collectively making this unreachable error: unreachable pattern --> $DIR/reachability.rs:105:9 diff --git a/tests/ui/pattern/usefulness/issue-12369.stderr b/tests/ui/pattern/usefulness/issue-12369.stderr index dbd6bab6aeb85..7754cbc24843f 100644 --- a/tests/ui/pattern/usefulness/issue-12369.stderr +++ b/tests/ui/pattern/usefulness/issue-12369.stderr @@ -1,13 +1,18 @@ error: unreachable pattern --> $DIR/issue-12369.rs:9:9 | +LL | &[10,a, ref rest @ ..] => 10 + | ^^^^^^^^^^^^^^^^^^^^^^ unreachable pattern + | +note: these patterns collectively make the last one unreachable + --> $DIR/issue-12369.rs:9:9 + | LL | &[a,b,c] => 3, | -------- matches some of the same values LL | &[a, ref rest @ ..] => a, | ------------------- matches some of the same values LL | &[10,a, ref rest @ ..] => 10 - | ^^^^^^^^^^^^^^^^^^^^^^ unreachable pattern - | + | ^^^^^^^^^^^^^^^^^^^^^^ collectively making this unreachable note: the lint level is defined here --> $DIR/issue-12369.rs:1:9 | diff --git a/tests/ui/pattern/usefulness/issue-31221.stderr b/tests/ui/pattern/usefulness/issue-31221.stderr index f564422faae3f..596f4d8096d9a 100644 --- a/tests/ui/pattern/usefulness/issue-31221.stderr +++ b/tests/ui/pattern/usefulness/issue-31221.stderr @@ -23,12 +23,18 @@ LL | &Var2 => (), error: unreachable pattern --> $DIR/issue-31221.rs:31:9 | +LL | anything => () + | ^^^^^^^^ unreachable pattern + | +note: these patterns collectively make the last one unreachable + --> $DIR/issue-31221.rs:31:9 + | LL | (Var1, b) => (), | --------- matches some of the same values LL | (c, d) => (), | ------ matches some of the same values LL | anything => () - | ^^^^^^^^ unreachable pattern + | ^^^^^^^^ collectively making this unreachable error: aborting due to 3 previous errors diff --git a/tests/ui/pattern/usefulness/match-arm-statics.stderr b/tests/ui/pattern/usefulness/match-arm-statics.stderr index 37f1ac58a1603..b6f2b47047dce 100644 --- a/tests/ui/pattern/usefulness/match-arm-statics.stderr +++ b/tests/ui/pattern/usefulness/match-arm-statics.stderr @@ -25,6 +25,12 @@ LL | Some(Some(East)) => (), error: unreachable pattern --> $DIR/match-arm-statics.rs:60:9 | +LL | Foo { bar: Some(EAST), baz: NewBool(false) } => () + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unreachable pattern + | +note: these patterns collectively make the last one unreachable + --> $DIR/match-arm-statics.rs:60:9 + | LL | Foo { bar: _, baz: NEW_FALSE } => (), | ------------------------------ matches some of the same values ... @@ -32,7 +38,7 @@ LL | Foo { bar: Some(EAST), .. } => (), | --------------------------- matches some of the same values LL | Foo { bar: Some(North), baz: NewBool(true) } => (), LL | Foo { bar: Some(EAST), baz: NewBool(false) } => () - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unreachable pattern + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ collectively making this unreachable error: aborting due to 3 previous errors diff --git a/tests/ui/pattern/usefulness/top-level-alternation.stderr b/tests/ui/pattern/usefulness/top-level-alternation.stderr index 0e7e7d4969dcd..ad846f2315597 100644 --- a/tests/ui/pattern/usefulness/top-level-alternation.stderr +++ b/tests/ui/pattern/usefulness/top-level-alternation.stderr @@ -72,12 +72,18 @@ LL | None => {} error: unreachable pattern --> $DIR/top-level-alternation.rs:49:9 | +LL | None | Some(_) => {} + | ^^^^^^^^^^^^^^ unreachable pattern + | +note: these patterns collectively make the last one unreachable + --> $DIR/top-level-alternation.rs:49:9 + | LL | Some(_) => {} | ------- matches some of the same values LL | None => {} | ---- matches some of the same values LL | None | Some(_) => {} - | ^^^^^^^^^^^^^^ unreachable pattern + | ^^^^^^^^^^^^^^ collectively making this unreachable error: unreachable pattern --> $DIR/top-level-alternation.rs:53:9