 # Borrowing and use after move issue

Hi,

I have two functions that I am trying to combine to one function. I am struggling with borrow/movement concept. Can I combine calc_prc and calc_prc2? The calling function is calling calc_prc and calc_prc2 with the same df_rows vector.

``````pub fn build_df(res:&mut Vec<crate::dbhandling::Res1>)
{
let mut df_rows = Vec::new();
let mut prices = Vec::new();

copy_data_df(res, &mut df_rows, &mut prices);
calc_prc(&mut df_rows, &mut prices);
calc_prc2(&mut df_rows);
}

fn calc_prc(df_rows: &mut Vec<Dfrow>, prices: &mut Vec<f64>)
{
let mut i = 0;
for d in df_rows
{
if i == 0
{
i += 1;
continue;
}
d.back_prc = prc(prices[i], prices[i-1]);

i += 1;
}
}

fn calc_prc2(df_rows2: &mut Vec<Dfrow>)
{
let num_entries = df_rows2.len();

for t in 1..100
{
for i in t..num_entries
{
df_rows2[i].back_prc[t] = df_rows2[i-1].back_prc[t-1];
}
}
}

fn prc(newdata:f64, old:f64) -> f64
{
return 100000.0 * (newdata - old) / old;
}
``````

Thanks,
Mor

What is the error?

if I try to combine i get this:

``````fn calc_prc(df_rows: &mut Vec<Dfrow>, prices: &mut Vec<f64>)
{
let mut i = 0;
for d in df_rows
{
if i == 0
{
i += 1;
continue;
}
d.back_prc = prc(prices[i], prices[i-1]);

i += 1;
}
// }

// fn calc_prc2(df_rows2: &mut Vec<Dfrow>)
// {
let num_entries = df_rows.len();

for t in 1..100
{
for i in t..num_entries
{
df_rows[i].back_prc[t] = df_rows[i-1].back_prc[t-1];
}
}
}
``````

48 | fn calc_prc(df_rows: &mut Vec, prices: &mut Vec)
| ------- move occurs because `df_rows` has type `&mut Vec<Dfrow>`, which does not implement the `Copy` trait
...
51 | for d in df_rows
| -------
| |
| `df_rows` moved due to this implicit call to `.into_iter()`
| help: consider borrowing to avoid moving into the for loop: `&df_rows`
...
66 | let num_entries = df_rows.len();
| ^^^^^^^ value borrowed here after move
|
note: this function consumes the receiver `self` by taking ownership of it, which moves `df_rows`
--> C:\Users\mgrut.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\core\src\iter\traits\collect.rs:232:18
|
232 | fn into_iter(self) -> Self::IntoIter;
| ^^^^

error: aborting due to previous error

Replace `for d in df_rows` with `for d in &mut *df_rows`

When I do that, I get:

error[E0277]: `Vec<Dfrow>` is not an iterator
--> src\myapp.rs:51:14
|
51 | for d in &mut df_rows
| ^^^^^^^^^^^^ `Vec<Dfrow>` is not an iterator
|
= help: the trait `std::iter::Iterator` is not implemented for `Vec<Dfrow>`
= note: required because of the requirements on the impl of `std::iter::Iterator` for `&mut Vec<Dfrow>`
= note: required because of the requirements on the impl of `std::iter::Iterator` for `&mut &mut Vec<Dfrow>`
= note: required because of the requirements on the impl of `IntoIterator` for `&mut &mut Vec<Dfrow>`
= note: required by `into_iter`

error: aborting due to previous error

`for d in &mut *df_rows` - note the asterisk.

Works! Thanks.

Can anyone add a small explanation? Or link to the right page in the document?

Thanks again.

A mutable reference does not implement the `Copy` trait because mutable references are guaranteed to be unique. Thus, since the for loop consumes the object given to it, the mutable reference is not accessible later.

The `&mut *df_rows` syntax creates a new mutable sub-reference to the same vector. The for loop then consumes the sub-mutable reference, leaving the original mutable reference intact and usable later. Creating a sub-reference like this is called reborrowing.

The compiler can automatically reborrow mutable references in some cases, but this is not one of them.

You can also write this as `for d in df_rows.iter_mut()`.

ok, Thanks all for your help