Skip to content

Commit 91242dc

Browse files
committed
Merge remote-tracking branch 'origin/main' into rebranch
2 parents 378b6d4 + 3cf257f commit 91242dc

Some content is hidden

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

51 files changed

+553
-196
lines changed

docs/ABI/Mangling.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -556,13 +556,14 @@ Types
556556
C-TYPE is mangled according to the Itanium ABI, and prefixed with the length.
557557
Non-ASCII identifiers are preserved as-is; we do not use Punycode.
558558

559-
function-signature ::= params-type params-type async? throws? // results and parameters
559+
function-signature ::= params-type params-type async? concurrent? throws? // results and parameters
560560

561561
params-type ::= type 'z'? 'h'? // tuple in case of multiple parameters or a single parameter with a single tuple type
562562
// with optional inout convention, shared convention. parameters don't have labels,
563563
// they are mangled separately as part of the entity.
564564
params-type ::= empty-list // shortcut for no parameters
565565

566+
concurrent ::= 'J' // @concurrent on function types
566567
async ::= 'Y' // 'async' annotation on function types
567568
throws ::= 'K' // 'throws' annotation on function types
568569

include/swift/ABI/Metadata.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1637,6 +1637,7 @@ struct TargetFunctionTypeMetadata : public TargetMetadata<Runtime> {
16371637
}
16381638
bool isAsync() const { return Flags.isAsync(); }
16391639
bool isThrowing() const { return Flags.isThrowing(); }
1640+
bool isConcurrent() const { return Flags.isConcurrent(); }
16401641
bool hasParameterFlags() const { return Flags.hasParameterFlags(); }
16411642
bool isEscaping() const { return Flags.isEscaping(); }
16421643

include/swift/ABI/MetadataValues.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -779,6 +779,7 @@ class TargetFunctionTypeFlags {
779779
DifferentiableMask = 0x08000000U,
780780
LinearMask = 0x10000000U,
781781
AsyncMask = 0x20000000U,
782+
ConcurrentMask = 0x40000000U,
782783
};
783784
int_type Data;
784785

@@ -831,6 +832,13 @@ class TargetFunctionTypeFlags {
831832
(isEscaping ? EscapingMask : 0));
832833
}
833834

835+
constexpr TargetFunctionTypeFlags<int_type>
836+
withConcurrent(bool isConcurrent) const {
837+
return TargetFunctionTypeFlags<int_type>(
838+
(Data & ~ConcurrentMask) |
839+
(isConcurrent ? ConcurrentMask : 0));
840+
}
841+
834842
unsigned getNumParameters() const { return Data & NumParametersMask; }
835843

