Search code examples
xcodeswiftclangcompiler-warningssuppress-warnings

Hide Swift "Will never be executed" warning


I've got some code that is generating warnings like so:

code path.swift:9:13: warning: will never be executed

       fatalError()
       ^

code path.swift:9:13: note: a call to a noreturn function

       fatalError()
       ^

The compiler output doesn't give any -W arguments I can use to silence these in my source file. How can I stop these warnings?

Please note this is testing code and everything is working as designed - removing the lines complained about is not a solution


Solution

  • The Swift compiler does not have an option to suppress warnings (as far as I know). The only chance is to avoid the warnings.

    In your particular case I don't have a full explanation for the warning, but a possible workaround. As you said in the comments, the problem occurs with the Nimble framework in

    expect{ fatalError() }.to(throwError()) // Warning: Will never be executed
    

    Here, { fatalError() } is a closure of type () -> Void, and expect ultimately calls the Expression initializer

    public init(expression: () throws -> T?, location: SourceLocation, isClosure: Bool = true)
    

    which takes a closure of type () throws -> T? as the first parameter. The problem is now related to the optional return type T?.

    This can be stripped down to the following minimal self-contained example:

    let cl1 : () -> Void  = { fatalError() } // No warning
    let cl2 : () -> Void? = { fatalError() } // Warning: Will never be executed
    

    Only the second line generates a warning. I assume that the compiler creates some wrapper code to convert the Void return type from fatalError() to Void?, and then warns that the wrapper code is never executed.

    As a workaround, you can make the closure type explicit as

    let cl3 : () -> Void?  = { _ -> Void in fatalError() } // No warning
    

    or assign the closure to an intermediate variable:

    let fatalClosure = { fatalError() }
    let cl4 : () -> Void? = fatalClosure // No warning
    

    This can be applied to your case:

    expect {
        _ -> Void in fatalError()
    }.to(throwError())
    

    But note that fatalError() – when called – terminates the program immediately. There is no chance to "catch" that termination.