Skip to content

Commit 60807a7

Browse files
authored
Merge pull request #71433 from rjmccall/isolated-any-typechecking
Experimental type-checking support for `@isolated(any)` function types.
2 parents 1795f7f + 2f8a33c commit 60807a7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+759
-94
lines changed

docs/ABI/Mangling.rst

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -643,7 +643,7 @@ Types
643643
C-TYPE is mangled according to the Itanium ABI, and prefixed with the length.
644644
Non-ASCII identifiers are preserved as-is; we do not use Punycode.
645645

646-
function-signature ::= params-type params-type async? sendable? throws? differentiable? global-actor? // results and parameters
646+
function-signature ::= params-type params-type async? sendable? throws? differentiable? function-isolation? // results and parameters
647647

648648
params-type ::= type 'z'? 'h'? // tuple in case of multiple parameters or a single parameter with a single tuple type
649649
// with optional inout convention, shared convention. parameters don't have labels,
@@ -653,11 +653,12 @@ Types
653653
#if SWIFT_RUNTIME_VERSION >= 5.5
654654
async ::= 'Ya' // 'async' annotation on function types
655655
sendable ::= 'Yb' // @Sendable on function types
656-
global-actor :: = type 'Yc' // Global actor on function type
656+
function-isolation ::= type 'Yc' // Global actor on function type
657657
#endif
658658
throws ::= 'K' // 'throws' annotation on function types
659659
#if SWIFT_RUNTIME_VERSION >= 5.11
660660
throws ::= type 'YK' // 'throws(type)' annotation on function types
661+
function-isolation ::= type 'YA' // @isolated(any) on function type
661662
#endif
662663
differentiable ::= 'Yjf' // @differentiable(_forward) on function type
663664
differentiable ::= 'Yjr' // @differentiable(reverse) on function type

include/swift/ABI/MetadataValues.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1183,6 +1183,10 @@ template <typename int_type>
11831183
class TargetExtendedFunctionTypeFlags {
11841184
enum : int_type {
11851185
TypedThrowsMask = 0x00000001U,
1186+
IsolationMask = 0x0000000EU, // three bits
1187+
1188+
// Values for the enumerated isolation kinds
1189+
IsolatedAny = 0x00000002U,
11861190
};
11871191
int_type Data;
11881192

@@ -1196,8 +1200,23 @@ class TargetExtendedFunctionTypeFlags {
11961200
(Data & ~TypedThrowsMask) | (typedThrows ? TypedThrowsMask : 0));
11971201
}
11981202

1203+
const TargetExtendedFunctionTypeFlags<int_type>
1204+
withNonIsolated() const {
1205+
return TargetExtendedFunctionTypeFlags<int_type>(Data & ~IsolationMask);
1206+
}
1207+
1208+
const TargetExtendedFunctionTypeFlags<int_type>
1209+
withIsolatedAny() const {
1210+
return TargetExtendedFunctionTypeFlags<int_type>(
1211+
(Data & ~IsolationMask) | IsolatedAny);
1212+
}
1213+
11991214
bool isTypedThrows() const { return bool(Data & TypedThrowsMask); }
12001215

1216+
bool isIsolatedAny() const {
1217+
return (Data & IsolationMask) == IsolatedAny;
1218+
}
1219+
12011220
int_type getIntValue() const {
12021221
return Data;
12031222
}

include/swift/AST/ASTBridging.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1466,6 +1466,17 @@ BridgedTypeAttribute BridgedTypeAttribute_createSimple(
14661466
BridgedASTContext cContext, BridgedTypeAttrKind cKind,
14671467
BridgedSourceLoc cAtLoc, BridgedSourceLoc cNameLoc);
14681468

