New warning message while switching on an enum


(Pushkar N Kulkarni) #1

Hi there,

I see a new warning message for switch statements on enums, like this one:

enum Test {

case one(Any)

case two

}

let x: Test = .one(“One”)

switch x {

case .one(let s as String): print(s)

case .one: break

case .two: break

}

enum.swift:9:10: warning: case is already handled by previous patterns; consider removing it

case .one: break 

I do not see this warning with the 04-24 dev snapshot.

The warning goes away with the use of the wildcard pattern in the second case:

switch x {

case .one(let s as String): print(s)

case .one(_): break

case .two: break

}

I am wondering if this change is intentional, though it does make sense to me. Can someone please point me to the related commit?

Thanks in advance!

Pushkar N Kulkarni,

IBM Runtimes

Simplicity is prerequisite for reliability - Edsger W. Dijkstra


(Jordan Rose) #2

That looks like a bug to me, since of course the first pattern won't always match. I suspect this is Robert's work on trying to make the exhaustive checks better, https://github.com/apple/swift/pull/8908. Thanks for catching this!

Jordan

···

On May 9, 2017, at 07:09, Pushkar N Kulkarni via swift-dev <swift-dev@swift.org> wrote:

Hi there,

I see a new warning message for switch statements on enums, like this one:

enum Test {
    case one(Any)
    case two
}

let x: Test = .one("One")
switch x {
    case .one(let s as String): print(s)
    case .one: break
    case .two: break
}

enum.swift:9:10: warning: case is already handled by previous patterns; consider removing it
    case .one: break

I do not see this warning with the 04-24 dev snapshot.

The warning goes away with the use of the wildcard pattern in the second case:

switch x {
    case .one(let s as String): print(s)
    case .one(_): break
    case .two: break
}

I am wondering if this change is intentional, though it does make sense to me. Can someone please point me to the related commit?

Thanks in advance!

Pushkar N Kulkarni,
IBM Runtimes

Simplicity is prerequisite for reliability - Edsger W. Dijkstra

_______________________________________________
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev


(Robert Widmann) #3

It’s mine, yep. It looks like it’s classifying the cast in the first pattern as a variable binding instead of an expression pattern. I’ll push a fix later.

Thanks!

···

On May 9, 2017, at 1:52 PM, Jordan Rose <jordan_rose@apple.com> wrote:

That looks like a bug to me, since of course the first pattern won't always match. I suspect this is Robert's work on trying to make the exhaustive checks better, https://github.com/apple/swift/pull/8908. Thanks for catching this!

Jordan

On May 9, 2017, at 07:09, Pushkar N Kulkarni via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:

Hi there,

I see a new warning message for switch statements on enums, like this one:

enum Test {
    case one(Any)
    case two
}

let x: Test = .one("One")
switch x {
    case .one(let s as String): print(s)
    case .one: break
    case .two: break
}

enum.swift:9:10: warning: case is already handled by previous patterns; consider removing it
    case .one: break

I do not see this warning with the 04-24 dev snapshot.

The warning goes away with the use of the wildcard pattern in the second case:

switch x {
    case .one(let s as String): print(s)
    case .one(_): break
    case .two: break
}

I am wondering if this change is intentional, though it does make sense to me. Can someone please point me to the related commit?

Thanks in advance!

Pushkar N Kulkarni,
IBM Runtimes

Simplicity is prerequisite for reliability - Edsger W. Dijkstra

_______________________________________________
swift-dev mailing list
swift-dev@swift.org <mailto:swift-dev@swift.org>
https://lists.swift.org/mailman/listinfo/swift-dev


(Jordan Rose) #4

It's neither a variable binding nor an expression pattern, right? It has to be compared against the original type to know whether it's exhaustive or not. (Consider "let error as NSError" in a catch clause, which should be considered exhaustive.)

Jordan

···

On May 9, 2017, at 11:12, Robert Widmann <devteam.codafi@gmail.com> wrote:

