From 07851679cd8ced5933095c4173d3877c1abc96dd Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 10 Sep 2023 03:33:07 +0000 Subject: [PATCH] Point out the actual mismatch error --- .../src/traits/error_reporting/mod.rs | 15 ++++++++++++++- .../generic-const-items/unsatisfied-bounds.stderr | 2 ++ tests/ui/impl-trait/issues/issue-62742.stderr | 1 + tests/ui/indexing/index-help.stderr | 1 + tests/ui/indexing/indexing-requires-a-uint.stderr | 1 + tests/ui/integral-indexing.stderr | 8 ++++++++ tests/ui/issues/issue-34334.stderr | 1 + tests/ui/issues/issue-45801.stderr | 1 + ...issue-66923-show-error-for-correct-call.stderr | 2 ++ tests/ui/iterators/invalid-iterator-chain.stderr | 2 ++ ...r-value-fallback-issue-66757.nofallback.stderr | 1 + tests/ui/on-unimplemented/impl-substs.stderr | 1 + tests/ui/on-unimplemented/on-impl.stderr | 3 +++ tests/ui/on-unimplemented/slice-index.stderr | 1 + tests/ui/str/str-idx.stderr | 3 +++ tests/ui/str/str-mut-idx.stderr | 3 +++ tests/ui/suggestions/issue-101623.stderr | 1 + .../suggest-dereferencing-index.stderr | 1 + tests/ui/traits/coercion-generic-bad.stderr | 1 + tests/ui/try-block/try-block-bad-type.stderr | 1 + tests/ui/try-trait/bad-interconversion.stderr | 3 +++ 21 files changed, 52 insertions(+), 1 deletion(-) 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 1a89f7b54e1..9a728b1060f 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; @@ -1943,6 +1945,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); @@ -1972,7 +1976,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); } @@ -2000,6 +2004,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 2cee53431a4..14894cef770 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 7592a850682..8d969e8e0f3 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 d3310ceb053..2cb212a0139 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 fcfac3a5e93..6ea6bb600e9 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 b7d80565a1e..97e658617cf 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 bacae965eed..753942dd1d1 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 8967f49df02..e651e2a68d1 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 48cd549cb33..128288e28f5 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 1d7cf039972..2601c9c0d69 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 54c16230fe6..cb378630589 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 018068c1af1..36d80f3e681 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 2253c5992a6..3a0b8353fa5 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 d378470a368..5e0117be529 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 3b4cb5e6a19..e8bbb8058fa 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 f22ecea6257..e6835bb54fb 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 cfb5c6ae191..9f00de17484 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 47cb25de627..adf01339972 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 e7e8a796796..30a3c40db95 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 e11c3f81003..b41bf86d3d9 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 7039a5c5495..d8b9431becc 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