Rollup merge of #119957 - Young-Flash:fix, r=fmease
fix: correct suggestion arg for impl trait follow up https://github.com/rust-lang/rust/pull/118502, close https://github.com/rust-lang/rust/issues/119775
This commit is contained in:
commit
c6f0a5cfe3
@ -1601,23 +1601,33 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
self.ty_to_value_string(rcvr_ty.peel_refs())
|
||||
};
|
||||
if let SelfSource::MethodCall(_) = source {
|
||||
let first_arg = if let Some(CandidateSource::Impl(impl_did)) = static_candidates.get(0)
|
||||
&& let Some(assoc) = self.associated_value(*impl_did, item_name)
|
||||
&& assoc.kind == ty::AssocKind::Fn
|
||||
{
|
||||
let first_arg = static_candidates.get(0).and_then(|candidate_source| {
|
||||
let (assoc_did, self_ty) = match candidate_source {
|
||||
CandidateSource::Impl(impl_did) => {
|
||||
(*impl_did, self.tcx.type_of(*impl_did).instantiate_identity())
|
||||
}
|
||||
CandidateSource::Trait(trait_did) => (*trait_did, rcvr_ty),
|
||||
};
|
||||
|
||||
let assoc = self.associated_value(assoc_did, item_name)?;
|
||||
if assoc.kind != ty::AssocKind::Fn {
|
||||
return None;
|
||||
}
|
||||
|
||||
// for CandidateSource::Impl, `Self` will be instantiated to a concrete type
|
||||
// but for CandidateSource::Trait, `Self` is still `Self`
|
||||
let sig = self.tcx.fn_sig(assoc.def_id).instantiate_identity();
|
||||
sig.inputs().skip_binder().get(0).and_then(|first| {
|
||||
let impl_ty = self.tcx.type_of(*impl_did).instantiate_identity();
|
||||
// if the type of first arg is the same as the current impl type, we should take the first arg into assoc function
|
||||
if first.peel_refs() == impl_ty {
|
||||
let first_ty = first.peel_refs();
|
||||
if first_ty == self_ty || first_ty == self.tcx.types.self_param {
|
||||
Some(first.ref_mutability().map_or("", |mutbl| mutbl.ref_prefix_str()))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
});
|
||||
|
||||
let mut applicability = Applicability::MachineApplicable;
|
||||
let args = if let SelfSource::MethodCall(receiver) = source
|
||||
&& let Some(args) = args
|
||||
|
@ -0,0 +1,29 @@
|
||||
// run-rustfix
|
||||
|
||||
struct A {
|
||||
|
||||
}
|
||||
|
||||
trait M {
|
||||
fn foo(_a: Self);
|
||||
fn bar(_a: Self);
|
||||
fn baz(_a: i32);
|
||||
}
|
||||
|
||||
impl M for A {
|
||||
fn foo(_a: Self) {}
|
||||
fn bar(_a: A) {}
|
||||
fn baz(_a: i32) {}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _a = A {};
|
||||
A::foo(_a);
|
||||
//~^ ERROR no method named `foo` found
|
||||
A::baz(0);
|
||||
//~^ ERROR no method named `baz` found
|
||||
|
||||
let _b = A {};
|
||||
A::bar(_b);
|
||||
//~^ ERROR no method named `bar` found
|
||||
}
|
29
tests/ui/suggestions/suggest-assoc-fn-call-for-impl-trait.rs
Normal file
29
tests/ui/suggestions/suggest-assoc-fn-call-for-impl-trait.rs
Normal file
@ -0,0 +1,29 @@
|
||||
// run-rustfix
|
||||
|
||||
struct A {
|
||||
|
||||
}
|
||||
|
||||
trait M {
|
||||
fn foo(_a: Self);
|
||||
fn bar(_a: Self);
|
||||
fn baz(_a: i32);
|
||||
}
|
||||
|
||||
impl M for A {
|
||||
fn foo(_a: Self) {}
|
||||
fn bar(_a: A) {}
|
||||
fn baz(_a: i32) {}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _a = A {};
|
||||
_a.foo();
|
||||
//~^ ERROR no method named `foo` found
|
||||
_a.baz(0);
|
||||
//~^ ERROR no method named `baz` found
|
||||
|
||||
let _b = A {};
|
||||
_b.bar();
|
||||
//~^ ERROR no method named `bar` found
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
error[E0599]: no method named `foo` found for struct `A` in the current scope
|
||||
--> $DIR/suggest-assoc-fn-call-for-impl-trait.rs:21:8
|
||||
|
|
||||
LL | struct A {
|
||||
| -------- method `foo` not found for this struct
|
||||
...
|
||||
LL | _a.foo();
|
||||
| ---^^^--
|
||||
| | |
|
||||
| | this is an associated function, not a method
|
||||
| help: use associated function syntax instead: `A::foo(_a)`
|
||||
|
|
||||
= note: found the following associated functions; to be used as methods, functions must have a `self` parameter
|
||||
note: the candidate is defined in the trait `M`
|
||||
--> $DIR/suggest-assoc-fn-call-for-impl-trait.rs:8:5
|
||||
|
|
||||
LL | fn foo(_a: Self);
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0599]: no method named `baz` found for struct `A` in the current scope
|
||||
--> $DIR/suggest-assoc-fn-call-for-impl-trait.rs:23:8
|
||||
|
|
||||
LL | struct A {
|
||||
| -------- method `baz` not found for this struct
|
||||
...
|
||||
LL | _a.baz(0);
|
||||
| ---^^^---
|
||||
| | |
|
||||
| | this is an associated function, not a method
|
||||
| help: use associated function syntax instead: `A::baz(0)`
|
||||
|
|
||||
= note: found the following associated functions; to be used as methods, functions must have a `self` parameter
|
||||
note: the candidate is defined in the trait `M`
|
||||
--> $DIR/suggest-assoc-fn-call-for-impl-trait.rs:10:5
|
||||
|
|
||||
LL | fn baz(_a: i32);
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0599]: no method named `bar` found for struct `A` in the current scope
|
||||
--> $DIR/suggest-assoc-fn-call-for-impl-trait.rs:27:8
|
||||
|
|
||||
LL | struct A {
|
||||
| -------- method `bar` not found for this struct
|
||||
...
|
||||
LL | _b.bar();
|
||||
| ---^^^--
|
||||
| | |
|
||||
| | this is an associated function, not a method
|
||||
| help: use associated function syntax instead: `A::bar(_b)`
|
||||
|
|
||||
= note: found the following associated functions; to be used as methods, functions must have a `self` parameter
|
||||
note: the candidate is defined in the trait `M`
|
||||
--> $DIR/suggest-assoc-fn-call-for-impl-trait.rs:9:5
|
||||
|
|
||||
LL | fn bar(_a: Self);
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0599`.
|
Loading…
x
Reference in New Issue
Block a user