error [E0716]: temporary value dropped while borrowed (rust)

Your problem is indeed at the line indicated by the compile. Let’s analyze it a little bit:

fn fun1(s1: &String, v1: &mut Vec1) {
    v1.insert(0, &s1.clone());
}

Your understanding is not quite correct. Let’s look at the insert’s signature:

pub fn insert(&mut self, index: usize, element: T)

The type T means that it captures by value, so element won’t be used after the call. You just tweaked this by making the vector a Vec<&String> not a Vec<String>.

Outcome: You want to insert a reference to a clone of the string

How it is done: you clone and insert the the reference

The difference between rust’s reference and C/C++ pointers is that rust doesn’t allow reference to point to deallocated data (they must always point to valid data). When you clone the string, you create a carbon copy of it, but that carbon copy is available only for the lifetime of fun1. When the call to fun1 ends, the cloned string will be dropped, because the function owned that clone, so it is responsible for cleaning it (rust’s ownership based resource management).

In C++ that would have been valid: you could’ve allocated a pointer and push that pointer into the vector, but rust does not allow such things.

Your fun1 is equivalent to this one:

fn fun1(s1: &String, v1: &mut Vec1) {
    let im_tmp = s1.clone();
    v1.insert(0, &im_tmp);
}

Similar operation should always ring a bell becase im_tmp will be cleaned. To fix your issue:

type Vec1<'a> = Vec::<String>;

fn fun1(s1: &String, v1: &mut Vec1) {
    v1.insert(0, s1.clone());
}

fn main() {
    let mut vec1 = Vec::new();
    let str1 = String::new();
    fun1(&str1, &mut vec1);
    println!("{:?}", vec1);
}

The type is no longer a vector of references, but instead the actual object. In fun1, the vector takes ownership of the cloned string.

Another example where your vector has the type you created, is this one, but this works because the compiler can infer the lifetime of the cloned string. Notice, if you do vec1.insert(0, &str1.clone()) won’t work , because tha reference to the clone will be available only for the lifetime of the call to the insert:

type Vec1<'a> = Vec::<&'a String>;

fn main() {
    let mut vec1 = Vec::new();
    let str1 = String::new();
    let clone = str1.clone();
    vec1.insert(0, &clone);
    println!("{:?}", vec1);
}

Leave a Comment