My failing code (Minimal, Reproducible Example):
// my code
fn test() {
let mut list: Vec<Text> = Vec::new();
const ARRAY: [char; 3] = ['a', 'b', 'c'];
for (i, _) in ARRAY.iter().enumerate() {
list.push(Text::new(&ARRAY[i].to_string()));
}
}
// external crate
#[derive(Debug, Clone, Copy, PartialEq)]
struct Text<'a> {
pub text: &'a str,
}
impl<'a> Text<'a> {
pub fn new(text: &'a str) -> Self {
Text {
text
}
}
}
The compiler: "temporary value dropped while borrowed". Red squiggly lines below
ARRAY[i].to_string()
Classic borrow checker problem, I guess?
I tried to change up the types to be &strs instead of chars and everything worked fine:
// my code
fn test() {
let mut list: Vec<Text> = Vec::new();
const ARRAY: [&str; 3] = ["a", "b", "c"]; // CHANGE HERE
for (i, _) in ARRAY.iter().enumerate() {
list.push(Text::new(&ARRAY[i])); // CHANGE HERE
}
}
Can't figure out what's so special about char or the conversion with to_string() that makes this code fail.
Your failing code is equivalent to this one:
for a in &ARRAY {
let temp = a.to_string();
list.push(Text::new(&temp));
drop(temp);
}
Except that the temporary variable has a name in my code (the call to drop() is redundant, I added it for clarity).
So all the temporaries created during the loop are being added as references to the list, remember that Text holds a reference, not the string itself. But these temporaries do not survive the iteration where they are created, so your list contains dangling references. Rust detects that and fails to compile.
The easy solution would be to modify Text to hold the String itself, instead of a reference. If you cannot modify that, then your strings have to live somewhere, you can build a Vec<String> and get the references from there:
fn test() {
const ARRAY: [char; 3] = ['a', 'b', 'c'];
let mut tmps: Vec<String> = Vec::new();
for a in &ARRAY {
tmps.push(a.to_string());
}
let list: Vec<Text> = tmps
.iter()
.map(|s| Text::new(s))
.collect();
}
Your second code works simply because now you array contains static references &'static str so there is no temporary variables anywhere.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With