Skip to content

Commit 6b5f379

Browse files
committed
rustc_parse: improve the error diagnostic for "missing let in let chain"
1 parent 7704328 commit 6b5f379

3 files changed

Lines changed: 50 additions & 1 deletion

File tree

compiler/rustc_parse/messages.ftl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,3 +1030,15 @@ parse_where_generics = generic parameters on `where` clauses are reserved for fu
10301030
10311031
parse_zero_chars = empty character literal
10321032
.label = {parse_zero_chars}
1033+
1034+
parse_let_chain_missing_let =
1035+
let-chain with missing `let`
1036+
1037+
parse_let_chain_start =
1038+
let-chain starting here
1039+
1040+
parse_expected_let_found_assign =
1041+
expected `let` expression, found assignment
1042+
1043+
parse_add_let =
1044+
add `let` before the expression

compiler/rustc_parse/src/errors.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3684,3 +3684,21 @@ pub(crate) struct ImplReuseInherentImpl {
36843684
#[primary_span]
36853685
pub span: Span,
36863686
}
3687+
3688+
#[derive(Diagnostic)]
3689+
#[diag(parse_let_chain_missing_let)]
3690+
pub(crate) struct LetChainWithMissingLet {
3691+
#[label(parse_let_chain_start)]
3692+
pub left_span: Span,
3693+
3694+
#[label(parse_expected_let_found_assign)]
3695+
pub right_span: Span,
3696+
3697+
#[suggestion(
3698+
parse_add_let,
3699+
style = "verbose",
3700+
applicability = "machine-applicable",
3701+
code = "let "
3702+
)]
3703+
pub let_span: Span,
3704+
}

compiler/rustc_parse/src/parser/expr.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4211,7 +4211,26 @@ impl MutVisitor for CondChecker<'_> {
42114211
}
42124212
}
42134213
}
4214-
ExprKind::Binary(Spanned { node: BinOpKind::And, .. }, _, _) => {
4214+
4215+
ExprKind::Binary(Spanned { node: BinOpKind::And, .. }, ref lhs, ref mut rhs) => {
4216+
if let ExprKind::Assign(assign_lhs, _, _) = &rhs.kind {
4217+
if let ExprKind::Call(callee, _) = &assign_lhs.kind
4218+
&& let ExprKind::Path(None, path) = &callee.kind
4219+
&& path.segments.len() == 1
4220+
&& path.segments[0].ident.name == sym::Some
4221+
{
4222+
let guar = self
4223+
.parser
4224+
.dcx()
4225+
.create_err(errors::LetChainWithMissingLet {
4226+
right_span: rhs.span,
4227+
left_span: lhs.span,
4228+
let_span: rhs.span.shrink_to_hi(),
4229+
})
4230+
.emit();
4231+
*rhs = self.parser.mk_expr_err(rhs.span, guar);
4232+
}
4233+
}
42154234
mut_visit::walk_expr(self, e);
42164235
}
42174236
ExprKind::Binary(Spanned { node: BinOpKind::Or, span: or_span }, _, _)

0 commit comments

Comments
 (0)