about summary refs log tree commit diff
diff options
context:
space:
mode:
authorxizheyin <xizheyin@smail.nju.edu.cn>2025-06-29 16:10:52 +0800
committerxizheyin <xizheyin@smail.nju.edu.cn>2025-07-03 23:47:19 +0800
commit236b392904d234d9ec2968c55ae20132405a555d (patch)
tree259d9512ef8f1558cbe3264bc56f93a7e084cd70
parent000f038e9999ebdbaf3167c42dadc3db872a5d3f (diff)
downloadrust-236b392904d234d9ec2968c55ae20132405a555d.tar.gz
rust-236b392904d234d9ec2968c55ae20132405a555d.zip
Return early when `self` resolve failure because of `let self = ...`
Signed-off-by: xizheyin <xizheyin@smail.nju.edu.cn>
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs16
-rw-r--r--tests/ui/error-codes/E0424.stderr2
-rw-r--r--tests/ui/resolve/false-self-in-macro-issue-143134.stderr7
3 files changed, 14 insertions, 11 deletions
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index e7b8c988cd4..0b78835326f 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -1183,15 +1183,23 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
                 _ => "`self` value is a keyword only available in methods with a `self` parameter",
             },
         );
+
+        // using `let self` is wrong even if we're not in an associated method or if we're in a macro expansion.
+        // So, we should return early if we're in a pattern, see issue #143134.
+        if matches!(source, PathSource::Pat) {
+            return true;
+        }
+
         let is_assoc_fn = self.self_type_is_available();
         let self_from_macro = "a `self` parameter, but a macro invocation can only \
                                access identifiers it receives from parameters";
-        if let Some((fn_kind, span)) = &self.diag_metadata.current_function {
+        if let Some((fn_kind, fn_span)) = &self.diag_metadata.current_function {
             // The current function has a `self` parameter, but we were unable to resolve
             // a reference to `self`. This can only happen if the `self` identifier we
-            // are resolving came from a different hygiene context.
+            // are resolving came from a different hygiene context or a variable binding.
+            // But variable binding error is returned early above.
             if fn_kind.decl().inputs.get(0).is_some_and(|p| p.is_self()) {
-                err.span_label(*span, format!("this function has {self_from_macro}"));
+                err.span_label(*fn_span, format!("this function has {self_from_macro}"));
             } else {
                 let doesnt = if is_assoc_fn {
                     let (span, sugg) = fn_kind
@@ -1204,7 +1212,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
                             // This avoids placing the suggestion into the visibility specifier.
                             let span = fn_kind
                                 .ident()
-                                .map_or(*span, |ident| span.with_lo(ident.span.hi()));
+                                .map_or(*fn_span, |ident| fn_span.with_lo(ident.span.hi()));
                             (
                                 self.r
                                     .tcx
diff --git a/tests/ui/error-codes/E0424.stderr b/tests/ui/error-codes/E0424.stderr
index d02da3e4ecb..831a070bf6c 100644
--- a/tests/ui/error-codes/E0424.stderr
+++ b/tests/ui/error-codes/E0424.stderr
@@ -40,8 +40,6 @@ LL |     fn qux(&self) {
 error[E0424]: expected unit struct, unit variant or constant, found module `self`
   --> $DIR/E0424.rs:20:9
    |
-LL | fn main () {
-   |    ---- this function can't have a `self` parameter
 LL |     let self = "self";
    |         ^^^^ `self` value is a keyword and may not be bound to variables or shadowed
 
diff --git a/tests/ui/resolve/false-self-in-macro-issue-143134.stderr b/tests/ui/resolve/false-self-in-macro-issue-143134.stderr
index 43e77e183ae..48c979575ea 100644
--- a/tests/ui/resolve/false-self-in-macro-issue-143134.stderr
+++ b/tests/ui/resolve/false-self-in-macro-issue-143134.stderr
@@ -1,11 +1,8 @@
 error[E0424]: expected unit struct, unit variant or constant, found local variable `self`
   --> $DIR/false-self-in-macro-issue-143134.rs:6:13
    |
-LL | /     fn f(self) {
-LL | |         let self = ();
-   | |             ^^^^ `self` value is a keyword and may not be bound to variables or shadowed
-LL | |     }
-   | |_____- this function has a `self` parameter, but a macro invocation can only access identifiers it receives from parameters
+LL |         let self = ();
+   |             ^^^^ `self` value is a keyword and may not be bound to variables or shadowed
 
 error: aborting due to 1 previous error