Closed
Description
The following playground highlights the issue: https://play.rust-lang.org/?gist=cf6be643e3a2fb6d69ac835cec890ad2&version=nightly&mode=debug&edition=2015
fn main() {
let mut v = Vec::new();
let x = good(v.iter().cloned());
let y = bad(v.iter().cloned()); // if you comment out this line, it compiles.
v.push(3);
}
fn good<I: Iterator<Item = usize>>(x: I) -> std::vec::IntoIter<usize> {
x.collect::<Vec<usize>>().into_iter()
}
fn bad<I: Iterator<Item = usize>>(x: I) -> impl Iterator<Item = usize> {
x.collect::<Vec<usize>>().into_iter()
}
error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable
--> src/main.rs:5:5
|
4 | let y = bad(v.iter().cloned()); // if you comment out this line, it compiles.
| - immutable borrow occurs here
5 | v.push(3);
| ^ mutable borrow occurs here
6 | }
| - immutable borrow ends here
We have two implementations of the same function that are equivalent, except that one returns an impl Iterator
while the other returns a concrete type. Calling the version that returns impl Trait
seems to incorrectly tie the lifetime of the return value to the function's argument.
We have tested this on:
- rustc 1.28.0
- rustc 1.29.0-beta4
- rustc 1.30.0-nightly (b202882 2018-08-16)
/cc: @nathansobo