Skip to content

Commit bc949c3

Browse files
committed
[CSBindings] Don't favor application result types before application happens
Until `ApplicableFunction` constraint is simplified result type associated with it cannot be bound because the binding set if incomplete. Resolves: rdar://139237088
1 parent 0d7054b commit bc949c3

File tree

4 files changed

+41
-3
lines changed

4 files changed

+41
-3
lines changed

include/swift/Sema/ConstraintSystem.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,10 @@ class TypeVariableType::Implementation {
486486
/// Determine whether this type variable represents a subscript result type.
487487
bool isSubscriptResultType() const;
488488

489+
/// Determine whether this type variable represents a result type of an
490+
/// application i.e. a call, an operator, or a subscript.
491+
bool isApplicationResultType() const;
492+
489493
/// Determine whether this type variable represents an opened
490494
/// type parameter pack.
491495
bool isParameterPack() const;

lib/Sema/CSBindings.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1293,9 +1293,16 @@ bool BindingSet::favoredOverDisjunction(Constraint *disjunction) const {
12931293

12941294
return !hasConversions(binding.BindingType);
12951295
})) {
1296-
// Result type of subscript could be l-value so we can't bind it early.
1297-
if (!TypeVar->getImpl().isSubscriptResultType() &&
1298-
llvm::none_of(Info.DelayedBy, [](const Constraint *constraint) {
1296+
bool isApplicationResultType = TypeVar->getImpl().isApplicationResultType();
1297+
if (llvm::none_of(Info.DelayedBy, [&isApplicationResultType](
1298+
const Constraint *constraint) {
1299+
// Let's not attempt to bind result type before application
1300+
// happens. For example because it could be discardable or
1301+
// l-value (subscript applications).
1302+
if (isApplicationResultType &&
1303+
constraint->getKind() == ConstraintKind::ApplicableFunction)
1304+
return true;
1305+
12991306
return constraint->getKind() == ConstraintKind::Disjunction ||
13001307
constraint->getKind() == ConstraintKind::ValueMember;
13011308
}))

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,16 @@ bool TypeVariableType::Implementation::isSubscriptResultType() const {
175175
KeyPathExpr::Component::Kind::UnresolvedSubscript;
176176
}
177177

178+
bool TypeVariableType::Implementation::isApplicationResultType() const {
179+
if (!(locator && locator->getAnchor()))
180+
return false;
181+
182+
if (!locator->isLastElement<LocatorPathElt::FunctionResult>())
183+
return false;
184+
185+
return isExpr<ApplyExpr>(locator->getAnchor()) || isSubscriptResultType();
186+
}
187+
178188
bool TypeVariableType::Implementation::isParameterPack() const {
179189
return locator
180190
&& locator->isForGenericParameter()

test/Constraints/async.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,3 +180,20 @@ struct OverloadInImplicitAsyncClosure {
180180

181181
init(int: Int) throws { }
182182
}
183+
184+
@available(SwiftStdlib 5.5, *)
185+
func test(_: Int) async throws {}
186+
187+
@discardableResult
188+
@available(SwiftStdlib 5.5, *)
189+
func test(_: Int) -> String { "" }
190+
191+
@available(SwiftStdlib 5.5, *)
192+
func compute(_: @escaping () -> Void) {}
193+
194+
@available(SwiftStdlib 5.5, *)
195+
func test_sync_in_closure_context() {
196+
compute {
197+
test(42) // Ok (select sync overloads and discards the result)
198+
}
199+
}

0 commit comments

Comments
 (0)