836844
FunctionMetadataConvention getConvention() const {
@@ -845,6 +853,10 @@ class TargetFunctionTypeFlags {
845853
return bool (Data & EscapingMask);
846854
}
847855

856+
bool isConcurrent() const {
857+
return bool (Data & ConcurrentMask);
858+
}
859+
848860
bool hasParameterFlags() const { return bool(Data & ParamFlagsMask); }
849861

850862
bool isDifferentiable() const {

include/swift/AST/Attr.def

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ TYPE_ATTR(escaping)
5454
TYPE_ATTR(differentiable)
5555
TYPE_ATTR(noDerivative)
5656
TYPE_ATTR(async)
57+
TYPE_ATTR(concurrent)
5758

5859
// SIL-specific attributes
5960
TYPE_ATTR(block_storage)
@@ -599,6 +600,12 @@ CONTEXTUAL_SIMPLE_DECL_ATTR(async, Async,
599600
APIBreakingToAdd | APIBreakingToRemove,
600601
106)
601602

603+
SIMPLE_DECL_ATTR(concurrent, Concurrent,
604+
OnFunc | OnConstructor | OnAccessor | ConcurrencyOnly |
605+
ABIStableToAdd | ABIStableToRemove |
606+
APIBreakingToAdd | APIBreakingToRemove,
607+
107)
608+
602609
#undef TYPE_ATTR
603610
#undef DECL_ATTR_ALIAS
604611
#undef CONTEXTUAL_DECL_ATTR_ALIAS

include/swift/AST/Decl.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5773,6 +5773,11 @@ class AbstractFunctionDecl : public GenericContext, public ValueDecl {
57735773
/// type of the function will be `async` as well.
57745774
bool hasAsync() const { return Bits.AbstractFunctionDecl.Async; }
57755775

5776+
/// Determine whether the given function is concurrent.
5777+
///
5778+
/// A function is concurrent if it has the @concurrent attribute.
5779+
bool isConcurrent() const;
5780+
57765781
/// Returns true if the function is a suitable 'async' context.
57775782
///
57785783
/// Functions that are an 'async' context can make calls to 'async' functions.

include/swift/AST/DiagnosticsSema.def

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3727,26 +3727,30 @@ NOTE(silence_debug_description_in_interpolation_segment_call,none,
37273727
"use 'String(describing:)' to silence this warning", ())
37283728

37293729
NOTE(noescape_parameter,none,
3730-
"parameter %0 is implicitly non-escaping",
3731-
(Identifier))
3730+
"parameter %1 is implicitly %select{non-escaping|non-concurrent}0",
3731+
(unsigned, Identifier))
37323732
NOTE(generic_parameters_always_escaping,none,
37333733
"generic parameters are always considered '@escaping'", ())
37343734

3735-
ERROR(passing_noescape_to_escaping,none,
3736-
"passing non-escaping parameter %0 to function expecting an @escaping closure",
3737-
(Identifier))
3735+
ERROR(passing_noattrfunc_to_attrfunc,none,
3736+
"passing %select{non-escaping|non-concurrent}0 parameter %1 to function "
3737+
"expecting %select{an @escaping|a @concurrent}0 closure",
3738+
(unsigned, Identifier))
37383739
ERROR(converting_noespace_param_to_generic_type,none,
37393740
"converting non-escaping parameter %0 to generic parameter %1 may allow it to escape",
37403741
(Identifier, Type))
3741-
ERROR(assigning_noescape_to_escaping,none,
3742-
"assigning non-escaping parameter %0 to an @escaping closure",
3743-
(Identifier))
3744-
ERROR(general_noescape_to_escaping,none,
3745-
"using non-escaping parameter %0 in a context expecting an @escaping closure",
3746-
(Identifier))
3747-
ERROR(converting_noescape_to_type,none,
3748-
"converting non-escaping value to %0 may allow it to escape",
3749-
(Type))
3742+
ERROR(assigning_noattrfunc_to_attrfunc,none,
3743+
"assigning %select{non-escaping|non-concurrent}0 parameter %1 to "
3744+
"%select{an @escaping|a @concurrent}0 closure",
3745+
(unsigned, Identifier))
3746+
ERROR(general_noattrfunc_to_attr,none,
3747+
"using %select{non-escaping|non-concurrent}0 parameter %1 in a context "
3748+
"expecting %select{an @escaping|a @concurrent}0 closure",
3749+
(unsigned, Identifier))
3750+
ERROR(converting_noattrfunc_to_type,none,
3751+
"converting %select{non-escaping|non-concurrent function}0 value to %1 "
3752+
"may %select{allow it to escape|introduce data races}0",
3753+
(unsigned, Type))
37503754

37513755
ERROR(capture_across_type_decl,none,
37523756
"%0 declaration cannot close over value %1 defined in outer scope",
@@ -4256,10 +4260,23 @@ WARNING(concurrent_access_local,none,
42564260
"local %0 %1 is unsafe to reference in code that may execute "
42574261
"concurrently",
42584262
(DescriptiveDeclKind, DeclName))
4259-
ERROR(actor_isolated_concurrent_access,none,
4260-
"actor-isolated %0 %1 is unsafe to reference in code "
4261-
"that may execute concurrently",
4263+
ERROR(actor_isolated_from_concurrent_closure,none,
4264+
"actor-isolated %0 %1 cannot be referenced from a concurrent closure",
4265+
(DescriptiveDeclKind, DeclName))
4266+
ERROR(actor_isolated_from_concurrent_function,none,
4267+
"actor-isolated %0 %1 cannot be referenced from a concurrent function",
4268+
(DescriptiveDeclKind, DeclName))
4269+
ERROR(actor_isolated_from_async_let,none,
4270+
"actor-isolated %0 %1 cannot be referenced from 'async let' initializer",
42624271
(DescriptiveDeclKind, DeclName))
4272+
ERROR(actor_isolated_from_escaping_closure,none,
4273+
"actor-isolated %0 %1 cannot be referenced from an '@escaping' closure",
4274+
(DescriptiveDeclKind, DeclName))
4275+
ERROR(local_function_executed_concurrently,none,
4276+
"concurrently-executed %0 %1 must be marked as '@concurrent'",
4277+
(DescriptiveDeclKind, DeclName))
4278+
NOTE(concurrent_access_here,none,
4279+
"access in concurrently-executed code here", ())
42634280
NOTE(actor_isolated_sync_func,none,
42644281
"calls to %0 %1 from outside of its actor context are "
42654282
"implicitly asynchronous",

include/swift/AST/ExtInfo.h

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -289,20 +289,21 @@ class ASTExtInfoBuilder {
289289
friend AnyFunctionType;
290290
friend ASTExtInfo;
291291

292-
// If bits are added or removed, then TypeBase::AnyFunctionTypeBits
292+
// If bits are added or removed, then TypeBase::NumAFTExtInfoBits
293293
// and NumMaskBits must be updated, and they must match.
294294
//
295-
// |representation|noEscape|async|throws|differentiability|
296-
// | 0 .. 3 | 4 | 5 | 6 | 7 .. 8 |
295+
// |representation|noEscape|concurrent|async|throws|differentiability|
296+
// | 0 .. 3 | 4 | 5 | 6 | 7 | 8 .. 9 |
297297
//
298298
enum : unsigned {
299299
RepresentationMask = 0xF << 0,
300300
NoEscapeMask = 1 << 4,
301-
AsyncMask = 1 << 5,
302-
ThrowsMask = 1 << 6,
303-
DifferentiabilityMaskOffset = 7,
301+
ConcurrentMask = 1 << 5,
302+
AsyncMask = 1 << 6,
303+
ThrowsMask = 1 << 7,
304+
DifferentiabilityMaskOffset = 8,
304305
DifferentiabilityMask = 0x3 << DifferentiabilityMaskOffset,
305-
NumMaskBits = 9
306+
NumMaskBits = 10
306307
};
307308

308309
unsigned bits; // Naturally sized for speed.
@@ -350,6 +351,8 @@ class ASTExtInfoBuilder {
350351

351352
constexpr bool isNoEscape() const { return bits & NoEscapeMask; }
352353

354+
constexpr bool isConcurrent() const { return bits & ConcurrentMask; }
355+
353356
constexpr bool isAsync() const { return bits & AsyncMask; }
354357

355358
constexpr bool isThrowing() const { return bits & ThrowsMask; }
@@ -407,6 +410,12 @@ class ASTExtInfoBuilder {
407410
clangTypeInfo);
408411
}
409412
LLVM_NODISCARD
413+
ASTExtInfoBuilder withConcurrent(bool concurrent = true) const {
414+
return ASTExtInfoBuilder(concurrent ? (bits | ConcurrentMask)
415+
: (bits & ~ConcurrentMask),
416+
clangTypeInfo);
417+
}
418+
LLVM_NODISCARD
410419
ASTExtInfoBuilder withAsync(bool async = true) const {
411420
return ASTExtInfoBuilder(async ? (bits | AsyncMask)
412421
: (bits & ~AsyncMask),
@@ -497,6 +506,8 @@ class ASTExtInfo {
497506

498507
constexpr bool isNoEscape() const { return builder.isNoEscape(); }
499508

509+
constexpr bool isConcurrent() const { return builder.isConcurrent(); }
510+
500511
constexpr bool isAsync() const { return builder.isAsync(); }
501512

502513
constexpr bool isThrowing() const { return builder.isThrowing(); }
@@ -529,6 +540,14 @@ class ASTExtInfo {
529540
return builder.withNoEscape(noEscape).build();
530541
}
531542

543+
/// Helper method for changing only the concurrent field.
544+
///
545+
/// Prefer using \c ASTExtInfoBuilder::withConcurrent for chaining.
546+
LLVM_NODISCARD
547+
ASTExtInfo withConcurrent(bool concurrent = true) const {
548+
return builder.withConcurrent(concurrent).build();
549+
}
550+
532551
/// Helper method for changing only the throws field.
533552
///
534553
/// Prefer using \c ASTExtInfoBuilder::withThrows for chaining.

include/swift/AST/TypeMatcher.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,9 @@ class TypeMatcher {
208208
if (firstFunc->isNoEscape() != secondFunc->isNoEscape())
209209
return mismatch(firstFunc.getPointer(), secondFunc, sugaredFirstType);
210210

211+
if (firstFunc->isConcurrent() != secondFunc->isConcurrent())
212+
return mismatch(firstFunc.getPointer(), secondFunc, sugaredFirstType);
213+
211214
auto sugaredFirstFunc = sugaredFirstType->castTo<AnyFunctionType>();
212215
if (firstFunc->getParams().size() != secondFunc->getParams().size())
213216
return mismatch(firstFunc.getPointer(), secondFunc, sugaredFirstFunc);

include/swift/AST/Types.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ class alignas(1 << TypeAlignInBits) TypeBase {
315315
}
316316

317317
protected:
318-
enum { NumAFTExtInfoBits = 9 };
318+
enum { NumAFTExtInfoBits = 10 };
319319
enum { NumSILExtInfoBits = 9 };
320320
union { uint64_t OpaqueBits;
321321

@@ -3145,6 +3145,10 @@ class AnyFunctionType : public TypeBase {
31453145
return getExtInfo().isNoEscape();
31463146
}
31473147

3148+
bool isConcurrent() const {
3149+
return getExtInfo().isConcurrent();
3150+
}
3151+
31483152
bool isAsync() const { return getExtInfo().isAsync(); }
31493153

31503154
bool isThrowing() const { return getExtInfo().isThrowing(); }

include/swift/Demangling/DemangleNodes.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ NODE(EnumCase)
8585
NODE(ErrorType)
8686
NODE(EscapingAutoClosureType)
8787
NODE(NoEscapeFunctionType)
88+
NODE(ConcurrentFunctionType)
8889
NODE(ExistentialMetatype)
8990
CONTEXT_NODE(ExplicitClosure)
9091
CONTEXT_NODE(Extension)

0 commit comments

Comments
 (0)