@@ -1646,7 +1646,9 @@ bool TypeChecker::coerceParameterListToType(ParameterList *P, ClosureExpr *CE,
1646
1646
auto hasParenSugar = [](ArrayRef<AnyFunctionType::Param> params) -> bool {
1647
1647
if (params.size () == 1 ) {
1648
1648
const auto ¶m = params.front ();
1649
- return !param.hasLabel () && !param.isVariadic ();
1649
+ return (!param.hasLabel () &&
1650
+ !param.isVariadic () &&
1651
+ !param.isInOut ());
1650
1652
}
1651
1653
1652
1654
return false ;
@@ -1661,36 +1663,28 @@ bool TypeChecker::coerceParameterListToType(ParameterList *P, ClosureExpr *CE,
1661
1663
return type;
1662
1664
};
1663
1665
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.
1669
1677
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.
1674
1681
if (P->size () == 1 )
1675
1682
return handleParameter (P->get (0 ), underlyingTy, /* mutable*/ false );
1676
- }
1677
1683
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 ¶m = 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);
1690
1687
}
1691
- diagnose (P->getStartLoc (), diag::tuple_pattern_in_non_tuple_context,
1692
- param.getType ());
1693
- hadError = true ;
1694
1688
}
1695
1689
1696
1690
// The number of elements must match exactly.
0 commit comments