如何告诉编译器内部字段实现特征或通用特征只有 2 个变体?

How to tell compiler that inner field implements traits or that generic trait has only 2 variants?

我有 2 个低级类型,StateBaseStates 可以是 observed,但根据视角的不同,有些人会看到完整的 State,而其他人只会看到 Base.

State 构成了高级类型的基础,但我找不到一种方法来检查这种矛盾的 observe 行为。

这里是用通用性和简单的 impl trait bound 来实现它的归结尝试:

// Those two things can be observed..
struct State;
struct Base;

// .. but from 2 different views.
trait Observable<Obs> {
    fn observe(&self) -> Obs;
}
// Some view states as states.
impl Observable<State> for State {
    fn observe(&self) -> State {
        State {}
    }
}
// Some view states as bases.
impl Observable<Base> for State {
    fn observe(&self) -> Base {
        Base {}
    }
}

// States serve as basis for other types..
struct Container {
    field: State,
} // .. there are quite a few like this one.

// Now, when it's time to observe the inner state of the container..
fn process<Obs>(state: &impl Observable<Obs>, container: &Container) -> (Obs, Obs) {
    (
        state.observe(), // (this typechecks fine)
        // .. how to annotate this so the compiler is confident that
        // container.field *does* implements Observable<Obs>?
        container.field.observe(),
    )
}

fn main() {
    // Build up data.
    let s = State {};
    let c = Container { field: State {} };
    // And observe it.
    let o_full: (State, State) = process(&s, &c);
    let o_partial: (Base, Base) = process(&s, &c);
}

产生错误

error[E0277]: the trait bound `State: Observable<Obs>` is not satisfied
  --> src/main.rs:33:25
   |
33 |         container.field.observe(),
   |                         ^^^^^^^ the trait `Observable<Obs>` is not implemented for `State`

我相信这可以通过泛型和单态化来实现,因为一切都是静态已知的。

我也有点理解为什么编译器担心 Observe<Obs> 可能无法在 State 上为任何 Obs 类型实现。

但是编译器在这里缺少信息,因为我仍然比它知道的更多:

也许我漏掉了什么,但你不能说 State 实现了 Observable<Obs> 吗?即:

fn process<Obs>(state: &impl Observable<Obs>, container: &Container) -> (Obs, Obs)
    where State: Observable<Obs> // <--- tell compiler that State satisfies Observable<Obs>
{
    (
        state.observe(),
        container.field.observe(),
    )
}