Interaction of `+ 'static` and `+ use<>` bounds

⚓ Rust    📅 2025-07-08    👤 surdeus    👁️ 3      

surdeus

Is there any interaction between these two concepts? I would guess yes, since if something is 'static, it surely does not capture any (non-static) lifetimes.

This can be also illustrated with the following (which compiles and outputs ()):

use std::fmt::Debug;

fn foo<'a>(_: &'a String) -> impl Debug + 'static + use<'a> {}
// This is (as of edition 2024) just desugared version of
// fn foo(_: &String) -> impl Debug + 'static {}

fn main() {
    let s = "hello".to_owned();
    let x = foo(&s);
    drop(s);
    // `s` is dropped but is still borrowed by `x`.
    println!("{x:?}");
}

However, if I add indirection, it no longer compiles

use std::fmt::Debug;

fn foo<'a>(_: &'a String) -> impl Debug + 'static + use<'a> {}
// This is just desugared version of
// fn foo(_: &String) -> impl Debug + 'static {}

fn get_debug() -> impl Debug + 'static {
    let s = "hello".to_owned();
    foo(&s)
}

fn main() {
    let x = get_debug();
    println!("{x:?}");
}

with

   Compiling playground v0.0.1 (/playground)
error[E0597]: `s` does not live long enough
  --> src/main.rs:9:9
   |
8  |     let s = "hello".to_owned();
   |         - binding `s` declared here
9  |     foo(&s)
   |     ----^^-
   |     |   |
   |     |   borrowed value does not live long enough
   |     argument requires that `s` is borrowed for `'static`
10 | }
   | - `s` dropped here while still borrowed

For more information about this error, try `rustc --explain E0597`.
error: could not compile `playground` (bin "playground") due to 1 previous error

So, is this expected? I would expect either both of them to work or neither, because the first one seemingly leverages knowledge of that + 'static + use<'_> means that either '_: 'static or that the returned type actually does not capture the lifetime, so it must be the same thing as just + 'static.

The second example seems to not use reasoning like this, but then ends up with constraints that effectively enforce '_: 'static.

But more importantly, it's weird that the same function can be used with non-static lifetimes in one context and effectively cannot be in others.

1 post - 1 participant

Read full topic

🏷️ rust_feed