pub trait Named {
fn name() -> &'static str;
}
pub trait Backend<'a>: Named {
type Settings: Settings;
}
pub trait Settings {}
impl<'a, N: Settings + Named, T: Backend<'a, Settings = N>> Named for T {
fn name() -> &'static str {
N::name()
}
}
Yields this error:
error[E0207]: the type parameter `N` is not constrained by the impl trait, self type, or predicates
--> src/lib.rs:11:10
|
11 | impl<'a, N: Settings + Named, T: Backend<'a, Settings = N>> Named for T {
| ^ unconstrained type parameter
Isn't it enough constrained in the way that its used as Settings = N? What is even more puzzling to me is that it compiles when I remove the life time ( playground ):
pub trait Named {
fn name() -> &'static str;
}
pub trait Backend: Named {
type Settings: Settings;
}
pub trait Settings {}
impl<N: Settings + Named, T: Backend<Settings = N>> Named for T {
fn name() -> &'static str {
N::name()
}
}
Any ideas?
The idea of the code is that a Backend can either have a Settings type that determines the name of the Backend or if it has to specify it by implementing Named manually.
Great advice! Both solutions do work. But now a new error surfaced. It seems that the blanket impl is also applying to a T where the T::Settings does not implement Named. Consequently it says that there are conflicting implementations. I added this struct. ( playground ):
struct CoolBackend {}
impl Named for CoolBackend {
fn name() -> &'static str {
"CoolBackend"
}
}
impl Settings for () {}
impl<'a> Backend<'a> for CoolBackend {
type Settings = ();
}
Got this error:
error[E0119]: conflicting implementations of trait `Named` for type `CoolBackend`:
--> src/lib.rs:26:1
|
11 | / impl<'a, T: Backend<'a>> Named for T
12 | | where
13 | | T::Settings: Named + Settings
14 | | {
... |
17 | | }
18 | | }
| |_- first implementation here
...
26 | impl Named for CoolBackend {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `CoolBackend`
I guess what I am trying to do falls under specialization. Maybe it is my C++ way of thinking that I always hit this roadblock. I have to come up with other abstractions.
I just thought because this blanket impl does not apply at it does not count.