Skip to content

Commit b1e55cb

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. (cherry picked from commit 38ee650)
1 parent 2ae78d6 commit b1e55cb

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
@@ -5110,6 +5110,19 @@ bool ConstraintSystem::repairFailures(
51105110
});
51115111
};
51125112

5113+
// Check whether this is a tuple with a single unlabeled element
5114+
// i.e. `(_: Int)` and return type of that element if so. Note that
5115+
// if the element is pack expansion type the tuple is significant.
5116+
auto isSingleUnlabeledElementTuple = [](Type type) -> Type {
5117+
if (auto *tuple = type->getAs<TupleType>()) {
5118+
if (tuple->getNumElements() == 1 && !tuple->getElement(0).hasName()) {
5119+
auto eltType = tuple->getElement(0).getType();
5120+
return isPackExpansionType(eltType) ? Type() : eltType;
5121+
}
5122+
}
5123+
return Type();
5124+
};
5125+
51135126
if (repairArrayLiteralUsedAsDictionary(*this, lhs, rhs, matchKind,
51145127
conversionsOrFixes,
51155128
getConstraintLocator(locator)))
@@ -5916,6 +5929,14 @@ bool ConstraintSystem::repairFailures(
59165929
conversionsOrFixes.push_back(fix);
59175930
}
59185931

5932+
// Solver can unwrap contextual type in an unlabeled one-element tuple
5933+
// while matching type to a tuple that contains one or more pack expansion
5934+
// types (because such tuples can loose their elements under substitution),
5935+
// if that's the case, let's just produce a regular contextual mismatch fix.
5936+
if (auto contextualType = isSingleUnlabeledElementTuple(rhs)) {
5937+
rhs = contextualType;
5938+
}
5939+
59195940
if (purpose == CTP_Initialization && lhs->is<TupleType>() &&
59205941
rhs->is<TupleType>()) {
59215942
auto *fix = AllowTupleTypeMismatch::create(*this, lhs, rhs,
@@ -6111,6 +6132,13 @@ bool ConstraintSystem::repairFailures(
61116132
if (tupleLocator->findLast<LocatorPathElt::OptionalPayload>())
61126133
break;
61136134

6135+
if (tupleLocator->isForContextualType()) {
6136+
if (auto contextualTy = isSingleUnlabeledElementTuple(rhs)) {
6137+
return repairFailures(lhs, contextualTy, matchKind, flags,
6138+
conversionsOrFixes, tupleLocator);
6139+
}
6140+
}
6141+
61146142
ConstraintFix *fix;
61156143
if (tupleLocator->isLastElement<LocatorPathElt::FunctionArgument>()) {
61166144
fix = AllowFunctionTypeMismatch::create(*this, lhs, rhs, tupleLocator, index);

0 commit comments

Comments
 (0)