Sort method suggestions by DefPath instead of DefId

This commit is contained in:
Oli Scherer 2024-03-21 16:47:04 +00:00
parent 727807293b
commit 57f68c3555
8 changed files with 54 additions and 51 deletions

View File

@ -81,7 +81,7 @@ pub struct NoMatchData<'tcx> {
// A pared down enum describing just the places from which a method // A pared down enum describing just the places from which a method
// candidate can arise. Used for error reporting only. // candidate can arise. Used for error reporting only.
#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)] #[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum CandidateSource { pub enum CandidateSource {
Impl(DefId), Impl(DefId),
Trait(DefId /* trait id */), Trait(DefId /* trait id */),

View File

@ -1567,7 +1567,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
sources: &mut Vec<CandidateSource>, sources: &mut Vec<CandidateSource>,
sugg_span: Option<Span>, sugg_span: Option<Span>,
) { ) {
sources.sort(); sources.sort_by_key(|source| match source {
CandidateSource::Trait(id) => (0, self.tcx.def_path_str(id)),
CandidateSource::Impl(id) => (1, self.tcx.def_path_str(id)),
});
sources.dedup(); sources.dedup();
// Dynamic limit to avoid hiding just one candidate, which is silly. // Dynamic limit to avoid hiding just one candidate, which is silly.
let limit = if sources.len() == 5 { 5 } else { 4 }; let limit = if sources.len() == 5 { 5 } else { 4 };

View File

@ -4,16 +4,16 @@ error[E0034]: multiple applicable items in scope
LL | const X: i32 = <i32>::ID; LL | const X: i32 = <i32>::ID;
| ^^ multiple `ID` found | ^^ multiple `ID` found
| |
note: candidate #1 is defined in an impl of the trait `Foo` for the type `i32` note: candidate #1 is defined in an impl of the trait `Bar` for the type `i32`
--> $DIR/associated-const-ambiguity-report.rs:10:5
|
LL | const ID: i32 = 1;
| ^^^^^^^^^^^^^
note: candidate #2 is defined in an impl of the trait `Bar` for the type `i32`
--> $DIR/associated-const-ambiguity-report.rs:14:5 --> $DIR/associated-const-ambiguity-report.rs:14:5
| |
LL | const ID: i32 = 3; LL | const ID: i32 = 3;
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
note: candidate #2 is defined in an impl of the trait `Foo` for the type `i32`
--> $DIR/associated-const-ambiguity-report.rs:10:5
|
LL | const ID: i32 = 1;
| ^^^^^^^^^^^^^
help: use fully-qualified syntax to disambiguate help: use fully-qualified syntax to disambiguate
| |
LL | const X: i32 = <i32 as Bar>::ID; LL | const X: i32 = <i32 as Bar>::ID;

View File

@ -4,17 +4,17 @@ error[E0034]: multiple applicable items in scope
LL | x.foo(); LL | x.foo();
| ^^^ multiple `foo` found | ^^^ multiple `foo` found
| |
note: candidate #1 is defined in an impl for the type `(dyn T + 'a)` note: candidate #1 is defined in the trait `T`
--> $DIR/issue-18446.rs:9:5
|
LL | fn foo(&self) {}
| ^^^^^^^^^^^^^
note: candidate #2 is defined in the trait `T`
--> $DIR/issue-18446.rs:5:5 --> $DIR/issue-18446.rs:5:5
| |
LL | fn foo(&self); LL | fn foo(&self);
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
help: disambiguate the method for candidate #2 note: candidate #2 is defined in an impl for the type `(dyn T + 'a)`
--> $DIR/issue-18446.rs:9:5
|
LL | fn foo(&self) {}
| ^^^^^^^^^^^^^
help: disambiguate the method for candidate #1
| |
LL | T::foo(&x); LL | T::foo(&x);
| ~~~~~~~~~~ | ~~~~~~~~~~

View File

@ -4,24 +4,24 @@ error[E0034]: multiple applicable items in scope
LL | self.to_int() + other.to_int() LL | self.to_int() + other.to_int()
| ^^^^^^ multiple `to_int` found | ^^^^^^ multiple `to_int` found
| |
note: candidate #1 is defined in an impl of the trait `ToPrimitive` for the type `isize` note: candidate #1 is defined in an impl of the trait `Add` for the type `isize`
--> $DIR/issue-3702-2.rs:2:5
|
LL | fn to_int(&self) -> isize { 0 }
| ^^^^^^^^^^^^^^^^^^^^^^^^^
note: candidate #2 is defined in an impl of the trait `Add` for the type `isize`
--> $DIR/issue-3702-2.rs:14:5 --> $DIR/issue-3702-2.rs:14:5
| |
LL | fn to_int(&self) -> isize { *self } LL | fn to_int(&self) -> isize { *self }
| ^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^
help: disambiguate the method for candidate #1 note: candidate #2 is defined in an impl of the trait `ToPrimitive` for the type `isize`
--> $DIR/issue-3702-2.rs:2:5
| |
LL | ToPrimitive::to_int(&self) + other.to_int() LL | fn to_int(&self) -> isize { 0 }
| ~~~~~~~~~~~~~~~~~~~~~~~~~~ | ^^^^^^^^^^^^^^^^^^^^^^^^^
help: disambiguate the method for candidate #2 help: disambiguate the method for candidate #1
| |
LL | Add::to_int(&self) + other.to_int() LL | Add::to_int(&self) + other.to_int()
| ~~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~~~~~~
help: disambiguate the method for candidate #2
|
LL | ToPrimitive::to_int(&self) + other.to_int()
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to 1 previous error error: aborting due to 1 previous error

View File

@ -4,20 +4,20 @@ error[E0034]: multiple applicable items in scope
LL | fn main() { 1_usize.me(); } LL | fn main() { 1_usize.me(); }
| ^^ multiple `me` found | ^^ multiple `me` found
| |
= note: candidate #1 is defined in an impl of the trait `Me` for the type `usize` note: candidate #1 is defined in an impl of the trait `Me2` for the type `usize`
note: candidate #2 is defined in an impl of the trait `Me2` for the type `usize`
--> $DIR/method-ambig-two-traits-cross-crate.rs:10:22 --> $DIR/method-ambig-two-traits-cross-crate.rs:10:22
| |
LL | impl Me2 for usize { fn me(&self) -> usize { *self } } LL | impl Me2 for usize { fn me(&self) -> usize { *self } }
| ^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^
= note: candidate #2 is defined in an impl of the trait `Me` for the type `usize`
help: disambiguate the method for candidate #1 help: disambiguate the method for candidate #1
| |
LL | fn main() { Me::me(&1_usize); }
| ~~~~~~~~~~~~~~~~
help: disambiguate the method for candidate #2
|
LL | fn main() { Me2::me(&1_usize); } LL | fn main() { Me2::me(&1_usize); }
| ~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~~~~~
help: disambiguate the method for candidate #2
|
LL | fn main() { Me::me(&1_usize); }
| ~~~~~~~~~~~~~~~~
error: aborting due to 1 previous error error: aborting due to 1 previous error

View File

@ -4,23 +4,23 @@ error[E0034]: multiple applicable items in scope
LL | 1_usize.method(); LL | 1_usize.method();
| ^^^^^^ multiple `method` found | ^^^^^^ multiple `method` found
| |
note: candidate #1 is defined in an impl of the trait `Foo` for the type `usize` note: candidate #1 is defined in an impl of the trait `Bar` for the type `usize`
--> $DIR/method-ambig-two-traits-with-default-method.rs:5:13
|
LL | trait Foo { fn method(&self) {} }
| ^^^^^^^^^^^^^^^^
note: candidate #2 is defined in an impl of the trait `Bar` for the type `usize`
--> $DIR/method-ambig-two-traits-with-default-method.rs:6:13 --> $DIR/method-ambig-two-traits-with-default-method.rs:6:13
| |
LL | trait Bar { fn method(&self) {} } LL | trait Bar { fn method(&self) {} }
| ^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
note: candidate #2 is defined in an impl of the trait `Foo` for the type `usize`
--> $DIR/method-ambig-two-traits-with-default-method.rs:5:13
|
LL | trait Foo { fn method(&self) {} }
| ^^^^^^^^^^^^^^^^
help: disambiguate the method for candidate #1 help: disambiguate the method for candidate #1
| |
LL | Foo::method(&1_usize); LL | Bar::method(&1_usize);
| ~~~~~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~~~~~~~~~
help: disambiguate the method for candidate #2 help: disambiguate the method for candidate #2
| |
LL | Bar::method(&1_usize); LL | Foo::method(&1_usize);
| ~~~~~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~~~~~~~~~
error: aborting due to 1 previous error error: aborting due to 1 previous error

View File

@ -29,33 +29,33 @@ error[E0034]: multiple applicable items in scope
LL | let z = x.foo(); LL | let z = x.foo();
| ^^^ multiple `foo` found | ^^^ multiple `foo` found
| |
note: candidate #1 is defined in an impl of the trait `X` for the type `T` note: candidate #1 is defined in the trait `FinalFoo`
--> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:45:9 --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:59:5
| |
LL | fn foo(self: Smaht<Self, u64>) -> u64 { LL | fn foo(&self) -> u8;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
note: candidate #2 is defined in an impl of the trait `NuisanceFoo` for the type `T` note: candidate #2 is defined in an impl of the trait `NuisanceFoo` for the type `T`
--> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:72:9 --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:72:9
| |
LL | fn foo(self) {} LL | fn foo(self) {}
| ^^^^^^^^^^^^ | ^^^^^^^^^^^^
note: candidate #3 is defined in the trait `FinalFoo` note: candidate #3 is defined in an impl of the trait `X` for the type `T`
--> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:59:5 --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:45:9
| |
LL | fn foo(&self) -> u8; LL | fn foo(self: Smaht<Self, u64>) -> u64 {
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: disambiguate the method for candidate #1 help: disambiguate the method for candidate #1
| |
LL | let z = X::foo(x); LL | let z = FinalFoo::foo(&x);
| ~~~~~~~~~ | ~~~~~~~~~~~~~~~~~
help: disambiguate the method for candidate #2 help: disambiguate the method for candidate #2
| |
LL | let z = NuisanceFoo::foo(x); LL | let z = NuisanceFoo::foo(x);
| ~~~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~~~~~~~
help: disambiguate the method for candidate #3 help: disambiguate the method for candidate #3
| |
LL | let z = FinalFoo::foo(&x); LL | let z = X::foo(x);
| ~~~~~~~~~~~~~~~~~ | ~~~~~~~~~
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:139:24 --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:139:24