Skip to content

Commit 0785167

Browse files
Point out the actual mismatch error
1 parent 8be12f4 commit 0785167

21 files changed

+52
-1
lines changed

compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs

+14-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// ignore-tidy-filelength :(
2+
13
mod ambiguity;
24
pub mod on_unimplemented;
35
pub mod suggestions;
@@ -1943,6 +1945,8 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
19431945
other: bool,
19441946
param_env: ty::ParamEnv<'tcx>,
19451947
) -> bool {
1948+
// If we have a single implementation, try to unify it with the trait ref
1949+
// that failed. This should uncover a better hint for what *is* implemented.
19461950
if let [single] = &impl_candidates {
19471951
if self.probe(|_| {
19481952
let ocx = ObligationCtxt::new(self);
@@ -1972,7 +1976,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
19721976
std::iter::zip(obligation_trait_ref.args, impl_trait_ref.args)
19731977
{
19741978
if let Err(terr) =
1975-
ocx.eq(&ObligationCause::dummy(), param_env, obligation_arg, impl_arg)
1979+
ocx.eq(&ObligationCause::dummy(), param_env, impl_arg, obligation_arg)
19761980
{
19771981
terrs.push(terr);
19781982
}
@@ -2000,6 +2004,15 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
20002004
(cand.self_ty().to_string(), Style::Highlight),
20012005
("`".to_string(), Style::NoStyle),
20022006
]);
2007+
2008+
if let [TypeError::Sorts(exp_found)] = &terrs[..] {
2009+
let exp_found = self.resolve_vars_if_possible(*exp_found);
2010+
err.help(format!(
2011+
"for that trait implementation, expected `{}`, found `{}`",
2012+
exp_found.expected, exp_found.found
2013+
));
2014+
}
2015+
20032016
true
20042017
}) {
20052018
return true;

tests/ui/generic-const-items/unsatisfied-bounds.stderr

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ LL | let () = K::<()>;
1717
| ^^ the trait `From<()>` is not implemented for `Infallible`
1818
|
1919
= help: the trait `From<!>` is implemented for `Infallible`
20+
= help: for that trait implementation, expected `!`, found `()`
2021
note: required by a bound in `K`
2122
--> $DIR/unsatisfied-bounds.rs:12:17
2223
|
@@ -48,6 +49,7 @@ LL | let _ = <() as Trait<&'static str>>::B::<()>;
4849
| ^^ the trait `From<()>` is not implemented for `Infallible`
4950
|
5051
= help: the trait `From<!>` is implemented for `Infallible`
52+
= help: for that trait implementation, expected `!`, found `()`
5153
note: required by a bound in `Trait::B`
5254
--> $DIR/unsatisfied-bounds.rs:21:21
5355
|

tests/ui/impl-trait/issues/issue-62742.stderr

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ LL | WrongImpl::<()>::foo(0i32);
4343
| ^^^^^^^^^^^^^^^ the trait `Raw<()>` is not implemented for `RawImpl<()>`
4444
|
4545
= help: the trait `Raw<[()]>` is implemented for `RawImpl<()>`
46+
= help: for that trait implementation, expected `[()]`, found `()`
4647
note: required by a bound in `SafeImpl`
4748
--> $DIR/issue-62742.rs:26:35
4849
|

tests/ui/indexing/index-help.stderr

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ LL | x[0i32];
66
|
77
= help: the trait `SliceIndex<[{integer}]>` is not implemented for `i32`
88
= help: the trait `SliceIndex<[{integer}]>` is implemented for `usize`
9+
= help: for that trait implementation, expected `usize`, found `i32`
910
= note: required for `Vec<{integer}>` to implement `Index<i32>`
1011

1112
error: aborting due to previous error

tests/ui/indexing/indexing-requires-a-uint.stderr

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ LL | [0][0u8];
66
|
77
= help: the trait `SliceIndex<[{integer}]>` is not implemented for `u8`
88
= help: the trait `SliceIndex<[{integer}]>` is implemented for `usize`
9+
= help: for that trait implementation, expected `usize`, found `u8`
910
= note: required for `[{integer}]` to implement `Index<u8>`
1011

1112
error[E0308]: mismatched types

tests/ui/integral-indexing.stderr

+8
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ LL | v[3u8];
66
|
77
= help: the trait `SliceIndex<[isize]>` is not implemented for `u8`
88
= help: the trait `SliceIndex<[isize]>` is implemented for `usize`
9+
= help: for that trait implementation, expected `usize`, found `u8`
910
= note: required for `Vec<isize>` to implement `Index<u8>`
1011

1112
error[E0277]: the type `[isize]` cannot be indexed by `i8`
@@ -16,6 +17,7 @@ LL | v[3i8];
1617
|
1718
= help: the trait `SliceIndex<[isize]>` is not implemented for `i8`
1819
= help: the trait `SliceIndex<[isize]>` is implemented for `usize`
20+
= help: for that trait implementation, expected `usize`, found `i8`
1921
= note: required for `Vec<isize>` to implement `Index<i8>`
2022

2123
error[E0277]: the type `[isize]` cannot be indexed by `u32`
@@ -26,6 +28,7 @@ LL | v[3u32];
2628
|
2729
= help: the trait `SliceIndex<[isize]>` is not implemented for `u32`
2830
= help: the trait `SliceIndex<[isize]>` is implemented for `usize`
31+
= help: for that trait implementation, expected `usize`, found `u32`
2932
= note: required for `Vec<isize>` to implement `Index<u32>`
3033

3134
error[E0277]: the type `[isize]` cannot be indexed by `i32`
@@ -36,6 +39,7 @@ LL | v[3i32];
3639
|
3740
= help: the trait `SliceIndex<[isize]>` is not implemented for `i32`
3841
= help: the trait `SliceIndex<[isize]>` is implemented for `usize`
42+
= help: for that trait implementation, expected `usize`, found `i32`
3943
= note: required for `Vec<isize>` to implement `Index<i32>`
4044

4145
error[E0277]: the type `[u8]` cannot be indexed by `u8`
@@ -46,6 +50,7 @@ LL | s.as_bytes()[3u8];
4650
|
4751
= help: the trait `SliceIndex<[u8]>` is not implemented for `u8`
4852
= help: the trait `SliceIndex<[u8]>` is implemented for `usize`
53+
= help: for that trait implementation, expected `usize`, found `u8`
4954
= note: required for `[u8]` to implement `Index<u8>`
5055

5156
error[E0277]: the type `[u8]` cannot be indexed by `i8`
@@ -56,6 +61,7 @@ LL | s.as_bytes()[3i8];
5661
|
5762
= help: the trait `SliceIndex<[u8]>` is not implemented for `i8`
5863
= help: the trait `SliceIndex<[u8]>` is implemented for `usize`
64+
= help: for that trait implementation, expected `usize`, found `i8`
5965
= note: required for `[u8]` to implement `Index<i8>`
6066

6167
error[E0277]: the type `[u8]` cannot be indexed by `u32`
@@ -66,6 +72,7 @@ LL | s.as_bytes()[3u32];
6672
|
6773
= help: the trait `SliceIndex<[u8]>` is not implemented for `u32`
6874
= help: the trait `SliceIndex<[u8]>` is implemented for `usize`
75+
= help: for that trait implementation, expected `usize`, found `u32`
6976
= note: required for `[u8]` to implement `Index<u32>`
7077

7178
error[E0277]: the type `[u8]` cannot be indexed by `i32`
@@ -76,6 +83,7 @@ LL | s.as_bytes()[3i32];
7683
|
7784
= help: the trait `SliceIndex<[u8]>` is not implemented for `i32`
7885
= help: the trait `SliceIndex<[u8]>` is implemented for `usize`
86+
= help: for that trait implementation, expected `usize`, found `i32`
7987
= note: required for `[u8]` to implement `Index<i32>`
8088

8189
error: aborting due to 8 previous errors

tests/ui/issues/issue-34334.stderr

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ LL | let sr2: Vec<(u32, _, _)> = sr.iter().map(|(faction, th_sender, th_rece
2020
|
2121
= help: the trait `FromIterator<()>` is not implemented for `Vec<(u32, _, _)>`
2222
= help: the trait `FromIterator<(u32, _, _)>` is implemented for `Vec<(u32, _, _)>`
23+
= help: for that trait implementation, expected `(u32, _, _)`, found `()`
2324
note: the method call chain might not have had the expected associated types
2425
--> $DIR/issue-34334.rs:5:43
2526
|

tests/ui/issues/issue-45801.stderr

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ LL | req.get_ref::<Params>();
55
| ^^^^^^^ the trait `Plugin<i32>` is not implemented for `Params`
66
|
77
= help: the trait `Plugin<Foo>` is implemented for `Params`
8+
= help: for that trait implementation, expected `Foo`, found `i32`
89

910
error: aborting due to previous error
1011

tests/ui/issues/issue-66923-show-error-for-correct-call.stderr

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ LL | let x2: Vec<f64> = x1.into_iter().collect();
66
|
77
= help: the trait `FromIterator<&f64>` is not implemented for `Vec<f64>`
88
= help: the trait `FromIterator<f64>` is implemented for `Vec<f64>`
9+
= help: for that trait implementation, expected `f64`, found `&f64`
910
note: the method call chain might not have had the expected associated types
1011
--> $DIR/issue-66923-show-error-for-correct-call.rs:8:27
1112
|
@@ -26,6 +27,7 @@ LL | let x3 = x1.into_iter().collect::<Vec<f64>>();
2627
|
2728
= help: the trait `FromIterator<&f64>` is not implemented for `Vec<f64>`
2829
= help: the trait `FromIterator<f64>` is implemented for `Vec<f64>`
30+
= help: for that trait implementation, expected `f64`, found `&f64`
2931
note: the method call chain might not have had the expected associated types
3032
--> $DIR/issue-66923-show-error-for-correct-call.rs:12:17
3133
|

tests/ui/iterators/invalid-iterator-chain.stderr

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ LL | i.collect()
66
|
77
= help: the trait `FromIterator<&X>` is not implemented for `Vec<X>`
88
= help: the trait `FromIterator<X>` is implemented for `Vec<X>`
9+
= help: for that trait implementation, expected `X`, found `&X`
910
note: the method call chain might not have had the expected associated types
1011
--> $DIR/invalid-iterator-chain.rs:4:26
1112
|
@@ -160,6 +161,7 @@ LL | let g: Vec<i32> = f.collect();
160161
|
161162
= help: the trait `FromIterator<()>` is not implemented for `Vec<i32>`
162163
= help: the trait `FromIterator<i32>` is implemented for `Vec<i32>`
164+
= help: for that trait implementation, expected `i32`, found `()`
163165
note: the method call chain might not have had the expected associated types
164166
--> $DIR/invalid-iterator-chain.rs:44:15
165167
|

tests/ui/never_type/never-value-fallback-issue-66757.nofallback.stderr

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ LL | <E as From<_>>::from(never);
55
| ^ the trait `From<()>` is not implemented for `E`
66
|
77
= help: the trait `From<!>` is implemented for `E`
8+
= help: for that trait implementation, expected `!`, found `()`
89

910
error: aborting due to previous error
1011

tests/ui/on-unimplemented/impl-substs.stderr

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ LL | Foo::<usize>::foo((1i32, 1i32, 1i32));
88
|
99
= help: the trait `Foo<usize>` is not implemented for `(i32, i32, i32)`
1010
= help: the trait `Foo<i32>` is implemented for `(i32, i32, i32)`
11+
= help: for that trait implementation, expected `i32`, found `usize`
1112

1213
error: aborting due to previous error
1314

tests/ui/on-unimplemented/on-impl.stderr

+3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ LL | Index::<u32>::index(&[1, 2, 3] as &[i32], 2u32);
88
|
99
= help: the trait `Index<u32>` is not implemented for `[i32]`
1010
= help: the trait `Index<usize>` is implemented for `[i32]`
11+
= help: for that trait implementation, expected `usize`, found `u32`
1112

1213
error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
1314
--> $DIR/on-impl.rs:22:5
@@ -17,6 +18,7 @@ LL | Index::<u32>::index(&[1, 2, 3] as &[i32], 2u32);
1718
|
1819
= help: the trait `Index<u32>` is not implemented for `[i32]`
1920
= help: the trait `Index<usize>` is implemented for `[i32]`
21+
= help: for that trait implementation, expected `usize`, found `u32`
2022

2123
error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
2224
--> $DIR/on-impl.rs:22:5
@@ -26,6 +28,7 @@ LL | Index::<u32>::index(&[1, 2, 3] as &[i32], 2u32);
2628
|
2729
= help: the trait `Index<u32>` is not implemented for `[i32]`
2830
= help: the trait `Index<usize>` is implemented for `[i32]`
31+
= help: for that trait implementation, expected `usize`, found `u32`
2932

3033
error: aborting due to 3 previous errors
3134

tests/ui/on-unimplemented/slice-index.stderr

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ LL | x[1i32];
66
|
77
= help: the trait `SliceIndex<[i32]>` is not implemented for `i32`
88
= help: the trait `SliceIndex<[i32]>` is implemented for `usize`
9+
= help: for that trait implementation, expected `usize`, found `i32`
910
= note: required for `[i32]` to implement `Index<i32>`
1011

1112
error[E0277]: the type `[i32]` cannot be indexed by `RangeTo<i32>`

tests/ui/str/str-idx.stderr

+3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ LL | let _: u8 = s[4];
88
= note: you can use `.chars().nth()` or `.bytes().nth()`
99
for more information, see chapter 8 in The Book: <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>
1010
= help: the trait `SliceIndex<[_]>` is implemented for `usize`
11+
= help: for that trait implementation, expected `[_]`, found `str`
1112
= note: required for `str` to implement `Index<{integer}>`
1213

1314
error[E0277]: the type `str` cannot be indexed by `{integer}`
@@ -22,6 +23,7 @@ LL | let _ = s.get(4);
2223
= note: you can use `.chars().nth()` or `.bytes().nth()`
2324
for more information, see chapter 8 in The Book: <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>
2425
= help: the trait `SliceIndex<[_]>` is implemented for `usize`
26+
= help: for that trait implementation, expected `[_]`, found `str`
2527
note: required by a bound in `core::str::<impl str>::get`
2628
--> $SRC_DIR/core/src/str/mod.rs:LL:COL
2729

@@ -37,6 +39,7 @@ LL | let _ = s.get_unchecked(4);
3739
= note: you can use `.chars().nth()` or `.bytes().nth()`
3840
for more information, see chapter 8 in The Book: <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>
3941
= help: the trait `SliceIndex<[_]>` is implemented for `usize`
42+
= help: for that trait implementation, expected `[_]`, found `str`
4043
note: required by a bound in `core::str::<impl str>::get_unchecked`
4144
--> $SRC_DIR/core/src/str/mod.rs:LL:COL
4245

tests/ui/str/str-mut-idx.stderr

+3
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ LL | s[1usize] = bot();
3232
|
3333
= help: the trait `SliceIndex<str>` is not implemented for `usize`
3434
= help: the trait `SliceIndex<[_]>` is implemented for `usize`
35+
= help: for that trait implementation, expected `[_]`, found `str`
3536
= note: required for `str` to implement `Index<usize>`
3637

3738
error[E0277]: the type `str` cannot be indexed by `{integer}`
@@ -46,6 +47,7 @@ LL | s.get_mut(1);
4647
= note: you can use `.chars().nth()` or `.bytes().nth()`
4748
for more information, see chapter 8 in The Book: <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>
4849
= help: the trait `SliceIndex<[_]>` is implemented for `usize`
50+
= help: for that trait implementation, expected `[_]`, found `str`
4951
note: required by a bound in `core::str::<impl str>::get_mut`
5052
--> $SRC_DIR/core/src/str/mod.rs:LL:COL
5153

@@ -61,6 +63,7 @@ LL | s.get_unchecked_mut(1);
6163
= note: you can use `.chars().nth()` or `.bytes().nth()`
6264
for more information, see chapter 8 in The Book: <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>
6365
= help: the trait `SliceIndex<[_]>` is implemented for `usize`
66+
= help: for that trait implementation, expected `[_]`, found `str`
6467
note: required by a bound in `core::str::<impl str>::get_unchecked_mut`
6568
--> $SRC_DIR/core/src/str/mod.rs:LL:COL
6669

tests/ui/suggestions/issue-101623.stderr

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ LL | Trait::do_stuff({ fun(&mut *inner) });
88
| required by a bound introduced by this call
99
|
1010
= help: the trait `Trait<'_>` is implemented for `()`
11+
= help: for that trait implementation, expected `()`, found `*mut ()`
1112

1213
error: aborting due to previous error
1314

tests/ui/suggestions/suggest-dereferencing-index.stderr

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ LL | let one_item_please: i32 = [1, 2, 3][i];
66
|
77
= help: the trait `SliceIndex<[{integer}]>` is not implemented for `&usize`
88
= help: the trait `SliceIndex<[{integer}]>` is implemented for `usize`
9+
= help: for that trait implementation, expected `usize`, found `&usize`
910
= note: required for `[{integer}]` to implement `Index<&usize>`
1011
help: dereference this index
1112
|

tests/ui/traits/coercion-generic-bad.stderr

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ LL | let s: Box<dyn Trait<isize>> = Box::new(Struct { person: "Fred" });
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait<isize>` is not implemented for `Struct`
66
|
77
= help: the trait `Trait<&'static str>` is implemented for `Struct`
8+
= help: for that trait implementation, expected `&'static str`, found `isize`
89
= note: required for the cast from `Box<Struct>` to `Box<dyn Trait<isize>>`
910

1011
error: aborting due to previous error

tests/ui/try-block/try-block-bad-type.stderr

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ LL | Err("")?;
66
|
77
= note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
88
= help: the trait `From<Infallible>` is implemented for `TryFromSliceError`
9+
= help: for that trait implementation, expected `Infallible`, found `&str`
910
= note: required for `Result<u32, TryFromSliceError>` to implement `FromResidual<Result<Infallible, &str>>`
1011

1112
error[E0271]: type mismatch resolving `<Result<i32, i32> as Try>::Output == &str`

tests/ui/try-trait/bad-interconversion.stderr

+3
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ LL | ControlFlow::Continue(Err("hello")?)
7474
|
7575
= help: the trait `FromResidual<Result<Infallible, &str>>` is not implemented for `ControlFlow<String>`
7676
= help: the trait `FromResidual<ControlFlow<String, Infallible>>` is implemented for `ControlFlow<String>`
77+
= help: for that trait implementation, expected `ControlFlow<String, Infallible>`, found `Result<Infallible, &str>`
7778

7879
error[E0277]: the `?` operator can only be used on `ControlFlow`s in a function that returns `ControlFlow`
7980
--> $DIR/bad-interconversion.rs:37:12
@@ -85,6 +86,7 @@ LL | Some(3)?;
8586
|
8687
= help: the trait `FromResidual<Option<Infallible>>` is not implemented for `ControlFlow<u64>`
8788
= help: the trait `FromResidual<ControlFlow<u64, Infallible>>` is implemented for `ControlFlow<u64>`
89+
= help: for that trait implementation, expected `ControlFlow<u64, Infallible>`, found `Option<Infallible>`
8890

8991
error[E0277]: the `?` operator in a function that returns `ControlFlow<B, _>` can only be used on other `ControlFlow<B, _>`s (with the same Break type)
9092
--> $DIR/bad-interconversion.rs:43:29
@@ -97,6 +99,7 @@ LL | ControlFlow::Break(4_u8)?;
9799
= help: the trait `FromResidual<ControlFlow<u8, Infallible>>` is not implemented for `ControlFlow<i64>`
98100
= note: unlike `Result`, there's no `From`-conversion performed for `ControlFlow`
99101
= help: the trait `FromResidual<ControlFlow<i64, Infallible>>` is implemented for `ControlFlow<i64>`
102+
= help: for that trait implementation, expected `i64`, found `u8`
100103

101104
error: aborting due to 8 previous errors
102105

0 commit comments

Comments
 (0)