Skip to content

Commit c6eb493

Browse files
committed
[AST][Sema] Implement '@apex' precedence group attribute
1 parent 94f252a commit c6eb493

File tree

9 files changed

+66
-11
lines changed

9 files changed

+66
-11
lines changed

include/swift/AST/Attr.def

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information
@@ -630,6 +630,11 @@ DECL_ATTR(hasAsyncAlternative, HasAsyncAlternative,
630630
APIStableToAdd | APIStableToRemove,
631631
111)
632632

633+
SIMPLE_DECL_ATTR(apex, Apex,
634+
OnPrecedenceGroup |
635+
ABIStableToAdd | ABIStableToRemove | APIBreakingToAdd | APIBreakingToRemove,
636+
112)
637+
633638
#undef TYPE_ATTR
634639
#undef DECL_ATTR_ALIAS
635640
#undef CONTEXTUAL_DECL_ATTR_ALIAS

include/swift/AST/Decl.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information
@@ -6995,6 +6995,10 @@ class PrecedenceGroupDecl : public Decl {
69956995
return { getLowerThanBuffer(), NumLowerThan };
69966996
}
69976997

6998+
bool isApex() const {
6999+
return getAttrs().hasAttribute<ApexAttr>();
7000+
}
7001+
69987002
static bool classof(const Decl *D) {
69997003
return D->getKind() == DeclKind::PrecedenceGroup;
70007004
}

include/swift/AST/DiagnosticsSema.def

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information
@@ -976,6 +976,9 @@ NOTE(previous_precedence_group_decl,none,
976976
"previous precedence group declaration here", ())
977977
NOTE(circular_reference_through_precedence_group, none,
978978
"through reference to precedence group %0 here", (Identifier))
979+
ERROR(precedence_group_higher_than_apex,none,
980+
"precedence group cannot be given higher precedence than '@apex' group",
981+
())
979982

980983
//------------------------------------------------------------------------------
981984
// MARK: Expression Type Checking Errors
@@ -3381,7 +3384,11 @@ ERROR(construct_protocol_by_name,none,
33813384

33823385
// Operators
33833386
ERROR(unknown_binop,none,
3384-
"operator is not a known binary operator", ())
3387+
"operator is not a known binary operator", ())
3388+
ERROR(unordered_adjacent_unary_operator,none,
3389+
"operator in precedence group %0 and adjacent unary operator have"
3390+
"undefined relative precedence; use grouping parentheses",
3391+
(Identifier))
33853392
ERROR(non_associative_adjacent_operators,none,
33863393
"adjacent operators are in non-associative precedence group %0",
33873394
(Identifier))

lib/Sema/TypeCheckAttr.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information
@@ -99,6 +99,7 @@ class AttributeChecker : public AttributeVisitor<AttributeChecker> {
9999

100100
#define IGNORED_ATTR(X) void visit##X##Attr(X##Attr *) {}
101101
IGNORED_ATTR(AlwaysEmitIntoClient)
102+
IGNORED_ATTR(Apex)
102103
IGNORED_ATTR(HasInitialValue)
103104
IGNORED_ATTR(ClangImporterSynthesizedType)
104105
IGNORED_ATTR(Convenience)

lib/Sema/TypeCheckDecl.cpp

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information
@@ -1450,8 +1450,19 @@ void swift::validatePrecedenceGroup(PrecedenceGroupDecl *PGD) {
14501450
continue;
14511451

14521452
// TODO: Requestify the lookup of a relation's group.
1453-
rel.Group = lookupPrecedenceGroupForRelation(
1453+
auto *group = lookupPrecedenceGroupForRelation(
14541454
dc, rel, PrecedenceGroupDescriptor::HigherThan);
1455+
rel.Group = group;
1456+
1457+
if (group && group->isApex()) {
1458+
if (!PGD->isInvalid()) {
1459+
Diags.diagnose(rel.NameLoc, diag::precedence_group_higher_than_apex);
1460+
Diags.diagnose(group->getNameLoc(), diag::kind_declared_here,
1461+
DescriptiveDeclKind::PrecedenceGroup);
1462+
}
1463+
PGD->setInvalid();
1464+
}
1465+
14551466
if (rel.Group) {
14561467
addedHigherThan = true;
14571468
} else {
@@ -1474,6 +1485,13 @@ void swift::validatePrecedenceGroup(PrecedenceGroupDecl *PGD) {
14741485
if (!group)
14751486
group = dc->lookupPrecedenceGroup(rel.Name).getSingle();
14761487

1488+
if (group && PGD->isApex()) {
1489+
if (!PGD->isInvalid()) {
1490+
Diags.diagnose(rel.NameLoc, diag::precedence_group_higher_than_apex);
1491+
}
1492+
PGD->setInvalid();
1493+
}
1494+
14771495
if (group &&
14781496
group->getDeclContext()->getParentModule() == dc->getParentModule()) {
14791497
if (!PGD->isInvalid()) {

lib/Sema/TypeCheckDeclOverride.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information
@@ -1541,6 +1541,8 @@ namespace {
15411541

15421542
UNINTERESTING_ATTR(AtReasync)
15431543

1544+
UNINTERESTING_ATTR(Apex)
1545+
15441546
#undef UNINTERESTING_ATTR
15451547

15461548
void visitAvailableAttr(AvailableAttr *attr) {

lib/Sema/TypeCheckExpr.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information
@@ -281,7 +281,24 @@ static Expr *makeBinOp(ASTContext &Ctx, Expr *Op, Expr *LHS, Expr *RHS,
281281
await->setSubExpr(sub);
282282
return await;
283283
}
284-
284+
285+
// Operators in apex precedence groups are unordered relative to prefix and
286+
// postfix operators.
287+
if (opPrecedence && opPrecedence->isApex()) {
288+
if (auto *prefixUnary = dyn_cast<PrefixUnaryExpr>(LHS)) {
289+
Ctx.Diags.diagnose(Op->getLoc(),
290+
diag::unordered_adjacent_unary_operator,
291+
opPrecedence->getName())
292+
.highlight(prefixUnary->getFn()->getSourceRange());
293+
}
294+
if (auto *postfixUnary = dyn_cast<PostfixUnaryExpr>(RHS)) {
295+
Ctx.Diags.diagnose(Op->getLoc(),
296+
diag::unordered_adjacent_unary_operator,
297+
opPrecedence->getName())
298+
.highlight(postfixUnary->getFn()->getSourceRange());
299+
}
300+
}
301+
285302
// If this is an assignment operator, and the left operand is an optional
286303
// evaluation, pull the operator into the chain.
287304
if (opPrecedence && opPrecedence->isAssignment()) {

stdlib/public/core/FloatingPointTypes.swift.gyb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information

stdlib/public/core/Policy.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,7 @@ precedencegroup MultiplicationPrecedence {
368368
precedencegroup BitwiseShiftPrecedence {
369369
higherThan: MultiplicationPrecedence
370370
}
371+
@apex
371372
precedencegroup ExponentiationPrecedence {
372373
associativity: right
373374
higherThan: MultiplicationPrecedence

0 commit comments

Comments
 (0)