Repository navigation
Description
The following code does not compile:
trait MyTrait1 {
type X;
fn get_val(&self) -> Self::X;
}
trait MyTrait2: MyTrait1 where <Self as MyTrait1>::X: Into<u32> {}
struct MyStruct(u32);
impl MyTrait1 for MyStruct {
type X = u32;
fn get_val(&self) -> Self::X { self.0 }
}
impl MyTrait2 for MyStruct {}
fn myfunc<T: MyTrait2>(v: &T) {
println!("{}", Into::<u32>::into(v.get_val()));
}
fn main() {
let s = MyStruct(10);
myfunc(&s);
}It fails with
error[E0277]: the trait bound `u32: std::convert::From<<T as MyTrait1>::X>` is not satisfied
--> src/main.rs:16:1
|
16 | / fn myfunc<T: MyTrait2>(v: &T) {
17 | | println!("{}", Into::<u32>::into(v.get_val()));
18 | | }
| |_^ the trait `std::convert::From<<T as MyTrait1>::X>` is not implemented for `u32`
|
= help: consider adding a `where u32: std::convert::From<<T as MyTrait1>::X>` bound
= note: required because of the requirements on the impl of `std::convert::Into<u32>` for `<T as MyTrait1>::X`
note: required by `MyTrait2`
--> src/main.rs:6:1
|
6 | trait MyTrait2: MyTrait1 where <Self as MyTrait1>::X: Into<u32> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
In fact, I haven't been able to come up with any syntax for myfunc which uses a trait bound using MyTrait2 that will compile once the trait bound X exists.
Changing the declaration of MyTrait2 to trait MyTrait2: MyTrait1<X=u32> {} does work, so it's clearly possible for super traits to put constraints on the associated types of subtraits. However I've only been able to create constraints that require the associated types to be of a particular type, not to require that they implement particular traits. I also tried trait MyTrait2: MyTrait1<X: Into<u32>> {}, however that just yielded a syntax error.
It's quite possible that I'm misunderstanding the meaning of the syntax in the original example above, and that I should create an RFC for supporting what I'm trying to accomplish above.
Activity
rkarp commentedon Oct 14, 2018
This is another issue with probably the same underlying cause as #24159. Here's how to fix your code:
Funnily enough there is no error when you remove
myfuncaltogether. I guess rustc believes it's fine to declareMytrait2as long as you never actually use it.estebank commentedon Jun 15, 2020
Current output:
A possible solution is to incorporate a new type param to restrict
MyTrait2::Xwith:estebank commentedon Feb 2, 2021
Triage: no change.
estebank commentedon Aug 3, 2023
Current output suggests a fix:
robertbastian commentedon Aug 28, 2023
Why does
myfuncneed the<T as MyTrait1>::X: Into<u32>bound? It already hasT: MyTrait2, which implies<T as MyTrait1>::X: Into<u32>.