From 804fd370679e1defaa81d261a3c50428de895abb Mon Sep 17 00:00:00 2001 From: John Holdsworth Date: Fri, 22 Mar 2019 13:21:46 +0000 Subject: [PATCH 1/5] Exclude properties with type Self --- lib/Sema/TypeCheckType.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp index 07a79cebe8b6e..6c0781e3ee56b 100644 --- a/lib/Sema/TypeCheckType.cpp +++ b/lib/Sema/TypeCheckType.cpp @@ -1065,7 +1065,8 @@ static Type diagnoseUnknownType(TypeResolution resolution, methodDecl->getDeclContext() == dc->getParentForLookup(); if (((!insideClass || !declaringMethod) && - !options.is(TypeResolverContext::GenericRequirement)) || + !options.is(TypeResolverContext::GenericRequirement) && + !options.is(TypeResolverContext::PatternBindingDecl)) || options.is(TypeResolverContext::ExplicitCastExpr)) { Type SelfType = nominal->getSelfInterfaceType(); if (insideClass) From dd9cd44b5ebea7e6d56edf0d521fdf51fcc7bdb9 Mon Sep 17 00:00:00 2001 From: John Holdsworth Date: Fri, 22 Mar 2019 13:48:12 +0000 Subject: [PATCH 2/5] Include test of error on declaring property with type Self --- test/type/self.swift | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/test/type/self.swift b/test/type/self.swift index 0a9fea9611bc8..49b330105b69f 100644 --- a/test/type/self.swift +++ b/test/type/self.swift @@ -151,3 +151,27 @@ enum E { return .e } } + +class A1 { + required init() {} + func copy() -> Self { + let copy = Self.init() + return copy + } + + var copied: Self { // expected-error {{'Self' is only available in a protocol or as the result of a method in a class; did you mean 'A1'?}} + let copy = Self.init() + return copy + } +} + +class B1: A1 { + override func copy() -> Self { + let copy = super.copy() as! Self // supported + return copy + } + override var copied: Self { // expected-error {{'Self' is only available in a protocol or as the result of a method in a class; did you mean 'B1'?}} + let copy = super.copied as! Self // unsupported + return copy + } +} From 59963971bc0357767e8c53546d6706c8abab2ce7 Mon Sep 17 00:00:00 2001 From: John Holdsworth Date: Fri, 22 Mar 2019 18:01:52 +0000 Subject: [PATCH 3/5] Don't exclude Self on properties of Value types. --- lib/Sema/TypeCheckType.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp index 6c0781e3ee56b..68dbadac23cc8 100644 --- a/lib/Sema/TypeCheckType.cpp +++ b/lib/Sema/TypeCheckType.cpp @@ -1064,9 +1064,9 @@ static Type diagnoseUnknownType(TypeResolution resolution, bool declaringMethod = methodDecl && methodDecl->getDeclContext() == dc->getParentForLookup(); - if (((!insideClass || !declaringMethod) && - !options.is(TypeResolverContext::GenericRequirement) && - !options.is(TypeResolverContext::PatternBindingDecl)) || + if (((!insideClass || !declaringMethod) && !(insideClass && + options.is(TypeResolverContext::PatternBindingDecl)) && + !options.is(TypeResolverContext::GenericRequirement)) || options.is(TypeResolverContext::ExplicitCastExpr)) { Type SelfType = nominal->getSelfInterfaceType(); if (insideClass) From e515daca20eaa16333eb544c81b15123471f8c6c Mon Sep 17 00:00:00 2001 From: John Holdsworth Date: Sun, 24 Mar 2019 12:59:48 +0000 Subject: [PATCH 4/5] Intermediate variable --- lib/Sema/TypeCheckType.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp index 68dbadac23cc8..6c69fdcacee22 100644 --- a/lib/Sema/TypeCheckType.cpp +++ b/lib/Sema/TypeCheckType.cpp @@ -1063,9 +1063,10 @@ static Type diagnoseUnknownType(TypeResolution resolution, AbstractFunctionDecl *methodDecl = dc->getInnermostMethodContext(); bool declaringMethod = methodDecl && methodDecl->getDeclContext() == dc->getParentForLookup(); + bool isPropertyOfClass = insideClass && + options.is(TypeResolverContext::PatternBindingDecl); - if (((!insideClass || !declaringMethod) && !(insideClass && - options.is(TypeResolverContext::PatternBindingDecl)) && + if (((!insideClass || !declaringMethod) && !isPropertyOfClass && !options.is(TypeResolverContext::GenericRequirement)) || options.is(TypeResolverContext::ExplicitCastExpr)) { Type SelfType = nominal->getSelfInterfaceType(); From ed11057eb4dbe2f5cf66c8d0ad73acb34cae13a0 Mon Sep 17 00:00:00 2001 From: John Holdsworth Date: Sun, 24 Mar 2019 18:27:18 +0000 Subject: [PATCH 5/5] Tighten up test --- test/type/self.swift | 50 +++++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/test/type/self.swift b/test/type/self.swift index 49b330105b69f..2582ad27dedf0 100644 --- a/test/type/self.swift +++ b/test/type/self.swift @@ -70,6 +70,15 @@ class A { // expected-warning@-1 {{conditional cast from 'Self' to 'Self' always succeeds}} // expected-warning@-2 {{conditional downcast from 'Self?' to 'A' is equivalent to an implicit conversion to an optional 'A'}} } + func copy() -> Self { + let copy = Self.init(a: 11) + return copy + } + + var copied: Self { // expected-error {{'Self' is only available in a protocol or as the result of a method in a class; did you mean 'A'?}} + let copy = Self.init(a: 11) + return copy + } } class B: A { @@ -88,6 +97,14 @@ class B: A { override class func y() { print("override \(Self.self).\(#function)") } + override func copy() -> Self { + let copy = super.copy() as! Self // supported + return copy + } + override var copied: Self { // expected-error {{'Self' is only available in a protocol or as the result of a method in a class; did you mean 'B'?}} + let copy = super.copied as! Self // unsupported + return copy + } } class C { @@ -121,6 +138,15 @@ struct S2 { // expected-warning@-1 {{conditional cast from 'S2.S3' to 'S2.S3' always succeeds}} } } + func copy() -> Self { + let copy = Self.init() + return copy + } + + var copied: Self { + let copy = Self.init() + return copy + } } extension S2 { @@ -151,27 +177,3 @@ enum E { return .e } } - -class A1 { - required init() {} - func copy() -> Self { - let copy = Self.init() - return copy - } - - var copied: Self { // expected-error {{'Self' is only available in a protocol or as the result of a method in a class; did you mean 'A1'?}} - let copy = Self.init() - return copy - } -} - -class B1: A1 { - override func copy() -> Self { - let copy = super.copy() as! Self // supported - return copy - } - override var copied: Self { // expected-error {{'Self' is only available in a protocol or as the result of a method in a class; did you mean 'B1'?}} - let copy = super.copied as! Self // unsupported - return copy - } -}