Skip to content

Commit dd7b62c

Browse files
committed
Sema: Fix crash with ambiguous overload inside a trailing closure
Any ambiguity inside of a call with a trailing closure call was going down the code path that would tell you to add an argument label... but the ambiguity might not be with the call that has the trailing closure itself, and instead something inside.
1 parent 1e93d73 commit dd7b62c

File tree

2 files changed

+15
-2
lines changed

2 files changed

+15
-2
lines changed

lib/Sema/CSDiag.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -325,13 +325,17 @@ static DeclName getOverloadChoiceName(ArrayRef<OverloadChoice> choices) {
325325

326326
/// Returns true if any diagnostics were emitted.
327327
static bool
328-
tryDiagnoseTrailingClosureAmbiguity(TypeChecker &tc, const Expr *expr,
328+
tryDiagnoseTrailingClosureAmbiguity(TypeChecker &tc,
329+
const Expr *expr,
330+
const Expr *anchor,
329331
ArrayRef<OverloadChoice> choices) {
330332
auto *callExpr = dyn_cast<CallExpr>(expr);
331333
if (!callExpr)
332334
return false;
333335
if (!callExpr->hasTrailingClosure())
334336
return false;
337+
if (callExpr->getFn() != anchor)
338+
return false;
335339

336340
llvm::SmallMapVector<Identifier, const ValueDecl *, 8> choicesByLabel;
337341
for (const OverloadChoice &choice : choices) {
@@ -465,7 +469,7 @@ static bool diagnoseAmbiguity(ConstraintSystem &cs,
465469
: diag::ambiguous_decl_ref,
466470
name);
467471

468-
if (tryDiagnoseTrailingClosureAmbiguity(tc, expr, overload.choices))
472+
if (tryDiagnoseTrailingClosureAmbiguity(tc, expr, anchor, overload.choices))
469473
return true;
470474

471475
// Emit candidates. Use a SmallPtrSet to make sure only emit a particular

test/Constraints/diagnostics.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -931,3 +931,12 @@ let _ = (r29850459() ? r29850459_a : r29850459_b) + 42.0 // expected-error {{bin
931931
// expected-note@-1 {{overloads for '+' exist with these partially matching parameter lists: (Double, Double), (Int, Int), (Int, UnsafeMutablePointer<Pointee>), (Int, UnsafePointer<Pointee>)}}
932932
let _ = ((r29850459_flag || r29850459()) ? r29850459_a : r29850459_b) + 42.0 // expected-error {{binary operator '+' cannot be applied to operands of type 'Int' and 'Double'}}
933933
// expected-note@-1 {{overloads for '+' exist with these partially matching parameter lists: (Double, Double), (Int, Int), (Int, UnsafeMutablePointer<Pointee>), (Int, UnsafePointer<Pointee>)}}
934+
935+
// Ambiguous overload inside a trailing closure
936+
937+
func ambiguousCall() -> Int {} // expected-note {{found this candidate}}
938+
func ambiguousCall() -> Float {} // expected-note {{found this candidate}}
939+
940+
func takesClosure(fn: () -> ()) {}
941+
942+
takesClosure() { ambiguousCall() } // expected-error {{ambiguous use of 'ambiguousCall()'}}

0 commit comments

Comments
 (0)