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-6975] Bogus "Case is already handled by previous patterns" warning when using an is-pattern that always succeeds #49523

Closed
hamishknight opened this issue Feb 10, 2018 · 11 comments
Assignees
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself

Comments

@hamishknight
Copy link
Collaborator

Previous ID SR-6975
Radar None
Original Reporter @hamishknight
Type Bug
Status Closed
Resolution Done
Environment

Swift version 4.1-dev (LLVM b1f1b1f5b8, Clang d8b11579e8, Swift c8ec79b)
Target: x86_64-apple-darwin17.4.0

Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug
Assignee @gregomni
Priority Medium

md5: 91a829021512f6d2bc934848477d4ac3

Issue Description:

The following code yields two warnings:

enum E {
  case a, b
}

let e = E.b
switch e {
case .a as E: // warning: 'as' test is always true
  print("a")
case .b: // warning: Case is already handled by previous patterns; consider removing it
  print("b")
}

The first warning is expected, the second is unexpected as although the is-pattern always succeeds, its sub-pattern does not.

@gregomni
Copy link
Collaborator

Thanks Hamish! Fixed in #14539

@hamishknight
Copy link
Collaborator Author

Awesome, thanks for the fast turnaround Greg!

@CodaFi
Copy link
Member

CodaFi commented Feb 12, 2018

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")
  }

@gregomni
Copy link
Collaborator

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. 🙂

@belkadan
Copy link
Contributor

It looks like downcasts are okay: case (_ as Bundle) as NSObject

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?)

@hamishknight
Copy link
Collaborator Author

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")

@gregomni
Copy link
Collaborator

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.

@hamishknight
Copy link
Collaborator Author

LGTM, thanks again Greg!

@swift-ci
Copy link
Collaborator

Comment by Frank (JIRA)

This warning also appears unexpectedly in my case where I use the `fallthrough` keyword to have multiple cases executed.
Shall I open a new ticket for it, or reopen this one?

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
}

@xwu
Copy link
Collaborator

xwu commented Mar 24, 2020

@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.

@swift-ci
Copy link
Collaborator

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

@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

6 participants