Skip to content

Commit 8476c51

Browse files
mejrsdtolnay
mejrs
authored andcommitted
Don't recommend if let if let else works
1 parent 31c2021 commit 8476c51

File tree

11 files changed

+26
-89
lines changed

11 files changed

+26
-89
lines changed

compiler/rustc_error_messages/locales/en-US/mir_build.ftl

+1-1
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ mir_build_suggest_if_let = you might want to use `if let` to ignore the {$count
358358
*[other] variants that aren't
359359
} matched
360360
361-
mir_build_suggest_let_else = alternatively, you might want to use `let else` to handle the {$count ->
361+
mir_build_suggest_let_else = you might want to use `let else` to handle the {$count ->
362362
[one] variant that isn't
363363
*[other] variants that aren't
364364
} matched

compiler/rustc_mir_build/src/errors.rs

+10-32
Original file line numberDiff line numberDiff line change
@@ -747,9 +747,7 @@ pub(crate) struct PatternNotCovered<'s, 'tcx> {
747747
pub _p: (),
748748
pub pattern_ty: Ty<'tcx>,
749749
#[subdiagnostic]
750-
pub if_let_suggestion: Option<SuggestIfLet>,
751-
#[subdiagnostic]
752-
pub let_else_suggestion: Option<SuggestLetElse>,
750+
pub let_suggestion: Option<SuggestLet>,
753751
#[subdiagnostic]
754752
pub res_defined_here: Option<ResDefinedHere>,
755753
}
@@ -809,43 +807,23 @@ pub struct InterpretedAsConst {
809807
}
810808

811809
#[derive(Subdiagnostic)]
812-
pub enum SuggestIfLet {
810+
pub enum SuggestLet {
813811
#[multipart_suggestion(mir_build_suggest_if_let, applicability = "has-placeholders")]
814-
None {
812+
If {
815813
#[suggestion_part(code = "if ")]
816814
start_span: Span,
817815
#[suggestion_part(code = " {{ todo!() }}")]
818816
semi_span: Span,
819817
count: usize,
820818
},
821-
#[multipart_suggestion(mir_build_suggest_if_let, applicability = "has-placeholders")]
822-
One {
823-
#[suggestion_part(code = "let {binding} = if ")]
824-
start_span: Span,
825-
#[suggestion_part(code = " {{ {binding} }} else {{ todo!() }}")]
826-
end_span: Span,
827-
binding: Ident,
828-
count: usize,
829-
},
830-
#[multipart_suggestion(mir_build_suggest_if_let, applicability = "has-placeholders")]
831-
More {
832-
#[suggestion_part(code = "let ({bindings}) = if ")]
833-
start_span: Span,
834-
#[suggestion_part(code = " {{ ({bindings}) }} else {{ todo!() }}")]
819+
#[suggestion(
820+
mir_build_suggest_let_else,
821+
code = " else {{ todo!() }}",
822+
applicability = "has-placeholders"
823+
)]
824+
Else {
825+
#[primary_span]
835826
end_span: Span,
836-
bindings: String,
837827
count: usize,
838828
},
839829
}
840-
841-
#[derive(Subdiagnostic)]
842-
#[suggestion(
843-
mir_build_suggest_let_else,
844-
code = " else {{ todo!() }}",
845-
applicability = "has-placeholders"
846-
)]
847-
pub struct SuggestLetElse {
848-
#[primary_span]
849-
pub end_span: Span,
850-
pub count: usize,
851-
}

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

+7-16
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
394394
return;
395395
}
396396

