0

I have a function that loads an struct called Executor from a file and returns a reference to it.

  • if the Executor struct contains a field Module, it compiles and works
  • if the Executor struct contains a field Arc<Module>, it won't compile and complains struct belongs to the current function.
use std::sync::Arc;

#[derive(Debug)]
struct Module {
    foo: bool,
}

#[derive(Debug)]
struct Executor {
    module: Module,
}

impl Executor {
    pub fn load() -> Result<&'static Executor, ()> {
        Ok(&Executor {
            module: Module { foo: true },
        })
    }
}

#[derive(Debug)]
struct ExecutorArc {
    module: Arc<Module>,
}

impl ExecutorArc {
    pub fn load() -> Result<&'static ExecutorArc, ()> {
        Ok(&ExecutorArc {
            module: Arc::new(Module { foo: true }),
        })
    }
}

fn main() {
    let executor = Executor::load().unwrap();
    println!("executor = {:?}", executor);

    let executor_arc = ExecutorArc::load().unwrap();
    println!("executor_arc = {:?}", executor_arc);
}

playground

error[E0515]: cannot return value referencing temporary value
  --> src/main.rs:28:9
   |
28 |            Ok(&ExecutorArc {
   |  __________^___-
   | | _________|
   | ||
29 | ||             module: Arc::new(Module { foo: true }),
30 | ||         })
   | ||_________-^ returns a value referencing data owned by the current function
   | |__________|
   |            temporary value created here

It seems to me that in both cases the struct Executor belongs to the function called, where it is allocated.

How can I do something like this?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Andrew Mackenzie
  • 5,477
  • 5
  • 48
  • 70
  • You've asked enough questions by now that we shouldn't have to remind you that not including your code *in the question* means that the question is off topic. Or that you should include the error you get. Please respect the rules. – Shepmaster Jan 20 '19 at 16:08
  • The duplicate question applies for the same rules, swapping "variable" for "temporary". – Shepmaster Jan 20 '19 at 16:11
  • That question (https://stackoverflow.com/questions/50345139/why-can-i-return-a-reference-to-a-local-literal-but-not-a-variable) refers to returning a Literal in one of the cases, is it actually the same? – Andrew Mackenzie Jan 20 '19 at 16:27
  • 1
    Yes. `Executor { module: Module { foo: true } }` is a literal that can be converted to a `static`, but `ExecutorArc { module: Arc::new(Module { foo: true }) }` is not because it contains a function call. – Shepmaster Jan 20 '19 at 16:46
  • OK. Thanks. Is "contains function call" the only criteria, or stack allocation of a struct (i.e. non literal) would also call this? Well, I guess to allocate, you need a function call....so maybe the same thing? – Andrew Mackenzie Jan 21 '19 at 17:43
  • At first approximation, it's "the literal must contain only literals itself" in order to be automatically promoted to a `static`. There's a few edge cases inside the standard library, but those are exceptions. – Shepmaster Jan 21 '19 at 17:47

0 Answers0