swiftlang / swift

The Swift Programming Language
https://swift.org
Apache License 2.0
67.57k stars 10.36k forks source link

[SR-12229] Assertion failure when trying to pattern match enum cases with same base name #54655

Open jckarter opened 4 years ago

jckarter commented 4 years ago
Previous ID SR-12229
Radar rdar://problem/59655509
Original Reporter @jckarter
Type Sub-task
Additional Detail from JIRA | | | |------------------|-----------------| |Votes | 2 | |Component/s | Compiler | |Labels | Sub-task | |Assignee | None | |Priority | Medium | md5: 350d59c094ebd69b46ed0ffb8988f306

Parent-Task:

is blocked by:

duplicates:

Issue Description:

This crashes the compiler in an assertions-enabled build:

enum Foo {
  case foo(bar: Int)
  case foo(bas: Int)
  case bar
}

func switchFoo(x: Foo) {
  switch x {
  case .foo(bar: let bar):
    print("foo bar \(bar)")
  case .foo(bas: let bas):
    print("foo bas \(bas)")
  case .bar:
    print("bar")
  }
}

switchFoo(x: .foo(bar: 1))
switchFoo(x: .foo(bas: 1))
switchFoo(x: .bar)
Assertion failed: (!foundElement && "ambiguity in enum case name lookup?!"), function filterForEnumElement, file /Users/jgroff/swift/public/swift/lib/Sema/TypeCheckPattern.cpp, line 98.
Stack dump:
0.  Program arguments: /Users/jgroff/swift/public/build/Ninja-RelWithDebInfoAssert/swift-macosx-x86_64/bin/swift -frontend -c -primary-file /Users/jgroff/foo.swift -target x86_64-apple-darwin19.0.0 -enable-objc-interop -color-diagnostics -module-name foo -o /var/folders/t7/glhhlkys4272r_9964jlvp4c0000gn/T/foo-09ac98.o 
1.  Swift version 5.2-dev (LLVM 9505d8980c, Swift 1403e75a0e)
2.  While evaluating request TypeCheckSourceFileRequest(source_file "/Users/jgroff/foo.swift")
3.  While evaluating request TypeCheckFunctionBodyUntilRequest(foo.(file).switchFoo(x:)@/Users/jgroff/foo.swift:7:6, )
4.  While type-checking statement at [/Users/jgroff/foo.swift:7:24 - line:16:1] RangeText="{
  switch x {
  case .foo(bar: let bar):
    print("foo bar \(bar)")
  case .foo(bas: let bas):
    print("foo bas \(bas)")
  case .bar:
    print("bar")
  }
"
5.  While type-checking statement at [/Users/jgroff/foo.swift:8:3 - line:15:3] RangeText="switch x {
  case .foo(bar: let bar):
    print("foo bar \(bar)")
  case .foo(bas: let bas):
    print("foo bas \(bas)")
  case .bar:
    print("bar")
  "

Without assertions enabled, it emits a bogus diagnostic:

/Users/jgroff/foo.swift:9:13: error: tuple pattern element label 'bar' must be 'bas'
  case .foo(bar: let bar):
            ^

The same assertion trips if you try to match only on pattern binding name:

enum Foo {
  case foo(bar: Int)
  case foo(bas: Int)
  case bar
}

func switchFoo(x: Foo) {
  switch x {
  case .foo(let bar):
    print("foo bar \(bar)")
  case .foo(let bas):
    print("foo bas \(bas)")
  case .bar:
    print("bar")
  }
}

switchFoo(x: .foo(bar: 1))
switchFoo(x: .foo(bas: 1))
switchFoo(x: .bar)

or if the cases differ in arity, not only in label names:

enum Foo {
  case foo(bar: Int)
  case foo(bar: Int, bas: Int)
  case bar
}

func switchFoo(x: Foo) {
  switch x {
  case .foo(let bar):
    print("foo bar \(bar)")
  case .foo(let butt):
    print("foo bar \(bar)")
  case .foo(bar: let bar):
    print("foo bas \(bar)")
  case .bar:
    print("bar")
  }
}

switchFoo(x: .foo(bar: 1))
switchFoo(x: .bar)
hborla commented 4 years ago

@swift-ci create

Gotyanov commented 4 years ago

If to use optional associated values and matching to nil without label there will not be warnings or errors, but result will be unpredictable for programmer:

enum Enum {
    case value(b: Bool?)
    case value(s: String?)
}

func check(_ e: Enum) {
    switch e {
    case .value(nil):
        print("\(e): associated value is nil")

    default:
        print("\(e): associated value is not nil")
    }
}

check(.value(s: nil)) // printed: value(s: nil):  associated value is nil
check(.value(b: nil)) // printed: value(b: nil): associated value is not nil

Tested in XCode 12.0.1 with default keychain. For development snapshot 2020-09-23 will be assertion failure "ambiguity in enum case name lookup?!"