Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2299,6 +2299,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
// FIXME: this could use a better heuristic, like just checking
// that args[1..] is the same.
let all_traits_equal = traits.len() == 1;
let mut types: Vec<_> =
candidates.iter().map(|(c, _)| c.self_ty().to_string()).collect();
types.sort();
types.dedup();
let all_types_equal = types.len() == 1;

let end = if candidates.len() <= 9 || self.tcx.sess.opts.verbose {
candidates.len()
Expand All @@ -2312,6 +2317,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
for (c, def_id) in &candidates {
let msg = if all_traits_equal {
format!("`{}`", self.tcx.short_string(c.self_ty(), err.long_ty_path()))
} else if all_types_equal {
format!(
"`{}`",
self.tcx.short_string(c.print_only_trait_path(), err.long_ty_path())
)
} else {
format!(
"`{}` implements `{}`",
Expand All @@ -2321,13 +2331,19 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
};
span.push_span_label(self.tcx.def_span(*def_id), msg);
}
err.span_help(
span,
let msg = if all_types_equal {
format!(
"`{}` implements trait `{}`",
self.tcx.short_string(candidates[0].0.self_ty(), err.long_ty_path()),
self.tcx.short_string(trait_ref.print_trait_sugared(), err.long_ty_path()),
)
} else {
format!(
"the following {other}types implement trait `{}`",
trait_ref.print_trait_sugared(),
),
);
self.tcx.short_string(trait_ref.print_trait_sugared(), err.long_ty_path()),
)
};
err.span_help(span, msg);
} else {
let candidate_names: Vec<String> = candidates
.iter()
Expand All @@ -2337,6 +2353,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
"\n {}",
self.tcx.short_string(c.self_ty(), err.long_ty_path())
)
} else if all_types_equal {
format!(
"\n {}",
self.tcx
.short_string(c.print_only_trait_path(), err.long_ty_path())
)
} else {
format!(
"\n `{}` implements `{}`",
Expand All @@ -2347,9 +2369,21 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
}
})
.collect();
let msg = if all_types_equal {
format!(
"`{}` implements trait `{}`",
self.tcx.short_string(candidates[0].0.self_ty(), err.long_ty_path()),
self.tcx.short_string(trait_ref.print_trait_sugared(), err.long_ty_path()),
)
} else {
format!(
"the following {other}types implement trait `{}`",
self.tcx.short_string(trait_ref.print_trait_sugared(), err.long_ty_path()),
)
};

