Skip to content

let_else returns in surprising borrowck errors with impl trait #93951

Description

@lcnr
#![feature(let_else)]
use std::fmt::Debug;

fn foo<'a>(x: &'a str) -> Result<impl Debug + 'a, ()> {
    Ok(x)
}

fn fail() {
    let x = String::from("Hey");

    let Ok(s) = foo(&x) else { return };
}

fn ok() {
    let x = String::from("Hey");

    let s = if let Ok(s) = foo(&x) { s } else { return };
}

results in

error[E0597]: `x` does not live long enough
  --> src/main.rs:11:21
   |
11 |     let Ok(s) = foo(&x) else { return };
   |                 ----^^-
   |                 |   |
   |                 |   borrowed value does not live long enough
   |                 a temporary with access to the borrow is created here ...
12 | }
   | -
   | |
   | `x` dropped here while still borrowed
   | ... and the borrow might be used here, when that temporary is dropped and runs the destructor for type `Result<impl Debug, ()>`
   |
help: consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped
   |
11 |     let Ok(s) = foo(&x) else { return };;
   |                                        +

I am not sure if this issue exists only in combination with impl Trait of if it can be triggered in some other ways as well, haven't managed to get this bug some other way.

cc #93628 @est31 do you know whether this behavior is known already?

Activity

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

    C-bugCategory: This is a bug.F-let_elseIssues related to let-else statements (RFC 3137)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