Skip to content

Commit 8d028bb

Browse files
committed
Check for non-associativity at end of chain of right-assoc operators.
1 parent db3b0d9 commit 8d028bb

File tree

2 files changed

+29
-2
lines changed

2 files changed

+29
-2
lines changed

lib/Sema/TypeCheckExpr.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -522,8 +522,17 @@ static Expr *foldSequence(TypeChecker &TC, DeclContext *DC,
522522
// If we've drained the entire sequence, we're done.
523523
if (S.empty()) return LHS;
524524

525-
// Otherwise, start all over with our new LHS.
526-
return foldSequence(TC, DC, LHS, S, precedenceBound);
525+
// Otherwise, we have to check that this next operator actually
526+
// associates.
527+
if ((op2 = getNextOperator()) && op2.precedence) {
528+
associativity =
529+
TC.Context.associateInfixOperators(op1.precedence, op2.precedence);
530+
RHS = S[1];
531+
}
532+
533+
// If so, start all over with our new LHS.
534+
if (associativity != Associativity::None)
535+
return foldSequence(TC, DC, LHS, S, precedenceBound);
527536
}
528537

529538
// If we ended up here, it's because we're either:

test/Constraints/operator.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,3 +237,21 @@ func sr10843() {
237237
(^^^)(s, s)
238238
_ = (==)(0, 0)
239239
}
240+
241+
// SR-10970
242+
precedencegroup PowerPrecedence {
243+
lowerThan: BitwiseShiftPrecedence
244+
higherThan: AdditionPrecedence
245+
associativity: right
246+
}
247+
infix operator ^^ : PowerPrecedence
248+
249+
extension Int {
250+
static func ^^ (lhs: Int, rhs: Int) -> Int {
251+
var result = 1
252+
for _ in 1...rhs { result *= lhs }
253+
return result
254+
}
255+
}
256+
257+
_ = 1 ^^ 2 ^^ 3 * 4 // expected-error {{adjacent operators are in unordered precedence groups 'PowerPrecedence' and 'MultiplicationPrecedence'}}

0 commit comments

Comments
 (0)