mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
These are tests that fail in the next commit without this flag. This does not add -verify-ignore-unrelated to all tests with -verify, only the ones that would fail without it. This is NFC since this flag is currently a no-op.
326 lines
12 KiB
Swift
326 lines
12 KiB
Swift
// RUN: %target-typecheck-verify-swift -verify-ignore-unrelated
|
|
|
|
enum Foo : Int {
|
|
case a, b, c
|
|
}
|
|
|
|
var raw1: Int = Foo.a.rawValue
|
|
var raw2: Foo.RawValue = raw1
|
|
var cooked1: Foo? = Foo(rawValue: 0)
|
|
var cooked2: Foo? = Foo(rawValue: 22)
|
|
|
|
enum Bar : Double {
|
|
case a, b, c
|
|
}
|
|
|
|
func localEnum() -> Int {
|
|
enum LocalEnum : Int {
|
|
case a, b, c
|
|
}
|
|
return LocalEnum.a.rawValue
|
|
}
|
|
|
|
enum MembersReferenceRawType : Int {
|
|
case a, b, c
|
|
|
|
init?(rawValue: Int) {
|
|
self = MembersReferenceRawType(rawValue: rawValue)!
|
|
}
|
|
|
|
func successor() -> MembersReferenceRawType {
|
|
return MembersReferenceRawType(rawValue: rawValue + 1)!
|
|
}
|
|
}
|
|
|
|
func serialize<T : RawRepresentable>(_ values: [T]) -> [T.RawValue] {
|
|
return values.map { $0.rawValue }
|
|
}
|
|
|
|
func deserialize<T : RawRepresentable>(_ serialized: [T.RawValue]) -> [T] {
|
|
return serialized.map { T(rawValue: $0)! }
|
|
}
|
|
|
|
var ints: [Int] = serialize([Foo.a, .b, .c])
|
|
var doubles: [Double] = serialize([Bar.a, .b, .c])
|
|
|
|
var foos: [Foo] = deserialize([1, 2, 3])
|
|
var bars: [Bar] = deserialize([1.2, 3.4, 5.6])
|
|
|
|
// We reject enums where the raw type stated in the inheritance clause does not
|
|
// match the types of the witnesses.
|
|
enum Color : Int {
|
|
case red
|
|
case blue
|
|
|
|
init?(rawValue: Double) {
|
|
return nil
|
|
}
|
|
|
|
var rawValue: Double { // expected-note {{found this candidate}}
|
|
return 1.0
|
|
}
|
|
}
|
|
|
|
func useRawValue(of color: Color) {
|
|
_ = color.rawValue
|
|
// expected-error@-1 {{ambiguous use of 'rawValue'}}
|
|
}
|
|
|
|
var colorRaw: Color.RawValue = 7.5
|
|
// expected-error@-1 {{cannot convert value of type 'Double' to specified type 'Color.RawValue' (aka 'Int')}}
|
|
|
|
// Mismatched case types
|
|
|
|
enum BadPlain : UInt { // expected-error {{'BadPlain' declares raw type 'UInt', but does not conform to RawRepresentable and conformance could not be synthesized}} expected-note {{add stubs for conformance}}
|
|
case a = "hello" // expected-error {{cannot convert value of type 'String' to raw type 'UInt'}}
|
|
}
|
|
|
|
// Recursive diagnostics issue in tryRawRepresentableFixIts()
|
|
class Outer {
|
|
// The setup is that we have to trigger the conformance check
|
|
// while diagnosing the conversion here. For the purposes of
|
|
// the test I'm putting everything inside a class in the right
|
|
// order, but the problem can trigger with a multi-file
|
|
// scenario too.
|
|
let a: Int = E.a // expected-error {{cannot convert value of type 'Outer.E' to specified type 'Int'}}
|
|
|
|
enum E : Array<Int> {
|
|
// expected-error@-1 {{raw type 'Array<Int>' is not expressible by a string, integer, or floating-point literal}}
|
|
// expected-error@-2 {{'Outer.E' declares raw type 'Array<Int>', but does not conform to RawRepresentable and conformance could not be synthesized}}
|
|
// expected-note@-3 {{add stubs for conformance}}
|
|
case a
|
|
}
|
|
}
|
|
|
|
// rdar://problem/32431736 - Conversion fix-it from String to String raw value enum can't look through optionals
|
|
|
|
func rdar32431736() {
|
|
enum E : String {
|
|
case A = "A"
|
|
case B = "B"
|
|
}
|
|
|
|
let items1: [String] = ["A", "a"]
|
|
let items2: [String]? = ["A"]
|
|
|
|
let myE1: E = items1.first
|
|
// expected-error@-1 {{cannot convert value of type 'String?' to specified type 'E'}}
|
|
// expected-note@-2 {{construct 'E' from unwrapped 'String' value}} {{17-17=E(rawValue: }} {{29-29=!) ?? <#default value#>}}
|
|
|
|
let myE2: E = items2?.first
|
|
// expected-error@-1 {{cannot convert value of type 'String?' to specified type 'E'}}
|
|
// expected-note@-2 {{construct 'E' from unwrapped 'String' value}} {{17-17=E(rawValue: (}} {{30-30=)!) ?? <#default value#>}}
|
|
}
|
|
|
|
// rdar://problem/32431165 - improve diagnostic for raw representable argument mismatch
|
|
|
|
enum E_32431165 : String {
|
|
case foo = "foo"
|
|
case bar = "bar" // expected-note {{'bar' declared here}}
|
|
}
|
|
|
|
func rdar32431165_1(_: E_32431165) {}
|
|
func rdar32431165_1(_: Int) {}
|
|
func rdar32431165_1(_: Int, _: E_32431165) {}
|
|
|
|
rdar32431165_1(E_32431165.baz)
|
|
// expected-error@-1 {{type 'E_32431165' has no member 'baz'; did you mean 'bar'?}}
|
|
|
|
rdar32431165_1(.baz)
|
|
// expected-error@-1 {{reference to member 'baz' cannot be resolved without a contextual type}}
|
|
|
|
rdar32431165_1("")
|
|
// expected-error@-1 {{cannot convert value of type 'String' to expected argument type 'E_32431165'}}
|
|
rdar32431165_1(42, "")
|
|
// expected-error@-1 {{cannot convert value of type 'String' to expected argument type 'E_32431165'}} {{20-20=E_32431165(rawValue: }} {{22-22=) ?? <#default value#>}}
|
|
|
|
func rdar32431165_2(_: String) {}
|
|
func rdar32431165_2(_: Int) {}
|
|
func rdar32431165_2(_: Int, _: String) {}
|
|
|
|
rdar32431165_2(E_32431165.bar)
|
|
// expected-error@-1 {{cannot convert value of type 'E_32431165' to expected argument type 'String'}} {{30-30=.rawValue}}
|
|
rdar32431165_2(42, E_32431165.bar)
|
|
// expected-error@-1 {{cannot convert value of type 'E_32431165' to expected argument type 'String'}} {{34-34=.rawValue}}
|
|
|
|
// TODO: In following two examples it's possible to fix a problem by either using `.rawValue` on first argument
|
|
// or constructing raw representable type from second, both ways are valid.
|
|
do {
|
|
E_32431165.bar == "bar"
|
|
// expected-error@-1 {{cannot convert value of type 'E_32431165' to expected argument type 'String'}} {{17-17=.rawValue}}
|
|
|
|
"bar" == E_32431165.bar
|
|
// expected-error@-1 {{cannot convert value of type 'E_32431165' to expected argument type 'String'}} {{26-26=.rawValue}}
|
|
}
|
|
|
|
func rdar32431165_overloaded() -> Int { 42 } // expected-note {{'rdar32431165_overloaded()' produces 'Int', not the expected contextual result type 'E_32431165'}}
|
|
func rdar32431165_overloaded() -> String { "A" } // expected-note {{'rdar32431165_overloaded()' produces 'String', not the expected contextual result type 'E_32431165'}}
|
|
|
|
func test_candidate_diagnostic() {
|
|
func test_argument(_: E_32431165) {}
|
|
|
|
let _: E_32431165 = rdar32431165_overloaded() // expected-error {{no 'rdar32431165_overloaded' candidates produce the expected contextual result type 'E_32431165'}}
|
|
test_argument(rdar32431165_overloaded()) // expected-error {{cannot convert value of type 'String' to expected argument type 'E_32431165'}} {{17-17=E_32431165(rawValue: }} {{42-42=) ?? <#default value#>}}
|
|
}
|
|
|
|
func rdar32432253(_ condition: Bool = false) {
|
|
let choice: E_32431165 = condition ? .foo : .bar
|
|
let _ = choice == "bar"
|
|
// expected-error@-1 {{cannot convert value of type 'E_32431165' to expected argument type 'String'}} {{17-17=.rawValue}}
|
|
}
|
|
|
|
// https://github.com/apple/swift/issues/50682
|
|
do {
|
|
func helper1(_: Int) {}
|
|
func helper1(_: Double) {}
|
|
|
|
func helper2(_: Double) {}
|
|
func helper2(_: Int) {}
|
|
|
|
func helper3(_: Foo) {}
|
|
func helper3(_: Bar) {}
|
|
|
|
func helper4(_: Bar) {}
|
|
func helper4(_: Foo) {}
|
|
|
|
do {
|
|
let bar: Bar
|
|
|
|
helper1(bar)
|
|
// expected-error@-1 {{cannot convert value of type 'Bar' to expected argument type 'Double'}} {{16-16=.rawValue}}
|
|
helper2(bar)
|
|
// expected-error@-1 {{cannot convert value of type 'Bar' to expected argument type 'Double'}} {{16-16=.rawValue}}
|
|
helper3(0.0)
|
|
// expected-error@-1 {{cannot convert value of type 'Double' to expected argument type 'Bar'}} {{13-13=Bar(rawValue: }} {{16-16=) ?? <#default value#>}}
|
|
helper4(0.0)
|
|
// expected-error@-1 {{cannot convert value of type 'Double' to expected argument type 'Bar'}} {{13-13=Bar(rawValue: }} {{16-16=) ?? <#default value#>}}
|
|
}
|
|
|
|
// Bonus problem with mutable values being passed.
|
|
do {
|
|
class Box {
|
|
var bar: Bar
|
|
init(bar: Bar) {}
|
|
}
|
|
|
|
let box: Box
|
|
|
|
helper1(box.bar)
|
|
// expected-error@-1 {{cannot convert value of type 'Bar' to expected argument type 'Double'}} {{20-20=.rawValue}}
|
|
|
|
var bar = box.bar
|
|
helper1(bar)
|
|
// expected-error@-1 {{cannot convert value of type 'Bar' to expected argument type 'Double'}} {{16-16=.rawValue}}
|
|
}
|
|
|
|
do {
|
|
let opt: Bar?
|
|
|
|
helper1(opt)
|
|
// expected-error@-1 {{cannot convert value of type 'Bar?' to expected argument type 'Double'}} {{16-16=?.rawValue ?? <#default value#>}}
|
|
helper1(opt ?? Bar.a)
|
|
// expected-error@-1 {{cannot convert value of type 'Bar' to expected argument type 'Double'}} {{13-13=(}} {{25-25=).rawValue}}
|
|
let _: Double? = opt
|
|
// expected-error@-1 {{cannot convert value of type 'Bar?' to specified type 'Double?'}} {{25-25=?.rawValue}}
|
|
}
|
|
}
|
|
|
|
struct NotEquatable { }
|
|
|
|
enum ArrayOfNewEquatable : Array<NotEquatable> { }
|
|
// expected-error@-1{{raw type 'Array<NotEquatable>' is not expressible by a string, integer, or floating-point literal}}
|
|
// expected-error@-2{{'ArrayOfNewEquatable' declares raw type 'Array<NotEquatable>', but does not conform to RawRepresentable and conformance could not be synthesized}}
|
|
// expected-error@-3{{RawRepresentable conformance cannot be synthesized because raw type 'Array<NotEquatable>' is not Equatable}}
|
|
// expected-error@-4{{an enum with no cases cannot declare a raw type}}
|
|
// expected-note@-5 {{add stubs for conformance}}
|
|
|
|
// rdar://58127114
|
|
struct NotEquatableInteger : ExpressibleByIntegerLiteral {
|
|
typealias IntegerLiteralType = Int
|
|
|
|
init(integerLiteral: Int) {}
|
|
}
|
|
|
|
enum NotEquatableRawType1 : NotEquatableInteger {
|
|
// expected-error@-1 {{'NotEquatableRawType1' declares raw type 'NotEquatableInteger', but does not conform to RawRepresentable and conformance could not be synthesized}}
|
|
// expected-error@-2 {{RawRepresentable conformance cannot be synthesized because raw type 'NotEquatableInteger' is not Equatable}}
|
|
// expected-note@-3 {{add stubs for conformance}}
|
|
case a = 123
|
|
}
|
|
|
|
|
|
enum NotEquatableRawType2 : NotEquatableInteger {
|
|
// expected-error@-1 {{'NotEquatableRawType2' declares raw type 'NotEquatableInteger', but does not conform to RawRepresentable and conformance could not be synthesized}}
|
|
// expected-error@-2 {{RawRepresentable conformance cannot be synthesized because raw type 'NotEquatableInteger' is not Equatable}}
|
|
// expected-note@-3 {{add stubs for conformance}}
|
|
typealias RawValue = NotEquatableInteger
|
|
|
|
case a = 123
|
|
}
|
|
|
|
struct NotEquatableString : ExpressibleByStringLiteral {
|
|
init(stringLiteral: String) {}
|
|
}
|
|
|
|
// FIXME: This could be diagnosed a bit better. The notes are disembodied
|
|
enum NotEquatableRawType3: NotEquatableString {
|
|
// expected-error@-1 {{RawRepresentable conformance cannot be synthesized because raw type 'NotEquatableString' is not Equatable}}
|
|
// expected-error@-2 {{'NotEquatableRawType3' declares raw type 'NotEquatableString', but does not conform to RawRepresentable and conformance could not be synthesized}}
|
|
// expected-note@-3 {{add stubs for conformance}}
|
|
case a
|
|
typealias RawValue = NotEquatableString
|
|
init?(rawValue: Int) { self = .a }
|
|
// expected-note@-1 {{candidate has non-matching type '(rawValue: Int)'}}
|
|
var rawValue: Int { 0 }
|
|
// expected-note@-1 {{candidate has non-matching type 'Int'}}
|
|
}
|
|
|
|
enum MismatchedRawValues {
|
|
enum ExistentialBound: Any? {
|
|
// expected-error@-1 {{raw type 'Any?' is not expressible}}
|
|
// expected-error@-2 {{'MismatchedRawValues.ExistentialBound' declares raw type 'Any?'}}
|
|
// expected-error@-3 {{RawRepresentable conformance cannot be synthesized }}
|
|
// expected-note@-4 {{add stubs for conformance}}
|
|
case test = nil
|
|
}
|
|
|
|
public enum StringViaStaticString: StaticString {
|
|
// expected-error@-1 {{'MismatchedRawValues.StringViaStaticString' declares raw type 'StaticString', but does not conform to RawRepresentable}}
|
|
// expected-error@-2 {{RawRepresentable conformance cannot be synthesized because}}
|
|
// expected-note@-3 {{add stubs for conformance}}
|
|
public typealias RawValue = String
|
|
|
|
case TRUE = "TRUE"
|
|
case FALSE = "FALSE"
|
|
}
|
|
|
|
public enum IntViaString: String {
|
|
// expected-error@-1 {{'MismatchedRawValues.IntViaString' declares raw type 'String', but does not conform to RawRepresentable}}
|
|
// expected-note@-2 {{add stubs for conformance}}
|
|
public typealias RawValue = Int
|
|
|
|
case TRUE = "TRUE"
|
|
case FALSE = "FALSE"
|
|
}
|
|
|
|
public enum ViaNested: String {
|
|
// expected-error@-1 {{'MismatchedRawValues.ViaNested' declares raw type 'String', but does not conform to RawRepresentable}}
|
|
// expected-note@-2 {{add stubs for conformance}}
|
|
struct RawValue: Equatable {
|
|
let x: String
|
|
}
|
|
|
|
case TRUE = "TRUE"
|
|
case FALSE = "FALSE"
|
|
}
|
|
|
|
public enum ViaGenericBound<RawValue: Equatable>: String {
|
|
// expected-error@-1 {{'MismatchedRawValues.ViaGenericBound<RawValue>' declares raw type 'String', but does not conform to RawRepresentable}}
|
|
// expected-note@-2 {{add stubs for conformance}}
|
|
typealias RawValue = RawValue
|
|
case TRUE = "TRUE"
|
|
case FALSE = "FALSE"
|
|
}
|
|
}
|
|
|