Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions lib/Sema/CSSimplify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10926,6 +10926,24 @@ bool ConstraintSystem::simplifyAppliedOverloadsImpl(

auto *argList = getArgumentList(getConstraintLocator(locator));

// If argument list has trailing closures and this is `init` call to
// a callable type, let's not filter anything since there is a possibility
// that it needs an implicit `.callAsFunction` to work.
if (argList && argList->hasAnyTrailingClosures()) {
if (disjunction->getLocator()
->isLastElement<LocatorPathElt::ConstructorMember>()) {
auto choice = disjunction->getNestedConstraints()[0]->getOverloadChoice();
if (auto *decl = choice.getDeclOrNull()) {
auto *dc = decl->getDeclContext();
if (auto *parent = dc->getSelfNominalTypeDecl()) {
auto type = parent->getDeclaredInterfaceType();
if (type->isCallableNominalType(DC))
return false;
}
}
}
}

// Consider each of the constraints in the disjunction.
retry_after_fail:
bool hasUnhandledConstraints = false;
Expand Down
7 changes: 7 additions & 0 deletions lib/Sema/ConstraintSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,13 @@ ConstraintLocator *ConstraintSystem::getCalleeLocator(
}

if (auto *UDE = getAsExpr<UnresolvedDotExpr>(anchor)) {
if (UDE->isImplicit() &&
UDE->getName().getBaseName() == Context.Id_callAsFunction) {
return getConstraintLocator(anchor,
{LocatorPathElt::ApplyFunction(),
LocatorPathElt::ImplicitCallAsFunction()});
}

return getConstraintLocator(
anchor, TypeChecker::getSelfForInitDelegationInConstructor(DC, UDE)
? ConstraintLocator::ConstructorMember
Expand Down
22 changes: 22 additions & 0 deletions test/Constraints/callAsFunction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,25 @@ struct Test {
}
}
}

// rdar://92912878 - filtering prevents disambiguation of `.callAsFunction`
func test_no_filtering_of_overloads() {
struct S {
init() {}
init(_: String) {}

func callAsFunction<T>(_ fn: () -> T) -> T {
fn()
}
}

func test(_: () -> Void) {
}

test {
_ = S() { // Ok
_ = 42
print("Hello")
}
}
}
24 changes: 24 additions & 0 deletions test/Constraints/result_builder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1174,3 +1174,27 @@ let list3 = list {
}
print(list3)
// CHECK: (cons "4" (cons (cons "3" (cons 2.0 nil)) (cons 1 nil)))

func test_callAsFunction_with_resultBuilder() {
struct CallableTest {
func callAsFunction<T>(@TupleBuilder _ body: (Bool) -> T) {
print(body(true))
}
}

CallableTest() {
0
"with parens"
$0
}

CallableTest {
1
"without parens"
$0
}
}

test_callAsFunction_with_resultBuilder()
// CHECK: (0, "with parens", true)
// CHECK: (1, "without parens", true)