Implementation of `From` is not general enough, but I don't need such general

Hi, I have a problem that reduces to this (playground):

struct S<'a> {
    data: &'a i32,
}

struct S1<'a> {
    inner: S<'a>,
}

struct S2<'a> {
    inner: S<'a>,
}

impl<'a> From<S<'a>> for S1<'a> {
    fn from(inner: S<'a>) -> Self {
        Self{inner}
    }
}

impl<'a> From<S<'a>> for S2<'a> {
    fn from(inner: S<'a>) -> Self {
        Self{inner}
    }
}

fn run<T>(func: impl Fn(T))
where
    for<'a> T: From<S<'a>>
{
}

fn work_with_s1<'a>(_s: S1<'a>) { }
fn work_with_s2<'a>(_s: S2<'a>) { }

fn main() {
    run(work_with_s1);
    run(work_with_s2);
}

error:

error: implementation of `From` is not general enough
   --> src/main.rs:35:5
    |
35  |       run(work_with_s1);
    |       ^^^ implementation of `From` is not general enough
    |
    = note: `From<S<'0>>` would have to be implemented for the type `S1<'_>`, for any lifetime `'0`...
    = note: ...but `From<S<'1>>` is actually implemented for the type `S1<'1>`, for some specific lifetime `'1`

I read from the error message that trait From only implemented for a specific lifetime, but fn run want it for any lifetime.
The question is: How can I modify the constrain on fn run to only accept From<S> just for a specific lifetime?

This generic bound means the T can be converted from S<'a>, for whatever lifetime possible named 'a. But really, S1<'a> can only be converted from the S<'a>, not something S<'b> which may have shorter lifetime.You need some specific 'a provided by the caller, not a whatever lifetime.

fn run<'a, T>(func: impl Fn(T))
where
    T: From<S<'a>>
{
}
3 Likes