rust - Trouble implementing higher ranked lifetime type bound for a byte slice -
i trying implement trait on &'a [u8] , use in implementation uses higher ranked lifetimes, e.g.:
pub trait intotest<'a, t> { fn into_test(&'a self) -> t self: sized; } impl<'a> intotest<'a, &'a [u8]> &'a [u8] { fn into_test(&'a self) -> &'a [u8] { self } } fn higher_ranked_lifetime<t>(test: t) t: for<'a> intotest<'a, &'a [u8]> { let _t = test.into_test(); } fn main() { println!("hello, world!"); let vec = vec![1u8]; let slice = &vec[..]; higher_ranked_lifetime(slice); } short url: http://is.gd/1qkhyk
the error getting is:
<anon>:19:5: 19:27 error: trait `for<'a> intotest<'a, &'a [u8]>` not implemented type `&[u8]` [e0277] <anon>:19 higher_ranked_lifetime(slice); how should doing this? right thing do? not want scope higher_ranked_lifetime specific lifetime, have applicable byte slice passed it.
this not correct way, , compiler right.
one way can see why @ type (the slice) , trait think implements side side:
for<'a> intotest<'a, &'a [u8]> &'a [u8] here i've added lifetime parameter on slice clarity. can see in trait bound lifetime parameter 'a bound for qualifier, in other words, declaration self-contained, not depend on in external scope.
in slice, however, lifetime parameter 'a free - defined in external scope, example, through lifetime elision. therefore, there no way slice can satisfy trait implementation. work trait should implemented this:
impl<'a, 'b> intotest<'a, &'a [u8]> &'b [u8] { fn into_test(&'a self) -> &'a [u8] { unimplemented!() } } which compiles, although doesn't , couldn't want. can see in declaration lifetimes of slice , in trait signature disjoint, therefore slices satisfy for<'a>-based bound.
there way @ problem. t: for<'a> intotest<'a, &'a [u8]> bound means type t implements trait every possible lifetime parameter of trait, function can decide lifetime wants. example, request 'static. naturally in code &[u8] tied vector in main method , cannot 'static. therefore soundness violated - &[u8] can't provide lifetime user wants, , not implement for<'a> intotest<'a, &'a [u8]>.
note adding lifetime parameter generic function won't work either:
fn higher_ranked_lifetime<'a, t>(test: t) t: intotest<'a, &'a [u8]> { let _t = test.into_test(); } there error:
<anon>:12:14: 12:18 error: `test` not live long enough <anon>:12 let _t = test.into_test(); ^~~~ <anon>:11:79: 13:2 note: reference must valid lifetime 'a defined on block @ 11:78... <anon>:11 fn higher_ranked_lifetime<'a, t>(test: t) t: intotest<'a, &'a [u8]> { <anon>:12 let _t = test.into_test(); <anon>:13 } <anon>:11:79: 13:2 note: ...but borrowed value valid scope of parameters function @ 11:78 <anon>:11 fn higher_ranked_lifetime<'a, t>(test: t) t: intotest<'a, &'a [u8]> { <anon>:12 let _t = test.into_test(); <anon>:13 } and again correct. remember trait defined this:
pub trait intotest<'a, t> { fn into_test(&'a self) -> t self: sized; } here require self passed reference same lifetime lifetime parameter of trait. however, above declaration of generic function makes method not callable in principle:
fn higher_ranked_lifetime<'a, t>(test: t) t: intotest<'a, &'a [u8]> here trait specified have lifetime parameter equal lifetime parameter of function. however, test parameter lives through body of function. therefore, reference taken test, including implicit 1 when calling into_test():
let _t = (&test).into_test(); will have lifetime strictly less lifetime parameter, , can't used parameter into_test() method. error about.
because didn't explain need, it's hard should do. guess 1 of general ways drop lifetime parameter on trait , make trait method accept self value, , fix generic function accordingly:
pub trait intotest<t> { fn into_test(self) -> t; } impl<'a> intotest<&'a [u8]> &'a [u8] { fn into_test(self) -> &'a [u8] { self } } fn higher_ranked_lifetime<'a, t>(test: t) t: intotest<&'a [u8]> { let _t = test.into_test(); } fn main() { println!("hello, world!"); let vec = vec![1u8]; let slice = &vec[..]; higher_ranked_lifetime(slice); } this does work because trait not have lifetime parameters , not add requirements on how call it. lifetime parameters moved types implement it.
Comments
Post a Comment