diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index e9752d7a4a8..39d54f1a25e 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -81,7 +81,7 @@ pub struct NoMatchData<'tcx> { // A pared down enum describing just the places from which a method // 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 { Impl(DefId), Trait(DefId /* trait id */), diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 952d5368298..3a4ff8fbb3b 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -1567,7 +1567,10 @@ fn note_candidates_on_method_error( sources: &mut Vec, sugg_span: Option, ) { - 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(); // Dynamic limit to avoid hiding just one candidate, which is silly. let limit = if sources.len() == 5 { 5 } else { 4 }; diff --git a/tests/ui/associated-consts/associated-const-ambiguity-report.stderr b/tests/ui/associated-consts/associated-const-ambiguity-report.stderr index 42d722291c3..35ee95d1215 100644 --- a/tests/ui/associated-consts/associated-const-ambiguity-report.stderr +++ b/tests/ui/associated-consts/associated-const-ambiguity-report.stderr @@ -4,16 +4,16 @@ error[E0034]: multiple applicable items in scope LL | const X: i32 = ::ID; | ^^ multiple `ID` found | -note: candidate #1 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; - | ^^^^^^^^^^^^^ -note: candidate #2 is defined in an impl of the trait `Bar` 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:14:5 | 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 | LL | const X: i32 = ::ID; diff --git a/tests/ui/issues/issue-18446.stderr b/tests/ui/issues/issue-18446.stderr index d84c490df4d..08a9cfc644f 100644 --- a/tests/ui/issues/issue-18446.stderr +++ b/tests/ui/issues/issue-18446.stderr @@ -4,17 +4,17 @@ error[E0034]: multiple applicable items in scope LL | x.foo(); | ^^^ multiple `foo` found | -note: candidate #1 is defined in an impl for the type `(dyn T + 'a)` - --> $DIR/issue-18446.rs:9:5 - | -LL | fn foo(&self) {} - | ^^^^^^^^^^^^^ -note: candidate #2 is defined in the trait `T` +note: candidate #1 is defined in the trait `T` --> $DIR/issue-18446.rs:5:5 | 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); | ~~~~~~~~~~ diff --git a/tests/ui/issues/issue-3702-2.stderr b/tests/ui/issues/issue-3702-2.stderr index 4edca796f43..7ab6520a0ca 100644 --- a/tests/ui/issues/issue-3702-2.stderr +++ b/tests/ui/issues/issue-3702-2.stderr @@ -4,24 +4,24 @@ error[E0034]: multiple applicable items in scope LL | self.to_int() + other.to_int() | ^^^^^^ multiple `to_int` found | -note: candidate #1 is defined in an impl of the trait `ToPrimitive` 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` +note: candidate #1 is defined in an impl of the trait `Add` for the type `isize` --> $DIR/issue-3702-2.rs:14:5 | 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() - | ~~~~~~~~~~~~~~~~~~~~~~~~~~ -help: disambiguate the method for candidate #2 +LL | fn to_int(&self) -> isize { 0 } + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +help: disambiguate the method for candidate #1 | 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 diff --git a/tests/ui/methods/method-ambig-two-traits-cross-crate.stderr b/tests/ui/methods/method-ambig-two-traits-cross-crate.stderr index 0c775612bfb..0fc0c909ea8 100644 --- a/tests/ui/methods/method-ambig-two-traits-cross-crate.stderr +++ b/tests/ui/methods/method-ambig-two-traits-cross-crate.stderr @@ -4,20 +4,20 @@ error[E0034]: multiple applicable items in scope LL | fn main() { 1_usize.me(); } | ^^ multiple `me` found | - = note: candidate #1 is defined in an impl of the trait `Me` for the type `usize` -note: candidate #2 is defined in an impl of the trait `Me2` for the type `usize` +note: candidate #1 is defined in an impl of the trait `Me2` for the type `usize` --> $DIR/method-ambig-two-traits-cross-crate.rs:10:22 | 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 | -LL | fn main() { Me::me(&1_usize); } - | ~~~~~~~~~~~~~~~~ -help: disambiguate the method for candidate #2 - | 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 diff --git a/tests/ui/methods/method-ambig-two-traits-with-default-method.stderr b/tests/ui/methods/method-ambig-two-traits-with-default-method.stderr index 9da307436e9..b36ef77fb7e 100644 --- a/tests/ui/methods/method-ambig-two-traits-with-default-method.stderr +++ b/tests/ui/methods/method-ambig-two-traits-with-default-method.stderr @@ -4,23 +4,23 @@ error[E0034]: multiple applicable items in scope LL | 1_usize.method(); | ^^^^^^ multiple `method` found | -note: candidate #1 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) {} } - | ^^^^^^^^^^^^^^^^ -note: candidate #2 is defined in an impl of the trait `Bar` 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:6:13 | 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 | -LL | Foo::method(&1_usize); +LL | Bar::method(&1_usize); | ~~~~~~~~~~~~~~~~~~~~~ help: disambiguate the method for candidate #2 | -LL | Bar::method(&1_usize); +LL | Foo::method(&1_usize); | ~~~~~~~~~~~~~~~~~~~~~ error: aborting due to 1 previous error diff --git a/tests/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr b/tests/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr index 755179650bb..6159d87c73e 100644 --- a/tests/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr +++ b/tests/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr @@ -29,33 +29,33 @@ error[E0034]: multiple applicable items in scope LL | let z = x.foo(); | ^^^ multiple `foo` found | -note: candidate #1 is defined in an impl of the trait `X` for the type `T` - --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:45:9 +note: candidate #1 is defined in the trait `FinalFoo` + --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:59:5 | -LL | fn foo(self: Smaht) -> u64 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn foo(&self) -> u8; + | ^^^^^^^^^^^^^^^^^^^^ 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 | LL | fn foo(self) {} | ^^^^^^^^^^^^ -note: candidate #3 is defined in the trait `FinalFoo` - --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:59:5 +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:45:9 | -LL | fn foo(&self) -> u8; - | ^^^^^^^^^^^^^^^^^^^^ +LL | fn foo(self: Smaht) -> u64 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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 | LL | let z = NuisanceFoo::foo(x); | ~~~~~~~~~~~~~~~~~~~ help: disambiguate the method for candidate #3 | -LL | let z = FinalFoo::foo(&x); - | ~~~~~~~~~~~~~~~~~ +LL | let z = X::foo(x); + | ~~~~~~~~~ error[E0308]: mismatched types --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:139:24