Skip to content

Commit 761d372

Browse files
authored
Reconcile differences from upstream finishApplyDynamicCallable. (swiftlang#26320)
1 parent 3416770 commit 761d372

File tree

1 file changed

+53
-77
lines changed

1 file changed

+53
-77
lines changed

lib/Sema/CSApply.cpp

Lines changed: 53 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1069,6 +1069,10 @@ namespace {
10691069
Expr *finishApply(ApplyExpr *apply, Type openedType,
10701070
ConstraintLocatorBuilder locator);
10711071

1072+
// Resolve @dynamicCallable applications.
1073+
Expr *finishApplyDynamicCallable(const Solution &solution, ApplyExpr *apply,
1074+
ConstraintLocatorBuilder locator);
1075+
10721076
private:
10731077
/// Simplify the given type by substituting all occurrences of
10741078
/// type variables for their fixed types.
@@ -6827,11 +6831,10 @@ Expr *ExprRewriter::convertLiteralInPlace(Expr *literal,
68276831
}
68286832

68296833
// Resolve @dynamicCallable applications.
6830-
static Expr *finishApplyDynamicCallable(ExprRewriter &rewriter,
6831-
ConstraintSystem &cs,
6832-
const Solution &solution,
6833-
ApplyExpr *apply,
6834-
ConstraintLocatorBuilder locator) {
6834+
Expr *
6835+
ExprRewriter::finishApplyDynamicCallable(const Solution &solution,
6836+
ApplyExpr *apply,
6837+
ConstraintLocatorBuilder locator) {
68356838
auto &ctx = cs.getASTContext();
68366839
auto *fn = apply->getFn();
68376840

@@ -6843,13 +6846,13 @@ static Expr *finishApplyDynamicCallable(ExprRewriter &rewriter,
68436846
auto loc = locator.withPathElement(ConstraintLocator::ApplyFunction);
68446847
auto selected = solution.getOverloadChoice(cs.getConstraintLocator(loc));
68456848
auto *method = dyn_cast<FuncDecl>(selected.choice.getDecl());
6846-
auto methodType =
6847-
solution.simplifyType(selected.openedType)->castTo<AnyFunctionType>();
6849+
auto methodType = simplifyType(selected.openedType)->castTo<AnyFunctionType>();
68486850
assert(method->getName() == ctx.Id_dynamicallyCall &&
68496851
"Expected 'dynamicallyCall' method");
68506852
auto params = methodType->getParams();
68516853
assert(params.size() == 1 &&
68526854
"Expected 'dynamicallyCall' method with one parameter");
6855+
auto argumentType = params[0].getParameterType();
68536856
auto argumentLabel = params[0].getLabel();
68546857
assert((argumentLabel == ctx.Id_withArguments ||
68556858
argumentLabel == ctx.Id_withKeywordArguments) &&
@@ -6860,92 +6863,65 @@ static Expr *finishApplyDynamicCallable(ExprRewriter &rewriter,
68606863
// `withKeywordArguments` method.
68616864
bool useKwargsMethod = argumentLabel == ctx.Id_withKeywordArguments;
68626865

6863-
// Construct expression referencing the `dynamicallyCall` method.
6864-
MemberRefExpr *member =
6865-
new (ctx) MemberRefExpr(fn, fn->getEndLoc(), ConcreteDeclRef(method),
6866-
DeclNameLoc(method->getNameLoc()),
6867-
/*Implicit*/ true);
6868-
6869-
cs.setType(member, methodType);
6870-
6866+
// Construct expression referencing the `dynamicallyCall` method.
68716867
bool isDynamic =
68726868
selected.choice.getKind() == OverloadChoiceKind::DeclViaDynamic;
6873-
Expr *memberExpr = rewriter.buildMemberRef(
6874-
member->getBase(), selected.openedFullType, member->getDotLoc(),
6875-
selected.choice, member->getNameLoc(), selected.openedType,
6876-
cs.getConstraintLocator(member), loc, /*Implicit*/ true,
6877-
selected.choice.getFunctionRefKind(), member->getAccessSemantics(),
6878-
isDynamic);
6869+
auto member = buildMemberRef(fn, selected.openedFullType,
6870+
SourceLoc(), selected.choice,
6871+
DeclNameLoc(method->getNameLoc()),
6872+
selected.openedType, loc, loc, /*implicit*/ true,
6873+
selected.choice.getFunctionRefKind(),
6874+
AccessSemantics::Ordinary, isDynamic);
68796875

68806876
// Construct argument to the method (either an array or dictionary
68816877
// expression).
68826878
Expr *argument = nullptr;
6883-
auto expectedParamType = methodType->getParams().front().getParameterType();
68846879
if (!useKwargsMethod) {
6885-
auto arrayLitProto = cs.TC.getProtocol(
6886-
fn->getLoc(), KnownProtocolKind::ExpressibleByArrayLiteral);
6887-
auto conformance =
6888-
cs.TC.conformsToProtocol(expectedParamType, arrayLitProto, cs.DC,
6889-
ConformanceCheckFlags::InExpression);
6890-
auto paramType = conformance->getTypeWitnessByName(
6891-
expectedParamType, cs.getASTContext().Id_ArrayLiteralElement)
6892-
->getDesugaredType();
6893-
6894-
auto arrayElements =
6895-
map<std::vector<Expr *>>(arg->getElements(), [&](Expr *origArgElt) {
6896-
return rewriter.coerceToType(origArgElt, paramType, loc);
6897-
});
6898-
auto *arrayExpr = ArrayExpr::create(
6899-
ctx, arg->getStartLoc(), arrayElements, {}, arg->getEndLoc());
6900-
cs.setType(arrayExpr, expectedParamType);
6901-
rewriter.finishArrayExpr(arrayExpr);
6902-
argument = arrayExpr;
6880+
argument = ArrayExpr::create(ctx, SourceLoc(), arg->getElements(),
6881+
{}, SourceLoc());
6882+
cs.setType(argument, argumentType);
6883+
finishArrayExpr(cast<ArrayExpr>(argument));
69036884
} else {
6904-
auto dictLitProto = cs.TC.getProtocol(
6905-
fn->getLoc(), KnownProtocolKind::ExpressibleByDictionaryLiteral);
6885+
auto dictLitProto =
6886+
ctx.getProtocol(KnownProtocolKind::ExpressibleByDictionaryLiteral);
69066887
auto conformance =
6907-
cs.TC.conformsToProtocol(expectedParamType, dictLitProto, cs.DC,
6888+
cs.TC.conformsToProtocol(argumentType, dictLitProto, cs.DC,
69086889
ConformanceCheckFlags::InExpression);
6909-
auto keyAssocType =
6910-
conformance->getTypeWitnessByName(expectedParamType, ctx.Id_Key)
6911-
->getDesugaredType();
6912-
auto valueAssocType =
6913-
conformance->getTypeWitnessByName(expectedParamType, ctx.Id_Value)
6914-
->getDesugaredType();
6915-
6890+
auto keyType = conformance->getTypeWitnessByName(argumentType, ctx.Id_Key);
6891+
auto valueType = conformance->getTypeWitnessByName(argumentType,
6892+
ctx.Id_Value);
6893+
SmallVector<Identifier, 4> names;
69166894
SmallVector<Expr *, 4> dictElements;
69176895
for (unsigned i = 0, n = arg->getNumElements(); i < n; i++) {
6918-
auto *labelExpr = new (ctx) StringLiteralExpr(
6919-
arg->getElementName(i).get(), arg->getElementNameLoc(i),
6920-
/*Implicit*/ true);
6921-
cs.setType(labelExpr, keyAssocType);
6922-
6923-
Expr *dictElt = TupleExpr::createImplicit(
6924-
ctx,
6925-
{rewriter.visitStringLiteralExpr(labelExpr),
6926-
rewriter.coerceToType(arg->getElement(i), valueAssocType, loc)},
6927-
{});
6928-
cs.setType(dictElt, TupleType::get({TupleTypeElt{keyAssocType},
6929-
TupleTypeElt{valueAssocType}},
6930-
ctx));
6931-
dictElements.push_back(dictElt);
6932-
}
6933-
auto *dictExpr = DictionaryExpr::create(
6934-
ctx, arg->getStartLoc(), dictElements, {}, arg->getEndLoc());
6935-
cs.setType(dictExpr, expectedParamType);
6936-
rewriter.finishDictionaryExpr(dictExpr);
6937-
argument = dictExpr;
6896+
Expr *labelExpr =
6897+
new (ctx) StringLiteralExpr(arg->getElementName(i).get(),
6898+
arg->getElementNameLoc(i),
6899+
/*Implicit*/ true);
6900+
cs.setType(labelExpr, keyType);
6901+
handleStringLiteralExpr(cast<LiteralExpr>(labelExpr));
6902+
6903+
Expr *valueExpr = coerceToType(arg->getElement(i), valueType, loc);
6904+
if (!valueExpr)
6905+
return nullptr;
6906+
Expr *pair = TupleExpr::createImplicit(ctx, {labelExpr, valueExpr}, {});
6907+
auto eltTypes = { TupleTypeElt(keyType), TupleTypeElt(valueType) };
6908+
cs.setType(pair, TupleType::get(eltTypes, ctx));
6909+
dictElements.push_back(pair);
6910+
}
6911+
argument = DictionaryExpr::create(ctx, SourceLoc(), dictElements, {},
6912+
SourceLoc());
6913+
cs.setType(argument, argumentType);
6914+
finishDictionaryExpr(cast<DictionaryExpr>(argument));
69386915
}
69396916
argument->setImplicit();
69406917

69416918
// Construct call to the `dynamicallyCall` method.
6942-
auto getType = [&](const Expr *E) -> Type { return cs.getType(E); };
6943-
CallExpr *result = CallExpr::createImplicit(ctx, memberExpr, argument,
6944-
{argumentLabel}, getType);
6919+
auto result = CallExpr::createImplicit(ctx, member, argument,
6920+
{ argumentLabel });
6921+
cs.setType(result->getArg(), AnyFunctionType::composeInput(ctx, params,
6922+
false));
69456923
cs.setType(result, methodType->getResult());
6946-
// Set the type of the newly constructed argument in the constraint system.
6947-
if (result->getArg()->getType())
6948-
cs.setType(result->getArg(), result->getArg()->getType());
6924+
cs.cacheExprTypes(result);
69496925
return result;
69506926
}
69516927

@@ -7299,7 +7275,7 @@ Expr *ExprRewriter::finishApply(ApplyExpr *apply, Type openedType,
72997275

73007276
// Handle @dynamicCallable applications.
73017277
// At this point, all other ApplyExpr cases have been handled.
7302-
return finishApplyDynamicCallable(*this, cs, solution, apply, locator);
7278+
return finishApplyDynamicCallable(solution, apply, locator);
73037279
}
73047280

73057281

0 commit comments

Comments
 (0)