Skip to content

Commit 511c3c3

Browse files
committed
[CSSimplify] Prevent contextual mismatch diagnostics from seeing one-element tuples
If solver had to introduce an unlabeled single-element tuple around contextual type, let's strip it and fix as a regular contextual mismatch (instead of a tuple mismatch) because this action should be transparent to diagnostics.
1 parent f73d722 commit 511c3c3

File tree

1 file changed

+28
-0
lines changed

1 file changed

+28
-0
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5114,6 +5114,19 @@ bool ConstraintSystem::repairFailures(
51145114
});
51155115
};
51165116

5117+
// Check whether this is a tuple with a single unlabeled element
5118+
// i.e. `(_: Int)` and return type of that element if so. Note that
5119+
// if the element is pack expansion type the tuple is significant.
5120+
auto isSingleUnlabeledElementTuple = [](Type type) -> Type {
5121+
if (auto *tuple = type->getAs<TupleType>()) {
5122+
if (tuple->getNumElements() == 1 && !tuple->getElement(0).hasName()) {
5123+
auto eltType = tuple->getElement(0).getType();
5124+
return isPackExpansionType(eltType) ? Type() : eltType;
5125+
}
5126+
}
5127+
return Type();
5128+
};
5129+
51175130
if (repairArrayLiteralUsedAsDictionary(*this, lhs, rhs, matchKind,
51185131
conversionsOrFixes,
51195132
getConstraintLocator(locator)))
@@ -5928,6 +5941,14 @@ bool ConstraintSystem::repairFailures(
59285941
conversionsOrFixes.push_back(fix);
59295942
}
59305943

5944+
// Solver can unwrap contextual type in an unlabeled one-element tuple
5945+
// while matching type to a tuple that contains one or more pack expansion
5946+
// types (because such tuples can loose their elements under substitution),
5947+
// if that's the case, let's just produce a regular contextual mismatch fix.
5948+
if (auto contextualType = isSingleUnlabeledElementTuple(rhs)) {
5949+
rhs = contextualType;
5950+
}
5951+
59315952
if (purpose == CTP_Initialization && lhs->is<TupleType>() &&
59325953
rhs->is<TupleType>()) {
59335954
auto *fix = AllowTupleTypeMismatch::create(*this, lhs, rhs,
@@ -6123,6 +6144,13 @@ bool ConstraintSystem::repairFailures(
61236144
if (tupleLocator->findLast<LocatorPathElt::OptionalPayload>())
61246145
break;
61256146

6147+
if (tupleLocator->isForContextualType()) {
6148+
if (auto contextualTy = isSingleUnlabeledElementTuple(rhs)) {
6149+
return repairFailures(lhs, contextualTy, matchKind, flags,
6150+
conversionsOrFixes, tupleLocator);
6151+
}
6152+
}
6153+
61266154
ConstraintFix *fix;
61276155
if (tupleLocator->isLastElement<LocatorPathElt::FunctionArgument>()) {
61286156
fix = AllowFunctionTypeMismatch::create(*this, lhs, rhs, tupleLocator, index);

0 commit comments

Comments
 (0)