From c710db8ea7fb59ef90d854d2e1a5d9d93464b074 Mon Sep 17 00:00:00 2001 From: Young-Flash <871946895@qq.com> Date: Thu, 23 Nov 2023 20:22:17 +0800 Subject: [PATCH] feat: make let_binding_suggestion more reasonable --- .../rustc_resolve/src/late/diagnostics.rs | 15 +++++-- .../suggest-let-for-assignment.fixed | 6 +++ .../suggestions/suggest-let-for-assignment.rs | 6 +++ .../suggest-let-for-assignment.stderr | 42 +++++++++++++++++-- 4 files changed, 62 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index fd5d6fabf021d..d078cbefde93b 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1966,13 +1966,22 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { 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 ast::ExprKind::Path(None, ref path) = lhs.kind { if !ident_span.from_expansion() { + let (span, text) = match path.segments.first() { + Some(seg) if let Some(name) = seg.ident.as_str().strip_prefix("let") => { + // a special case for #117894 + let name = name.strip_prefix("_").unwrap_or(name); + (ident_span, format!("let {name}")) + } + _ => (ident_span.shrink_to_lo(), "let ".to_string()), + }; + err.span_suggestion_verbose( - ident_span.shrink_to_lo(), + span, "you might have meant to introduce a new binding", - "let ".to_string(), + text, Applicability::MaybeIncorrect, ); return true; diff --git a/tests/ui/suggestions/suggest-let-for-assignment.fixed b/tests/ui/suggestions/suggest-let-for-assignment.fixed index 3a25e25eede62..76dc1dad80a90 100644 --- a/tests/ui/suggestions/suggest-let-for-assignment.fixed +++ b/tests/ui/suggestions/suggest-let-for-assignment.fixed @@ -7,6 +7,12 @@ fn main() { let x = "x"; //~ ERROR cannot find value `x` in this scope println!("x: {}", x); //~ ERROR cannot find value `x` in this scope + let some_variable = 6; //~ cannot find value `let_some_variable` in this scope + println!("some_variable: {}", some_variable); //~ ERROR cannot find value `some_variable` in this scope + + let other_variable = 6; //~ cannot find value `letother_variable` in this scope + println!("other_variable: {}", other_variable); //~ ERROR cannot find value `other_variable` in this scope + if x == "x" { //~^ ERROR cannot find value `x` in this scope println!("x is 1"); diff --git a/tests/ui/suggestions/suggest-let-for-assignment.rs b/tests/ui/suggestions/suggest-let-for-assignment.rs index 67705fe063a79..f1edf65a72614 100644 --- a/tests/ui/suggestions/suggest-let-for-assignment.rs +++ b/tests/ui/suggestions/suggest-let-for-assignment.rs @@ -7,6 +7,12 @@ fn main() { x = "x"; //~ ERROR cannot find value `x` in this scope println!("x: {}", x); //~ ERROR cannot find value `x` in this scope + let_some_variable = 6; //~ cannot find value `let_some_variable` in this scope + println!("some_variable: {}", some_variable); //~ ERROR cannot find value `some_variable` in this scope + + letother_variable = 6; //~ cannot find value `letother_variable` in this scope + println!("other_variable: {}", other_variable); //~ ERROR cannot find value `other_variable` in this scope + if x == "x" { //~^ ERROR cannot find value `x` in this scope println!("x is 1"); diff --git a/tests/ui/suggestions/suggest-let-for-assignment.stderr b/tests/ui/suggestions/suggest-let-for-assignment.stderr index 3f6a3da4be2b3..8d97dbeb14a7a 100644 --- a/tests/ui/suggestions/suggest-let-for-assignment.stderr +++ b/tests/ui/suggestions/suggest-let-for-assignment.stderr @@ -32,14 +32,48 @@ error[E0425]: cannot find value `x` in this scope LL | println!("x: {}", x); | ^ not found in this scope +error[E0425]: cannot find value `let_some_variable` in this scope + --> $DIR/suggest-let-for-assignment.rs:10:5 + | +LL | let_some_variable = 6; + | ^^^^^^^^^^^^^^^^^ + | +help: you might have meant to introduce a new binding + | +LL | let some_variable = 6; + | ~~~~~~~~~~~~~~~~~ + +error[E0425]: cannot find value `some_variable` in this scope + --> $DIR/suggest-let-for-assignment.rs:11:35 + | +LL | println!("some_variable: {}", some_variable); + | ^^^^^^^^^^^^^ not found in this scope + +error[E0425]: cannot find value `letother_variable` in this scope + --> $DIR/suggest-let-for-assignment.rs:13:5 + | +LL | letother_variable = 6; + | ^^^^^^^^^^^^^^^^^ + | +help: you might have meant to introduce a new binding + | +LL | let other_variable = 6; + | ~~~~~~~~~~~~~~~~~~ + +error[E0425]: cannot find value `other_variable` in this scope + --> $DIR/suggest-let-for-assignment.rs:14:36 + | +LL | println!("other_variable: {}", other_variable); + | ^^^^^^^^^^^^^^ not found in this scope + error[E0425]: cannot find value `x` in this scope - --> $DIR/suggest-let-for-assignment.rs:10:8 + --> $DIR/suggest-let-for-assignment.rs:16:8 | LL | if x == "x" { | ^ not found in this scope error[E0425]: cannot find value `y` in this scope - --> $DIR/suggest-let-for-assignment.rs:15:5 + --> $DIR/suggest-let-for-assignment.rs:21:5 | LL | y = 1 + 2; | ^ @@ -50,11 +84,11 @@ LL | let y = 1 + 2; | +++ error[E0425]: cannot find value `y` in this scope - --> $DIR/suggest-let-for-assignment.rs:16:23 + --> $DIR/suggest-let-for-assignment.rs:22:23 | LL | println!("y: {}", y); | ^ not found in this scope -error: aborting due to 7 previous errors +error: aborting due to 11 previous errors For more information about this error, try `rustc --explain E0425`.