Skip to content

Commit 2f6b6d2

Browse files
committed
[Fix-it] Support defaulted and variadic arguments in renamed fix-it
1 parent 2ef0a8f commit 2f6b6d2

File tree

2 files changed

+71
-6
lines changed

2 files changed

+71
-6
lines changed

lib/Sema/MiscDiagnostics.cpp

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1434,11 +1434,53 @@ void swift::fixItAvailableAttrRename(TypeChecker &TC,
14341434
});
14351435

14361436
if (auto args = dyn_cast<TupleShuffleExpr>(argExpr)) {
1437-
if (!args->getVariadicArgs().empty()) {
1438-
// FIXME: Support variadic arguments.
1437+
argExpr = args->getSubExpr();
1438+
1439+
// Coerce the `argumentLabelIDs` to the user supplied arguments.
1440+
// e.g:
1441+
// @available(.., renamed: "new(w:x:y:z:)")
1442+
// func old(a: Int, b: Int..., c: String="", d: Int=0){}
1443+
// old(a: 1, b: 2, 3, 4, d: 5)
1444+
// coerce
1445+
// argumentLabelIDs = {"w", "x", "y", "z"}
1446+
// to
1447+
// argumentLabelIDs = {"w", "x", "", "", "z"}
1448+
auto elementMap = args->getElementMapping();
1449+
if (elementMap.size() != argumentLabelIDs.size()) {
1450+
// Mismatched lengths; give up.
14391451
return;
14401452
}
1441-
argExpr = args->getSubExpr();
1453+
auto I = argumentLabelIDs.begin();
1454+
for (auto shuffleIdx : elementMap) {
1455+
switch (shuffleIdx) {
1456+
case TupleShuffleExpr::DefaultInitialize:
1457+
case TupleShuffleExpr::CallerDefaultInitialize:
1458+
// Defaulted: remove param label of it.
1459+
I = argumentLabelIDs.erase(I);
1460+
break;
1461+
case TupleShuffleExpr::Variadic: {
1462+
auto variadicArgsNum = args->getVariadicArgs().size();
1463+
if (variadicArgsNum == 0) {
1464+
// No arguments: Remove param label of it.
1465+
I = argumentLabelIDs.erase(I);
1466+
} else if (variadicArgsNum == 1) {
1467+
// One argument: Just advance.
1468+
++I;
1469+
} else {
1470+
// Two or more arguments: Insert empty labels after the first one.
1471+
I = argumentLabelIDs.insert(++I, --variadicArgsNum, Identifier());
1472+
I += variadicArgsNum;
1473+
}
1474+
break;
1475+
}
1476+
default:
1477+
// Normal: Just advance.
1478+
assert(shuffleIdx == (I - argumentLabelIDs.begin()) &&
1479+
"SE-0060 guarantee");
1480+
++I;
1481+
break;
1482+
}
1483+
}
14421484
}
14431485

14441486
if (auto args = dyn_cast<TupleExpr>(argExpr)) {

test/attr/attr_availability.swift

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -753,10 +753,33 @@ func testTrailingClosure() {
753753
closure_UU_LU_ne(1, { 0 }) // expected-error {{'closure_UU_LU_ne' has been renamed to 'after(arg:_:)'}} {{3-19=after}} {{20-20=arg: }} {{none}}
754754
}
755755

756+
@available(*, unavailable, renamed: "after(x:)")
757+
func defaultUnnamed(_ a: Int = 1) {} // expected-note 2 {{here}}
756758
@available(*, unavailable, renamed: "after(x:y:)")
757-
func variadic1(a: Int ..., b: Int = 0) {} // expected-note {{here}}
759+
func defaultBeforeRequired(a: Int = 1, b: Int) {} // expected-note {{here}}
760+
@available(*, unavailable, renamed: "after(x:y:z:)")
761+
func defaultPlusTrailingClosure(a: Int = 1, b: Int = 2, c: () -> Void) {} // expected-note 3 {{here}}
762+
763+
func testDefaults() {
764+
defaultUnnamed() // expected-error {{'defaultUnnamed' has been renamed to 'after(x:)'}} {{3-17=after}} {{none}}
765+
defaultUnnamed(1) // expected-error {{'defaultUnnamed' has been renamed to 'after(x:)'}} {{3-17=after}} {{18-18=x: }} {{none}}
766+
defaultBeforeRequired(b: 5) // expected-error {{'defaultBeforeRequired(a:b:)' has been renamed to 'after(x:y:)'}} {{3-24=after}} {{25-26=y}} {{none}}
767+
defaultPlusTrailingClosure {} // expected-error {{'defaultPlusTrailingClosure(a:b:c:)' has been renamed to 'after(x:y:z:)'}} {{3-29=after}} {{none}}
768+
defaultPlusTrailingClosure(c: {}) // expected-error {{'defaultPlusTrailingClosure(a:b:c:)' has been renamed to 'after(x:y:z:)'}} {{3-29=after}} {{30-31=z}} {{none}}
769+
defaultPlusTrailingClosure(a: 1) {} // expected-error {{'defaultPlusTrailingClosure(a:b:c:)' has been renamed to 'after(x:y:z:)'}} {{3-29=after}} {{30-31=x}} {{none}}
770+
}
771+
772+
@available(*, unavailable, renamed: "after(x:y:)")
773+
func variadic1(a: Int ..., b: Int = 0) {} // expected-note 2 {{here}}
774+
@available(*, unavailable, renamed: "after(x:y:)")
775+
func variadic2(a: Int, _ b: Int ...) {} // expected-note {{here}}
776+
@available(*, unavailable, renamed: "after(x:_:y:z:)")
777+
func variadic3(_ a: Int, b: Int ..., c: String = "", d: String) {} // expected-note 2 {{here}}
758778

759779
func testVariadic() {
760-
// FIXME: fix-it should be: {{1-9=newFn7}} {{10-11=x}} {{none}}
761-
variadic1(a: 1, 1) // expected-error {{'variadic1(a:b:)' has been renamed to 'after(x:y:)'}} {{3-12=after}} {{none}}
780+
variadic1(a: 1, 2) // expected-error {{'variadic1(a:b:)' has been renamed to 'after(x:y:)'}} {{3-12=after}} {{13-14=x}} {{none}}
781+
variadic1(a: 1, 2, b: 3) // expected-error {{'variadic1(a:b:)' has been renamed to 'after(x:y:)'}} {{3-12=after}} {{13-14=x}} {{22-23=y}} {{none}}
782+
variadic2(a: 1, 2, 3) // expected-error {{'variadic2(a:_:)' has been renamed to 'after(x:y:)'}} {{3-12=after}} {{13-14=x}} {{19-19=y: }} {{none}}
783+
variadic3(1, b: 2, 3, d: "test") // expected-error {{'variadic3(_:b:c:d:)' has been renamed to 'after(x:_:y:z:)'}} {{3-12=after}} {{13-13=x: }} {{16-19=}} {{25-26=z}} {{none}}
784+
variadic3(1, d:"test") // expected-error {{'variadic3(_:b:c:d:)' has been renamed to 'after(x:_:y:z:)'}} {{3-12=after}} {{13-13=x: }} {{16-17=z}} {{none}}
762785
}

0 commit comments

Comments
 (0)