Skip to content

Commit 805a5e9

Browse files
committed
[Diagnostics] Extend missing argument(s) diagnostic to support closure returns
If return type is a function, it's possible to return a closure which can have some of its arguments unused in the body e.g. `let _: () -> ((Int) -> Void) = { return { } }` In this case resulting closure has to use its only parameter or explictly ignore it by declaring `_ in`.
1 parent 3116d6e commit 805a5e9

File tree

4 files changed

+14
-7
lines changed

4 files changed

+14
-7
lines changed

lib/Sema/CSDiagnostics.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3767,12 +3767,11 @@ bool ImplicitInitOnNonConstMetatypeFailure::diagnoseAsError() {
37673767
bool MissingArgumentsFailure::diagnoseAsError() {
37683768
auto &cs = getConstraintSystem();
37693769
auto *locator = getLocator();
3770-
auto path = locator->getPath();
37713770

3772-
if (path.empty() ||
3773-
!(path.back().getKind() == ConstraintLocator::ApplyArgToParam ||
3774-
path.back().getKind() == ConstraintLocator::ContextualType ||
3775-
path.back().getKind() == ConstraintLocator::ApplyArgument))
3771+
if (!(locator->isLastElement<LocatorPathElt::ApplyArgToParam>() ||
3772+
locator->isLastElement<LocatorPathElt::ContextualType>() ||
3773+
locator->isLastElement<LocatorPathElt::ApplyArgument>() ||
3774+
locator->isLastElement<LocatorPathElt::ClosureResult>()))
37763775
return false;
37773776

37783777
// If this is a misplaced `missng argument` situation, it would be
@@ -4015,6 +4014,13 @@ bool MissingArgumentsFailure::diagnoseClosure(ClosureExpr *closure) {
40154014
funcType = cs.getContextualType()->getAs<FunctionType>();
40164015
} else if (auto info = getFunctionArgApplyInfo(locator)) {
40174016
funcType = info->getParamType()->getAs<FunctionType>();
4017+
} else if (locator->isLastElement<LocatorPathElt::ClosureResult>()) {
4018+
// Based on the locator we know this this is something like this:
4019+
// `let _: () -> ((Int) -> Void) = { return {} }`.
4020+
funcType = getType(getRawAnchor())
4021+
->castTo<FunctionType>()
4022+
->getResult()
4023+
->castTo<FunctionType>();
40184024
}
40194025

40204026
if (!funcType)

test/Constraints/closures.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,7 @@ let _ = { $0 = $0 = 42 } // expected-error {{assigning a variable to itself}}
484484
let mismatchInClosureResultType : (String) -> ((Int) -> Void) = {
485485
(String) -> ((Int) -> Void) in
486486
return { }
487-
// expected-error@-1 {{contextual type for closure argument list expects 1 argument, which cannot be implicitly ignored}}
487+
// expected-error@-1 {{contextual type for closure argument list expects 1 argument, which cannot be implicitly ignored}} {{13-13= _ in}}
488488
}
489489

490490
// SR-3520: Generic function taking closure with inout parameter can result in a variety of compiler errors or EXC_BAD_ACCESS

test/Constraints/diagnostics.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ func r18800223(_ i : Int) {
288288

289289

290290
var buttonTextColor: String?
291-
_ = (buttonTextColor != nil) ? 42 : {$0}; // expected-error {{type of expression is ambiguous without more context}}
291+
_ = (buttonTextColor != nil) ? 42 : {$0}; // expected-error {{unable to infer closure type in the current context}}
292292
}
293293

294294
// <rdar://problem/21883806> Bogus "'_' can only appear in a pattern or on the left side of an assignment" is back

test/expr/closure/closures.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ var closure1 : () -> Int = {4} // Function producing 4 whenever it is called.
1212
var closure2 : (Int,Int) -> Int = { 4 } // expected-error{{contextual type for closure argument list expects 2 arguments, which cannot be implicitly ignored}} {{36-36= _,_ in}}
1313
var closure3a : () -> () -> (Int,Int) = {{ (4, 2) }} // multi-level closing.
1414
var closure3b : (Int,Int) -> (Int) -> (Int,Int) = {{ (4, 2) }} // expected-error{{contextual type for closure argument list expects 2 arguments, which cannot be implicitly ignored}} {{52-52=_,_ in }}
15+
// expected-error@-1 {{contextual type for closure argument list expects 1 argument, which cannot be implicitly ignored}} {{53-53= _ in}}
1516
var closure4 : (Int,Int) -> Int = { $0 + $1 }
1617
var closure5 : (Double) -> Int = {
1718
$0 + 1.0

0 commit comments

Comments
 (0)