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.

0 commit comments

Comments
 (0)