err.help(format!(
"the following {other}types implement trait `{}`:{}{}",
trait_ref.print_trait_sugared(),
"{msg}:{}{}",
candidate_names[..end].join(""),
if candidates.len() > 9 && !self.tcx.sess.opts.verbose {
format!("\nand {} others", candidates.len() - 8)
Expand Down
6 changes: 3 additions & 3 deletions tests/run-make/crate-loading/multiple-dep-versions.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -177,14 +177,14 @@ LL | Err(Error2)?;
| this can't be annotated with `?` because it has type `Result<_, Error2>`
|
= note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
help: the following other types implement trait `From<T>`
help: `dependency::OtherError` implements trait `From<T>`
--> replaced
|
LL | impl From<()> for OtherError {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dependency::OtherError` implements `From<()>`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `From<()>`
...
LL | impl From<i32> for OtherError {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dependency::OtherError` implements `From<i32>`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `From<i32>`
= note: there are multiple different versions of crate `dependency` in the dependency graph
= help: you can use `cargo tree` to explore your dependency tree

Expand Down
18 changes: 9 additions & 9 deletions tests/ui/const-generics/exhaustive-value.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ error[E0277]: the trait bound `(): Foo<N>` is not satisfied
LL | <() as Foo<N>>::test()
| ^^ the trait `Foo<N>` is not implemented for `()`
|
= help: the following other types implement trait `Foo<N>`:
`()` implements `Foo<0>`
`()` implements `Foo<100>`
`()` implements `Foo<101>`
`()` implements `Foo<102>`
`()` implements `Foo<103>`
`()` implements `Foo<104>`
`()` implements `Foo<105>`
`()` implements `Foo<106>`
= help: `()` implements trait `Foo<N>`:
Foo<0>
Foo<100>
Foo<101>
Foo<102>
Foo<103>
Foo<104>
Foo<105>
Foo<106>
and 248 others

error: aborting due to 1 previous error
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ help: the trait `Foo<usize>` is not implemented for `Bar`
|
LL | struct Bar;
| ^^^^^^^^^^
help: the following other types implement trait `Foo<A>`
help: `Bar` implements trait `Foo<A>`
--> $DIR/issue-21659-show-relevant-trait-impls-1.rs:15:1
|
LL | impl Foo<i32> for Bar {}
| ^^^^^^^^^^^^^^^^^^^^^ `Bar` implements `Foo<i32>`
| ^^^^^^^^^^^^^^^^^^^^^ `Foo<i32>`
LL |
LL | impl Foo<u8> for Bar {}
| ^^^^^^^^^^^^^^^^^^^^ `Bar` implements `Foo<u8>`
| ^^^^^^^^^^^^^^^^^^^^ `Foo<u8>`

error: aborting due to 1 previous error

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ help: the trait `Foo<usize>` is not implemented for `Bar`
|
LL | struct Bar;
| ^^^^^^^^^^
= help: the following other types implement trait `Foo<A>`:
`Bar` implements `Foo<i16>`
`Bar` implements `Foo<i32>`
`Bar` implements `Foo<i8>`
`Bar` implements `Foo<u16>`
`Bar` implements `Foo<u32>`
`Bar` implements `Foo<u8>`
= help: `Bar` implements trait `Foo<A>`:
Foo<i16>
Foo<i32>
Foo<i8>
Foo<u16>
Foo<u32>
Foo<u8>

error: aborting due to 1 previous error

Expand Down
36 changes: 18 additions & 18 deletions tests/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ LL | Foo::<i32>::bar(&1i8);
| |
| required by a bound introduced by this call
|
= help: the following other types implement trait `Foo<B>`:
`i8` implements `Foo<bool>`
`i8` implements `Foo<u16>`
`i8` implements `Foo<u32>`
`i8` implements `Foo<u64>`
`i8` implements `Foo<u8>`
= help: `i8` implements trait `Foo<B>`:
Foo<bool>
Foo<u16>
Foo<u32>
Foo<u64>
Foo<u8>

error[E0277]: the trait bound `u8: Foo<i32>` is not satisfied
--> $DIR/issue-39802-show-5-trait-impls.rs:25:21
Expand All @@ -21,17 +21,17 @@ LL | Foo::<i32>::bar(&1u8);
| |
| required by a bound introduced by this call
|
help: the following other types implement trait `Foo<B>`
help: `u8` implements trait `Foo<B>`
--> $DIR/issue-39802-show-5-trait-impls.rs:11:1
|
LL | impl Foo<u16> for u8 {}
| ^^^^^^^^^^^^^^^^^^^^ `u8` implements `Foo<u16>`
| ^^^^^^^^^^^^^^^^^^^^ `Foo<u16>`
LL | impl Foo<u32> for u8 {}
| ^^^^^^^^^^^^^^^^^^^^ `u8` implements `Foo<u32>`
| ^^^^^^^^^^^^^^^^^^^^ `Foo<u32>`
LL | impl Foo<u64> for u8 {}
| ^^^^^^^^^^^^^^^^^^^^ `u8` implements `Foo<u64>`
| ^^^^^^^^^^^^^^^^^^^^ `Foo<u64>`
LL | impl Foo<bool> for u8 {}
| ^^^^^^^^^^^^^^^^^^^^^ `u8` implements `Foo<bool>`
| ^^^^^^^^^^^^^^^^^^^^^ `Foo<bool>`

error[E0277]: the trait bound `bool: Foo<i32>` is not satisfied
--> $DIR/issue-39802-show-5-trait-impls.rs:26:21
Expand All @@ -41,13 +41,13 @@ LL | Foo::<i32>::bar(&true);
| |
| required by a bound introduced by this call
|
= help: the following other types implement trait `Foo<B>`:
`bool` implements `Foo<bool>`
`bool` implements `Foo<i8>`
`bool` implements `Foo<u16>`
`bool` implements `Foo<u32>`
`bool` implements `Foo<u64>`
`bool` implements `Foo<u8>`
= help: `bool` implements trait `Foo<B>`:
Foo<bool>
Foo<i8>
Foo<u16>
Foo<u32>
Foo<u64>
Foo<u8>

error: aborting due to 3 previous errors

Expand Down
6 changes: 3 additions & 3 deletions tests/ui/indexing/index-help.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ LL | x[0i32];
| ^^^^ slice indices are of type `usize` or ranges of `usize`
|
= help: the trait `SliceIndex<[{integer}]>` is not implemented for `i32`
help: the following other types implement trait `SliceIndex<T>`
help: `usize` implements trait `SliceIndex<T>`
--> $SRC_DIR/core/src/slice/index.rs:LL:COL
|
= note: `usize` implements `SliceIndex<[T]>`
= note: `SliceIndex<[T]>`
--> $SRC_DIR/core/src/bstr/traits.rs:LL:COL
|
= note: `usize` implements `SliceIndex<ByteStr>`
= note: `SliceIndex<ByteStr>`
= note: required for `Vec<{integer}>` to implement `Index<i32>`

error: aborting due to 1 previous error
Expand Down
48 changes: 24 additions & 24 deletions tests/ui/indexing/indexing-integral-types.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ LL | v[3u8];
| ^^^ slice indices are of type `usize` or ranges of `usize`
|
= help: the trait `SliceIndex<[isize]>` is not implemented for `u8`
help: the following other types implement trait `SliceIndex<T>`
help: `usize` implements trait `SliceIndex<T>`
--> $SRC_DIR/core/src/slice/index.rs:LL:COL
|
= note: `usize` implements `SliceIndex<[T]>`
= note: `SliceIndex<[T]>`
--> $SRC_DIR/core/src/bstr/traits.rs:LL:COL
|
= note: `usize` implements `SliceIndex<ByteStr>`
= note: `SliceIndex<ByteStr>`
= note: required for `Vec<isize>` to implement `Index<u8>`

error[E0277]: the type `[isize]` cannot be indexed by `i8`
Expand All @@ -21,13 +21,13 @@ LL | v[3i8];
| ^^^ slice indices are of type `usize` or ranges of `usize`
|
= help: the trait `SliceIndex<[isize]>` is not implemented for `i8`
help: the following other types implement trait `SliceIndex<T>`
help: `usize` implements trait `SliceIndex<T>`
--> $SRC_DIR/core/src/slice/index.rs:LL:COL
|
= note: `usize` implements `SliceIndex<[T]>`
= note: `SliceIndex<[T]>`
--> $SRC_DIR/core/src/bstr/traits.rs:LL:COL
|
= note: `usize` implements `SliceIndex<ByteStr>`
= note: `SliceIndex<ByteStr>`
= note: required for `Vec<isize>` to implement `Index<i8>`

error[E0277]: the type `[isize]` cannot be indexed by `u32`
Expand All @@ -37,13 +37,13 @@ LL | v[3u32];
| ^^^^ slice indices are of type `usize` or ranges of `usize`
|
= help: the trait `SliceIndex<[isize]>` is not implemented for `u32`
help: the following other types implement trait `SliceIndex<T>`
help: `usize` implements trait `SliceIndex<T>`
--> $SRC_DIR/core/src/slice/index.rs:LL:COL
|
= note: `usize` implements `SliceIndex<[T]>`
= note: `SliceIndex<[T]>`
--> $SRC_DIR/core/src/bstr/traits.rs:LL:COL
|
= note: `usize` implements `SliceIndex<ByteStr>`
= note: `SliceIndex<ByteStr>`
= note: required for `Vec<isize>` to implement `Index<u32>`

error[E0277]: the type `[isize]` cannot be indexed by `i32`
Expand All @@ -53,13 +53,13 @@ LL | v[3i32];
| ^^^^ slice indices are of type `usize` or ranges of `usize`
|
= help: the trait `SliceIndex<[isize]>` is not implemented for `i32`
help: the following other types implement trait `SliceIndex<T>`
help: `usize` implements trait `SliceIndex<T>`
--> $SRC_DIR/core/src/slice/index.rs:LL:COL
|
= note: `usize` implements `SliceIndex<[T]>`
= note: `SliceIndex<[T]>`
--> $SRC_DIR/core/src/bstr/traits.rs:LL:COL
|
= note: `usize` implements `SliceIndex<ByteStr>`
= note: `SliceIndex<ByteStr>`
= note: required for `Vec<isize>` to implement `Index<i32>`

error[E0277]: the type `[u8]` cannot be indexed by `u8`
Expand All @@ -69,13 +69,13 @@ LL | s.as_bytes()[3u8];
| ^^^ slice indices are of type `usize` or ranges of `usize`
|
= help: the trait `SliceIndex<[u8]>` is not implemented for `u8`
help: the following other types implement trait `SliceIndex<T>`
help: `usize` implements trait `SliceIndex<T>`
--> $SRC_DIR/core/src/slice/index.rs:LL:COL
|
= note: `usize` implements `SliceIndex<[T]>`
= note: `SliceIndex<[T]>`
--> $SRC_DIR/core/src/bstr/traits.rs:LL:COL
|
= note: `usize` implements `SliceIndex<ByteStr>`
= note: `SliceIndex<ByteStr>`
= note: required for `[u8]` to implement `Index<u8>`

error[E0277]: the type `[u8]` cannot be indexed by `i8`
Expand All @@ -85,13 +85,13 @@ LL | s.as_bytes()[3i8];
| ^^^ slice indices are of type `usize` or ranges of `usize`
|
= help: the trait `SliceIndex<[u8]>` is not implemented for `i8`
help: the following other types implement trait `SliceIndex<T>`
help: `usize` implements trait `SliceIndex<T>`
--> $SRC_DIR/core/src/slice/index.rs:LL:COL
|
= note: `usize` implements `SliceIndex<[T]>`
= note: `SliceIndex<[T]>`
--> $SRC_DIR/core/src/bstr/traits.rs:LL:COL
|
= note: `usize` implements `SliceIndex<ByteStr>`
= note: `SliceIndex<ByteStr>`
= note: required for `[u8]` to implement `Index<i8>`

error[E0277]: the type `[u8]` cannot be indexed by `u32`
Expand All @@ -101,13 +101,13 @@ LL | s.as_bytes()[3u32];
| ^^^^ slice indices are of type `usize` or ranges of `usize`
|
= help: the trait `SliceIndex<[u8]>` is not implemented for `u32`
help: the following other types implement trait `SliceIndex<T>`
help: `usize` implements trait `SliceIndex<T>`
--> $SRC_DIR/core/src/slice/index.rs:LL:COL
|
= note: `usize` implements `SliceIndex<[T]>`
= note: `SliceIndex<[T]>`
--> $SRC_DIR/core/src/bstr/traits.rs:LL:COL
|
= note: `usize` implements `SliceIndex<ByteStr>`
= note: `SliceIndex<ByteStr>`
= note: required for `[u8]` to implement `Index<u32>`

error[E0277]: the type `[u8]` cannot be indexed by `i32`
Expand All @@ -117,13 +117,13 @@ LL | s.as_bytes()[3i32];
| ^^^^ slice indices are of type `usize` or ranges of `usize`
|
= help: the trait `SliceIndex<[u8]>` is not implemented for `i32`
help: the following other types implement trait `SliceIndex<T>`
help: `usize` implements trait `SliceIndex<T>`
--> $SRC_DIR/core/src/slice/index.rs:LL:COL
|
= note: `usize` implements `SliceIndex<[T]>`
= note: `SliceIndex<[T]>`
--> $SRC_DIR/core/src/bstr/traits.rs:LL:COL
|
= note: `usize` implements `SliceIndex<ByteStr>`
= note: `SliceIndex<ByteStr>`
= note: required for `[u8]` to implement `Index<i32>`

error: aborting due to 8 previous errors
Expand Down
Loading
Loading