Skip to content

Commit 4150e34

Browse files
committed
When a trait isn't implemented, but another similar impl is found, point at it:
``` error[E0277]: the trait bound `u32: Trait` is not satisfied --> $DIR/trait_objects_fail.rs:26:9 | LL | foo(&10_u32); | ^^^^^^^ the trait `Trait` is not implemented for `u32` | help: the trait `Trait<12>` is not implemented for `u32` but trait `Trait<2>` is implemented for it --> $DIR/trait_objects_fail.rs:7:1 | LL | impl Trait<2> for u32 {} | ^^^^^^^^^^^^^^^^^^^^^ = note: required for the cast from `&u32` to `&dyn Trait` ``` Pointing at the `impl` definition that *could* apply given a different self type is particularly useful when it has a blanket self type, as it might not be obvious and is not trivially greppable: ``` error[E0277]: the trait bound `RawImpl<_>: Raw<_>` is not satisfied --> $DIR/issue-62742.rs:4:5 | LL | WrongImpl::foo(0i32); | ^^^^^^^^^ unsatisfied trait bound | help: the trait `Raw<_>` is not implemented for `RawImpl<_>` but trait `Raw<[_]>` is implemented for it --> $DIR/issue-62742.rs:29:1 | LL | impl<T> Raw<[T]> for RawImpl<T> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `SafeImpl` --> $DIR/issue-62742.rs:33:35 | LL | pub struct SafeImpl<T: ?Sized, A: Raw<T>>(PhantomData<(A, T)>); | ^^^^^^ required by this bound in `SafeImpl` ```
1 parent c018ae5 commit 4150e34

31 files changed

+230
-100
lines changed

