Skip to content

Commit 1b62039

Browse files
committed
[cssimplify] add a fix for contextual type conversion for function type
1 parent cad60ba commit 1b62039

File tree

3 files changed

+57
-58
lines changed

3 files changed

+57
-58
lines changed

lib/Sema/CSDiag.cpp

Lines changed: 0 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -2315,64 +2315,6 @@ bool FailureDiagnosis::diagnoseContextualConversionError(
23152315
exprType->isEqual(contextualType)) {
23162316
return false;
23172317
}
2318-
2319-
// If we're trying to convert something of type "() -> T" to T, then we
2320-
// probably meant to call the value.
2321-
if (auto srcFT = exprType->getAs<AnyFunctionType>()) {
2322-
if (srcFT->getParams().empty() &&
2323-
!isUnresolvedOrTypeVarType(srcFT->getResult()) &&
2324-
CS.TC.isConvertibleTo(srcFT->getResult(), contextualType, CS.DC)) {
2325-
diagnose(expr->getLoc(), diag::missing_nullary_call, srcFT->getResult())
2326-
.highlight(expr->getSourceRange())
2327-
.fixItInsertAfter(expr->getEndLoc(), "()");
2328-
2329-
// It is possible that we're looking at a stored property being
2330-
// initialized with a closure. Something like:
2331-
//
2332-
// var foo: Int = { return 0 }
2333-
//
2334-
// Let's offer another fix-it to remove the '=' to turn the stored
2335-
// property into a computed property. If the variable is immutable, then
2336-
// replace the 'let' with a 'var'
2337-
2338-
// First, check if the variable is declared top level or not. If it is
2339-
// not, then it means we're inside a decl like a class or an extension.
2340-
PatternBindingDecl *PBD = nullptr;
2341-
2342-
if (auto TLCD = dyn_cast<TopLevelCodeDecl>(CS.DC)) {
2343-
if (TLCD->getBody()->isImplicit()) {
2344-
if (auto decl = TLCD->getBody()->getElement(0).dyn_cast<Decl *>()) {
2345-
if (auto binding = dyn_cast<PatternBindingDecl>(decl)) {
2346-
PBD = binding;
2347-
}
2348-
}
2349-
}
2350-
} else if (auto PBI = dyn_cast<PatternBindingInitializer>(CS.DC)) {
2351-
PBD = PBI->getBinding();
2352-
}
2353-
2354-
if (PBD) {
2355-
if (auto VD = PBD->getSingleVar()) {
2356-
auto entry = PBD->getPatternEntryForVarDecl(VD);
2357-
2358-
if (!VD->isStatic() &&
2359-
!VD->getAttrs().getAttribute<DynamicReplacementAttr>() &&
2360-
entry.getInit() && isa<ClosureExpr>(entry.getInit())) {
2361-
auto diag = CS.TC.diagnose(expr->getLoc(),
2362-
diag::extension_stored_property_fixit,
2363-
VD->getName());
2364-
diag.fixItRemove(entry.getEqualLoc());
2365-
2366-
if (VD->isLet()) {
2367-
diag.fixItReplace(PBD->getStartLoc(), getTokenText(tok::kw_var));
2368-
}
2369-
}
2370-
}
2371-
}
2372-
2373-
return true;
2374-
}
2375-
}
23762318

23772319
// If this is a conversion from T to () in a call argument context, it is
23782320
// almost certainly an extra argument being passed in.

lib/Sema/CSDiagnostics.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "swift/AST/Decl.h"
2323
#include "swift/AST/Expr.h"
2424
#include "swift/AST/GenericSignature.h"
25+
#include "swift/AST/Initializer.h"
2526
#include "swift/AST/ParameterList.h"
2627
#include "swift/AST/Pattern.h"
2728
#include "swift/AST/ProtocolConformance.h"
@@ -1348,6 +1349,51 @@ bool ContextualFailure::diagnoseMissingFunctionCall() const {
13481349
srcFT->getResult())
13491350
.highlight(anchor->getSourceRange())
13501351
.fixItInsertAfter(anchor->getEndLoc(), "()");
1352+
1353+
// It is possible that we're looking at a stored property being
1354+
// initialized with a closure. Something like:
1355+
//
1356+
// var foo: Int = { return 0 }
1357+
//
1358+
// Let's offer another fix-it to remove the '=' to turn the stored
1359+
// property into a computed property. If the variable is immutable, then
1360+
// replace the 'let' with a 'var'
1361+
1362+
// First, check if the variable is declared top level or not. If it is
1363+
// not, then it means we're inside a decl like a class or an extension.
1364+
PatternBindingDecl *PBD = nullptr;
1365+
1366+
if (auto TLCD = dyn_cast<TopLevelCodeDecl>(getDC())) {
1367+
if (TLCD->getBody()->isImplicit()) {
1368+
if (auto decl = TLCD->getBody()->getElement(0).dyn_cast<Decl *>()) {
1369+
if (auto binding = dyn_cast<PatternBindingDecl>(decl)) {
1370+
PBD = binding;
1371+
}
1372+
}
1373+
}
1374+
} else if (auto PBI = dyn_cast<PatternBindingInitializer>(getDC())) {
1375+
PBD = PBI->getBinding();
1376+
}
1377+
1378+
if (PBD) {
1379+
if (auto VD = PBD->getSingleVar()) {
1380+
auto entry = PBD->getPatternEntryForVarDecl(VD);
1381+
1382+
if (!VD->isStatic() &&
1383+
!VD->getAttrs().getAttribute<DynamicReplacementAttr>() &&
1384+
entry.getInit() && isa<ClosureExpr>(entry.getInit())) {
1385+
auto diag =
1386+
TC.diagnose(anchor->getLoc(), diag::extension_stored_property_fixit,
1387+
VD->getName());
1388+
diag.fixItRemove(entry.getEqualLoc());
1389+
1390+
if (VD->isLet()) {
1391+
diag.fixItReplace(PBD->getStartLoc(), getTokenText(tok::kw_var));
1392+
}
1393+
}
1394+
}
1395+
}
1396+
13511397
return true;
13521398
}
13531399

lib/Sema/CSSimplify.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1989,6 +1989,17 @@ repairFailures(ConstraintSystem &cs, Type lhs, Type rhs,
19891989
break;
19901990
}
19911991

1992+
case ConstraintLocator::ContextualType: {
1993+
if (lhs->is<FunctionType>() && !rhs->is<AnyFunctionType>()) {
1994+
auto *fix = ContextualMismatch::create(cs, lhs, rhs,
1995+
cs.getConstraintLocator(locator));
1996+
conversionsOrFixes.push_back(fix);
1997+
break;
1998+
}
1999+
2000+
return;
2001+
}
2002+
19922003
default:
19932004
return;
19942005
}

0 commit comments

Comments
 (0)