Skip to content

Commit 93b205e

Browse files
committed
Sema: Simplify coerceParameterListToType()
1 parent 20dc9a4 commit 93b205e

File tree

4 files changed

+11
-111
lines changed

4 files changed

+11
-111
lines changed

lib/Sema/CSApply.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7315,8 +7315,7 @@ namespace {
73157315
// Coerce the pattern, in case we resolved something.
73167316
auto fnType = cs.getType(closure)->castTo<FunctionType>();
73177317
auto *params = closure->getParameters();
7318-
if (tc.coerceParameterListToType(params, closure, fnType))
7319-
return { false, nullptr };
7318+
tc.coerceParameterListToType(params, closure, fnType);
73207319

73217320
// Require layout of dependent types that could be used to materialize
73227321
// metadata types/conformances during IRGen.

lib/Sema/CSDiag.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5741,8 +5741,7 @@ bool FailureDiagnosis::diagnoseClosureExpr(
57415741
}
57425742

57435743
// Coerce parameter types here only if there are no unresolved
5744-
if (CS.TC.coerceParameterListToType(params, CE, fnType))
5745-
return true;
5744+
CS.TC.coerceParameterListToType(params, CE, fnType);
57465745
expectedResultType = fnType->getResult();
57475746
}
57485747

lib/Sema/TypeCheckPattern.cpp

Lines changed: 8 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1588,28 +1588,13 @@ bool TypeChecker::coercePatternToType(Pattern *&P, TypeResolution resolution,
15881588

15891589
/// Coerce the specified parameter list of a ClosureExpr to the specified
15901590
/// 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,
15981592
AnyFunctionType *FN) {
1599-
llvm::SmallVector<AnyFunctionType::Param, 4> params;
1600-
params.reserve(FN->getNumParams());
1601-
1602-
bool hadError = false;
1603-
for (const auto &param : FN->getParams()) {
1604-
params.push_back(param);
1605-
hadError |= param.getPlainType()->hasError();
1606-
}
16071593

16081594
// Local function to check if the given type is valid e.g. doesn't have
16091595
// errors, type variables or unresolved types related to it.
16101596
auto isValidType = [](Type type) -> bool {
1611-
return !(type.isNull() || type->hasError() || type->hasUnresolvedType() ||
1612-
type->hasTypeVariable());
1597+
return !(type->hasError() || type->hasUnresolvedType());
16131598
};
16141599

16151600
// Local function to check whether type of given parameter
@@ -1624,31 +1609,9 @@ bool TypeChecker::coerceParameterListToType(ParameterList *P, ClosureExpr *CE,
16241609
return true;
16251610
};
16261611

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)
16501614
param->setSpecifier(VarDecl::Specifier::InOut);
1651-
}
16521615

16531616
// If contextual type is invalid and we have a valid argument type
16541617
// trying to coerce argument to contextual type would mean erasing
@@ -1659,76 +1622,18 @@ bool TypeChecker::coerceParameterListToType(ParameterList *P, ClosureExpr *CE,
16591622
}
16601623

16611624
checkTypeModifyingDeclAttributes(param);
1662-
return hadError;
16631625
};
16641626

1665-
auto hasParenSugar = [](ArrayRef<AnyFunctionType::Param> params) -> bool {
1666-
if (params.size() == 1) {
1667-
const auto &param = 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 &param) -> 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-
17131627
// Coerce each parameter to the respective type.
1628+
ArrayRef<AnyFunctionType::Param> params = FN->getParams();
17141629
for (unsigned i = 0, e = P->size(); i != e; ++i) {
17151630
auto &param = 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-
17261631
assert(param->getArgumentName().empty() &&
17271632
"Closures cannot have API names");
17281633

1729-
hadError |= handleParameter(param, CoercionType, isMutableParam);
1634+
handleParameter(param,
1635+
params[i].getParameterType(),
1636+
params[i].isInOut());
17301637
assert(!param->isDefaultArgument() && "Closures cannot have default args");
17311638
}
1732-
1733-
return hadError;
17341639
}

lib/Sema/TypeChecker.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1501,10 +1501,7 @@ class TypeChecker final : public LazyResolver {
15011501

15021502
/// Coerce the specified parameter list of a ClosureExpr to the specified
15031503
/// contextual type.
1504-
///
1505-
/// \returns true if an error occurred, false otherwise.
1506-
bool coerceParameterListToType(ParameterList *P, ClosureExpr *CE, AnyFunctionType *FN);
1507-
1504+
void coerceParameterListToType(ParameterList *P, ClosureExpr *CE, AnyFunctionType *FN);
15081505

15091506
/// Type-check an initialized variable pattern declaration.
15101507
bool typeCheckBinding(Pattern *&P, Expr *&Init, DeclContext *DC);

0 commit comments

Comments
 (0)