How to supress “will never be executed” warning from closure parameter of type `Never`?

i have a generic method that takes a closure which looks like:

func highlight<Link>(_ fragments:[Fragment<Link>], 
    _ anchor:(Link) throws -> Anchor) 
    rethrows 

however, if i call it with Link == Never, i get the “warning: will never be executed” warning:

warning: will never be executed
    return .code(Self.highlight(signature) { _ in fatalError("unreachable") })
                                                      ^
note: '_' is of type 'Never' which cannot be constructed because it is an 
enum with no cases
    return .code(Self.highlight(signature) { _ in fatalError("unreachable") })

how do i get rid of this warning?

I think replacing this:

with this:

    return .code(Self.highlight(signature) { _ in /*no code here*/})

would work.

that causes

error: cannot convert value of type '()' to closure result type 'Anchor'

I suppose is a bug then. At least one of those should not warn, I think.

I'm not able to reproduce this with the simple example below. Is there something else going on perhaps?

func f<T>(_ argument: T?, _ closure: (T) throws -> Int) rethrows {
    if let argument = argument {
        try closure(argument)
    }
}
f(nil as Never?) { _ in fatalError() }

I ran across a similar issue a few weeks ago when I tried to switch over a multi-thousand case enum. The switch was technically exhaustive, but the compiler told me it didn't want to do the checking and recommended I short-circuit by adding a default. It compiled once I added the default, however with a warning similar to will never be executed :disappointed:.

1 Like

Try this:

func absurd<A>(_: Never) -> A { }

...

    return .code(Self.highlight(signature, absurd))
1 Like

here’s a minimal example:

func foo<T>(first:[Int], second:[T], _ function:(T) throws -> Int) 
    rethrows -> [Int]
{
    try first + second.map(function)
}
func bar()
{
    let _ = foo(first: [0], second: [] as [Never]) 
    { 
        _ in fatalError("unreachable") 
    }
}

this is the same as

While I agree that the compiler should treat them the same, it does not:

BTW, I didn't invent this workaround. I first saw it in swift-composable-architecture.

2 Likes

Ugh, I am able to reproduce it with both my minimal example and yours; the warning is just suppressed in Swift Playgrounds (which I find handy for these little snippets).

It's not exactly a diagnostics bug, as the fatalError call is indeed unreachable. Rather, there seems to be some sort of type inference bug, as a sufficient workaround is actually to annotate the closure argument type, leaving the body empty:

foo(first: [0], second: [] as [Never]) { (_: Never) -> Int in }

Put another way, it's the error you encounter with an empty closure that's the bug and not the warning, and that is indeed worthy of a report.

2 Likes

Giving an explicit return type seems to suffice:

    let _ = foo(first: [0], second: [] as [Never]) { _ -> Int in }
2 Likes

Cool, this nicely implicates closure return type inference as the problem :)

1 Like

this worked for me!