Holding a reference to a protocol method

Sometimes it's helpful to hold a reference to a method of a concrete type, e.g.

let signum: (Int) -> () -> Int = Int.signum
signum(-5)()

Is there an equivalent for holding a reference to a protocol method?

protocol ExampleProtocol {
    func example()
}

let example: (ExampleProtocol) -> () -> Void = ExampleProtocol.example

The example above produces a compile-time segmentation fault while emitting SIL.

(It also scares Xcode and results in everyone's favorite "An internal error occurred. Source editor functionality is limited." banner along the top.)

I imagine there's a technical limitation here that's beyond my current understanding of the compiler, but I'd love to learn about it.

Considering you want to hold a reference, likely you intend to call the method at some point. Isn’t calling such a method, to put it mildly, ambiguous?

That said, I don’t see why this should be allowed. Although Xcode freaking out should be considered a bug, of course :)

Edit: Ah, misread the signature. Of course, should be filed. Follow up with a link if you do!

A quick search on https://bugs.swift.org didn't turn up an exact match (although there are a few reports about protocols and segfaults in SILGen).

Could you please file a bug at https://bugs.swift.org

1 Like

I'd consider it a bug, since you can do it explicitly...

let example: (ExampleProtocol) -> () -> Void = { example in
    { example.example() }
}
2 Likes

Every segmentation fault is a bug

(But I get what you meant ;) )

Filed: https://bugs.swift.org/browse/SR-7264
Thanks all!

1 Like