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-12229] Assertion failure when trying to pattern match enum cases with same base name #54655

Open
jckarter opened this issue Feb 18, 2020 · 2 comments
Labels

Comments

@jckarter
Copy link
Member

jckarter commented Feb 18, 2020

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:

  • SR-14638 ☂️ Full support for overloaded enum cases (SE-0155)

is blocked by:

  • SR-12764 Pattern matching forces arbitrary label

duplicates:

  • SR-12746 Assertion failure when type-checking patterns with ambiguous cases

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
Copy link
Member

hborla commented Feb 21, 2020

@swift-ci create

@Gotyanov
Copy link

Gotyanov commented Sep 26, 2020

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?!"

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants