about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2023-10-19 22:34:45 +0000
committerEsteban Küber <esteban@kuber.com.ar>2023-10-20 15:58:25 +0000
commitb0d17f35d98c5cafd43a673c70f8ab5d393c31a3 (patch)
tree42f3f639de8a8ba1b2b07397095a475264be1bdf
parentcc705b801236d064260bb67b3a0a25e4747fa7ec (diff)
downloadrust-b0d17f35d98c5cafd43a673c70f8ab5d393c31a3.tar.gz
rust-b0d17f35d98c5cafd43a673c70f8ab5d393c31a3.zip
Typo suggestion to change bindings with leading underscore
When encountering a binding that isn't found but has a typo suggestion
for a binding with a leading underscore, suggest changing the binding
definition instead of the use place.

Fix #60164.
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs17
-rw-r--r--tests/ui/suggestions/silenced-binding-typo.fixed5
-rw-r--r--tests/ui/suggestions/silenced-binding-typo.rs5
-rw-r--r--tests/ui/suggestions/silenced-binding-typo.stderr14
4 files changed, 39 insertions, 2 deletions
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 925ee615b09..4ad838e5aed 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -1511,9 +1511,22 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                 ),
             );
         }
+
+        let (span, sugg, post) = if let SuggestionTarget::SimilarlyNamed = suggestion.target
+            && let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span)
+            && let Some(span) = suggestion.span
+            && let Some(candidate) = suggestion.candidate.as_str().strip_prefix("_")
+            && snippet == candidate
+        {
+            // When the suggested binding change would be from `x` to `_x`, suggest changing the
+            // original binding definition instead. (#60164)
+            (span, snippet, ", consider changing it")
+        } else {
+            (span, suggestion.candidate.to_string(), "")
+        };
         let msg = match suggestion.target {
             SuggestionTarget::SimilarlyNamed => format!(
-                "{} {} with a similar name exists",
+                "{} {} with a similar name exists{post}",
                 suggestion.res.article(),
                 suggestion.res.descr()
             ),
@@ -1521,7 +1534,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                 format!("maybe you meant this {}", suggestion.res.descr())
             }
         };
-        err.span_suggestion(span, msg, suggestion.candidate, Applicability::MaybeIncorrect);
+        err.span_suggestion(span, msg, sugg, Applicability::MaybeIncorrect);
         true
     }
 
diff --git a/tests/ui/suggestions/silenced-binding-typo.fixed b/tests/ui/suggestions/silenced-binding-typo.fixed
new file mode 100644
index 00000000000..e0f9e31bef3
--- /dev/null
+++ b/tests/ui/suggestions/silenced-binding-typo.fixed
@@ -0,0 +1,5 @@
+// run-rustfix
+fn main() {
+    let x = 42; //~ HELP
+    let _y = x; //~ ERROR
+}
diff --git a/tests/ui/suggestions/silenced-binding-typo.rs b/tests/ui/suggestions/silenced-binding-typo.rs
new file mode 100644
index 00000000000..6cadd5a93a7
--- /dev/null
+++ b/tests/ui/suggestions/silenced-binding-typo.rs
@@ -0,0 +1,5 @@
+// run-rustfix
+fn main() {
+    let _x = 42; //~ HELP
+    let _y = x; //~ ERROR
+}
diff --git a/tests/ui/suggestions/silenced-binding-typo.stderr b/tests/ui/suggestions/silenced-binding-typo.stderr
new file mode 100644
index 00000000000..9c0e6e26569
--- /dev/null
+++ b/tests/ui/suggestions/silenced-binding-typo.stderr
@@ -0,0 +1,14 @@
+error[E0425]: cannot find value `x` in this scope
+  --> $DIR/silenced-binding-typo.rs:4:14
+   |
+LL |     let _y = x;
+   |              ^
+   |
+help: a local variable with a similar name exists, consider changing it
+   |
+LL |     let x = 42;
+   |         ~
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0425`.