Skip to content

Commit 06392ab

Browse files
committed
Sema: Clean up 'tuple splat' code in coerceParameterListToType()
1 parent f2ae23a commit 06392ab

File tree

1 file changed

+20
-26
lines changed

1 file changed

+20
-26
lines changed

lib/Sema/TypeCheckPattern.cpp

Lines changed: 20 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1646,7 +1646,9 @@ bool TypeChecker::coerceParameterListToType(ParameterList *P, ClosureExpr *CE,
16461646
auto hasParenSugar = [](ArrayRef<AnyFunctionType::Param> params) -> bool {
16471647
if (params.size() == 1) {
16481648
const auto &param = params.front();
1649-
return !param.hasLabel() && !param.isVariadic();
1649+
return (!param.hasLabel() &&
1650+
!param.isVariadic() &&
1651+
!param.isInOut());
16501652
}
16511653

16521654
return false;
@@ -1661,36 +1663,28 @@ bool TypeChecker::coerceParameterListToType(ParameterList *P, ClosureExpr *CE,
16611663
return type;
16621664
};
16631665

1664-
// Check if parameter list only contains one single tuple.
1665-
// If it is, then parameter type would be sugared ParenType
1666-
// with a single underlying TupleType. In that case, check if
1667-
// the closure argument is also one to avoid the tuple splat
1668-
// from happening.
1666+
// If the closure is called with a single argument of tuple type
1667+
// but the closure body expects multiple parameters, explode the
1668+
// tuple.
1669+
//
1670+
// FIXME: This looks like the wrong place for this; the constraint
1671+
// solver should have inserted an explicit conversion already.
1672+
//
1673+
// The only reason we can get away with this, I think, is that
1674+
// at the SIL level, recursive tuple expansion lowers
1675+
// ((T, U)) -> () and (T, U) -> () to the same function type,
1676+
// and SILGen doesn't enforce AST invariaints very strictly.
16691677
if (!hadError && hasParenSugar(params)) {
1670-
auto underlyingTy = params.front().getType();
1671-
1672-
if (underlyingTy->is<TupleType>() &&
1673-
!underlyingTy->castTo<TupleType>()->getVarArgsBaseType()) {
1678+
auto underlyingTy = params.front().getPlainType();
1679+
if (underlyingTy->is<TupleType>()) {
1680+
// If we're actually expecting a single parameter, handle it normally.
16741681
if (P->size() == 1)
16751682
return handleParameter(P->get(0), underlyingTy, /*mutable*/false);
1676-
}
16771683

1678-
// pass (strip paren sugar)
1679-
params.clear();
1680-
FunctionType::decomposeInput(underlyingTy, params);
1681-
}
1682-
1683-
// The context type must be a tuple.
1684-
if (hasParenSugar(params) && !hadError) {
1685-
const auto &param = params.front();
1686-
if (P->size() == 1) {
1687-
assert(P->size() == params.size());
1688-
return handleParameter(P->get(0), getType(param),
1689-
/*mutable*/ param.isInOut());
1684+
// Otherwise, explode the tuple.
1685+
params.clear();
1686+
FunctionType::decomposeInput(underlyingTy, params);
16901687
}
1691-
diagnose(P->getStartLoc(), diag::tuple_pattern_in_non_tuple_context,
1692-
param.getType());
1693-
hadError = true;
16941688
}
16951689

16961690
// The number of elements must match exactly.

0 commit comments

Comments
 (0)