It’s mine, yep. It looks like it’s classifying the cast in the first pattern as a variable binding instead of an expression pattern. I’ll push a fix later.

Thanks!

On May 9, 2017, at 1:52 PM, Jordan Rose <jordan_rose@apple.com <mailto:jordan_rose@apple.com>> wrote:

That looks like a bug to me, since of course the first pattern won't always match. I suspect this is Robert's work on trying to make the exhaustive checks better, https://github.com/apple/swift/pull/8908. Thanks for catching this!

Jordan

On May 9, 2017, at 07:09, Pushkar N Kulkarni via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:

Hi there,

I see a new warning message for switch statements on enums, like this one:

enum Test {
    case one(Any)
    case two
}

let x: Test = .one("One")
switch x {
    case .one(let s as String): print(s)
    case .one: break
    case .two: break
}

enum.swift:9:10: warning: case is already handled by previous patterns; consider removing it
    case .one: break

I do not see this warning with the 04-24 dev snapshot.

The warning goes away with the use of the wildcard pattern in the second case:

switch x {
    case .one(let s as String): print(s)
    case .one(_): break
    case .two: break
}

I am wondering if this change is intentional, though it does make sense to me. Can someone please point me to the related commit?

Thanks in advance!

Pushkar N Kulkarni,
IBM Runtimes

Simplicity is prerequisite for reliability - Edsger W. Dijkstra

_______________________________________________
swift-dev mailing list
swift-dev@swift.org <mailto:swift-dev@swift.org>
https://lists.swift.org/mailman/listinfo/swift-dev


(Robert Widmann) #5

We’ll warn if that kind of cast is a tautology, right? That leaves only the dynamic casts, which can’t be assumed exhaustive.

~Robert Widmann

···

On May 9, 2017, at 2:13 PM, Jordan Rose <jordan_rose@apple.com> wrote:

It's neither a variable binding nor an expression pattern, right? It has to be compared against the original type to know whether it's exhaustive or not. (Consider "let error as NSError" in a catch clause, which should be considered exhaustive.)

Jordan

On May 9, 2017, at 11:12, Robert Widmann <devteam.codafi@gmail.com <mailto:devteam.codafi@gmail.com>> wrote:

It’s mine, yep. It looks like it’s classifying the cast in the first pattern as a variable binding instead of an expression pattern. I’ll push a fix later.

Thanks!

On May 9, 2017, at 1:52 PM, Jordan Rose <jordan_rose@apple.com <mailto:jordan_rose@apple.com>> wrote:

That looks like a bug to me, since of course the first pattern won't always match. I suspect this is Robert's work on trying to make the exhaustive checks better, https://github.com/apple/swift/pull/8908. Thanks for catching this!

Jordan

On May 9, 2017, at 07:09, Pushkar N Kulkarni via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:

Hi there,

I see a new warning message for switch statements on enums, like this one:

enum Test {
    case one(Any)
    case two
}

let x: Test = .one("One")
switch x {
    case .one(let s as String): print(s)
    case .one: break
    case .two: break
}

enum.swift:9:10: warning: case is already handled by previous patterns; consider removing it
    case .one: break

I do not see this warning with the 04-24 dev snapshot.

The warning goes away with the use of the wildcard pattern in the second case:

switch x {
    case .one(let s as String): print(s)
    case .one(_): break
    case .two: break
}

I am wondering if this change is intentional, though it does make sense to me. Can someone please point me to the related commit?

Thanks in advance!

Pushkar N Kulkarni,
IBM Runtimes

Simplicity is prerequisite for reliability - Edsger W. Dijkstra

_______________________________________________
swift-dev mailing list
swift-dev@swift.org <mailto:swift-dev@swift.org>
https://lists.swift.org/mailman/listinfo/swift-dev


(Jordan Rose) #6

"as NSError" isn't a tautology, though—the original type is 'Error'. Additionally, the presence or absence of a warning shouldn't affect exhaustiveness analysis, which is currently an error when you get it wrong. Warnings are things you can build with and fix later.

