mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[SILGen] Fix the type of closure thunks that are passed const reference structs
This PR is another attempt at landing #76903. The changes compared to the original PR: * Instead of increasing the size of SILDeclRef, store the necessary type information in a side channel using withClosureTypeInfo. * Rely on SGFContext to get the right ClangType * Extend BridgingConversion with an AbstractionPattern to store the original clang type. * The PR above introduced a crash during indexing system modules that references foreign types coming from modules imported as implementation only. These entities are implementation details so they do not need to be included during serialization. This PR adds a test and adds logic to exclude such clang types in the serialization process. rdar://131321096&141786724
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
#include "swift/AST/ASTMangler.h"
|
||||
#include "swift/AST/ASTVisitor.h"
|
||||
#include "swift/AST/AutoDiff.h"
|
||||
#include "swift/AST/Decl.h"
|
||||
#include "swift/AST/DiagnosticsCommon.h"
|
||||
#include "swift/AST/DiagnosticsSema.h"
|
||||
#include "swift/AST/Expr.h"
|
||||
@@ -41,6 +42,7 @@
|
||||
#include "swift/AST/SynthesizedFileUnit.h"
|
||||
#include "swift/AST/TypeCheckRequests.h"
|
||||
#include "swift/AST/TypeVisitor.h"
|
||||
#include "swift/AST/Types.h"
|
||||
#include "swift/Basic/Assertions.h"
|
||||
#include "swift/Basic/Defer.h"
|
||||
#include "swift/Basic/FileSystem.h"
|
||||
@@ -5567,6 +5569,31 @@ static TypeAliasDecl *findTypeAliasForBuiltin(ASTContext &Ctx, Type T) {
|
||||
return cast<TypeAliasDecl>(CurModuleResults[0]);
|
||||
}
|
||||
|
||||
namespace {
|
||||
struct ImplementationOnlyWalker : TypeWalker {
|
||||
bool hadImplementationOnlyDecl = false;
|
||||
const ModuleDecl *currentModule;
|
||||
ImplementationOnlyWalker(const ModuleDecl *M) : currentModule(M) {}
|
||||
Action walkToTypePre(Type ty) override {
|
||||
if (auto *typeAlias = dyn_cast<TypeAliasType>(ty)) {
|
||||
if (importedImplementationOnly(typeAlias->getDecl()))
|
||||
return Action::Stop;
|
||||
} else if (auto *nominal = ty->getAs<NominalType>()) {
|
||||
if (importedImplementationOnly(nominal->getDecl()))
|
||||
return Action::Stop;
|
||||
}
|
||||
return Action::Continue;
|
||||
}
|
||||
bool importedImplementationOnly(const Decl *D) {
|
||||
if (currentModule->isImportedImplementationOnly(D->getModuleContext())) {
|
||||
hadImplementationOnlyDecl = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
} // namespace
|
||||
|
||||
class Serializer::TypeSerializer : public TypeVisitor<TypeSerializer> {
|
||||
Serializer &S;
|
||||
|
||||
@@ -5920,10 +5947,23 @@ public:
|
||||
using namespace decls_block;
|
||||
|
||||
auto resultType = S.addTypeRef(fnTy->getResult());
|
||||
auto clangType =
|
||||
S.getASTContext().LangOpts.UseClangFunctionTypes
|
||||
? S.addClangTypeRef(fnTy->getClangTypeInfo().getType())
|
||||
: ClangTypeID(0);
|
||||
bool shouldSerializeClangType = true;
|
||||
if (S.hadImplementationOnlyImport && S.M &&
|
||||
S.M->getResilienceStrategy() != ResilienceStrategy::Resilient) {
|
||||
// Deserializing clang types from implementation only modules could crash
|
||||
// as the transitive clang module might not be available to retrieve the
|
||||
// declarations from. In an optimal world we would make the deseriaization
|
||||
// more resilient to these problems but the failure is in Clang's
|
||||
// deserialization code path that is not architected with potentially
|
||||
// missing declarations in mind.
|
||||
ImplementationOnlyWalker walker{S.M};
|
||||
Type(const_cast<FunctionType *>(fnTy)).walk(walker);
|
||||
if (walker.hadImplementationOnlyDecl)
|
||||
shouldSerializeClangType = false;
|
||||
}
|
||||
auto clangType = shouldSerializeClangType
|
||||
? S.addClangTypeRef(fnTy->getClangTypeInfo().getType())
|
||||
: ClangTypeID(0);
|
||||
|
||||
auto isolation = encodeIsolation(fnTy->getIsolation());
|
||||
|
||||
@@ -7005,8 +7045,13 @@ void Serializer::writeAST(ModuleOrSourceFile DC) {
|
||||
nextFile->getTopLevelDeclsWithAuxiliaryDecls(fileDecls);
|
||||
|
||||
for (auto D : fileDecls) {
|
||||
if (isa<ImportDecl>(D) || isa<MacroExpansionDecl>(D) ||
|
||||
isa<TopLevelCodeDecl>(D) || isa<UsingDecl>(D)) {
|
||||
if (const auto *ID = dyn_cast<ImportDecl>(D)) {
|
||||
if (ID->getAttrs().hasAttribute<ImplementationOnlyAttr>())
|
||||
hadImplementationOnlyImport = true;
|
||||
continue;
|
||||
}
|
||||
if (isa<MacroExpansionDecl>(D) || isa<TopLevelCodeDecl>(D) ||
|
||||
isa<UsingDecl>(D)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user