let_else returns in surprising borrowck errors with impl trait · Issue #93951 · rust-lang/rust (original) (raw)

@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?