mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Updates the message to use the type or ValueDecl instead of this on previous 'Found this candidate' messages Note: doees not yet change all test cases so more tests are failing Improve Diagnostic message on overload ambiguitiy Remove messages that say 'found this candidate' in favour of providing the type for the candidate to aid in selection when the candidates are presented in a dialogue window. Fix more tests
844 lines
24 KiB
Swift
844 lines
24 KiB
Swift
// RUN: %target-typecheck-verify-swift
|
|
|
|
// Leaf expression patterns are matched to corresponding pieces of a switch
|
|
// subject (TODO: or ~= expression) using ~= overload resolution.
|
|
switch (1, 2.5, "three") {
|
|
case (1, _, _):
|
|
()
|
|
// Double is ExpressibleByIntegerLiteral
|
|
case (_, 2, _),
|
|
(_, 2.5, _),
|
|
(_, _, "three"):
|
|
()
|
|
// ~= overloaded for (Range<Int>, Int)
|
|
case (0..<10, _, _),
|
|
(0..<10, 2.5, "three"),
|
|
(0...9, _, _),
|
|
(0...9, 2.5, "three"):
|
|
()
|
|
default:
|
|
()
|
|
}
|
|
|
|
switch (1, 2) {
|
|
case (var a, a): // expected-error {{cannot find 'a' in scope}}
|
|
()
|
|
}
|
|
|
|
// 'is' patterns can perform the same checks that 'is' expressions do.
|
|
|
|
protocol P { func p() }
|
|
|
|
class B : P {
|
|
init() {}
|
|
func p() {}
|
|
func b() {}
|
|
}
|
|
class D : B {
|
|
override init() { super.init() }
|
|
func d() {}
|
|
}
|
|
class E {
|
|
init() {}
|
|
func e() {}
|
|
}
|
|
|
|
struct S : P {
|
|
func p() {}
|
|
func s() {}
|
|
}
|
|
|
|
// Existential-to-concrete.
|
|
var bp : P = B()
|
|
switch bp {
|
|
case is B,
|
|
is D,
|
|
is S:
|
|
()
|
|
case is E:
|
|
()
|
|
default:
|
|
()
|
|
}
|
|
|
|
switch bp {
|
|
case let b as B:
|
|
b.b()
|
|
case let d as D:
|
|
d.b()
|
|
d.d()
|
|
case let s as S:
|
|
s.s()
|
|
case let e as E:
|
|
e.e()
|
|
default:
|
|
()
|
|
}
|
|
|
|
// Super-to-subclass.
|
|
var db : B = D()
|
|
switch db {
|
|
case is D:
|
|
()
|
|
case is E: // expected-warning {{always fails}}
|
|
()
|
|
default:
|
|
()
|
|
}
|
|
|
|
// Raise an error if pattern productions are used in expressions.
|
|
var b = var x // expected-error{{expected initial value after '='}} expected-error {{type annotation missing in pattern}} expected-error {{consecutive statements on a line must be separated by ';'}} {{8-8=;}}
|
|
var c = is Int // expected-error{{expected initial value after '='}} expected-error {{expected expression}} expected-error {{consecutive statements on a line must be separated by ';'}} {{8-8=;}}
|
|
|
|
// TODO: Bad recovery in these cases. Although patterns are never valid
|
|
// expr-unary productions, it would be good to parse them anyway for recovery.
|
|
//var e = 2 + var y
|
|
//var e = var y + 2
|
|
|
|
// 'E.Case' can be used in a dynamic type context as an equivalent to
|
|
// '.Case as E'.
|
|
protocol HairType {}
|
|
enum MacbookHair: HairType {
|
|
case HairSupply(S)
|
|
}
|
|
|
|
enum iPadHair<T>: HairType {
|
|
case HairForceOne
|
|
}
|
|
|
|
enum Watch {
|
|
case Sport, Watch, Edition
|
|
}
|
|
|
|
let hair: HairType = MacbookHair.HairSupply(S())
|
|
switch hair {
|
|
case MacbookHair.HairSupply(let s):
|
|
s.s()
|
|
case iPadHair<S>.HairForceOne:
|
|
()
|
|
case iPadHair<E>.HairForceOne:
|
|
()
|
|
case iPadHair.HairForceOne: // expected-error{{generic enum type 'iPadHair' is ambiguous without explicit generic parameters when matching value of type 'any HairType'}}
|
|
()
|
|
case Watch.Edition: // expected-error {{pattern of type 'Watch' cannot match 'any HairType'}}
|
|
()
|
|
case .HairForceOne: // expected-error{{type 'any HairType' has no member 'HairForceOne'}}
|
|
()
|
|
default:
|
|
break
|
|
}
|
|
|
|
|
|
// <rdar://problem/19382878> Introduce new x? pattern
|
|
switch Optional(42) {
|
|
case let x?: break // expected-warning{{immutable value 'x' was never used; consider replacing with '_' or removing it}} {{10-11=_}}
|
|
case nil: break
|
|
}
|
|
|
|
// https://github.com/apple/swift/issues/44675
|
|
func f_44675(x: Int?) {
|
|
// nil literals should still work when wrapped in parentheses
|
|
switch x {
|
|
case (nil): break
|
|
case _?: break
|
|
}
|
|
switch x {
|
|
case ((nil)): break
|
|
case _?: break
|
|
}
|
|
switch (x, x) {
|
|
case ((nil), _): break
|
|
case (_?, _): break
|
|
}
|
|
}
|
|
|
|
// Test x???? patterns.
|
|
switch (nil as Int???) {
|
|
case let x???: print(x, terminator: "")
|
|
case let x??: print(x as Any, terminator: "")
|
|
case let x?: print(x as Any, terminator: "")
|
|
case 4???: break
|
|
case nil??: break // expected-warning {{case is already handled by previous patterns; consider removing it}}
|
|
case nil?: break // expected-warning {{case is already handled by previous patterns; consider removing it}}
|
|
default: break
|
|
}
|
|
|
|
switch ("foo" as String?) {
|
|
case "what": break
|
|
default: break
|
|
}
|
|
|
|
|
|
// Test some value patterns.
|
|
let x : Int?
|
|
|
|
extension Int {
|
|
func method() -> Int { return 42 }
|
|
}
|
|
|
|
func ~= <T : Equatable>(lhs: T?, rhs: T?) -> Bool {
|
|
return lhs == rhs
|
|
}
|
|
|
|
switch 4 as Int? {
|
|
case x?.method(): break // match value
|
|
default: break
|
|
}
|
|
|
|
switch 4 {
|
|
case x ?? 42: break // match value
|
|
default: break
|
|
}
|
|
|
|
for (var x) in 0...100 {} // expected-warning{{variable 'x' was never used; consider replacing with '_' or removing it}}
|
|
for var x in 0...100 {} // rdar://20167543 expected-warning{{variable 'x' was never used; consider replacing with '_' or removing it}}
|
|
for (let x) in 0...100 { _ = x} // expected-error {{'let' pattern cannot appear nested in an already immutable context}}
|
|
|
|
var (let y) = 42 // expected-error {{'let' cannot appear nested inside another 'var' or 'let' pattern}}
|
|
let (var z) = 42 // expected-error {{'var' cannot appear nested inside another 'var' or 'let' pattern}}
|
|
|
|
|
|
// Crash when re-typechecking EnumElementPattern.
|
|
// FIXME: This should actually type-check -- the diagnostics are bogus. But
|
|
// at least we don't crash anymore.
|
|
|
|
protocol PP {
|
|
associatedtype E
|
|
}
|
|
|
|
struct A<T> : PP {
|
|
typealias E = T
|
|
}
|
|
|
|
extension PP {
|
|
func map<T>(_ f: (Self.E) -> T) -> T {}
|
|
}
|
|
|
|
enum EE {
|
|
case A
|
|
case B
|
|
}
|
|
|
|
func good(_ a: A<EE>) -> Int {
|
|
return a.map {
|
|
switch $0 {
|
|
case .A:
|
|
return 1
|
|
default:
|
|
return 2
|
|
}
|
|
}
|
|
}
|
|
|
|
func bad(_ a: A<EE>) {
|
|
let _ = a.map {
|
|
let _: EE = $0
|
|
return 1
|
|
}
|
|
}
|
|
|
|
func ugly(_ a: A<EE>) {
|
|
let _ = a.map {
|
|
switch $0 {
|
|
case .A:
|
|
return 1
|
|
default:
|
|
return 2
|
|
}
|
|
}
|
|
}
|
|
|
|
// https://github.com/apple/swift/issues/44666
|
|
do {
|
|
enum E {
|
|
case foo
|
|
}
|
|
|
|
let x: E?
|
|
if case .foo = x { } // Ok
|
|
}
|
|
|
|
// Invalid 'is' pattern
|
|
class SomeClass {}
|
|
if case let doesNotExist as SomeClass:AlsoDoesNotExist {}
|
|
// expected-error@-1 {{cannot find type 'AlsoDoesNotExist' in scope}}
|
|
// expected-error@-2 {{variable binding in a condition requires an initializer}}
|
|
|
|
// `.foo` and `.bar(...)` pattern syntax should also be able to match
|
|
// static members as expr patterns
|
|
|
|
struct StaticMembers: Equatable {
|
|
init() {}
|
|
init(_: Int) {}
|
|
init?(opt: Int) {}
|
|
static var prop = StaticMembers()
|
|
static var optProp: Optional = StaticMembers()
|
|
|
|
static func method(_: Int) -> StaticMembers { return prop }
|
|
static func method(withLabel: Int) -> StaticMembers { return prop }
|
|
static func optMethod(_: Int) -> StaticMembers? { return optProp }
|
|
|
|
static func ==(x: StaticMembers, y: StaticMembers) -> Bool { return true }
|
|
}
|
|
|
|
let staticMembers = StaticMembers()
|
|
let optStaticMembers: Optional = StaticMembers()
|
|
|
|
switch staticMembers {
|
|
case .init: break // expected-error{{member 'init(opt:)' expects argument of type 'Int'}}
|
|
case .init(opt:): break // expected-error{{member 'init(opt:)' expects argument of type 'Int'}}
|
|
case .init(): break
|
|
|
|
case .init(0): break
|
|
case .init(_): break // expected-error{{'_' can only appear in a pattern}}
|
|
case .init(let x): break // expected-error{{cannot appear in an expression}}
|
|
case .init(opt: 0): break // expected-error{{value of optional type 'StaticMembers?' must be unwrapped to a value of type 'StaticMembers'}}
|
|
// expected-note@-1 {{force-unwrap using '!' to abort execution if the optional value contains 'nil'}}
|
|
// expected-note@-2 {{coalesce using '??' to provide a default when the optional value contains 'nil'}}
|
|
|
|
case .prop: break
|
|
case .optProp: break
|
|
|
|
case .method: break // expected-error{{member 'method' expects argument of type 'Int'}}
|
|
case .method(0): break
|
|
case .method(_): break // expected-error{{'_' can only appear in a pattern}}
|
|
case .method(let x): break // expected-error{{cannot appear in an expression}}
|
|
|
|
case .method(withLabel:): break // expected-error{{member 'method(withLabel:)' expects argument of type 'Int'}}
|
|
case .method(withLabel: 0): break
|
|
case .method(withLabel: _): break // expected-error{{'_' can only appear in a pattern}}
|
|
case .method(withLabel: let x): break // expected-error{{cannot appear in an expression}}
|
|
|
|
case .optMethod: break // expected-error{{member 'optMethod' expects argument of type 'Int'}}
|
|
case .optMethod(0): break
|
|
}
|
|
|
|
_ = 0
|
|
|
|
// rdar://problem/32241441 - Add fix-it for cases in switch with optional chaining
|
|
|
|
struct S_32241441 {
|
|
enum E_32241441 {
|
|
case foo
|
|
case bar
|
|
}
|
|
|
|
var type: E_32241441 = E_32241441.foo
|
|
}
|
|
|
|
func rdar32241441() {
|
|
let s: S_32241441? = S_32241441()
|
|
|
|
switch s?.type { // expected-error {{switch must be exhaustive}} expected-note {{add missing case: '.none'}}
|
|
case .foo: // Ok
|
|
break;
|
|
case .bar: // Ok
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
// https://github.com/apple/swift/issues/48655
|
|
|
|
struct One<Two> { // expected-note{{'Two' declared as parameter to type 'One'}}
|
|
public enum E: Error {
|
|
// if you remove associated value, everything works
|
|
case SomeError(String)
|
|
}
|
|
}
|
|
|
|
enum HomeworkError: Error {
|
|
case dogAteIt
|
|
case forgot
|
|
}
|
|
|
|
func testOne() {
|
|
do {
|
|
} catch let error { // expected-warning{{'catch' block is unreachable because no errors are thrown in 'do' block}}
|
|
if case One.E.SomeError = error {} // expected-error{{generic parameter 'Two' could not be inferred}}
|
|
}
|
|
do {
|
|
} catch HomeworkError.forgot { // expected-warning{{'catch' block is unreachable because no errors are thrown in 'do' block}}
|
|
} catch {
|
|
}
|
|
}
|
|
|
|
// https://github.com/apple/swift/issues/50875
|
|
// Constrain initializer expressions of optional some pattern bindings to
|
|
// be optional.
|
|
func test_50875() -> String {
|
|
struct C {
|
|
subscript (s: String) -> String? {
|
|
return ""
|
|
}
|
|
subscript (s: String) -> [String] {
|
|
return [""]
|
|
}
|
|
|
|
func f() -> String? {
|
|
return ""
|
|
}
|
|
func f() -> Int {
|
|
return 3
|
|
}
|
|
|
|
func g() -> String {
|
|
return ""
|
|
}
|
|
|
|
func h() -> String {
|
|
return ""
|
|
}
|
|
func h() -> Double {
|
|
return 3.0
|
|
}
|
|
func h() -> Int? { //expected-note{{found candidate with type '() -> Int?'}}
|
|
return 2
|
|
}
|
|
func h() -> Float? { //expected-note{{found candidate with type '() -> Float?'}}
|
|
return nil
|
|
}
|
|
|
|
}
|
|
|
|
let c = C()
|
|
if let s = c[""] {
|
|
return s
|
|
}
|
|
if let s = c.f() {
|
|
return s
|
|
}
|
|
if let s = c.g() { //expected-error{{initializer for conditional binding must have Optional type, not 'String'}}
|
|
return s
|
|
}
|
|
if let s = c.h() { //expected-error{{ambiguous use of 'h()'}}
|
|
return s
|
|
}
|
|
}
|
|
|
|
// https://github.com/apple/swift/issues/50338
|
|
do {
|
|
enum E {
|
|
case baz
|
|
case bar
|
|
|
|
static var member: Self {
|
|
.baz
|
|
}
|
|
|
|
static func method() -> Self {
|
|
.bar
|
|
}
|
|
|
|
static func methodArg(_: Void) -> Self {
|
|
.baz
|
|
}
|
|
|
|
static var none: Self {
|
|
.baz
|
|
}
|
|
}
|
|
|
|
let oe: E? = .bar
|
|
|
|
switch oe {
|
|
case .bar?: break // Ok
|
|
case .baz: break // Ok
|
|
case .member: break // Ok
|
|
case .missingMember: break // expected-error {{type 'E?' has no member 'missingMember'}}
|
|
case .method(): break // Ok
|
|
case .methodArg(()): break // Ok
|
|
case .none: break // expected-warning {{assuming you mean 'Optional<E>.none'; did you mean 'E.none' instead?}} expected-note {{use 'nil' to silence this warning}} expected-note {{use 'none?' instead}}
|
|
default: break
|
|
}
|
|
|
|
let ooe: E?? = .baz
|
|
|
|
switch ooe {
|
|
case .bar?: break // Ok
|
|
case .baz: break // Ok
|
|
case .member: break // Ok
|
|
case .missingMember: break // expected-error {{type 'E??' has no member 'missingMember'}}
|
|
case .method(): break // Ok
|
|
case .methodArg(()): break // Ok
|
|
default: break
|
|
}
|
|
|
|
if case .baz = ooe {} // Ok
|
|
if case .bar? = ooe {} // Ok
|
|
if case .member = ooe {} // Ok
|
|
if case .missingMember = ooe {} // expected-error {{type 'E??' has no member 'missingMember'}}
|
|
if case .method() = ooe {} // Ok
|
|
if case .methodArg(()) = ooe {} // Ok
|
|
|
|
enum M {
|
|
case m
|
|
static func `none`(_: Void) -> Self { .m }
|
|
}
|
|
|
|
let om: M? = .m
|
|
|
|
switch om {
|
|
case .none: break // Ok
|
|
default: break
|
|
}
|
|
}
|
|
|
|
// rdar://problem/60048356 - `if case` fails when `_` pattern doesn't have a label
|
|
func rdar_60048356() {
|
|
typealias Info = (code: ErrorCode, reason: String)
|
|
|
|
enum ErrorCode {
|
|
case normalClosure
|
|
}
|
|
|
|
enum Failure {
|
|
case closed(Info) // expected-note {{'closed' declared here}}
|
|
}
|
|
|
|
enum Reason {
|
|
case close(Failure)
|
|
}
|
|
|
|
func test(_ reason: Reason) {
|
|
if case .close(.closed((code: .normalClosure, _))) = reason { // Ok
|
|
}
|
|
}
|
|
|
|
// rdar://problem/60061646
|
|
func test(e: Failure) {
|
|
if case .closed(code: .normalClosure, _) = e { // Ok
|
|
// expected-warning@-1 {{enum case 'closed' has one associated value that is a tuple of 2 elements}}
|
|
}
|
|
}
|
|
|
|
enum E {
|
|
case foo((x: Int, y: Int)) // expected-note {{declared here}}
|
|
case bar(x: Int, y: Int) // expected-note {{declared here}}
|
|
}
|
|
|
|
func test_destructing(e: E) {
|
|
if case .foo(let x, let y) = e { // Ok (destructring)
|
|
// expected-warning@-1 {{enum case 'foo' has one associated value that is a tuple of 2 elements}}
|
|
_ = x == y
|
|
}
|
|
if case .bar(let tuple) = e { // Ok (matching via tuple)
|
|
// expected-warning@-1 {{enum case 'bar' has 2 associated values; matching them as a tuple is deprecated}}
|
|
_ = tuple.0 == tuple.1
|
|
}
|
|
}
|
|
}
|
|
|
|
// rdar://problem/63510989 - valid pattern doesn't type-check
|
|
func rdar63510989() {
|
|
enum Value : P {
|
|
func p() {}
|
|
}
|
|
|
|
enum E {
|
|
case single(P?)
|
|
case double(P??)
|
|
case triple(P???)
|
|
}
|
|
|
|
func test(e: E) {
|
|
if case .single(_) = e {} // Ok
|
|
if case .single(_ as Value) = e {} // Ok
|
|
if case .single(let v as Value) = e {} // Ok
|
|
// expected-warning@-1 {{immutable value 'v' was never used; consider replacing with '_' or removing it}}
|
|
if case .double(_ as Value) = e {} // Ok
|
|
if case .double(let v as Value) = e {} // Ok
|
|
// expected-warning@-1 {{immutable value 'v' was never used; consider replacing with '_' or removing it}}
|
|
if case .double(let v as Value?) = e {} // Ok
|
|
// expected-warning@-1 {{immutable value 'v' was never used; consider replacing with '_' or removing it}}
|
|
if case .triple(_ as Value) = e {} // Ok
|
|
if case .triple(let v as Value) = e {} // Ok
|
|
// expected-warning@-1 {{immutable value 'v' was never used; consider replacing with '_' or removing it}}
|
|
if case .triple(let v as Value?) = e {} // Ok
|
|
// expected-warning@-1 {{immutable value 'v' was never used; consider replacing with '_' or removing it}}
|
|
if case .triple(let v as Value??) = e {} // Ok
|
|
// expected-warning@-1 {{immutable value 'v' was never used; consider replacing with '_' or removing it}}
|
|
}
|
|
}
|
|
|
|
// rdar://problem/64157451 - compiler crash when using undefined type in pattern
|
|
func rdar64157451() {
|
|
enum E {
|
|
case foo(Int)
|
|
}
|
|
|
|
func test(e: E) {
|
|
if case .foo(let v as DoeNotExist) = e {} // expected-error {{cannot find type 'DoeNotExist' in scope}}
|
|
}
|
|
}
|
|
|
|
// rdar://80797176 - circular reference incorrectly diagnosed while reaching for a type of a pattern.
|
|
func rdar80797176 () {
|
|
for x: Int in [1, 2] where x.bitWidth == 32 { // Ok
|
|
}
|
|
}
|
|
|
|
// https://github.com/apple/swift/issues/60029
|
|
for (key, values) in oldName { // expected-error{{cannot find 'oldName' in scope}}
|
|
for (idx, value) in values.enumerated() {
|
|
print(key, idx, value)
|
|
}
|
|
}
|
|
|
|
// https://github.com/apple/swift/issues/60503
|
|
func f60503() {
|
|
let (key, _) = settings.enumerate() // expected-error{{cannot find 'settings' in scope}}
|
|
let (_, _) = settings.enumerate() // expected-error{{cannot find 'settings' in scope}}
|
|
}
|
|
|
|
// rdar://105089074
|
|
enum EWithIdent<Id> where Id: P {
|
|
case test(Id)
|
|
}
|
|
|
|
extension [EWithIdent<Int>] { // expected-error {{type 'Int' does not conform to protocol 'P'}}
|
|
func test() {
|
|
sorted { lhs, rhs in
|
|
switch (rhs, rhs) {
|
|
case let (.test(x), .test(y)): break
|
|
// expected-error@-1 2 {{type 'Element' has no member 'test'}}
|
|
case (_, _): break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
struct TestIUOMatchOp {
|
|
static func ~= (lhs: TestIUOMatchOp, rhs: TestIUOMatchOp) -> Bool! { nil }
|
|
func foo() {
|
|
if case self = self {}
|
|
}
|
|
}
|
|
|
|
struct TestRecursiveVarRef<T> {
|
|
lazy var e: () -> Int = {e}()
|
|
}
|
|
|
|
func testMultiStmtClosureExprPattern(_ x: Int) {
|
|
if case { (); return x }() = x {}
|
|
}
|
|
|
|
func testExprPatternIsolation() {
|
|
// We type-check ExprPatterns separately, so these are illegal.
|
|
if case 0 = nil {} // expected-error {{'nil' requires a contextual type}}
|
|
let _ = {
|
|
if case 0 = nil {} // expected-error {{'nil' requires a contextual type}}
|
|
}
|
|
for case 0 in nil {} // expected-error {{'nil' requires a contextual type}}
|
|
for case 0 in [nil] {}
|
|
// expected-error@-1 {{type 'Any' cannot conform to 'Equatable'}}
|
|
// expected-note@-2 {{only concrete types such as structs, enums and classes can conform to protocols}}
|
|
// expected-note@-3 {{requirement from conditional conformance of 'Any?' to 'Equatable'}}
|
|
|
|
// Though we will try Double for an integer literal...
|
|
let d: Double = 0
|
|
if case d = 0 {}
|
|
let _ = {
|
|
if case d = 0 {}
|
|
}
|
|
for case d in [0] {}
|
|
|
|
// But not Float
|
|
let f: Float = 0
|
|
if case f = 0 {} // expected-error {{expression pattern of type 'Float' cannot match values of type 'Int'}}
|
|
let _ = {
|
|
if case f = 0 {} // expected-error {{expression pattern of type 'Float' cannot match values of type 'Int'}}
|
|
}
|
|
for case f in [0] {} // expected-error {{expression pattern of type 'Float' cannot match values of type 'Int'}}
|
|
|
|
enum MultiPayload<T: Equatable>: Equatable {
|
|
case e(T, T)
|
|
static func f(_ x: T, _ y: T) -> Self { .e(x, y) }
|
|
}
|
|
enum E: Equatable {
|
|
case a, b
|
|
static var c: E { .a }
|
|
static var d: E { .b }
|
|
}
|
|
|
|
func produceMultiPayload<T>() -> MultiPayload<T> { fatalError() }
|
|
|
|
// We type-check ExprPatterns left to right, so only one of these works.
|
|
if case .e(0.0, 0) = produceMultiPayload() {}
|
|
if case .e(0, 0.0) = produceMultiPayload() {} // expected-error {{expression pattern of type 'Double' cannot match values of type 'Int'}}
|
|
|
|
for case .e(0.0, 0) in [produceMultiPayload()] {}
|
|
for case .e(0, 0.0) in [produceMultiPayload()] {} // expected-error {{expression pattern of type 'Double' cannot match values of type 'Int'}}
|
|
|
|
// Same, because although it's a top-level ExprPattern, we don't resolve
|
|
// that until during solving.
|
|
if case .f(0.0, 0) = produceMultiPayload() {}
|
|
if case .f(0, 0.0) = produceMultiPayload() {} // expected-error {{expression pattern of type 'Double' cannot match values of type 'Int'}}
|
|
|
|
if case .e(5, nil) = produceMultiPayload() {} // expected-warning {{type 'Int' is not optional, value can never be nil; this is an error in the Swift 6 language mode}}
|
|
|
|
// FIXME: Bad error (https://github.com/apple/swift/issues/64279)
|
|
if case .e(nil, 0) = produceMultiPayload() {}
|
|
// expected-error@-1 {{expression pattern of type 'String' cannot match values of type 'Substring'}}
|
|
// expected-note@-2 {{overloads for '~=' exist with these partially matching parameter lists}}
|
|
|
|
if case .e(5, nil) = produceMultiPayload() as MultiPayload<Int?> {}
|
|
if case .e(nil, 0) = produceMultiPayload() as MultiPayload<Int?> {}
|
|
|
|
// Enum patterns are solved together.
|
|
if case .e(E.a, .b) = produceMultiPayload() {}
|
|
if case .e(.a, E.b) = produceMultiPayload() {}
|
|
|
|
// These also work because they start life as EnumPatterns.
|
|
if case .e(E.c, .d) = produceMultiPayload() {}
|
|
if case .e(.c, E.d) = produceMultiPayload() {}
|
|
for case .e(E.c, .d) in [produceMultiPayload()] {}
|
|
for case .e(.c, E.d) in [produceMultiPayload()] {}
|
|
|
|
// Silly, but allowed.
|
|
if case 0: Int? = 0 {} // expected-warning {{non-optional expression of type 'Int' used in a check for optionals}}
|
|
|
|
var opt: Int?
|
|
if case opt = 0 {}
|
|
}
|
|
|
|
enum LotsOfOptional {
|
|
case yup(Int?, Int?, Int?, Int?, Int?, Int?, Int?, Int?, Int?, Int?, Int?, Int?, Int?, Int?, Int?)
|
|
}
|
|
func testLotsOfNil(_ x: LotsOfOptional) {
|
|
if case .yup(nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil) = x {}
|
|
}
|
|
|
|
// https://github.com/apple/swift/issues/66752
|
|
// FIXME: We ought to improve the diagnostics here
|
|
func issue66752(_ x: Result<String, Error>) {
|
|
let _ = {
|
|
if case .failure() = x {}
|
|
// expected-error@-1 {{type '()' cannot conform to 'Error}}
|
|
// expected-note@-2 {{only concrete types such as structs, enums and classes can conform to protocols}}
|
|
// expected-note@-3 {{required by generic enum 'Result' where 'Failure' = '()'}}
|
|
}
|
|
let _ = {
|
|
if case (.failure(), let y) = (x, 0) {}
|
|
// expected-error@-1 {{type '()' cannot conform to 'Error}}
|
|
// expected-note@-2 {{only concrete types such as structs, enums and classes can conform to protocols}}
|
|
// expected-note@-3 {{required by generic enum 'Result' where 'Failure' = '()'}}
|
|
}
|
|
if case .failure() = x {}
|
|
// expected-error@-1 {{type '()' cannot conform to 'Error}}
|
|
// expected-note@-2 {{only concrete types such as structs, enums and classes can conform to protocols}}
|
|
// expected-note@-3 {{required by generic enum 'Result' where 'Failure' = '()'}}
|
|
|
|
if case (.failure(), let y) = (x, 0) {}
|
|
// expected-error@-1 {{type '()' cannot conform to 'Error}}
|
|
// expected-note@-2 {{only concrete types such as structs, enums and classes can conform to protocols}}
|
|
// expected-note@-3 {{required by generic enum 'Result' where 'Failure' = '()'}}
|
|
}
|
|
|
|
// https://github.com/apple/swift/issues/66750
|
|
// FIXME: We ought to improve the diagnostics here
|
|
func issue66750(_ x: Result<String, Error>) {
|
|
let _ = {
|
|
switch x {
|
|
case .success:
|
|
"a"
|
|
case .failure():
|
|
// expected-error@-1 {{type '()' cannot conform to 'Error}}
|
|
// expected-note@-2 {{only concrete types such as structs, enums and classes can conform to protocols}}
|
|
// expected-note@-3 {{required by generic enum 'Result' where 'Failure' = '()'}}
|
|
"b"
|
|
}
|
|
}
|
|
let _ = {
|
|
switch (x, 0) {
|
|
case (.success, let y):
|
|
"a"
|
|
case (.failure(), let y):
|
|
// expected-error@-1 {{type '()' cannot conform to 'Error}}
|
|
// expected-note@-2 {{only concrete types such as structs, enums and classes can conform to protocols}}
|
|
// expected-note@-3 {{required by generic enum 'Result' where 'Failure' = '()'}}
|
|
"b"
|
|
}
|
|
}
|
|
switch x {
|
|
case .success:
|
|
break
|
|
case .failure(): // expected-error {{tuple pattern cannot match values of the non-tuple type 'any Error'}}
|
|
break
|
|
}
|
|
switch (x, 0) {
|
|
case (.success, let y):
|
|
break
|
|
case (.failure(), let y):
|
|
// expected-error@-1 {{tuple pattern cannot match values of the non-tuple type 'any Error'}}
|
|
break
|
|
}
|
|
}
|
|
|
|
// rdar://123466496 - `type of expression is ambiguous without a type annotation` with extra elements
|
|
do {
|
|
enum E {
|
|
case test(a: Int, b: String)
|
|
}
|
|
|
|
func test(_: (E) -> Void) {
|
|
}
|
|
|
|
test {
|
|
switch $0 {
|
|
case .test(a: 42, b: "", c: 0.0): break
|
|
// expected-error@-1 {{tuple pattern has the wrong length for tuple type '(Int, String)'}}
|
|
}
|
|
}
|
|
}
|
|
|
|
func testMatchingNonErrorConformingTypeInClosure(_ x: any Error) {
|
|
enum E {
|
|
case e
|
|
}
|
|
_ = {
|
|
switch x {
|
|
case E.e: // expected-error {{pattern of type 'E' does not conform to expected match type 'Error'}}
|
|
break
|
|
default:
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
// rdar://131819800 - crash in `transformWithPosition` while trying to emit diagnostics for `AllowFunctionTypeMismatch` fix
|
|
do {
|
|
enum E {
|
|
case test(kind: Int, defaultsToEmpty: Bool = false)
|
|
}
|
|
|
|
func test(e: E) {
|
|
if case .test(kind: _, // expected-error {{tuple pattern has the wrong length for tuple type '(Int, Bool)'}}
|
|
name: let name?,
|
|
defaultsToEmpty: _,
|
|
deprecateName: let deprecatedName?) = e {
|
|
}
|
|
}
|
|
}
|
|
|
|
// Make sure we diagnose 'Undefined' here.
|
|
func testUndefinedTypeInPattern(_ x: Int) {
|
|
switch x {
|
|
case Optional<Undefined>.alsoUndefined: // expected-error {{cannot find type 'Undefined' in scope}}
|
|
break
|
|
}
|
|
_ = {
|
|
switch x {
|
|
case Optional<Undefined>.alsoUndefined: // expected-error {{cannot find type 'Undefined' in scope}}
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
func testUndefinedInClosureVar() {
|
|
// Make sure we don't produce "unable to infer closure type without a type annotation"
|
|
_ = {
|
|
var x: Undefined // expected-error {{cannot find type 'Undefined' in scope}}
|
|
}
|
|
}
|