How to use `Self` type in trait methods?

I’m getting a trait implementation error when trying to return a function that takes the implementing type as a parameter. The compiler seems to interpret Self differently between the trait definition and implementation.

Here’s my code

trait Handler:
    fn get_handler(mut self) -> fn (mut Self) raises escaping:
        ...

struct MyHandler(Handler):
    fn __init__(out self):
        pass

    fn get_handler(mut self) -> fn (mut Self) raises escaping:
        fn inner(mut handler: Self) raises escaping:
            pass

        return inner

fn main() raises:
    var handler = MyHandler()
    var func = handler.get_handler()
error: 'MyHandler' does not implement all requirements for 'Handler'
note: no 'get_handler' candidates have type 'fn[Handler](mut $0) raises escaping -> None[MyHandler]'
note: candidate declared here with type 'fn(mut self: MyHandler) -> fn(mut MyHandler) raises escaping -> None'

The trait expects fn[Handler](mut $0) but my implementation provides fn(mut MyHandler). How do I properly reference the concrete type in the trait implementation when returning functions that take Self as a parameter?

Could you maybe file an issue on Github?

@billyzhu what do you think? To me this signature in the error message looks wrong:

no get_handler candidates have type fn[Handler](mut $0) raises escaping -> None[MyHandler]

Also, it only happens when for escaping closure.

+1 with @denis that the error message looks pretty badly formatted. This is a problem in our type printer for struct types that represent closures. But it hides the actual problem, which is the representation of “generic” closure struct types and the logic to implicitly convert between them. We may not be able to get to this very soon as we’re in the middle of a closure overhaul, but by the end of it we should be more equipped to handle this.

@shuklaayush please feel free to file an issue to keep track. For the time being, as @sora said, this only applies to “closures”, not raw function types, so by removing the escaping keyword, you can make this work. It just requires that the function you return need no state. Hopefully you’re able to refactor your code so that any captured state necessary can be passed explicitly (like with the self argument passed into the handler).