Rollup merge of #116086 - estebank:issue-115992, r=compiler-errors

More accurate suggestion for `self.` and `Self::`

Detect that we can't suggest `self.` in an associated function without `&self` receiver.

Partially address #115992.

r? ``@compiler-errors``
This commit is contained in:
Matthias Krüger 2023-09-24 01:14:06 +02:00 committed by GitHub
commit 61b38b216a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 128 additions and 37 deletions

View File

@ -214,6 +214,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
module: None,
}
} else {
let mut span_label = None;
let item_span = path.last().unwrap().ident.span;
let (mod_prefix, mod_str, module, suggestion) = if path.len() == 1 {
debug!(?self.diagnostic_metadata.current_impl_items);
@ -224,32 +225,41 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
&& let FnKind::Fn(_, _, sig, ..) = fn_kind
&& let Some(items) = self.diagnostic_metadata.current_impl_items
&& let Some(item) = items.iter().find(|i| {
if let AssocItemKind::Fn(..) | AssocItemKind::Const(..) = &i.kind
&& i.ident.name == item_str.name
// don't suggest if the item is in Fn signature arguments
// issue #112590
i.ident.name == item_str.name
// Don't suggest if the item is in Fn signature arguments (#112590).
&& !sig.span.contains(item_span)
{
debug!(?item_str.name);
return true
}
false
})
{
let self_sugg = match &item.kind {
AssocItemKind::Fn(fn_) if fn_.sig.decl.has_self() => "self.",
_ => "Self::",
};
Some((
item_span.shrink_to_lo(),
match &item.kind {
AssocItemKind::Fn(..) => "consider using the associated function",
AssocItemKind::Const(..) => "consider using the associated constant",
_ => unreachable!("item kind was filtered above"),
},
self_sugg.to_string()
))
let sp = item_span.shrink_to_lo();
match &item.kind {
AssocItemKind::Fn(fn_)
if !sig.decl.has_self() && fn_.sig.decl.has_self() => {
// Ensure that we only suggest `self.` if `self` is available,
// you can't call `fn foo(&self)` from `fn bar()` (#115992).
// We also want to mention that the method exists.
span_label = Some((
item.ident.span,
"a method by that name is available on `Self` here",
));
None
}
AssocItemKind::Fn(fn_) if fn_.sig.decl.has_self() => Some((
sp,
"consider using the method on `Self`",
"self.".to_string(),
)),
AssocItemKind::Fn(_) => Some((
sp,
"consider using the associated function on `Self`",
"Self::".to_string(),
)),
AssocItemKind::Const(..) => Some((
sp,
"consider using the associated constant on `Self`",
"Self::".to_string(),
)),
_ => None
}
} else {
None
};
@ -314,7 +324,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
msg: format!("cannot find {expected} `{item_str}` in {mod_prefix}{mod_str}"),
fallback_label,
span: item_span,
span_label: None,
span_label,
could_be_expr: false,
suggestion,
module,

View File

@ -0,0 +1,15 @@
struct Foo {
field: u32,
}
impl Foo {
fn field(&self) -> u32 {
self.field
}
fn new() -> Foo {
field; //~ ERROR cannot find value `field` in this scope
Foo { field } //~ ERROR cannot find value `field` in this scope
}
}
fn main() {}

View File

@ -0,0 +1,21 @@
error[E0425]: cannot find value `field` in this scope
--> $DIR/field-and-method-in-self-not-available-in-assoc-fn.rs:11:9
|
LL | fn field(&self) -> u32 {
| ----- a method by that name is available on `Self` here
...
LL | field;
| ^^^^^ a field by this name exists in `Self`
error[E0425]: cannot find value `field` in this scope
--> $DIR/field-and-method-in-self-not-available-in-assoc-fn.rs:12:15
|
LL | fn field(&self) -> u32 {
| ----- a method by that name is available on `Self` here
...
LL | Foo { field }
| ^^^^^ a field by this name exists in `Self`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0425`.

View File

@ -19,7 +19,7 @@ error[E0425]: cannot find function `first` in this scope
LL | first()
| ^^^^^ not found in this scope
|
help: consider using the associated function
help: consider using the method on `Self`
|
LL | self.first()
| +++++

View File

@ -73,7 +73,7 @@ error[E0425]: cannot find function `static_method` in this scope
LL | static_method();
| ^^^^^^^^^^^^^ not found in this scope
|
help: consider using the associated function
help: consider using the associated function on `Self`
|
LL | Self::static_method();
| ++++++
@ -102,7 +102,7 @@ error[E0425]: cannot find function `grow_older` in this scope
LL | grow_older();
| ^^^^^^^^^^ not found in this scope
|
help: consider using the associated function
help: consider using the associated function on `Self`
|
LL | Self::grow_older();
| ++++++

View File

@ -10,7 +10,7 @@ error[E0425]: cannot find function `sleep` in this scope
LL | sleep();
| ^^^^^ not found in this scope
|
help: consider using the associated function
help: consider using the method on `Self`
|
LL | self.sleep();
| +++++

View File

@ -4,7 +4,7 @@ error[E0425]: cannot find value `A_CONST` in this scope
LL | A_CONST
| ^^^^^^^ not found in this scope
|
help: consider using the associated constant
help: consider using the associated constant on `Self`
|
LL | Self::A_CONST
| ++++++

View File

@ -17,4 +17,12 @@ impl S {
bar(); //~ ERROR cannot find function `bar` in this scope
baz(2, 3); //~ ERROR cannot find function `baz` in this scope
}
fn d(&self) {
fn c() {
foo(); //~ ERROR cannot find function `foo` in this scope
}
foo(); //~ ERROR cannot find function `foo` in this scope
bar(); //~ ERROR cannot find function `bar` in this scope
baz(2, 3); //~ ERROR cannot find function `baz` in this scope
}
}

View File

@ -4,7 +4,7 @@ error[E0425]: cannot find function `foo` in this scope
LL | foo();
| ^^^ not found in this scope
|
help: consider using the associated function
help: consider using the associated function on `Self`
|
LL | Self::foo();
| ++++++
@ -12,13 +12,11 @@ LL | Self::foo();
error[E0425]: cannot find function `bar` in this scope
--> $DIR/assoc_fn_without_self.rs:17:9
|
LL | fn bar(&self) {}
| --- a method by that name is available on `Self` here
...
LL | bar();
| ^^^ not found in this scope
|
help: consider using the associated function
|
LL | self.bar();
| +++++
error[E0425]: cannot find function `baz` in this scope
--> $DIR/assoc_fn_without_self.rs:18:9
@ -26,7 +24,7 @@ error[E0425]: cannot find function `baz` in this scope
LL | baz(2, 3);
| ^^^ not found in this scope
|
help: consider using the associated function
help: consider using the associated function on `Self`
|
LL | Self::baz(2, 3);
| ++++++
@ -37,6 +35,45 @@ error[E0425]: cannot find function `foo` in this scope
LL | foo();
| ^^^ not found in this scope
error: aborting due to 4 previous errors
error[E0425]: cannot find function `foo` in this scope
--> $DIR/assoc_fn_without_self.rs:24:9
|
LL | foo();
| ^^^ not found in this scope
|
help: consider using the associated function on `Self`
|
LL | Self::foo();
| ++++++
error[E0425]: cannot find function `bar` in this scope
--> $DIR/assoc_fn_without_self.rs:25:9
|
LL | bar();
| ^^^ not found in this scope
|
help: consider using the method on `Self`
|
LL | self.bar();
| +++++
error[E0425]: cannot find function `baz` in this scope
--> $DIR/assoc_fn_without_self.rs:26:9
|
LL | baz(2, 3);
| ^^^ not found in this scope
|
help: consider using the associated function on `Self`
|
LL | Self::baz(2, 3);
| ++++++
error[E0425]: cannot find function `foo` in this scope
--> $DIR/assoc_fn_without_self.rs:22:13
|
LL | foo();
| ^^^ not found in this scope
error: aborting due to 8 previous errors
For more information about this error, try `rustc --explain E0425`.