Why doesn't trait associated function satisfy these trait bounds

I'm confused why this code, the compiler complains about some lifetime bounds not being satisfied when an associated function defined as a trait is passed, but not when an associated function on the same type is passed if its not part of a trait. The code linked could probably be distilled a bit but I derived it from a library I'm playing around with and am not sure where the full problem stems from.

struct Foo<A, B, C> {
    a: A,
    b: B,
    c: C,
}

trait FooTrait<A> {}

struct FooThing<A> {
    a: A,
}

impl<A> FooTrait<A> for FooThing<A> {}

impl<A: 'static, B: FooTrait<A> + 'static, C: FnMut(&mut A) -> B + 'static> Foo<A, B, C> {
    pub fn new(a: A, c: C) -> Self {
        todo!()
    }

    pub fn run(self) {
        todo!()
    }
}

pub trait MyTrait: Sized {
    fn my_fn(state: &mut Self) -> impl FooTrait<Self>;
}

#[derive(Default, Clone)]
struct Baz {
    message: String,
}

impl MyTrait for Baz {
    fn my_fn(state: &mut Self) -> impl FooTrait<Self> {
        FooThing { a: state.clone() }
    }
}

impl Baz {
    fn my_other_fn(state: &mut Self) -> impl FooTrait<Self> {
        FooThing { a: state.clone() }
    }
}

fn my_run() {
    Foo::new(Baz::default(), Baz::my_fn).run(); // does not compile
    // Foo::new(Baz::default(), Baz::my_other_fn).run(); // does compile
}

See my answer here. In brief, the output type of my_other_fn doesn't capture the input lifetime on &mut self and is thus a single concrete type for all input lifetimese, whereas the output type of my_fn does capture the input lifetime and is thus a type constructor parameterize by a lifetime (and cannot unify with a type variable like B).

If it's still not clear, let me know.

I guess you probably control MyTrait? In that case, don't use RPITIT for the method if you never intend to capture the input lifetime; use an associated type.

pub trait MyTrait: Sized {
    type MfOut: FooTrait<Self>;
    fn my_fn(state: &mut Self) -> Self::MfOut;
}

impl MyTrait for Baz {
    type MfOut = FooThing<Baz>;
    fn my_fn(state: &mut Self) -> Self::MfOut {
        FooThing { a: state.clone() }
    }
}

On nightly you can combine impl Trait and associated types, if you wanted the associated type to remain opaque for Baz's implementation.

#![feature(impl_trait_in_assoc_type)]
impl MyTrait for Baz {
    type MfOut = impl FooTrait<Self>;
    fn my_fn(state: &mut Self) -> Self::MfOut {
        FooThing { a: state.clone() }
    }
}

Ah thanks this working example made the rest of it make sense. Thank you!