From 3394091997413dd58a51264e73dd3f673fb07261 Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Tue, 4 Apr 2023 13:08:00 -0700 Subject: [PATCH] TDBGen: add a workaround for a workaround for async PWT When a protocol witness thunk is formed to a serialised protocol containing an `async` function, the async function pointer to the conformance needs to be made public due to a SIL Verifier check failure (reference to a non-fragile function from within a public fragile function). Add a stop-gap solution of rolling an extra emission for a private symbol as a public symbol to avoid the error (the underlying issue has been open for ~6y and counting as of this commit). This was identified by swift-package-manager (#64900). Thanks to @DougGregor and @aschwaighofer for the discussion on this! --- lib/IRGen/TBDGen.cpp | 11 +++++++++-- test/IRGen/serialised-pwt-afp.swift | 23 +++++++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 test/IRGen/serialised-pwt-afp.swift diff --git a/lib/IRGen/TBDGen.cpp b/lib/IRGen/TBDGen.cpp index 75f55823bd376..d4f1efbe0956c 100644 --- a/lib/IRGen/TBDGen.cpp +++ b/lib/IRGen/TBDGen.cpp @@ -472,9 +472,16 @@ void TBDGenVisitor::addProtocolWitnessThunk(RootProtocolConformance *C, ValueDecl *requirementDecl) { Mangle::ASTMangler Mangler; + std::string decorated = Mangler.mangleWitnessThunk(C, requirementDecl); // FIXME: We should have a SILDeclRef SymbolSource for this. - addSymbol(Mangler.mangleWitnessThunk(C, requirementDecl), - SymbolSource::forUnknown()); + addSymbol(decorated, SymbolSource::forUnknown()); + + if (requirementDecl->isProtocolRequirement()) { + ValueDecl *PWT = C->getWitness(requirementDecl).getDecl(); + if (const auto *AFD = dyn_cast(PWT)) + if (AFD->hasAsync()) + addSymbol(decorated + "Tu", SymbolSource::forUnknown()); + } } void TBDGenVisitor::addFirstFileSymbols() { diff --git a/test/IRGen/serialised-pwt-afp.swift b/test/IRGen/serialised-pwt-afp.swift new file mode 100644 index 0000000000000..155dd92529d2a --- /dev/null +++ b/test/IRGen/serialised-pwt-afp.swift @@ -0,0 +1,23 @@ +// RUN: %empty-directory(%t) +// RUN: %target-swift-frontend -disable-availability-checking -emit-module -emit-module-path %t/P.swiftmodule -parse-as-library -module-name P -DP %s +// RUN: %target-swift-frontend -disable-availability-checking -I%t -parse-as-library -module-name Q -c %s -o /dev/null -validate-tbd-against-ir=missing + +// REQUIRES: concurrency + +#if P +public protocol P { + func f() async +} +#else +import P + +protocol Q: P { } + +extension Q { + public func f() async { } +} + +public struct S: Q { + public init() { } +} +#endif