Skip to content

Commit

Permalink
Properly account for self ty in method disambiguation suggestion
Browse files Browse the repository at this point in the history
Fix #116703.
  • Loading branch information
estebank committed Oct 13, 2023
1 parent df4379b commit ae8c677
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 3 deletions.
9 changes: 6 additions & 3 deletions compiler/rustc_hir_typeck/src/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1311,7 +1311,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)
Expand All @@ -1329,6 +1329,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,
Expand Down Expand Up @@ -1365,6 +1366,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,
Expand Down Expand Up @@ -3107,6 +3109,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,
Expand All @@ -3133,13 +3136,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,
Expand Down
27 changes: 27 additions & 0 deletions tests/ui/methods/disambiguate-multiple-blanket-impl.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 28 additions & 0 deletions tests/ui/methods/disambiguate-multiple-blanket-impl.stderr
Original file line number Diff line number Diff line change
@@ -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 changes: 26 additions & 0 deletions tests/ui/methods/disambiguate-multiple-impl.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 28 additions & 0 deletions tests/ui/methods/disambiguate-multiple-impl.stderr
Original file line number Diff line number Diff line change
@@ -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`.

0 comments on commit ae8c677

Please sign in to comment.