Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot borrow as immutable - String and len()

let mut result = String::with_capacity(1000);

result.push_str("things... ");
result.push_str("stuff... ");

result.truncate((result.len() - 4));

However, this is a compile error. Something to do with the borrow checker and possibly mutability.

error[E0502]: cannot borrow `result` as immutable because it is also borrowed as mutable
 --> <anon>:7:22
  |
7 |     result.truncate((result.len() - 4));
  |     ------           ^^^^^^           - mutable borrow ends here
  |     |                |
  |     |                immutable borrow occurs here
  |     mutable borrow occurs here

Yet, if I change it slightly I am allowed to do this:

let newlen = result.len() - 4;
result.truncate(newlen);

Why? Is there a way to change this so it can be written in one line? (P.S. this is on Rust 1.0)

like image 876
jocull Avatar asked May 29 '15 14:05

jocull


People also ask

How do you borrow variables in rust?

An Example of Borrowing in Rust You can borrow the ownership of a variable by referencing the owner using the ampersand (&) symbol. Without borrowing by referencing, the program would panic. It would violate the ownership rule that a value can have one owner, and two variables cannot point to the same memory location.

What is borrowing in Rust?

What is Borrowing? When a function transfers its control over a variable/value to another function temporarily, for a while, it is called borrowing. This is achieved by passing a reference to the variable (& var_name) rather than passing the variable/value itself to the function.

Why might we choose to borrow a value in Rust?

Rust Reference and Borrow Value Since a value can only have an owner at a given time, using it inside the function will transfer ownership. Since we don't want the ownership to be transferred to the function, we borrow the value using by referencing its owner.


1 Answers

This is an unfortunate shortcoming of Rust borrow checking procedure. This essentially happens because

result.truncate(result.len() - 2)

is equivalent to

String::truncate(&mut result, result.len() - 2)

and here you can see that because arguments are computed in left-to-right order, result is indeed borrowed mutably before it is used in result.len().

I found this problem in Rust issue tracker: #6268. This issue was closed in favor of non-lexical borrows RFC issue. It seems that it's just one of those things which would be nice to have but which needed more time to be done that it was available before 1.0. This post may also be of some interest (even though it is almost two years old).

like image 80
Vladimir Matveev Avatar answered Oct 15 '22 14:10

Vladimir Matveev