Skip to content

Commit 5a8e1fa

Browse files
committed
[cs] extract computed property fix-it into separate method
1 parent 9750762 commit 5a8e1fa

File tree

5 files changed

+50
-46
lines changed

5 files changed

+50
-46
lines changed

lib/Sema/CSDiag.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2323,11 +2323,10 @@ bool FailureDiagnosis::diagnoseContextualConversionError(
23232323
!isUnresolvedOrTypeVarType(srcFT->getResult()) &&
23242324
CS.TC.isConvertibleTo(srcFT->getResult(), contextualType, CS.DC)) {
23252325

2326-
auto locator = CS.getConstraintLocator(expr);
2327-
auto extendedLocator =
2328-
CS.getConstraintLocator(locator, ConstraintLocator::ContextualType);
2329-
ContextualFailure failure = ContextualFailure(
2330-
nullptr, CS, srcFT, contextualType, extendedLocator);
2326+
auto locator =
2327+
CS.getConstraintLocator(expr, ConstraintLocator::ContextualType);
2328+
ContextualFailure failure =
2329+
ContextualFailure(nullptr, CS, srcFT, contextualType, locator);
23312330
auto diagnosed = failure.diagnoseAsError();
23322331
assert(diagnosed && "Failed to produce contextual failure diagnostic");
23332332
(void)diagnosed;

lib/Sema/CSDiagnostics.cpp

Lines changed: 39 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1350,6 +1350,42 @@ bool ContextualFailure::diagnoseMissingFunctionCall() const {
13501350
.highlight(anchor->getSourceRange())
13511351
.fixItInsertAfter(anchor->getEndLoc(), "()");
13521352

1353+
if (isa<ClosureExpr>(getAnchor())) {
1354+
tryComputedPropertyFixIts(TC, anchor, getDC());
1355+
}
1356+
1357+
return true;
1358+
}
1359+
1360+
bool ContextualFailure::trySequenceSubsequenceFixIts(InFlightDiagnostic &diag,
1361+
ConstraintSystem &CS,
1362+
Type fromType, Type toType,
1363+
Expr *expr) {
1364+
if (!CS.TC.Context.getStdlibModule())
1365+
return false;
1366+
1367+
auto String = CS.TC.getStringType(CS.DC);
1368+
auto Substring = CS.TC.getSubstringType(CS.DC);
1369+
1370+
if (!String || !Substring)
1371+
return false;
1372+
1373+
// Substring -> String conversion
1374+
// Wrap in String.init
1375+
if (fromType->isEqual(Substring)) {
1376+
if (toType->isEqual(String)) {
1377+
auto range = expr->getSourceRange();
1378+
diag.fixItInsert(range.Start, "String(");
1379+
diag.fixItInsertAfter(range.End, ")");
1380+
return true;
1381+
}
1382+
}
1383+
1384+
return false;
1385+
}
1386+
1387+
void ContextualFailure::tryComputedPropertyFixIts(TypeChecker &TC, Expr *expr,
1388+
DeclContext *dc) {
13531389
// It is possible that we're looking at a stored property being
13541390
// initialized with a closure. Something like:
13551391
//
@@ -1359,23 +1395,17 @@ bool ContextualFailure::diagnoseMissingFunctionCall() const {
13591395
// property into a computed property. If the variable is immutable, then
13601396
// replace the 'let' with a 'var'.
13611397

1362-
if (getAnchor() && !isa<ClosureExpr>(getAnchor())) {
1363-
return true;
1364-
}
1365-
1366-
// First, check if the variable is declared top level or not. If it is
1367-
// not, then it means we're inside a decl like a class or an extension.
13681398
PatternBindingDecl *PBD = nullptr;
13691399

1370-
if (auto TLCD = dyn_cast<TopLevelCodeDecl>(getDC())) {
1400+
if (auto TLCD = dyn_cast<TopLevelCodeDecl>(dc)) {
13711401
if (TLCD->getBody()->isImplicit()) {
13721402
if (auto decl = TLCD->getBody()->getElement(0).dyn_cast<Decl *>()) {
13731403
if (auto binding = dyn_cast<PatternBindingDecl>(decl)) {
13741404
PBD = binding;
13751405
}
13761406
}
13771407
}
1378-
} else if (auto PBI = dyn_cast<PatternBindingInitializer>(getDC())) {
1408+
} else if (auto PBI = dyn_cast<PatternBindingInitializer>(dc)) {
13791409
PBD = PBI->getBinding();
13801410
}
13811411

@@ -1387,7 +1417,7 @@ bool ContextualFailure::diagnoseMissingFunctionCall() const {
13871417
!VD->getAttrs().getAttribute<DynamicReplacementAttr>() &&
13881418
entry.getInit() && isa<ClosureExpr>(entry.getInit())) {
13891419
auto diag =
1390-
TC.diagnose(anchor->getLoc(), diag::extension_stored_property_fixit,
1420+
TC.diagnose(expr->getLoc(), diag::extension_stored_property_fixit,
13911421
VD->getName());
13921422
diag.fixItRemove(entry.getEqualLoc());
13931423

@@ -1397,35 +1427,6 @@ bool ContextualFailure::diagnoseMissingFunctionCall() const {
13971427
}
13981428
}
13991429
}
1400-
1401-
return true;
1402-
}
1403-
1404-
bool ContextualFailure::trySequenceSubsequenceFixIts(InFlightDiagnostic &diag,
1405-
ConstraintSystem &CS,
1406-
Type fromType, Type toType,
1407-
Expr *expr) {
1408-
if (!CS.TC.Context.getStdlibModule())
1409-
return false;
1410-
1411-
auto String = CS.TC.getStringType(CS.DC);
1412-
auto Substring = CS.TC.getSubstringType(CS.DC);
1413-
1414-
if (!String || !Substring)
1415-
return false;
1416-
1417-
// Substring -> String conversion
1418-
// Wrap in String.init
1419-
if (fromType->isEqual(Substring)) {
1420-
if (toType->isEqual(String)) {
1421-
auto range = expr->getSourceRange();
1422-
diag.fixItInsert(range.Start, "String(");
1423-
diag.fixItInsertAfter(range.End, ")");
1424-
return true;
1425-
}
1426-
}
1427-
1428-
return false;
14291430
}
14301431

14311432
bool AutoClosureForwardingFailure::diagnoseAsError() {

lib/Sema/CSDiagnostics.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,10 @@ class ContextualFailure final : public FailureDiagnostic {
671671
static bool trySequenceSubsequenceFixIts(InFlightDiagnostic &diag,
672672
ConstraintSystem &CS, Type fromType,
673673
Type toType, Expr *expr);
674+
/// Try to add a fix-it to convert a stored property into a computed
675+
/// property
676+
static void tryComputedPropertyFixIts(TypeChecker &TC, Expr *expr,
677+
DeclContext *dc);
674678

675679
private:
676680
Type resolve(Type rawType) {

lib/Sema/CSSimplify.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1990,7 +1990,8 @@ repairFailures(ConstraintSystem &cs, Type lhs, Type rhs,
19901990
}
19911991

19921992
case ConstraintLocator::ContextualType: {
1993-
if (lhs->is<FunctionType>() && !rhs->is<AnyFunctionType>()) {
1993+
if (lhs->is<FunctionType>() && !rhs->is<AnyFunctionType>() &&
1994+
isa<ClosureExpr>(anchor)) {
19941995
auto *fix = ContextualMismatch::create(cs, lhs, rhs,
19951996
cs.getConstraintLocator(locator));
19961997
conversionsOrFixes.push_back(fix);

test/expr/closure/closures.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@ var closure5 : (Double) -> Int = {
2020

2121
var closure6 = $0 // expected-error {{anonymous closure argument not contained in a closure}}
2222

23-
var closure7 : Int =
24-
{ 4 } // expected-error {{function produces expected type 'Int'; did you mean to call it with '()'?}} {{9-9=()}}
23+
var closure7 : Int = { 4 } // expected-error {{function produces expected type 'Int'; did you mean to call it with '()'?}} {{27-27=()}} // expected-note {{Remove '=' to make 'closure7' a computed property}}{{20-22=}}
2524

2625
var capturedVariable = 1
2726
var closure8 = { [capturedVariable] in

0 commit comments

Comments
 (0)