Skip to content

Commit 0445e5a

Browse files
committed
[Parse] Implement parsing of @execution(...) decl attribute
1 parent 5c8f7ec commit 0445e5a

File tree

4 files changed

+57
-3
lines changed

4 files changed

+57
-3
lines changed

include/swift/AST/KnownIdentifiers.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,8 @@ IDENTIFIER(size)
332332
IDENTIFIER(speed)
333333
IDENTIFIER(unchecked)
334334
IDENTIFIER(unsafe)
335+
IDENTIFIER(concurrent)
336+
IDENTIFIER(caller)
335337

336338
// The singleton instance of TupleTypeDecl in the Builtin module
337339
IDENTIFIER(TheTupleType)

lib/Parse/ParseDecl.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2706,6 +2706,8 @@ ParserResult<LifetimeAttr> Parser::parseLifetimeAttribute(SourceLoc atLoc,
27062706
/* implicit */ false, lifetimeEntry.get()));
27072707
}
27082708

2709+
2710+
27092711
/// Parses a (possibly optional) argument for an attribute containing a single, arbitrary identifier.
27102712
///
27112713
/// \param P The parser object.
@@ -4022,6 +4024,21 @@ ParserStatus Parser::parseNewDeclAttribute(DeclAttributes &Attributes,
40224024
Attributes.add(Attr.get());
40234025
break;
40244026
}
4027+
4028+
case DeclAttrKind::Execution: {
4029+
auto behavior = parseSingleAttrOption<ExecutionKind>(
4030+
*this, Loc, AttrRange, AttrName, DK,
4031+
{{Context.Id_concurrent, ExecutionKind::Concurrent},
4032+
{Context.Id_caller, ExecutionKind::Caller}});
4033+
if (!behavior)
4034+
return makeParserSuccess();
4035+
4036+
if (!DiscardAttribute)
4037+
Attributes.add(new (Context) ExecutionAttr(AtLoc, AttrRange, *behavior,
4038+
/*Implicit*/ false));
4039+
4040+
break;
4041+
}
40254042
}
40264043

40274044
if (DuplicateAttribute) {
@@ -9729,7 +9746,7 @@ Parser::parseDeclSubscript(SourceLoc StaticLoc,
97299746
}
97309747
}
97319748
}
9732-
9749+
97339750
ParserStatus Status;
97349751
SourceLoc SubscriptLoc = consumeToken(tok::kw_subscript);
97359752

test/IDE/complete_decl_attribute_feature_requirement.swift

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
// REQUIRES: asserts
77

88
// RUN: %batch-code-completion -filecheck-additional-suffix _DISABLED
9-
// RUN: %batch-code-completion -filecheck-additional-suffix _ENABLED -enable-experimental-feature ABIAttribute
9+
// RUN: %batch-code-completion -filecheck-additional-suffix _ENABLED \
10+
// RUN: -enable-experimental-feature ABIAttribute \
11+
// RUN: -enable-experimental-feature NonIsolatedAsyncInheritsIsolationFromContext
1012

1113
// NOTE: Please do not include the ", N items" after "Begin completions". The
1214
// item count creates needless merge conflicts given that an "End completions"
@@ -16,14 +18,18 @@
1618

1719
// KEYWORD2: Begin completions
1820
// KEYWORD2_ENABLED-DAG: Keyword/None: abi[#Func Attribute#]; name=abi
21+
// KEYWORD2_ENABLED-DAG: Keyword/None: execution[#Func Attribute#]; name=execution
1922
// KEYWORD2_DISABLED-NOT: Keyword/None: abi[#{{.*}} Attribute#]; name=abi
23+
// KEYWORD2_DISABLED-NOT: Keyword/None: execution[#{{.*}} Attribute#]; name=execution
2024
// KEYWORD2: End completions
2125

2226
@#^KEYWORD3^# class C {}
2327

2428
// KEYWORD3: Begin completions
2529
// KEYWORD3_ENABLED-NOT: Keyword/None: abi[#{{.*}} Attribute#]; name=abi
30+
// KEYWORD3_ENABLED-NOT: Keyword/None: execution[#{{.*}} Attribute#]; name=execution
2631
// KEYWORD3_DISABLED-NOT: Keyword/None: abi[#{{.*}} Attribute#]; name=abi
32+
// KEYWORD3_DISABLED-NOT: Keyword/None: execution[#{{.*}} Attribute#]; name=execution
2733
// KEYWORD3: End completions
2834