Jordan

···

On May 9, 2017, at 11:22, Robert Widmann <devteam.codafi@gmail.com> wrote:

We’ll warn if that kind of cast is a tautology, right? That leaves only the dynamic casts, which can’t be assumed exhaustive.

~Robert Widmann

On May 9, 2017, at 2:13 PM, Jordan Rose <jordan_rose@apple.com <mailto:jordan_rose@apple.com>> wrote:

It's neither a variable binding nor an expression pattern, right? It has to be compared against the original type to know whether it's exhaustive or not. (Consider "let error as NSError" in a catch clause, which should be considered exhaustive.)

Jordan

On May 9, 2017, at 11:12, Robert Widmann <devteam.codafi@gmail.com <mailto:devteam.codafi@gmail.com>> wrote:

It’s mine, yep. It looks like it’s classifying the cast in the first pattern as a variable binding instead of an expression pattern. I’ll push a fix later.

Thanks!

On May 9, 2017, at 1:52 PM, Jordan Rose <jordan_rose@apple.com <mailto:jordan_rose@apple.com>> wrote:

That looks like a bug to me, since of course the first pattern won't always match. I suspect this is Robert's work on trying to make the exhaustive checks better, https://github.com/apple/swift/pull/8908. Thanks for catching this!

Jordan

On May 9, 2017, at 07:09, Pushkar N Kulkarni via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:

Hi there,

I see a new warning message for switch statements on enums, like this one:

enum Test {
    case one(Any)
    case two
}

let x: Test = .one("One")
switch x {
    case .one(let s as String): print(s)
    case .one: break
    case .two: break
}

enum.swift:9:10: warning: case is already handled by previous patterns; consider removing it
    case .one: break

I do not see this warning with the 04-24 dev snapshot.

The warning goes away with the use of the wildcard pattern in the second case:

switch x {
    case .one(let s as String): print(s)
    case .one(_): break
    case .two: break
}

I am wondering if this change is intentional, though it does make sense to me. Can someone please point me to the related commit?

Thanks in advance!

Pushkar N Kulkarni,
IBM Runtimes

Simplicity is prerequisite for reliability - Edsger W. Dijkstra

_______________________________________________
swift-dev mailing list
swift-dev@swift.org <mailto:swift-dev@swift.org>
https://lists.swift.org/mailman/listinfo/swift-dev


(Robert Widmann) #7

Right. I guess I should have asked: Are there any other kinds of patterns we consider exhaustive that have this structure?

~Robert Widmann

···

On May 9, 2017, at 2:23 PM, Jordan Rose <jordan_rose@apple.com> wrote:

"as NSError" isn't a tautology, though—the original type is 'Error'. Additionally, the presence or absence of a warning shouldn't affect exhaustiveness analysis, which is currently an error when you get it wrong. Warnings are things you can build with and fix later.

Jordan

On May 9, 2017, at 11:22, Robert Widmann <devteam.codafi@gmail.com <mailto:devteam.codafi@gmail.com>> wrote:

We’ll warn if that kind of cast is a tautology, right? That leaves only the dynamic casts, which can’t be assumed exhaustive.

~Robert Widmann

On May 9, 2017, at 2:13 PM, Jordan Rose <jordan_rose@apple.com <mailto:jordan_rose@apple.com>> wrote:

It's neither a variable binding nor an expression pattern, right? It has to be compared against the original type to know whether it's exhaustive or not. (Consider "let error as NSError" in a catch clause, which should be considered exhaustive.)

Jordan

On May 9, 2017, at 11:12, Robert Widmann <devteam.codafi@gmail.com <mailto:devteam.codafi@gmail.com>> wrote:

It’s mine, yep. It looks like it’s classifying the cast in the first pattern as a variable binding instead of an expression pattern. I’ll push a fix later.

Thanks!

On May 9, 2017, at 1:52 PM, Jordan Rose <jordan_rose@apple.com <mailto:jordan_rose@apple.com>> wrote:

