Skip to content

Commit aaac511

Browse files
committed
Add empty parens to var-to-function renames, take two. (swiftlang#4938)
This time, propagate the decl marked deprecated or unavailable through to the fix-it, so we can be sure it's a var. https://bugs.swift.org/browse/SR-1649 (cherry picked from commit d89c232)
1 parent bc641c1 commit aaac511

File tree

6 files changed

+58
-25
lines changed

6 files changed

+58
-25
lines changed

lib/Sema/MiscDiagnostics.cpp

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1333,6 +1333,7 @@ bool swift::fixItOverrideDeclarationTypes(TypeChecker &TC,
13331333
void swift::fixItAvailableAttrRename(TypeChecker &TC,
13341334
InFlightDiagnostic &diag,
13351335
SourceRange referenceRange,
1336+
const ValueDecl *renamedDecl,
13361337
const AvailableAttr *attr,
13371338
const ApplyExpr *call) {
13381339
ParsedDeclName parsed = swift::parseDeclName(attr->Rename);
@@ -1487,6 +1488,12 @@ void swift::fixItAvailableAttrRename(TypeChecker &TC,
14871488
baseReplace += '.';
14881489
}
14891490
baseReplace += parsed.BaseName;
1491+
if (parsed.IsFunctionName && parsed.ArgumentLabels.empty() &&
1492+
isa<VarDecl>(renamedDecl)) {
1493+
// If we're going from a var to a function with no arguments, emit an
1494+
// empty parameter list.
1495+
baseReplace += "()";
1496+
}
14901497
diag.fixItReplace(referenceRange, baseReplace);
14911498
}
14921499

@@ -1689,11 +1696,14 @@ describeRename(ASTContext &ctx, const AvailableAttr *attr, const ValueDecl *D,
16891696
return ReplacementDeclKind::None;
16901697
}
16911698

1692-
void TypeChecker::diagnoseDeprecated(SourceRange ReferenceRange,
1693-
const DeclContext *ReferenceDC,
1694-
const AvailableAttr *Attr,
1695-
DeclName Name,
1696-
const ApplyExpr *Call) {
1699+
void TypeChecker::diagnoseIfDeprecated(SourceRange ReferenceRange,
1700+
const DeclContext *ReferenceDC,
1701+
const ValueDecl *DeprecatedDecl,
1702+
const ApplyExpr *Call) {
1703+
const AvailableAttr *Attr = TypeChecker::getDeprecated(DeprecatedDecl);
1704+
if (!Attr)
1705+
return;
1706+
16971707
// We match the behavior of clang to not report deprecation warnings
16981708
// inside declarations that are themselves deprecated on all deployment
16991709
// targets.
@@ -1712,6 +1722,7 @@ void TypeChecker::diagnoseDeprecated(SourceRange ReferenceRange,
17121722
}
17131723
}
17141724

1725+
DeclName Name = DeprecatedDecl->getFullName();
17151726
StringRef Platform = Attr->prettyPlatformString();
17161727
clang::VersionTuple DeprecatedVersion;
17171728
if (Attr->Deprecated)
@@ -1750,7 +1761,8 @@ void TypeChecker::diagnoseDeprecated(SourceRange ReferenceRange,
17501761
auto renameDiag = diagnose(ReferenceRange.Start,
17511762
diag::note_deprecated_rename,
17521763
newName);
1753-
fixItAvailableAttrRename(*this, renameDiag, ReferenceRange, Attr, Call);
1764+
fixItAvailableAttrRename(*this, renameDiag, ReferenceRange, DeprecatedDecl,
1765+
Attr, Call);
17541766
}
17551767
}
17561768

@@ -1806,7 +1818,7 @@ bool TypeChecker::diagnoseExplicitUnavailability(const ValueDecl *D,
18061818
const ApplyExpr *call) {
18071819
return diagnoseExplicitUnavailability(D, R, DC,
18081820
[=](InFlightDiagnostic &diag) {
1809-
fixItAvailableAttrRename(*this, diag, R, AvailableAttr::isUnavailable(D),
1821+
fixItAvailableAttrRename(*this, diag, R, D, AvailableAttr::isUnavailable(D),
18101822
call);
18111823
});
18121824
}
@@ -2134,9 +2146,7 @@ bool AvailabilityWalker::diagAvailability(const ValueDecl *D, SourceRange R,
21342146
return true;
21352147

21362148
// Diagnose for deprecation
2137-
if (const AvailableAttr *Attr = TypeChecker::getDeprecated(D)) {
2138-
TC.diagnoseDeprecated(R, DC, Attr, D->getFullName(), call);
2139-
}
2149+
TC.diagnoseIfDeprecated(R, DC, D, call);
21402150

21412151
// Diagnose for potential unavailability
21422152
auto maybeUnavail = TC.checkDeclarationAvailability(D, R.Start, DC);

lib/Sema/MiscDiagnostics.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ bool diagnoseArgumentLabelError(TypeChecker &TC, const Expr *expr,
7373
void fixItAvailableAttrRename(TypeChecker &TC,
7474
InFlightDiagnostic &diag,
7575
SourceRange referenceRange,
76+
const ValueDecl *renamedDecl,
7677
const AvailableAttr *attr,
7778
const ApplyExpr *call);
7879

lib/Sema/TypeCheckType.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1259,10 +1259,11 @@ static Type resolveIdentTypeComponent(
12591259
}
12601260

12611261
// FIXME: Merge this with diagAvailability in MiscDiagnostics.cpp.
1262-
static bool checkTypeDeclAvailability(Decl *TypeDecl, IdentTypeRepr *IdType,
1262+
static bool checkTypeDeclAvailability(const TypeDecl *TypeDecl,
1263+
IdentTypeRepr *IdType,
12631264
SourceLoc Loc, DeclContext *DC,
12641265
TypeChecker &TC,
1265-
bool AllowPotentiallyUnavailableProtocol) {
1266+
bool AllowPotentiallyUnavailableProtocol){
12661267

12671268
if (auto CI = dyn_cast<ComponentIdentTypeRepr>(IdType)) {
12681269
if (auto Attr = AvailableAttr::isUnavailable(TypeDecl)) {
@@ -1282,7 +1283,8 @@ static bool checkTypeDeclAvailability(Decl *TypeDecl, IdentTypeRepr *IdType,
12821283
diag::availability_decl_unavailable_rename,
12831284
CI->getIdentifier(), /*"replaced"*/false,
12841285
/*special kind*/0, Attr->Rename);
1285-
fixItAvailableAttrRename(TC, diag, Loc, Attr, /*call*/nullptr);
1286+
fixItAvailableAttrRename(TC, diag, Loc, TypeDecl, Attr,
1287+
/*call*/nullptr);
12861288
} else if (Attr->Message.empty()) {
12871289
TC.diagnose(Loc,
12881290
inSwift ? diag::availability_decl_unavailable_in_swift
@@ -1308,11 +1310,9 @@ static bool checkTypeDeclAvailability(Decl *TypeDecl, IdentTypeRepr *IdType,
13081310
return true;
13091311
}
13101312

1311-
if (auto *Attr = TypeChecker::getDeprecated(TypeDecl)) {
1312-
TC.diagnoseDeprecated(CI->getSourceRange(), DC, Attr,
1313-
CI->getIdentifier(), /*call, N/A*/nullptr);
1314-
}
1315-
1313+
TC.diagnoseIfDeprecated(CI->getSourceRange(), DC, TypeDecl,
1314+
/*call, N/A*/nullptr);
1315+
13161316
if (AllowPotentiallyUnavailableProtocol && isa<ProtocolDecl>(TypeDecl))
13171317
return false;
13181318

lib/Sema/TypeChecker.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1921,11 +1921,10 @@ class TypeChecker final : public LazyResolver {
19211921
/// Emits a diagnostic for a reference to a declaration that is deprecated.
19221922
/// Callers can provide a lambda that adds additional information (such as a
19231923
/// fixit hint) to the deprecation diagnostic, if it is emitted.
1924-
void diagnoseDeprecated(SourceRange SourceRange,
1925-
const DeclContext *ReferenceDC,
1926-
const AvailableAttr *Attr,
1927-
DeclName Name,
1928-
const ApplyExpr *Call);
1924+
void diagnoseIfDeprecated(SourceRange SourceRange,
1925+
const DeclContext *ReferenceDC,
1926+
const ValueDecl *DeprecatedDecl,
1927+
const ApplyExpr *Call);
19291928
/// @}
19301929

19311930
/// If LangOptions::DebugForbidTypecheckPrefix is set and the given decl

test/1_stdlib/Renames.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -519,8 +519,8 @@ func _String<S, C>(x: String, s: S, c: C, i: String.Index)
519519
x.replaceRange(i..<i, with: x) // expected-error {{'replaceRange(_:with:)' has been renamed to 'replaceSubrange'}} {{5-17=replaceSubrange}} {{none}}
520520
_ = x.removeAtIndex(i) // expected-error {{'removeAtIndex' has been renamed to 'remove(at:)'}} {{9-22=remove}} {{23-23=at: }} {{none}}
521521
x.removeRange(i..<i) // expected-error {{'removeRange' has been renamed to 'removeSubrange'}} {{5-16=removeSubrange}} {{none}}
522-
_ = x.lowercaseString // expected-error {{'lowercaseString' has been renamed to 'lowercased()'}} {{9-24=lowercased}} {{none}}
523-
_ = x.uppercaseString // expected-error {{'uppercaseString' has been renamed to 'uppercased()'}} {{9-24=uppercased}} {{none}}
522+
_ = x.lowercaseString // expected-error {{'lowercaseString' has been renamed to 'lowercased()'}} {{9-24=lowercased()}} {{none}}
523+
_ = x.uppercaseString // expected-error {{'uppercaseString' has been renamed to 'uppercased()'}} {{9-24=uppercased()}} {{none}}
524524
// FIXME: SR-1649 <rdar://problem/26563343>; We should suggest to add '()'
525525
}
526526
func _String<S : Sequence>(s: S, sep: String) where S.Iterator.Element == String {

test/Sema/availability.swift

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,3 +130,26 @@ func testPlatforms() {
130130
let _: UnavailableOnOSXAppExt = 0
131131
let _: UnavailableOnMacOSAppExt = 0
132132
}
133+
134+
struct VarToFunc {
135+
@available(*, unavailable, renamed: "function()")
136+
var variable: Int // expected-note 2 {{explicitly marked unavailable here}}
137+
138+
@available(*, unavailable, renamed: "function()")
139+
func oldFunction() -> Int { return 42 } // expected-note 2 {{explicitly marked unavailable here}}
140+
141+
func function() -> Int {
142+
_ = variable // expected-error{{'variable' has been renamed to 'function()'}}{{9-17=function()}}
143+
_ = oldFunction() //expected-error{{'oldFunction()' has been renamed to 'function()'}}{{9-20=function}}
144+
_ = oldFunction // expected-error{{'oldFunction()' has been renamed to 'function()'}} {{9-20=function}}
145+
146+
return 42
147+
}
148+
149+
mutating func testAssignment() {
150+
// This is nonsense, but someone shouldn't be using 'renamed' for this
151+
// anyway. Just make sure we don't crash or anything.
152+
variable = 2 // expected-error {{'variable' has been renamed to 'function()'}} {{5-13=function()}}
153+
}
154+
}
155+

0 commit comments

Comments
 (0)