compiler/rustc_errors/src/emitter.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1526,16 +1526,17 @@ impl HumanEmitter {
15261526
label_width += 2;
15271527
}
15281528
let mut line = 0;
1529+
let mut pad = false;
15291530
for (text, style) in msgs.iter() {
15301531
let text =
15311532
self.translator.translate_message(text, args).map_err(Report::new).unwrap();
15321533
// Account for newlines to align output to its label.
1533-
for text in normalize_whitespace(&text).lines() {
1534+
for text in normalize_whitespace(&text).split('\n') {
15341535
buffer.append(
15351536
line,
15361537
&format!(
15371538
"{}{}",
1538-
if line == 0 { String::new() } else { " ".repeat(label_width) },
1539+
if pad { " ".repeat(label_width) } else { String::new() },
15391540
text
15401541
),
15411542
match style {
@@ -1544,7 +1545,9 @@ impl HumanEmitter {
15441545
},
15451546
);
15461547
line += 1;
1548+
pad = true;
15471549
}
1550+
pad = false;
15481551
// We add lines above, but if the last line has no explicit newline (which would
15491552
// yield an empty line), then we revert one line up to continue with the next
15501553
// styled text chunk on the same line as the last one from the prior one. Otherwise

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2112,7 +2112,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
21122112
msg.extend(types.1.0);
21132113
msg.push(StringPart::normal("`"));
21142114
}
2115-
err.highlighted_help(msg);
2115+
err.highlighted_span_help(self.tcx.def_span(single.impl_def_id), msg);
21162116

21172117
if let [TypeError::Sorts(exp_found)] = &terrs[..] {
21182118
let exp_found = self.resolve_vars_if_possible(*exp_found);

tests/ui/const-generics/associated-type-bound-fail.stderr

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,12 @@ error[E0277]: the trait bound `u16: Bar<N>` is not satisfied
44
LL | type Assoc = u16;
55
| ^^^ the trait `Bar<N>` is not implemented for `u16`
66
|
7-
= help: the trait `Bar<N>` is not implemented for `u16`
8-
but trait `Bar<3>` is implemented for it
7+
help: the trait `Bar<N>` is not implemented for `u16`
8+
but trait `Bar<3>` is implemented for it
9+
--> $DIR/associated-type-bound-fail.rs:7:1
10+
|
11+
LL | impl Bar<3> for u16 {}
12+
| ^^^^^^^^^^^^^^^^^^^
913
note: required by a bound in `Foo::Assoc`
1014
--> $DIR/associated-type-bound-fail.rs:4:17
1115
|

tests/ui/const-generics/defaults/rp_impl_trait_fail.stderr

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,12 @@ LL |
1818
LL | 1_u32
1919
| ----- return type was inferred to be `u32` here
2020
|
21-
= help: the trait `Traitor<N, N>` is not implemented for `u32`
22-
but trait `Traitor<N, 2>` is implemented for it
21+
help: the trait `Traitor<N, N>` is not implemented for `u32`
22+
but trait `Traitor<N, 2>` is implemented for it
23+
--> $DIR/rp_impl_trait_fail.rs:13:1
24+
|
25+
LL | impl<const N: u8> Traitor<N, 2> for u32 {}
26+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2327

2428
error[E0277]: the trait bound `u64: Traitor` is not satisfied
2529
--> $DIR/rp_impl_trait_fail.rs:21:13
@@ -30,8 +34,12 @@ LL |
3034
LL | 1_u64
3135
| ----- return type was inferred to be `u64` here
3236
|
33-
= help: the trait `Traitor<1, 1>` is not implemented for `u64`
34-
but trait `Traitor<1, 2>` is implemented for it
37+
help: the trait `Traitor<1, 1>` is not implemented for `u64`
38+
but trait `Traitor<1, 2>` is implemented for it
39+
--> $DIR/rp_impl_trait_fail.rs:14:1
40+
|
41+
LL | impl Traitor<1, 2> for u64 {}
42+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
3543

3644
error[E0284]: type annotations needed
3745
--> $DIR/rp_impl_trait_fail.rs:28:5

tests/ui/const-generics/defaults/trait_objects_fail.stderr

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,12 @@ error[E0277]: the trait bound `u32: Trait` is not satisfied
44
LL | foo(&10_u32);
55
| ^^^^^^^ the trait `Trait` is not implemented for `u32`
66
|
7-
= help: the trait `Trait<12>` is not implemented for `u32`
8-
but trait `Trait<2>` is implemented for it
7+
help: the trait `Trait<12>` is not implemented for `u32`
8+
but trait `Trait<2>` is implemented for it
9+
--> $DIR/trait_objects_fail.rs:7:1
10+
|
11+
LL | impl Trait<2> for u32 {}
12+
| ^^^^^^^^^^^^^^^^^^^^^
913
= note: required for the cast from `&u32` to `&dyn Trait`
1014

1115
error[E0277]: the trait bound `bool: Traitor<_>` is not satisfied
@@ -14,8 +18,12 @@ error[E0277]: the trait bound `bool: Traitor<_>` is not satisfied
1418
LL | bar(&true);
1519
| ^^^^^ the trait `Traitor<_>` is not implemented for `bool`
1620
|
17-
= help: the trait `Traitor<_, _>` is not implemented for `bool`
18-
but trait `Traitor<2, 3>` is implemented for it
21+
help: the trait `Traitor<_, _>` is not implemented for `bool`
22+
but trait `Traitor<2, 3>` is implemented for it
23+
--> $DIR/trait_objects_fail.rs:19:1
24+
|
25+
LL | impl Traitor<2, 3> for bool {}
26+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
1927
= note: required for the cast from `&bool` to `&dyn Traitor<_>`
2028

2129
error: aborting due to 2 previous errors

tests/ui/const-generics/defaults/wfness.stderr

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,12 @@ error[E0277]: the trait bound `(): Trait<2>` is not satisfied
1010
LL | (): Trait<N>;
1111
| ^^^^^^^^ the trait `Trait<2>` is not implemented for `()`
1212
|
13-
= help: the trait `Trait<2>` is not implemented for `()`
14-
but trait `Trait<3>` is implemented for it
13+
help: the trait `Trait<2>` is not implemented for `()`
14+
but trait `Trait<3>` is implemented for it
15+
--> $DIR/wfness.rs:5:1
16+
|
17+
LL | impl Trait<3> for () {}
18+
| ^^^^^^^^^^^^^^^^^^^^
1519
note: required by a bound in `WhereClause`
1620
--> $DIR/wfness.rs:8:9
1721
|
@@ -27,8 +31,12 @@ error[E0277]: the trait bound `(): Trait<1>` is not satisfied
2731
LL | fn foo() -> DependentDefaultWfness {
2832
| ^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait<1>` is not implemented for `()`
2933
|
30-
= help: the trait `Trait<1>` is not implemented for `()`
31-
but trait `Trait<3>` is implemented for it
34+
help: the trait `Trait<1>` is not implemented for `()`
35+
but trait `Trait<3>` is implemented for it
36+
--> $DIR/wfness.rs:5:1
37+
|
38+
LL | impl Trait<3> for () {}
39+
| ^^^^^^^^^^^^^^^^^^^^
3240
note: required by a bound in `WhereClause`
3341
--> $DIR/wfness.rs:8:9
3442
|

tests/ui/const-generics/occurs-check/unused-substs-1.stderr

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,12 @@ error[E0277]: the trait bound `A<_>: Bar<_>` is not satisfied
44
LL | let _ = A;
55
| ^ the trait `Bar<_>` is not implemented for `A<_>`
66
|
7-
= help: the trait `Bar<_>` is not implemented for `A<_>`
8-
but it is implemented for `A<{ 6 + 1 }>`
7+
help: the trait `Bar<_>` is not implemented for `A<_>`
8+
but it is implemented for `A<{ 6 + 1 }>`
9+
--> $DIR/unused-substs-1.rs:5:1
10+
|
11+
LL | impl<const N: usize> Bar<N> for A<{ 6 + 1 }> {}
12+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
913
note: required by a bound in `A`
1014
--> $DIR/unused-substs-1.rs:9:11
1115
|

tests/ui/diagnostic_namespace/do_not_recommend/as_expression.current.stderr

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,12 @@ error[E0277]: the trait bound `&str: AsExpression<Integer>` is not satisfied
44
LL | SelectInt.check("bar");
55
| ^^^^^ the trait `AsExpression<Integer>` is not implemented for `&str`
66
|
7-
= help: the trait `AsExpression<Integer>` is not implemented for `&str`
8-
but trait `AsExpression<Text>` is implemented for it
7+
help: the trait `AsExpression<Integer>` is not implemented for `&str`
8+
but trait `AsExpression<Text>` is implemented for it
9+
--> $DIR/as_expression.rs:40:1
10+
|
11+
LL | impl AsExpression<Text> for &'_ str {
12+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
913
= help: for that trait implementation, expected `Text`, found `Integer`
1014

1115
error: aborting due to 1 previous error

tests/ui/diagnostic_namespace/do_not_recommend/as_expression.next.stderr

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,12 @@ LL | SelectInt.check("bar");
66
| |
77
| required by a bound introduced by this call
88
|
9-
= help: the trait `AsExpression<Integer>` is not implemented for `&str`
10-
but trait `AsExpression<Text>` is implemented for it
9+
help: the trait `AsExpression<Integer>` is not implemented for `&str`
10+
but trait `AsExpression<Text>` is implemented for it
11+
--> $DIR/as_expression.rs:40:1
12+
|
13+
LL | impl AsExpression<Text> for &'_ str {
14+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1115
= help: for that trait implementation, expected `Text`, found `Integer`
1216
note: required by a bound in `Foo::check`
1317
--> $DIR/as_expression.rs:47:12
@@ -24,8 +28,12 @@ error[E0277]: the trait bound `&str: AsExpression<Integer>` is not satisfied
2428
LL | SelectInt.check("bar");
2529
| ^^^^^^^^^^^^^^^^^^^^^^ the trait `AsExpression<Integer>` is not implemented for `&str`
2630
|
27-
= help: the trait `AsExpression<Integer>` is not implemented for `&str`
28-
but trait `AsExpression<Text>` is implemented for it
31+
help: the trait `AsExpression<Integer>` is not implemented for `&str`
32+
but trait `AsExpression<Text>` is implemented for it
33+
--> $DIR/as_expression.rs:40:1
34+
|
35+
LL | impl AsExpression<Text> for &'_ str {
36+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2937
= help: for that trait implementation, expected `Text`, found `Integer`
3038

3139
error: aborting due to 2 previous errors

tests/ui/did_you_mean/casting-fn-item-to-fn-pointer.stderr

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ error[E0277]: a value of type `Vec<(&str, fn())>` cannot be built from an iterat
44
LL | let _: Vec<(&str, fn())> = [("foo", foo)].into_iter().collect();
55
| ^^^^^^^ value of type `Vec<(&str, fn())>` cannot be built from `std::iter::Iterator<Item=(&str, fn() {foo})>`
66
|
7-
= help: the trait `FromIterator<(&_, fn() {foo})>` is not implemented for `Vec<(&str, fn())>`
8-
but trait `FromIterator<(&_, fn())>` is implemented for it
7+
help: the trait `FromIterator<(&_, fn() {foo})>` is not implemented for `Vec<(&str, fn())>`
8+
but trait `FromIterator<(&_, fn())>` is implemented for it
9+
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
910
= help: for that trait implementation, expected `fn()`, found `fn() {foo}`
1011
= note: fn items are distinct from fn pointers
1112
= help: consider casting the fn item to a fn pointer: `foo as fn()`
@@ -25,8 +26,9 @@ error[E0277]: a value of type `Vec<fn()>` cannot be built from an iterator over
2526
LL | let _: Vec<fn()> = [foo].into_iter().collect();
2627
| ^^^^^^^ value of type `Vec<fn()>` cannot be built from `std::iter::Iterator<Item=fn() {foo}>`
2728
|
28-
= help: the trait `FromIterator<fn() {foo}>` is not implemented for `Vec<fn()>`
29-
but trait `FromIterator<fn()>` is implemented for it
29+
help: the trait `FromIterator<fn() {foo}>` is not implemented for `Vec<fn()>`
30+
but trait `FromIterator<fn()>` is implemented for it
31+
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
3032
= help: for that trait implementation, expected `fn()`, found `fn() {foo}`
3133
= note: fn items are distinct from fn pointers
3234
= help: consider casting the fn item to a fn pointer: `foo as fn()`

0 commit comments

Comments
 (0)