That looks like a bug to me, since of course the first pattern won't always match. I suspect this is Robert's work on trying to make the exhaustive checks better, https://github.com/apple/swift/pull/8908. Thanks for catching this!

Jordan

On May 9, 2017, at 07:09, Pushkar N Kulkarni via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:

Hi there,

I see a new warning message for switch statements on enums, like this one:

enum Test {
    case one(Any)
    case two
}

let x: Test = .one("One")
switch x {
    case .one(let s as String): print(s)
    case .one: break
    case .two: break
}

enum.swift:9:10: warning: case is already handled by previous patterns; consider removing it
    case .one: break

I do not see this warning with the 04-24 dev snapshot.

The warning goes away with the use of the wildcard pattern in the second case:

switch x {
    case .one(let s as String): print(s)
    case .one(_): break
    case .two: break
}

I am wondering if this change is intentional, though it does make sense to me. Can someone please point me to the related commit?

Thanks in advance!

Pushkar N Kulkarni,
IBM Runtimes

Simplicity is prerequisite for reliability - Edsger W. Dijkstra

_______________________________________________
swift-dev mailing list
swift-dev@swift.org <mailto:swift-dev@swift.org>
https://lists.swift.org/mailman/listinfo/swift-dev


(Jordan Rose) #8

I think any bridging conversion or upcast would count.

enum Foo {
  case foo(NSFileManager)
  case bar(NSString)
  case baz(Int)
}
func test(x: Foo) {
  switch x {
  case .foo(let obj as NSObject):
    print("totally legal")
  case .bar(let obj as String):
    print("also cool")
  case .baz(let obj as Any):
    print("I'm not sure why, but sure")
  }
}

Jordan

···

On May 9, 2017, at 11:29, Robert Widmann <devteam.codafi@gmail.com> wrote:

Right. I guess I should have asked: Are there any other kinds of patterns we consider exhaustive that have this structure?

~Robert Widmann

On May 9, 2017, at 2:23 PM, Jordan Rose <jordan_rose@apple.com <mailto:jordan_rose@apple.com>> wrote:

"as NSError" isn't a tautology, though—the original type is 'Error'. Additionally, the presence or absence of a warning shouldn't affect exhaustiveness analysis, which is currently an error when you get it wrong. Warnings are things you can build with and fix later.

Jordan

On May 9, 2017, at 11:22, Robert Widmann <devteam.codafi@gmail.com <mailto:devteam.codafi@gmail.com>> wrote:

We’ll warn if that kind of cast is a tautology, right? That leaves only the dynamic casts, which can’t be assumed exhaustive.

~Robert Widmann

On May 9, 2017, at 2:13 PM, Jordan Rose <jordan_rose@apple.com <mailto:jordan_rose@apple.com>> wrote:

It's neither a variable binding nor an expression pattern, right? It has to be compared against the original type to know whether it's exhaustive or not. (Consider "let error as NSError" in a catch clause, which should be considered exhaustive.)

Jordan

On May 9, 2017, at 11:12, Robert Widmann <devteam.codafi@gmail.com <mailto:devteam.codafi@gmail.com>> wrote:

It’s mine, yep. It looks like it’s classifying the cast in the first pattern as a variable binding instead of an expression pattern. I’ll push a fix later.

Thanks!

On May 9, 2017, at 1:52 PM, Jordan Rose <jordan_rose@apple.com <mailto:jordan_rose@apple.com>> wrote:

That looks like a bug to me, since of course the first pattern won't always match. I suspect this is Robert's work on trying to make the exhaustive checks better, https://github.com/apple/swift/pull/8908. Thanks for catching this!

Jordan

On May 9, 2017, at 07:09, Pushkar N Kulkarni via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:

Hi there,

I see a new warning message for switch statements on enums, like this one:

enum Test {
    case one(Any)
    case two
}

let x: Test = .one("One")
switch x {
    case .one(let s as String): print(s)
    case .one: break
    case .two: break
}

