// RUN: %target-typecheck-verify-swift -enable-experimental-property-behaviors -module-name Main // REQUIRES: property_behavior_value_substitution protocol behavior { associatedtype Value } extension behavior { var value: Value { fatalError("") } } struct NotABehavior {} var test1: Int __behavior behavior var test2: String __behavior Main.behavior // expected-error@+1{{property behavior name must refer to a protocol}} var test5: String __behavior NotABehavior struct Concrete { var test: String __behavior behavior static var test: String __behavior behavior } protocol Proto { } extension Proto { var test: String __behavior behavior static var test: String __behavior behavior } struct Generic { var test: String __behavior behavior static var test: String __behavior behavior } protocol SelfRequirement {} protocol ValueRequirement {} protocol constraints: SelfRequirement { associatedtype Value: ValueRequirement } extension constraints { var value: Value { fatalError("") } } struct VR: ValueRequirement {} struct GVR: ValueRequirement {} struct NVR {} // expected-error@+3{{property behavior 'constraints' can only be used on instance properties because it has 'Self' requirements}} // expected-error@+2{{type 'NVR' does not conform to protocol 'ValueRequirement'}} // expected-note@+1{{behavior 'constraints' requires property type to conform to protocol 'ValueRequirement'}} var a: NVR __behavior constraints // expected-error@+1{{property behavior 'constraints' can only be used on instance properties because it has 'Self' requirements}} var b: VR __behavior constraints struct SR: SelfRequirement { // expected-error@+2{{type 'NVR' does not conform to protocol 'ValueRequirement'}} // expected-note@+1{{behavior 'constraints' requires property type to conform to protocol 'ValueRequirement'}} var a: NVR __behavior constraints var b: VR __behavior constraints // expected-error@+3{{property behavior 'constraints' can only be used on instance properties because it has 'Self' requirements}} // expected-error@+2{{type 'NVR' does not conform to protocol 'ValueRequirement'}} // expected-note@+1{{behavior 'constraints' requires property type to conform to protocol 'ValueRequirement'}} static var a: NVR __behavior constraints // expected-error@+1{{property behavior 'constraints' can only be used on instance properties because it has 'Self' requirements}} static var b: VR __behavior constraints } // expected-error@+1 * {{type 'NSR' does not conform to protocol 'SelfRequirement'}} struct NSR { // expected-note@+3{{conformance to 'SelfRequirement' required to contain an instance property with behavior 'constraints'}} // expected-error@+2{{type 'NVR' does not conform to protocol 'ValueRequirement'}} // expected-note@+1{{behavior 'constraints' requires property type to conform to protocol 'ValueRequirement'}} var a: NVR __behavior constraints // expected-note@+1{{conformance to 'SelfRequirement' required to contain an instance property with behavior 'constraints'}} var b: VR __behavior constraints } struct GSR: SelfRequirement { var a: VR __behavior constraints var b: GVR __behavior constraints } extension GSR where T: ValueRequirement { var c: T __behavior constraints } protocol nonBehaviorReqt { associatedtype Value func notBehaviorRelated() // expected-note{{declared here}} } extension nonBehaviorReqt { var value: Value { fatalError("") } } // expected-error@+1{{behavior protocol 'nonBehaviorReqt' has non-behavior requirement 'notBehaviorRelated'}} var x: Int __behavior nonBehaviorReqt protocol hasStorage { associatedtype Value var storage: Value? { get set } } extension hasStorage { static func initStorage() -> Value? { return nil } // Overloads that should be disregarded static func initStorage() -> Value { fatalError("") } static func initStorage(_: String) -> Value? { fatalError("") } var value: Value { fatalError("") } } var tuple = (0,0) var storage1: Int __behavior hasStorage // expected-error {{not supported}} struct Foo { static var staticStorage1: T __behavior hasStorage // expected-error{{static stored properties not supported in generic types}} var storage2: T __behavior hasStorage // FIXME: Hack because we can't find the synthesized associated type witness // during witness matching. typealias Value = T func foo(_: U) { var storage1: T __behavior hasStorage // expected-error {{not supported}} var storage2: U __behavior hasStorage // expected-error {{not supported}} _ = storage1 _ = storage2 } } struct Foo2 { var storage3: Int = 0 // expected-error {{initializer expression provided, but property behavior 'hasStorage' does not use it}} __behavior hasStorage var (storage4, storage5) = tuple // expected-error* {{initializer expression provided, but property behavior 'hasStorage' does not use it}} __behavior hasStorage // FIXME: Hack because we can't find the synthesized associated type witness // during witness matching. typealias Value = Int } extension Foo { static var y: T __behavior hasStorage // expected-error{{static stored properties not supported in generic types}} var y: T __behavior hasStorage // expected-error {{extensions may not contain stored properties}} } protocol storageWithoutInit { associatedtype Value var storage: Value { get set } } extension storageWithoutInit { var value: Value { fatalError("") } func initStorage() -> Int { fatalError("signature is wrong") } // expected-note * {{found this candidate}} } struct Bar { var x: Int __behavior storageWithoutInit // expected-error {{property behavior protocol has a 'storage' requirement but does not have a static 'initStorage' method with the expected type '() -> Self.Value'}} } class Bas { var x: Int __behavior storageWithoutInit // expected-error {{property behavior protocol has a 'storage' requirement but does not have a static 'initStorage' method with the expected type '() -> Self.Value'}} } protocol valueTypeMismatch { associatedtype Value } extension valueTypeMismatch { var value: Value? { fatalError("") } // expected-note {{'value' property declared here}} } var x: Int __behavior valueTypeMismatch // expected-error {{property behavior 'valueTypeMismatch' provides 'value' property implementation with type 'Int?' that doesn't match type 'x' of declared property 'Int'}} protocol getset { associatedtype Value } extension getset { var value: Value { get { } set { } } } var testGetset: Int __behavior getset class C { var testGetset: T __behavior getset static var testGetset: T __behavior getset } struct S { var testGetset: T __behavior getset static var testGetset: T __behavior getset } protocol parameterized { associatedtype Value func parameter() -> Value } extension parameterized { var value: Value { get { } set { } } } struct TestParameters { var hasParameter: Int __behavior parameterized { 0 } var (sharedParameter1, sharedParameter2): (Int,Int) __behavior parameterized { 0 } // expected-error {{multiple variables is not supported}} expected-error{{sharedParameter2}} var missingParameter: Int __behavior parameterized // expected-error{{requires a parameter}} var invalidParameter: Int __behavior parameterized { 5.5 } // expected-error{{cannot convert return expression of type 'Double' to return type 'Int'}} } // TODO var globalParameter: Int __behavior parameterized { 0 } // expected-error{{not supported}} protocol noParameter { associatedtype Value } extension noParameter { var value: Value { get { } set { } } } var hasNoParameter: Int __behavior noParameter var hasUnwantedParameter: Int __behavior noParameter { 0 } // expected-error{{parameter expression provided, but property behavior 'noParameter' does not use it}} protocol storageWithInitialValue { associatedtype Value var storage: Value? { get set } } extension storageWithInitialValue { var value: Value { get { } } static func initStorage(_ x: Value) -> Value? { return nil } } struct TestStorageWithInitialValue { var x: Int __behavior storageWithInitialValue // Would require DI var y = 0 __behavior storageWithInitialValue var z: Int = 5.5 __behavior storageWithInitialValue // expected-error {{cannot convert value of type 'Double' to type 'Int' in coercion}} var (a, b) = tuple __behavior storageWithInitialValue // expected-error* {{do not support destructuring}} // FIXME: Hack because we can't find the synthesized associated type witness // during witness matching. typealias Value = Int }