mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-16 17:03:35 +00:00
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:
commit
61b38b216a
@ -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,
|
||||
|
@ -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() {}
|
@ -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`.
|
@ -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()
|
||||
| +++++
|
||||
|
@ -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();
|
||||
| ++++++
|
||||
|
@ -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();
|
||||
| +++++
|
||||
|
@ -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
|
||||
| ++++++
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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`.
|
||||
|
Loading…
Reference in New Issue
Block a user