enum.swift:9:10: warning: case is already handled by previous patterns; consider removing it
    case .one: break

I do not see this warning with the 04-24 dev snapshot.

The warning goes away with the use of the wildcard pattern in the second case:

switch x {
    case .one(let s as String): print(s)
    case .one(_): break
    case .two: break
}

I am wondering if this change is intentional, though it does make sense to me. Can someone please point me to the related commit?

Thanks in advance!

Pushkar N Kulkarni,
IBM Runtimes

Simplicity is prerequisite for reliability - Edsger W. Dijkstra

_______________________________________________
swift-dev mailing list
swift-dev@swift.org <mailto:swift-dev@swift.org>
https://lists.swift.org/mailman/listinfo/swift-dev


(Robert Widmann) #9

Is there a catch-all to query for such casts (sorry, I'm away from my computer at the moment).

~Robert Widmann

2017/05/09 16:40、Jordan Rose <jordan_rose@apple.com> のメッセージ:

···

I think any bridging conversion or upcast would count.

enum Foo {
  case foo(NSFileManager)
  case bar(NSString)
  case baz(Int)
}
func test(x: Foo) {
  switch x {
  case .foo(let obj as NSObject):
    print("totally legal")
  case .bar(let obj as String):
    print("also cool")
  case .baz(let obj as Any):
    print("I'm not sure why, but sure")
  }
}

Jordan

On May 9, 2017, at 11:29, Robert Widmann <devteam.codafi@gmail.com> wrote:

Right. I guess I should have asked: Are there any other kinds of patterns we consider exhaustive that have this structure?

~Robert Widmann

On May 9, 2017, at 2:23 PM, Jordan Rose <jordan_rose@apple.com> wrote:

"as NSError" isn't a tautology, though—the original type is 'Error'. Additionally, the presence or absence of a warning shouldn't affect exhaustiveness analysis, which is currently an error when you get it wrong. Warnings are things you can build with and fix later.

Jordan

On May 9, 2017, at 11:22, Robert Widmann <devteam.codafi@gmail.com> wrote:

We’ll warn if that kind of cast is a tautology, right? That leaves only the dynamic casts, which can’t be assumed exhaustive.

~Robert Widmann

On May 9, 2017, at 2:13 PM, Jordan Rose <jordan_rose@apple.com> wrote:

It's neither a variable binding nor an expression pattern, right? It has to be compared against the original type to know whether it's exhaustive or not. (Consider "let error as NSError" in a catch clause, which should be considered exhaustive.)

Jordan

On May 9, 2017, at 11:12, Robert Widmann <devteam.codafi@gmail.com> wrote:

It’s mine, yep. It looks like it’s classifying the cast in the first pattern as a variable binding instead of an expression pattern. I’ll push a fix later.

Thanks!

On May 9, 2017, at 1:52 PM, Jordan Rose <jordan_rose@apple.com> wrote:

That looks like a bug to me, since of course the first pattern won't always match. I suspect this is Robert's work on trying to make the exhaustive checks better, https://github.com/apple/swift/pull/8908. Thanks for catching this!

Jordan

On May 9, 2017, at 07:09, Pushkar N Kulkarni via swift-dev <swift-dev@swift.org> wrote:

Hi there,

I see a new warning message for switch statements on enums, like this one:

enum Test {
    case one(Any)
    case two
}

let x: Test = .one("One")
switch x {
    case .one(let s as String): print(s)
    case .one: break
    case .two: break
}

enum.swift:9:10: warning: case is already handled by previous patterns; consider removing it
    case .one: break

I do not see this warning with the 04-24 dev snapshot.

The warning goes away with the use of the wildcard pattern in the second case:

switch x {
    case .one(let s as String): print(s)
    case .one(_): break
    case .two: break
}

I am wondering if this change is intentional, though it does make sense to me. Can someone please point me to the related commit?

Thanks in advance!

Pushkar N Kulkarni,
IBM Runtimes

Simplicity is prerequisite for reliability - Edsger W. Dijkstra

_______________________________________________
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev


(Jordan Rose) #10

I think they'll all be IsPatterns, which means you can look at the CheckedCastKind.

Jordan

···

On May 9, 2017, at 13:54, Robert Widmann <devteam.codafi@gmail.com> wrote:

Is there a catch-all to query for such casts (sorry, I'm away from my computer at the moment).

~Robert Widmann

2017/05/09 16:40、Jordan Rose <jordan_rose@apple.com <mailto:jordan_rose@apple.com>> のメッセージ:

I think any bridging conversion or upcast would count.

enum Foo {
  case foo(NSFileManager)
  case bar(NSString)
  case baz(Int)
}
func test(x: Foo) {
  switch x {
  case .foo(let obj as NSObject):
    print("totally legal")
  case .bar(let obj as String):
    print("also cool")
  case .baz(let obj as Any):
    print("I'm not sure why, but sure")
  }
}

Jordan

On May 9, 2017, at 11:29, Robert Widmann <devteam.codafi@gmail.com <mailto:devteam.codafi@gmail.com>> wrote:

Right. I guess I should have asked: Are there any other kinds of patterns we consider exhaustive that have this structure?

~Robert Widmann

On May 9, 2017, at 2:23 PM, Jordan Rose <jordan_rose@apple.com <mailto:jordan_rose@apple.com>> wrote:

"as NSError" isn't a tautology, though—the original type is 'Error'. Additionally, the presence or absence of a warning shouldn't affect exhaustiveness analysis, which is currently an error when you get it wrong. Warnings are things you can build with and fix later.

Jordan

On May 9, 2017, at 11:22, Robert Widmann <devteam.codafi@gmail.com <mailto:devteam.codafi@gmail.com>> wrote:

We’ll warn if that kind of cast is a tautology, right? That leaves only the dynamic casts, which can’t be assumed exhaustive.

~Robert Widmann

On May 9, 2017, at 2:13 PM, Jordan Rose <jordan_rose@apple.com <mailto:jordan_rose@apple.com>> wrote:

It's neither a variable binding nor an expression pattern, right? It has to be compared against the original type to know whether it's exhaustive or not. (Consider "let error as NSError" in a catch clause, which should be considered exhaustive.)

Jordan

On May 9, 2017, at 11:12, Robert Widmann <devteam.codafi@gmail.com <mailto:devteam.codafi@gmail.com>> wrote:

It’s mine, yep. It looks like it’s classifying the cast in the first pattern as a variable binding instead of an expression pattern. I’ll push a fix later.

Thanks!

On May 9, 2017, at 1:52 PM, Jordan Rose <jordan_rose@apple.com <mailto:jordan_rose@apple.com>> wrote:

That looks like a bug to me, since of course the first pattern won't always match. I suspect this is Robert's work on trying to make the exhaustive checks better, https://github.com/apple/swift/pull/8908. Thanks for catching this!

Jordan

On May 9, 2017, at 07:09, Pushkar N Kulkarni via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:

Hi there,

I see a new warning message for switch statements on enums, like this one:

enum Test {
    case one(Any)
    case two
}

let x: Test = .one("One")
switch x {
    case .one(let s as String): print(s)
    case .one: break
    case .two: break
}

enum.swift:9:10: warning: case is already handled by previous patterns; consider removing it
    case .one: break

I do not see this warning with the 04-24 dev snapshot.

The warning goes away with the use of the wildcard pattern in the second case:

switch x {
    case .one(let s as String): print(s)
    case .one(_): break
    case .two: break
}

I am wondering if this change is intentional, though it does make sense to me. Can someone please point me to the related commit?

Thanks in advance!

Pushkar N Kulkarni,
IBM Runtimes

Simplicity is prerequisite for reliability - Edsger W. Dijkstra

_______________________________________________
swift-dev mailing list
swift-dev@swift.org <mailto:swift-dev@swift.org>
https://lists.swift.org/mailman/listinfo/swift-dev