File tree Expand file tree Collapse file tree 4 files changed +71
-0
lines changed Expand file tree Collapse file tree 4 files changed +71
-0
lines changed Original file line number Diff line number Diff line change @@ -10931,6 +10931,24 @@ bool ConstraintSystem::simplifyAppliedOverloadsImpl(
1093110931
1093210932 auto *argList = getArgumentList(getConstraintLocator(locator));
1093310933
10934+ // If argument list has trailing closures and this is `init` call to
10935+ // a callable type, let's not filter anything since there is a possibility
10936+ // that it needs an implicit `.callAsFunction` to work.
10937+ if (argList && argList->hasAnyTrailingClosures()) {
10938+ if (disjunction->getLocator()
10939+ ->isLastElement<LocatorPathElt::ConstructorMember>()) {
10940+ auto choice = disjunction->getNestedConstraints()[0]->getOverloadChoice();
10941+ if (auto *decl = choice.getDeclOrNull()) {
10942+ auto *dc = decl->getDeclContext();
10943+ if (auto *parent = dc->getSelfNominalTypeDecl()) {
10944+ auto type = parent->getDeclaredInterfaceType();
10945+ if (type->isCallableNominalType(DC))
10946+ return false;
10947+ }
10948+ }
10949+ }
10950+ }
10951+
1093410952 // Consider each of the constraints in the disjunction.
1093510953retry_after_fail:
1093610954 bool hasUnhandledConstraints = false;
Original file line number Diff line number Diff line change @@ -564,6 +564,13 @@ ConstraintLocator *ConstraintSystem::getCalleeLocator(
564564 }
565565
566566 if (auto *UDE = getAsExpr<UnresolvedDotExpr>(anchor)) {
567+ if (UDE->isImplicit () &&
568+ UDE->getName ().getBaseName () == Context.Id_callAsFunction ) {
569+ return getConstraintLocator (anchor,
570+ {LocatorPathElt::ApplyFunction (),
571+ LocatorPathElt::ImplicitCallAsFunction ()});
572+ }
573+
567574 return getConstraintLocator (
568575 anchor, TypeChecker::getSelfForInitDelegationInConstructor (DC, UDE)
569576 ? ConstraintLocator::ConstructorMember
Original file line number Diff line number Diff line change @@ -29,3 +29,25 @@ struct Test {
2929 }
3030 }
3131}
32+
33+ // rdar://92912878 - filtering prevents disambiguation of `.callAsFunction`
34+ func test_no_filtering_of_overloads( ) {
35+ struct S {
36+ init ( ) { }
37+ init ( _: String ) { }
38+
39+ func callAsFunction< T> ( _ fn: ( ) -> T ) -> T {
40+ fn ( )
41+ }
42+ }
43+
44+ func test( _: ( ) -> Void ) {
45+ }
46+
47+ test {
48+ _ = S ( ) { // Ok
49+ _ = 42
50+ print ( " Hello " )
51+ }
52+ }
53+ }
Original file line number Diff line number Diff line change @@ -1174,3 +1174,27 @@ let list3 = list {
11741174}
11751175print ( list3)
11761176// CHECK: (cons "4" (cons (cons "3" (cons 2.0 nil)) (cons 1 nil)))
1177+
1178+ func test_callAsFunction_with_resultBuilder( ) {
1179+ struct CallableTest {
1180+ func callAsFunction< T> ( @TupleBuilder _ body: ( Bool ) -> T ) {
1181+ print ( body ( true ) )
1182+ }
1183+ }
1184+
1185+ CallableTest ( ) {
1186+ 0
1187+ " with parens "
1188+ $0
1189+ }
1190+
1191+ CallableTest {
1192+ 1
1193+ " without parens "
1194+ $0
1195+ }
1196+ }
1197+
1198+ test_callAsFunction_with_resultBuilder ( )
1199+ // CHECK: (0, "with parens", true)
1200+ // CHECK: (1, "without parens", true)
You can’t perform that action at this time.
0 commit comments