I have the following code.
use std::ops::Deref;
#[derive(Debug)]
struct Foo;
// HealthReporter (not a marker)
trait A {
type Aa;
}
impl A for Foo {
type Aa = ();
}
// impl A for smart pointers to anything impl A
impl<T, I> A for T where
T: Deref<Target = I>,
I: A + ?Sized,
{
type Aa = I::Aa;
}
// HealthAware (marker)
trait B {}
impl<T: A + ?Sized> B for T {}
fn baz<T: B>(b: T) {}
fn main() {
let foo: Box<dyn A<Aa = ()>> = Box::new(Foo);
let bar: Box<dyn B> = Box::new(Foo);
baz(foo);
baz(bar); // fails
}
Also available on the playground.
I would like for Box<dyn B>
to satisfy the trait bounds :B
, but doing so results in:
error[E0277]: the trait bound `dyn B: Deref` is not satisfied
--> src/main.rs:35:9
|
35 | baz(bar);
| --- ^^^ the trait `Deref` is not implemented for `dyn B`, which is required by `Box<dyn B>: B`
| |
| required by a bound introduced by this call
|
note: required for `dyn B` to implement `A`
--> src/main.rs:16:12
|
16 | impl<T, I> A for T where
| ^ ^
17 | T: Deref<Target = I>,
| ----------------- unsatisfied trait bound introduced here
= note: 1 redundant requirement hidden
= note: required for `Box<dyn B>` to implement `A`
note: required for `Box<dyn B>` to implement `B`
--> src/main.rs:26:21
|
26 | impl<T: A + ?Sized> B for T {}
| - ^ ^
| |
| unsatisfied trait bound introduced here
note: required by a bound in `baz`
--> src/main.rs:28:11
|
28 | fn baz<T: B>(b: T) {}
| ^ required by this bound in `baz`
Am I thinking about this wrong? Is there some piece I haven't implemented? Does this require a fundamental capability that Rust doesn't have (...something about coercion...)?