I'm trying to iterate over a series of filenames and parse the corresponding files.
My Cargo.toml
:
[package]
name = "fold"
version = "0.1.0"
authors = ["Akshat Mahajan"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
goblin = "0.4.3"
My main.rs
:
/// A program linker to generate x64 ELF executables from object files.
use goblin::elf::Elf;
use std::error::Error;
use std::fs;
fn parse_files(files: Vec<String>) -> Result<Vec<Elf<'static>>, Box<dyn Error>> {
let mut elfs: Vec<Elf> = vec![];
for file in files {
elfs.push(Elf::parse(fs::read(file)?.as_slice())?);
}
return Ok(elfs);
}
fn main() {
parse_files(vec!["foo".to_string(), "bar".to_string()]);
}
The borrow checker complains:
error[E0515]: cannot return value referencing temporary value
--> src/main.rs:17:12
|
14 | elfs.push(Elf::parse(fs::read(file)?.as_slice())?);
| --------------- temporary value created here
...
17 | return Ok(elfs);
| ^^^^^^^^ returns a value referencing data owned by the current function
Elf::parse
only accepts a byte slice, rather than anything heap-allocated for a longer lifetime:
pub fn parse(bytes: &'a [u8]) -> Result<Self>
What is the correct way to make this operation succeed?
Things I've tried:
- Moving everything in
parse_files
intomain
, only to be hit by a drop of temporary variable error. - Read Is there any way to return a reference to a variable created in a function?. I don't think this helps me because it seems my actual problem is that the lifetime of the byte stream created by
fs::read
is temporary, when I really want it to be tied to the lifetime of the program. I don't know how to achieve this cleanly.