Skip to content

Commit 90c68b1

Browse files
authored
Merge pull request #35492 from xedin/rdar-70764991-5.4
[5.4][Diagnostics] Adjust OoO fix-it intervals to account for replacement of first argument
2 parents 757853b + 8c7c19d commit 90c68b1

File tree

2 files changed

+33
-5
lines changed

2 files changed

+33
-5
lines changed

lib/Sema/CSDiagnostics.cpp

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4812,13 +4812,27 @@ bool OutOfOrderArgumentFailure::diagnoseAsError() {
48124812
auto text = SM.extractText(
48134813
Lexer::getCharSourceRangeFromSourceRange(SM, firstRange));
48144814

4815-
auto removalRange =
4816-
SourceRange(Lexer::getLocForEndOfToken(
4817-
SM, tuple->getElement(ArgIdx - 1)->getEndLoc()),
4818-
firstRange.End);
4815+
SourceLoc removalStartLoc;
4816+
// For the first argument, start is always next token after `(`.
4817+
if (ArgIdx == 0) {
4818+
removalStartLoc = tuple->getLParenLoc();
4819+
} else {
4820+
// For all other arguments, start is the next token past
4821+
// the previous argument.
4822+
removalStartLoc = tuple->getElement(ArgIdx - 1)->getEndLoc();
4823+
}
4824+
4825+
SourceRange removalRange{Lexer::getLocForEndOfToken(SM, removalStartLoc),
4826+
firstRange.End};
4827+
4828+
// Move requires postfix comma only if argument is moved in-between
4829+
// other arguments.
4830+
bool requiresComma = !isExpr<BinaryExpr>(anchor) &&
4831+
PrevArgIdx != tuple->getNumElements() - 1;
4832+
48194833
diag.fixItRemove(removalRange);
48204834
diag.fixItInsert(secondRange.Start,
4821-
text.str() + (isExpr<BinaryExpr>(anchor) ? "" : ", "));
4835+
text.str() + (requiresComma ? ", " : ""));
48224836
};
48234837

48244838
// There are 4 diagnostic messages variations depending on

test/Constraints/argument_matching.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1745,3 +1745,17 @@ func --- (_ lhs: String, _ rhs: String) -> Bool { true }
17451745

17461746
let x = 1
17471747
x --- x // expected-error 2 {{cannot convert value of type 'Int' to expected argument type 'String'}}
1748+
1749+
// rdar://problem/70764991 - out-of-order diagnostic crashes the compiler
1750+
func rdar70764991() {
1751+
struct S {
1752+
static var foo: S { get { S() } }
1753+
}
1754+
1755+
func bar(_: Any, _: String) {
1756+
}
1757+
1758+
func test(_ str: String) {
1759+
bar(str, S.foo) // expected-error {{unnamed argument #1 must precede unnamed argument #2}} {{9-12=}} {{14-14=str}}
1760+
}
1761+
}

0 commit comments

Comments
 (0)