These are chat archives for rust-lang/rust

8th
Mar 2019
Sam Johnson
@sam0x17
Mar 08 02:49

how can I add lifetime parameters to this trait to make a construction like this work:

pub trait Stream {
    fn transform(&self, data: &[u8]) -> &[u8] { return data; }
}

error:

error[E0623]: lifetime mismatch
  --> src/stream.rs:15:56
   |
15 |     fn transform(&self, data: &[u8]) -> &[u8] { return data; }
   |                               -----     -----          ^^^^ ...but data from `data` is returned here
   |                               |
   |                               this parameter and the return type are declared with different lifetimes...

error: aborting due to previous error
Riley Cat
@WreckedAvent
Mar 08 03:45
@sam0x17
pub trait Stream {
    fn transform<'a>(&self, data: &'a [u8]) -> &'a [u8] { data }
}
(also try to avoid return since it'll force you to think in a more rust-y way)
Sam Johnson
@sam0x17
Mar 08 03:51
thanks so much @WreckedAvent -- is there an actual difference when you omit the return? I come from ruby so I'm very used to omitting returns ;)
also is there a cheat sheet somewhere that shows how to annotate things with lifetime parameters in every situation? I find that so hard to google and almost every placement of where the annotation goes surprises / shocks me lol
the rust book glosses over it a lot imo
Riley Cat
@WreckedAvent
Mar 08 03:53

afaik

{ return 2; }

and

{ 2 }

are identical emits, but it's more idiomatic to use the second

it's also refreshingly comfortable if you're coming from a background with a language with auto returns
(note the missing semi-colon in the second, that's what makes it automatic return)
as for life time parameters the compiler allows you to not annotate for the most common scenarios, like this doesn't need a lifetime:
pub trait Stream {
    fn transform(data: &[u8]) -> &[u8] { data }
}

but that's just the compiler auto-inserting it for you:

pub trait Stream {
    fn transform<'a>(data: &'a [u8]) -> &'a [u8] { data }
}

and in this case, where there's one input, one output, the compiler just assumes the same lifetime and it works for quite a lot of functions

and I believe, but I'm not certain, that's why you get the some-what confusing error about them having different lifetimes in your original example
since if you follow that "auto insert" rule you get this:
pub trait Stream {
    fn transform<'a, 'b>(&'a self, data: &'b [u8]) -> &'a [u8] { data }
}
Riley Cat
@WreckedAvent
Mar 08 03:58
and clearly the rvalue and data have different lifetimes
^ @sam0x17
as for "rules" or a "cheatsheet" I've generally found you want to use lifetimes to make sure that some input and some output share the same lifetime
in your example all I did was identify you were just returning data so I just made the rvalue and data have the same lifetime
Riley Cat
@WreckedAvent
Mar 08 04:03
and so long as you can derive the rvalue from that input somehow than the compiler is generally happy
mmynsted
@mmynsted
Mar 08 04:33
Anybody have experience with more than one templating solution? I want something that will compile templates from template files with the end goal being to create simple html or markdown files.
I looked in cartes.io. There are a number of options. I am leaning toward Askama.
Sam Johnson
@sam0x17
Mar 08 07:49
@WreckedAvent thanks a bunch for the detailed explanation!
if I have a trait that inherits from another trait, how can I specify that one of its methods overrides the method in the parent trait? The compiler complains about this saying that calls to write are ambiguous:
pub trait A {
    fn write(&mut self, data: &[u8]);
}

pub trait B : A {
    fn write(&mut self, data: &[u8]) {
        // implementation here
    }
}
Sylwester Rąpała
@xoac
Mar 08 10:09
@knappador You can try azure piplines I am trying to make it working inspirited by tokio https://github.com/xoac/rust-azure-pipelines
Denis Lisov
@tanriol
Mar 08 12:16
@sam0x17 You cannot override a method in the parent trait. It will be possible to call that method explicitly anyway.
Also, looking at your trait Stream from the previous question, I have to note that most likely you want to return something like Vec<u8> as the signature fn transform<'a>(&self, data: &'a [u8]) -> &'a [u8] won't allow you to return anything other than a subslice of the input.
Sylwester Rąpała
@xoac
Mar 08 14:58
HI, how should I name crate that operate on streams and sinks and filesystem? At this moment it's tokio-fs-stream but I think it should be more futures-fs but futures-fs already exist and do more or less what tokio-fs. The main aim at this moment for my create is SendAllFs that will do the same what SendAll do but it buffer items on disk when Sink is not ready. On the other hand I would like to implement easy serialize item to disks.