@@ -1006,27 +1006,37 @@ void swift::fixItAvailableAttrRename(TypeChecker &TC,
1006
1006
InFlightDiagnostic &diag,
1007
1007
SourceRange referenceRange,
1008
1008
const AvailableAttr *attr,
1009
- const CallExpr *CE ) {
1009
+ const ApplyExpr *call ) {
1010
1010
ParsedDeclName parsed = swift::parseDeclName (attr->Rename );
1011
1011
if (!parsed)
1012
1012
return ;
1013
1013
1014
+ bool originallyWasKnownOperatorExpr = false ;
1015
+ if (call) {
1016
+ originallyWasKnownOperatorExpr =
1017
+ isa<BinaryExpr>(call) ||
1018
+ isa<PrefixUnaryExpr>(call) ||
1019
+ isa<PostfixUnaryExpr>(call);
1020
+ }
1021
+ if (parsed.isOperator () != originallyWasKnownOperatorExpr)
1022
+ return ;
1023
+
1014
1024
SourceManager &sourceMgr = TC.Context .SourceMgr ;
1015
1025
1016
1026
if (parsed.isInstanceMember ()) {
1017
1027
// Replace the base of the call with the "self argument".
1018
1028
// We can only do a good job with the fix-it if we have the whole call
1019
1029
// expression.
1020
1030
// FIXME: Should we be validating the ContextName in some way?
1021
- if (!CE )
1031
+ if (!dyn_cast_or_null<CallExpr>(call) )
1022
1032
return ;
1023
1033
1024
1034
unsigned selfIndex = parsed.SelfIndex .getValue ();
1025
1035
const Expr *selfExpr = nullptr ;
1026
1036
SourceLoc removeRangeStart;
1027
1037
SourceLoc removeRangeEnd;
1028
1038
1029
- const Expr *argExpr = CE ->getArg ();
1039
+ const Expr *argExpr = call ->getArg ();
1030
1040
if (auto args = dyn_cast<TupleExpr>(argExpr)) {
1031
1041
size_t numElementsWithinParens = args->getNumElements ();
1032
1042
numElementsWithinParens -= args->hasTrailingClosure ();
@@ -1115,21 +1125,22 @@ void swift::fixItAvailableAttrRename(TypeChecker &TC,
1115
1125
selfReplace.push_back (' )' );
1116
1126
selfReplace.push_back (' .' );
1117
1127
selfReplace += parsed.BaseName ;
1118
- diag.fixItReplace (CE ->getFn ()->getSourceRange (), selfReplace);
1128
+ diag.fixItReplace (call ->getFn ()->getSourceRange (), selfReplace);
1119
1129
1120
1130
if (!parsed.isPropertyAccessor ())
1121
1131
diag.fixItRemoveChars (removeRangeStart, removeRangeEnd);
1122
1132
1123
1133
// Continue on to diagnose any argument label renames.
1124
1134
1125
- } else if (parsed.BaseName == TC.Context .Id_init .str () && CE) {
1135
+ } else if (parsed.BaseName == TC.Context .Id_init .str () &&
1136
+ dyn_cast_or_null<CallExpr>(call)) {
1126
1137
// For initializers, replace with a "call" of the context type...but only
1127
1138
// if we know we're doing a call (rather than a first-class reference).
1128
1139
if (parsed.isMember ()) {
1129
- diag.fixItReplace (CE ->getFn ()->getSourceRange (), parsed.ContextName );
1140
+ diag.fixItReplace (call ->getFn ()->getSourceRange (), parsed.ContextName );
1130
1141
1131
1142
} else {
1132
- auto *dotCall = dyn_cast<DotSyntaxCallExpr>(CE ->getFn ());
1143
+ auto *dotCall = dyn_cast<DotSyntaxCallExpr>(call ->getFn ());
1133
1144
if (!dotCall)
1134
1145
return ;
1135
1146
@@ -1151,10 +1162,10 @@ void swift::fixItAvailableAttrRename(TypeChecker &TC,
1151
1162
diag.fixItReplace (referenceRange, baseReplace);
1152
1163
}
1153
1164
1154
- if (!CE )
1165
+ if (!dyn_cast_or_null<CallExpr>(call) )
1155
1166
return ;
1156
1167
1157
- const Expr *argExpr = CE ->getArg ();
1168
+ const Expr *argExpr = call ->getArg ();
1158
1169
if (parsed.IsGetter ) {
1159
1170
diag.fixItRemove (argExpr->getSourceRange ());
1160
1171
return ;
@@ -1297,7 +1308,7 @@ void TypeChecker::diagnoseDeprecated(SourceRange ReferenceRange,
1297
1308
const DeclContext *ReferenceDC,
1298
1309
const AvailableAttr *Attr,
1299
1310
DeclName Name,
1300
- const CallExpr *CE ) {
1311
+ const ApplyExpr *Call ) {
1301
1312
// We match the behavior of clang to not report deprecation warnings
1302
1313
// inside declarations that are themselves deprecated on all deployment
1303
1314
// targets.
@@ -1354,7 +1365,7 @@ void TypeChecker::diagnoseDeprecated(SourceRange ReferenceRange,
1354
1365
auto renameDiag = diagnose (ReferenceRange.Start ,
1355
1366
diag::note_deprecated_rename,
1356
1367
newName);
1357
- fixItAvailableAttrRename (*this , renameDiag, ReferenceRange, Attr, CE );
1368
+ fixItAvailableAttrRename (*this , renameDiag, ReferenceRange, Attr, Call );
1358
1369
}
1359
1370
}
1360
1371
@@ -1407,11 +1418,11 @@ void TypeChecker::diagnoseUnavailableOverride(ValueDecl *override,
1407
1418
bool TypeChecker::diagnoseExplicitUnavailability (const ValueDecl *D,
1408
1419
SourceRange R,
1409
1420
const DeclContext *DC,
1410
- const CallExpr *CE ) {
1421
+ const ApplyExpr *call ) {
1411
1422
return diagnoseExplicitUnavailability (D, R, DC,
1412
1423
[=](InFlightDiagnostic &diag) {
1413
1424
fixItAvailableAttrRename (*this , diag, R, AvailableAttr::isUnavailable (D),
1414
- CE );
1425
+ call );
1415
1426
});
1416
1427
}
1417
1428
@@ -1546,19 +1557,19 @@ class AvailabilityWalker : public ASTWalker {
1546
1557
1547
1558
if (auto DR = dyn_cast<DeclRefExpr>(E))
1548
1559
diagAvailability (DR->getDecl (), DR->getSourceRange (),
1549
- getEnclosingCallExpr ());
1560
+ getEnclosingApplyExpr ());
1550
1561
if (auto MR = dyn_cast<MemberRefExpr>(E)) {
1551
1562
walkMemberRef (MR);
1552
1563
return skipChildren ();
1553
1564
}
1554
1565
if (auto OCDR = dyn_cast<OtherConstructorDeclRefExpr>(E))
1555
1566
diagAvailability (OCDR->getDecl (),
1556
1567
OCDR->getConstructorLoc ().getSourceRange (),
1557
- getEnclosingCallExpr ());
1568
+ getEnclosingApplyExpr ());
1558
1569
if (auto DMR = dyn_cast<DynamicMemberRefExpr>(E))
1559
1570
diagAvailability (DMR->getMember ().getDecl (),
1560
1571
DMR->getNameLoc ().getSourceRange (),
1561
- getEnclosingCallExpr ());
1572
+ getEnclosingApplyExpr ());
1562
1573
if (auto DS = dyn_cast<DynamicSubscriptExpr>(E))
1563
1574
diagAvailability (DS->getMember ().getDecl (), DS->getSourceRange ());
1564
1575
if (auto S = dyn_cast<SubscriptExpr>(E)) {
@@ -1586,12 +1597,12 @@ class AvailabilityWalker : public ASTWalker {
1586
1597
1587
1598
private:
1588
1599
bool diagAvailability (const ValueDecl *D, SourceRange R,
1589
- const CallExpr *CE = nullptr );
1600
+ const ApplyExpr *call = nullptr );
1590
1601
bool diagnoseIncDecRemoval (const ValueDecl *D, SourceRange R,
1591
1602
const AvailableAttr *Attr);
1592
1603
1593
- // / Walks up from a potential callee to the enclosing CallExpr .
1594
- const CallExpr * getEnclosingCallExpr () const {
1604
+ // / Walks up from a potential callee to the enclosing ApplyExpr .
1605
+ const ApplyExpr * getEnclosingApplyExpr () const {
1595
1606
ArrayRef<const Expr *> parents = ExprStack;
1596
1607
assert (!parents.empty () && " must be called while visiting an expression" );
1597
1608
size_t idx = parents.size () - 1 ;
@@ -1606,7 +1617,7 @@ class AvailabilityWalker : public ASTWalker {
1606
1617
isa<ForceValueExpr>(parents[idx]) || // f!(a)
1607
1618
isa<BindOptionalExpr>(parents[idx])); // f?(a)
1608
1619
1609
- auto *call = dyn_cast<CallExpr >(parents[idx]);
1620
+ auto *call = dyn_cast<ApplyExpr >(parents[idx]);
1610
1621
if (!call || call->getFn () != parents[idx+1 ])
1611
1622
return nullptr ;
1612
1623
return call;
@@ -1723,20 +1734,20 @@ class AvailabilityWalker : public ASTWalker {
1723
1734
// / Diagnose uses of unavailable declarations. Returns true if a diagnostic
1724
1735
// / was emitted.
1725
1736
bool AvailabilityWalker::diagAvailability (const ValueDecl *D, SourceRange R,
1726
- const CallExpr *CE ) {
1737
+ const ApplyExpr *call ) {
1727
1738
if (!D)
1728
1739
return false ;
1729
1740
1730
1741
if (auto *attr = AvailableAttr::isUnavailable (D))
1731
1742
if (diagnoseIncDecRemoval (D, R, attr))
1732
1743
return true ;
1733
1744
1734
- if (TC.diagnoseExplicitUnavailability (D, R, DC, CE ))
1745
+ if (TC.diagnoseExplicitUnavailability (D, R, DC, call ))
1735
1746
return true ;
1736
1747
1737
1748
// Diagnose for deprecation
1738
1749
if (const AvailableAttr *Attr = TypeChecker::getDeprecated (D)) {
1739
- TC.diagnoseDeprecated (R, DC, Attr, D->getFullName (), CE );
1750
+ TC.diagnoseDeprecated (R, DC, Attr, D->getFullName (), call );
1740
1751
}
1741
1752
1742
1753
if (TC.getLangOpts ().DisableAvailabilityChecking )
0 commit comments