397-
let (inform, interpreted_as_const, res_defined_here, if_let_suggestion, let_else_suggestion) =
397+
let (inform, interpreted_as_const, res_defined_here,let_suggestion) =
398398
if let hir::PatKind::Path(hir::QPath::Resolved(
399399
None,
400400
hir::Path {
@@ -417,7 +417,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
417417
res,
418418
}
419419
},
420-
None, None,
420+
None,
421421
)
422422
} else if let Some(span) = sp && self.tcx.sess.source_map().is_span_accessible(span) {
423423
let mut bindings = vec![];
@@ -430,19 +430,11 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
430430
let start_span = span.shrink_to_lo();
431431
let end_span = semi_span.shrink_to_lo();
432432
let count = witnesses.len();
433-
let if_let = match *bindings {
434-
[] => SuggestIfLet::None{start_span, semi_span, count},
435-
[binding] => SuggestIfLet::One{start_span, end_span, count, binding },
436-
_ => SuggestIfLet::More{start_span, end_span, count, bindings: bindings
437-
.iter()
438-
.map(|ident| ident.to_string())
439-
.collect::<Vec<_>>()
440-
.join(", ")},
441-
};
442-
let let_else = if bindings.is_empty() {None} else{Some( SuggestLetElse{end_span, count })};
443-
(sp.map(|_|Inform), None, None, Some(if_let), let_else)
433+
434+
let let_suggestion = if bindings.is_empty() {SuggestLet::If{start_span, semi_span, count}} else{ SuggestLet::Else{end_span, count }};
435+
(sp.map(|_|Inform), None, None, Some(let_suggestion))
444436
} else{
445-
(sp.map(|_|Inform), None, None, None, None)
437+
(sp.map(|_|Inform), None, None, None)
446438
};
447439

448440
let adt_defined_here = try {
@@ -465,8 +457,7 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
465457
interpreted_as_const,
466458
_p: (),
467459
pattern_ty,
468-
if_let_suggestion,
469-
let_else_suggestion,
460+
let_suggestion,
470461
res_defined_here,
471462
adt_defined_here,
472463
});

tests/ui/empty/empty-never-array.stderr

