Skip to content

improve error message when returning iterator with reference into stack frame  #53882

Open
@nikomatsakis

Description

@nikomatsakis
Contributor

This example (playground):

use std::rc::Rc;

fn iterate(data: Rc<Vec<u32>>) -> impl Iterator<Item = u32> {
    data.iter().cloned()
}

fn main() {
    for x in iterate(Rc::new(vec![1, 2, 3])) {
        println!("Hi! {}", x);
    }
}

gives this error:

error[E0597]: `data` would be dropped while still borrowed
 --> src/main.rs:4:5
   |
 4 |     data.iter().cloned()
   |     ^^^^ borrowed value does not live long enough
 5 | }
   | - borrowed value only lives until here
   |
   = note: borrowed value must be valid for the static lifetime...

I think we could do better. For example, we don't explain anything about how impl Iterator disallows lifetimes; and I think we can clarify why `data is being dropped.

I don't yet have a concrete suggestion, though, have to think about it.

Related to #52534 -- in some sense a specific instance of that.

Activity

added
A-diagnosticsArea: Messages for errors, warnings, and lints
T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
on Sep 1, 2018
changed the title [-]improve error message when [/-] [+]improve error message when returning iterator with reference into stack frame [/+] on Sep 1, 2018
nikomatsakis

nikomatsakis commented on Sep 1, 2018

@nikomatsakis
ContributorAuthor

With respect to impl Iterator, one thing I thought of is this

error[E0597]: reference to `data` would be used after `data` is freed
 --> src/main.rs:4:5
   |
 3 | fn iterate(data: Rc<Vec<u32>>) -> impl Iterator<Item = u32> {
   |                                   -------------------------
   |                                   |
   |                                   as written, this type does not permit borrowed data
   |                                   help: try `impl Iterator<Item = u32> + '_`
 4 |     data.iter().cloned()
   |     ^^^^ `data` is borrowed here
 5 | }
   | - borrowed value only lives until here
   |
   = note: borrowed value must be valid for the static lifetime...

But in a way -- in this particular case -- it doesn't matter anyway, as there is nothing you could change that signature too that would work.

self-assigned this
on Sep 1, 2018
matthewjasper

matthewjasper commented on Sep 1, 2018

@matthewjasper
Contributor

I've assigned myself since I've been working on things in this area recently, but other things have come up as higher priority, so I might not get around to this for a few weeks.

removed their assignment
on Jan 1, 2019
added
C-enhancementCategory: An issue proposing an enhancement or a PR with one.
on Jun 11, 2020
Nadrieril

Nadrieril commented on Nov 30, 2023

@Nadrieril
Member

The current error is:

error[E0597]: `data` does not live long enough
 --> src/main.rs:4:5
  |
3 | fn iterate(data: Rc<Vec<u32>>) -> impl Iterator<Item = u32> {
  |            ---- binding `data` declared here
4 |     data.iter().cloned()
  |     ^^^^----------------
  |     |
  |     borrowed value does not live long enough
  |     opaque type requires that `data` is borrowed for `'static`
5 | }
  | - `data` dropped here while still borrowed

For more information about this error, try `rustc --explain E0597`.

Which is already much better! I think "opaque type requires that" could point to the impl Iterator return type as Niko suggested, and "borrowed value does not live long enough" doesn't explain what it points to. My personal ideal would look like:

error[E0597]: `data` does not live long enough
 --> src/main.rs:4:5
  |
3 | fn iterate(data: Rc<Vec<u32>>) -> impl Iterator<Item = u32> {
  |            ----                   -------------------------
  |            |                      |
  |            |                      as written, this type does not permit borrowed data
  |            |                      help: try `impl Iterator<Item = u32> + '_`
  |            binding `data` declared here
4 |     data.iter().cloned()
  |     ^^^^----------------
  |     |
  |     `data` is borrowed here...
  |     ...and the borrow is captured by this whole expression
5 | }
  | ^ `data` dropped here while still borrowed

For more information about this error, try `rustc --explain E0597`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsC-enhancementCategory: An issue proposing an enhancement or a PR with one.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

        Participants

        @nikomatsakis@crlf0710@Nadrieril@matthewjasper

        Issue actions

          improve error message when returning iterator with reference into stack frame · Issue #53882 · rust-lang/rust