Merge pull request #12941 from rjmccall/block-to-func-formal-bridging
Bridge the formal block type in a block-to-func thunk
diff --git a/cmake/modules/SwiftSharedCMakeConfig.cmake b/cmake/modules/SwiftSharedCMakeConfig.cmake
index a832224..5c2db0f 100644
--- a/cmake/modules/SwiftSharedCMakeConfig.cmake
+++ b/cmake/modules/SwiftSharedCMakeConfig.cmake
@@ -81,7 +81,9 @@
# HACK: this ugly tweaking is to prevent the propagation of the flag from LLVM
# into swift. The use of this flag pollutes all targets, and we are not able
# to remove it on a per-target basis which breaks cross-compilation.
- string(REGEX REPLACE "-Wl,-z,defs" "" CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
+ if("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
+ string(REGEX REPLACE "-Wl,-z,defs" "" CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
+ endif()
set(PACKAGE_VERSION "${LLVM_PACKAGE_VERSION}")
string(REGEX REPLACE "([0-9]+)\\.[0-9]+(\\.[0-9]+)?" "\\1" PACKAGE_VERSION_MAJOR
diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h
index ab1b13a..5be9bbc 100644
--- a/include/swift/AST/Decl.h
+++ b/include/swift/AST/Decl.h
@@ -2225,6 +2225,10 @@
getFormalAccessScope(const DeclContext *useDC = nullptr,
bool respectVersionedAttr = false) const;
+
+ /// Copy the formal access level and @_versioned attribute from source.
+ void copyFormalAccessAndVersionedAttrFrom(ValueDecl *source);
+
/// Returns the access level that actually controls how a declaration should
/// be emitted and may be used.
///
@@ -3402,7 +3406,7 @@
/// Synthesize implicit, trivial destructor, add it to this ClassDecl
/// and return it.
- DestructorDecl *addImplicitDestructor();
+ void addImplicitDestructor();
/// Determine whether this class inherits the convenience initializers
/// from its superclass.
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 483107a..4233676 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -2184,6 +2184,19 @@
llvm_unreachable("unknown access level");
}
+void ValueDecl::copyFormalAccessAndVersionedAttrFrom(ValueDecl *source) {
+ if (!hasAccess()) {
+ setAccess(source->getFormalAccess());
+ }
+
+ // Inherit the @_versioned attribute.
+ if (source->getAttrs().hasAttribute<VersionedAttr>()) {
+ auto &ctx = getASTContext();
+ auto *clonedAttr = new (ctx) VersionedAttr(/*implicit=*/true);
+ getAttrs().add(clonedAttr);
+ }
+}
+
Type TypeDecl::getDeclaredInterfaceType() const {
if (auto *NTD = dyn_cast<NominalTypeDecl>(this))
return NTD->getDeclaredInterfaceType();
@@ -2689,9 +2702,9 @@
return cast<DestructorDecl>(results.front());
}
-DestructorDecl *ClassDecl::addImplicitDestructor() {
+void ClassDecl::addImplicitDestructor() {
if (hasDestructor() || isInvalid())
- return nullptr;
+ return;
auto *selfDecl = ParamDecl::createSelf(getLoc(), this);
@@ -2699,12 +2712,36 @@
auto *DD = new (ctx) DestructorDecl(getLoc(), selfDecl, this);
DD->setImplicit();
+ DD->setValidationStarted();
// Create an empty body for the destructor.
DD->setBody(BraceStmt::create(ctx, getLoc(), { }, getLoc(), true));
addMember(DD);
setHasDestructor();
- return DD;
+
+ // Propagate access control and versioned-ness.
+ DD->copyFormalAccessAndVersionedAttrFrom(this);
+
+ // Wire up generic environment of DD.
+ DD->setGenericEnvironment(getGenericEnvironmentOfContext());
+
+ // Mark DD as ObjC, as all dtors are.
+ DD->setIsObjC(true);
+ recordObjCMethod(DD);
+
+ // Assign DD the interface type (Self) -> () -> ()
+ ArrayRef<AnyFunctionType::Param> noParams;
+ AnyFunctionType::ExtInfo info;
+ Type selfTy = selfDecl->getInterfaceType();
+ Type voidTy = TupleType::getEmpty(ctx);
+ Type funcTy = FunctionType::get(noParams, voidTy, info);
+ if (auto *sig = DD->getGenericSignature()) {
+ DD->setInterfaceType(
+ GenericFunctionType::get(sig, {selfTy}, funcTy, info));
+ } else {
+ DD->setInterfaceType(
+ FunctionType::get({selfTy}, funcTy, info));
+ }
}
diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp
index 40c58a4..3982bd6 100644
--- a/lib/ClangImporter/ImportDecl.cpp
+++ b/lib/ClangImporter/ImportDecl.cpp
@@ -4254,7 +4254,7 @@
result->setCheckedInheritanceClause();
result->setAddedImplicitInitializers(); // suppress all initializers
addObjCAttribute(result, Impl.importIdentifier(decl->getIdentifier()));
- Impl.registerExternalDecl(result);
+ result->addImplicitDestructor();
return result;
};
@@ -4274,7 +4274,6 @@
auto result = createRootClass(Impl.SwiftContext.Id_Protocol,
nsObjectDecl->getDeclContext());
result->setForeignClassKind(ClassDecl::ForeignKind::RuntimeOnly);
- result->addImplicitDestructor();
return result;
}
@@ -4359,7 +4358,6 @@
markMissingSwiftDecl(result);
if (decl->getAttr<clang::ObjCRuntimeVisibleAttr>()) {
result->setForeignClassKind(ClassDecl::ForeignKind::RuntimeOnly);
- result->addImplicitDestructor();
}
// If this Objective-C class has a supertype, import it.
@@ -4392,7 +4390,6 @@
if (decl->getName() == "OS_object" ||
decl->getName() == "OS_os_log") {
result->setForeignClassKind(ClassDecl::ForeignKind::RuntimeOnly);
- result->addImplicitDestructor();
}
// If the superclass is runtime-only, our class is also. This only
@@ -4420,9 +4417,7 @@
#include "InferredAttributes.def"
result->setMemberLoader(&Impl, 0);
-
- // Pass the class to the type checker to create an implicit destructor.
- Impl.registerExternalDecl(result);
+ result->addImplicitDestructor();
return result;
}
diff --git a/lib/Sema/CodeSynthesis.cpp b/lib/Sema/CodeSynthesis.cpp
index 38d6a0d..882d537 100644
--- a/lib/Sema/CodeSynthesis.cpp
+++ b/lib/Sema/CodeSynthesis.cpp
@@ -2205,9 +2205,3 @@
return ctor;
}
-
-void TypeChecker::addImplicitDestructor(ClassDecl *CD) {
- auto *DD = CD->addImplicitDestructor();
- if (DD)
- typeCheckDecl(DD, /*isFirstPass=*/true);
-}
diff --git a/lib/Sema/DerivedConformanceEquatableHashable.cpp b/lib/Sema/DerivedConformanceEquatableHashable.cpp
index 72124cc..fa3707a 100644
--- a/lib/Sema/DerivedConformanceEquatableHashable.cpp
+++ b/lib/Sema/DerivedConformanceEquatableHashable.cpp
@@ -671,7 +671,7 @@
FunctionType::ExtInfo());
}
eqDecl->setInterfaceType(interfaceTy);
- copyFormalAccess(eqDecl, typeDecl);
+ eqDecl->copyFormalAccessAndVersionedAttrFrom(typeDecl);
// If the enum was not imported, the derived conformance is either from the
// enum itself or an extension, in which case we will emit the declaration
@@ -1090,7 +1090,7 @@
AnyFunctionType::ExtInfo());
getterDecl->setInterfaceType(interfaceType);
- copyFormalAccess(getterDecl, typeDecl);
+ getterDecl->copyFormalAccessAndVersionedAttrFrom(typeDecl);
// If the enum was not imported, the derived conformance is either from the
// enum itself or an extension, in which case we will emit the declaration
@@ -1106,7 +1106,7 @@
hashValueDecl->setInterfaceType(intType);
hashValueDecl->makeComputed(SourceLoc(), getterDecl,
nullptr, nullptr, SourceLoc());
- copyFormalAccess(hashValueDecl, typeDecl);
+ hashValueDecl->copyFormalAccessAndVersionedAttrFrom(typeDecl);
Pattern *hashValuePat = new (C) NamedPattern(hashValueDecl, /*implicit*/true);
hashValuePat->setType(intType);
diff --git a/lib/Sema/DerivedConformanceRawRepresentable.cpp b/lib/Sema/DerivedConformanceRawRepresentable.cpp
index c3fb22a..853e9ed 100644
--- a/lib/Sema/DerivedConformanceRawRepresentable.cpp
+++ b/lib/Sema/DerivedConformanceRawRepresentable.cpp
@@ -349,7 +349,7 @@
}
initDecl->setInterfaceType(allocIfaceType);
initDecl->setInitializerInterfaceType(initIfaceType);
- copyFormalAccess(initDecl, enumDecl);
+ initDecl->copyFormalAccessAndVersionedAttrFrom(enumDecl);
// If the enum was not imported, the derived conformance is either from the
// enum itself or an extension, in which case we will emit the declaration
diff --git a/lib/Sema/DerivedConformances.cpp b/lib/Sema/DerivedConformances.cpp
index 0beaf5f..f2e6d36 100644
--- a/lib/Sema/DerivedConformances.cpp
+++ b/lib/Sema/DerivedConformances.cpp
@@ -251,7 +251,7 @@
interfaceType = FunctionType::get({selfParam}, interfaceType,
FunctionType::ExtInfo());
getterDecl->setInterfaceType(interfaceType);
- copyFormalAccess(getterDecl, typeDecl);
+ getterDecl->copyFormalAccessAndVersionedAttrFrom(typeDecl);
// If the enum was not imported, the derived conformance is either from the
// enum itself or an extension, in which case we will emit the declaration
@@ -281,7 +281,7 @@
propDecl->setImplicit();
propDecl->makeComputed(SourceLoc(), getterDecl, nullptr, nullptr,
SourceLoc());
- copyFormalAccess(propDecl, typeDecl);
+ propDecl->copyFormalAccessAndVersionedAttrFrom(typeDecl);
propDecl->setInterfaceType(propertyInterfaceType);
// If this is supposed to be a final property, mark it as such.
@@ -304,14 +304,3 @@
return {propDecl, pbDecl};
}
-
-void DerivedConformance::copyFormalAccess(ValueDecl *dest, ValueDecl *source) {
- dest->setAccess(source->getFormalAccess());
-
- // Inherit the @_versioned attribute.
- if (source->getAttrs().hasAttribute<VersionedAttr>()) {
- auto &ctx = source->getASTContext();
- auto *clonedAttr = new (ctx) VersionedAttr(/*implicit=*/true);
- dest->getAttrs().add(clonedAttr);
- }
-}
diff --git a/lib/Sema/DerivedConformances.h b/lib/Sema/DerivedConformances.h
index 0e6ab8b..2457971 100644
--- a/lib/Sema/DerivedConformances.h
+++ b/lib/Sema/DerivedConformances.h
@@ -185,9 +185,6 @@
/// Build a reference to the 'self' decl of a derived function.
DeclRefExpr *createSelfDeclRef(AbstractFunctionDecl *fn);
-/// Copy access from the source decl to the destination decl.
-void copyFormalAccess(ValueDecl *dest, ValueDecl *source);
-
}
}
diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp
index 9070037..62f9cb5 100644
--- a/lib/Sema/TypeCheckDecl.cpp
+++ b/lib/Sema/TypeCheckDecl.cpp
@@ -4638,7 +4638,7 @@
if (!IsFirstPass)
TC.addImplicitConstructors(CD);
- TC.addImplicitDestructor(CD);
+ CD->addImplicitDestructor();
if (!IsFirstPass && !CD->isInvalid())
TC.checkConformancesInContext(CD, CD);
@@ -7213,13 +7213,7 @@
&& "Decl parsing must prevent destructors outside of types!");
TC.checkDeclAttributesEarly(DD);
- if (!DD->hasAccess()) {
- DD->setAccess(enclosingClass->getFormalAccess());
- }
-
- if (enclosingClass->getAttrs().hasAttribute<VersionedAttr>()) {
- DD->getAttrs().add(new (TC.Context) VersionedAttr(/*implicit=*/true));
- }
+ DD->copyFormalAccessAndVersionedAttrFrom(enclosingClass);
configureImplicitSelf(TC, DD);
@@ -7963,7 +7957,7 @@
// class, you shouldn't have to know what the vtable layout is.
if (auto *CD = dyn_cast<ClassDecl>(nominal)) {
TC.addImplicitConstructors(CD);
- TC.addImplicitDestructor(CD);
+ CD->addImplicitDestructor();
}
// validateDeclForNameLookup will not trigger an immediate full
diff --git a/lib/Sema/TypeChecker.cpp b/lib/Sema/TypeChecker.cpp
index b5d3c2f..b75df46 100644
--- a/lib/Sema/TypeChecker.cpp
+++ b/lib/Sema/TypeChecker.cpp
@@ -69,7 +69,7 @@
addImplicitStructConformances(SD);
}
if (auto CD = dyn_cast<ClassDecl>(decl)) {
- addImplicitDestructor(CD);
+ CD->addImplicitDestructor();
}
if (auto ED = dyn_cast<EnumDecl>(decl)) {
addImplicitEnumConformances(ED);
diff --git a/lib/Sema/TypeChecker.h b/lib/Sema/TypeChecker.h
index 1a22724..fa1ecae 100644
--- a/lib/Sema/TypeChecker.h
+++ b/lib/Sema/TypeChecker.h
@@ -1511,10 +1511,6 @@
/// struct or class.
void addImplicitConstructors(NominalTypeDecl *typeDecl);
- /// \brief Add an implicitly-defined destructor, if there is no
- /// user-provided destructor.
- void addImplicitDestructor(ClassDecl *CD);
-
/// \brief Add the RawOptionSet (todo:, Equatable, and Hashable) methods to an
/// imported NS_OPTIONS struct.
void addImplicitStructConformances(StructDecl *ED);
diff --git a/lib/Serialization/Deserialization.cpp b/lib/Serialization/Deserialization.cpp
index 5ca4aa6..0918a5b 100644
--- a/lib/Serialization/Deserialization.cpp
+++ b/lib/Serialization/Deserialization.cpp
@@ -1277,9 +1277,18 @@
DeclBaseName name = getDeclBaseName(IID);
pathTrace.addValue(name);
- Type filterTy = getType(TID);
- if (!isType)
+ Type filterTy;
+ if (!isType) {
+ auto maybeType = getTypeChecked(TID);
+ if (!maybeType) {
+ // FIXME: Don't throw away the inner error's information.
+ llvm::consumeError(maybeType.takeError());
+ return llvm::make_error<XRefError>("couldn't decode type",
+ pathTrace, name);
+ }
+ filterTy = maybeType.get();
pathTrace.addType(filterTy);
+ }
baseModule->lookupQualified(ModuleType::get(baseModule), name,
NL_QualifiedDefault | NL_KnownNoDependency,
@@ -1482,9 +1491,18 @@
pathTrace.addValue(memberName);
- Type filterTy = getType(TID);
- if (!isType)
+ Type filterTy;
+ if (!isType) {
+ auto maybeType = getTypeChecked(TID);
+ if (!maybeType) {
+ // FIXME: Don't throw away the inner error's information.
+ llvm::consumeError(maybeType.takeError());
+ return llvm::make_error<XRefError>("couldn't decode type",
+ pathTrace, memberName);
+ }
+ filterTy = maybeType.get();
pathTrace.addType(filterTy);
+ }
if (values.size() != 1) {
return llvm::make_error<XRefError>("multiple matching base values",
diff --git a/stdlib/public/SwiftRemoteMirror/CMakeLists.txt b/stdlib/public/SwiftRemoteMirror/CMakeLists.txt
index 260d04e..6aa7709 100644
--- a/stdlib/public/SwiftRemoteMirror/CMakeLists.txt
+++ b/stdlib/public/SwiftRemoteMirror/CMakeLists.txt
@@ -1,3 +1,6 @@
+# HACK: Force this library to build with undefined symbols.
+string(REGEX REPLACE "-Wl,-z,defs" "" CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
+
# libswiftRemoteMirror.dylib should not have runtime dependencies; it's
# always built as a shared library.
if(SWIFT_BUILD_DYNAMIC_STDLIB OR SWIFT_BUILD_REMOTE_MIRROR)
diff --git a/stdlib/public/core/FloatingPointTypes.swift.gyb b/stdlib/public/core/FloatingPointTypes.swift.gyb
index 3861ca5..79c021f 100644
--- a/stdlib/public/core/FloatingPointTypes.swift.gyb
+++ b/stdlib/public/core/FloatingPointTypes.swift.gyb
@@ -559,11 +559,11 @@
// in angles in the wrong quadrant if users aren't careful. This is
// not a problem for Double or Float80, as pi rounds down in both of
// those formats.
- return Float(0x1.921fb4p1)
+ return 0x1.921fb4p1
%elif bits == 64:
- return Double(0x1.921fb54442d18p1)
+ return 0x1.921fb54442d18p1
%elif bits == 80:
- return Float80(0x1.921fb54442d1846ap1)
+ return 0x1.921fb54442d1846ap1
%end
}
diff --git a/test/Serialization/Recovery/Inputs/custom-modules/Overrides.h b/test/Serialization/Recovery/Inputs/custom-modules/Overrides.h
index 7bf9c7a..6eaf68c 100644
--- a/test/Serialization/Recovery/Inputs/custom-modules/Overrides.h
+++ b/test/Serialization/Recovery/Inputs/custom-modules/Overrides.h
@@ -115,3 +115,22 @@
//- (nonnull instancetype)initWithValue:(long)value;
#endif
@end
+
+
+#if !BAD
+struct BoxedInt {
+ int value;
+};
+#endif
+
+@interface MethodWithDisappearingType : Object
+#if !BAD
+- (struct BoxedInt)boxItUp;
+#endif
+@end
+
+@interface InitializerWithDisappearingType : Object
+#if !BAD
+- (nonnull instancetype)initWithBoxedInt:(struct BoxedInt)box;
+#endif
+@end
diff --git a/test/Serialization/Recovery/overrides.swift b/test/Serialization/Recovery/overrides.swift
index c0b7b25..486f6c0 100644
--- a/test/Serialization/Recovery/overrides.swift
+++ b/test/Serialization/Recovery/overrides.swift
@@ -311,4 +311,33 @@
// CHECK-RECOVERY-NEXT: /* placeholder for init(value:) */
// CHECK-RECOVERY-NEXT: {{^}$}}
+public class E1_MethodWithDisappearingType : MethodWithDisappearingType {
+ public override func boxItUp() -> BoxedInt { fatalError() }
+}
+
+// CHECK-LABEL: class E1_MethodWithDisappearingType : MethodWithDisappearingType {
+// CHECK-NEXT: override func boxItUp() -> BoxedInt
+// CHECK-NEXT: init()
+// CHECK-NEXT: {{^}$}}
+
+// CHECK-RECOVERY-LABEL: class E1_MethodWithDisappearingType : MethodWithDisappearingType {
+// CHECK-RECOVERY-NEXT: init()
+// CHECK-RECOVERY-NEXT: {{^}$}}
+
+public class E2_InitializerStub : InitializerWithDisappearingType {
+ public init(unrelatedValue: Int) { fatalError() }
+}
+
+// CHECK-LABEL: class E2_InitializerStub : InitializerWithDisappearingType {
+// CHECK-NEXT: init(unrelatedValue: Int)
+// CHECK-NEXT: init(boxedInt box: BoxedInt)
+// CHECK-NEXT: init()
+// CHECK-NEXT: {{^}$}}
+
+// CHECK-RECOVERY-LABEL: class E2_InitializerStub : InitializerWithDisappearingType {
+// CHECK-RECOVERY-NEXT: init(unrelatedValue: Int)
+// CHECK-RECOVERY-NEXT: /* placeholder for init(boxedInt:) */
+// CHECK-RECOVERY-NEXT: init()
+// CHECK-RECOVERY-NEXT: {{^}$}}
+
#endif // TEST