Skip to content

Commit 15a48ff

Browse files
Merge pull request #59993 from LucianoPAlmeida/fix-it-rename-noop
[Diagnostics] Do not emit rename fix-it if call function has the same name
2 parents f63b6d8 + a238ab6 commit 15a48ff

File tree

2 files changed

+90
-6
lines changed

2 files changed

+90
-6
lines changed

lib/Sema/TypeCheckAvailability.cpp

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2397,13 +2397,40 @@ static void fixItAvailableAttrRename(InFlightDiagnostic &diag,
23972397
("." + baseReplace.str() + "(").str());
23982398
diag.fixItReplace(SE->getEndLoc(), ")");
23992399
} else {
2400-
if (parsed.IsFunctionName && parsed.ArgumentLabels.empty() &&
2401-
isa<VarDecl>(renamedDecl)) {
2402-
// If we're going from a var to a function with no arguments, emit an
2403-
// empty parameter list.
2404-
baseReplace += "()";
2400+
bool shouldEmitRenameFixit = true;
2401+
if (auto *CE = dyn_cast_or_null<CallExpr>(call)) {
2402+
SmallString<64> callContextName;
2403+
llvm::raw_svector_ostream name(callContextName);
2404+
if (auto *DCE = dyn_cast<DotSyntaxCallExpr>(CE->getDirectCallee())) {
2405+
if (auto *TE = dyn_cast<TypeExpr>(DCE->getBase())) {
2406+
TE->getTypeRepr()->print(name);
2407+
if (!parsed.ContextName.empty()) {
2408+
// If there is a context in rename function e.g.
2409+
// `Context.function()` and call context is a `DotSyntaxCallExpr`
2410+
// adjust the range so it replaces the base as well.
2411+
referenceRange =
2412+
SourceRange(TE->getStartLoc(), referenceRange.End);
2413+
}
2414+
}
2415+
}
2416+
// Function names are the same(including context if applicable), so
2417+
// renaming fix-it doesn't need do be produced.
2418+
if ((parsed.ContextName.empty() ||
2419+
parsed.ContextName == callContextName) &&
2420+
CE->getCalledValue()->getBaseName() == parsed.BaseName) {
2421+
shouldEmitRenameFixit = false;
2422+
}
2423+
}
2424+
if (shouldEmitRenameFixit) {
2425+
if (parsed.IsFunctionName && parsed.ArgumentLabels.empty() &&
2426+
isa<VarDecl>(renamedDecl)) {
2427+
// If we're going from a var to a function with no arguments, emit an
2428+
// empty parameter list.
2429+
baseReplace += "()";
2430+
}
2431+
2432+
diag.fixItReplace(referenceRange, baseReplace);
24052433
}
2406-
diag.fixItReplace(referenceRange, baseReplace);
24072434
}
24082435
}
24092436

test/Sema/deprecation_osx.swift

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,3 +165,60 @@ func functionWithDeprecatedMethodInDeadElseBranch() {
165165
let _ = ClassDeprecatedIn10_9() // no-warning
166166
}
167167
}
168+
169+
// https://github.com/apple/swift/issues/59843
170+
class I59843_A {
171+
@available(macOS, deprecated: 10.51, renamed: "configure(with:)")
172+
static func configure(a: String, b: String) {}
173+
174+
static func configure(with: Int) {}
175+
176+
@available(macOS, deprecated: 10.51, renamed: "method(with:)")
177+
func method(a: String, b: String) {}
178+
179+
func method(with: Int) {}
180+
181+
func f() {
182+
self.method(a: "a", b: "b") // expected-warning{{'method(a:b:)' was deprecated in macOS 10.51: renamed to 'method(with:)'}}
183+
// expected-note@-1{{use 'method(with:)' instead}} {{none}}
184+
}
185+
}
186+
187+
class I59843_B {
188+
@available(macOS, deprecated: 10.51, renamed: "configure(with:and:)")
189+
static func configure(a: String, b: String) {}
190+
191+
static func configure(with: Int, and: Int) {}
192+
193+
@available(macOS, deprecated: 10.51, renamed: "method(with:and:)")
194+
func method(a: String, b: String) {}
195+
196+
func method(with: Int, and: Int) {}
197+
198+
// Context
199+
@available(macOS, deprecated: 10.51, renamed: "I59843_B.context(with:and:)")
200+
static func context(a: String, b: String) {}
201+
202+
static func context(with: Int, and: Int) {}
203+
204+
@available(macOS, deprecated: 10.51, renamed: "I59843_A.contextDiff(with:and:)")
205+
static func contextDiff(a: String, b: String) {}
206+
207+
static func contextDiff(with: Int, and: Int) {}
208+
209+
func f() {
210+
self.method(a: "a", b: "b") // expected-warning{{'method(a:b:)' was deprecated in macOS 10.51: renamed to 'method(with:and:)'}}
211+
// expected-note@-1{{use 'method(with:and:)' instead}} {{17-18=with}} {{25-26=and}}
212+
}
213+
}
214+
215+
func I59843_f() {
216+
I59843_A.configure(a: "a", b: "b") // expected-warning{{'configure(a:b:)' was deprecated in macOS 10.51: renamed to 'configure(with:)'}}
217+
// expected-note@-1{{use 'configure(with:)' instead}} {{none}}
218+
I59843_B.configure(a: "a", b: "b") // expected-warning{{'configure(a:b:)' was deprecated in macOS 10.51: renamed to 'configure(with:and:)'}}
219+
// expected-note@-1{{use 'configure(with:and:)' instead}} {{22-23=with}} {{30-31=and}}
220+
I59843_B.context(a: "a", b: "b") // expected-warning{{'context(a:b:)' was deprecated in macOS 10.51: replaced by 'I59843_B.context(with:and:)'}}
221+
// expected-note@-1{{use 'I59843_B.context(with:and:)' instead}} {{20-21=with}} {{28-29=and}}
222+
I59843_B.contextDiff(a: "a", b: "b") // expected-warning{{'contextDiff(a:b:)' was deprecated in macOS 10.51: replaced by 'I59843_A.contextDiff(with:and:)'}}
223+
// expected-note@-1{{use 'I59843_A.contextDiff(with:and:)' instead}} {{3-23=I59843_A.contextDiff}} {{24-25=with}} {{32-33=and}}
224+
}

0 commit comments

Comments
 (0)