From aacc052c62b94166a388ea649be8bfbef19f77c3 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Mon, 17 Feb 2020 22:23:27 -0500 Subject: [PATCH 1/2] Sema: Prefer an outer type named 'Self' over the SE-0068 behavior This fixes a recent source break. We need to perform the normal unqualified lookup before we handle the special case of 'Self', because there might be a type named Self defined in an outer context. Fixes / --- lib/Sema/TypeCheckType.cpp | 42 +++++++++++++++++++------------------- test/type/self.swift | 12 +++++++++++ 2 files changed, 33 insertions(+), 21 deletions(-) diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp index b6cdd15921f63..7f4c7c0f1122b 100644 --- a/lib/Sema/TypeCheckType.cpp +++ b/lib/Sema/TypeCheckType.cpp @@ -1299,27 +1299,6 @@ resolveTopLevelIdentTypeComponent(TypeResolution resolution, auto DC = resolution.getDeclContext(); auto id = comp->getIdentifier(); - // Dynamic 'Self' in the result type of a function body. - if (id == ctx.Id_Self) { - if (auto *typeDC = DC->getInnermostTypeContext()) { - // FIXME: The passed-in TypeRepr should get 'typechecked' as well. - // The issue is though that ComponentIdentTypeRepr only accepts a ValueDecl - // while the 'Self' type is more than just a reference to a TypeDecl. - auto selfType = resolution.mapTypeIntoContext( - typeDC->getSelfInterfaceType()); - - // Check if we can reference Self here, and if so, what kind of Self it is. - switch (getSelfTypeKind(DC, options)) { - case SelfTypeKind::StaticSelf: - return selfType; - case SelfTypeKind::DynamicSelf: - return DynamicSelfType::get(selfType, ctx); - case SelfTypeKind::InvalidSelf: - break; - } - } - } - NameLookupOptions lookupOptions = defaultUnqualifiedLookupOptions; if (options.contains(TypeResolutionFlags::KnownNonCascadingDependency)) lookupOptions |= NameLookupFlags::KnownPrivate; @@ -1378,6 +1357,27 @@ resolveTopLevelIdentTypeComponent(TypeResolution resolution, // If we found nothing, complain and give ourselves a chance to recover. if (current.isNull()) { + // Dynamic 'Self' in the result type of a function body. + if (id.isSimpleName(ctx.Id_Self)) { + if (auto *typeDC = DC->getInnermostTypeContext()) { + // FIXME: The passed-in TypeRepr should get 'typechecked' as well. + // The issue is though that ComponentIdentTypeRepr only accepts a ValueDecl + // while the 'Self' type is more than just a reference to a TypeDecl. + auto selfType = resolution.mapTypeIntoContext( + typeDC->getSelfInterfaceType()); + + // Check if we can reference Self here, and if so, what kind of Self it is. + switch (getSelfTypeKind(DC, options)) { + case SelfTypeKind::StaticSelf: + return selfType; + case SelfTypeKind::DynamicSelf: + return DynamicSelfType::get(selfType, ctx); + case SelfTypeKind::InvalidSelf: + break; + } + } + } + // If we're not allowed to complain or we couldn't fix the // source, bail out. if (options.contains(TypeResolutionFlags::SilenceErrors)) diff --git a/test/type/self.swift b/test/type/self.swift index 10e27b93a4e6e..c4b13fb93dfcf 100644 --- a/test/type/self.swift +++ b/test/type/self.swift @@ -287,3 +287,15 @@ class Boxer { required init() {} } + +// https://bugs.swift.org/browse/SR-12133 - a type named 'Self' should be found first +struct OuterType { + struct `Self` { + let string: String + } + + var foo: `Self`? { + let optional: String? = "foo" + return optional.map { `Self`(string: $0) } + } +} From 42fbd5125e22efec09467984078b62e82ee4b412 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Tue, 18 Feb 2020 12:34:13 -0500 Subject: [PATCH 2/2] Fix compile error on swift-5.2-branch --- lib/Sema/TypeCheckType.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp index 7f4c7c0f1122b..39249f89a6cac 100644 --- a/lib/Sema/TypeCheckType.cpp +++ b/lib/Sema/TypeCheckType.cpp @@ -1358,7 +1358,7 @@ resolveTopLevelIdentTypeComponent(TypeResolution resolution, // If we found nothing, complain and give ourselves a chance to recover. if (current.isNull()) { // Dynamic 'Self' in the result type of a function body. - if (id.isSimpleName(ctx.Id_Self)) { + if (id == ctx.Id_Self) { if (auto *typeDC = DC->getInnermostTypeContext()) { // FIXME: The passed-in TypeRepr should get 'typechecked' as well. // The issue is though that ComponentIdentTypeRepr only accepts a ValueDecl