Lifetimes on Trait Impl

I am attempting to create a small grpc service using the tonic framework (but I don't think that should matter here?)

It receives a request and then pings a list of servers which I have stored in a vector and added to my struct

pub struct GRPCServer<'a> {
    server_list: Arc<RwLock<Vec<DownStreamServer<'a>>>>,
}

#[tonic::async_trait]
impl grpcservice for GRPCServer<'_>{
    ...
}

#[derive(Default)]
pub struct DownStreamServer<'a> {
    pub host: &'a str,
    pub port: u16,
    pub protocol: Protocol,
}

Currently I get an error

error[E0726]: implicit elided lifetime not allowed here
  --> src/server.rs:27:18
   |
27 | impl grpcservice for GRPCServer {
   |                  ^^^^^^^^^^^^^^^^^- help: indicate the anonymous lifetime: `<'_>`

and it suggests I add the anonymous lifetime but once I do that it errors on the trait saying lifetime bound not satisfied

I am not too sure where to go from here as it says that

error[E0478]: lifetime bound not satisfied
  --> src/server.rs:27:6
   |
27 | impl grpcservice for GRPCServer<'_> {
   |      ^^^^^^^^^^^
   |
note: lifetime parameter instantiated with the lifetime `'_` as defined on the impl at 27:36
  --> src/server.rs:27:36
   |
27 | impl grpcservice for GRPCServer<'_> {
   |                                    ^^
   = note: but lifetime parameter must outlive the static lifetime

I know that the 'static lifetime is the lifetime that lasts the length of the program but I am not sure of the syntax I should be using to explain that to the compiler

Edit: I think I may have found my answer here
https://stackoverflow.com/questions/59880262/rust-lifetime-parameter-must-outlive-the-static-lifetime

Which I guess means my host value must have a static lifetime?

Would the correct approach be to switch the &str to a String?

Yes. The &str type means "this is a reference to a string, but the string is stored somewhere else, and this struct has a lifetime <'a> so the compiler can track where the string came from".

1 Like

Thanks for the help Alice, I appreciate it.

I have a quick followup that is sorta related.

I am trying to do something like tonic/server.rs at master · hyperium/tonic · GitHub

Where they are looping through the features vector

    let current_servers_list = &self.server_list.read().unwrap();
    for server in current_servers_list[..] {}

but am receiving the error

error[E0277]: the size for values of type `[DownStreamSever]` cannot be known at compilation time
  --> src/server.rs:34:23
   |
34 |         for server in current_servers_list[..] {}
   |                               ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
   |
   = help: the trait `std::marker::Sized` is not implemented for `[DownStreamServer]`
   = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-    types.html#dynamically-    sized-types-and-the-sized-trait>
   = note: required by `std::iter::IntoIterator::into_iter`

They don't seem to implement that in their example so I am not sure if I am missing something

What is it? You do not need to ask if you can ask.

1 Like

Sorry Alice, I keep hitting shift enter which submits on these forms but adds a line in slack(a bad habit)

See my edit of the above comment

You're missing an ampersand: &current_servers_list[..]

1 Like

Ah ok, Thanks a bunch you have been a great help!

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.