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-6975] Bogus "Case is already handled by previous patterns" warning when using an is-pattern that always succeeds #49523
Comments
Thanks Hamish! Fixed in #14539 |
Awesome, thanks for the fast turnaround Greg! |
I am reopening this because the fix is too narrow enum E {
case a, b
}
let e = E.b
switch e {
case (E.a as E) as E?:
print("second a")
case .b:
print("ss")
case .a:
print("asdf")
} |
Interesting, thanks @CodaFi! Is optional wrapping the only situation in which this can occur? I can't come up with anything else, but I'm also the one who missed this possibility. 🙂 |
It looks like downcasts are okay: And I bet you could contrive something awful with ObjC bridging, but I'm okay with not worrying about that. (Honestly, I'm not so worried about your case either, Robert. Did this come up in real code?) |
This seems to be the case with arbitrary coercions, including bridging coercions. Although I doubt many people (if any) are writing such code, it is a fairly serious issue, as it means we allow code like this to compile, as we consider the switch to be exhaustive: func foo(_ str: String) -> Int {
switch str {
case let (x as Int) as Any:
return x
}
}
let i = foo("wtf") |
Having thought about this some more, I'm fairly sure that the original type space coverage for coercions was just plain wrong any time there is a subpattern - it certainly shouldn't be the entire type if any other conditional matching is happening. This should be fixed in #15264 (which also adds Hamish's latest example above as a test) and the failure mode now if I haven't thought of everything correctly is flipped so that maybe we'll require a default case in what a user thinks is an exhaustive switch instead of letting through crashers. |
LGTM, thanks again Greg! |
Comment by Frank (JIRA) This warning also appears unexpectedly in my case where I use the `fallthrough` keyword to have multiple cases executed. enum E {
case a, b
}
let e = E.b
switch e {
case .a, .b:
print("a and b")
fallthrough
case .b:
print("b") // warning: Case is already handled by previous patterns; consider removing it
case .a:
print("a") // warning: Case is already handled by previous patterns; consider removing it
} |
@frank This warning is correct. I think you are misunderstanding what ‘fallthrough’ means. The second case in your example will be executed unconditionally and the last one never executed. |
Comment by Frank (JIRA) Oh this is quite embarrassing 😃. I was thinking that with `fallthrough` it is just continuing the evaluation of the cases. Thanks for pointing this out @xwu |
Environment
Swift version 4.1-dev (LLVM b1f1b1f5b8, Clang d8b11579e8, Swift c8ec79b)
Target: x86_64-apple-darwin17.4.0
Additional Detail from JIRA
md5: 91a829021512f6d2bc934848477d4ac3
Issue Description:
The following code yields two warnings:
The first warning is expected, the second is unexpected as although the is-pattern always succeeds, its sub-pattern does not.
The text was updated successfully, but these errors were encountered: