Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 720
ccleve Avatar asked May 23 '26 08:05

ccleve


1 Answers

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:

  • Borrowing Data in a Derived impl
  • Serde field attributes (borrow)
like image 92
Peter Hall Avatar answered May 25 '26 20:05

Peter Hall



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!