Skip to content

Commit d89c232

Browse files
authored
Add empty parens to var-to-function renames, take two. (#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
1 parent 69b3cc0 commit d89c232

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
@@ -1325,6 +1325,7 @@ bool swift::fixItOverrideDeclarationTypes(TypeChecker &TC,
13251325
void swift::fixItAvailableAttrRename(TypeChecker &TC,
13261326
InFlightDiagnostic &diag,
13271327
SourceRange referenceRange,
1328+
const ValueDecl *renamedDecl,
13281329
const AvailableAttr *attr,
13291330
const ApplyExpr *call) {
13301331
ParsedDeclName parsed = swift::parseDeclName(attr->Rename);
@@ -1479,6 +1480,12 @@ void swift::fixItAvailableAttrRename(TypeChecker &TC,
14791480
baseReplace += '.';
14801481
}
14811482
baseReplace += parsed.BaseName;
1483+
if (parsed.IsFunctionName && parsed.ArgumentLabels.empty() &&
1484+
isa<VarDecl>(renamedDecl)) {
1485+
// If we're going from a var to a function with no arguments, emit an
1486+
// empty parameter list.
1487+
baseReplace += "()";
1488+
}
14821489
diag.fixItReplace(referenceRange, baseReplace);
14831490
}
14841491

@@ -1681,11 +1688,14 @@ describeRename(ASTContext &ctx, const AvailableAttr *attr, const ValueDecl *D,
16811688
return ReplacementDeclKind::None;
16821689
}
16831690

1684-
void TypeChecker::diagnoseDeprecated(SourceRange ReferenceRange,
1685-
const DeclContext *ReferenceDC,
1686-
const AvailableAttr *Attr,
1687-
DeclName Name,
1688-
const ApplyExpr *Call) {
1691+
void TypeChecker::diagnoseIfDeprecated(SourceRange ReferenceRange,
1692+
const DeclContext *ReferenceDC,
1693+
const ValueDecl *DeprecatedDecl,
1694+
const ApplyExpr *Call) {
1695+
const AvailableAttr *Attr = TypeChecker::getDeprecated(DeprecatedDecl);
1696+
if (!Attr)
1697+
return;
1698+
16891699
// We match the behavior of clang to not report deprecation warnings
16901700
// inside declarations that are themselves deprecated on all deployment
16911701
// targets.
@@ -1704,6 +1714,7 @@ void TypeChecker::diagnoseDeprecated(SourceRange ReferenceRange,
17041714
}
17051715
}
17061716

1717+
DeclName Name = DeprecatedDecl->getFullName();
17071718
StringRef Platform = Attr->prettyPlatformString();
17081719
clang::VersionTuple DeprecatedVersion;
17091720
if (Attr->Deprecated)
@@ -1742,7 +1753,8 @@ void TypeChecker::diagnoseDeprecated(SourceRange ReferenceRange,
17421753
auto renameDiag = diagnose(ReferenceRange.Start,
17431754
diag::note_deprecated_rename,
17441755
newName);
1745-
fixItAvailableAttrRename(*this, renameDiag, ReferenceRange, Attr, Call);
1756+
fixItAvailableAttrRename(*this, renameDiag, ReferenceRange, DeprecatedDecl,
1757+
Attr, Call);
17461758
}
17471759
}
17481760

@@ -1798,7 +1810,7 @@ bool TypeChecker::diagnoseExplicitUnavailability(const ValueDecl *D,
17981810
const ApplyExpr *call) {
17991811
return diagnoseExplicitUnavailability(D, R, DC,
18001812
[=](InFlightDiagnostic &diag) {
1801-
fixItAvailableAttrRename(*this, diag, R, AvailableAttr::isUnavailable(D),
1813+
fixItAvailableAttrRename(*this, diag, R, D, AvailableAttr::isUnavailable(D),
18021814
call);
18031815
});
18041816
}
@@ -2126,9 +2138,7 @@ bool AvailabilityWalker::diagAvailability(const ValueDecl *D, SourceRange R,
21262138
return true;
21272139

21282140
// Diagnose for deprecation
2129-
if (const AvailableAttr *Attr = TypeChecker::getDeprecated(D)) {
2130-
TC.diagnoseDeprecated(R, DC, Attr, D->getFullName(), call);
2131-
}
2141+
TC.diagnoseIfDeprecated(R, DC, D, call);
21322142

21332143
// Diagnose for potential unavailability
21342144
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
@@ -1289,10 +1289,11 @@ static Type resolveIdentTypeComponent(
12891289
}
12901290

12911291
// FIXME: Merge this with diagAvailability in MiscDiagnostics.cpp.
1292-
static bool checkTypeDeclAvailability(Decl *TypeDecl, IdentTypeRepr *IdType,
1292+
static bool checkTypeDeclAvailability(const TypeDecl *TypeDecl,
1293+
IdentTypeRepr *IdType,
12931294
SourceLoc Loc, DeclContext *DC,
12941295
TypeChecker &TC,
1295-
bool AllowPotentiallyUnavailableProtocol) {
1296+
bool AllowPotentiallyUnavailableProtocol){
12961297

12971298
if (auto CI = dyn_cast<ComponentIdentTypeRepr>(IdType)) {
12981299
if (auto Attr = AvailableAttr::isUnavailable(TypeDecl)) {
@@ -1312,7 +1313,8 @@ static bool checkTypeDeclAvailability(Decl *TypeDecl, IdentTypeRepr *IdType,
13121313
diag::availability_decl_unavailable_rename,
13131314
CI->getIdentifier(), /*"replaced"*/false,
13141315
/*special kind*/0, Attr->Rename);
1315-
fixItAvailableAttrRename(TC, diag, Loc, Attr, /*call*/nullptr);
1316+
fixItAvailableAttrRename(TC, diag, Loc, TypeDecl, Attr,
1317+
/*call*/nullptr);
13161318
} else if (Attr->Message.empty()) {
13171319
TC.diagnose(Loc,
13181320
inSwift ? diag::availability_decl_unavailable_in_swift
@@ -1338,11 +1340,9 @@ static bool checkTypeDeclAvailability(Decl *TypeDecl, IdentTypeRepr *IdType,
13381340
return true;
13391341
}
13401342

1341-
if (auto *Attr = TypeChecker::getDeprecated(TypeDecl)) {
1342-
TC.diagnoseDeprecated(CI->getSourceRange(), DC, Attr,
1343-
CI->getIdentifier(), /*call, N/A*/nullptr);
1344-
}
1345-
1343+
TC.diagnoseIfDeprecated(CI->getSourceRange(), DC, TypeDecl,
1344+
/*call, N/A*/nullptr);
1345+
13461346
if (AllowPotentiallyUnavailableProtocol && isa<ProtocolDecl>(TypeDecl))
13471347
return false;
13481348

lib/Sema/TypeChecker.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1932,11 +1932,10 @@ class TypeChecker final : public LazyResolver {
19321932
/// Emits a diagnostic for a reference to a declaration that is deprecated.
19331933
/// Callers can provide a lambda that adds additional information (such as a
19341934
/// fixit hint) to the deprecation diagnostic, if it is emitted.
1935-
void diagnoseDeprecated(SourceRange SourceRange,
1936-
const DeclContext *ReferenceDC,
1937-
const AvailableAttr *Attr,
1938-
DeclName Name,
1939-
const ApplyExpr *Call);
1935+
void diagnoseIfDeprecated(SourceRange SourceRange,
1936+
const DeclContext *ReferenceDC,
1937+
const ValueDecl *DeprecatedDecl,
1938+
const ApplyExpr *Call);
19401939
/// @}
19411940

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

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+

test/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 {

0 commit comments

Comments
 (0)