I think this isn't possible but struggled for long enough that I wanted to confirm.
I'm trying to return a Workspace
struct, which contains references. I initially tried:
use cargo::core::Workspace;
use cargo::util::config::Config;
use std::path::Path;
fn workspace<'a>() -> Workspace<'a> {
let config = Config::default().unwrap();
let path = Path::new("/Users/maximilian/workspace/rust-test/Cargo.toml");
Workspace::new(path, &config).unwrap()
}
fn main() {
dbg!(workspace());
}
This raises:
error[E0515]: cannot return value referencing local variable `config`
--> src/main.rs:13:5
|
13 | Workspace::new(path, &config).unwrap()
| ^^^^^^^^^^^^^^^^^^^^^-------^^^^^^^^^^
| | |
| | `config` is borrowed here
| returns a value referencing data owned by the current function
error: aborting due to previous error
For more information about this error, try `rustc --explain E0515`.
error: Could not compile `rust-test`.
To learn more, run the command again with --verbose.
[Finished running. Exit status: 101]
I think this is because:
- the
workspace
function is returning aWorkspace
struct, which contains references created in theConfig::new
call - and a
Workspace
isn't Clone-able so it can't move the value into the calling function.
Is that correct?
One way around this is to have another function which creates the Config
struct, so it's owned by the main function:
use cargo::util::config::Config;
use std::path::Path;
// new
fn c() -> Config {
Config::default().unwrap()
}
// fn workspace<'a>() -> Workspace<'a> {
fn workspace<'a>(config: &'a Config) -> Workspace<'a> {
// let config = Config::default().unwrap();
let path = Path::new("/Users/maximilian/workspace/rust-test/Cargo.toml");
Workspace::new(path, &config).unwrap()
}
fn main() {
// dbg!(workspace());
dbg!(workspace(&c()));
}
Questions I'd appreciate help with:
- Is there any way to retain the structure of the original example, so that
main
doesn't have to pass aroundConfig
objects? I'm happy to use any combination ofBox
/Rc
etc! - In the working second version, a function can return a locally created
Config
struct, despite it not implementing Clone, while the first version can't return aWorkspace
.- Is there a generalizable principle for what Structs locally created can be returned? They seem to implement the same Traits.
- Is the difference that
Workspace
contains references and so has an explicit lifetime?
Thank you!