Generics unbind lifetimes and I dislike that

⚓ Rust    📅 2026-01-29    👤 surdeus    👁️ 6      

surdeus

Warning

This post was published 33 days ago. The information described in this article may have changed.

Hi!
I recently discovered a problem in my code which I don't know how to escape.
Basically, my structure behaves similar to this:

// this makes an anonymous struct which takes the `T`
fn printer<T: Debug>() -> impl FnOnce(T) {
    |val| { println!("{val:?}"); }
}

fn take_binded(_: impl for<'a> FnOnce(&'a i32)) { .. }

Now writing the printer without the generic T makes it able to being passed into take_binded.
However, because there's the generic involved, it tries to collapse the lifetime and I instead get

error: implementation of `FnOnce` is not general enough
 --> src/main.rs:5:5
  |
5 |     take_binded(printer());
  |     ^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
  |
  = note: `impl FnOnce(&'2 i32)` must implement `FnOnce<(&'1 i32,)>`, for any lifetime `'1`...
  = note: ...but it actually implements `FnOnce<(&'2 i32,)>`, for some specific lifetime `'2`

As I've already played around with some basic trait shenanigans to overcome this, I don't think it's possible to make this work (except there's a suuuper magic trick for this).

Tho I wanted to ask if there's any reason logical-wise which should disallow this or if there just wasn't yet made the effort to "track bindings" of lifetimes with generics.

Thanks :smiley:

PS: for playing around with the issue playground

5 posts - 3 participants

Read full topic

🏷️ Rust_feed