diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 62c105b60b6e1..fb145d680d258 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1,3 +1,5 @@ +// ignore-tidy-filelength :( + mod ambiguity; pub mod on_unimplemented; pub mod suggestions; @@ -1941,6 +1943,8 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { other: bool, param_env: ty::ParamEnv<'tcx>, ) -> bool { + // If we have a single implementation, try to unify it with the trait ref + // that failed. This should uncover a better hint for what *is* implemented. if let [single] = &impl_candidates { if self.probe(|_| { let ocx = ObligationCtxt::new(self); @@ -1970,7 +1974,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { std::iter::zip(obligation_trait_ref.args, impl_trait_ref.args) { if let Err(terr) = - ocx.eq(&ObligationCause::dummy(), param_env, obligation_arg, impl_arg) + ocx.eq(&ObligationCause::dummy(), param_env, impl_arg, obligation_arg) { terrs.push(terr); } @@ -1998,6 +2002,15 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { (cand.self_ty().to_string(), Style::Highlight), ("`".to_string(), Style::NoStyle), ]); + + if let [TypeError::Sorts(exp_found)] = &terrs[..] { + let exp_found = self.resolve_vars_if_possible(*exp_found); + err.help(format!( + "... for that trait implementation, expected `{}`, found `{}`", + exp_found.expected, exp_found.found + )); + } + true }) { return true; diff --git a/tests/ui/generic-const-items/unsatisfied-bounds.stderr b/tests/ui/generic-const-items/unsatisfied-bounds.stderr index 2cee53431a42e..cc2b004b0171a 100644 --- a/tests/ui/generic-const-items/unsatisfied-bounds.stderr +++ b/tests/ui/generic-const-items/unsatisfied-bounds.stderr @@ -17,6 +17,7 @@ LL | let () = K::<()>; | ^^ the trait `From<()>` is not implemented for `Infallible` | = help: the trait `From` is implemented for `Infallible` + = help: ... for that trait implementation, expected `!`, found `()` note: required by a bound in `K` --> $DIR/unsatisfied-bounds.rs:12:17 | @@ -48,6 +49,7 @@ LL | let _ = <() as Trait<&'static str>>::B::<()>; | ^^ the trait `From<()>` is not implemented for `Infallible` | = help: the trait `From` is implemented for `Infallible` + = help: ... for that trait implementation, expected `!`, found `()` note: required by a bound in `Trait::B` --> $DIR/unsatisfied-bounds.rs:21:21 | diff --git a/tests/ui/impl-trait/issues/issue-62742.stderr b/tests/ui/impl-trait/issues/issue-62742.stderr index 7592a85068297..b877efdfc883a 100644 --- a/tests/ui/impl-trait/issues/issue-62742.stderr +++ b/tests/ui/impl-trait/issues/issue-62742.stderr @@ -43,6 +43,7 @@ LL | WrongImpl::<()>::foo(0i32); | ^^^^^^^^^^^^^^^ the trait `Raw<()>` is not implemented for `RawImpl<()>` | = help: the trait `Raw<[()]>` is implemented for `RawImpl<()>` + = help: ... for that trait implementation, expected `[()]`, found `()` note: required by a bound in `SafeImpl` --> $DIR/issue-62742.rs:26:35 | diff --git a/tests/ui/indexing/index-help.stderr b/tests/ui/indexing/index-help.stderr index d3310ceb0537a..a7dde43f6ad29 100644 --- a/tests/ui/indexing/index-help.stderr +++ b/tests/ui/indexing/index-help.stderr @@ -6,6 +6,7 @@ LL | x[0i32]; | = help: the trait `SliceIndex<[{integer}]>` is not implemented for `i32` = help: the trait `SliceIndex<[{integer}]>` is implemented for `usize` + = help: ... for that trait implementation, expected `usize`, found `i32` = note: required for `Vec<{integer}>` to implement `Index` error: aborting due to previous error diff --git a/tests/ui/indexing/indexing-requires-a-uint.stderr b/tests/ui/indexing/indexing-requires-a-uint.stderr index fcfac3a5e93e7..3e45dce878890 100644 --- a/tests/ui/indexing/indexing-requires-a-uint.stderr +++ b/tests/ui/indexing/indexing-requires-a-uint.stderr @@ -6,6 +6,7 @@ LL | [0][0u8]; | = help: the trait `SliceIndex<[{integer}]>` is not implemented for `u8` = help: the trait `SliceIndex<[{integer}]>` is implemented for `usize` + = help: ... for that trait implementation, expected `usize`, found `u8` = note: required for `[{integer}]` to implement `Index` error[E0308]: mismatched types diff --git a/tests/ui/integral-indexing.stderr b/tests/ui/integral-indexing.stderr index b7d80565a1e61..c7ae3e6bc0335 100644 --- a/tests/ui/integral-indexing.stderr +++ b/tests/ui/integral-indexing.stderr @@ -6,6 +6,7 @@ LL | v[3u8]; | = help: the trait `SliceIndex<[isize]>` is not implemented for `u8` = help: the trait `SliceIndex<[isize]>` is implemented for `usize` + = help: ... for that trait implementation, expected `usize`, found `u8` = note: required for `Vec` to implement `Index` error[E0277]: the type `[isize]` cannot be indexed by `i8` @@ -16,6 +17,7 @@ LL | v[3i8]; | = help: the trait `SliceIndex<[isize]>` is not implemented for `i8` = help: the trait `SliceIndex<[isize]>` is implemented for `usize` + = help: ... for that trait implementation, expected `usize`, found `i8` = note: required for `Vec` to implement `Index` error[E0277]: the type `[isize]` cannot be indexed by `u32` @@ -26,6 +28,7 @@ LL | v[3u32]; | = help: the trait `SliceIndex<[isize]>` is not implemented for `u32` = help: the trait `SliceIndex<[isize]>` is implemented for `usize` + = help: ... for that trait implementation, expected `usize`, found `u32` = note: required for `Vec` to implement `Index` error[E0277]: the type `[isize]` cannot be indexed by `i32` @@ -36,6 +39,7 @@ LL | v[3i32]; | = help: the trait `SliceIndex<[isize]>` is not implemented for `i32` = help: the trait `SliceIndex<[isize]>` is implemented for `usize` + = help: ... for that trait implementation, expected `usize`, found `i32` = note: required for `Vec` to implement `Index` error[E0277]: the type `[u8]` cannot be indexed by `u8` @@ -46,6 +50,7 @@ LL | s.as_bytes()[3u8]; | = help: the trait `SliceIndex<[u8]>` is not implemented for `u8` = help: the trait `SliceIndex<[u8]>` is implemented for `usize` + = help: ... for that trait implementation, expected `usize`, found `u8` = note: required for `[u8]` to implement `Index` error[E0277]: the type `[u8]` cannot be indexed by `i8` @@ -56,6 +61,7 @@ LL | s.as_bytes()[3i8]; | = help: the trait `SliceIndex<[u8]>` is not implemented for `i8` = help: the trait `SliceIndex<[u8]>` is implemented for `usize` + = help: ... for that trait implementation, expected `usize`, found `i8` = note: required for `[u8]` to implement `Index` error[E0277]: the type `[u8]` cannot be indexed by `u32` @@ -66,6 +72,7 @@ LL | s.as_bytes()[3u32]; | = help: the trait `SliceIndex<[u8]>` is not implemented for `u32` = help: the trait `SliceIndex<[u8]>` is implemented for `usize` + = help: ... for that trait implementation, expected `usize`, found `u32` = note: required for `[u8]` to implement `Index` error[E0277]: the type `[u8]` cannot be indexed by `i32` @@ -76,6 +83,7 @@ LL | s.as_bytes()[3i32]; | = help: the trait `SliceIndex<[u8]>` is not implemented for `i32` = help: the trait `SliceIndex<[u8]>` is implemented for `usize` + = help: ... for that trait implementation, expected `usize`, found `i32` = note: required for `[u8]` to implement `Index` error: aborting due to 8 previous errors diff --git a/tests/ui/issues/issue-34334.stderr b/tests/ui/issues/issue-34334.stderr index bacae965eed83..bb33951a08d98 100644 --- a/tests/ui/issues/issue-34334.stderr +++ b/tests/ui/issues/issue-34334.stderr @@ -20,6 +20,7 @@ LL | let sr2: Vec<(u32, _, _)> = sr.iter().map(|(faction, th_sender, th_rece | = help: the trait `FromIterator<()>` is not implemented for `Vec<(u32, _, _)>` = help: the trait `FromIterator<(u32, _, _)>` is implemented for `Vec<(u32, _, _)>` + = help: ... for that trait implementation, expected `(u32, _, _)`, found `()` note: the method call chain might not have had the expected associated types --> $DIR/issue-34334.rs:5:43 | diff --git a/tests/ui/issues/issue-45801.stderr b/tests/ui/issues/issue-45801.stderr index 8967f49df02a5..056180158134e 100644 --- a/tests/ui/issues/issue-45801.stderr +++ b/tests/ui/issues/issue-45801.stderr @@ -5,6 +5,7 @@ LL | req.get_ref::(); | ^^^^^^^ the trait `Plugin` is not implemented for `Params` | = help: the trait `Plugin` is implemented for `Params` + = help: ... for that trait implementation, expected `Foo`, found `i32` error: aborting due to previous error diff --git a/tests/ui/issues/issue-66923-show-error-for-correct-call.stderr b/tests/ui/issues/issue-66923-show-error-for-correct-call.stderr index 48cd549cb3344..d3f7185e89ae2 100644 --- a/tests/ui/issues/issue-66923-show-error-for-correct-call.stderr +++ b/tests/ui/issues/issue-66923-show-error-for-correct-call.stderr @@ -6,6 +6,7 @@ LL | let x2: Vec = x1.into_iter().collect(); | = help: the trait `FromIterator<&f64>` is not implemented for `Vec` = help: the trait `FromIterator` is implemented for `Vec` + = help: ... for that trait implementation, expected `f64`, found `&f64` note: the method call chain might not have had the expected associated types --> $DIR/issue-66923-show-error-for-correct-call.rs:8:27 | @@ -26,6 +27,7 @@ LL | let x3 = x1.into_iter().collect::>(); | = help: the trait `FromIterator<&f64>` is not implemented for `Vec` = help: the trait `FromIterator` is implemented for `Vec` + = help: ... for that trait implementation, expected `f64`, found `&f64` note: the method call chain might not have had the expected associated types --> $DIR/issue-66923-show-error-for-correct-call.rs:12:17 | diff --git a/tests/ui/iterators/invalid-iterator-chain.stderr b/tests/ui/iterators/invalid-iterator-chain.stderr index 1d7cf03997261..888a2f3899636 100644 --- a/tests/ui/iterators/invalid-iterator-chain.stderr +++ b/tests/ui/iterators/invalid-iterator-chain.stderr @@ -6,6 +6,7 @@ LL | i.collect() | = help: the trait `FromIterator<&X>` is not implemented for `Vec` = help: the trait `FromIterator` is implemented for `Vec` + = help: ... for that trait implementation, expected `X`, found `&X` note: the method call chain might not have had the expected associated types --> $DIR/invalid-iterator-chain.rs:4:26 | @@ -160,6 +161,7 @@ LL | let g: Vec = f.collect(); | = help: the trait `FromIterator<()>` is not implemented for `Vec` = help: the trait `FromIterator` is implemented for `Vec` + = help: ... for that trait implementation, expected `i32`, found `()` note: the method call chain might not have had the expected associated types --> $DIR/invalid-iterator-chain.rs:44:15 | diff --git a/tests/ui/never_type/never-value-fallback-issue-66757.nofallback.stderr b/tests/ui/never_type/never-value-fallback-issue-66757.nofallback.stderr index 54c16230fe68b..df1ae23426198 100644 --- a/tests/ui/never_type/never-value-fallback-issue-66757.nofallback.stderr +++ b/tests/ui/never_type/never-value-fallback-issue-66757.nofallback.stderr @@ -5,6 +5,7 @@ LL | >::from(never); | ^ the trait `From<()>` is not implemented for `E` | = help: the trait `From` is implemented for `E` + = help: ... for that trait implementation, expected `!`, found `()` error: aborting due to previous error diff --git a/tests/ui/on-unimplemented/impl-substs.stderr b/tests/ui/on-unimplemented/impl-substs.stderr index 018068c1af1b4..bdada79657b88 100644 --- a/tests/ui/on-unimplemented/impl-substs.stderr +++ b/tests/ui/on-unimplemented/impl-substs.stderr @@ -8,6 +8,7 @@ LL | Foo::::foo((1i32, 1i32, 1i32)); | = help: the trait `Foo` is not implemented for `(i32, i32, i32)` = help: the trait `Foo` is implemented for `(i32, i32, i32)` + = help: ... for that trait implementation, expected `i32`, found `usize` error: aborting due to previous error diff --git a/tests/ui/on-unimplemented/on-impl.stderr b/tests/ui/on-unimplemented/on-impl.stderr index 2253c5992a64a..4d3ad25aa7372 100644 --- a/tests/ui/on-unimplemented/on-impl.stderr +++ b/tests/ui/on-unimplemented/on-impl.stderr @@ -8,6 +8,7 @@ LL | Index::::index(&[1, 2, 3] as &[i32], 2u32); | = help: the trait `Index` is not implemented for `[i32]` = help: the trait `Index` is implemented for `[i32]` + = help: ... for that trait implementation, expected `usize`, found `u32` error[E0277]: the trait bound `[i32]: Index` is not satisfied --> $DIR/on-impl.rs:22:5 @@ -17,6 +18,7 @@ LL | Index::::index(&[1, 2, 3] as &[i32], 2u32); | = help: the trait `Index` is not implemented for `[i32]` = help: the trait `Index` is implemented for `[i32]` + = help: ... for that trait implementation, expected `usize`, found `u32` error[E0277]: the trait bound `[i32]: Index` is not satisfied --> $DIR/on-impl.rs:22:5 @@ -26,6 +28,7 @@ LL | Index::::index(&[1, 2, 3] as &[i32], 2u32); | = help: the trait `Index` is not implemented for `[i32]` = help: the trait `Index` is implemented for `[i32]` + = help: ... for that trait implementation, expected `usize`, found `u32` error: aborting due to 3 previous errors diff --git a/tests/ui/on-unimplemented/slice-index.stderr b/tests/ui/on-unimplemented/slice-index.stderr index d378470a36885..109f12c843d6f 100644 --- a/tests/ui/on-unimplemented/slice-index.stderr +++ b/tests/ui/on-unimplemented/slice-index.stderr @@ -6,6 +6,7 @@ LL | x[1i32]; | = help: the trait `SliceIndex<[i32]>` is not implemented for `i32` = help: the trait `SliceIndex<[i32]>` is implemented for `usize` + = help: ... for that trait implementation, expected `usize`, found `i32` = note: required for `[i32]` to implement `Index` error[E0277]: the type `[i32]` cannot be indexed by `RangeTo` diff --git a/tests/ui/str/str-idx.stderr b/tests/ui/str/str-idx.stderr index 3b4cb5e6a190b..35f29dbbba8c0 100644 --- a/tests/ui/str/str-idx.stderr +++ b/tests/ui/str/str-idx.stderr @@ -8,6 +8,7 @@ LL | let _: u8 = s[4]; = note: you can use `.chars().nth()` or `.bytes().nth()` for more information, see chapter 8 in The Book: = help: the trait `SliceIndex<[_]>` is implemented for `usize` + = help: ... for that trait implementation, expected `[_]`, found `str` = note: required for `str` to implement `Index<{integer}>` error[E0277]: the type `str` cannot be indexed by `{integer}` @@ -22,6 +23,7 @@ LL | let _ = s.get(4); = note: you can use `.chars().nth()` or `.bytes().nth()` for more information, see chapter 8 in The Book: = help: the trait `SliceIndex<[_]>` is implemented for `usize` + = help: ... for that trait implementation, expected `[_]`, found `str` note: required by a bound in `core::str::::get` --> $SRC_DIR/core/src/str/mod.rs:LL:COL @@ -37,6 +39,7 @@ LL | let _ = s.get_unchecked(4); = note: you can use `.chars().nth()` or `.bytes().nth()` for more information, see chapter 8 in The Book: = help: the trait `SliceIndex<[_]>` is implemented for `usize` + = help: ... for that trait implementation, expected `[_]`, found `str` note: required by a bound in `core::str::::get_unchecked` --> $SRC_DIR/core/src/str/mod.rs:LL:COL diff --git a/tests/ui/str/str-mut-idx.stderr b/tests/ui/str/str-mut-idx.stderr index f22ecea625770..8b4ed0c80bddd 100644 --- a/tests/ui/str/str-mut-idx.stderr +++ b/tests/ui/str/str-mut-idx.stderr @@ -32,6 +32,7 @@ LL | s[1usize] = bot(); | = help: the trait `SliceIndex` is not implemented for `usize` = help: the trait `SliceIndex<[_]>` is implemented for `usize` + = help: ... for that trait implementation, expected `[_]`, found `str` = note: required for `str` to implement `Index` error[E0277]: the type `str` cannot be indexed by `{integer}` @@ -46,6 +47,7 @@ LL | s.get_mut(1); = note: you can use `.chars().nth()` or `.bytes().nth()` for more information, see chapter 8 in The Book: = help: the trait `SliceIndex<[_]>` is implemented for `usize` + = help: ... for that trait implementation, expected `[_]`, found `str` note: required by a bound in `core::str::::get_mut` --> $SRC_DIR/core/src/str/mod.rs:LL:COL @@ -61,6 +63,7 @@ LL | s.get_unchecked_mut(1); = note: you can use `.chars().nth()` or `.bytes().nth()` for more information, see chapter 8 in The Book: = help: the trait `SliceIndex<[_]>` is implemented for `usize` + = help: ... for that trait implementation, expected `[_]`, found `str` note: required by a bound in `core::str::::get_unchecked_mut` --> $SRC_DIR/core/src/str/mod.rs:LL:COL diff --git a/tests/ui/suggestions/issue-101623.stderr b/tests/ui/suggestions/issue-101623.stderr index cfb5c6ae1917e..0202133e10baf 100644 --- a/tests/ui/suggestions/issue-101623.stderr +++ b/tests/ui/suggestions/issue-101623.stderr @@ -8,6 +8,7 @@ LL | Trait::do_stuff({ fun(&mut *inner) }); | required by a bound introduced by this call | = help: the trait `Trait<'_>` is implemented for `()` + = help: ... for that trait implementation, expected `()`, found `*mut ()` error: aborting due to previous error diff --git a/tests/ui/suggestions/suggest-dereferencing-index.stderr b/tests/ui/suggestions/suggest-dereferencing-index.stderr index 47cb25de627d3..9e2473c53abde 100644 --- a/tests/ui/suggestions/suggest-dereferencing-index.stderr +++ b/tests/ui/suggestions/suggest-dereferencing-index.stderr @@ -6,6 +6,7 @@ LL | let one_item_please: i32 = [1, 2, 3][i]; | = help: the trait `SliceIndex<[{integer}]>` is not implemented for `&usize` = help: the trait `SliceIndex<[{integer}]>` is implemented for `usize` + = help: ... for that trait implementation, expected `usize`, found `&usize` = note: required for `[{integer}]` to implement `Index<&usize>` help: dereference this index | diff --git a/tests/ui/traits/coercion-generic-bad.stderr b/tests/ui/traits/coercion-generic-bad.stderr index e7e8a796796b3..9caaf38c5a17e 100644 --- a/tests/ui/traits/coercion-generic-bad.stderr +++ b/tests/ui/traits/coercion-generic-bad.stderr @@ -5,6 +5,7 @@ LL | let s: Box> = Box::new(Struct { person: "Fred" }); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `Struct` | = help: the trait `Trait<&'static str>` is implemented for `Struct` + = help: ... for that trait implementation, expected `&'static str`, found `isize` = note: required for the cast from `Box` to `Box>` error: aborting due to previous error diff --git a/tests/ui/try-block/try-block-bad-type.stderr b/tests/ui/try-block/try-block-bad-type.stderr index e11c3f810035c..4efae8b2fb3b7 100644 --- a/tests/ui/try-block/try-block-bad-type.stderr +++ b/tests/ui/try-block/try-block-bad-type.stderr @@ -6,6 +6,7 @@ LL | Err("")?; | = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait = help: the trait `From` is implemented for `TryFromSliceError` + = help: ... for that trait implementation, expected `Infallible`, found `&str` = note: required for `Result` to implement `FromResidual>` error[E0271]: type mismatch resolving ` as Try>::Output == &str` diff --git a/tests/ui/try-trait/bad-interconversion.stderr b/tests/ui/try-trait/bad-interconversion.stderr index 7039a5c5495a9..1dbfb9287f0a6 100644 --- a/tests/ui/try-trait/bad-interconversion.stderr +++ b/tests/ui/try-trait/bad-interconversion.stderr @@ -74,6 +74,7 @@ LL | ControlFlow::Continue(Err("hello")?) | = help: the trait `FromResidual>` is not implemented for `ControlFlow` = help: the trait `FromResidual>` is implemented for `ControlFlow` + = help: ... for that trait implementation, expected `ControlFlow`, found `Result` error[E0277]: the `?` operator can only be used on `ControlFlow`s in a function that returns `ControlFlow` --> $DIR/bad-interconversion.rs:37:12 @@ -85,6 +86,7 @@ LL | Some(3)?; | = help: the trait `FromResidual>` is not implemented for `ControlFlow` = help: the trait `FromResidual>` is implemented for `ControlFlow` + = help: ... for that trait implementation, expected `ControlFlow`, found `Option` error[E0277]: the `?` operator in a function that returns `ControlFlow` can only be used on other `ControlFlow`s (with the same Break type) --> $DIR/bad-interconversion.rs:43:29 @@ -97,6 +99,7 @@ LL | ControlFlow::Break(4_u8)?; = help: the trait `FromResidual>` is not implemented for `ControlFlow` = note: unlike `Result`, there's no `From`-conversion performed for `ControlFlow` = help: the trait `FromResidual>` is implemented for `ControlFlow` + = help: ... for that trait implementation, expected `i64`, found `u8` error: aborting due to 8 previous errors