有没有办法让 Rust 相信特定的关联类型与具体类型相同?
Is there a way to convince Rust that a particular associated type is the same as a concrete type?
鉴于以下特征和实现:
trait Wrapper<Type> {
type Inner : Wrapped<Type>;
fn bind<B, F>(self, f: F) -> <B as Wrapped<Type>>::Outer
where B: Wrapped<Type>, F: Fn(Self::Inner) -> <B as Wrapped<Type>>::Outer;
}
trait Wrapped<Type> {
type Outer : Wrapper<Type>;
}
struct Opt;
impl<T> Wrapped<Opt> for T {
type Outer = Option<T>;
}
impl<T> Wrapper<Opt> for Option<T> {
type Inner = T;
fn bind<B, F>(self, f: F) -> <B as Wrapped<Opt>>::Outer
where B: Wrapped<Opt>, F: Fn(Self::Inner) -> <B as Wrapped<Opt>>::Outer {
match self {
Some(a) => f(a),
None => None, // *** fails to compile
}
}
}
很明显,<B as Wrapped<Opt>>::Outer
类型必须始终是 Option<B>
,但 rustc
似乎无法弄清楚这一点:
src/main.rs:47:21: 47:25 error: mismatched types:
expected `<B as Wrapped<Opt>>::Outer`,
found `core::option::Option<_>`
(expected associated type,
found enum `core::option::Option`) [E0308]
src/main.rs:47 None => None,
^~~~
有什么办法可以让它相信这是安全的吗?我什至会接受 unsafe
解决方案,但是 mem::transmute
也是不允许的,因为它不能证明类型是相同的大小和对齐的(即使只涉及一种真实类型而不是甚至任何可能会弄乱对齐的新型包装器)。
鉴于以下特征和实现:
trait Wrapper<Type> {
type Inner : Wrapped<Type>;
fn bind<B, F>(self, f: F) -> <B as Wrapped<Type>>::Outer
where B: Wrapped<Type>, F: Fn(Self::Inner) -> <B as Wrapped<Type>>::Outer;
}
trait Wrapped<Type> {
type Outer : Wrapper<Type>;
}
struct Opt;
impl<T> Wrapped<Opt> for T {
type Outer = Option<T>;
}
impl<T> Wrapper<Opt> for Option<T> {
type Inner = T;
fn bind<B, F>(self, f: F) -> <B as Wrapped<Opt>>::Outer
where B: Wrapped<Opt>, F: Fn(Self::Inner) -> <B as Wrapped<Opt>>::Outer {
match self {
Some(a) => f(a),
None => None, // *** fails to compile
}
}
}
很明显,<B as Wrapped<Opt>>::Outer
类型必须始终是 Option<B>
,但 rustc
似乎无法弄清楚这一点:
src/main.rs:47:21: 47:25 error: mismatched types:
expected `<B as Wrapped<Opt>>::Outer`,
found `core::option::Option<_>`
(expected associated type,
found enum `core::option::Option`) [E0308]
src/main.rs:47 None => None,
^~~~
有什么办法可以让它相信这是安全的吗?我什至会接受 unsafe
解决方案,但是 mem::transmute
也是不允许的,因为它不能证明类型是相同的大小和对齐的(即使只涉及一种真实类型而不是甚至任何可能会弄乱对齐的新型包装器)。