[E0502] error: cannot borrow as immutable because it is also borrowed as mutable



I’m going to create topics containing error codes and messages such that, by title, they are easy to find by others too.

The purpose of such topics would be gathering other examples of code giving the error and solutions to them.

The description of the error: https://doc.rust-lang.org/error-index.html#E0502. The solution provided there does not seem to fit my bill.

The first sample code is at https://gist.github.com/flavius/353e633c6758b565dbc902c7632092ef/cf31965f6c51830e7f5d454a114e5d157abc4517

The message:

src/lib.rs:85:20: 85:23 error: cannot borrow `log` as immutable because it is also borrowed as mutable [E0502]
src/lib.rs:85         assert_eq!(log.version(), entry.version());
src/lib.rs:84:21: 84:24 note: mutable borrow occurs here
src/lib.rs:84         let entry = log.new_entry();
src/lib.rs:86:5: 86:6 note: mutable borrow ends here
src/lib.rs:86     }
src/lib.rs:85:9: 85:52 note: in this expansion of assert_eq! (defined in <std macros>)
src/lib.rs:85:20: 85:23 help: run `rustc --explain E0502` to see a detailed explanation

How to solve this problem? The AppendlogEntry newly created needs to stay owned by the vector entries inside Appendlog.


Store log.version() in a variable before creating entry.

let mut log = Appendlog::new();
let log_ver = log.version();
let entry = log.new_entry();
assert_eq!(log_ver, entry.version());

This way, log doesn’t need to be borrowed for the assert while entry exists.



I’ve tried it and it’s a valid solution.

However I went with returning a deep copy of the new entry for ergonomic considerations: https://gist.github.com/flavius/353e633c6758b565dbc902c7632092ef/1bbb30ca568f977215829f62e043c44ec92669ce

Anyone is welcome to share other approaches for others to read.