1469+
enum ENUM_EXTENSIBILITY_ATTR(closed) BridgedIsolatedTypeAttrIsolationKind {
1470+
BridgedIsolatedTypeAttrIsolationKind_DynamicIsolation,
1471+
};
1472+
1473+
SWIFT_NAME("BridgedTypeAttribute.createIsolated(_:atLoc:nameLoc:lpLoc:isolationKindLoc:isolationKind:rpLoc:)")
1474+
BridgedTypeAttribute BridgedTypeAttribute_createIsolated(
1475+
BridgedASTContext cContext,
1476+
BridgedSourceLoc cAtLoc, BridgedSourceLoc cNameLoc,
1477+
BridgedSourceLoc cLPLoc, BridgedSourceLoc cIsolationLoc,
1478+
BridgedIsolatedTypeAttrIsolationKind cIsolation, BridgedSourceLoc cRPLoc);
1479+
14691480
//===----------------------------------------------------------------------===//
14701481
// MARK: TypeReprs
14711482
//===----------------------------------------------------------------------===//

include/swift/AST/ActorIsolation.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ class ActorIsolation {
6666
/// The declaration is isolated to a global actor. It can refer to other
6767
/// entities with the same global actor.
6868
GlobalActor,
69+
/// The actor isolation iss statically erased, as for a call to
70+
/// an isolated(any) function. This is not possible for declarations.
71+
Erased,
6972
};
7073

7174
private:
@@ -129,6 +132,10 @@ class ActorIsolation {
129132
return ActorIsolation(GlobalActor, globalActor);
130133
}
131134

135+
static ActorIsolation forErased() {
136+
return ActorIsolation(Erased);
137+
}
138+
132139
static std::optional<ActorIsolation> forSILString(StringRef string) {
133140
auto kind =
134141
llvm::StringSwitch<std::optional<ActorIsolation::Kind>>(string)
@@ -174,6 +181,7 @@ class ActorIsolation {
174181
switch (getKind()) {
175182
case ActorInstance:
176183
case GlobalActor:
184+
case Erased:
177185
return true;
178186

179187
case Unspecified:
@@ -259,6 +267,9 @@ class ActorIsolation {
259267
case GlobalActor:
260268
os << "global_actor";
261269
return;
270+
case Erased:
271+
os << "erased";
272+
return;
262273
}
263274
llvm_unreachable("Covered switch isn't covered?!");
264275
}

include/swift/AST/Attr.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2936,6 +2936,10 @@ class alignas(1 << AttrAlignInBits) TypeAttribute
29362936
: NumPadBits,
29372937
Index : 32
29382938
);
2939+
2940+
SWIFT_INLINE_BITFIELD_FULL(IsolatedTypeAttr, TypeAttribute, 8,
2941+
Kind : 8
2942+
);
29392943
} Bits;
29402944
// clang-format on
29412945

@@ -3161,6 +3165,39 @@ class PackElementTypeAttr
31613165
void printImpl(ASTPrinter &printer, const PrintOptions &options) const;
31623166
};
31633167

3168+
/// The @isolated function type attribute, not to be confused with the
3169+
/// `isolated` declaration modifier (IsolatedAttr) or the `isolated`
3170+
/// parameter specifier (IsolatedTypeRepr).
3171+
class IsolatedTypeAttr : public SimpleTypeAttrWithArgs<TypeAttrKind::Isolated> {
3172+
public:
3173+
enum class IsolationKind : uint8_t {
3174+
Dynamic
3175+
};
3176+
3177+
private:
3178+
SourceLoc KindLoc;
3179+
3180+
public:
3181+
IsolatedTypeAttr(SourceLoc atLoc, SourceLoc kwLoc, SourceRange parensRange,
3182+
Located<IsolationKind> kind)
3183+
: SimpleTypeAttr(atLoc, kwLoc, parensRange), KindLoc(kind.Loc) {
3184+
Bits.IsolatedTypeAttr.Kind = uint8_t(kind.Item);
3185+
}
3186+
3187+
IsolationKind getIsolationKind() const {
3188+
return IsolationKind(Bits.IsolatedTypeAttr.Kind);
3189+
}
3190+
SourceLoc getIsolationKindLoc() const {
3191+
return KindLoc;
3192+
}
3193+
const char *getIsolationKindName() const {
3194+
return getIsolationKindName(getIsolationKind());
3195+
}
3196+
static const char *getIsolationKindName(IsolationKind kind);
3197+
3198+
void printImpl(ASTPrinter &printer, const PrintOptions &options) const;
3199+
};
3200+
31643201
using TypeOrCustomAttr =
31653202
llvm::PointerUnion<CustomAttr*, TypeAttribute*>;
31663203