+1-5
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,7 @@ LL | enum Helper<T, U> {
1414
LL | T(T, [!; 0]),
1515
| - not covered
1616
= note: the matched value is of type `Helper<T, U>`
17-
help: you might want to use `if let` to ignore the variant that isn't matched
18-
|
19-
LL | let u = if let Helper::U(u) = Helper::T(t, []) { u } else { todo!() };
20-
| ++++++++++ ++++++++++++++++++++++
21-
help: alternatively, you might want to use `let else` to handle the variant that isn't matched
17+
help: you might want to use `let else` to handle the variant that isn't matched
2218
|
2319
LL | let Helper::U(u) = Helper::T(t, []) else { todo!() };
2420
| ++++++++++++++++

tests/ui/error-codes/E0005.stderr

+1-5
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,7 @@ LL | let Some(y) = x;
77
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
88
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
99
= note: the matched value is of type `Option<i32>`
10-
help: you might want to use `if let` to ignore the variant that isn't matched
11-
|
12-
LL | let y = if let Some(y) = x { y } else { todo!() };
13-
| ++++++++++ ++++++++++++++++++++++
14-
help: alternatively, you might want to use `let else` to handle the variant that isn't matched
10+
help: you might want to use `let else` to handle the variant that isn't matched
1511
|
1612
LL | let Some(y) = x else { todo!() };
1713
| ++++++++++++++++

tests/ui/feature-gates/feature-gate-exhaustive-patterns.stderr

+1-5
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,7 @@ LL | let Ok(_x) = foo();
77
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
88
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
99
= note: the matched value is of type `Result<u32, !>`
10-
help: you might want to use `if let` to ignore the variant that isn't matched
11-
|
12-
LL | let _x = if let Ok(_x) = foo() { _x } else { todo!() };
13-
| +++++++++++ +++++++++++++++++++++++
14-
help: alternatively, you might want to use `let else` to handle the variant that isn't matched
10+
help: you might want to use `let else` to handle the variant that isn't matched
1511
|
1612
LL | let Ok(_x) = foo() else { todo!() };
1713
| ++++++++++++++++

tests/ui/pattern/usefulness/issue-31561.stderr

+1-5
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,7 @@ LL | Bar,
1717
LL | Baz
1818
| --- not covered
1919
= note: the matched value is of type `Thing`
20-
help: you might want to use `if let` to ignore the variants that aren't matched
21-
|
22-
LL | let y = if let Thing::Foo(y) = Thing::Foo(1) { y } else { todo!() };
23-
| ++++++++++ ++++++++++++++++++++++
24-
help: alternatively, you might want to use `let else` to handle the variants that aren't matched
20+
help: you might want to use `let else` to handle the variants that aren't matched
2521
|
2622
LL | let Thing::Foo(y) = Thing::Foo(1) else { todo!() };
2723
| ++++++++++++++++

tests/ui/pattern/usefulness/non-exhaustive-defined-here.stderr

+1-5
Original file line numberDiff line numberDiff line change
@@ -183,11 +183,7 @@ LL | enum Opt {
183183
LL | None,
184184
| ---- not covered
185185
= note: the matched value is of type `Opt`
186-
help: you might want to use `if let` to ignore the variant that isn't matched
187-
|
188-
LL | let _x = if let Opt::Some(ref _x) = e { _x } else { todo!() };
189-
| +++++++++++ +++++++++++++++++++++++
190-
help: alternatively, you might want to use `let else` to handle the variant that isn't matched
186+
help: you might want to use `let else` to handle the variant that isn't matched
191187
|
192188
LL | let Opt::Some(ref _x) = e else { todo!() };
193189
| ++++++++++++++++

tests/ui/recursion/recursive-types-are-not-uninhabited.stderr

+1-5
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,7 @@ LL | let Ok(x) = res;
77
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
88
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
99
= note: the matched value is of type `Result<u32, &R<'_>>`
10-
help: you might want to use `if let` to ignore the variant that isn't matched
11-
|
12-
LL | let x = if let Ok(x) = res { x } else { todo!() };
13-
| ++++++++++ ++++++++++++++++++++++
14-
help: alternatively, you might want to use `let else` to handle the variant that isn't matched
10+
help: you might want to use `let else` to handle the variant that isn't matched
1511
|
1612
LL | let Ok(x) = res else { todo!() };
1713
| ++++++++++++++++

tests/ui/uninhabited/uninhabited-irrefutable.stderr

+1-5
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,7 @@ LL | enum Foo {
1414
LL | A(foo::SecretlyEmpty),
1515
| - not covered
1616
= note: the matched value is of type `Foo`
17-
help: you might want to use `if let` to ignore the variant that isn't matched
18-
|
19-
LL | let (_y, _z) = if let Foo::D(_y, _z) = x { (_y, _z) } else { todo!() };
20-
| +++++++++++++++++ +++++++++++++++++++++++++++++
21-
help: alternatively, you might want to use `let else` to handle the variant that isn't matched
17+
help: you might want to use `let else` to handle the variant that isn't matched
2218
|
2319
LL | let Foo::D(_y, _z) = x else { todo!() };
2420
| ++++++++++++++++

tests/ui/uninhabited/uninhabited-matches-feature-gated.stderr

+1-5
Original file line numberDiff line numberDiff line change
@@ -104,11 +104,7 @@ LL | let Ok(x) = x;
104104
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
105105
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
106106
= note: the matched value is of type `Result<u32, Void>`
107-
help: you might want to use `if let` to ignore the variant that isn't matched
108-
|
109-
LL | let x = if let Ok(x) = x { x } else { todo!() };
110-
| ++++++++++ ++++++++++++++++++++++
111-
help: alternatively, you might want to use `let else` to handle the variant that isn't matched
107+
help: you might want to use `let else` to handle the variant that isn't matched
112108
|
113109
LL | let Ok(x) = x else { todo!() };
114110
| ++++++++++++++++

0 commit comments

Comments
 (0)