MLQ
MLQ

Reputation: 13511

Compile error for passing nil to an optional parameter with a generic type constraint

My class MQChainedOperation has a function append which accepts any operation that inherits from MQOperation:

public func append<T: MQOperation>(operation: T, 
    validator: (Any? -> Bool)?,
    configurator: ((T, Any?) -> Void)?) {
        // ...
}

In a view controller, I do this:

let chain = MQChainedOperation()
chain.append(
    MQBlockOperation {[unowned self] in
        // ...
    },
    validator: nil,
    configurator: nil)
chain.append(
    SignUpOperation(),
    validator: nil,
    configurator: nil)

And the compiler throws this error at me from both calls to append, when both MQBlockOperation and SignUpOperation do inherit from MQOperation:

Cannot invoke 'append' with an argument list of type '(MQOperation, validator: (Any? -> Bool)?, configurator: ((MQOperation, Any?) -> Void)?)'

Expected an argument list of type '(T, validator: (Any? -> Bool)?, configurator: ((T, Any?) -> Void)?)'

However, if I supply an empty closure for the configurator, it works:

chain.append(
    MQBlockOperation {[unowned self] in
        // ...
        return NSDate()
    },
    validator: nil,
    configurator: {(op, result) in})
chain.append(
    SignUpOperation(),
    validator: nil,
    configurator: {(op, result) in})

I should be able to pass nil to an optional parameter, and the workaround makes my code ugly. How do I fix this?

Upvotes: 1

Views: 143

Answers (1)

MLQ
MLQ

Reputation: 13511

As in the comments, this seems like a bug with the Swift compiler. For now, a quick, clean fix I like is to provide nil as a default value in the function signature.

public func append<T: MQOperation>(operation: T,
    validator: (Any? -> Bool)?,
    configurator: ((T, Any?) -> Void)? = nil)

Upvotes: 1

Related Questions