@@ -1588,28 +1588,13 @@ bool TypeChecker::coercePatternToType(Pattern *&P, TypeResolution resolution,
1588
1588
1589
1589
// / Coerce the specified parameter list of a ClosureExpr to the specified
1590
1590
// / contextual type.
1591
- // /
1592
- // / \returns true if an error occurred, false otherwise.
1593
- // /
1594
- // / TODO: These diagnostics should be a lot better now that we know this is
1595
- // / all specific to closures.
1596
- // /
1597
- bool TypeChecker::coerceParameterListToType (ParameterList *P, ClosureExpr *CE,
1591
+ void TypeChecker::coerceParameterListToType (ParameterList *P, ClosureExpr *CE,
1598
1592
AnyFunctionType *FN) {
1599
- llvm::SmallVector<AnyFunctionType::Param, 4 > params;
1600
- params.reserve (FN->getNumParams ());
1601
-
1602
- bool hadError = false ;
1603
- for (const auto ¶m : FN->getParams ()) {
1604
- params.push_back (param);
1605
- hadError |= param.getPlainType ()->hasError ();
1606
- }
1607
1593
1608
1594
// Local function to check if the given type is valid e.g. doesn't have
1609
1595
// errors, type variables or unresolved types related to it.
1610
1596
auto isValidType = [](Type type) -> bool {
1611
- return !(type.isNull () || type->hasError () || type->hasUnresolvedType () ||
1612
- type->hasTypeVariable ());
1597
+ return !(type->hasError () || type->hasUnresolvedType ());
1613
1598
};
1614
1599
1615
1600
// Local function to check whether type of given parameter
@@ -1624,31 +1609,9 @@ bool TypeChecker::coerceParameterListToType(ParameterList *P, ClosureExpr *CE,
1624
1609
return true ;
1625
1610
};
1626
1611
1627
- // Sometimes a scalar type gets applied to a single-argument parameter list.
1628
- auto handleParameter = [&](ParamDecl *param, Type ty, bool forceMutable) -> bool {
1629
- bool hadError = false ;
1630
-
1631
- // Check that the type, if explicitly spelled, is ok.
1632
- if (param->getTypeLoc ().getTypeRepr ()) {
1633
- hadError |= validateParameterType (param,
1634
- TypeResolution::forContextual (CE),
1635
- None, *this );
1636
-
1637
- // Now that we've type checked the explicit argument type, see if it
1638
- // agrees with the contextual type.
1639
- auto paramType = param->getTypeLoc ().getType ();
1640
- // Coerce explicitly specified argument type to contextual type
1641
- // only if both types are valid and do not match.
1642
- if (!hadError && isValidType (ty) && !ty->isEqual (paramType)) {
1643
- param->setType (ty);
1644
- param->setInterfaceType (ty->mapTypeOutOfContext ());
1645
- }
1646
- }
1647
-
1648
- assert (ty->isMaterializable ());
1649
- if (forceMutable) {
1612
+ auto handleParameter = [&](ParamDecl *param, Type ty, bool forceMutable) {
1613
+ if (forceMutable)
1650
1614
param->setSpecifier (VarDecl::Specifier::InOut);
1651
- }
1652
1615
1653
1616
// If contextual type is invalid and we have a valid argument type
1654
1617
// trying to coerce argument to contextual type would mean erasing
@@ -1659,76 +1622,18 @@ bool TypeChecker::coerceParameterListToType(ParameterList *P, ClosureExpr *CE,
1659
1622
}
1660
1623
1661
1624
checkTypeModifyingDeclAttributes (param);
1662
- return hadError;
1663
1625
};
1664
1626
1665
- auto hasParenSugar = [](ArrayRef<AnyFunctionType::Param> params) -> bool {
1666
- if (params.size () == 1 ) {
1667
- const auto ¶m = params.front ();
1668
- return (!param.hasLabel () &&
1669
- !param.isVariadic () &&
1670
- !param.isInOut ());
1671
- }
1672
-
1673
- return false ;
1674
- };
1675
-
1676
- auto getType = [](const AnyFunctionType::Param ¶m) -> Type {
1677
- return param.getParameterType ();
1678
- };
1679
-
1680
- // If the closure is called with a single argument of tuple type
1681
- // but the closure body expects multiple parameters, explode the
1682
- // tuple.
1683
- //
1684
- // FIXME: This looks like the wrong place for this; the constraint
1685
- // solver should have inserted an explicit conversion already.
1686
- //
1687
- // The only reason we can get away with this, I think, is that
1688
- // at the SIL level, recursive tuple expansion lowers
1689
- // ((T, U)) -> () and (T, U) -> () to the same function type,
1690
- // and SILGen doesn't enforce AST invariaints very strictly.
1691
- if (!hadError && hasParenSugar (params)) {
1692
- auto underlyingTy = params.front ().getPlainType ();
1693
- if (underlyingTy->is <TupleType>()) {
1694
- // If we're actually expecting a single parameter, handle it normally.
1695
- if (P->size () == 1 )
1696
- return handleParameter (P->get (0 ), underlyingTy, /* mutable*/ false );
1697
-
1698
- // Otherwise, explode the tuple.
1699
- params.clear ();
1700
- FunctionType::decomposeInput (underlyingTy, params);
1701
- }
1702
- }
1703
-
1704
- // The number of elements must match exactly.
1705
- // TODO: incomplete tuple patterns, with some syntax.
1706
- if (!hadError && params.size () != P->size ()) {
1707
- auto fnType = FunctionType::get (params, FN->getResult ());
1708
- diagnose (P->getStartLoc (), diag::closure_argument_list_tuple, fnType,
1709
- params.size (), P->size (), (P->size () == 1 ));
1710
- hadError = true ;
1711
- }
1712
-
1713
1627
// Coerce each parameter to the respective type.
1628
+ ArrayRef<AnyFunctionType::Param> params = FN->getParams ();
1714
1629
for (unsigned i = 0 , e = P->size (); i != e; ++i) {
1715
1630
auto ¶m = P->get (i);
1716
-
1717
- Type CoercionType;
1718
- bool isMutableParam = false ;
1719
- if (hadError) {
1720
- CoercionType = ErrorType::get (Context);
1721
- } else {
1722
- CoercionType = getType (params[i]);
1723
- isMutableParam = params[i].isInOut ();
1724
- }
1725
-
1726
1631
assert (param->getArgumentName ().empty () &&
1727
1632
" Closures cannot have API names" );
1728
1633
1729
- hadError |= handleParameter (param, CoercionType, isMutableParam);
1634
+ handleParameter (param,
1635
+ params[i].getParameterType (),
1636
+ params[i].isInOut ());
1730
1637
assert (!param->isDefaultArgument () && " Closures cannot have default args" );
1731
1638
}
1732
-
1733
- return hadError;
1734
1639
}
0 commit comments