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
Comments
Looks like a bug with the synthesized protocol witness. @jckarter, who'd be good to look at this? |
@slavapestov did the `Never` stuff originally. Anyone familiar with the SIL diagnostic passes might be able to look into it too. |
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)
}
} |
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
} |
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. |
Well, in this case, the diagnostic is just wrong and needs to be fixed. |
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. |
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.) |
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? |
Probably yes. |
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. |
@swift-ci create |
Additional Detail from JIRA
md5: 05103d6ed56884dc153cd8dc698f830b
relates to:
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:
Output:
Swift version: (Xcode 8.0)
The text was updated successfully, but these errors were encountered: