ccleve
ccleve

Reputation: 15799

Understanding dependent lifetimes

How do I tell the compiler that one lifetime must outlive another?

use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Debug)]
pub struct Tokens<'a> {
    buffer: String,
    list: Vec<Token<'a>>,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct Token<'a> {
    term: &'a str,
}

yields

error: lifetime may not live long enough
 --> src/pipeline/tokenizers/test.rs:6:5
  |
3 | #[derive(Serialize, Deserialize, Debug)]
  |                     ----------- lifetime `'de` defined here
4 | pub struct Tokens<'a> {
  |                   -- lifetime `'a` defined here
5 |     buffer: String,
6 |     list: Vec<Token<'a>>,
  |     ^^^^ requires that `'de` must outlive `'a`
  |
  = help: consider adding the following bound: `'de: 'a`

In the code above, the token.term: &str will always refer to a slice of tokens.buffer. I'm not sure how to specify that relationship. I'm also not sure how to add the requested bound.

Will this even work? If so, what's the magic syntax?

Upvotes: 3

Views: 243

Answers (2)

Peter Hall
Peter Hall

Reputation: 58785

You can use the attribute, #[serde(borrow)], which makes the generated Deserialize implementation borrow the data.

use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Debug)]
pub struct Tokens<'a> {
    buffer: String,
    #[serde(borrow)]
    list: Vec<Token<'a>>,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct Token<'a> {
    term: &'a str,
}

See:

Upvotes: 4

Silvio Mayolo
Silvio Mayolo

Reputation: 70297

You can't add constraints to a derive implementation. You could write the entire Deserialize implementation yourself and put the constraint in the usual place. But fortunately, serde thought of this use case. If you indicate to serde that the data should be borrowed from the deserializer, it will put the constraint in for you.

#[derive(Serialize, Deserialize, Debug)]
pub struct Tokens<'a> {
    buffer: String,
    #[serde(borrow)]
    list: Vec<Token<'a>>,
}

Upvotes: 4

Related Questions