Skip to content

Closures which return a reference that depends on an argument unconditionally fail borrow checking #111662

Closed as not planned
@saethlin

Description

@saethlin

This code does not compile:

fn main() {
    let _c = |b: &u8| b;
}

It did in the past though. Starting in 1.36, it comes with this warning (https://godbolt.org/z/W7KGM3369):

warning: lifetime may not live long enough
 --> <source>:2:23
  |
2 |     let _c = |b: &u8| b;
  |                  -  - ^ returning this value requires that `'1` must outlive `'2`
  |                  |  |
  |                  |  return type of closure is &'2 u8
  |                  let's call the lifetime of this reference `'1`
  |
  = warning: this error has been downgraded to a warning for backwards compatibility with previous releases
  = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future

(I do not think there is any chance that this code has UB)

But this code does compile:

fn oof<'a>() {
    let _c = |b: &'a u8| b;
}

At the very least, I think that the diagnostic here is bad. I can't figure out what it is trying to tell me.

This was all re-minimized from an already-minimzed example from @jyn514 :

fn sort(blobs: &mut Vec<(String, Vec<u8>)>) {
    blobs.sort_unstable_by_key(|blob| &blob.0);
}

This is the code we'd really like to see compile.


I'm going to just uh apply all the labels I think are applicable please fix them if they're wrong.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-NLLArea: Non-lexical lifetimes (NLL)A-closuresArea: Closures (`|…| { … }`)A-diagnosticsArea: Messages for errors, warnings, and lintsA-lifetimesArea: Lifetimes / regionsC-bugCategory: This is a bug.NLL-diagnosticsWorking towards the "diagnostic parity" goal

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions