mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 16:24:46 +00:00
Properly account for self ty in method disambiguation suggestion
Fix #116703.
This commit is contained in:
parent
93e62a260f
commit
5cc9216ff3
@ -1322,7 +1322,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let path = self.tcx.def_path_str(trait_ref.skip_binder().def_id);
|
||||
|
||||
let ty = match item.kind {
|
||||
ty::AssocKind::Const | ty::AssocKind::Type => rcvr_ty,
|
||||
ty::AssocKind::Const | ty::AssocKind::Type => impl_ty,
|
||||
ty::AssocKind::Fn => self
|
||||
.tcx
|
||||
.fn_sig(item.def_id)
|
||||
@ -1340,6 +1340,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
err,
|
||||
path,
|
||||
ty,
|
||||
impl_ty,
|
||||
item.kind,
|
||||
self.tcx.def_kind_descr(item.kind.as_def_kind(), item.def_id),
|
||||
sugg_span,
|
||||
@ -1376,6 +1377,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
err,
|
||||
path,
|
||||
rcvr_ty,
|
||||
rcvr_ty,
|
||||
item.kind,
|
||||
self.tcx.def_kind_descr(item.kind.as_def_kind(), item.def_id),
|
||||
sugg_span,
|
||||
@ -3146,6 +3148,7 @@ fn print_disambiguation_help<'tcx>(
|
||||
err: &mut Diagnostic,
|
||||
trait_name: String,
|
||||
rcvr_ty: Ty<'_>,
|
||||
self_ty: Ty<'_>,
|
||||
kind: ty::AssocKind,
|
||||
def_kind_descr: &'static str,
|
||||
span: Span,
|
||||
@ -3172,13 +3175,13 @@ fn print_disambiguation_help<'tcx>(
|
||||
.join(", "),
|
||||
);
|
||||
let trait_name = if !fn_has_self_parameter {
|
||||
format!("<{rcvr_ty} as {trait_name}>")
|
||||
format!("<{self_ty} as {trait_name}>")
|
||||
} else {
|
||||
trait_name
|
||||
};
|
||||
(span, format!("{trait_name}::{item_name}{args}"))
|
||||
} else {
|
||||
(span.with_hi(item_name.span.lo()), format!("<{rcvr_ty} as {trait_name}>::"))
|
||||
(span.with_hi(item_name.span.lo()), format!("<{self_ty} as {trait_name}>::"))
|
||||
};
|
||||
err.span_suggestion_verbose(
|
||||
span,
|
||||
|
27
tests/ui/methods/disambiguate-multiple-blanket-impl.rs
Normal file
27
tests/ui/methods/disambiguate-multiple-blanket-impl.rs
Normal file
@ -0,0 +1,27 @@
|
||||
trait A {
|
||||
fn foo(&self);
|
||||
}
|
||||
|
||||
trait B {
|
||||
fn foo(&self);
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct S;
|
||||
|
||||
impl<T: std::fmt::Debug> A for T {
|
||||
fn foo(&self) {} //~ NOTE candidate #1
|
||||
}
|
||||
|
||||
impl<T: std::fmt::Debug> B for T {
|
||||
fn foo(&self) {} //~ NOTE candidate #2
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let s = S;
|
||||
S::foo(&s); //~ ERROR multiple applicable items in scope
|
||||
//~^ NOTE multiple `foo` found
|
||||
//~| HELP disambiguate
|
||||
//~| HELP disambiguate
|
||||
}
|
||||
|
28
tests/ui/methods/disambiguate-multiple-blanket-impl.stderr
Normal file
28
tests/ui/methods/disambiguate-multiple-blanket-impl.stderr
Normal file
@ -0,0 +1,28 @@
|
||||
error[E0034]: multiple applicable items in scope
|
||||
--> $DIR/disambiguate-multiple-blanket-impl.rs:22:8
|
||||
|
|
||||
LL | S::foo(&s);
|
||||
| ^^^ multiple `foo` found
|
||||
|
|
||||
note: candidate #1 is defined in an impl of the trait `A` for the type `T`
|
||||
--> $DIR/disambiguate-multiple-blanket-impl.rs:13:5
|
||||
|
|
||||
LL | fn foo(&self) {}
|
||||
| ^^^^^^^^^^^^^
|
||||
note: candidate #2 is defined in an impl of the trait `B` for the type `T`
|
||||
--> $DIR/disambiguate-multiple-blanket-impl.rs:17:5
|
||||
|
|
||||
LL | fn foo(&self) {}
|
||||
| ^^^^^^^^^^^^^
|
||||
help: disambiguate the method for candidate #1
|
||||
|
|
||||
LL | <T as A>::foo(&s);
|
||||
| ~~~~~~~~~~
|
||||
help: disambiguate the method for candidate #2
|
||||
|
|
||||
LL | <T as B>::foo(&s);
|
||||
| ~~~~~~~~~~
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0034`.
|
26
tests/ui/methods/disambiguate-multiple-impl.rs
Normal file
26
tests/ui/methods/disambiguate-multiple-impl.rs
Normal file
@ -0,0 +1,26 @@
|
||||
trait A {
|
||||
fn foo(&self);
|
||||
}
|
||||
|
||||
trait B {
|
||||
fn foo(&self);
|
||||
}
|
||||
|
||||
struct S;
|
||||
|
||||
impl A for S {
|
||||
fn foo(&self) {} //~ NOTE candidate #1
|
||||
}
|
||||
|
||||
impl B for S {
|
||||
fn foo(&self) {} //~ NOTE candidate #2
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let s = S;
|
||||
S::foo(&s); //~ ERROR multiple applicable items in scope
|
||||
//~^ NOTE multiple `foo` found
|
||||
//~| HELP disambiguate
|
||||
//~| HELP disambiguate
|
||||
}
|
||||
|
28
tests/ui/methods/disambiguate-multiple-impl.stderr
Normal file
28
tests/ui/methods/disambiguate-multiple-impl.stderr
Normal file
@ -0,0 +1,28 @@
|
||||
error[E0034]: multiple applicable items in scope
|
||||
--> $DIR/disambiguate-multiple-impl.rs:21:8
|
||||
|
|
||||
LL | S::foo(&s);
|
||||
| ^^^ multiple `foo` found
|
||||
|
|
||||
note: candidate #1 is defined in an impl of the trait `A` for the type `S`
|
||||
--> $DIR/disambiguate-multiple-impl.rs:12:5
|
||||
|
|
||||
LL | fn foo(&self) {}
|
||||
| ^^^^^^^^^^^^^
|
||||
note: candidate #2 is defined in an impl of the trait `B` for the type `S`
|
||||
--> $DIR/disambiguate-multiple-impl.rs:16:5
|
||||
|
|
||||
LL | fn foo(&self) {}
|
||||
| ^^^^^^^^^^^^^
|
||||
help: disambiguate the method for candidate #1
|
||||
|
|
||||
LL | <S as A>::foo(&s);
|
||||
| ~~~~~~~~~~
|
||||
help: disambiguate the method for candidate #2
|
||||
|
|
||||
LL | <S as B>::foo(&s);
|
||||
| ~~~~~~~~~~
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0034`.
|
Loading…
Reference in New Issue
Block a user