2015-12-01 24 views
3

鑑於以下特點和實現:有沒有辦法讓Rust相信特定的關聯類型與具體類型相同?

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也是不允許的,因爲它不能證明類型是相同的大小和對齊(即使只涉及一個實際類型,甚至沒有任何新類型的包裝可能會搞砸對準)。

回答

4

這很可能是一個錯誤(this onethat one,我不確定)。在解決之前,我只能想到做一些習慣性的不安全欺騙。這是一個transmute函數,在運行時進行大小相等檢查。

unsafe fn runtime_transmute<T, U>(t: T) -> U { 
    assert_eq!(std::mem::size_of::<T>(), std::mem::size_of::<U>()); 
    std::ptr::read(&t as *const _ as *const _) 
} 

現在你可以用

unsafe { runtime_transmute(None::<T>) } 
取代你 None
相關問題