Skip to content

Commit 5b38f3d

Browse files
committed
Fix #57354: Fix-it for deprecated initializers removes the .init part from self.init
1 parent 78430f4 commit 5b38f3d

File tree

2 files changed

+36
-15
lines changed

2 files changed

+36
-15
lines changed

lib/Sema/TypeCheckAvailability.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2359,16 +2359,22 @@ static void fixItAvailableAttrRename(InFlightDiagnostic &diag,
23592359
} else if (parsed.BaseName == "init" && isa_and_nonnull<CallExpr>(call)) {
23602360
auto *CE = cast<CallExpr>(call);
23612361

2362-
// For initializers, replace with a "call" of the context type...but only
2363-
// if we know we're doing a call (rather than a first-class reference).
2362+
// If it is a call to an initializer (rather than a first-class reference):
2363+
23642364
if (parsed.isMember()) {
2365+
// replace with a "call" to the type (instead of writing `.init`)
23652366
diag.fixItReplace(CE->getFn()->getSourceRange(), parsed.ContextName);
23662367
} else if (auto *dotCall = dyn_cast<DotSyntaxCallExpr>(CE->getFn())) {
2367-
SourceLoc removeLoc = dotCall->getDotLoc();
2368-
if (removeLoc.isInvalid())
2369-
return;
2370-
2371-
diag.fixItRemove(SourceRange(removeLoc, dotCall->getFn()->getEndLoc()));
2368+
// if it's a dot call, and the left side is a type (and not, for example,
2369+
// `self`, just remove the dot and the right side, again in order to make
2370+
// it a "call" to the type
2371+
if (isa<TypeExpr>(dotCall->getBase())) {
2372+
SourceLoc removeLoc = dotCall->getDotLoc();
2373+
if (removeLoc.isInvalid())
2374+
return;
2375+
2376+
diag.fixItRemove(SourceRange(removeLoc, dotCall->getFn()->getEndLoc()));
2377+
}
23722378
} else if (!isa<ConstructorRefCallExpr>(CE->getFn())) {
23732379
return;
23742380
}

test/attr/attr_availability.swift

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,29 @@ func testFactoryMethods() {
590590
Int.factory2(other: 1) // expected-error {{'factory2(other:)' has been replaced by 'Int.init(other:)'}} {{3-15=Int}}
591591
}
592592

593+
class DeprecatedInitBase {
594+
@available(*, deprecated, renamed: "init(new:)")
595+
init(old: Int) {}
596+
597+
init(new: Int) {}
598+
599+
convenience init(testSelf: Int) {
600+
self.init(old: testSelf) // expected-warning {{'init(old:)' is deprecated: replaced by 'init(new:)'}} expected-note {{use 'init(new:)' instead}} {{15-18=new}}
601+
}
602+
603+
init(testSuper: Int) {}
604+
}
605+
606+
class DeprecatedInitSub1: DeprecatedInitBase {
607+
override init(testSuper: Int) {
608+
super.init(old: testSuper) // expected-warning {{'init(old:)' is deprecated: replaced by 'init(new:)'}} expected-note {{use 'init(new:)' instead}} {{16-19=new}}
609+
}
610+
}
611+
612+
class DeprecatedInitSub2: DeprecatedInitBase { }
613+
614+
_ = DeprecatedInitSub2(old: 0) // expected-warning {{'init(old:)' is deprecated}}
615+
593616
class Base {
594617
@available(*, unavailable)
595618
func bad() {} // expected-note {{here}}
@@ -1048,14 +1071,6 @@ struct UnavailableAccessors {
10481071
}
10491072
}
10501073

1051-
class BaseDeprecatedInit {
1052-
@available(*, deprecated) init(bad: Int) { }
1053-
}
1054-
1055-
class SubInheritedDeprecatedInit: BaseDeprecatedInit { }
1056-
1057-
_ = SubInheritedDeprecatedInit(bad: 0) // expected-warning {{'init(bad:)' is deprecated}}
1058-
10591074
// https://github.com/apple/swift/issues/51149
10601075
// Should produce no warnings.
10611076

0 commit comments

Comments
 (0)