Constrain type parameter to function types

This is a pretty simple question. Say I wanted to build a struct like so:

struct FunctionHolder<Function> {
    c: @convention(c) Function
    block: @convention(block) Function
}

the compiler will complain that @convention attribute only applies to function types. Is there a way to us constraints to constrain the Function type parameter to only function types?

If you want to represent a function in the generics system, you can usually do that by using the function's parameters and result as generic parameters, as shown below:

struct Function<each Parameter> {
    struct Returning<Result> {
        struct Holder {
            var function: (repeat each Parameter) -> Result
        }
        private init() {}
    }
    private init() {}
}

let functionHolder = Function.Returning<Void>.Holder(function: {})

Unfortunately, in the case of @convention(c) and @convention(block), that won't work. You'll get an error saying that "'(repeat each Parameter) -> Result' is not representable in Objective-C, so it cannot be used with '@convention(c/block)'". This error occurs even if each Parameter and Result are constrained to Objective-C–representable types like NSObject or NSObjectProtocol. As far as I know, using @convention(c/block) with generics is not possible with Swift at the moment. You could try doing this with macros, though.

2 Likes

Thanks for the helpful information! I may take a look at macros.

1 Like