Skip to content

Commit 574aee0

Browse files
committed
[AST] Allow @preconcurrency attribute in inheritance clause
1 parent a48dc87 commit 574aee0

File tree

6 files changed

+53
-2
lines changed

6 files changed

+53
-2
lines changed

include/swift/AST/ASTBridging.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1161,6 +1161,7 @@ enum ENUM_EXTENSIBILITY_ATTR(closed) BridgedTypeAttrKind : size_t {
11611161
BridgedTypeAttrKind_Sendable,
11621162
BridgedTypeAttrKind_retroactive,
11631163
BridgedTypeAttrKind_unchecked,
1164+
BridgedTypeAttrKind_preconcurrency,
11641165
BridgedTypeAttrKind__local,
11651166
BridgedTypeAttrKind__noMetadata,
11661167
BridgedTypeAttrKind__opaqueReturnTypeOf,

include/swift/AST/Attr.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ TYPE_ATTR(async)
5757
TYPE_ATTR(Sendable)
5858
TYPE_ATTR(retroactive)
5959
TYPE_ATTR(unchecked)
60+
TYPE_ATTR(preconcurrency)
6061
TYPE_ATTR(_local)
6162
TYPE_ATTR(_noMetadata)
6263
TYPE_ATTR(_opaqueReturnTypeOf)

include/swift/AST/DiagnosticsSema.def

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5626,6 +5626,11 @@ ERROR(unchecked_not_inheritance_clause,none,
56265626
ERROR(unchecked_not_existential,none,
56275627
"'unchecked' attribute cannot apply to non-protocol type %0", (Type))
56285628

5629+
ERROR(preconcurrency_not_inheritance_clause,none,
5630+
"'preconcurrency' attribute only applies in inheritance clauses", ())
5631+
ERROR(preconcurrency_not_existential,none,
5632+
"'preconcurrency' attribute cannot apply to non-protocol type %0", (Type))
5633+
56295634
ERROR(redundant_any_in_existential,none,
56305635
"redundant 'any' in type %0",
56315636
(Type))

lib/ASTGen/Sources/ASTGen/Types.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -419,8 +419,8 @@ extension ASTGenVisitor {
419419
fallthrough
420420

421421
case .autoclosure, .escaping, .noescape, .noDerivative, .async,
422-
.sendable, .retroactive, .unchecked, ._local, ._noMetadata,
423-
.pack_owned, .pack_guaranteed, .pack_inout, .pack_out,
422+
.sendable, .retroactive, .unchecked, .preconcurrency, ._local,
423+
._noMetadata, .pack_owned, .pack_guaranteed, .pack_inout, .pack_out,
424424
.pseudogeneric, .yields, .yield_once, .yield_many, .thin, .thick,
425425
.count, .unimplementable:
426426
typeAttributes.addSimpleAttr(kind: typeAttrKind, atLoc: atLoc, attrLoc: attrLoc)

lib/Sema/TypeCheckType.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3250,6 +3250,25 @@ TypeResolver::resolveAttributedType(TypeAttributes &attrs, TypeRepr *repr,
32503250
attrs.clearAttribute(TAK_unchecked);
32513251
}
32523252

3253+
if (attrs.has(TAK_preconcurrency)) {
3254+
ty = resolveType(repr, options);
3255+
if (!ty || ty->hasError()) return ty;
3256+
3257+
if (!options.is(TypeResolverContext::Inherited) ||
3258+
getDeclContext()->getSelfProtocolDecl()) {
3259+
diagnoseInvalid(repr, attrs.getLoc(TAK_preconcurrency),
3260+
diag::preconcurrency_not_inheritance_clause);
3261+
ty = ErrorType::get(getASTContext());
3262+
} else if (!ty->isConstraintType()) {
3263+
diagnoseInvalid(repr, attrs.getLoc(TAK_preconcurrency),
3264+
diag::preconcurrency_not_existential, ty);
3265+
ty = ErrorType::get(getASTContext());
3266+
}
3267+
3268+
// Nothing to record in the type. Just clear the attribute.
3269+
attrs.clearAttribute(TAK_preconcurrency);
3270+
}
3271+
32533272
if (attrs.has(TAK_retroactive)) {
32543273
ty = resolveType(repr, options);
32553274
if (!ty || ty->hasError()) return ty;

test/Concurrency/predates_concurrency.swift

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,3 +249,28 @@ extension MainActorPreconcurrency: NotIsolated {
249249
}
250250
}
251251
}
252+
253+
do {
254+
class K {}
255+
256+
struct A : @preconcurrency Q {} // Ok
257+
struct B : @preconcurrency K {
258+
// expected-error@-1 {{'preconcurrency' attribute cannot apply to non-protocol type 'K'}}
259+
var x: @preconcurrency Int
260+
// expected-error@-1 {{'preconcurrency' attribute only applies in inheritance clauses}}
261+
}
262+
263+
typealias T = @preconcurrency Q
264+
// expected-error@-1 {{'preconcurrency' attribute only applies in inheritance clauses}}
265+
266+
func test(_: @preconcurrency K) {}
267+
// expected-error@-1 {{'preconcurrency' attribute only applies in inheritance clauses}}
268+
}
269+
270+
protocol InvalidUseOfPreconcurrencyAttr : @preconcurrency Q {
271+
// expected-error@-1 {{'preconcurrency' attribute only applies in inheritance clauses}}
272+
}
273+
274+
struct TestPreconcurrencyAttr {}
275+
extension TestPreconcurrencyAttr : @preconcurrency Q { // Ok
276+
}

0 commit comments

Comments
 (0)