// RUN: %target-typecheck-verify-swift -swift-version 5 -enable-objc-interop // ---------------------------------------------------------------------------- // DynamicSelf is only allowed on the return type of class and // protocol methods. func global() -> Self { } // expected-error{{global function cannot return 'Self'}} func inFunction() { func local() -> Self { } // expected-error{{local function cannot return 'Self'}} } struct S0 { func f() -> Self { } func g(_ ds: Self) { } } enum E0 { func f() -> Self { } func g(_ ds: Self) { } } class C0 { func f() -> Self { } // okay func g(_ ds: Self) { } // expected-error{{covariant 'Self' or 'Self?' can only appear as the type of a property, subscript or method result; did you mean 'C0'?}} func h(_ ds: Self) -> Self { } // expected-error{{covariant 'Self' or 'Self?' can only appear as the type of a property, subscript or method result; did you mean 'C0'?}} } protocol P0 { func f() -> Self // okay func g(_ ds: Self) // okay } extension P0 { func h() -> Self { // okay func g(_ t : Self) -> Self { // okay return t } return g(self) } } protocol P1: AnyObject { func f() -> Self // okay func g(_ ds: Self) // okay } extension P1 { func h() -> Self { // okay func g(_ t : Self) -> Self { // okay return t } return g(self) } } // ---------------------------------------------------------------------------- // The 'self' type of a Self method is based on Self class C1 { required init(int i: Int) {} // expected-note {{'init(int:)' declared here}} // Instance methods have a self of type Self. func f(_ b: Bool) -> Self { // FIXME: below diagnostic should complain about C1 -> Self conversion if b { return C1(int: 5) } // expected-error{{cannot convert return expression of type 'C1' to return type 'Self'}} // One can use `type(of:)` to attempt to construct an object of type Self. if !b { return type(of: self).init(int: 5) } // Can utter Self within the body of a method. var _: Self = self // Okay to return 'self', because it has the appropriate type. return self // okay } // Type methods have a self of type Self.Type. class func factory(_ b: Bool) -> Self { // Check directly. var x: Int = self // expected-error{{cannot convert value of type 'Self.Type' to specified type 'Int'}} // Can't utter Self within the body of a method. var c1 = C1(int: 5) as Self // expected-error{{'C1' is not convertible to 'Self'}} // expected-note@-1{{did you mean to use 'as!' to force downcast?}} {{25-27=as!}} if b { return self.init(int: 5) } return Self() // expected-error{{missing argument for parameter 'int' in call}} {{17-17=int: <#Int#>}} } // This used to crash because metatype construction went down a // different code path that didn't handle DynamicSelfType. class func badFactory() -> Self { return self(int: 0) // expected-error@-1 {{initializing from a metatype value must reference 'init' explicitly}} } } // ---------------------------------------------------------------------------- // Using a method with a Self result carries the receiver type. class X { func instance() -> Self { } class func factory() -> Self { } func produceX() -> X { } } class Y : X { func produceY() -> Y { } } func testInvokeInstanceMethodSelf() { // Trivial case: invoking on the declaring class. var x = X() var x2 = x.instance() x = x2 // at least an X x2 = x // no more than an X // Invoking on a subclass. var y = Y() var y2 = y.instance(); y = y2 // at least a Y y2 = y // no more than a Y } func testInvokeTypeMethodSelf() { // Trivial case: invoking on the declaring class. var x = X() var x2 = X.factory() x = x2 // at least an X x2 = x // no more than an X // Invoking on a subclass. var y = Y() var y2 = Y.factory() y = y2 // at least a Y y2 = y // no more than a Y } func testCurryInstanceMethodSelf() { // Trivial case: currying on the declaring class. var produceX = X.produceX var produceX2 = X.instance produceX = produceX2 produceX2 = produceX // Currying on a subclass. var produceY = Y.produceY var produceY2 = Y.instance produceY = produceY2 produceY2 = produceY } class GX { func instance() -> Self { } class func factory() -> Self { } func produceGX() -> GX { } } class GY : GX<[T]> { func produceGY() -> GY { } } func testInvokeInstanceMethodSelfGeneric() { // Trivial case: invoking on the declaring class. var x = GX() var x2 = x.instance() x = x2 // at least an GX x2 = x // no more than an GX // Invoking on a subclass. var y = GY() var y2 = y.instance(); y = y2 // at least a GY y2 = y // no more than a GY } func testInvokeTypeMethodSelfGeneric() { // Trivial case: invoking on the declaring class. var x = GX() var x2 = GX.factory() x = x2 // at least an GX x2 = x // no more than an GX // Invoking on a subclass. var y = GY() var y2 = GY.factory(); y = y2 // at least a GY y2 = y // no more than a GY } func testCurryInstanceMethodSelfGeneric() { // Trivial case: currying on the declaring class. var produceGX = GX.produceGX var produceGX2 = GX.instance produceGX = produceGX2 produceGX2 = produceGX // Currying on a subclass. var produceGY = GY.produceGY var produceGY2 = GY.instance produceGY = produceGY2 produceGY2 = produceGY } // ---------------------------------------------------------------------------- // Overriding a method with a Self class Z : Y { override func instance() -> Self { } override class func factory() -> Self { } } func testOverriddenMethodSelfGeneric() { var z = Z() var z2 = z.instance(); z = z2 z2 = z var z3 = Z.factory() z = z3 z3 = z } // ---------------------------------------------------------------------------- // Generic uses of Self methods. protocol P { func f() -> Self } func testGenericCall(_ t: T) { var t = t var t2 = t.f() t2 = t t = t2 } // ---------------------------------------------------------------------------- // Existential uses of Self methods. func testExistentialCall(_ p: P) { _ = p.f() } // ---------------------------------------------------------------------------- // Dynamic lookup of Self methods. @objc class SomeClass { @objc func method() -> Self { return self } } func testAnyObject(_ ao: AnyObject) { var ao = ao var result : AnyObject = ao.method!() result = ao ao = result } // ---------------------------------------------------------------------------- // Name lookup on Self values extension Y { func testInstance() -> Self { if false { return self.instance() } return instance() } class func testFactory() -> Self { if false { return self.factory() } return factory() } } // ---------------------------------------------------------------------------- // Optional Self returns extension X { func tryToClone() -> Self? { return nil } func tryHarderToClone() -> Self! { return nil } func cloneOrFail() -> Self { return self } func cloneAsObjectSlice() -> X? { return self } } extension Y { func operationThatOnlyExistsOnY() {} } func testOptionalSelf(_ y : Y) { if let clone = y.tryToClone() { clone.operationThatOnlyExistsOnY() } // Soundness-checking to make sure that the above succeeding // isn't coincidental. if let clone = y.cloneOrFail() { // expected-error {{initializer for conditional binding must have Optional type, not 'Y'}} clone.operationThatOnlyExistsOnY() } // Soundness-checking to make sure that the above succeeding // isn't coincidental. if let clone = y.cloneAsObjectSlice() { clone.operationThatOnlyExistsOnY() // expected-error {{value of type 'X' has no member 'operationThatOnlyExistsOnY'}} } if let clone = y.tryHarderToClone().tryToClone() { clone.operationThatOnlyExistsOnY(); } } // ---------------------------------------------------------------------------- // Conformance lookup on Self protocol Runcible { associatedtype Runcer } extension Runcible { func runce() {} func runced(_: Runcer) {} } func wantsRuncible(_: T) {} class Runce : Runcible { typealias Runcer = Int func getRunced() -> Self { runce() wantsRuncible(self) runced(3) return self } } // ---------------------------------------------------------------------------- // Forming a type with 'Self' in invariant position struct Generic { init(_: T) {} } // expected-note {{arguments to generic parameter 'T' ('Self' and 'InvariantSelf') are expected to be equal}} // expected-note@-1 {{arguments to generic parameter 'T' ('Self' and 'FinalInvariantSelf') are expected to be equal}} class InvariantSelf { func me() -> Self { let a = Generic(self) let _: Generic = a // expected-error@-1 {{cannot assign value of type 'Generic' to type 'Generic'}} return self } } // FIXME: This should be allowed final class FinalInvariantSelf { func me() -> Self { let a = Generic(self) let _: Generic = a // expected-error@-1 {{cannot assign value of type 'Generic' to type 'Generic'}} return self } } // ---------------------------------------------------------------------------- // Semi-bogus factory init pattern protocol FactoryPattern { init(factory: @autoclosure () -> Self) } extension FactoryPattern { init(factory: @autoclosure () -> Self) { self = factory() } } class Factory : FactoryPattern { init(_string: String) {} convenience init(string: String) { self.init(factory: Factory(_string: string)) // expected-error@-1 {{cannot convert value of type 'Factory' to expected argument type 'Self'}} } } // Final classes are OK final class FinalFactory : FactoryPattern { init(_string: String) {} convenience init(string: String) { self.init(factory: FinalFactory(_string: string)) } } // Operators returning Self class SelfOperator { required init() {} static func +(lhs: SelfOperator, rhs: SelfOperator) -> Self { return self.init() } func double() -> Self { // FIXME: Should this work? return self + self // expected-error {{cannot convert return expression of type 'SelfOperator' to return type 'Self'}} } } func useSelfOperator() { let s = SelfOperator() _ = s + s } // for ... in loops struct DummyIterator : IteratorProtocol { func next() -> Int? { return nil } } class Iterable : Sequence { func returnsSelf() -> Self { for _ in self {} return self } func makeIterator() -> DummyIterator { return DummyIterator() } } // Default arguments of methods cannot capture 'Self' or 'self' class MathClass { func invalidDefaultArg(s: Int = Self.intMethod()) {} // expected-error@-1 {{covariant 'Self' type cannot be referenced from a default argument expression}} // Make sure we check subscripts too. subscript(_: Int = Self.intMethod()) -> Int { return 0 } // expected-error@-1 {{covariant 'Self' type cannot be referenced from a default argument expression}} static func intMethod() -> Int { return 0 } }