Files
swift-mirror/test/Sema/enum_equatable_hashable.swift
Chris Lattner b5500b8600 Generalize the conditions in which we'll accept an ambiguous solution to
a constraint system in "allowFreeTypeVariables" mode.  Previously, we
only allowed a few specific constraints, now we allow any relational and
member constraints.  The later one is a big deal because it means that we
can allow ".Foo" expressions as ambiguous solutions, which CSDiags can
handle well.

This unblocks solving 23942743 and enables some minor improvements across
the board, including diagnosing things like this better:
  Optional(.none)  // now: generic parameter 'T' could not be inferred

That said, it also just permutes some non-awesome diagnostics.
2016-01-11 17:04:46 -08:00

127 lines
3.1 KiB
Swift

// RUN: rm -rf %t && mkdir -p %t
// RUN: cp %s %t/main.swift
// RUN: %target-swift-frontend -parse -verify -primary-file %t/main.swift %S/Inputs/enum_equatable_hashable_other.swift
enum Foo {
case A, B
}
if Foo.A == .B { }
var aHash: Int = Foo.A.hashValue
enum Generic<T> {
case A, B
func method() -> Int {
if A == B { }
return A.hashValue
}
}
if Generic<Foo>.A == .B { }
var gaHash: Int = Generic<Foo>.A.hashValue
func localEnum() -> Bool {
enum Local {
case A, B
}
return Local.A == .B
}
enum CustomHashable {
case A, B
var hashValue: Int { return 0 }
}
func ==(x: CustomHashable, y: CustomHashable) -> Bool { // expected-note{{non-matching type}}
return true
}
if CustomHashable.A == .B { }
var custHash: Int = CustomHashable.A.hashValue
// We still synthesize conforming overloads of '==' and 'hashValue' if
// explicit definitions don't satisfy the protocol requirements. Probably
// not what we actually want.
enum InvalidCustomHashable {
case A, B
var hashValue: String { return "" } // expected-note{{previously declared here}}
}
func ==(x: InvalidCustomHashable, y: InvalidCustomHashable) -> String { // expected-note{{non-matching type}}
return ""
}
if InvalidCustomHashable.A == .B { }
var s: String = InvalidCustomHashable.A == .B
s = InvalidCustomHashable.A.hashValue
var i: Int = InvalidCustomHashable.A.hashValue
// Check use of an enum's synthesized members before the enum is actually declared.
struct UseEnumBeforeDeclaration {
let eqValue = EnumToUseBeforeDeclaration.A == .A
let hashValue = EnumToUseBeforeDeclaration.A.hashValue
}
enum EnumToUseBeforeDeclaration {
case A
}
// Check enums from another file in the same module.
if FromOtherFile.A == .A {}
let _: Int = FromOtherFile.A.hashValue
func getFromOtherFile() -> AlsoFromOtherFile { return .A }
if .A == getFromOtherFile() {}
// FIXME: This should work.
func overloadFromOtherFile() -> YetAnotherFromOtherFile { return .A }
func overloadFromOtherFile() -> Bool { return false }
if .A == overloadFromOtherFile() {}
// Complex enums are not implicitly Equatable or Hashable.
enum Complex {
case A(Int)
case B
}
if Complex.A(1) == .B { } // expected-error{{binary operator '==' cannot be applied to operands of type 'Complex' and '_'}}
// expected-note @-1 {{overloads for '==' exist with these partially matching parameter lists: }}
// rdar://19773050
private enum Bar<T> {
case E(Unknown<T>) // expected-error {{use of undeclared type 'Unknown'}}
mutating func value() -> T {
switch self {
case E(let x): // expected-error{{invalid pattern}}
return x.value
}
}
}
// Equatable extension -- rdar://20981254
enum Instrument {
case Piano
case Violin
case Guitar
}
extension Instrument : Equatable {}
// Explicit conformance should work too
public enum Medicine {
case Antibiotic
case Antihistamine
}
extension Medicine : Equatable {}
public func ==(lhs: Medicine, rhs: Medicine) -> Bool { // expected-note{{non-matching type}}
return true
}
// No explicit conformance and cannot be derived
extension Complex : Hashable {} // expected-error 2 {{does not conform}}