Return early when `self` resolve failure because of `let self = ...`
Signed-off-by: xizheyin <xizheyin@smail.nju.edu.cn>
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index e7b8c98..0b78835 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -1183,15 +1183,23 @@ fn suggest_self_value(
_ => "`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 @@ fn suggest_self_value(
// 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 d02da3e..831a070 100644
--- a/tests/ui/error-codes/E0424.stderr
+++ b/tests/ui/error-codes/E0424.stderr
@@ -40,8 +40,6 @@
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 43e77e1..48c9795 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