Rollup merge of #104186 - chenyukang:yukang/fix-104086-let-binding-issue, r=oli-obk

Tighten the 'introduce new binding' suggestion

Fixes #104086
This commit is contained in:
Manish Goregaokar 2022-11-10 10:47:40 -05:00 committed by GitHub
commit 819c9315c3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 182 additions and 18 deletions

View file

@ -527,6 +527,7 @@ struct DiagnosticMetadata<'ast> {
/// Used to detect possible new binding written without `let` and to provide structured suggestion.
in_assignment: Option<&'ast Expr>,
is_assign_rhs: bool,
/// If we are currently in a trait object definition. Used to point at the bounds when
/// encountering a struct or enum.
@ -3963,10 +3964,15 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
self.resolve_expr(elem, Some(expr));
self.visit_expr(idx);
}
ExprKind::Assign(..) => {
let old = self.diagnostic_metadata.in_assignment.replace(expr);
visit::walk_expr(self, expr);
self.diagnostic_metadata.in_assignment = old;
ExprKind::Assign(ref lhs, ref rhs, _) => {
if !self.diagnostic_metadata.is_assign_rhs {
self.diagnostic_metadata.in_assignment = Some(expr);
}
self.visit_expr(lhs);
self.diagnostic_metadata.is_assign_rhs = true;
self.diagnostic_metadata.in_assignment = None;
self.visit_expr(rhs);
self.diagnostic_metadata.is_assign_rhs = false;
}
_ => {
visit::walk_expr(self, expr);

View file

@ -1810,29 +1810,22 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
false
}
fn let_binding_suggestion(&self, err: &mut Diagnostic, ident_span: Span) -> bool {
// try to give a suggestion for this pattern: `name = 1`, which is common in other languages
let mut added_suggestion = false;
if let Some(Expr { kind: ExprKind::Assign(lhs, _rhs, _), .. }) = self.diagnostic_metadata.in_assignment &&
// try to give a suggestion for this pattern: `name = blah`, which is common in other languages
// suggest `let name = blah` to introduce a new binding
fn let_binding_suggestion(&mut self, err: &mut Diagnostic, ident_span: Span) -> bool {
if let Some(Expr { kind: ExprKind::Assign(lhs, .. ), .. }) = self.diagnostic_metadata.in_assignment &&
let ast::ExprKind::Path(None, _) = lhs.kind {
let sm = self.r.session.source_map();
let line_span = sm.span_extend_to_line(ident_span);
let ident_name = sm.span_to_snippet(ident_span).unwrap();
// HACK(chenyukang): make sure ident_name is at the starting of the line to protect against macros
if sm
.span_to_snippet(line_span)
.map_or(false, |s| s.trim().starts_with(&ident_name))
{
if !ident_span.from_expansion() {
err.span_suggestion_verbose(
ident_span.shrink_to_lo(),
"you might have meant to introduce a new binding",
"let ".to_string(),
Applicability::MaybeIncorrect,
);
added_suggestion = true;
return true;
}
}
added_suggestion
false
}
fn find_module(&mut self, def_id: DefId) -> Option<(Module<'a>, ImportSuggestion)> {