Skip to content

Commit 68d146e

Browse files
authored
Merge pull request #68317 from xedin/delay-default-inference
[CSBindings] Delay default binding production until inference is exhausted
2 parents 9876411 + 56f390d commit 68d146e

File tree

2 files changed

+44
-1
lines changed

2 files changed

+44
-1
lines changed

lib/Sema/CSBindings.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2052,7 +2052,7 @@ bool TypeVarBindingProducer::computeNext() {
20522052
}
20532053
}
20542054

2055-
if (NumTries == 0) {
2055+
if (newBindings.empty()) {
20562056
// Add defaultable constraints (if any).
20572057
for (auto *constraint : DelayedDefaults) {
20582058
if (constraint->getKind() == ConstraintKind::FallbackType) {
@@ -2065,6 +2065,9 @@ bool TypeVarBindingProducer::computeNext() {
20652065

20662066
addNewBinding(getDefaultBinding(constraint));
20672067
}
2068+
2069+
// Drop all of the default since we have converted them into bindings.
2070+
DelayedDefaults.clear();
20682071
}
20692072

20702073
if (newBindings.empty())

unittests/Sema/BindingInferenceTests.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,3 +395,43 @@ TEST_F(SemaTest, TestNoDoubleVoidClosureResultInference) {
395395

396396
verifyInference(closureResultWithoutVoid, 3);
397397
}
398+
399+
TEST_F(SemaTest, TestSupertypeInferenceWithDefaults) {
400+
ConstraintSystemOptions options;
401+
ConstraintSystem cs(DC, options);
402+
403+
auto *genericArg = cs.createTypeVariable(
404+
cs.getConstraintLocator({}, ConstraintLocator::GenericArgument),
405+
/*options=*/0);
406+
407+
// KeyPath<String, Int> i.e. \.utf8.count or something similar
408+
auto keyPath =
409+
BoundGenericType::get(Context.getKeyPathDecl(), /*parent=*/Type(),
410+
{getStdlibType("String"), getStdlibType("Int")});
411+
412+
cs.addConstraint(ConstraintKind::Conversion, keyPath, genericArg,
413+
cs.getConstraintLocator({}));
414+
415+
cs.addConstraint(ConstraintKind::Defaultable, genericArg, Context.TheAnyType,
416+
cs.getConstraintLocator({}));
417+
418+
auto bindings = cs.getBindingsFor(genericArg);
419+
TypeVarBindingProducer producer(bindings);
420+
421+
llvm::SmallVector<Type, 4> inferredTypes;
422+
while (auto binding = producer()) {
423+
ASSERT_TRUE(binding.has_value());
424+
inferredTypes.push_back(binding->getType());
425+
}
426+
427+
// The inference should produce 4 types: KeyPath<String, Int>,
428+
// PartialKeyPath<String>, AnyKeyPath and Any - in that order.
429+
430+
ASSERT_EQ(inferredTypes.size(), 4);
431+
ASSERT_TRUE(inferredTypes[0]->isEqual(keyPath));
432+
ASSERT_TRUE(inferredTypes[1]->isEqual(
433+
BoundGenericType::get(Context.getPartialKeyPathDecl(),
434+
/*parent=*/Type(), {getStdlibType("String")})));
435+
ASSERT_TRUE(inferredTypes[2]->isEqual(getStdlibType("AnyKeyPath")));
436+
ASSERT_TRUE(inferredTypes[3]->isEqual(Context.TheAnyType));
437+
}

0 commit comments

Comments
 (0)