diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 358c244eca9..dd2f0ec2096 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -6,8 +6,8 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::unord::UnordSet; use rustc_errors::codes::*; use rustc_errors::{ - Applicability, Diag, ErrorGuaranteed, MultiSpan, StashKey, StringPart, Suggestions, pluralize, - struct_span_code_err, + Applicability, Diag, ErrorGuaranteed, Level, MultiSpan, StashKey, StringPart, Suggestions, + pluralize, struct_span_code_err, }; use rustc_hir::def::Namespace; use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId}; @@ -1833,6 +1833,22 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { return false; } + if let [child, ..] = &err.children[..] + && child.level == Level::Help + && let Some(line) = child.messages.get(0) + && let Some(line) = line.0.as_str() + && line.starts_with("the trait") + && line.contains("is not implemented for") + { + // HACK(estebank): we remove the pre-existing + // "the trait `X` is not implemented for" note, which only happens if there + // was a custom label. We do this because we want that note to always be the + // first, and making this logic run earlier will get tricky. For now, we + // instead keep the logic the same and modify the already constructed error + // to avoid the wording duplication. + err.children.remove(0); + } + let traits = self.cmp_traits( obligation_trait_ref.def_id, &obligation_trait_ref.args[1..], diff --git a/tests/ui/indexing/index-help.stderr b/tests/ui/indexing/index-help.stderr index d4637da1426..1974e13eabc 100644 --- a/tests/ui/indexing/index-help.stderr +++ b/tests/ui/indexing/index-help.stderr @@ -4,7 +4,6 @@ error[E0277]: the type `[{integer}]` cannot be indexed by `i32` 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 trait `SliceIndex<[{integer}]>` is not implemented for `i32` but it is implemented for `usize` = help: for that trait implementation, expected `usize`, found `i32` diff --git a/tests/ui/indexing/indexing-requires-a-uint.stderr b/tests/ui/indexing/indexing-requires-a-uint.stderr index fdcf9b030a5..5c60a30946d 100644 --- a/tests/ui/indexing/indexing-requires-a-uint.stderr +++ b/tests/ui/indexing/indexing-requires-a-uint.stderr @@ -4,7 +4,6 @@ error[E0277]: the type `[{integer}]` cannot be indexed by `u8` LL | [0][0u8]; | ^^^ slice indices are of type `usize` or ranges of `usize` | - = help: the trait `SliceIndex<[{integer}]>` is not implemented for `u8` = help: the trait `SliceIndex<[{integer}]>` is not implemented for `u8` but it is implemented for `usize` = help: for that trait implementation, expected `usize`, found `u8` diff --git a/tests/ui/integral-indexing.stderr b/tests/ui/integral-indexing.stderr index f731d303774..e7a45c2c88d 100644 --- a/tests/ui/integral-indexing.stderr +++ b/tests/ui/integral-indexing.stderr @@ -4,7 +4,6 @@ error[E0277]: the type `[isize]` cannot be indexed by `u8` 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 trait `SliceIndex<[isize]>` is not implemented for `u8` but it is implemented for `usize` = help: for that trait implementation, expected `usize`, found `u8` @@ -16,7 +15,6 @@ error[E0277]: the type `[isize]` cannot be indexed by `i8` 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 trait `SliceIndex<[isize]>` is not implemented for `i8` but it is implemented for `usize` = help: for that trait implementation, expected `usize`, found `i8` @@ -28,7 +26,6 @@ error[E0277]: the type `[isize]` cannot be indexed by `u32` 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 trait `SliceIndex<[isize]>` is not implemented for `u32` but it is implemented for `usize` = help: for that trait implementation, expected `usize`, found `u32` @@ -40,7 +37,6 @@ error[E0277]: the type `[isize]` cannot be indexed by `i32` 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 trait `SliceIndex<[isize]>` is not implemented for `i32` but it is implemented for `usize` = help: for that trait implementation, expected `usize`, found `i32` @@ -52,7 +48,6 @@ error[E0277]: the type `[u8]` cannot be indexed by `u8` 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 trait `SliceIndex<[u8]>` is not implemented for `u8` but it is implemented for `usize` = help: for that trait implementation, expected `usize`, found `u8` @@ -64,7 +59,6 @@ error[E0277]: the type `[u8]` cannot be indexed by `i8` 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 trait `SliceIndex<[u8]>` is not implemented for `i8` but it is implemented for `usize` = help: for that trait implementation, expected `usize`, found `i8` @@ -76,7 +70,6 @@ error[E0277]: the type `[u8]` cannot be indexed by `u32` 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 trait `SliceIndex<[u8]>` is not implemented for `u32` but it is implemented for `usize` = help: for that trait implementation, expected `usize`, found `u32` @@ -88,7 +81,6 @@ error[E0277]: the type `[u8]` cannot be indexed by `i32` 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 trait `SliceIndex<[u8]>` is not implemented for `i32` but it is implemented for `usize` = help: for that trait implementation, expected `usize`, found `i32` diff --git a/tests/ui/issues/issue-34334.stderr b/tests/ui/issues/issue-34334.stderr index 8213136faa1..6562ccfdcd2 100644 --- a/tests/ui/issues/issue-34334.stderr +++ b/tests/ui/issues/issue-34334.stderr @@ -17,7 +17,6 @@ error[E0277]: a value of type `Vec<(u32, _, _)>` cannot be built from an iterato LL | let sr2: Vec<(u32, _, _)> = sr.iter().map(|(faction, th_sender, th_receiver)| {}).collect(); | ^^^^^^^ value of type `Vec<(u32, _, _)>` cannot be built from `std::iter::Iterator` | - = help: the trait `FromIterator<()>` is not implemented for `Vec<(u32, _, _)>` = help: the trait `FromIterator<()>` is not implemented for `Vec<(u32, _, _)>` but trait `FromIterator<(u32, _, _)>` is implemented for it = help: for that trait implementation, expected `(u32, _, _)`, found `()` 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 e62be48edf6..d2852093725 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 @@ -4,7 +4,6 @@ error[E0277]: a value of type `Vec` cannot be built from an iterator over e LL | let x2: Vec = x1.into_iter().collect(); | ^^^^^^^ value of type `Vec` cannot be built from `std::iter::Iterator` | - = help: the trait `FromIterator<&f64>` is not implemented for `Vec` = help: the trait `FromIterator<&_>` is not implemented for `Vec` but trait `FromIterator<_>` is implemented for it = help: for that trait implementation, expected `f64`, found `&f64` @@ -26,7 +25,6 @@ LL | let x3 = x1.into_iter().collect::>(); | | | required by a bound introduced by this call | - = help: the trait `FromIterator<&f64>` is not implemented for `Vec` = help: the trait `FromIterator<&_>` is not implemented for `Vec` but trait `FromIterator<_>` is implemented for it = help: for that trait implementation, expected `f64`, found `&f64` diff --git a/tests/ui/iterators/invalid-iterator-chain-fixable.stderr b/tests/ui/iterators/invalid-iterator-chain-fixable.stderr index d6f82741c4c..09439fe8fbd 100644 --- a/tests/ui/iterators/invalid-iterator-chain-fixable.stderr +++ b/tests/ui/iterators/invalid-iterator-chain-fixable.stderr @@ -6,7 +6,6 @@ LL | let i = i.map(|x| x.clone()); LL | i.collect() | ^^^^^^^ value of type `Vec` cannot be built from `std::iter::Iterator` | - = help: the trait `FromIterator<&X>` is not implemented for `Vec` = help: the trait `FromIterator<&_>` is not implemented for `Vec` but trait `FromIterator<_>` is implemented for it = help: for that trait implementation, expected `X`, found `&X` @@ -124,7 +123,6 @@ error[E0277]: a value of type `Vec` cannot be built from an iterator over e LL | let g: Vec = f.collect(); | ^^^^^^^ value of type `Vec` cannot be built from `std::iter::Iterator` | - = help: the trait `FromIterator<()>` is not implemented for `Vec` = help: the trait `FromIterator<()>` is not implemented for `Vec` but trait `FromIterator` is implemented for it = help: for that trait implementation, expected `i32`, found `()` diff --git a/tests/ui/iterators/invalid-iterator-chain.stderr b/tests/ui/iterators/invalid-iterator-chain.stderr index 2522471b3b5..b810e06d0f7 100644 --- a/tests/ui/iterators/invalid-iterator-chain.stderr +++ b/tests/ui/iterators/invalid-iterator-chain.stderr @@ -6,7 +6,6 @@ LL | let i = i.map(|x| x.clone()); LL | i.collect() | ^^^^^^^ value of type `Vec` cannot be built from `std::iter::Iterator` | - = help: the trait `FromIterator<&X>` is not implemented for `Vec` = help: the trait `FromIterator<&_>` is not implemented for `Vec` but trait `FromIterator<_>` is implemented for it = help: for that trait implementation, expected `X`, found `&X` @@ -181,7 +180,6 @@ error[E0277]: a value of type `Vec` cannot be built from an iterator over e LL | let g: Vec = f.collect(); | ^^^^^^^ value of type `Vec` cannot be built from `std::iter::Iterator` | - = help: the trait `FromIterator<()>` is not implemented for `Vec` = help: the trait `FromIterator<()>` is not implemented for `Vec` but trait `FromIterator` is implemented for it = help: for that trait implementation, expected `i32`, found `()` diff --git a/tests/ui/on-unimplemented/impl-substs.stderr b/tests/ui/on-unimplemented/impl-substs.stderr index cdb9172ef0f..b85d45eba5b 100644 --- a/tests/ui/on-unimplemented/impl-substs.stderr +++ b/tests/ui/on-unimplemented/impl-substs.stderr @@ -6,7 +6,6 @@ LL | Foo::::foo((1i32, 1i32, 1i32)); | | | required by a bound introduced by this call | - = help: the trait `Foo` is not implemented for `(i32, i32, i32)` = help: the trait `Foo` is not implemented for `(i32, i32, i32)` but trait `Foo` is implemented for it = help: for that trait implementation, expected `i32`, found `usize` diff --git a/tests/ui/on-unimplemented/on-impl.stderr b/tests/ui/on-unimplemented/on-impl.stderr index d20b559def7..5e7e2c4ea77 100644 --- a/tests/ui/on-unimplemented/on-impl.stderr +++ b/tests/ui/on-unimplemented/on-impl.stderr @@ -6,7 +6,6 @@ LL | Index::::index(&[1, 2, 3] as &[i32], 2u32); | | | required by a bound introduced by this call | - = help: the trait `Index` is not implemented for `[i32]` = help: the trait `Index` is not implemented for `[i32]` but trait `Index` is implemented for it = help: for that trait implementation, expected `usize`, found `u32` @@ -17,7 +16,6 @@ error[E0277]: the trait bound `[i32]: Index` is not satisfied LL | Index::::index(&[1, 2, 3] as &[i32], 2u32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ a usize is required to index into a slice | - = help: the trait `Index` is not implemented for `[i32]` = help: the trait `Index` is not implemented for `[i32]` but trait `Index` is implemented for it = help: for that trait implementation, expected `usize`, found `u32` diff --git a/tests/ui/on-unimplemented/slice-index.stderr b/tests/ui/on-unimplemented/slice-index.stderr index 8f7169b30d4..0a9ebe3f088 100644 --- a/tests/ui/on-unimplemented/slice-index.stderr +++ b/tests/ui/on-unimplemented/slice-index.stderr @@ -4,7 +4,6 @@ error[E0277]: the type `[i32]` cannot be indexed by `i32` LL | x[1i32]; | ^^^^ slice indices are of type `usize` or ranges of `usize` | - = help: the trait `SliceIndex<[i32]>` is not implemented for `i32` = help: the trait `SliceIndex<[i32]>` is not implemented for `i32` but it is implemented for `usize` = help: for that trait implementation, expected `usize`, found `i32` diff --git a/tests/ui/str/str-idx.stderr b/tests/ui/str/str-idx.stderr index 0ce0c207561..bedbbd9cb50 100644 --- a/tests/ui/str/str-idx.stderr +++ b/tests/ui/str/str-idx.stderr @@ -4,7 +4,6 @@ error[E0277]: the type `str` cannot be indexed by `{integer}` LL | let _: u8 = s[4]; | ^ string indices are ranges of `usize` | - = help: the trait `SliceIndex` is not implemented for `{integer}` = note: you can use `.chars().nth()` or `.bytes().nth()` for more information, see chapter 8 in The Book: = help: the trait `SliceIndex` is not implemented for `{integer}` @@ -20,7 +19,6 @@ LL | let _ = s.get(4); | | | required by a bound introduced by this call | - = help: the trait `SliceIndex` is not implemented for `{integer}` = note: you can use `.chars().nth()` or `.bytes().nth()` for more information, see chapter 8 in The Book: = help: the trait `SliceIndex` is not implemented for `{integer}` @@ -37,7 +35,6 @@ LL | let _ = s.get_unchecked(4); | | | required by a bound introduced by this call | - = help: the trait `SliceIndex` is not implemented for `{integer}` = note: you can use `.chars().nth()` or `.bytes().nth()` for more information, see chapter 8 in The Book: = help: the trait `SliceIndex` is not implemented for `{integer}` diff --git a/tests/ui/str/str-mut-idx.stderr b/tests/ui/str/str-mut-idx.stderr index 7bc46ff33b3..f09a4c329e5 100644 --- a/tests/ui/str/str-mut-idx.stderr +++ b/tests/ui/str/str-mut-idx.stderr @@ -30,7 +30,6 @@ error[E0277]: the type `str` cannot be indexed by `usize` LL | s[1usize] = bot(); | ^^^^^^ string indices are ranges of `usize` | - = help: the trait `SliceIndex` is not implemented for `usize` = help: the trait `SliceIndex` is not implemented for `usize` but trait `SliceIndex<[_]>` is implemented for it = help: for that trait implementation, expected `[_]`, found `str` @@ -44,7 +43,6 @@ LL | s.get_mut(1); | | | required by a bound introduced by this call | - = help: the trait `SliceIndex` is not implemented for `{integer}` = note: you can use `.chars().nth()` or `.bytes().nth()` for more information, see chapter 8 in The Book: = help: the trait `SliceIndex` is not implemented for `{integer}` @@ -61,7 +59,6 @@ LL | s.get_unchecked_mut(1); | | | required by a bound introduced by this call | - = help: the trait `SliceIndex` is not implemented for `{integer}` = note: you can use `.chars().nth()` or `.bytes().nth()` for more information, see chapter 8 in The Book: = help: the trait `SliceIndex` is not implemented for `{integer}` diff --git a/tests/ui/suggestions/suggest-dereferencing-index.stderr b/tests/ui/suggestions/suggest-dereferencing-index.stderr index cd5364fcffb..0335d8eafde 100644 --- a/tests/ui/suggestions/suggest-dereferencing-index.stderr +++ b/tests/ui/suggestions/suggest-dereferencing-index.stderr @@ -4,7 +4,6 @@ error[E0277]: the type `[{integer}]` cannot be indexed by `&usize` LL | let one_item_please: i32 = [1, 2, 3][i]; | ^ slice indices are of type `usize` or ranges of `usize` | - = help: the trait `SliceIndex<[{integer}]>` is not implemented for `&usize` = help: the trait `SliceIndex<[{integer}]>` is not implemented for `&_` but it is implemented for `_` = help: for that trait implementation, expected `usize`, found `&usize` diff --git a/tests/ui/try-trait/bad-interconversion.stderr b/tests/ui/try-trait/bad-interconversion.stderr index 20fe2d721bc..bb5e5646ad2 100644 --- a/tests/ui/try-trait/bad-interconversion.stderr +++ b/tests/ui/try-trait/bad-interconversion.stderr @@ -66,7 +66,6 @@ LL | fn result_to_control_flow() -> ControlFlow { LL | ControlFlow::Continue(Err("hello")?) | ^ this `?` produces `Result`, which is incompatible with `ControlFlow` | - = help: the trait `FromResidual>` is not implemented for `ControlFlow` = help: the trait `FromResidual>` is not implemented for `ControlFlow` but trait `FromResidual>` is implemented for it = help: for that trait implementation, expected `ControlFlow`, found `Result` @@ -79,7 +78,6 @@ LL | fn option_to_control_flow() -> ControlFlow { LL | Some(3)?; | ^ this `?` produces `Option`, which is incompatible with `ControlFlow` | - = help: the trait `FromResidual>` is not implemented for `ControlFlow` = help: the trait `FromResidual>` is not implemented for `ControlFlow` but trait `FromResidual>` is implemented for it = help: for that trait implementation, expected `ControlFlow`, found `Option` @@ -92,7 +90,6 @@ LL | fn control_flow_to_control_flow() -> ControlFlow { LL | ControlFlow::Break(4_u8)?; | ^ this `?` produces `ControlFlow`, which is incompatible with `ControlFlow` | - = 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 not implemented for `ControlFlow` but trait `FromResidual>` is implemented for it diff --git a/tests/ui/type-alias-impl-trait/self-referential-2.current.stderr b/tests/ui/type-alias-impl-trait/self-referential-2.current.stderr index 1e799f15635..e4399f2d8f4 100644 --- a/tests/ui/type-alias-impl-trait/self-referential-2.current.stderr +++ b/tests/ui/type-alias-impl-trait/self-referential-2.current.stderr @@ -6,7 +6,6 @@ LL | fn bar() -> Bar { LL | 42_i32 | ------ return type was inferred to be `i32` here | - = help: the trait `PartialEq` is not implemented for `i32` = help: the trait `PartialEq` is not implemented for `i32` but trait `PartialEq` is implemented for it