Suggest if let x = y
when encountering if x = y
Detect potential cases where `if let` was meant but `let` was left out. Fix #44990.
This commit is contained in:
parent
85fbf49ce0
commit
07112ca62d
11 changed files with 268 additions and 102 deletions
|
@ -378,6 +378,9 @@ struct DiagnosticMetadata<'ast> {
|
|||
|
||||
/// Only used for better errors on `let <pat>: <expr, not type>;`.
|
||||
current_let_binding: Option<(Span, Option<Span>, Option<Span>)>,
|
||||
|
||||
/// Used to detect possible `if let` written without `let` and to provide structured suggestion.
|
||||
in_if_condition: Option<&'ast Expr>,
|
||||
}
|
||||
|
||||
struct LateResolutionVisitor<'a, 'b, 'ast> {
|
||||
|
@ -403,7 +406,7 @@ struct LateResolutionVisitor<'a, 'b, 'ast> {
|
|||
///
|
||||
/// In particular, rustdoc uses this to avoid giving errors for `cfg()` items.
|
||||
/// In most cases this will be `None`, in which case errors will always be reported.
|
||||
/// If it is `Some(_)`, then it will be updated when entering a nested function or trait body.
|
||||
/// If it is `true`, then it will be updated when entering a nested function or trait body.
|
||||
in_func_body: bool,
|
||||
}
|
||||
|
||||
|
@ -2199,7 +2202,9 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
|||
|
||||
ExprKind::If(ref cond, ref then, ref opt_else) => {
|
||||
self.with_rib(ValueNS, NormalRibKind, |this| {
|
||||
let old = this.diagnostic_metadata.in_if_condition.replace(cond);
|
||||
this.visit_expr(cond);
|
||||
this.diagnostic_metadata.in_if_condition = old;
|
||||
this.visit_block(then);
|
||||
});
|
||||
if let Some(expr) = opt_else {
|
||||
|
|
|
@ -176,6 +176,19 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> {
|
|||
let code = source.error_code(res.is_some());
|
||||
let mut err = self.r.session.struct_span_err_with_code(base_span, &base_msg, code);
|
||||
|
||||
match (source, self.diagnostic_metadata.in_if_condition) {
|
||||
(PathSource::Expr(_), Some(Expr { span, kind: ExprKind::Assign(..), .. })) => {
|
||||
err.span_suggestion_verbose(
|
||||
span.shrink_to_lo(),
|
||||
"you might have meant to use pattern matching",
|
||||
"let ".to_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
self.r.session.if_let_suggestions.borrow_mut().insert(*span);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let is_assoc_fn = self.self_type_is_available(span);
|
||||
// Emit help message for fake-self from other languages (e.g., `this` in Javascript).
|
||||
if ["this", "my"].contains(&&*item_str.as_str()) && is_assoc_fn {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue