Skip to content

Commit 70c370d

Browse files
committed
[CSSimplify] Propagate contextual result type into result builder transformed closure
Propagate fully or partially resolved contextual type down into the body of result builder transformed closure by eagerly binding intermediate body result type to the contextual one. This helps to determine when closure body could be solved early. Resolves: rdar://106364495
1 parent 869fc17 commit 70c370d

File tree

1 file changed

+35
-20
lines changed

1 file changed

+35
-20
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3532,27 +3532,8 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
35323532
}
35333533
}
35343534

3535-
auto resultMatchKind = subKind;
3536-
// Performance optimization: Propagate fully or partially resolved contextual
3537-
// type down into the body of result builder transformed closure by eagerly
3538-
// binding intermediate body result type to the contextual one. This helps to
3539-
// determine when closure body could be solved early.
3540-
//
3541-
// TODO: This could be extended to cover all multi-statement closures.
3542-
//
3543-
// See \c BindingSet::favoredOverConjunction for more details.
3544-
if (resultMatchKind >= ConstraintKind::Subtype &&
3545-
!func2->getResult()->isTypeVariableOrMember()) {
3546-
if (auto *closure = getAsExpr<ClosureExpr>(locator.trySimplifyToExpr())) {
3547-
if (!closure->hasExplicitResultType() &&
3548-
getAppliedResultBuilderTransform(closure)) {
3549-
resultMatchKind = ConstraintKind::Equal;
3550-
}
3551-
}
3552-
}
3553-
35543535
// Result type can be covariant (or equal).
3555-
return matchTypes(func1->getResult(), func2->getResult(), resultMatchKind,
3536+
return matchTypes(func1->getResult(), func2->getResult(), subKind,
35563537
subflags,
35573538
locator.withPathElement(ConstraintLocator::FunctionResult));
35583539
}
@@ -6646,6 +6627,40 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
66466627
return matchTypesBindTypeVar(typeVar1, type2, kind, flags, locator,
66476628
formUnsolvedResult);
66486629
}
6630+
6631+
// Performance optimization: Propagate fully or partially resolved
6632+
// contextual type down into the body of result builder transformed
6633+
// closure by eagerly binding intermediate body result type to the
6634+
// contextual one. This helps to determine when closure body could be
6635+
// solved early.
6636+
//
6637+
// TODO: This could be extended to cover all multi-statement closures.
6638+
//
6639+
// See \c BindingSet::favoredOverConjunction for more details.
6640+
if (!typeVar2 && locator.endsWith<LocatorPathElt::FunctionResult>()) {
6641+
SmallVector<LocatorPathElt> path;
6642+
auto anchor = locator.getLocatorParts(path);
6643+
6644+
// Drop `FunctionResult` element.
6645+
path.pop_back();
6646+
6647+
ClosureExpr *closure = nullptr;
6648+
{
6649+
// This avoids a new locator allocation.
6650+
SourceRange range;
6651+
ArrayRef<LocatorPathElt> scratchPath(path);
6652+
simplifyLocator(anchor, scratchPath, range);
6653+
6654+
if (scratchPath.empty())
6655+
closure = getAsExpr<ClosureExpr>(anchor);
6656+
}
6657+
6658+
if (closure && !closure->hasExplicitResultType() &&
6659+
getAppliedResultBuilderTransform(closure)) {
6660+
return matchTypesBindTypeVar(typeVar1, type2, ConstraintKind::Equal,
6661+
flags, locator, formUnsolvedResult);
6662+
}
6663+
}
66496664
}
66506665

66516666
// If the left-hand side of a 'sequence element' constraint

0 commit comments

Comments
 (0)