2935
@#^KEYWORD3_2?check=KEYWORD3^#IB class C2 {}
@@ -32,46 +38,60 @@
3238
@#^KEYWORD4^# enum E {}
3339
// KEYWORD4: Begin completions
3440
// KEYWORD4_ENABLED-NOT: Keyword/None: abi[#{{.*}} Attribute#]; name=abi
41+
// KEYWORD4_ENABLED-NOT: Keyword/None: execution[#{{.*}} Attribute#]; name=execution
3542
// KEYWORD4_DISABLED-NOT: Keyword/None: abi[#{{.*}} Attribute#]; name=abi
43+
// KEYWORD4_DISABLED-NOT: Keyword/None: execution[#{{.*}} Attribute#]; name=execution
3644
// KEYWORD4: End completions
3745

3846
@#^KEYWORD5^# struct S{}
3947
// KEYWORD5: Begin completions
4048
// KEYWORD5_ENABLED-NOT: Keyword/None: abi[#{{.*}} Attribute#]; name=abi
49+
// KEYWORD5_ENABLED-NOT: Keyword/None: execution[#{{.*}} Attribute#]; name=execution
4150
// KEYWORD5_DISABLED-NOT: Keyword/None: abi[#{{.*}} Attribute#]; name=abi
51+
// KEYWORD5_DISABLED-NOT: Keyword/None: execution[#{{.*}} Attribute#]; name=execution
4252
// KEYWORD5: End completions
4353

4454
@#^ON_GLOBALVAR^# var globalVar
4555
// ON_GLOBALVAR: Begin completions
4656
// ON_GLOBALVAR_ENABLED-DAG: Keyword/None: abi[#Var Attribute#]; name=abi
57+
// ON_GLOBALVAR_ENABLED-NOT: Keyword/None: execution[#{{.*}} Attribute#]; name=execution
4758
// ON_GLOBALVAR_DISABLED-NOT: Keyword/None: abi[#{{.*}} Attribute#]; name=abi
59+
// ON_GLOBALVAR_DISABLED-NOT: Keyword/None: execution[#{{.*}} Attribute#]; name=execution
4860
// ON_GLOBALVAR: End completions
4961

