diff options
11 files changed, 26 insertions, 89 deletions
diff --git a/compiler/rustc_error_messages/locales/en-US/mir_build.ftl b/compiler/rustc_error_messages/locales/en-US/mir_build.ftl index b277942cdcc..976614ecd9e 100644 --- a/compiler/rustc_error_messages/locales/en-US/mir_build.ftl +++ b/compiler/rustc_error_messages/locales/en-US/mir_build.ftl @@ -358,7 +358,7 @@ mir_build_suggest_if_let = you might want to use `if let` to ignore the {$count *[other] variants that aren't } matched -mir_build_suggest_let_else = alternatively, you might want to use `let else` to handle the {$count -> +mir_build_suggest_let_else = you might want to use `let else` to handle the {$count -> [one] variant that isn't *[other] variants that aren't } matched diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index a3c58c31654..1b2fbae2cd5 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -747,9 +747,7 @@ pub(crate) struct PatternNotCovered<'s, 'tcx> { pub _p: (), pub pattern_ty: Ty<'tcx>, #[subdiagnostic] - pub if_let_suggestion: Option<SuggestIfLet>, - #[subdiagnostic] - pub let_else_suggestion: Option<SuggestLetElse>, + pub let_suggestion: Option<SuggestLet>, #[subdiagnostic] pub res_defined_here: Option<ResDefinedHere>, } @@ -809,43 +807,23 @@ pub struct InterpretedAsConst { } #[derive(Subdiagnostic)] -pub enum SuggestIfLet { +pub enum SuggestLet { #[multipart_suggestion(mir_build_suggest_if_let, applicability = "has-placeholders")] - None { + If { #[suggestion_part(code = "if ")] start_span: Span, #[suggestion_part(code = " {{ todo!() }}")] semi_span: Span, count: usize, }, - #[multipart_suggestion(mir_build_suggest_if_let, applicability = "has-placeholders")] - One { - #[suggestion_part(code = "let {binding} = if ")] - start_span: Span, - #[suggestion_part(code = " {{ {binding} }} else {{ todo!() }}")] - end_span: Span, - binding: Ident, - count: usize, - }, - #[multipart_suggestion(mir_build_suggest_if_let, applicability = "has-placeholders")] - More { - #[suggestion_part(code = "let ({bindings}) = if ")] - start_span: Span, - #[suggestion_part(code = " {{ ({bindings}) }} else {{ todo!() }}")] + #[suggestion( + mir_build_suggest_let_else, + code = " else {{ todo!() }}", + applicability = "has-placeholders" + )] + Else { + #[primary_span] end_span: Span, - bindings: String, count: usize, }, } - -#[derive(Subdiagnostic)] -#[suggestion( - mir_build_suggest_let_else, - code = " else {{ todo!() }}", - applicability = "has-placeholders" -)] -pub struct SuggestLetElse { - #[primary_span] - pub end_span: Span, - pub count: usize, -} 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 422c2ff3ede..69481592895 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -394,7 +394,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> { return; } - let (inform, interpreted_as_const, res_defined_here, if_let_suggestion, let_else_suggestion) = + let (inform, interpreted_as_const, res_defined_here,let_suggestion) = if let hir::PatKind::Path(hir::QPath::Resolved( None, hir::Path { @@ -417,7 +417,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> { res, } }, - None, None, + None, ) } else if let Some(span) = sp && self.tcx.sess.source_map().is_span_accessible(span) { let mut bindings = vec![]; @@ -430,19 +430,11 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> { let start_span = span.shrink_to_lo(); let end_span = semi_span.shrink_to_lo(); let count = witnesses.len(); - let if_let = match *bindings { - [] => SuggestIfLet::None{start_span, semi_span, count}, - [binding] => SuggestIfLet::One{start_span, end_span, count, binding }, - _ => SuggestIfLet::More{start_span, end_span, count, bindings: bindings - .iter() - .map(|ident| ident.to_string()) - .collect::<Vec<_>>() - .join(", ")}, - }; - let let_else = if bindings.is_empty() {None} else{Some( SuggestLetElse{end_span, count })}; - (sp.map(|_|Inform), None, None, Some(if_let), let_else) + + let let_suggestion = if bindings.is_empty() {SuggestLet::If{start_span, semi_span, count}} else{ SuggestLet::Else{end_span, count }}; + (sp.map(|_|Inform), None, None, Some(let_suggestion)) } else{ - (sp.map(|_|Inform), None, None, None, None) + (sp.map(|_|Inform), None, None, None) }; let adt_defined_here = try { @@ -465,8 +457,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> { interpreted_as_const, _p: (), pattern_ty, - if_let_suggestion, - let_else_suggestion, + let_suggestion, res_defined_here, adt_defined_here, }); diff --git a/tests/ui/empty/empty-never-array.stderr b/tests/ui/empty/empty-never-array.stderr index 9385382f860..a488e484b2b 100644 --- a/tests/ui/empty/empty-never-array.stderr +++ b/tests/ui/empty/empty-never-array.stderr @@ -14,11 +14,7 @@ LL | enum Helper<T, U> { LL | T(T, [!; 0]), | - not covered = note: the matched value is of type `Helper<T, U>` -help: you might want to use `if let` to ignore the variant that isn't matched - | -LL | let u = if let Helper::U(u) = Helper::T(t, []) { u } else { todo!() }; - | ++++++++++ ++++++++++++++++++++++ -help: alternatively, you might want to use `let else` to handle the variant that isn't matched +help: you might want to use `let else` to handle the variant that isn't matched | LL | let Helper::U(u) = Helper::T(t, []) else { todo!() }; | ++++++++++++++++ diff --git a/tests/ui/error-codes/E0005.stderr b/tests/ui/error-codes/E0005.stderr index 3c27a7d4c06..4692b66413d 100644 --- a/tests/ui/error-codes/E0005.stderr +++ b/tests/ui/error-codes/E0005.stderr @@ -7,11 +7,7 @@ LL | let Some(y) = x; = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html = note: the matched value is of type `Option<i32>` -help: you might want to use `if let` to ignore the variant that isn't matched - | -LL | let y = if let Some(y) = x { y } else { todo!() }; - | ++++++++++ ++++++++++++++++++++++ -help: alternatively, you might want to use `let else` to handle the variant that isn't matched +help: you might want to use `let else` to handle the variant that isn't matched | LL | let Some(y) = x else { todo!() }; | ++++++++++++++++ diff --git a/tests/ui/feature-gates/feature-gate-exhaustive-patterns.stderr b/tests/ui/feature-gates/feature-gate-exhaustive-patterns.stderr index 5e4df7422fc..49e7ab6082c 100644 --- a/tests/ui/feature-gates/feature-gate-exhaustive-patterns.stderr +++ b/tests/ui/feature-gates/feature-gate-exhaustive-patterns.stderr @@ -7,11 +7,7 @@ LL | let Ok(_x) = foo(); = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html = note: the matched value is of type `Result<u32, !>` -help: you might want to use `if let` to ignore the variant that isn't matched - | -LL | let _x = if let Ok(_x) = foo() { _x } else { todo!() }; - | +++++++++++ +++++++++++++++++++++++ -help: alternatively, you might want to use `let else` to handle the variant that isn't matched +help: you might want to use `let else` to handle the variant that isn't matched | LL | let Ok(_x) = foo() else { todo!() }; | ++++++++++++++++ diff --git a/tests/ui/pattern/usefulness/issue-31561.stderr b/tests/ui/pattern/usefulness/issue-31561.stderr index 202fe9de5d3..5367de5e513 100644 --- a/tests/ui/pattern/usefulness/issue-31561.stderr +++ b/tests/ui/pattern/usefulness/issue-31561.stderr @@ -17,11 +17,7 @@ LL | Bar, LL | Baz | --- not covered = note: the matched value is of type `Thing` -help: you might want to use `if let` to ignore the variants that aren't matched - | -LL | let y = if let Thing::Foo(y) = Thing::Foo(1) { y } else { todo!() }; - | ++++++++++ ++++++++++++++++++++++ -help: alternatively, you might want to use `let else` to handle the variants that aren't matched +help: you might want to use `let else` to handle the variants that aren't matched | LL | let Thing::Foo(y) = Thing::Foo(1) else { todo!() }; | ++++++++++++++++ diff --git a/tests/ui/pattern/usefulness/non-exhaustive-defined-here.stderr b/tests/ui/pattern/usefulness/non-exhaustive-defined-here.stderr index 3e375066f1b..769d4070fb5 100644 --- a/tests/ui/pattern/usefulness/non-exhaustive-defined-here.stderr +++ b/tests/ui/pattern/usefulness/non-exhaustive-defined-here.stderr @@ -183,11 +183,7 @@ LL | enum Opt { LL | None, | ---- not covered = note: the matched value is of type `Opt` -help: you might want to use `if let` to ignore the variant that isn't matched - | -LL | let _x = if let Opt::Some(ref _x) = e { _x } else { todo!() }; - | +++++++++++ +++++++++++++++++++++++ -help: alternatively, you might want to use `let else` to handle the variant that isn't matched +help: you might want to use `let else` to handle the variant that isn't matched | LL | let Opt::Some(ref _x) = e else { todo!() }; | ++++++++++++++++ diff --git a/tests/ui/recursion/recursive-types-are-not-uninhabited.stderr b/tests/ui/recursion/recursive-types-are-not-uninhabited.stderr index b7521df88ec..1b4d80d9057 100644 --- a/tests/ui/recursion/recursive-types-are-not-uninhabited.stderr +++ b/tests/ui/recursion/recursive-types-are-not-uninhabited.stderr @@ -7,11 +7,7 @@ LL | let Ok(x) = res; = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html = note: the matched value is of type `Result<u32, &R<'_>>` -help: you might want to use `if let` to ignore the variant that isn't matched - | -LL | let x = if let Ok(x) = res { x } else { todo!() }; - | ++++++++++ ++++++++++++++++++++++ -help: alternatively, you might want to use `let else` to handle the variant that isn't matched +help: you might want to use `let else` to handle the variant that isn't matched | LL | let Ok(x) = res else { todo!() }; | ++++++++++++++++ diff --git a/tests/ui/uninhabited/uninhabited-irrefutable.stderr b/tests/ui/uninhabited/uninhabited-irrefutable.stderr index 461863e1127..8cafea555c1 100644 --- a/tests/ui/uninhabited/uninhabited-irrefutable.stderr +++ b/tests/ui/uninhabited/uninhabited-irrefutable.stderr @@ -14,11 +14,7 @@ LL | enum Foo { LL | A(foo::SecretlyEmpty), | - not covered = note: the matched value is of type `Foo` -help: you might want to use `if let` to ignore the variant that isn't matched - | -LL | let (_y, _z) = if let Foo::D(_y, _z) = x { (_y, _z) } else { todo!() }; - | +++++++++++++++++ +++++++++++++++++++++++++++++ -help: alternatively, you might want to use `let else` to handle the variant that isn't matched +help: you might want to use `let else` to handle the variant that isn't matched | LL | let Foo::D(_y, _z) = x else { todo!() }; | ++++++++++++++++ diff --git a/tests/ui/uninhabited/uninhabited-matches-feature-gated.stderr b/tests/ui/uninhabited/uninhabited-matches-feature-gated.stderr index 2c67eac51f5..466d7f2eadb 100644 --- a/tests/ui/uninhabited/uninhabited-matches-feature-gated.stderr +++ b/tests/ui/uninhabited/uninhabited-matches-feature-gated.stderr @@ -104,11 +104,7 @@ LL | let Ok(x) = x; = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html = note: the matched value is of type `Result<u32, Void>` -help: you might want to use `if let` to ignore the variant that isn't matched - | -LL | let x = if let Ok(x) = x { x } else { todo!() }; - | ++++++++++ ++++++++++++++++++++++ -help: alternatively, you might want to use `let else` to handle the variant that isn't matched +help: you might want to use `let else` to handle the variant that isn't matched | LL | let Ok(x) = x else { todo!() }; | ++++++++++++++++ |