include/swift/AST/DiagnosticsParse.def

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1711,6 +1711,14 @@ ERROR(expected_rparen_after_thrown_error_type,none,
17111711
ERROR(rethrows_with_thrown_error,none,
17121712
"'rethrows' cannot be combined with a specific thrown error type", ())
17131713

1714+
ERROR(attr_isolated_expected_lparen,none,
1715+
"expected '(' after '@isolated'; did you mean the 'isolated' modifier?",
1716+
())
1717+
ERROR(attr_isolated_expected_rparen,none,
1718+
"expected ')' after isolation kind", ())
1719+
ERROR(attr_isolated_expected_kind,none,
1720+
"expected 'any' as the isolation kind", ())
1721+
17141722
ERROR(attr_private_import_expected_rparen,none,
17151723
"expected ')' after function name for @_private", ())
17161724
ERROR(attr_private_import_expected_sourcefile, none,

include/swift/AST/DiagnosticsSema.def

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5548,6 +5548,14 @@ ERROR(isolated_parameter_global_actor_type,none,
55485548
ERROR(isolated_parameter_combined_nonisolated,none,
55495549
"%0 with 'isolated' parameter cannot be 'nonisolated'",
55505550
(DescriptiveDeclKind))
5551+
ERROR(isolated_parameter_isolated_attr_type,none,
5552+
"function with 'isolated' parameter cannot also be '@isolated(%0)'",
5553+
(StringRef))
5554+
ERROR(isolated_any_experimental,none,
5555+
"attribute requires '-enable-experimental-feature IsolatedAny'", ())
5556+
ERROR(isolated_attr_global_actor_type,none,
5557+
"function type cannot have both a global actor and '@isolated(%0)'",
5558+
(StringRef))
55515559
ERROR(isolation_macro_experimental,none,
55525560
"#isolation macro is experimental", ())
55535561

@@ -6001,6 +6009,9 @@ ERROR(generic_function_type,none,
60016009
"function values cannot be generic", ())
60026010
ERROR(unsupported_convention,none,
60036011
"convention '%0' not supported", (StringRef))
6012+
ERROR(invalid_isolated_and_convention_attributes,none,
6013+
"'@convention(%0)' attribute is not allowed on '@isolated' types",
6014+
(StringRef))
60046015
ERROR(unreferenced_generic_parameter,NoUsage,
60056016
"generic parameter '%0' is not used in function signature", (StringRef))
60066017
ERROR(unexpected_ctype_for_non_c_convention,none,

include/swift/AST/ExtInfo.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ class FunctionTypeIsolation {
6262
/// the parameter list.
6363
Parameter,
6464

65-
/// The function is dynamically isolated.
66-
Dynamic,
65+
/// The function's isolation is statically erased with @isolated(any).
66+
Erased,
6767
};
6868

6969
static constexpr size_t NumBits = 3; // future-proof this slightly
@@ -85,8 +85,8 @@ class FunctionTypeIsolation {
8585
static FunctionTypeIsolation forParameter() {
8686
return { Kind::Parameter };
8787
}
88-
static FunctionTypeIsolation forDynamic() {
89-
return { Kind::Dynamic };
88+
static FunctionTypeIsolation forErased() {
89+
return { Kind::Erased };
9090
}
9191

9292
Kind getKind() const { return value.getInt(); }
@@ -103,8 +103,8 @@ class FunctionTypeIsolation {
103103
bool isParameter() const {
104104
return getKind() == Kind::Parameter;
105105
}
106-
bool isDynamic() const {
107-
return getKind() == Kind::Dynamic;
106+
bool isErased() const {
107+
return getKind() == Kind::Erased;
108108
}
109109

110110
// The opaque accessors below are just for the benefit of ExtInfoBuilder,
@@ -543,8 +543,8 @@ class ASTExtInfoBuilder {
543543
return FunctionTypeIsolation::Kind(
544544
(bits & IsolationMask) >> IsolationMaskOffset);
545545
}
546-
bool isDynamicallyIsolated() const {
547-
return getIsolationKind() == FunctionTypeIsolation::Kind::Dynamic;
546+
bool isIsolationStaticallyErased() const {
547+
return getIsolationKind() == FunctionTypeIsolation::Kind::Erased;
548548
}
549549
static bool hasGlobalActorFromBits(unsigned bits) {
550550
return getIsolationKindFromBits(bits)

include/swift/AST/TypeAttr.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ SIMPLE_TYPE_ATTR(preconcurrency, Preconcurrency)
6565
SIMPLE_TYPE_ATTR(_local, Local)
6666
SIMPLE_TYPE_ATTR(_noMetadata, NoMetadata)
6767
TYPE_ATTR(_opaqueReturnTypeOf, OpaqueReturnTypeOf)
68+
TYPE_ATTR(isolated, Isolated)
6869

6970
// SIL-specific attributes
7071
SIMPLE_SIL_TYPE_ATTR(block_storage, BlockStorage)

include/swift/AST/Types.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3444,9 +3444,6 @@ class AnyFunctionType : public TypeBase {
34443444
return getExtInfo().getIsolation();
34453445
return FunctionTypeIsolation::forNonIsolated();
34463446
}
3447-
bool isDynamicallyIsolated() const {
3448-
return getIsolation().isDynamic();
3449-
}
34503447

34513448
/// Retrieve the "effective" thrown interface type, or llvm::None if
34523449
/// this function cannot throw.

include/swift/Basic/Features.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,9 @@ EXPERIMENTAL_FEATURE(DynamicActorIsolation, false)
276276
// Allow for `switch` of noncopyable values to be borrowing or consuming.
277277
EXPERIMENTAL_FEATURE(BorrowingSwitch, true)
278278

279+
// Enable isolated(any) attribute on function types.
280+
EXPERIMENTAL_FEATURE(IsolatedAny, false)
281+
279282
#undef EXPERIMENTAL_FEATURE_EXCLUDED_FROM_MODULE_INTERFACE
280283
#undef EXPERIMENTAL_FEATURE
281284
#undef UPCOMING_FEATURE

include/swift/Demangling/DemangleNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ NODE(InfixOperator)
148148
CONTEXT_NODE(Initializer)
149149
CONTEXT_NODE(InitAccessor)
150150
NODE(Isolated)
151+
NODE(IsolatedAnyFunctionType)
151152
NODE(KeyPathGetterThunkHelper)
152153
NODE(KeyPathSetterThunkHelper)
153154
NODE(KeyPathEqualsThunkHelper)

include/swift/Demangling/TypeDecoder.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -846,10 +846,11 @@ class TypeDecoder {
846846

847847
globalActorType = globalActorResult.getType();
848848
++firstChildIdx;
849+
} else if (Node->getChild(firstChildIdx)->getKind() ==
850+
NodeKind::IsolatedAnyFunctionType) {
851+
extFlags = extFlags.withIsolatedAny();
849852
}
850853

851-
// FIXME: other kinds of isolation
852-
853854
FunctionMetadataDifferentiabilityKind diffKind;
854855
if (Node->getChild(firstChildIdx)->getKind() ==
855856
NodeKind::DifferentiableFunctionType) {

include/swift/RemoteInspection/TypeRef.h

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -483,12 +483,14 @@ class FunctionTypeRef final : public TypeRef {
483483
std::vector<Param> Parameters;
484484
const TypeRef *Result;
485485
FunctionTypeFlags Flags;
486+
ExtendedFunctionTypeFlags ExtFlags;
486487
FunctionMetadataDifferentiabilityKind DifferentiabilityKind;
487488
const TypeRef *GlobalActor;
488489
const TypeRef *ThrownError;
489490

490491
static TypeRefID Profile(const std::vector<Param> &Parameters,
491492
const TypeRef *Result, FunctionTypeFlags Flags,
493+
ExtendedFunctionTypeFlags ExtFlags,
492494
FunctionMetadataDifferentiabilityKind DiffKind,
493495
const TypeRef *GlobalActor,
494496
const TypeRef *ThrownError) {
@@ -500,6 +502,7 @@ class FunctionTypeRef final : public TypeRef {
500502
}
501503
ID.addPointer(Result);
502504
ID.addInteger(static_cast<uint64_t>(Flags.getIntValue()));
505+
ID.addInteger(static_cast<uint64_t>(ExtFlags.getIntValue()));
503506
ID.addInteger(static_cast<uint64_t>(DiffKind.getIntValue()));
504507
ID.addPointer(GlobalActor);
505508
ID.addPointer(ThrownError);
@@ -510,21 +513,23 @@ class FunctionTypeRef final : public TypeRef {
510513
public:
511514
FunctionTypeRef(std::vector<Param> Params, const TypeRef *Result,
512515
FunctionTypeFlags Flags,
516+
ExtendedFunctionTypeFlags ExtFlags,
513517
FunctionMetadataDifferentiabilityKind DiffKind,
514518
const TypeRef *GlobalActor,
515519
const TypeRef *ThrownError)
516520
: TypeRef(TypeRefKind::Function), Parameters(Params), Result(Result),
517-
Flags(Flags), DifferentiabilityKind(DiffKind),
521+
Flags(Flags), ExtFlags(ExtFlags), DifferentiabilityKind(DiffKind),
518522
GlobalActor(GlobalActor), ThrownError(ThrownError) {}
519523

520524
template <typename Allocator>
521525
static const FunctionTypeRef *create(
522526
Allocator &A, std::vector<Param> Params, const TypeRef *Result,
523-
FunctionTypeFlags Flags, FunctionMetadataDifferentiabilityKind DiffKind,
527+
FunctionTypeFlags Flags, ExtendedFunctionTypeFlags ExtFlags,
528+
FunctionMetadataDifferentiabilityKind DiffKind,
524529
const TypeRef *GlobalActor, const TypeRef *ThrownError) {
525530
FIND_OR_CREATE_TYPEREF(
526-
A, FunctionTypeRef, Params, Result, Flags, DiffKind, GlobalActor,
527-
ThrownError);
531+
A, FunctionTypeRef, Params, Result, Flags, ExtFlags, DiffKind,
532+
GlobalActor, ThrownError);
528533
}
529534

530535
const std::vector<Param> &getParameters() const { return Parameters; };
@@ -537,6 +542,10 @@ class FunctionTypeRef final : public TypeRef {
537542
return Flags;
538543
}
539544

545+
ExtendedFunctionTypeFlags getExtFlags() const {
546+
return ExtFlags;
547+
}
548+
540549
FunctionMetadataDifferentiabilityKind getDifferentiabilityKind() const {
541550
return DifferentiabilityKind;
542551
}

include/swift/RemoteInspection/TypeRefBuilder.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1125,8 +1125,8 @@ class TypeRefBuilder {
11251125
ExtendedFunctionTypeFlags extFlags,
11261126
FunctionMetadataDifferentiabilityKind diffKind,
11271127
const TypeRef *globalActor, const TypeRef *thrownError) {
1128-
return FunctionTypeRef::create(*this, params, result, flags, diffKind,
1129-
globalActor, thrownError);
1128+
return FunctionTypeRef::create(*this, params, result, flags, extFlags,
1129+
diffKind, globalActor, thrownError);
11301130
}
11311131

11321132
const FunctionTypeRef *createImplFunctionType(
@@ -1139,6 +1139,7 @@ class TypeRefBuilder {
11391139
// reflection as capture types. For the reflection library's
11401140
// purposes, the only part that matters is the convention.
11411141
FunctionTypeFlags funcFlags;
1142+
ExtendedFunctionTypeFlags extFuncFlags;
11421143
switch (flags.getRepresentation()) {
11431144
case Demangle::ImplFunctionRepresentation::Thick:
11441145
case Demangle::ImplFunctionRepresentation::Closure:
@@ -1183,8 +1184,8 @@ class TypeRefBuilder {
11831184
}
11841185

11851186
auto result = createTupleType({}, llvm::ArrayRef<llvm::StringRef>());
1186-
return FunctionTypeRef::create(*this, {}, result, funcFlags, diffKind,
1187-
nullptr, nullptr);
1187+
return FunctionTypeRef::create(*this, {}, result, funcFlags, extFuncFlags,
1188+
diffKind, nullptr, nullptr);
11881189
}
11891190

11901191
BuiltType createProtocolTypeFromDecl(BuiltProtocolDecl protocol) {

0 commit comments

Comments
 (0)