Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-2729] Function incorrectly claims to be never executed #45333

Closed
swift-ci opened this issue Sep 22, 2016 · 14 comments
Closed

[SR-2729] Function incorrectly claims to be never executed #45333

swift-ci opened this issue Sep 22, 2016 · 14 comments
Assignees
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself

Comments

@swift-ci
Copy link
Collaborator

Previous ID SR-2729
Radar rdar://problem/40722854
Original Reporter jaspa (JIRA User)
Type Bug
Status Resolved
Resolution Done
Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug
Assignee @slavapestov
Priority Medium

md5: 05103d6ed56884dc153cd8dc698f830b

relates to:

  • SR-2105 Bogus "will never be executed" error in init?(exactly:)
  • SR-7841 Function returning associated type Never claims to be never executed
  • SR-7472 Compiler doesn't realize result of generic function specialized to Never doesn't ever return

Issue Description:

Given a protocol P which requires some function f with return type Never and some type T conforming to P:
A warning is issued, saying T.f would never be called because of a “call to a never-returning function”.

Example:

protocol Fooable {
 func foo() -> Never
}
struct Foo: Fooable {
 func foo() -> Never { // unexpected warning here
  fatalError()
 }
}

Output:

test.swift:5:7: warning: will never be executed
 func foo() -> Never {
      ^
test.swift:5:7: note: a call to a never-returning function
 func foo() -> Never {
      ^

Swift version: (Xcode 8.0)

Apple Swift version 3.0 (swiftlang-800.0.46.2 clang-800.0.38)
Target: x86_64-apple-macosx10.9
@belkadan
Copy link
Contributor

Looks like a bug with the synthesized protocol witness. @jckarter, who'd be good to look at this?

@jckarter
Copy link
Member

@slavapestov did the `Never` stuff originally. Anyone familiar with the SIL diagnostic passes might be able to look into it too.

@swift-ci
Copy link
Collaborator Author

Comment by Matthew Johnson (JIRA)

I just ran into this bug. Here is a small amount of code that causes it. If anyone knows of a workaround that will suppress the warning prior to a fix landing please share it here.

protocol StateContainer {
    associatedtype UpdateRequest
    associatedtype ChangeEvent
    mutating func update(using request: UpdateRequest) throws -> ChangeEvent
}

struct NoState: StateContainer {
    struct UpdateError: Error { let request: Never }
    mutating func update(using request: Never) throws -> Never { // warning here
        throw UpdateError(request: request)
    }
}

@jckarter
Copy link
Member

We should probably just not emit diagnostics for thunk functions such as witness table thunks. You might be able to work around this by hiding the `update` witness in a protocol extension which hides the `Never`-ness of the input and output types:

protocol StateContainer { ... }

protocol UnreachableStateContainer { ... }

extension StateContainer where Self: UnreachableStateContainer {
  mutating func update(using request: UpdateRequest) throws -> ChangeEvent { fatalError() }
}

struct NoState: StateContainer, UnreachableStateContainer {
  typealias UpdateRequest = Never
  typealias ChangeEvent = Never
}

@swift-ci
Copy link
Collaborator Author

Comment by Matthew Johnson (JIRA)

Thanks Joe. I had tried a few things like this but hadn't hit on the right one. This pointed me in the right direction.

Has something like `clang diagnostic` been considered? It is occasionally very useful to be able to turn off specific diagnostics in a very specific context. This is especially important when you want to turn on warnings as errors for CI builds.

@jckarter
Copy link
Member

Well, in this case, the diagnostic is just wrong and needs to be fixed.

@swift-ci
Copy link
Collaborator Author

Comment by Matthew Johnson (JIRA)

Yep, I understand that. I'm not sure if I've run into this problem when a compiler bug wasn't involved or not. Regardless, I think the ability to turn off warnings on a targeted basis is useful.

@belkadan
Copy link
Contributor

belkadan commented Dec 1, 2017

People who turn a warning off for a particular line of code never turn it back on. With a perfect compiler, a warning would always be valid or have a way to silence it if the code is merely suspicious. But I know we don't have a perfect compiler.

(This is probably not the right place to talk about this.)

@swift-ci
Copy link
Collaborator Author

swift-ci commented Dec 1, 2017

Comment by Matthew Johnson (JIRA)

FWIW, I agree with all of your comments @belkadan. Is something that would need to be discussed on evolution if it were to happen?

@belkadan
Copy link
Contributor

belkadan commented Dec 1, 2017

Probably yes.

@slavapestov
Copy link
Member

#13776

@lilyball
Copy link
Mannequin

lilyball mannequin commented Mar 28, 2018

This is still an issue with protocols that declare initializers. Trivial test case:

protocol Foo {
    init(x: Int)
}
enum NotEver: Foo {
    init(x: Int) {
        fatalError()
    }
}

I reproduced this using Xcode 9.3 beta 4 as well as the 3/26/2018 snapshots of both 4.1 and master.

@belkadan
Copy link
Contributor

belkadan commented Jun 1, 2018

@swift-ci create

@slavapestov
Copy link
Member

#17019

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself
Projects
None yet
Development

No branches or pull requests

4 participants