Rollup merge of #143177 - xizheyin:143134, r=lcnr

Remove false label when `self` resolve failure does not relate to macro

Fixes rust-lang/rust#143134

In the first commit, I did some code-clean, moving `suggest*` to `suggestions/` dir.
In the second, commit, I added ui test.
In the third, I change the code, and present the test result.

r? compiler
This commit is contained in:
Trevor Gross 2025-07-08 22:50:26 -05:00 committed by GitHub
commit a71dbcd679
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 31 additions and 6 deletions

View file

@ -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

View file

@ -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

View file

@ -0,0 +1,10 @@
trait T {
fn f(self);
}
impl T for () {
fn f(self) {
let self = (); //~ ERROR expected unit struct, unit variant or constant, found local variable `self`
}
}
fn main() {}

View file

@ -0,0 +1,9 @@
error[E0424]: expected unit struct, unit variant or constant, found local variable `self`
--> $DIR/false-self-in-macro-issue-143134.rs:6:13
|
LL | let self = ();
| ^^^^ `self` value is a keyword and may not be bound to variables or shadowed
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0424`.