Skip to content

Unexpected borrowck error when returning an impl Trait #53450

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

Labels

A-NLLArea: Non-lexical lifetimes (NLL)T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions