Merge pull request #65830 from xedin/rdar-108904190

[CSSimplify] Allow converting pack expansion types and tuples with pack expansions to Void for closure result
This commit is contained in:
Pavel Yaskevich
2023-05-16 09:56:27 -07:00
committed by GitHub
2 changed files with 32 additions and 16 deletions

View File

@@ -6989,6 +6989,14 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
return formUnsolvedResult();
}
// Closure result is allowed to convert to Void in certain circumstances,
// let's forego tuple matching because it is guaranteed to fail and jump
// to `() -> T` to `() -> Void` rule.
if (locator.endsWith<LocatorPathElt::ClosureBody>()) {
if (containsPackExpansionType(tuple1) && tuple2->isVoid())
break;
}
// Add each tuple type to the locator before matching the element types.
// This is useful for diagnostics, because the error message can use the
// full tuple type for several element mismatches. Use the original types
@@ -7286,22 +7294,6 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
}
}
// Matching types where one side is a pack expansion and the other is not
// means a pack expansion was used where it isn't supported.
if (type1->is<PackExpansionType>() != type2->is<PackExpansionType>()) {
if (!shouldAttemptFixes())
return getTypeMatchFailure(locator);
if (type1->isPlaceholder() || type2->isPlaceholder())
return getTypeMatchSuccess();
auto *loc = getConstraintLocator(locator);
if (recordFix(AllowInvalidPackExpansion::create(*this, loc)))
return getTypeMatchFailure(locator);
return getTypeMatchSuccess();
}
if (kind >= ConstraintKind::Conversion) {
// An lvalue of type T1 can be converted to a value of type T2 so long as
// T1 is convertible to T2 (by loading the value). Note that we cannot get
@@ -7724,6 +7716,22 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
}
}
// Matching types where one side is a pack expansion and the other is not
// means a pack expansion was used where it isn't supported.
if (type1->is<PackExpansionType>() != type2->is<PackExpansionType>()) {
if (!shouldAttemptFixes())
return getTypeMatchFailure(locator);
if (type1->isPlaceholder() || type2->isPlaceholder())
return getTypeMatchSuccess();
auto *loc = getConstraintLocator(locator);
if (recordFix(AllowInvalidPackExpansion::create(*this, loc)))
return getTypeMatchFailure(locator);
return getTypeMatchSuccess();
}
// Attempt fixes iff it's allowed, both types are concrete and
// we are not in the middle of attempting one already.
if (shouldAttemptFixes() && !flags.contains(TMF_ApplyingFix)) {