From b7fc1a743122e3c45f105a5d1169a042a2c6e8bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 24 Oct 2024 22:16:43 +0000 Subject: [PATCH 1/8] Add trait diff highlighting logic and use it in E0277 When a trait is not implemented for a type, but there *is* an `impl` for another type or different trait params, we format the output to use highlighting in the same way that E0308 does for types. The logic accounts for 3 cases: - When both the type and trait in the expected predicate and the candidate are different - When only the types are different - When only the trait generic params are different For each case, we use slightly different formatting and wording. --- .../src/error_reporting/infer/mod.rs | 61 +++++++++++++++++ .../traits/fulfillment_errors.rs | 68 +++++++++++++++---- .../associated-type-bound-fail.stderr | 3 +- .../defaults/rp_impl_trait_fail.stderr | 6 +- .../defaults/trait_objects_fail.stderr | 6 +- .../ui/const-generics/defaults/wfness.stderr | 6 +- .../occurs-check/unused-substs-1.stderr | 3 +- .../as_expression.current.stderr | 3 +- .../as_expression.next.stderr | 3 +- .../unsatisfied-bounds.stderr | 6 +- ...between-expected-trait-and-found-trait.svg | 28 ++++---- .../return-dont-satisfy-bounds.stderr | 3 +- tests/ui/impl-trait/issues/issue-62742.stderr | 6 +- tests/ui/impl-trait/nested-rpit-hrtb.stderr | 6 +- tests/ui/indexing/index-help.stderr | 3 +- .../indexing/indexing-requires-a-uint.stderr | 3 +- ...int-at-index-for-obligation-failure.stderr | 3 +- tests/ui/integral-indexing.stderr | 24 ++++--- tests/ui/issues/issue-34334.stderr | 3 +- tests/ui/issues/issue-45801.stderr | 3 +- ...e-66923-show-error-for-correct-call.stderr | 6 +- .../invalid-iterator-chain-fixable.stderr | 6 +- .../iterators/invalid-iterator-chain.stderr | 6 +- ...er_breaking_with_unit_fallback.unit.stderr | 3 +- ...lue-fallback-issue-66757.nofallback.stderr | 3 +- tests/ui/on-unimplemented/impl-substs.stderr | 3 +- tests/ui/on-unimplemented/on-impl.stderr | 6 +- tests/ui/on-unimplemented/slice-index.stderr | 3 +- tests/ui/str/str-idx.stderr | 9 ++- tests/ui/str/str-mut-idx.stderr | 9 ++- tests/ui/suggestions/issue-101623.stderr | 3 +- .../suggest-dereferencing-index.stderr | 3 +- tests/ui/traits/coercion-generic-bad.stderr | 3 +- tests/ui/traits/negative-bounds/simple.stderr | 3 +- tests/ui/try-block/try-block-bad-type.stderr | 3 +- tests/ui/try-trait/bad-interconversion.stderr | 9 ++- .../constrain_in_projection.current.stderr | 3 +- .../nested-tait-inference.current.stderr | 3 +- .../self-referential-2.current.stderr | 3 +- ...t-similar-impls-for-root-obligation.stderr | 3 +- 40 files changed, 251 insertions(+), 86 deletions(-) diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs index 574cf1e88b16b..4725047090edf 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -766,6 +766,67 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { values } + pub fn cmp_traits( + &self, + def_id1: DefId, + args1: &[ty::GenericArg<'tcx>], + def_id2: DefId, + args2: &[ty::GenericArg<'tcx>], + ) -> (DiagStyledString, DiagStyledString) { + let mut values = (DiagStyledString::new(), DiagStyledString::new()); + + if def_id1 != def_id2 { + values.0.push_highlighted(self.tcx.def_path_str(def_id1).as_str()); + values.1.push_highlighted(self.tcx.def_path_str(def_id2).as_str()); + } else { + values.0.push_normal(self.tcx.item_name(def_id1).as_str()); + values.1.push_normal(self.tcx.item_name(def_id2).as_str()); + } + + if args1.len() != args2.len() { + let (pre, post) = if args1.len() > 0 { ("<", ">") } else { ("", "") }; + values.0.push_normal(format!( + "{pre}{}{post}", + args1.iter().map(|a| a.to_string()).collect::>().join(", ") + )); + let (pre, post) = if args2.len() > 0 { ("<", ">") } else { ("", "") }; + values.1.push_normal(format!( + "{pre}{}{post}", + args2.iter().map(|a| a.to_string()).collect::>().join(", ") + )); + return values; + } + + if args1.len() > 0 { + values.0.push_normal("<"); + values.1.push_normal("<"); + } + for (i, (a, b)) in std::iter::zip(args1, args2).enumerate() { + let a_str = a.to_string(); + let b_str = b.to_string(); + if let (Some(a), Some(b)) = (a.as_type(), b.as_type()) { + let (a, b) = self.cmp(a, b); + values.0.0.extend(a.0); + values.1.0.extend(b.0); + } else if a_str != b_str { + values.0.push_highlighted(a_str); + values.1.push_highlighted(b_str); + } else { + values.0.push_normal(a_str); + values.1.push_normal(b_str); + } + if i + 1 < args1.len() { + values.0.push_normal(", "); + values.1.push_normal(", "); + } + } + if args1.len() > 0 { + values.0.push_normal(">"); + values.1.push_normal(">"); + } + values + } + /// Compares two given types, eliding parts that are the same between them and highlighting /// relevant differences, and return two representation of those types for highlighted printing. pub fn cmp(&self, t1: Ty<'tcx>, t2: Ty<'tcx>) -> (DiagStyledString, DiagStyledString) { 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 7aa558cfd3ffe..358c244eca941 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 @@ -1832,21 +1832,63 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { if impl_trait_ref.references_error() { return false; } - let self_ty = impl_trait_ref.self_ty().to_string(); - err.highlighted_help(vec![ - StringPart::normal(format!( - "the trait `{}` ", - impl_trait_ref.print_trait_sugared() - )), - StringPart::highlighted("is"), + + let traits = self.cmp_traits( + obligation_trait_ref.def_id, + &obligation_trait_ref.args[1..], + impl_trait_ref.def_id, + &impl_trait_ref.args[1..], + ); + let traits_content = (traits.0.content(), traits.1.content()); + let types = self.cmp(obligation_trait_ref.self_ty(), impl_trait_ref.self_ty()); + let types_content = (types.0.content(), types.1.content()); + let mut msg = vec![StringPart::normal("the trait `")]; + if traits_content.0 == traits_content.1 { + msg.push(StringPart::normal( + impl_trait_ref.print_trait_sugared().to_string(), + )); + } else { + msg.extend(traits.0.0); + } + msg.extend([ + StringPart::normal("` "), + StringPart::highlighted("is not"), StringPart::normal(" implemented for `"), - if let [TypeError::Sorts(_)] = &terrs[..] { - StringPart::normal(self_ty) - } else { - StringPart::highlighted(self_ty) - }, - StringPart::normal("`"), ]); + if types_content.0 == types_content.1 { + msg.push(StringPart::normal(obligation_trait_ref.self_ty().to_string())); + } else { + msg.extend(types.0.0); + } + msg.push(StringPart::normal("`")); + if types_content.0 == types_content.1 { + msg.push(StringPart::normal("\nbut trait `")); + msg.extend(traits.1.0); + msg.extend([ + StringPart::normal("` "), + StringPart::highlighted("is"), + StringPart::normal(" implemented for it"), + ]); + } else if traits_content.0 == traits_content.1 { + msg.extend([ + StringPart::normal("\nbut it "), + StringPart::highlighted("is"), + StringPart::normal(" implemented for `"), + ]); + msg.extend(types.1.0); + msg.push(StringPart::normal("`")); + } else { + msg.push(StringPart::normal("\nbut trait `")); + msg.extend(traits.1.0); + msg.extend([ + StringPart::normal("` "), + StringPart::highlighted("is"), + StringPart::normal(" implemented for `"), + ]); + msg.extend(types.1.0); + msg.push(StringPart::normal("`")); + } + err.highlighted_help(msg); if let [TypeError::Sorts(exp_found)] = &terrs[..] { let exp_found = self.resolve_vars_if_possible(*exp_found); diff --git a/tests/ui/const-generics/associated-type-bound-fail.stderr b/tests/ui/const-generics/associated-type-bound-fail.stderr index 602a8927a8530..e92aad7cec32c 100644 --- a/tests/ui/const-generics/associated-type-bound-fail.stderr +++ b/tests/ui/const-generics/associated-type-bound-fail.stderr @@ -4,7 +4,8 @@ error[E0277]: the trait bound `u16: Bar` is not satisfied LL | type Assoc = u16; | ^^^ the trait `Bar` is not implemented for `u16` | - = help: the trait `Bar<3>` is implemented for `u16` + = help: the trait `Bar` is not implemented for `u16` + but trait `Bar<3>` is implemented for it note: required by a bound in `Foo::Assoc` --> $DIR/associated-type-bound-fail.rs:4:17 | diff --git a/tests/ui/const-generics/defaults/rp_impl_trait_fail.stderr b/tests/ui/const-generics/defaults/rp_impl_trait_fail.stderr index 45be3126e3b3f..e36f645b2637b 100644 --- a/tests/ui/const-generics/defaults/rp_impl_trait_fail.stderr +++ b/tests/ui/const-generics/defaults/rp_impl_trait_fail.stderr @@ -18,7 +18,8 @@ LL | LL | 1_u32 | ----- return type was inferred to be `u32` here | - = help: the trait `Traitor` is implemented for `u32` + = help: the trait `Traitor` is not implemented for `u32` + but trait `Traitor` is implemented for it error[E0277]: the trait bound `u64: Traitor` is not satisfied --> $DIR/rp_impl_trait_fail.rs:21:13 @@ -29,7 +30,8 @@ LL | LL | 1_u64 | ----- return type was inferred to be `u64` here | - = help: the trait `Traitor<1, 2>` is implemented for `u64` + = help: the trait `Traitor<1, 1>` is not implemented for `u64` + but trait `Traitor<1, 2>` is implemented for it error[E0284]: type annotations needed --> $DIR/rp_impl_trait_fail.rs:28:5 diff --git a/tests/ui/const-generics/defaults/trait_objects_fail.stderr b/tests/ui/const-generics/defaults/trait_objects_fail.stderr index 481d77728b9ef..2390dfeadb906 100644 --- a/tests/ui/const-generics/defaults/trait_objects_fail.stderr +++ b/tests/ui/const-generics/defaults/trait_objects_fail.stderr @@ -4,7 +4,8 @@ error[E0277]: the trait bound `u32: Trait` is not satisfied LL | foo(&10_u32); | ^^^^^^^ the trait `Trait` is not implemented for `u32` | - = help: the trait `Trait<2>` is implemented for `u32` + = help: the trait `Trait<12>` is not implemented for `u32` + but trait `Trait<2>` is implemented for it = note: required for the cast from `&u32` to `&dyn Trait` error[E0277]: the trait bound `bool: Traitor<_>` is not satisfied @@ -13,7 +14,8 @@ error[E0277]: the trait bound `bool: Traitor<_>` is not satisfied LL | bar(&true); | ^^^^^ the trait `Traitor<_>` is not implemented for `bool` | - = help: the trait `Traitor<2, 3>` is implemented for `bool` + = help: the trait `Traitor<_, _>` is not implemented for `bool` + but trait `Traitor<2, 3>` is implemented for it = note: required for the cast from `&bool` to `&dyn Traitor<_>` error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/defaults/wfness.stderr b/tests/ui/const-generics/defaults/wfness.stderr index bd9bfcd7dadf6..290a80bd32fa0 100644 --- a/tests/ui/const-generics/defaults/wfness.stderr +++ b/tests/ui/const-generics/defaults/wfness.stderr @@ -10,7 +10,8 @@ error[E0277]: the trait bound `(): Trait<2>` is not satisfied LL | (): Trait; | ^^^^^^^^ the trait `Trait<2>` is not implemented for `()` | - = help: the trait `Trait<3>` is implemented for `()` + = help: the trait `Trait<2>` is not implemented for `()` + but trait `Trait<3>` is implemented for it error[E0277]: the trait bound `(): Trait<1>` is not satisfied --> $DIR/wfness.rs:18:13 @@ -18,7 +19,8 @@ error[E0277]: the trait bound `(): Trait<1>` is not satisfied LL | fn foo() -> DependentDefaultWfness { | ^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait<1>` is not implemented for `()` | - = help: the trait `Trait<3>` is implemented for `()` + = help: the trait `Trait<1>` is not implemented for `()` + but trait `Trait<3>` is implemented for it note: required by a bound in `WhereClause` --> $DIR/wfness.rs:8:9 | diff --git a/tests/ui/const-generics/occurs-check/unused-substs-1.stderr b/tests/ui/const-generics/occurs-check/unused-substs-1.stderr index 0184a05932707..07e86aa17f2d2 100644 --- a/tests/ui/const-generics/occurs-check/unused-substs-1.stderr +++ b/tests/ui/const-generics/occurs-check/unused-substs-1.stderr @@ -4,7 +4,8 @@ error[E0277]: the trait bound `A<_>: Bar<_>` is not satisfied LL | let _ = A; | ^ the trait `Bar<_>` is not implemented for `A<_>` | - = help: the trait `Bar<_>` is implemented for `A<{ 6 + 1 }>` + = help: the trait `Bar<_>` is not implemented for `A<_>` + but it is implemented for `A<{ 6 + 1 }>` note: required by a bound in `A` --> $DIR/unused-substs-1.rs:9:11 | diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.current.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.current.stderr index 41f222e46a77c..5d0c182641101 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.current.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.current.stderr @@ -4,7 +4,8 @@ error[E0277]: the trait bound `&str: AsExpression` is not satisfied LL | SelectInt.check("bar"); | ^^^^^ the trait `AsExpression` is not implemented for `&str` | - = help: the trait `AsExpression` is implemented for `&str` + = help: the trait `AsExpression` is not implemented for `&str` + but trait `AsExpression` is implemented for it = help: for that trait implementation, expected `Text`, found `Integer` error: aborting due to 1 previous error diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.next.stderr index 8c01b61191e60..1e1eae852f911 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.next.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.next.stderr @@ -22,7 +22,8 @@ error[E0277]: the trait bound `&str: AsExpression` is not satisfied LL | SelectInt.check("bar"); | ^^^^^ the trait `AsExpression` is not implemented for `&str` | - = help: the trait `AsExpression` is implemented for `&str` + = help: the trait `AsExpression` is not implemented for `&str` + but trait `AsExpression` is implemented for it = help: for that trait implementation, expected `Text`, found `Integer` error[E0271]: type mismatch resolving `::SqlType == Text` diff --git a/tests/ui/generic-const-items/unsatisfied-bounds.stderr b/tests/ui/generic-const-items/unsatisfied-bounds.stderr index 14894cef77089..de252b816e58a 100644 --- a/tests/ui/generic-const-items/unsatisfied-bounds.stderr +++ b/tests/ui/generic-const-items/unsatisfied-bounds.stderr @@ -16,7 +16,8 @@ error[E0277]: the trait bound `Infallible: From<()>` is not satisfied LL | let () = K::<()>; | ^^ the trait `From<()>` is not implemented for `Infallible` | - = help: the trait `From` is implemented for `Infallible` + = help: the trait `From<()>` is not implemented for `Infallible` + but trait `From` is implemented for it = help: for that trait implementation, expected `!`, found `()` note: required by a bound in `K` --> $DIR/unsatisfied-bounds.rs:12:17 @@ -48,7 +49,8 @@ error[E0277]: the trait bound `Infallible: From<()>` is not satisfied LL | let _ = <() as Trait<&'static str>>::B::<()>; | ^^ the trait `From<()>` is not implemented for `Infallible` | - = help: the trait `From` is implemented for `Infallible` + = help: the trait `From<()>` is not implemented for `Infallible` + but trait `From` is implemented for it = 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/diagnostics/highlight-difference-between-expected-trait-and-found-trait.svg b/tests/ui/impl-trait/diagnostics/highlight-difference-between-expected-trait-and-found-trait.svg index a18fc11a1e3c6..277fd1536bc71 100644 --- a/tests/ui/impl-trait/diagnostics/highlight-difference-between-expected-trait-and-found-trait.svg +++ b/tests/ui/impl-trait/diagnostics/highlight-difference-between-expected-trait-and-found-trait.svg @@ -1,4 +1,4 @@ - + diff --git a/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.stderr b/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.stderr index 768224e4c515c..663c9a7f2aeda 100644 --- a/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.stderr +++ b/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.stderr @@ -32,7 +32,8 @@ LL | fn foo>(self) -> impl Foo { LL | self | ---- return type was inferred to be `Bar` here | - = help: the trait `Foo` is implemented for `Bar` + = help: the trait `Foo` is not implemented for `Bar` + but trait `Foo` is implemented for it = help: for that trait implementation, expected `char`, found `u8` error: aborting due to 3 previous errors diff --git a/tests/ui/impl-trait/issues/issue-62742.stderr b/tests/ui/impl-trait/issues/issue-62742.stderr index 94822e41ccd67..98d17b02536cc 100644 --- a/tests/ui/impl-trait/issues/issue-62742.stderr +++ b/tests/ui/impl-trait/issues/issue-62742.stderr @@ -29,7 +29,8 @@ error[E0277]: the trait bound `RawImpl<_>: Raw<_>` is not satisfied LL | WrongImpl::foo(0i32); | ^^^^^^^^^ the trait `Raw<_>` is not implemented for `RawImpl<_>` | - = help: the trait `Raw<[_]>` is implemented for `RawImpl<_>` + = help: the trait `Raw<_>` is not implemented for `RawImpl<_>` + but trait `Raw<[_]>` is implemented for it note: required by a bound in `SafeImpl` --> $DIR/issue-62742.rs:33:35 | @@ -67,7 +68,8 @@ error[E0277]: the trait bound `RawImpl<()>: Raw<()>` is not satisfied LL | WrongImpl::<()>::foo(0i32); | ^^^^^^^^^^^^^^^ the trait `Raw<()>` is not implemented for `RawImpl<()>` | - = help: the trait `Raw<[()]>` is implemented for `RawImpl<()>` + = help: the trait `Raw<()>` is not implemented for `RawImpl<()>` + but trait `Raw<[()]>` is implemented for it = help: for that trait implementation, expected `[()]`, found `()` note: required by a bound in `SafeImpl` --> $DIR/issue-62742.rs:33:35 diff --git a/tests/ui/impl-trait/nested-rpit-hrtb.stderr b/tests/ui/impl-trait/nested-rpit-hrtb.stderr index d98de650d0d88..2e95ef370c7fd 100644 --- a/tests/ui/impl-trait/nested-rpit-hrtb.stderr +++ b/tests/ui/impl-trait/nested-rpit-hrtb.stderr @@ -83,7 +83,8 @@ error[E0277]: the trait bound `for<'a> &'a (): Qux<'b>` is not satisfied LL | fn one_hrtb_mention_fn_trait_param_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl Qux<'b>> {} | ^^^^^^^^^^^^ the trait `for<'a> Qux<'b>` is not implemented for `&'a ()` | - = help: the trait `Qux<'_>` is implemented for `()` + = help: the trait `Qux<'b>` is not implemented for `&'a ()` + but trait `Qux<'_>` is implemented for `()` = help: for that trait implementation, expected `()`, found `&'a ()` error: implementation of `Bar` is not general enough @@ -101,7 +102,8 @@ error[E0277]: the trait bound `for<'a, 'b> &'a (): Qux<'b>` is not satisfied LL | fn two_htrb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Qux<'b>> {} | ^^^^^^^^^^^^^^^^^^^^ the trait `for<'a, 'b> Qux<'b>` is not implemented for `&'a ()` | - = help: the trait `Qux<'_>` is implemented for `()` + = help: the trait `Qux<'b>` is not implemented for `&'a ()` + but trait `Qux<'_>` is implemented for `()` = help: for that trait implementation, expected `()`, found `&'a ()` error: aborting due to 9 previous errors diff --git a/tests/ui/indexing/index-help.stderr b/tests/ui/indexing/index-help.stderr index 4ec28ddf87171..d4637da1426a2 100644 --- a/tests/ui/indexing/index-help.stderr +++ b/tests/ui/indexing/index-help.stderr @@ -5,7 +5,8 @@ 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 implemented for `usize` + = 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` = note: required for `Vec<{integer}>` to implement `Index` diff --git a/tests/ui/indexing/indexing-requires-a-uint.stderr b/tests/ui/indexing/indexing-requires-a-uint.stderr index 3041c2c99a108..fdcf9b030a5e8 100644 --- a/tests/ui/indexing/indexing-requires-a-uint.stderr +++ b/tests/ui/indexing/indexing-requires-a-uint.stderr @@ -5,7 +5,8 @@ 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 implemented for `usize` + = 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` = note: required for `[{integer}]` to implement `Index` = note: 1 redundant requirement hidden diff --git a/tests/ui/indexing/point-at-index-for-obligation-failure.stderr b/tests/ui/indexing/point-at-index-for-obligation-failure.stderr index 4cced22789f74..0752231356cfc 100644 --- a/tests/ui/indexing/point-at-index-for-obligation-failure.stderr +++ b/tests/ui/indexing/point-at-index-for-obligation-failure.stderr @@ -4,7 +4,8 @@ error[E0277]: the trait bound `String: Borrow<&str>` is not satisfied LL | &s | ^^ the trait `Borrow<&str>` is not implemented for `String` | - = help: the trait `Borrow` is implemented for `String` + = help: the trait `Borrow<&_>` is not implemented for `String` + but trait `Borrow<_>` is implemented for it = help: for that trait implementation, expected `str`, found `&str` = note: required for `HashMap` to implement `Index<&&str>` diff --git a/tests/ui/integral-indexing.stderr b/tests/ui/integral-indexing.stderr index 97e658617cf03..f731d303774c3 100644 --- a/tests/ui/integral-indexing.stderr +++ b/tests/ui/integral-indexing.stderr @@ -5,7 +5,8 @@ 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 implemented for `usize` + = 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` = note: required for `Vec` to implement `Index` @@ -16,7 +17,8 @@ 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 implemented for `usize` + = 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` = note: required for `Vec` to implement `Index` @@ -27,7 +29,8 @@ 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 implemented for `usize` + = 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` = note: required for `Vec` to implement `Index` @@ -38,7 +41,8 @@ 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 implemented for `usize` + = 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` = note: required for `Vec` to implement `Index` @@ -49,7 +53,8 @@ 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 implemented for `usize` + = 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` = note: required for `[u8]` to implement `Index` @@ -60,7 +65,8 @@ 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 implemented for `usize` + = 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` = note: required for `[u8]` to implement `Index` @@ -71,7 +77,8 @@ 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 implemented for `usize` + = 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` = note: required for `[u8]` to implement `Index` @@ -82,7 +89,8 @@ 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 implemented for `usize` + = 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` = note: required for `[u8]` to implement `Index` diff --git a/tests/ui/issues/issue-34334.stderr b/tests/ui/issues/issue-34334.stderr index e14629f5f3aa2..8213136faa1dd 100644 --- a/tests/ui/issues/issue-34334.stderr +++ b/tests/ui/issues/issue-34334.stderr @@ -18,7 +18,8 @@ LL | let sr2: Vec<(u32, _, _)> = sr.iter().map(|(faction, th_sender, th_rece | ^^^^^^^ 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<(u32, _, _)>` is 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 `()` 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 5a10c429564c4..940c1865fa398 100644 --- a/tests/ui/issues/issue-45801.stderr +++ b/tests/ui/issues/issue-45801.stderr @@ -4,7 +4,8 @@ error[E0277]: the trait bound `Params: Plugin` is not satisfied LL | req.get_ref::(); | ^^^^^^^ the trait `Plugin` is not implemented for `Params` | - = help: the trait `Plugin` is implemented for `Params` + = help: the trait `Plugin` is not implemented for `Params` + but trait `Plugin` is implemented for it = help: for that trait implementation, expected `Foo`, found `i32` error: aborting due to 1 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 128288e28f5ac..e62be48edf6bd 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 @@ -5,7 +5,8 @@ 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 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` 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,7 +27,8 @@ 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 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` 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-fixable.stderr b/tests/ui/iterators/invalid-iterator-chain-fixable.stderr index 3d3bbab881926..d6f82741c4c34 100644 --- a/tests/ui/iterators/invalid-iterator-chain-fixable.stderr +++ b/tests/ui/iterators/invalid-iterator-chain-fixable.stderr @@ -7,7 +7,8 @@ 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 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` note: the method call chain might not have had the expected associated types --> $DIR/invalid-iterator-chain-fixable.rs:5:26 @@ -124,7 +125,8 @@ 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 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 `()` note: the method call chain might not have had the expected associated types --> $DIR/invalid-iterator-chain-fixable.rs:32:15 diff --git a/tests/ui/iterators/invalid-iterator-chain.stderr b/tests/ui/iterators/invalid-iterator-chain.stderr index bc35fcd489df5..2522471b3b5e8 100644 --- a/tests/ui/iterators/invalid-iterator-chain.stderr +++ b/tests/ui/iterators/invalid-iterator-chain.stderr @@ -7,7 +7,8 @@ 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 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` note: the method call chain might not have had the expected associated types --> $DIR/invalid-iterator-chain.rs:4:26 @@ -181,7 +182,8 @@ 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 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 `()` 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/from_infer_breaking_with_unit_fallback.unit.stderr b/tests/ui/never_type/from_infer_breaking_with_unit_fallback.unit.stderr index 3b8913ccf4577..9eacab9a0b775 100644 --- a/tests/ui/never_type/from_infer_breaking_with_unit_fallback.unit.stderr +++ b/tests/ui/never_type/from_infer_breaking_with_unit_fallback.unit.stderr @@ -4,7 +4,8 @@ error[E0277]: the trait bound `E: From<()>` is not satisfied LL | >::from(never); // Should the inference fail? | ^ the trait `From<()>` is not implemented for `E` | - = help: the trait `From` is implemented for `E` + = help: the trait `From<()>` is not implemented for `E` + but trait `From` is implemented for it = help: for that trait implementation, expected `!`, found `()` error: aborting due to 1 previous error 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 f5249814c785c..d6234c8e7e15e 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 @@ -4,7 +4,8 @@ error[E0277]: the trait bound `E: From<()>` is not satisfied LL | >::from(never); | ^ the trait `From<()>` is not implemented for `E` | - = help: the trait `From` is implemented for `E` + = help: the trait `From<()>` is not implemented for `E` + but trait `From` is implemented for it = help: for that trait implementation, expected `!`, found `()` error: aborting due to 1 previous error diff --git a/tests/ui/on-unimplemented/impl-substs.stderr b/tests/ui/on-unimplemented/impl-substs.stderr index e2ba2474d6c6e..cdb9172ef0f12 100644 --- a/tests/ui/on-unimplemented/impl-substs.stderr +++ b/tests/ui/on-unimplemented/impl-substs.stderr @@ -7,7 +7,8 @@ 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 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` error: aborting due to 1 previous error diff --git a/tests/ui/on-unimplemented/on-impl.stderr b/tests/ui/on-unimplemented/on-impl.stderr index c7d2a78af6cba..d20b559def7c4 100644 --- a/tests/ui/on-unimplemented/on-impl.stderr +++ b/tests/ui/on-unimplemented/on-impl.stderr @@ -7,7 +7,8 @@ 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 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` error[E0277]: the trait bound `[i32]: Index` is not satisfied @@ -17,7 +18,8 @@ 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 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` error: aborting due to 2 previous errors diff --git a/tests/ui/on-unimplemented/slice-index.stderr b/tests/ui/on-unimplemented/slice-index.stderr index d53ecb9db0cd5..8f7169b30d401 100644 --- a/tests/ui/on-unimplemented/slice-index.stderr +++ b/tests/ui/on-unimplemented/slice-index.stderr @@ -5,7 +5,8 @@ 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 implemented for `usize` + = 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` = note: required for `[i32]` to implement `Index` diff --git a/tests/ui/str/str-idx.stderr b/tests/ui/str/str-idx.stderr index e8bbb8058faf3..0ce0c20756159 100644 --- a/tests/ui/str/str-idx.stderr +++ b/tests/ui/str/str-idx.stderr @@ -7,7 +7,8 @@ LL | let _: u8 = s[4]; = 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 implemented for `usize` + = help: the trait `SliceIndex` is not implemented for `{integer}` + but trait `SliceIndex<[_]>` is implemented for `usize` = help: for that trait implementation, expected `[_]`, found `str` = note: required for `str` to implement `Index<{integer}>` @@ -22,7 +23,8 @@ LL | let _ = s.get(4); = 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 implemented for `usize` + = help: the trait `SliceIndex` is not implemented for `{integer}` + but 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 @@ -38,7 +40,8 @@ LL | let _ = s.get_unchecked(4); = 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 implemented for `usize` + = help: the trait `SliceIndex` is not implemented for `{integer}` + but 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 9390d689252f8..7bc46ff33b38a 100644 --- a/tests/ui/str/str-mut-idx.stderr +++ b/tests/ui/str/str-mut-idx.stderr @@ -31,7 +31,8 @@ LL | s[1usize] = bot(); | ^^^^^^ string indices are ranges of `usize` | = help: the trait `SliceIndex` is not implemented for `usize` - = help: the trait `SliceIndex<[_]>` is 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` = note: required for `str` to implement `Index` @@ -46,7 +47,8 @@ LL | s.get_mut(1); = 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 implemented for `usize` + = help: the trait `SliceIndex` is not implemented for `{integer}` + but 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 @@ -62,7 +64,8 @@ LL | s.get_unchecked_mut(1); = 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 implemented for `usize` + = help: the trait `SliceIndex` is not implemented for `{integer}` + but 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 4de91a1b99500..0733e67ea029e 100644 --- a/tests/ui/suggestions/issue-101623.stderr +++ b/tests/ui/suggestions/issue-101623.stderr @@ -7,7 +7,8 @@ LL | Trait::do_stuff({ fun(&mut *inner) }); | | the trait `Trait<'_>` is not implemented for `*mut ()` | required by a bound introduced by this call | - = help: the trait `Trait<'_>` is implemented for `()` + = help: the trait `Trait<'_>` is not implemented for `*mut ()` + but it is implemented for `()` = help: for that trait implementation, expected `()`, found `*mut ()` error: aborting due to 1 previous error diff --git a/tests/ui/suggestions/suggest-dereferencing-index.stderr b/tests/ui/suggestions/suggest-dereferencing-index.stderr index 2316acbe9da28..cd5364fcffba9 100644 --- a/tests/ui/suggestions/suggest-dereferencing-index.stderr +++ b/tests/ui/suggestions/suggest-dereferencing-index.stderr @@ -5,7 +5,8 @@ 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 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` = note: required for `[{integer}]` to implement `Index<&usize>` = note: 1 redundant requirement hidden diff --git a/tests/ui/traits/coercion-generic-bad.stderr b/tests/ui/traits/coercion-generic-bad.stderr index 26136c6f72c8b..c0553ea62c504 100644 --- a/tests/ui/traits/coercion-generic-bad.stderr +++ b/tests/ui/traits/coercion-generic-bad.stderr @@ -4,7 +4,8 @@ error[E0277]: the trait bound `Struct: Trait` is not satisfied 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: the trait `Trait` is not implemented for `Struct` + but trait `Trait<&'static str>` is implemented for it = help: for that trait implementation, expected `&'static str`, found `isize` = note: required for the cast from `Box` to `Box>` diff --git a/tests/ui/traits/negative-bounds/simple.stderr b/tests/ui/traits/negative-bounds/simple.stderr index b8d12138794bf..f8a43e605c477 100644 --- a/tests/ui/traits/negative-bounds/simple.stderr +++ b/tests/ui/traits/negative-bounds/simple.stderr @@ -28,7 +28,8 @@ error[E0277]: the trait bound `Copyable: !Copy` is not satisfied LL | not_copy::(); | ^^^^^^^^ the trait bound `Copyable: !Copy` is not satisfied | - = help: the trait `Copy` is implemented for `Copyable` + = help: the trait `Copy` is not implemented for `Copyable` + but trait `Copy` is implemented for it note: required by a bound in `not_copy` --> $DIR/simple.rs:3:16 | diff --git a/tests/ui/try-block/try-block-bad-type.stderr b/tests/ui/try-block/try-block-bad-type.stderr index d94962e403172..c67ad762a83b9 100644 --- a/tests/ui/try-block/try-block-bad-type.stderr +++ b/tests/ui/try-block/try-block-bad-type.stderr @@ -7,7 +7,8 @@ LL | Err("")?; | this can't be annotated with `?` because it has type `Result<_, &str>` | = 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: the trait `From<&str>` is not implemented for `TryFromSliceError` + but trait `From` is implemented for it = help: for that trait implementation, expected `Infallible`, found `&str` = note: required for `Result` to implement `FromResidual>` diff --git a/tests/ui/try-trait/bad-interconversion.stderr b/tests/ui/try-trait/bad-interconversion.stderr index fe28912ba0077..20fe2d721bc30 100644 --- a/tests/ui/try-trait/bad-interconversion.stderr +++ b/tests/ui/try-trait/bad-interconversion.stderr @@ -67,7 +67,8 @@ 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 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` error[E0277]: the `?` operator can only be used on `ControlFlow`s in a function that returns `ControlFlow` @@ -79,7 +80,8 @@ 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 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` error[E0277]: the `?` operator in a function that returns `ControlFlow` can only be used on other `ControlFlow`s (with the same Break type) @@ -92,7 +94,8 @@ 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: the trait `FromResidual>` is not implemented for `ControlFlow` + but trait `FromResidual>` is implemented for it = help: for that trait implementation, expected `i64`, found `u8` error: aborting due to 8 previous errors diff --git a/tests/ui/type-alias-impl-trait/constrain_in_projection.current.stderr b/tests/ui/type-alias-impl-trait/constrain_in_projection.current.stderr index c215d197db436..d96c86a2e6f16 100644 --- a/tests/ui/type-alias-impl-trait/constrain_in_projection.current.stderr +++ b/tests/ui/type-alias-impl-trait/constrain_in_projection.current.stderr @@ -4,7 +4,8 @@ error[E0277]: the trait bound `Foo: Trait` is not satisfied LL | let x = >::Assoc::default(); | ^^^ the trait `Trait` is not implemented for `Foo` | - = help: the trait `Trait<()>` is implemented for `Foo` + = help: the trait `Trait` is not implemented for `Foo` + but trait `Trait<()>` is implemented for it error: aborting due to 1 previous error diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference.current.stderr b/tests/ui/type-alias-impl-trait/nested-tait-inference.current.stderr index 34532afcbbae4..915432bbe675f 100644 --- a/tests/ui/type-alias-impl-trait/nested-tait-inference.current.stderr +++ b/tests/ui/type-alias-impl-trait/nested-tait-inference.current.stderr @@ -7,7 +7,8 @@ LL | fn foo() -> impl Foo { LL | () | -- return type was inferred to be `()` here | - = help: the trait `Foo<()>` is implemented for `()` + = help: the trait `Foo` is not implemented for `()` + but trait `Foo<()>` is implemented for it error: aborting due to 1 previous error 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 3ae3590ca7fe3..1e799f156352f 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 @@ -7,7 +7,8 @@ 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 implemented for `i32` + = help: the trait `PartialEq` is not implemented for `i32` + but trait `PartialEq` is implemented for it error: aborting due to 1 previous error diff --git a/tests/ui/typeck/suggest-similar-impls-for-root-obligation.stderr b/tests/ui/typeck/suggest-similar-impls-for-root-obligation.stderr index ab307aadec9ff..5c0d98735f7ff 100644 --- a/tests/ui/typeck/suggest-similar-impls-for-root-obligation.stderr +++ b/tests/ui/typeck/suggest-similar-impls-for-root-obligation.stderr @@ -4,7 +4,8 @@ error[E0277]: the trait bound `((),): Into` is not satisfied LL | let _: Bar = ((),).into(); | ^^^^ the trait `Foo<'_>` is not implemented for `((),)` | - = help: the trait `Foo<'_>` is implemented for `()` + = help: the trait `Foo<'_>` is not implemented for `((),)` + but it is implemented for `()` = help: for that trait implementation, expected `()`, found `((),)` note: required for `Bar` to implement `From<((),)>` --> $DIR/suggest-similar-impls-for-root-obligation.rs:7:22 From 7b9105dd8865ef10ef8d5f2f7bc3da180aec9dd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 24 Oct 2024 22:38:50 +0000 Subject: [PATCH 2/8] Trim output of E0277 in some cases Remove default note for "trait is not implemented" in favor of the more colorful diff output from the previous commit. Removes duplicated output. --- .../traits/fulfillment_errors.rs | 20 +++++++++++++++++-- tests/ui/indexing/index-help.stderr | 1 - .../indexing/indexing-requires-a-uint.stderr | 1 - tests/ui/integral-indexing.stderr | 8 -------- tests/ui/issues/issue-34334.stderr | 1 - ...e-66923-show-error-for-correct-call.stderr | 2 -- .../invalid-iterator-chain-fixable.stderr | 2 -- .../iterators/invalid-iterator-chain.stderr | 2 -- tests/ui/on-unimplemented/impl-substs.stderr | 1 - tests/ui/on-unimplemented/on-impl.stderr | 2 -- tests/ui/on-unimplemented/slice-index.stderr | 1 - tests/ui/str/str-idx.stderr | 3 --- tests/ui/str/str-mut-idx.stderr | 3 --- .../suggest-dereferencing-index.stderr | 1 - tests/ui/try-trait/bad-interconversion.stderr | 3 --- .../self-referential-2.current.stderr | 1 - 16 files changed, 18 insertions(+), 34 deletions(-) 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 358c244eca941..dd2f0ec2096b2 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 d4637da1426a2..1974e13eabcee 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 fdcf9b030a5e8..5c60a30946d37 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 f731d303774c3..e7a45c2c88dd9 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 8213136faa1dd..6562ccfdcd286 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 e62be48edf6bd..d2852093725ce 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 d6f82741c4c34..09439fe8fbd66 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 2522471b3b5e8..b810e06d0f7e4 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 cdb9172ef0f12..b85d45eba5bbc 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 d20b559def7c4..5e7e2c4ea7744 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 8f7169b30d401..0a9ebe3f088e0 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 0ce0c20756159..bedbbd9cb5029 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 7bc46ff33b38a..f09a4c329e5d8 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 cd5364fcffba9..0335d8eafde4b 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 20fe2d721bc30..bb5e5646ad294 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 1e799f156352f..e4399f2d8f4d3 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 From c6017badb4ca22b85c70916746c233340be53c97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 25 Oct 2024 02:41:39 +0000 Subject: [PATCH 3/8] Fix type shortening writing to file Make sure that we append to the file for long ty paths. Do not write the same type more than once. Shorten the calculated width a bit. --- compiler/rustc_middle/src/ty/error.rs | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs index c49824bb418cd..43d243b0584e4 100644 --- a/compiler/rustc_middle/src/ty/error.rs +++ b/compiler/rustc_middle/src/ty/error.rs @@ -1,5 +1,7 @@ use std::borrow::Cow; +use std::fs::File; use std::hash::{DefaultHasher, Hash, Hasher}; +use std::io::{Read, Write}; use std::path::PathBuf; use rustc_errors::pluralize; @@ -250,8 +252,8 @@ impl<'tcx> TyCtxt<'tcx> { } let width = self.sess.diagnostic_width(); - let length_limit = width.saturating_sub(30); - if regular.len() <= width { + let length_limit = width / 2; + if regular.len() <= width * 2 / 3 { return regular; } let short = self.ty_string_with_limit(ty, length_limit); @@ -265,7 +267,20 @@ impl<'tcx> TyCtxt<'tcx> { *path = Some(path.take().unwrap_or_else(|| { self.output_filenames(()).temp_path_ext(&format!("long-type-{hash}.txt"), None) })); - match std::fs::write(path.as_ref().unwrap(), &format!("{regular}\n")) { + let Ok(mut file) = + File::options().create(true).read(true).append(true).open(&path.as_ref().unwrap()) + else { + return regular; + }; + + // Do not write the same type to the file multiple times. + let mut contents = String::new(); + let _ = file.read_to_string(&mut contents); + if let Some(_) = contents.lines().find(|line| line == ®ular) { + return short; + } + + match write!(file, "{regular}\n") { Ok(_) => short, Err(_) => regular, } From 86b59656081d2dd03ef42d9d30d7141b1fc3b5f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 25 Oct 2024 02:41:55 +0000 Subject: [PATCH 4/8] Use `short_ty_string` --- .../src/error_reporting/traits/fulfillment_errors.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 dd2f0ec2096b2..cc56c67903105 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 @@ -1872,7 +1872,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { StringPart::normal(" implemented for `"), ]); if types_content.0 == types_content.1 { - msg.push(StringPart::normal(obligation_trait_ref.self_ty().to_string())); + let ty = + self.tcx.short_ty_string(obligation_trait_ref.self_ty(), &mut None); + msg.push(StringPart::normal(ty)); } else { msg.extend(types.0.0); } From 092ecca5b92c94ecf6ff373610e18097fb61b8a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 25 Oct 2024 04:38:48 +0000 Subject: [PATCH 5/8] Point at tail expression on rpit E0277 ``` error[E0277]: the trait bound `{gen block@$DIR/gen_block_is_coro.rs:7:5: 7:8}: Coroutine` is not satisfied --> $DIR/gen_block_is_coro.rs:6:13 | LL | fn foo() -> impl Coroutine { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Coroutine` is not implemented for `{gen block@$DIR/gen_block_is_coro.rs:7:5: 7:8}` LL | gen { yield 42 } | ---------------- return type was inferred to be `{gen block@$DIR/gen_block_is_coro.rs:7:5: 7:8}` here ``` The secondary span label is new. --- .../src/error_reporting/traits/suggestions.rs | 39 +++++++++++++------ tests/ui/async-await/async-error-span.stderr | 3 ++ .../arg-count-mismatch-on-unit-input.stderr | 5 ++- tests/ui/coroutine/gen_block_is_coro.stderr | 6 +++ .../coroutine/gen_block_is_no_future.stderr | 2 + tests/ui/coroutine/issue-88653.rs | 1 + tests/ui/coroutine/issue-88653.stderr | 18 +++++++-- ...between-expected-trait-and-found-trait.svg | 30 +++++++------- tests/ui/impl-trait/issue-55872-1.stderr | 6 +++ tests/ui/impl-trait/issue-55872-3.stderr | 3 ++ tests/ui/impl-trait/nested_impl_trait.stderr | 8 +++- .../opaque-cast-field-access-in-future.stderr | 3 ++ ...ction-mismatch-in-impl-where-clause.stderr | 3 ++ .../lifetime-elision-return-type-trait.stderr | 3 ++ tests/ui/lint/issue-106991.stderr | 3 ++ .../ui/never_type/impl_trait_fallback2.stderr | 6 +++ .../ui/never_type/impl_trait_fallback3.stderr | 3 ++ .../ui/never_type/impl_trait_fallback4.stderr | 3 ++ .../ui/type-alias-impl-trait/fallback.stderr | 5 ++- .../non-lifetime-binder-in-constraint.stderr | 3 ++ 20 files changed, 121 insertions(+), 32 deletions(-) diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 553bb61ed043b..64edeb35dd257 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -3563,17 +3563,34 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { )]); } ObligationCauseCode::OpaqueReturnType(expr_info) => { - if let Some((expr_ty, hir_id)) = expr_info { - let expr_ty = self.tcx.short_ty_string(expr_ty, long_ty_file); - let expr = self.infcx.tcx.hir().expect_expr(hir_id); - err.span_label( - expr.span, - with_forced_trimmed_paths!(format!( - "return type was inferred to be `{expr_ty}` here", - )), - ); - suggest_remove_deref(err, &expr); - } + let (expr_ty, expr) = if let Some((expr_ty, hir_id)) = expr_info { + let expr_ty = tcx.short_ty_string(expr_ty, long_ty_file); + let expr = tcx.hir().expect_expr(hir_id); + (expr_ty, expr) + } else if let Some(body_id) = tcx.hir_node_by_def_id(body_id).body_id() + && let body = tcx.hir().body(body_id) + && let hir::ExprKind::Block(block, _) = body.value.kind + && let Some(expr) = block.expr + && let Some(expr_ty) = self + .typeck_results + .as_ref() + .and_then(|typeck| typeck.node_type_opt(expr.hir_id)) + && let Some(pred) = predicate.as_clause() + && let ty::ClauseKind::Trait(pred) = pred.kind().skip_binder() + && self.can_eq(param_env, pred.self_ty(), expr_ty) + { + let expr_ty = tcx.short_ty_string(expr_ty, long_ty_file); + (expr_ty, expr) + } else { + return; + }; + err.span_label( + expr.span, + with_forced_trimmed_paths!(format!( + "return type was inferred to be `{expr_ty}` here", + )), + ); + suggest_remove_deref(err, &expr); } } } diff --git a/tests/ui/async-await/async-error-span.stderr b/tests/ui/async-await/async-error-span.stderr index 44f1583f4cc33..37b5c329a7d07 100644 --- a/tests/ui/async-await/async-error-span.stderr +++ b/tests/ui/async-await/async-error-span.stderr @@ -3,6 +3,9 @@ error[E0277]: `()` is not a future | LL | fn get_future() -> impl Future { | ^^^^^^^^^^^^^^^^^^^^^^^^ `()` is not a future +LL | +LL | panic!() + | -------- return type was inferred to be `_` here | = help: the trait `Future` is not implemented for `()` diff --git a/tests/ui/coroutine/arg-count-mismatch-on-unit-input.stderr b/tests/ui/coroutine/arg-count-mismatch-on-unit-input.stderr index c7d6507fd7940..839299f1c94c2 100644 --- a/tests/ui/coroutine/arg-count-mismatch-on-unit-input.stderr +++ b/tests/ui/coroutine/arg-count-mismatch-on-unit-input.stderr @@ -5,7 +5,10 @@ LL | fn foo() -> impl Coroutine { | ^^^^^^^^^^^^^^^^^^ expected due to this ... LL | |_: ()| {} - | ------- found signature defined here + | ---------- + | | + | found signature defined here + | return type was inferred to be `{coroutine@$DIR/arg-count-mismatch-on-unit-input.rs:8:5: 8:12}` here | = note: expected coroutine signature `fn(u8) -> _` found coroutine signature `fn(()) -> _` diff --git a/tests/ui/coroutine/gen_block_is_coro.stderr b/tests/ui/coroutine/gen_block_is_coro.stderr index afcdce1d58dfc..083e738f3ece7 100644 --- a/tests/ui/coroutine/gen_block_is_coro.stderr +++ b/tests/ui/coroutine/gen_block_is_coro.stderr @@ -3,18 +3,24 @@ error[E0277]: the trait bound `{gen block@$DIR/gen_block_is_coro.rs:7:5: 7:8}: C | LL | fn foo() -> impl Coroutine { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Coroutine` is not implemented for `{gen block@$DIR/gen_block_is_coro.rs:7:5: 7:8}` +LL | gen { yield 42 } + | ---------------- return type was inferred to be `{gen block@$DIR/gen_block_is_coro.rs:7:5: 7:8}` here error[E0277]: the trait bound `{gen block@$DIR/gen_block_is_coro.rs:11:5: 11:8}: Coroutine` is not satisfied --> $DIR/gen_block_is_coro.rs:10:13 | LL | fn bar() -> impl Coroutine { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Coroutine` is not implemented for `{gen block@$DIR/gen_block_is_coro.rs:11:5: 11:8}` +LL | gen { yield 42 } + | ---------------- return type was inferred to be `{gen block@$DIR/gen_block_is_coro.rs:11:5: 11:8}` here error[E0277]: the trait bound `{gen block@$DIR/gen_block_is_coro.rs:15:5: 15:8}: Coroutine` is not satisfied --> $DIR/gen_block_is_coro.rs:14:13 | LL | fn baz() -> impl Coroutine { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Coroutine` is not implemented for `{gen block@$DIR/gen_block_is_coro.rs:15:5: 15:8}` +LL | gen { yield 42 } + | ---------------- return type was inferred to be `{gen block@$DIR/gen_block_is_coro.rs:15:5: 15:8}` here error: aborting due to 3 previous errors diff --git a/tests/ui/coroutine/gen_block_is_no_future.stderr b/tests/ui/coroutine/gen_block_is_no_future.stderr index bf0985a76a28e..43e18dbc2a9c1 100644 --- a/tests/ui/coroutine/gen_block_is_no_future.stderr +++ b/tests/ui/coroutine/gen_block_is_no_future.stderr @@ -3,6 +3,8 @@ error[E0277]: `{gen block@$DIR/gen_block_is_no_future.rs:5:5: 5:8}` is not a fut | LL | fn foo() -> impl std::future::Future { | ^^^^^^^^^^^^^^^^^^^^^^^^ `{gen block@$DIR/gen_block_is_no_future.rs:5:5: 5:8}` is not a future +LL | gen { yield 42 } + | ---------------- return type was inferred to be `{gen block@$DIR/gen_block_is_no_future.rs:5:5: 5:8}` here | = help: the trait `Future` is not implemented for `{gen block@$DIR/gen_block_is_no_future.rs:5:5: 5:8}` diff --git a/tests/ui/coroutine/issue-88653.rs b/tests/ui/coroutine/issue-88653.rs index 3afd12a209379..b5936c7960de4 100644 --- a/tests/ui/coroutine/issue-88653.rs +++ b/tests/ui/coroutine/issue-88653.rs @@ -14,6 +14,7 @@ fn foo(bar: bool) -> impl Coroutine<(bool,)> { #[coroutine] |bar| { //~^ NOTE: found signature defined here + //~| NOTE: return type was inferred to be if bar { yield bar; } diff --git a/tests/ui/coroutine/issue-88653.stderr b/tests/ui/coroutine/issue-88653.stderr index 8a23ad17b8b37..ef0cc11dde8e8 100644 --- a/tests/ui/coroutine/issue-88653.stderr +++ b/tests/ui/coroutine/issue-88653.stderr @@ -1,11 +1,21 @@ error[E0631]: type mismatch in coroutine arguments --> $DIR/issue-88653.rs:8:22 | -LL | fn foo(bar: bool) -> impl Coroutine<(bool,)> { - | ^^^^^^^^^^^^^^^^^^^^^^^ expected due to this +LL | fn foo(bar: bool) -> impl Coroutine<(bool,)> { + | ^^^^^^^^^^^^^^^^^^^^^^^ expected due to this ... -LL | |bar| { - | ----- found signature defined here +LL | |bar| { + | ----- + | | + | _____found signature defined here + | | +LL | | +LL | | +LL | | if bar { +LL | | yield bar; +LL | | } +LL | | } + | |_____- return type was inferred to be `{coroutine@$DIR/issue-88653.rs:15:5: 15:10}` here | = note: expected coroutine signature `fn((bool,)) -> _` found coroutine signature `fn(bool) -> _` diff --git a/tests/ui/impl-trait/diagnostics/highlight-difference-between-expected-trait-and-found-trait.svg b/tests/ui/impl-trait/diagnostics/highlight-difference-between-expected-trait-and-found-trait.svg index 277fd1536bc71..1a79a9d7efa25 100644 --- a/tests/ui/impl-trait/diagnostics/highlight-difference-between-expected-trait-and-found-trait.svg +++ b/tests/ui/impl-trait/diagnostics/highlight-difference-between-expected-trait-and-found-trait.svg @@ -1,4 +1,4 @@ - + diff --git a/tests/ui/impl-trait/issue-55872-1.stderr b/tests/ui/impl-trait/issue-55872-1.stderr index 8912cce1b4b5b..2ccca0b562c06 100644 --- a/tests/ui/impl-trait/issue-55872-1.stderr +++ b/tests/ui/impl-trait/issue-55872-1.stderr @@ -12,6 +12,9 @@ error[E0277]: the trait bound `S: Copy` is not satisfied in `(S, T)` | LL | fn foo() -> Self::E { | ^^^^^^^ within `(S, T)`, the trait `Copy` is not implemented for `S` +... +LL | (S::default(), T::default()) + | ---------------------------- return type was inferred to be `(S, T)` here | = note: required because it appears within the type `(S, T)` help: consider further restricting this bound @@ -24,6 +27,9 @@ error[E0277]: the trait bound `T: Copy` is not satisfied in `(S, T)` | LL | fn foo() -> Self::E { | ^^^^^^^ within `(S, T)`, the trait `Copy` is not implemented for `T` +... +LL | (S::default(), T::default()) + | ---------------------------- return type was inferred to be `(S, T)` here | = note: required because it appears within the type `(S, T)` help: consider further restricting this bound diff --git a/tests/ui/impl-trait/issue-55872-3.stderr b/tests/ui/impl-trait/issue-55872-3.stderr index f892da2a5353b..98e9fbf415341 100644 --- a/tests/ui/impl-trait/issue-55872-3.stderr +++ b/tests/ui/impl-trait/issue-55872-3.stderr @@ -3,6 +3,9 @@ error[E0277]: the trait bound `{async block@$DIR/issue-55872-3.rs:15:9: 15:14}: | LL | fn foo() -> Self::E { | ^^^^^^^ the trait `Copy` is not implemented for `{async block@$DIR/issue-55872-3.rs:15:9: 15:14}` +LL | +LL | async {} + | -------- return type was inferred to be `{async block@$DIR/issue-55872-3.rs:15:9: 15:14}` here error: aborting due to 1 previous error diff --git a/tests/ui/impl-trait/nested_impl_trait.stderr b/tests/ui/impl-trait/nested_impl_trait.stderr index 31c3e0c901365..d01c5961e819e 100644 --- a/tests/ui/impl-trait/nested_impl_trait.stderr +++ b/tests/ui/impl-trait/nested_impl_trait.stderr @@ -46,7 +46,9 @@ error[E0277]: the trait bound `impl Debug: From>` is not satisfie --> $DIR/nested_impl_trait.rs:6:46 | LL | fn bad_in_ret_position(x: impl Into) -> impl Into { x } - | ^^^^^^^^^^^^^^^^^^^^^ the trait `From>` is not implemented for `impl Debug` + | ^^^^^^^^^^^^^^^^^^^^^ - return type was inferred to be `impl Into` here + | | + | the trait `From>` is not implemented for `impl Debug` | = help: the trait `Into` is implemented for `T` = note: required for `impl Into` to implement `Into` @@ -55,7 +57,9 @@ error[E0277]: the trait bound `impl Debug: From>` is not satisfie --> $DIR/nested_impl_trait.rs:19:34 | LL | fn bad(x: impl Into) -> impl Into { x } - | ^^^^^^^^^^^^^^^^^^^^^ the trait `From>` is not implemented for `impl Debug` + | ^^^^^^^^^^^^^^^^^^^^^ - return type was inferred to be `impl Into` here + | | + | the trait `From>` is not implemented for `impl Debug` | = help: the trait `Into` is implemented for `T` = note: required for `impl Into` to implement `Into` diff --git a/tests/ui/impl-trait/opaque-cast-field-access-in-future.stderr b/tests/ui/impl-trait/opaque-cast-field-access-in-future.stderr index 5ade6a69d4b0d..6866f3f5350b3 100644 --- a/tests/ui/impl-trait/opaque-cast-field-access-in-future.stderr +++ b/tests/ui/impl-trait/opaque-cast-field-access-in-future.stderr @@ -3,6 +3,9 @@ error[E0283]: type annotations needed | LL | fn run() -> Foo> { | ^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type +LL | +LL | loop {} + | ------- return type was inferred to be `!` here | = note: cannot satisfy `_: Future` diff --git a/tests/ui/impl-trait/projection-mismatch-in-impl-where-clause.stderr b/tests/ui/impl-trait/projection-mismatch-in-impl-where-clause.stderr index fa71adc63809f..96e18f1f1cb74 100644 --- a/tests/ui/impl-trait/projection-mismatch-in-impl-where-clause.stderr +++ b/tests/ui/impl-trait/projection-mismatch-in-impl-where-clause.stderr @@ -3,6 +3,9 @@ error[E0271]: type mismatch resolving `<() as Super>::Assoc == ()` | LL | fn test() -> impl Test { | ^^^^^^^^^ type mismatch resolving `<() as Super>::Assoc == ()` +LL | +LL | () + | -- return type was inferred to be `()` here | note: expected this to be `()` --> $DIR/projection-mismatch-in-impl-where-clause.rs:6:18 diff --git a/tests/ui/lifetimes/lifetime-elision-return-type-trait.stderr b/tests/ui/lifetimes/lifetime-elision-return-type-trait.stderr index 1664466df3cb3..f26d6b8d0be13 100644 --- a/tests/ui/lifetimes/lifetime-elision-return-type-trait.stderr +++ b/tests/ui/lifetimes/lifetime-elision-return-type-trait.stderr @@ -3,6 +3,9 @@ error[E0277]: the trait bound `Result<(), _>: Future` is not satisfied | LL | fn foo() -> impl Future> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Future` is not implemented for `Result<(), _>` +LL | +LL | Ok(()) + | ------ return type was inferred to be `Result<(), _>` here | help: this trait has no implementations, consider adding one --> $DIR/lifetime-elision-return-type-trait.rs:1:1 diff --git a/tests/ui/lint/issue-106991.stderr b/tests/ui/lint/issue-106991.stderr index 9b4fab68102e2..0441a6377d088 100644 --- a/tests/ui/lint/issue-106991.stderr +++ b/tests/ui/lint/issue-106991.stderr @@ -3,6 +3,9 @@ error[E0271]: expected `foo` to be a fn item that returns `i32`, but it returns | LL | fn bar() -> impl Iterator { | ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `()` +... +LL | x.iter_mut().map(foo) + | --------------------- return type was inferred to be `Map>, for<'a> fn(&'a mut Vec) {foo}>` here | = note: required for `Map>, for<'a> fn(&'a mut Vec) {foo}>` to implement `Iterator` diff --git a/tests/ui/never_type/impl_trait_fallback2.stderr b/tests/ui/never_type/impl_trait_fallback2.stderr index 78cc83bdbfadb..4c32dce465b85 100644 --- a/tests/ui/never_type/impl_trait_fallback2.stderr +++ b/tests/ui/never_type/impl_trait_fallback2.stderr @@ -3,6 +3,9 @@ error[E0277]: the trait bound `(): T` is not satisfied | LL | fn should_ret_unit() -> impl T { | ^^^^^^ the trait `T` is not implemented for `()` +LL | +LL | panic!() + | -------- return type was inferred to be `_` here | = help: the trait `T` is implemented for `i32` @@ -11,6 +14,9 @@ error[E0277]: the trait bound `(): T` is not satisfied | LL | fn a() -> Foo { | ^^^ the trait `T` is not implemented for `()` +LL | +LL | panic!() + | -------- return type was inferred to be `_` here | = help: the trait `T` is implemented for `i32` diff --git a/tests/ui/never_type/impl_trait_fallback3.stderr b/tests/ui/never_type/impl_trait_fallback3.stderr index e2246eea17c61..fde8d0896dda2 100644 --- a/tests/ui/never_type/impl_trait_fallback3.stderr +++ b/tests/ui/never_type/impl_trait_fallback3.stderr @@ -3,6 +3,9 @@ error[E0277]: the trait bound `(): T` is not satisfied | LL | fn a() -> Foo { | ^^^ the trait `T` is not implemented for `()` +... +LL | panic!() + | -------- return type was inferred to be `_` here | help: this trait has no implementations, consider adding one --> $DIR/impl_trait_fallback3.rs:5:1 diff --git a/tests/ui/never_type/impl_trait_fallback4.stderr b/tests/ui/never_type/impl_trait_fallback4.stderr index 8f6b5cfea68a9..c4fc949373ae4 100644 --- a/tests/ui/never_type/impl_trait_fallback4.stderr +++ b/tests/ui/never_type/impl_trait_fallback4.stderr @@ -3,6 +3,9 @@ error[E0277]: the trait bound `(): T` is not satisfied | LL | fn foo() -> impl T { | ^^^^^^ the trait `T` is not implemented for `()` +LL | +LL | panic!() + | -------- return type was inferred to be `_` here | help: this trait has no implementations, consider adding one --> $DIR/impl_trait_fallback4.rs:3:1 diff --git a/tests/ui/type-alias-impl-trait/fallback.stderr b/tests/ui/type-alias-impl-trait/fallback.stderr index 5250252a0da44..c909ab66f0ee2 100644 --- a/tests/ui/type-alias-impl-trait/fallback.stderr +++ b/tests/ui/type-alias-impl-trait/fallback.stderr @@ -4,7 +4,10 @@ error[E0283]: type annotations needed LL | fn unconstrained_foo() -> Wrapper { | ------------ type must be known at this point LL | Wrapper::Second - | ^^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the enum `Wrapper` + | ^^^^^^^^^^^^^^^ + | | + | cannot infer type of the type parameter `T` declared on the enum `Wrapper` + | return type was inferred to be `Wrapper<_>` here | = note: cannot satisfy `_: Copy` help: consider specifying the generic argument diff --git a/tests/ui/type-alias-impl-trait/non-lifetime-binder-in-constraint.stderr b/tests/ui/type-alias-impl-trait/non-lifetime-binder-in-constraint.stderr index fa3306ff11fa0..6e5bd34ce3817 100644 --- a/tests/ui/type-alias-impl-trait/non-lifetime-binder-in-constraint.stderr +++ b/tests/ui/type-alias-impl-trait/non-lifetime-binder-in-constraint.stderr @@ -17,6 +17,9 @@ error[E0277]: the trait bound `{integer}: Trait<()>` is not satisfied | LL | fn produce() -> impl for Trait<(), Assoc = impl Trait> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait<()>` is not implemented for `{integer}` +... +LL | 16 + | -- return type was inferred to be `{integer}` here | help: this trait has no implementations, consider adding one --> $DIR/non-lifetime-binder-in-constraint.rs:4:1 From 1a0c502183835c93f9a60433e05997b040de4f40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 25 Oct 2024 05:11:42 +0000 Subject: [PATCH 6/8] On long E0277 primary span label, move it to a `help` Long span labels don't read well. --- .../traits/fulfillment_errors.rs | 5 ++ .../async-closures/not-clone-closure.stderr | 3 +- tests/ui/async-await/coroutine-not-future.rs | 1 + .../async-await/coroutine-not-future.stderr | 30 ++++---- .../const_param_ty_bad.stderr | 3 +- tests/ui/coroutine/clone-impl.rs | 1 + tests/ui/coroutine/clone-impl.stderr | 72 +++++++++---------- tests/ui/coroutine/issue-105084.rs | 1 + tests/ui/coroutine/issue-105084.stderr | 18 ++--- ...rg-where-it-should-have-been-called.stderr | 3 +- tests/ui/suggestions/issue-84973-blacklist.rs | 1 + .../suggestions/issue-84973-blacklist.stderr | 24 +++---- .../bare-fn-no-impl-fn-ptr-99875.stderr | 3 +- tests/ui/transmutability/assoc-bound.stderr | 3 +- .../higher-ranked-fn-type.verbose.stderr | 3 +- 15 files changed, 93 insertions(+), 78 deletions(-) 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 cc56c67903105..cef704d832810 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 @@ -328,6 +328,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { } } else if let Some(custom_explanation) = safe_transmute_explanation { err.span_label(span, custom_explanation); + } else if explanation.len() > self.tcx.sess.diagnostic_width() { + // Really long types don't look good as span labels, instead move it + // to a `help`. + err.span_label(span, "unsatisfied trait bound"); + err.help(explanation); } else { err.span_label(span, explanation); } diff --git a/tests/ui/async-await/async-closures/not-clone-closure.stderr b/tests/ui/async-await/async-closures/not-clone-closure.stderr index 8d5612687db28..c2f963f9b924d 100644 --- a/tests/ui/async-await/async-closures/not-clone-closure.stderr +++ b/tests/ui/async-await/async-closures/not-clone-closure.stderr @@ -2,8 +2,9 @@ error[E0277]: the trait bound `NotClonableUpvar: Clone` is not satisfied in `{as --> $DIR/not-clone-closure.rs:32:15 | LL | not_clone.clone(); - | ^^^^^ within `{async closure@$DIR/not-clone-closure.rs:29:21: 29:34}`, the trait `Clone` is not implemented for `NotClonableUpvar` + | ^^^^^ unsatisfied trait bound | + = help: within `{async closure@$DIR/not-clone-closure.rs:29:21: 29:34}`, the trait `Clone` is not implemented for `NotClonableUpvar` note: required because it's used within this closure --> $DIR/not-clone-closure.rs:29:21 | diff --git a/tests/ui/async-await/coroutine-not-future.rs b/tests/ui/async-await/coroutine-not-future.rs index 4522743550785..de627333fe44c 100644 --- a/tests/ui/async-await/coroutine-not-future.rs +++ b/tests/ui/async-await/coroutine-not-future.rs @@ -1,4 +1,5 @@ //@ edition:2018 +//@compile-flags: --diagnostic-width=300 #![feature(coroutines, coroutine_trait, stmt_expr_attributes)] use std::future::Future; diff --git a/tests/ui/async-await/coroutine-not-future.stderr b/tests/ui/async-await/coroutine-not-future.stderr index 72921a72a9569..b0f371f6706d1 100644 --- a/tests/ui/async-await/coroutine-not-future.stderr +++ b/tests/ui/async-await/coroutine-not-future.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `impl Future: Coroutine<_>` is not satisfied - --> $DIR/coroutine-not-future.rs:35:21 + --> $DIR/coroutine-not-future.rs:36:21 | LL | takes_coroutine(async_fn()); | --------------- ^^^^^^^^^^ the trait `Coroutine<_>` is not implemented for `impl Future` @@ -7,13 +7,13 @@ LL | takes_coroutine(async_fn()); | required by a bound introduced by this call | note: required by a bound in `takes_coroutine` - --> $DIR/coroutine-not-future.rs:19:39 + --> $DIR/coroutine-not-future.rs:20:39 | LL | fn takes_coroutine(_g: impl Coroutine) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `takes_coroutine` error[E0277]: the trait bound `impl Future: Coroutine<_>` is not satisfied - --> $DIR/coroutine-not-future.rs:37:21 + --> $DIR/coroutine-not-future.rs:38:21 | LL | takes_coroutine(returns_async_block()); | --------------- ^^^^^^^^^^^^^^^^^^^^^ the trait `Coroutine<_>` is not implemented for `impl Future` @@ -21,27 +21,27 @@ LL | takes_coroutine(returns_async_block()); | required by a bound introduced by this call | note: required by a bound in `takes_coroutine` - --> $DIR/coroutine-not-future.rs:19:39 + --> $DIR/coroutine-not-future.rs:20:39 | LL | fn takes_coroutine(_g: impl Coroutine) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `takes_coroutine` -error[E0277]: the trait bound `{async block@$DIR/coroutine-not-future.rs:39:21: 39:26}: Coroutine<_>` is not satisfied - --> $DIR/coroutine-not-future.rs:39:21 +error[E0277]: the trait bound `{async block@$DIR/coroutine-not-future.rs:40:21: 40:26}: Coroutine<_>` is not satisfied + --> $DIR/coroutine-not-future.rs:40:21 | LL | takes_coroutine(async {}); - | --------------- ^^^^^^^^ the trait `Coroutine<_>` is not implemented for `{async block@$DIR/coroutine-not-future.rs:39:21: 39:26}` + | --------------- ^^^^^^^^ the trait `Coroutine<_>` is not implemented for `{async block@$DIR/coroutine-not-future.rs:40:21: 40:26}` | | | required by a bound introduced by this call | note: required by a bound in `takes_coroutine` - --> $DIR/coroutine-not-future.rs:19:39 + --> $DIR/coroutine-not-future.rs:20:39 | LL | fn takes_coroutine(_g: impl Coroutine) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `takes_coroutine` error[E0277]: `impl Coroutine` is not a future - --> $DIR/coroutine-not-future.rs:43:18 + --> $DIR/coroutine-not-future.rs:44:18 | LL | takes_future(returns_coroutine()); | ------------ ^^^^^^^^^^^^^^^^^^^ `impl Coroutine` is not a future @@ -50,13 +50,13 @@ LL | takes_future(returns_coroutine()); | = help: the trait `Future` is not implemented for `impl Coroutine` note: required by a bound in `takes_future` - --> $DIR/coroutine-not-future.rs:18:26 + --> $DIR/coroutine-not-future.rs:19:26 | LL | fn takes_future(_f: impl Future) {} | ^^^^^^^^^^^^^^^^^^^ required by this bound in `takes_future` -error[E0277]: `{coroutine@$DIR/coroutine-not-future.rs:47:9: 47:14}` is not a future - --> $DIR/coroutine-not-future.rs:47:9 +error[E0277]: `{coroutine@$DIR/coroutine-not-future.rs:48:9: 48:14}` is not a future + --> $DIR/coroutine-not-future.rs:48:9 | LL | takes_future( | ------------ required by a bound introduced by this call @@ -65,11 +65,11 @@ LL | / |ctx| { LL | | LL | | ctx = yield (); LL | | }, - | |_________^ `{coroutine@$DIR/coroutine-not-future.rs:47:9: 47:14}` is not a future + | |_________^ `{coroutine@$DIR/coroutine-not-future.rs:48:9: 48:14}` is not a future | - = help: the trait `Future` is not implemented for `{coroutine@$DIR/coroutine-not-future.rs:47:9: 47:14}` + = help: the trait `Future` is not implemented for `{coroutine@$DIR/coroutine-not-future.rs:48:9: 48:14}` note: required by a bound in `takes_future` - --> $DIR/coroutine-not-future.rs:18:26 + --> $DIR/coroutine-not-future.rs:19:26 | LL | fn takes_future(_f: impl Future) {} | ^^^^^^^^^^^^^^^^^^^ required by this bound in `takes_future` diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_bad.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_bad.stderr index 694f5a5c1a9da..4c8a5e46751c9 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_bad.stderr +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_bad.stderr @@ -20,10 +20,11 @@ error[E0277]: `{closure@$DIR/const_param_ty_bad.rs:8:11: 8:13}` can't be used as --> $DIR/const_param_ty_bad.rs:8:11 | LL | check(|| {}); - | ----- ^^^^^ the trait `UnsizedConstParamTy` is not implemented for closure `{closure@$DIR/const_param_ty_bad.rs:8:11: 8:13}` + | ----- ^^^^^ unsatisfied trait bound | | | required by a bound introduced by this call | + = help: the trait `UnsizedConstParamTy` is not implemented for closure `{closure@$DIR/const_param_ty_bad.rs:8:11: 8:13}` note: required by a bound in `check` --> $DIR/const_param_ty_bad.rs:4:18 | diff --git a/tests/ui/coroutine/clone-impl.rs b/tests/ui/coroutine/clone-impl.rs index 94420e56a2261..b07fad18aee1e 100644 --- a/tests/ui/coroutine/clone-impl.rs +++ b/tests/ui/coroutine/clone-impl.rs @@ -1,6 +1,7 @@ // gate-test-coroutine_clone // Verifies that non-static coroutines can be cloned/copied if all their upvars and locals held // across awaits can be cloned/copied. +//@compile-flags: --diagnostic-width=300 #![feature(coroutines, coroutine_clone, stmt_expr_attributes)] diff --git a/tests/ui/coroutine/clone-impl.stderr b/tests/ui/coroutine/clone-impl.stderr index 1256c97a02fc1..ed933fe784edd 100644 --- a/tests/ui/coroutine/clone-impl.stderr +++ b/tests/ui/coroutine/clone-impl.stderr @@ -1,76 +1,76 @@ -error[E0277]: the trait bound `Vec: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:43:5: 43:12}` - --> $DIR/clone-impl.rs:49:5 +error[E0277]: the trait bound `Vec: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:44:5: 44:12}` + --> $DIR/clone-impl.rs:50:5 | LL | move || { - | ------- within this `{coroutine@$DIR/clone-impl.rs:43:5: 43:12}` + | ------- within this `{coroutine@$DIR/clone-impl.rs:44:5: 44:12}` ... LL | check_copy(&gen_clone_0); - | ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:43:5: 43:12}`, the trait `Copy` is not implemented for `Vec` + | ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:44:5: 44:12}`, the trait `Copy` is not implemented for `Vec` | note: captured value does not implement `Copy` - --> $DIR/clone-impl.rs:47:14 + --> $DIR/clone-impl.rs:48:14 | LL | drop(clonable_0); | ^^^^^^^^^^ has type `Vec` which does not implement `Copy` note: required by a bound in `check_copy` - --> $DIR/clone-impl.rs:89:18 + --> $DIR/clone-impl.rs:90:18 | LL | fn check_copy(_x: &T) {} | ^^^^ required by this bound in `check_copy` -error[E0277]: the trait bound `Vec: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:43:5: 43:12}` - --> $DIR/clone-impl.rs:49:5 +error[E0277]: the trait bound `Vec: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:44:5: 44:12}` + --> $DIR/clone-impl.rs:50:5 | LL | move || { - | ------- within this `{coroutine@$DIR/clone-impl.rs:43:5: 43:12}` + | ------- within this `{coroutine@$DIR/clone-impl.rs:44:5: 44:12}` ... LL | check_copy(&gen_clone_0); - | ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:43:5: 43:12}`, the trait `Copy` is not implemented for `Vec` + | ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:44:5: 44:12}`, the trait `Copy` is not implemented for `Vec` | note: coroutine does not implement `Copy` as this value is used across a yield - --> $DIR/clone-impl.rs:45:9 + --> $DIR/clone-impl.rs:46:9 | LL | let v = vec!['a']; | - has type `Vec` which does not implement `Copy` LL | yield; | ^^^^^ yield occurs here, with `v` maybe used later note: required by a bound in `check_copy` - --> $DIR/clone-impl.rs:89:18 + --> $DIR/clone-impl.rs:90:18 | LL | fn check_copy(_x: &T) {} | ^^^^ required by this bound in `check_copy` -error[E0277]: the trait bound `Vec: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:58:5: 58:12}` - --> $DIR/clone-impl.rs:70:5 +error[E0277]: the trait bound `Vec: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:59:5: 59:12}` + --> $DIR/clone-impl.rs:71:5 | LL | move || { - | ------- within this `{coroutine@$DIR/clone-impl.rs:58:5: 58:12}` + | ------- within this `{coroutine@$DIR/clone-impl.rs:59:5: 59:12}` ... LL | check_copy(&gen_clone_1); - | ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:58:5: 58:12}`, the trait `Copy` is not implemented for `Vec` + | ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:59:5: 59:12}`, the trait `Copy` is not implemented for `Vec` | note: captured value does not implement `Copy` - --> $DIR/clone-impl.rs:68:14 + --> $DIR/clone-impl.rs:69:14 | LL | drop(clonable_1); | ^^^^^^^^^^ has type `Vec` which does not implement `Copy` note: required by a bound in `check_copy` - --> $DIR/clone-impl.rs:89:18 + --> $DIR/clone-impl.rs:90:18 | LL | fn check_copy(_x: &T) {} | ^^^^ required by this bound in `check_copy` -error[E0277]: the trait bound `Vec: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:58:5: 58:12}` - --> $DIR/clone-impl.rs:70:5 +error[E0277]: the trait bound `Vec: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:59:5: 59:12}` + --> $DIR/clone-impl.rs:71:5 | LL | move || { - | ------- within this `{coroutine@$DIR/clone-impl.rs:58:5: 58:12}` + | ------- within this `{coroutine@$DIR/clone-impl.rs:59:5: 59:12}` ... LL | check_copy(&gen_clone_1); - | ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:58:5: 58:12}`, the trait `Copy` is not implemented for `Vec` + | ^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:59:5: 59:12}`, the trait `Copy` is not implemented for `Vec` | note: coroutine does not implement `Copy` as this value is used across a yield - --> $DIR/clone-impl.rs:64:9 + --> $DIR/clone-impl.rs:65:9 | LL | let v = vec!['a']; | - has type `Vec` which does not implement `Copy` @@ -78,27 +78,27 @@ LL | let v = vec!['a']; LL | yield; | ^^^^^ yield occurs here, with `v` maybe used later note: required by a bound in `check_copy` - --> $DIR/clone-impl.rs:89:18 + --> $DIR/clone-impl.rs:90:18 | LL | fn check_copy(_x: &T) {} | ^^^^ required by this bound in `check_copy` -error[E0277]: the trait bound `NonClone: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:79:5: 79:12}` - --> $DIR/clone-impl.rs:83:5 +error[E0277]: the trait bound `NonClone: Copy` is not satisfied in `{coroutine@$DIR/clone-impl.rs:80:5: 80:12}` + --> $DIR/clone-impl.rs:84:5 | LL | move || { - | ------- within this `{coroutine@$DIR/clone-impl.rs:79:5: 79:12}` + | ------- within this `{coroutine@$DIR/clone-impl.rs:80:5: 80:12}` ... LL | check_copy(&gen_non_clone); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:79:5: 79:12}`, the trait `Copy` is not implemented for `NonClone` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:80:5: 80:12}`, the trait `Copy` is not implemented for `NonClone` | note: captured value does not implement `Copy` - --> $DIR/clone-impl.rs:81:14 + --> $DIR/clone-impl.rs:82:14 | LL | drop(non_clonable); | ^^^^^^^^^^^^ has type `NonClone` which does not implement `Copy` note: required by a bound in `check_copy` - --> $DIR/clone-impl.rs:89:18 + --> $DIR/clone-impl.rs:90:18 | LL | fn check_copy(_x: &T) {} | ^^^^ required by this bound in `check_copy` @@ -108,22 +108,22 @@ LL + #[derive(Copy)] LL | struct NonClone; | -error[E0277]: the trait bound `NonClone: Clone` is not satisfied in `{coroutine@$DIR/clone-impl.rs:79:5: 79:12}` - --> $DIR/clone-impl.rs:85:5 +error[E0277]: the trait bound `NonClone: Clone` is not satisfied in `{coroutine@$DIR/clone-impl.rs:80:5: 80:12}` + --> $DIR/clone-impl.rs:86:5 | LL | move || { - | ------- within this `{coroutine@$DIR/clone-impl.rs:79:5: 79:12}` + | ------- within this `{coroutine@$DIR/clone-impl.rs:80:5: 80:12}` ... LL | check_clone(&gen_non_clone); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:79:5: 79:12}`, the trait `Clone` is not implemented for `NonClone` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `{coroutine@$DIR/clone-impl.rs:80:5: 80:12}`, the trait `Clone` is not implemented for `NonClone` | note: captured value does not implement `Clone` - --> $DIR/clone-impl.rs:81:14 + --> $DIR/clone-impl.rs:82:14 | LL | drop(non_clonable); | ^^^^^^^^^^^^ has type `NonClone` which does not implement `Clone` note: required by a bound in `check_clone` - --> $DIR/clone-impl.rs:90:19 + --> $DIR/clone-impl.rs:91:19 | LL | fn check_clone(_x: &T) {} | ^^^^^ required by this bound in `check_clone` diff --git a/tests/ui/coroutine/issue-105084.rs b/tests/ui/coroutine/issue-105084.rs index 4e40bc127d780..0f6168ec58b02 100644 --- a/tests/ui/coroutine/issue-105084.rs +++ b/tests/ui/coroutine/issue-105084.rs @@ -1,3 +1,4 @@ +//@compile-flags: --diagnostic-width=300 #![feature(coroutines)] #![feature(coroutine_clone)] #![feature(coroutine_trait)] diff --git a/tests/ui/coroutine/issue-105084.stderr b/tests/ui/coroutine/issue-105084.stderr index 11b5852b638d6..073f1fbea4c63 100644 --- a/tests/ui/coroutine/issue-105084.stderr +++ b/tests/ui/coroutine/issue-105084.stderr @@ -1,8 +1,8 @@ error[E0382]: borrow of moved value: `g` - --> $DIR/issue-105084.rs:38:14 + --> $DIR/issue-105084.rs:39:14 | LL | let mut g = #[coroutine] - | ----- move occurs because `g` has type `{coroutine@$DIR/issue-105084.rs:15:5: 15:7}`, which does not implement the `Copy` trait + | ----- move occurs because `g` has type `{coroutine@$DIR/issue-105084.rs:16:5: 16:7}`, which does not implement the `Copy` trait ... LL | let mut h = copy(g); | - value moved here @@ -11,7 +11,7 @@ LL | Pin::new(&mut g).resume(()); | ^^^^^^ value borrowed here after move | note: consider changing this parameter type in function `copy` to borrow instead if owning the value isn't necessary - --> $DIR/issue-105084.rs:9:21 + --> $DIR/issue-105084.rs:10:21 | LL | fn copy(x: T) -> T { | ---- ^ this parameter takes ownership of the value @@ -22,17 +22,17 @@ help: consider cloning the value if the performance cost is acceptable LL | let mut h = copy(g.clone()); | ++++++++ -error[E0277]: the trait bound `Box<(i32, ())>: Copy` is not satisfied in `{coroutine@$DIR/issue-105084.rs:15:5: 15:7}` - --> $DIR/issue-105084.rs:32:17 +error[E0277]: the trait bound `Box<(i32, ())>: Copy` is not satisfied in `{coroutine@$DIR/issue-105084.rs:16:5: 16:7}` + --> $DIR/issue-105084.rs:33:17 | LL | || { - | -- within this `{coroutine@$DIR/issue-105084.rs:15:5: 15:7}` + | -- within this `{coroutine@$DIR/issue-105084.rs:16:5: 16:7}` ... LL | let mut h = copy(g); - | ^^^^^^^ within `{coroutine@$DIR/issue-105084.rs:15:5: 15:7}`, the trait `Copy` is not implemented for `Box<(i32, ())>` + | ^^^^^^^ within `{coroutine@$DIR/issue-105084.rs:16:5: 16:7}`, the trait `Copy` is not implemented for `Box<(i32, ())>` | note: coroutine does not implement `Copy` as this value is used across a yield - --> $DIR/issue-105084.rs:22:22 + --> $DIR/issue-105084.rs:23:22 | LL | Box::new((5, yield)); | -------------^^^^^-- @@ -40,7 +40,7 @@ LL | Box::new((5, yield)); | | yield occurs here, with `Box::new((5, yield))` maybe used later | has type `Box<(i32, ())>` which does not implement `Copy` note: required by a bound in `copy` - --> $DIR/issue-105084.rs:9:12 + --> $DIR/issue-105084.rs:10:12 | LL | fn copy(x: T) -> T { | ^^^^ required by this bound in `copy` diff --git a/tests/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr b/tests/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr index 75a3ae1a83e2f..60d0263c149b4 100644 --- a/tests/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr +++ b/tests/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr @@ -20,10 +20,11 @@ error[E0277]: the trait bound `{closure@$DIR/fn-ctor-passed-as-arg-where-it-shou --> $DIR/fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:19:9 | LL | bar(closure); - | --- ^^^^^^^ the trait `T` is not implemented for closure `{closure@$DIR/fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:18:19: 18:21}` + | --- ^^^^^^^ unsatisfied trait bound | | | required by a bound introduced by this call | + = help: the trait `T` is not implemented for closure `{closure@$DIR/fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:18:19: 18:21}` note: required by a bound in `bar` --> $DIR/fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:14:16 | diff --git a/tests/ui/suggestions/issue-84973-blacklist.rs b/tests/ui/suggestions/issue-84973-blacklist.rs index edc0637636b57..7edf4d347af25 100644 --- a/tests/ui/suggestions/issue-84973-blacklist.rs +++ b/tests/ui/suggestions/issue-84973-blacklist.rs @@ -1,5 +1,6 @@ // Checks that certain traits for which we don't want to suggest borrowing // are blacklisted and don't cause the suggestion to be issued. +//@compile-flags: --diagnostic-width=300 #![feature(coroutines)] diff --git a/tests/ui/suggestions/issue-84973-blacklist.stderr b/tests/ui/suggestions/issue-84973-blacklist.stderr index c1ef1cd428e4a..a6324a824c1c3 100644 --- a/tests/ui/suggestions/issue-84973-blacklist.stderr +++ b/tests/ui/suggestions/issue-84973-blacklist.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `String: Copy` is not satisfied - --> $DIR/issue-84973-blacklist.rs:15:12 + --> $DIR/issue-84973-blacklist.rs:16:12 | LL | f_copy("".to_string()); | ------ ^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String` @@ -7,7 +7,7 @@ LL | f_copy("".to_string()); | required by a bound introduced by this call | note: required by a bound in `f_copy` - --> $DIR/issue-84973-blacklist.rs:6:14 + --> $DIR/issue-84973-blacklist.rs:7:14 | LL | fn f_copy(t: T) {} | ^^^^ required by this bound in `f_copy` @@ -18,7 +18,7 @@ LL + f_copy(""); | error[E0277]: the trait bound `S: Clone` is not satisfied - --> $DIR/issue-84973-blacklist.rs:16:13 + --> $DIR/issue-84973-blacklist.rs:17:13 | LL | f_clone(S); | ------- ^ the trait `Clone` is not implemented for `S` @@ -26,7 +26,7 @@ LL | f_clone(S); | required by a bound introduced by this call | note: required by a bound in `f_clone` - --> $DIR/issue-84973-blacklist.rs:7:15 + --> $DIR/issue-84973-blacklist.rs:8:15 | LL | fn f_clone(t: T) {} | ^^^^^ required by this bound in `f_clone` @@ -36,24 +36,24 @@ LL + #[derive(Clone)] LL | struct S; | -error[E0277]: `{static coroutine@$DIR/issue-84973-blacklist.rs:17:26: 17:35}` cannot be unpinned - --> $DIR/issue-84973-blacklist.rs:17:26 +error[E0277]: `{static coroutine@$DIR/issue-84973-blacklist.rs:18:26: 18:35}` cannot be unpinned + --> $DIR/issue-84973-blacklist.rs:18:26 | LL | f_unpin(#[coroutine] static || { yield; }); - | ------- ^^^^^^^^^^^^^^^^^^^^ the trait `Unpin` is not implemented for `{static coroutine@$DIR/issue-84973-blacklist.rs:17:26: 17:35}` + | ------- ^^^^^^^^^^^^^^^^^^^^ the trait `Unpin` is not implemented for `{static coroutine@$DIR/issue-84973-blacklist.rs:18:26: 18:35}` | | | required by a bound introduced by this call | = note: consider using the `pin!` macro consider using `Box::pin` if you need to access the pinned value outside of the current scope note: required by a bound in `f_unpin` - --> $DIR/issue-84973-blacklist.rs:8:15 + --> $DIR/issue-84973-blacklist.rs:9:15 | LL | fn f_unpin(t: T) {} | ^^^^^ required by this bound in `f_unpin` error[E0277]: the size for values of type `dyn Fn()` cannot be known at compilation time - --> $DIR/issue-84973-blacklist.rs:22:13 + --> $DIR/issue-84973-blacklist.rs:23:13 | LL | f_sized(*ref_cl); | ------- ^^^^^^^ doesn't have a size known at compile-time @@ -62,7 +62,7 @@ LL | f_sized(*ref_cl); | = help: the trait `Sized` is not implemented for `dyn Fn()` note: required by a bound in `f_sized` - --> $DIR/issue-84973-blacklist.rs:9:15 + --> $DIR/issue-84973-blacklist.rs:10:15 | LL | fn f_sized(t: T) {} | ^^^^^ required by this bound in `f_sized` @@ -73,7 +73,7 @@ LL + f_sized(ref_cl); | error[E0277]: `Rc<{integer}>` cannot be sent between threads safely - --> $DIR/issue-84973-blacklist.rs:27:12 + --> $DIR/issue-84973-blacklist.rs:28:12 | LL | f_send(rc); | ------ ^^ `Rc<{integer}>` cannot be sent between threads safely @@ -82,7 +82,7 @@ LL | f_send(rc); | = help: the trait `Send` is not implemented for `Rc<{integer}>` note: required by a bound in `f_send` - --> $DIR/issue-84973-blacklist.rs:10:14 + --> $DIR/issue-84973-blacklist.rs:11:14 | LL | fn f_send(t: T) {} | ^^^^ required by this bound in `f_send` diff --git a/tests/ui/traits/fn-pointer/bare-fn-no-impl-fn-ptr-99875.stderr b/tests/ui/traits/fn-pointer/bare-fn-no-impl-fn-ptr-99875.stderr index 0666da4c707d4..5b89158b0dba2 100644 --- a/tests/ui/traits/fn-pointer/bare-fn-no-impl-fn-ptr-99875.stderr +++ b/tests/ui/traits/fn-pointer/bare-fn-no-impl-fn-ptr-99875.stderr @@ -20,10 +20,11 @@ error[E0277]: the trait bound `{closure@$DIR/bare-fn-no-impl-fn-ptr-99875.rs:14: --> $DIR/bare-fn-no-impl-fn-ptr-99875.rs:14:11 | LL | takes(|_: Argument| -> Return { todo!() }); - | ----- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for closure `{closure@$DIR/bare-fn-no-impl-fn-ptr-99875.rs:14:11: 14:34}` + | ----- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound | | | required by a bound introduced by this call | + = help: the trait `Trait` is not implemented for closure `{closure@$DIR/bare-fn-no-impl-fn-ptr-99875.rs:14:11: 14:34}` = help: the trait `Trait` is implemented for fn pointer `fn(Argument) -> Return` note: required by a bound in `takes` --> $DIR/bare-fn-no-impl-fn-ptr-99875.rs:9:18 diff --git a/tests/ui/transmutability/assoc-bound.stderr b/tests/ui/transmutability/assoc-bound.stderr index 08d9089439645..b3c7680bf2949 100644 --- a/tests/ui/transmutability/assoc-bound.stderr +++ b/tests/ui/transmutability/assoc-bound.stderr @@ -2,8 +2,9 @@ error[E0277]: the trait bound `::AssocA: TransmuteFrom<(), Assume { alig --> $DIR/assoc-bound.rs:16:19 | LL | type AssocB = T::AssocA; - | ^^^^^^^^^ the trait `TransmuteFrom<(), Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `::AssocA` + | ^^^^^^^^^ unsatisfied trait bound | + = help: the trait `TransmuteFrom<(), Assume { alignment: false, lifetimes: false, safety: false, validity: false }>` is not implemented for `::AssocA` note: required by a bound in `B::AssocB` --> $DIR/assoc-bound.rs:9:18 | diff --git a/tests/ui/where-clauses/higher-ranked-fn-type.verbose.stderr b/tests/ui/where-clauses/higher-ranked-fn-type.verbose.stderr index bb99f4ad27762..0d8ec5f892894 100644 --- a/tests/ui/where-clauses/higher-ranked-fn-type.verbose.stderr +++ b/tests/ui/where-clauses/higher-ranked-fn-type.verbose.stderr @@ -2,8 +2,9 @@ error[E0277]: the trait bound `for $DIR/higher-ranked-fn-type.rs:20:5 | LL | called() - | ^^^^^^^^ the trait `for Foo` is not implemented for `fn(&'^1_0.Named(DefId(0:6 ~ higher_ranked_fn_type[9e51]::called::'b), "'b") ())` + | ^^^^^^^^ unsatisfied trait bound | + = help: the trait `for Foo` is not implemented for `fn(&'^1_0.Named(DefId(0:6 ~ higher_ranked_fn_type[9e51]::called::'b), "'b") ())` help: this trait has no implementations, consider adding one --> $DIR/higher-ranked-fn-type.rs:6:1 | From 143b072c629c226c77aa06f225b9326f99698900 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 25 Oct 2024 22:54:42 +0000 Subject: [PATCH 7/8] Account for negative bounds in E0277 note and suggestion Do not suggest `#[derive(Copy)]` when we wanted a `!Copy` type. Do not say "`Copy` is not implemented for `T` but `Copy` is". Do not talk about `Trait` having no implementations when `!Trait` was desired. --- .../src/error_reporting/traits/fulfillment_errors.rs | 6 +++++- .../src/error_reporting/traits/suggestions.rs | 3 +++ .../traits/negative-bounds/on-unimplemented.stderr | 6 ------ tests/ui/traits/negative-bounds/simple.stderr | 12 ------------ 4 files changed, 8 insertions(+), 19 deletions(-) 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 cef704d832810..524b413960095 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 @@ -2540,12 +2540,16 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { && self.tcx.trait_impls_of(trait_def_id).is_empty() && !self.tcx.trait_is_auto(trait_def_id) && !self.tcx.trait_is_alias(trait_def_id) + && trait_predicate.polarity() == ty::PredicatePolarity::Positive { err.span_help( self.tcx.def_span(trait_def_id), crate::fluent_generated::trait_selection_trait_has_no_impls, ); - } else if !suggested && !unsatisfied_const { + } else if !suggested + && !unsatisfied_const + && trait_predicate.polarity() == ty::PredicatePolarity::Positive + { // Can't show anything else useful, try to find similar impls. let impl_candidates = self.find_similar_impl_candidates(trait_predicate); if !self.report_similar_impl_candidates( diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index 64edeb35dd257..68aa9cffef207 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -3697,6 +3697,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { err: &mut Diag<'_>, trait_pred: ty::PolyTraitPredicate<'tcx>, ) { + if trait_pred.polarity() == ty::PredicatePolarity::Negative { + return; + } let Some(diagnostic_name) = self.tcx.get_diagnostic_name(trait_pred.def_id()) else { return; }; diff --git a/tests/ui/traits/negative-bounds/on-unimplemented.stderr b/tests/ui/traits/negative-bounds/on-unimplemented.stderr index 07483e788e5b8..ed473d5791737 100644 --- a/tests/ui/traits/negative-bounds/on-unimplemented.stderr +++ b/tests/ui/traits/negative-bounds/on-unimplemented.stderr @@ -6,12 +6,6 @@ LL | fn hello() -> impl !Foo { LL | LL | NotFoo | ------ return type was inferred to be `NotFoo` here - | -help: this trait has no implementations, consider adding one - --> $DIR/on-unimplemented.rs:4:1 - | -LL | trait Foo {} - | ^^^^^^^^^ error: aborting due to 1 previous error diff --git a/tests/ui/traits/negative-bounds/simple.stderr b/tests/ui/traits/negative-bounds/simple.stderr index f8a43e605c477..499c19bb85468 100644 --- a/tests/ui/traits/negative-bounds/simple.stderr +++ b/tests/ui/traits/negative-bounds/simple.stderr @@ -28,18 +28,11 @@ error[E0277]: the trait bound `Copyable: !Copy` is not satisfied LL | not_copy::(); | ^^^^^^^^ the trait bound `Copyable: !Copy` is not satisfied | - = help: the trait `Copy` is not implemented for `Copyable` - but trait `Copy` is implemented for it note: required by a bound in `not_copy` --> $DIR/simple.rs:3:16 | LL | fn not_copy() {} | ^^^^^ required by this bound in `not_copy` -help: consider annotating `Copyable` with `#[derive(Copy)]` - | -LL + #[derive(Copy)] -LL | struct Copyable; - | error[E0277]: the trait bound `NotNecessarilyCopyable: !Copy` is not satisfied --> $DIR/simple.rs:37:16 @@ -52,11 +45,6 @@ note: required by a bound in `not_copy` | LL | fn not_copy() {} | ^^^^^ required by this bound in `not_copy` -help: consider annotating `NotNecessarilyCopyable` with `#[derive(Copy)]` - | -LL + #[derive(Copy)] -LL | struct NotNecessarilyCopyable; - | error: aborting due to 4 previous errors From 7e0d3ed9511f17097f9c88d849321267debd4a33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 2 Nov 2024 16:58:50 +0000 Subject: [PATCH 8/8] fix tests Paths in CI can be longer than in devs' machines. --- tests/ui/coroutine/static-not-unpin.current.stderr | 8 ++++---- tests/ui/coroutine/static-not-unpin.next.stderr | 8 ++++---- tests/ui/coroutine/static-not-unpin.rs | 3 ++- tests/ui/traits/next-solver/coroutine.rs | 2 +- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/tests/ui/coroutine/static-not-unpin.current.stderr b/tests/ui/coroutine/static-not-unpin.current.stderr index 7d6260ac569e8..19a6e72ccf11c 100644 --- a/tests/ui/coroutine/static-not-unpin.current.stderr +++ b/tests/ui/coroutine/static-not-unpin.current.stderr @@ -1,15 +1,15 @@ -error[E0277]: `{static coroutine@$DIR/static-not-unpin.rs:15:5: 15:14}` cannot be unpinned - --> $DIR/static-not-unpin.rs:18:18 +error[E0277]: `{static coroutine@$DIR/static-not-unpin.rs:16:5: 16:14}` cannot be unpinned + --> $DIR/static-not-unpin.rs:19:18 | LL | assert_unpin(coroutine); - | ------------ ^^^^^^^^^ the trait `Unpin` is not implemented for `{static coroutine@$DIR/static-not-unpin.rs:15:5: 15:14}` + | ------------ ^^^^^^^^^ the trait `Unpin` is not implemented for `{static coroutine@$DIR/static-not-unpin.rs:16:5: 16:14}` | | | required by a bound introduced by this call | = note: consider using the `pin!` macro consider using `Box::pin` if you need to access the pinned value outside of the current scope note: required by a bound in `assert_unpin` - --> $DIR/static-not-unpin.rs:11:20 + --> $DIR/static-not-unpin.rs:12:20 | LL | fn assert_unpin(_: T) {} | ^^^^^ required by this bound in `assert_unpin` diff --git a/tests/ui/coroutine/static-not-unpin.next.stderr b/tests/ui/coroutine/static-not-unpin.next.stderr index 7d6260ac569e8..19a6e72ccf11c 100644 --- a/tests/ui/coroutine/static-not-unpin.next.stderr +++ b/tests/ui/coroutine/static-not-unpin.next.stderr @@ -1,15 +1,15 @@ -error[E0277]: `{static coroutine@$DIR/static-not-unpin.rs:15:5: 15:14}` cannot be unpinned - --> $DIR/static-not-unpin.rs:18:18 +error[E0277]: `{static coroutine@$DIR/static-not-unpin.rs:16:5: 16:14}` cannot be unpinned + --> $DIR/static-not-unpin.rs:19:18 | LL | assert_unpin(coroutine); - | ------------ ^^^^^^^^^ the trait `Unpin` is not implemented for `{static coroutine@$DIR/static-not-unpin.rs:15:5: 15:14}` + | ------------ ^^^^^^^^^ the trait `Unpin` is not implemented for `{static coroutine@$DIR/static-not-unpin.rs:16:5: 16:14}` | | | required by a bound introduced by this call | = note: consider using the `pin!` macro consider using `Box::pin` if you need to access the pinned value outside of the current scope note: required by a bound in `assert_unpin` - --> $DIR/static-not-unpin.rs:11:20 + --> $DIR/static-not-unpin.rs:12:20 | LL | fn assert_unpin(_: T) {} | ^^^^^ required by this bound in `assert_unpin` diff --git a/tests/ui/coroutine/static-not-unpin.rs b/tests/ui/coroutine/static-not-unpin.rs index 54148368b1392..b66a248654e95 100644 --- a/tests/ui/coroutine/static-not-unpin.rs +++ b/tests/ui/coroutine/static-not-unpin.rs @@ -1,6 +1,7 @@ //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) -//@[next] compile-flags: -Znext-solver +//@[next] compile-flags: -Znext-solver --diagnostic-width=300 +//@[current] compile-flags: --diagnostic-width=300 #![feature(coroutines, stmt_expr_attributes)] diff --git a/tests/ui/traits/next-solver/coroutine.rs b/tests/ui/traits/next-solver/coroutine.rs index bdc34842f6d5e..7f75f29e4b116 100644 --- a/tests/ui/traits/next-solver/coroutine.rs +++ b/tests/ui/traits/next-solver/coroutine.rs @@ -1,4 +1,4 @@ -//@ compile-flags: -Znext-solver +//@ compile-flags: -Znext-solver --diagnostic-width=300 //@ edition: 2021 //@ revisions: pass fail //@[pass] check-pass