Skip to content

Commit edd0c47

Browse files
authored
Merge pull request swiftlang#35661 from DougGregor/serialize-foreign-async-convention
2 parents 3b77ce4 + 5f4da4c commit edd0c47

File tree

7 files changed

+110
-4
lines changed

7 files changed

+110
-4
lines changed

lib/Serialization/DeclTypeRecordNodes.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ PATTERN(VAR)
151151
OTHER(PARAMETERLIST, 210)
152152
// 211 is unused
153153
OTHER(FOREIGN_ERROR_CONVENTION, 212)
154-
// 213 is unused
154+
OTHER(FOREIGN_ASYNC_CONVENTION, 213)
155155
OTHER(XREF_TYPE_PATH_PIECE, 214)
156156
OTHER(XREF_VALUE_PATH_PIECE, 215)
157157
OTHER(XREF_EXTENSION_PATH_PIECE, 216)

lib/Serialization/Deserialization.cpp

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "swift/AST/AutoDiff.h"
1919
#include "swift/AST/DiagnosticsSema.h"
2020
#include "swift/AST/Expr.h"
21+
#include "swift/AST/ForeignAsyncConvention.h"
2122
#include "swift/AST/ForeignErrorConvention.h"
2223
#include "swift/AST/GenericEnvironment.h"
2324
#include "swift/AST/Initializer.h"
@@ -2697,6 +2698,8 @@ class DeclDeserializer {
26972698

26982699
if (auto errorConvention = MF.maybeReadForeignErrorConvention())
26992700
ctor->setForeignErrorConvention(*errorConvention);
2701+
if (auto asyncConvention = MF.maybeReadForeignAsyncConvention())
2702+
ctor->setForeignAsyncConvention(*asyncConvention);
27002703

27012704
if (auto bodyText = MF.maybeReadInlinableBodyText())
27022705
ctor->setBodyStringRepresentation(*bodyText);
@@ -3182,6 +3185,8 @@ class DeclDeserializer {
31823185

31833186
if (auto errorConvention = MF.maybeReadForeignErrorConvention())
31843187
fn->setForeignErrorConvention(*errorConvention);
3188+
if (auto asyncConvention = MF.maybeReadForeignAsyncConvention())
3189+
fn->setForeignAsyncConvention(*asyncConvention);
31853190

31863191
if (auto bodyText = MF.maybeReadInlinableBodyText())
31873192
fn->setBodyStringRepresentation(*bodyText);
@@ -5485,7 +5490,7 @@ class TypeDeserializer {
54855490

54865491
auto extInfo =
54875492
SILFunctionType::ExtInfoBuilder(*representation, pseudogeneric,
5488-
noescape, concurrent, async, *diffKind,
5493+
noescape, concurrent, async, *diffKind,
54895494
clangFunctionType)
54905495
.build();
54915496

@@ -6477,3 +6482,49 @@ Optional<ForeignErrorConvention> ModuleFile::maybeReadForeignErrorConvention() {
64776482

64786483
llvm_unreachable("Unhandled ForeignErrorConvention in switch.");
64796484
}
6485+
6486+
Optional<ForeignAsyncConvention> ModuleFile::maybeReadForeignAsyncConvention() {
6487+
using namespace decls_block;
6488+
6489+
SmallVector<uint64_t, 8> scratch;
6490+
6491+
BCOffsetRAII restoreOffset(DeclTypeCursor);
6492+
6493+
llvm::BitstreamEntry next =
6494+
fatalIfUnexpected(DeclTypeCursor.advance(AF_DontPopBlockAtEnd));
6495+
if (next.Kind != llvm::BitstreamEntry::Record)
6496+
return None;
6497+
6498+
unsigned recKind =
6499+
fatalIfUnexpected(DeclTypeCursor.readRecord(next.ID, scratch));
6500+
switch (recKind) {
6501+
case FOREIGN_ASYNC_CONVENTION:
6502+
restoreOffset.reset();
6503+
break;
6504+
6505+
default:
6506+
return None;
6507+
}
6508+
6509+
TypeID completionHandlerTypeID;
6510+
unsigned completionHandlerParameterIndex;
6511+
unsigned rawErrorParameterIndex;
6512+
ForeignAsyncConventionLayout::readRecord(scratch,
6513+
completionHandlerTypeID,
6514+
completionHandlerParameterIndex,
6515+
rawErrorParameterIndex);
6516+
6517+
Type completionHandlerType = getType(completionHandlerTypeID);
6518+
CanType canCompletionHandlerType;
6519+
if (completionHandlerType)
6520+
canCompletionHandlerType = completionHandlerType->getCanonicalType();
6521+
6522+
// Decode the error parameter.
6523+
Optional<unsigned> completionHandlerErrorParamIndex;
6524+
if (rawErrorParameterIndex > 0)
6525+
completionHandlerErrorParamIndex = rawErrorParameterIndex - 1;
6526+
6527+
return ForeignAsyncConvention(
6528+
canCompletionHandlerType, completionHandlerParameterIndex,
6529+
completionHandlerErrorParamIndex);
6530+
}

lib/Serialization/ModuleFile.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -805,9 +805,12 @@ class ModuleFile
805805
llvm::Expected<NormalProtocolConformance *>
806806
readNormalConformanceChecked(serialization::NormalConformanceID id);
807807

808-
/// Reads a foreign error conformance from \c DeclTypeCursor, if present.
808+
/// Reads a foreign error convention from \c DeclTypeCursor, if present.
809809
Optional<ForeignErrorConvention> maybeReadForeignErrorConvention();
810810

811+
/// Reads a foreign async convention from \c DeclTypeCursor, if present.
812+
Optional<ForeignAsyncConvention> maybeReadForeignAsyncConvention();
813+
811814
/// Reads inlinable body text from \c DeclTypeCursor, if present.
812815
Optional<StringRef> maybeReadInlinableBodyText();
813816

lib/Serialization/ModuleFormat.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0;
5656
/// describe what change you made. The content of this comment isn't important;
5757
/// it just ensures a conflict if two people change the module format.
5858
/// Don't worry about adhering to the 80-column limit for this line.
59-
const uint16_t SWIFTMODULE_VERSION_MINOR = 592; // @concurrent SIL function type
59+
const uint16_t SWIFTMODULE_VERSION_MINOR = 593; // foreign async convention
6060

6161
/// A standard hash seed used for all string hashes in a serialized module.
6262
///
@@ -1767,6 +1767,13 @@ namespace decls_block {
17671767
TypeIDField // result type
17681768
>;
17691769

1770+
using ForeignAsyncConventionLayout = BCRecordLayout<
1771+
FOREIGN_ASYNC_CONVENTION,
1772+
TypeIDField, // completion handler type
1773+
BCVBR<4>, // completion handler parameter index
1774+
BCVBR<4> // completion handler error parameter index (+1)
1775+
>;
1776+
17701777
using AbstractClosureExprLayout = BCRecordLayout<
17711778
ABSTRACT_CLOSURE_EXPR_CONTEXT,
17721779
TypeIDField, // type

lib/Serialization/Serialization.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "swift/AST/DiagnosticsCommon.h"
2020
#include "swift/AST/Expr.h"
2121
#include "swift/AST/FileSystem.h"
22+
#include "swift/AST/ForeignAsyncConvention.h"
2223
#include "swift/AST/ForeignErrorConvention.h"
2324
#include "swift/AST/GenericEnvironment.h"
2425
#include "swift/AST/IndexSubset.h"
@@ -2693,6 +2694,18 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
26932694
resultTypeID);
26942695
}
26952696

2697+
void writeForeignAsyncConvention(const ForeignAsyncConvention &fac) {
2698+
using namespace decls_block;
2699+
TypeID completionHandlerTypeID = S.addTypeRef(fac.completionHandlerType());
2700+
unsigned rawErrorParameterIndex = fac.completionHandlerErrorParamIndex()
2701+
.map([](unsigned index) { return index + 1; }).getValueOr(0);
2702+
auto abbrCode = S.DeclTypeAbbrCodes[ForeignAsyncConventionLayout::Code];
2703+
ForeignAsyncConventionLayout::emitRecord(S.Out, S.ScratchRecord, abbrCode,
2704+
completionHandlerTypeID,
2705+
fac.completionHandlerParamIndex(),
2706+
rawErrorParameterIndex);
2707+
}
2708+
26962709
void writeGenericParams(const GenericParamList *genericParams) {
26972710
using namespace decls_block;
26982711

@@ -3590,6 +3603,8 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
35903603

35913604
if (auto errorConvention = fn->getForeignErrorConvention())
35923605
writeForeignErrorConvention(*errorConvention);
3606+
if (auto asyncConvention = fn->getForeignAsyncConvention())
3607+
writeForeignAsyncConvention(*asyncConvention);
35933608

35943609
writeInlinableBodyTextIfNeeded(fn);
35953610
}
@@ -3671,6 +3686,8 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
36713686

36723687
if (auto errorConvention = fn->getForeignErrorConvention())
36733688
writeForeignErrorConvention(*errorConvention);
3689+
if (auto asyncConvention = fn->getForeignAsyncConvention())
3690+
writeForeignAsyncConvention(*asyncConvention);
36743691

36753692
writeInlinableBodyTextIfNeeded(fn);
36763693
}
@@ -3825,6 +3842,8 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
38253842

38263843
if (auto errorConvention = ctor->getForeignErrorConvention())
38273844
writeForeignErrorConvention(*errorConvention);
3845+
if (auto asyncConvention = ctor->getForeignAsyncConvention())
3846+
writeForeignAsyncConvention(*asyncConvention);
38283847

38293848
writeInlinableBodyTextIfNeeded(ctor);
38303849
}
@@ -4669,6 +4688,7 @@ void Serializer::writeAllDeclsAndTypes() {
46694688
registerDeclTypeAbbr<SubstitutionMapLayout>();
46704689

46714690
registerDeclTypeAbbr<ForeignErrorConventionLayout>();
4691+
registerDeclTypeAbbr<ForeignAsyncConventionLayout>();
46724692
registerDeclTypeAbbr<AbstractClosureExprLayout>();
46734693
registerDeclTypeAbbr<PatternBindingInitializerLayout>();
46744694
registerDeclTypeAbbr<DefaultArgumentInitializerLayout>();
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import Foundation
2+
3+
open class Base: NSObject { }
4+
5+
extension Base {
6+
@objc open func foo(id: Int) async { }
7+
}

test/Serialization/objc_async.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %empty-directory(%t-scratch)
3+
// RUN: %target-swift-frontend -emit-module -o %t-scratch/def_objc_async~partial.swiftmodule -primary-file %S/Inputs/def_objc_async.swift -module-name def_objc_async -enable-experimental-concurrency
4+
// RUN: %target-swift-frontend -merge-modules -emit-module -parse-as-library -enable-testing %t-scratch/def_objc_async~partial.swiftmodule -module-name def_objc_async -o %t/def_objc_async.swiftmodule -enable-experimental-concurrency
5+
// RUN: %target-swift-frontend -typecheck -I%t -verify %s -enable-experimental-concurrency
6+
7+
// REQUIRES: concurrency
8+
// REQUIRES: objc_interop
9+
10+
import def_objc_async
11+
import Foundation
12+
13+
class Derived: Base {
14+
}
15+
16+
extension Derived {
17+
override func foo(id: Int) async { }
18+
}

0 commit comments

Comments
 (0)