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

Popular posts from this blog

java - UnknownEntityTypeException: Unable to locate persister (Hibernate 5.0) -

python - ValueError: empty vocabulary; perhaps the documents only contain stop words -

ubuntu - collect2: fatal error: ld terminated with signal 9 [Killed] -