5062
struct _S {
5163
@#^ON_INIT^# init()
5264
// ON_INIT: Begin completions
5365
// ON_INIT_ENABLED-DAG: Keyword/None: abi[#Constructor Attribute#]; name=abi
66+
// ON_INIT_ENABLED-NOT: Keyword/None: execution[#{{.*}} Attribute#]; name=execution
5467
// ON_INIT_DISABLED-NOT: Keyword/None: abi[#{{.*}} Attribute#]; name=abi
68+
// ON_INIT_DISABLED-NOT: Keyword/None: execution[#{{.*}} Attribute#]; name=execution
5569
// ON_INIT: End completions
5670

5771
@#^ON_PROPERTY^# var foo
5872
// ON_PROPERTY: Begin completions
5973
// ON_PROPERTY_ENABLED-DAG: Keyword/None: abi[#Var Attribute#]; name=abi
74+
// ON_PROPERTY_ENABLED-NOT: Keyword/None: execution[#{{.*}} Attribute#]; name=execution
6075
// ON_PROPERTY_DISABLED-NOT: Keyword/None: abi[#{{.*}} Attribute#]; name=abi
76+
// ON_PROPERTY_DISABLED-NOT: Keyword/None: execution[#{{.*}} Attribute#]; name=execution
6177
// ON_PROPERTY: End completions
6278

6379
@#^ON_METHOD^# private
6480
func foo()
6581
// ON_METHOD: Begin completions
6682
// ON_METHOD_ENABLED-DAG: Keyword/None: abi[#Func Attribute#]; name=abi
83+
// ON_METHOD_ENABLED-DAG: Keyword/None: execution[#Func Attribute#]; name=execution
6784
// ON_METHOD_DISABLED-NOT: Keyword/None: abi[#{{.*}} Attribute#]; name=abi
85+
// ON_METHOD_DISABLED-NOT: Keyword/None: execution[#{{.*}} Attribute#]; name=execution
6886
// ON_METHOD: End completions
6987

7088

7189
func bar(@#^ON_PARAM_1?check=ON_PARAM^#)
7290
// ON_PARAM: Begin completions
7391
// ON_PARAM_ENABLED-NOT: Keyword/None: abi[#{{.*}} Attribute#]; name=abi
92+
// ON_PARAM_ENABLED-NOT: Keyword/None: execution[#{{.*}} Attribute#]; name=execution
7493
// ON_PARAM_DISABLED-NOT: Keyword/None: abi[#{{.*}} Attribute#]; name=abi
94+
// ON_PARAM_DISABLED-NOT: Keyword/None: execution[#{{.*}} Attribute#]; name=execution
7595
// ON_PARAM: End completions
7696

7797
func bar(
@@ -94,7 +114,9 @@ struct _S {
94114
@#^ON_MEMBER_LAST^#
95115
// ON_MEMBER_LAST: Begin completions
96116
// ON_MEMBER_LAST_ENABLED-DAG: Keyword/None: abi[#Declaration Attribute#]; name=abi
117+
// ON_MEMBER_LAST_ENABLED-DAG: Keyword/None: execution[#Declaration Attribute#]; name=execution
97118
// ON_MEMBER_LAST_DISABLED-NOT: Keyword/None: abi[#{{.*}} Attribute#]; name=abi
119+
// ON_MEMBER_LAST_DISABLED-NOT: Keyword/None: execution[#{{.*}} Attribute#]; name=execution
98120
// ON_MEMBER_LAST: End completions
99121
}
100122

@@ -106,7 +128,9 @@ func takeClosure(_: () -> Void) {
106128
// IN_CLOSURE: Begin completions
107129
// FIXME: Not valid in this position (but CompletionLookup can't tell that)
108130
// IN_CLOSURE_ENABLED-DAG: Keyword/None: abi[#Declaration Attribute#]; name=abi
131+
// IN_CLOSURE_ENABLED-DAG: Keyword/None: execution[#Declaration Attribute#]; name=execution
109132
// IN_CLOSURE_DISABLED-NOT: Keyword/None: abi[#{{.*}} Attribute#]; name=abi
133+
// IN_CLOSURE_DISABLED-NOT: Keyword/None: execution[#{{.*}} Attribute#]; name=execution
110134
// IN_CLOSURE: End completions
111135

112136
@#^KEYWORD_INDEPENDENT_1?check=KEYWORD_LAST^#
@@ -122,5 +146,7 @@ func dummy2() {}
122146

123147
// KEYWORD_LAST: Begin completions
124148
// KEYWORD_LAST_ENABLED-DAG: Keyword/None: abi[#Declaration Attribute#]; name=abi
149+
// KEYWORD_LAST_ENABLED-DAG: Keyword/None: execution[#Declaration Attribute#]; name=execution
125150
// KEYWORD_LAST_DISABLED-NOT: Keyword/None: abi[#Declaration Attribute#]; name=abi
151+
// KEYWORD_LAST_DISABLED-NOT: Keyword/None: execution[#Declaration Attribute#]; name=execution
126152
// KEYWORD_LAST: End completions

test/attr/feature_requirement.swift

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// RUN: %target-typecheck-verify-swift -parse-as-library -disable-experimental-parser-round-trip -verify-additional-prefix disabled-
2-
// RUN: %target-typecheck-verify-swift -parse-as-library -verify-additional-prefix enabled- -enable-experimental-feature ABIAttribute
2+
// RUN: %target-typecheck-verify-swift -parse-as-library -verify-additional-prefix enabled- -enable-experimental-feature ABIAttribute -enable-experimental-feature NonIsolatedAsyncInheritsIsolationFromContext
33

44
// REQUIRES: asserts
55

@@ -14,3 +14,12 @@ func fn() {} // expected-disabled-error@-1 {{'abi' attribute is only valid when
1414
#else
1515
#error("doesn't have @abi") // expected-disabled-error {{doesn't have @abi}}
1616
#endif
17+
18+
@execution(concurrent) func testExecutionAttr() async {}
19+
// expected-disabled-error@-1 {{'execution(concurrent)' attribute is only valid when experimental feature NonIsolatedAsyncInheritsIsolationFromContext is enabled}}
20+
21+
#if hasAttribute(execution)
22+
#error("does have @execution") // expected-enabled-error {{does have @execution}}
23+
#else
24+
#error("doesn't have @execution") // expected-disabled-error {{doesn't have @execution}}
25+
#endif

0 commit comments

Comments
 (0)