Skip to content

Commit 84d27f8

Browse files
committed
fix <rdar://problem/21675896> QoI: [Closure return type inference] Swift cannot find members for the result of inlined lambdas with branches
We previously produced the unhelpful error message: x.swift:11:7: error: type of expression is ambiguous without more context we now produce: error: unable to infer closure return type in current context which is going in the right direction.
1 parent 043c2e0 commit 84d27f8

File tree

4 files changed

+34
-4
lines changed

4 files changed

+34
-4
lines changed

lib/Sema/CSDiag.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6304,6 +6304,22 @@ void FailureDiagnosis::diagnoseAmbiguity(Expr *E) {
63046304
return;
63056305
}
63066306

6307+
// A very common cause of this diagnostic is a situation where a closure expr
6308+
// has no inferred type, due to being a multiline closure. Check to see if
6309+
// this is the case and (if so), speculatively diagnose that as the problem.
6310+
bool didDiagnose = false;
6311+
E->forEachChildExpr([&](Expr *subExpr) -> Expr*{
6312+
auto closure = dyn_cast<ClosureExpr>(subExpr);
6313+
if (!didDiagnose && closure)
6314+
didDiagnose = checkMultistatementClosureForAmbiguity(closure,
6315+
CS->getTypeChecker());
6316+
6317+
return subExpr;
6318+
});
6319+
6320+
if (didDiagnose) return;
6321+
6322+
63076323

63086324
// Attempt to re-type-check the entire expression, allowing ambiguity, but
63096325
// ignoring a contextual type.

test/Constraints/closures.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,5 +218,16 @@ let things = Thing().map { thing in // expected-error {{unable to infer closure
218218
}
219219

220220

221+
// <rdar://problem/21675896> QoI: [Closure return type inference] Swift cannot find members for the result of inlined lambdas with branches
222+
func r21675896(file : String) {
223+
let x: String = { // expected-error {{unable to infer closure return type in current context}}
224+
if true {
225+
return "foo"
226+
}
227+
else {
228+
return file
229+
}
230+
}().pathExtension
231+
}
221232

222233

test/Constraints/diagnostics.swift

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -465,9 +465,12 @@ func f20371273() {
465465

466466

467467
// <rdar://problem/20921068> Swift fails to compile: [0].map() { _ in let r = (1,2).0; return r }
468-
// FIXME: Should complain about not having a return type annotation in the closure.
469-
[0].map { _ in let r = (1,2).0; return r }
470-
// expected-error @-1 {{expression type '[_]' is ambiguous without more context}}
468+
[0].map { // expected-error {{unable to infer closure return type in current context}}
469+
_ in
470+
let r = (1,2).0
471+
return r
472+
}
473+
471474

472475
// <rdar://problem/21078316> Less than useful error message when using map on optional dictionary type
473476
func rdar21078316() {

test/expr/closure/closures.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ Void(0) // expected-error{{argument passed to call that takes no arguments}}
259259
_ = {0}
260260

261261
// <rdar://problem/22086634> "multi-statement closures require an explicit return type" should be an error not a note
262-
let samples = { // expected-error {{type of expression is ambiguous without more context}}
262+
let samples = { // expected-error {{unable to infer closure return type in current context}}
263263
// FIXME: This diagnostic should be improved, we can infer a type for the closure expr from
264264
// its body (by trying really hard in diagnostic generation) and say that we need an explicit
265265
// contextual result specified because we don't do cross-statement type inference or something.

0 commit comments

Comments
 (0)