Bedford
Bedford

Reputation: 1186

Suppress Swift compiler warning

I'm using the Nimble assertion framework for unit testing in Swift (Xcode 6.3 beta). It works fine, but the compiler gives a warning for one of the lines in the Nimble source code:

public func expect<T>(expression: () -> T?, file: String = __FILE__, line: UInt = __LINE__) -> Expectation<T> {
    return Expectation(
        expression: Expression(
            expression: expression,
            location: SourceLocation(file: file, line: line),
            isClosure: true))
}

The warning is for the first line:

Closure parameter prior to parameters with default arguments will not be treated as a trailing closure

It's not a very serious issue, but I'd like to keep the number of compiler warnings low (zero) in my projects. Is there a way to remove this warning?

Upvotes: 13

Views: 6297

Answers (4)

Julian
Julian

Reputation: 9337

You can avoid the warning if the method signature will look like:

public func expect<T>(expression: (() -> T?), file: String = __FILE__, line: UInt = __LINE__) -> Expectation<T> 

added extra parenthesis around the first argument, tested with Swift 2.0 and Xcode 7.1

Another way of fixing it is to have all attributes with default value before the closure attribute as trailing closure is a quite convenient thing to have

Upvotes: 25

Ilya Puchka
Ilya Puchka

Reputation: 141

@Julian Król answer is wrong for two reasons:

  1. the code snippet demonstrate the wrong syntax, the correct will be:

public func expect<T>(expression: (() -> T?), file: String = __FILE__, line: UInt = __LINE__) -> Expectation<T>

  1. even with right syntax in Xcode 7.1 it does not fix the issue, cause you can not call this methods with trailing closure- it will give you compile error like Missing argument for parameter #1 in call.

With provided code you will only get rid of warning but you will not be able to use trailing closure when you call this function.

It fixes warning because in Swift tuple with one child is interchangeable with just single variable. And even ((((value)))) is the same as just value. Also looks like compiler does not recognize tuple with closure child as standalone closure in function arguments list.

Upvotes: 3

gnasher729
gnasher729

Reputation: 52622

Looks like a very serious warning to me, that you most definitely should not ignore. It seems that what you think is a function call with a closure parameter is actually a function call without a closure parameter, followed by a closure.

You easily avoid the warning and fix the problem by putting the closure into the parameter list, or assigning it to a variable before the call and passing that variable.

Upvotes: -2

D&#225;niel Nagy
D&#225;niel Nagy

Reputation: 12045

To all the future readers of this topic: the answer is just for the case, when you have trailing closures. AFAIK, there is no way you can suppress Swift warnings like you would do in Objective-C (disable warnings for specific lines), maybe when the source of the Swift compiler will be open source, there will be some valid solutions, and this answer will be updated. Until then, you can check these answers (not Swift specific):

In Xcode, how to suppress all warnings in specific source files?

Is there a way to suppress warnings in Xcode?

If you can change the signature of expect, then put the parameter expression to the end, like:

public func expect<T>(file: String = __FILE__, line: UInt = __LINE__, expression: () -> T?) -> Expectation<T>

To be honest, it is poor design to have a closure parameter as the first parameter.

Upvotes: -1

Related Questions