2016-12-26 38 views
7

我發現了一生誤差鏽1.14由於使用相關聯的類型,由以下兩個類似的方案證實,其編譯沒有錯誤的第一和其具有第二終身錯誤。壽命錯誤使用相關性狀類型與壽命參數

項目#1 - 編譯沒有錯誤

trait Trait<'a> { 
    type T; 
} 

struct Impl; 

impl<'a> Trait<'a> for Impl { 
    type T = std::marker::PhantomData<&'a()>; 
} 

struct Alpha<'a, T: Trait<'a>> { 
    _dummy: std::marker::PhantomData<(&'a(), T)>, 
} 

fn use_alpha<'a>(_: &'a Alpha<'a, Impl>) {} 

fn main() { 
    for x in Vec::<Alpha<Impl>>::new().into_iter() { 
     use_alpha(&x); // <-- ok 
    } 
} 

項目#2 - 具有壽命錯誤

trait Trait<'a> { 
    type T; 
} 

struct Impl; 

impl<'a> Trait<'a> for Impl { 
    type T = std::marker::PhantomData<&'a()>; 
} 

struct Alpha<'a, T: Trait<'a>> { 
    _dummy: std::marker::PhantomData<(&'a(), T::T)>, 
} 

fn use_alpha<'a>(_: &'a Alpha<'a, Impl>) {} 

fn main() { 
    for x in Vec::<Alpha<Impl>>::new().into_iter() { 
     use_alpha(&x); // <-- !error! 
    } 
} 

這裏的第2程序編譯時錯誤:

error: `x` does not live long enough 
    --> src/main.rs:20:5 
    | 
19 |   use_alpha(&x); // <-- !error! 
    |     - borrow occurs here 
20 |  } 
    | ^`x` dropped here while still borrowed 
    | 
    = note: values in a scope are dropped in the opposite order they are created 

下面是兩個方案中的diff:

#[derive(Clone)] 
struct Alpha<'a, T: Trait<'a>> { 
- _dummy: std::marker::PhantomData<(&'a(), T)>, 
+ _dummy: std::marker::PhantomData<(&'a(), T::T)>, 
} 

唯一的區別是,通過改變所述第一程序使用相關聯的類型,而不是在struct定義類型參數時,出現壽命錯誤。我不知道爲什麼會發生這種情況。據我所知,關聯類型不應該產生任何額外的生存期限制 - 這一切都只是'a,但顯然Rust編譯器不同意。

如果我更換第二個程序的main簡單的實例化功能重複,那麼一生錯誤消失。那就是:

fn main() { 
    let x = Alpha::<Impl> { _dummy: std::marker::PhantomData }; 
    use_alpha(&x); // <-- ok in both programs 
} 

我不明白爲什麼迭代與直接實例化有什麼不同。

+0

我仍然在努力工作了這一點。但我_did_發現你可以使用'iter()'而不是'into_iter()'並且它可以工作。 –

回答

4

use_alpha,你可能用的參考Alpha和其生命週期參數相同的壽命。其壽命參數則成爲ImplTrait::T的使用壽命。該說明給出了有關訂單的暗示值下降:Impl::T得到,因爲它是Impl的定義的一部分Impl前下降,但意味着Alpha某些部分,而它仍然是圍繞已經下降。

您可以通過在use_alpha使用兩個壽命參數解決這個問題:

fn use_alpha<'a, 'b>(_: &'a Alpha<'b, Impl>) {} 

這將允許編譯器推斷出不同的生命週期的每個類型。

+0

被問及4小時後,你用幾分鐘的時間打敗了我的答案... – Shepmaster

+2

@Shepmaster最後! :P –

+0

另外,請隨時張貼你的或編輯我的。我對我的解釋並不滿意 - 部分原因是我不確定我是否100%自己理解。 –