-
Notifications
You must be signed in to change notification settings - Fork 13.4k
Suggest calling the instance method of the same name when method not found #103531
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -213,26 +213,26 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { | |
let (mod_prefix, mod_str, suggestion) = if path.len() == 1 { | ||
debug!(?self.diagnostic_metadata.current_impl_items); | ||
debug!(?self.diagnostic_metadata.current_function); | ||
let suggestion = if let Some(items) = self.diagnostic_metadata.current_impl_items | ||
let suggestion = if self.current_trait_ref.is_none() | ||
&& let Some((fn_kind, _)) = self.diagnostic_metadata.current_function | ||
&& self.current_trait_ref.is_none() | ||
&& let Some(FnCtxt::Assoc(_)) = fn_kind.ctxt() | ||
&& let Some(items) = self.diagnostic_metadata.current_impl_items | ||
&& let Some(item) = items.iter().find(|i| { | ||
if let AssocItemKind::Fn(fn_) = &i.kind | ||
&& !fn_.sig.decl.has_self() | ||
&& i.ident.name == item_str.name | ||
if let AssocItemKind::Fn(_) = &i.kind && i.ident.name == item_str.name | ||
{ | ||
debug!(?item_str.name); | ||
debug!(?fn_.sig.decl.inputs); | ||
return true | ||
} | ||
false | ||
}) | ||
&& let AssocItemKind::Fn(fn_) = &item.kind | ||
{ | ||
debug!(?fn_); | ||
let self_sugg = if fn_.sig.decl.has_self() { "self." } else { "Self::" }; | ||
Some(( | ||
item_span, | ||
item_span.shrink_to_lo(), | ||
"consider using the associated function", | ||
format!("Self::{}", item.ident) | ||
self_sugg.to_string() | ||
)) | ||
} else { | ||
None | ||
|
@@ -381,11 +381,13 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { | |
} | ||
|
||
fn suggest_self_or_self_ref(&mut self, err: &mut Diagnostic, path: &[Segment], span: Span) { | ||
let is_assoc_fn = self.self_type_is_available(); | ||
if !self.self_type_is_available() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This probably causes a regression in the suggestions for the code: struct Foo {
i: i32,
}
impl Foo {
fn needs_self() {
this.i
}
} Which currently looks like:
Can you check that it still works? Also useful to commit a test for it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This testcase still works, I didn't change the meaning of I will add this code into tests. |
||
return; | ||
} | ||
let Some(path_last_segment) = path.last() else { return }; | ||
let item_str = path_last_segment.ident; | ||
// Emit help message for fake-self from other languages (e.g., `this` in Javascript). | ||
if ["this", "my"].contains(&item_str.as_str()) && is_assoc_fn { | ||
if ["this", "my"].contains(&item_str.as_str()) { | ||
err.span_suggestion_short( | ||
span, | ||
"you might have meant to use `self` here instead", | ||
|
@@ -436,7 +438,6 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { | |
let is_enum_variant = &|res| matches!(res, Res::Def(DefKind::Variant, _)); | ||
let path_str = Segment::names_to_string(path); | ||
let ident_span = path.last().map_or(span, |ident| ident.ident.span); | ||
|
||
let mut candidates = self | ||
.r | ||
.lookup_import_candidates(ident, ns, &self.parent_scope, is_expected) | ||
|
@@ -1512,7 +1513,6 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { | |
_ => None, | ||
} | ||
} | ||
|
||
// Fields are generally expected in the same contexts as locals. | ||
if filter_fn(Res::Local(ast::DUMMY_NODE_ID)) { | ||
if let Some(node_id) = | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
struct S {} | ||
impl S { | ||
fn first(&self) {} | ||
|
||
fn second(&self) { | ||
first() | ||
//~^ ERROR cannot find function `first` in this scope | ||
} | ||
|
||
fn third(&self) { | ||
no_method_err() | ||
//~^ ERROR cannot find function `no_method_err` in this scope | ||
} | ||
} | ||
|
||
// https://github.com/rust-lang/rust/pull/103531#discussion_r1004728080 | ||
struct Foo { | ||
i: i32, | ||
} | ||
|
||
impl Foo { | ||
fn needs_self() { | ||
this.i | ||
//~^ ERROR cannot find value `this` in this scope | ||
} | ||
} | ||
|
||
fn main() {} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
error[E0425]: cannot find value `this` in this scope | ||
--> $DIR/issue-103474.rs:23:9 | ||
| | ||
LL | this.i | ||
| ^^^^ not found in this scope | ||
| | ||
help: you might have meant to use `self` here instead | ||
| | ||
LL | self.i | ||
| ~~~~ | ||
help: if you meant to use `self`, you are also missing a `self` receiver argument | ||
| | ||
LL | fn needs_self(&self) { | ||
| +++++ | ||
|
||
error[E0425]: cannot find function `first` in this scope | ||
--> $DIR/issue-103474.rs:6:9 | ||
| | ||
LL | first() | ||
| ^^^^^ not found in this scope | ||
| | ||
help: consider using the associated function | ||
| | ||
LL | self.first() | ||
| +++++ | ||
|
||
error[E0425]: cannot find function `no_method_err` in this scope | ||
--> $DIR/issue-103474.rs:11:9 | ||
| | ||
LL | no_method_err() | ||
| ^^^^^^^^^^^^^ not found in this scope | ||
|
||
error: aborting due to 3 previous errors | ||
|
||
For more information about this error, try `rustc --explain E0425`. |
Uh oh!
There was an error while loading. Please reload this page.