Cloning function result not enough to solve lifetime issue

⚓ Rust    📅 2025-12-11    👤 surdeus    👁️ 3      

surdeus

I have the following minimal example:

use core::marker::PhantomData;
use std::collections::HashMap;

#[derive(Clone, Copy, Debug)]
pub struct Node<'tree>(PhantomData<&'tree ()>);

#[derive(Clone, Debug)]
pub struct NameDecl<'a> {
    node: Node<'a>,
}

impl<'a> NameDecl<'a> {
    pub fn node(&self) -> &Node<'_> {
        &self.node
    }
}

#[derive(Clone, Debug)]
pub struct VariableDeclaration<'a> {
    names: Vec<NameDecl<'a>>,
}

impl<'a> VariableDeclaration<'a> {
    pub fn names(&'_ self) -> &Vec<NameDecl<'a>> {
        &self.names
    }
}

#[derive(Clone, Debug)]
pub struct SymbolTable<'a> {
    inner: HashMap<String, Node<'a>>,
}

impl<'a> SymbolTable<'a> {
    /// Insert all symbols found in a single variable declaration statement
    pub fn insert(&mut self, foo: &str, decl: VariableDeclaration<'a>) {
        for name in decl.names().iter() {
            self.inner.insert(foo.to_string(), name.node().clone());
        }
    }
}

which gives the following error:

error[E0597]: `decl` does not live long enough
  --> src/lib.rs:37:21
   |
34 | impl<'a> SymbolTable<'a> {
   |      -- lifetime `'a` defined here
35 |     /// Insert all symbols found in a single variable declaration statement
36 |     pub fn insert(&mut self, foo: &str, decl: VariableDeclaration<'a>) {
   |                                         ---- binding `decl` declared here

37 |         for name in decl.names().iter() {
   |                     ^^^^ borrowed value does not live long enough
38 |             self.inner.insert(foo.to_string(), name.node().clone());
   |             ------------------------------------------------------- argument requires that `decl` is borrowed for `'a`
39 |         }
40 |     }
   |     - `decl` dropped here while still borrowed

And I just cannot get my head around why name.node().clone() is not enough here, but if I change it to name.node, everything is fine? Why does rust think that name.node().clone() ends up keeping a reference to decl? What can I do to convince the compiler I want to store a copy here?

(In the real code, decl is actually also stored in SymbolTable, but I don't want to go down the route of storing references to other members of the struct).

4 posts - 2 participants

Read full topic

🏷️ Rust_feed