Open
Description
Code
#[diagnostic::on_unimplemented(note = "this is implemented on tuples of implementors too")]
trait SomeTrait {}
struct AnImplementor;
struct AnotherImplementor;
impl SomeTrait for AnImplementor {}
impl SomeTrait for AnotherImplementor {}
#[diagnostic::do_not_recommend]
impl<T: SomeTrait> SomeTrait for (T,) {}
#[diagnostic::do_not_recommend]
impl<T: SomeTrait, U: SomeTrait> SomeTrait for (T, U) {}
#[diagnostic::do_not_recommend]
impl<T: SomeTrait, U: SomeTrait, V: SomeTrait> SomeTrait for (T, U, V) {}
fn foo(_: impl SomeTrait) {}
pub fn bar() {
foo((AnImplementor, 5u32));
}
Current output
error[E0277]: the trait bound `(AnImplementor, u32): SomeTrait` is not satisfied
--> src/lib.rs:20:25
|
20 | foo((AnImplementor, 5u32));
| ^^^^ the trait `SomeTrait` is not implemented for `(AnImplementor, u32)`
|
= note: this is implemented on tuples of implementors too
= help: the following other types implement trait `SomeTrait`:
AnImplementor
AnotherImplementor
note: required by a bound in `foo`
--> src/lib.rs:17:16
|
17 | fn foo(_: impl SomeTrait) {}
| ^^^^^^^^^ required by this bound in `foo`
Desired output
error[E0277]: the trait bound `u32: SomeTrait` is not satisfied
--> src/lib.rs:21:29
|
21 | foo((AnImplementor, 5u32));
| ^^^^ the trait `SomeTrait` is not implemented for `u32`
|
= note: this is implemented on tuples of implementors too
= help: the following other types implement trait `SomeTrait`:
AnImplementor
AnotherImplementor
note: required by a bound in `foo`
--> src/lib.rs:18:20
|
18 | fn foo(_: impl SomeTrait) {}
| ^^^^^^^^^ required by this bound in `foo`
Rationale and extra context
Playground containing both with/without diagnostic attributes.
For variadic tuple implementations it's not useful to see all the tuples in the "the following other types implement trait", but they're still useful to be decomposed to only inform the user of the specific element of the tuple that is violating the trait impl.
It's interesting to see in the current error message it does point directly to the u32
, even though it refers to the type of the whole tuple.
Other cases
Without the diagnostic attributes
trait SomeTrait {}
struct AnImplementor;
struct AnotherImplementor;
impl SomeTrait for AnImplementor {}
impl SomeTrait for AnotherImplementor {}
impl<T: SomeTrait> SomeTrait for (T,) {}
impl<T: SomeTrait, U: SomeTrait> SomeTrait for (T, U) {}
impl<T: SomeTrait, U: SomeTrait, V: SomeTrait> SomeTrait for (T, U, V) {}
fn foo(_: impl SomeTrait) {}
pub fn bar() {
foo((AnImplementor, 5u32));
}
The output looks like
error[E0277]: the trait bound `u32: SomeTrait` is not satisfied
--> src/lib.rs:16:25
|
16 | foo((AnImplementor, 5u32));
| --- ^^^^ the trait `SomeTrait` is not implemented for `u32`
| |
| required by a bound introduced by this call
|
= help: the following other types implement trait `SomeTrait`:
(T, U)
(T, U, V)
(T,)
AnImplementor
AnotherImplementor
note: required for `(AnImplementor, u32)` to implement `SomeTrait`
--> src/lib.rs:10:34
|
10 | impl<T: SomeTrait, U: SomeTrait> SomeTrait for (T, U) {}
| --------- ^^^^^^^^^ ^^^^^^
| |
| unsatisfied trait bound introduced here
note: required by a bound in `foo`
--> src/lib.rs:13:16
|
13 | fn foo(_: impl SomeTrait) {}
| ^^^^^^^^^ required by this bound in `foo`
Rust Version
1.90.0-nightly (2025-06-23 706f244db581212cabf2)
Anything else?
No response