@@ -1108,6 +1108,10 @@ namespace {
1108
1108
Expr *finishApply (ApplyExpr *apply, Type openedType,
1109
1109
ConstraintLocatorBuilder locator);
1110
1110
1111
+ // Resolve @dynamicCallable applications.
1112
+ Expr *finishApplyDynamicCallable (const Solution &solution, ApplyExpr *apply,
1113
+ ConstraintLocatorBuilder locator);
1114
+
1111
1115
private:
1112
1116
// / Simplify the given type by substituting all occurrences of
1113
1117
// / type variables for their fixed types.
@@ -2041,9 +2045,6 @@ namespace {
2041
2045
}
2042
2046
2043
2047
Expr *handleStringLiteralExpr (LiteralExpr *expr) {
2044
- if (cs.getType (expr) && !cs.getType (expr)->hasTypeVariable ())
2045
- return expr;
2046
-
2047
2048
auto stringLiteral = dyn_cast<StringLiteralExpr>(expr);
2048
2049
auto magicLiteral = dyn_cast<MagicIdentifierLiteralExpr>(expr);
2049
2050
assert (bool (stringLiteral) != bool (magicLiteral) &&
@@ -7004,10 +7005,10 @@ Expr *ExprRewriter::convertLiteralInPlace(Expr *literal,
7004
7005
}
7005
7006
7006
7007
// Resolve @dynamicCallable applications.
7007
- static Expr *finishApplyDynamicCallable (ConstraintSystem &cs,
7008
- const Solution &solution,
7009
- ApplyExpr *apply,
7010
- ConstraintLocatorBuilder locator) {
7008
+ Expr *
7009
+ ExprRewriter::finishApplyDynamicCallable ( const Solution &solution,
7010
+ ApplyExpr *apply,
7011
+ ConstraintLocatorBuilder locator) {
7011
7012
auto &ctx = cs.getASTContext ();
7012
7013
auto *fn = apply->getFn ();
7013
7014
@@ -7019,12 +7020,14 @@ static Expr *finishApplyDynamicCallable(ConstraintSystem &cs,
7019
7020
auto loc = locator.withPathElement (ConstraintLocator::ApplyFunction);
7020
7021
auto selected = solution.getOverloadChoice (cs.getConstraintLocator (loc));
7021
7022
auto *method = dyn_cast<FuncDecl>(selected.choice .getDecl ());
7022
- auto methodType = selected.openedType ->castTo <AnyFunctionType>();
7023
+ auto methodType = simplifyType ( selected.openedType ) ->castTo <AnyFunctionType>();
7023
7024
assert (method->getName () == ctx.Id_dynamicallyCall &&
7024
7025
" Expected 'dynamicallyCall' method" );
7025
- assert (methodType->getParams ().size () == 1 &&
7026
+ auto params = methodType->getParams ();
7027
+ assert (params.size () == 1 &&
7026
7028
" Expected 'dynamicallyCall' method with one parameter" );
7027
- auto argumentLabel = methodType->getParams ()[0 ].getLabel ();
7029
+ auto argumentType = params[0 ].getParameterType ();
7030
+ auto argumentLabel = params[0 ].getLabel ();
7028
7031
assert ((argumentLabel == ctx.Id_withArguments ||
7029
7032
argumentLabel == ctx.Id_withKeywordArguments ) &&
7030
7033
" Expected 'dynamicallyCall' method argument label 'withArguments' or "
@@ -7034,39 +7037,62 @@ static Expr *finishApplyDynamicCallable(ConstraintSystem &cs,
7034
7037
// `withKeywordArguments` method.
7035
7038
bool useKwargsMethod = argumentLabel == ctx.Id_withKeywordArguments ;
7036
7039
7037
- // Construct expression referencing the `dynamicallyCall` method.
7038
- Expr *member =
7039
- new (ctx) MemberRefExpr (fn, fn->getEndLoc (), ConcreteDeclRef (method),
7040
- DeclNameLoc (method->getNameLoc ()),
7041
- /* Implicit*/ true );
7040
+ // Construct expression referencing the `dynamicallyCall` method.
7041
+ bool isDynamic =
7042
+ selected.choice .getKind () == OverloadChoiceKind::DeclViaDynamic;
7043
+ auto member = buildMemberRef (fn, selected.openedFullType ,
7044
+ SourceLoc (), selected.choice ,
7045
+ DeclNameLoc (method->getNameLoc ()),
7046
+ selected.openedType , loc, loc, /* implicit*/ true ,
7047
+ selected.choice .getFunctionRefKind (),
7048
+ AccessSemantics::Ordinary, isDynamic);
7042
7049
7043
7050
// Construct argument to the method (either an array or dictionary
7044
7051
// expression).
7045
7052
Expr *argument = nullptr ;
7046
7053
if (!useKwargsMethod) {
7047
7054
argument = ArrayExpr::create (ctx, SourceLoc (), arg->getElements (),
7048
7055
{}, SourceLoc ());
7056
+ cs.setType (argument, argumentType);
7057
+ finishArrayExpr (cast<ArrayExpr>(argument));
7049
7058
} else {
7059
+ auto dictLitProto =
7060
+ ctx.getProtocol (KnownProtocolKind::ExpressibleByDictionaryLiteral);
7061
+ auto conformance =
7062
+ cs.TC .conformsToProtocol (argumentType, dictLitProto, cs.DC ,
7063
+ ConformanceCheckFlags::InExpression);
7064
+ auto keyType = conformance->getTypeWitnessByName (argumentType, ctx.Id_Key );
7065
+ auto valueType = conformance->getTypeWitnessByName (argumentType,
7066
+ ctx.Id_Value );
7050
7067
SmallVector<Identifier, 4 > names;
7051
7068
SmallVector<Expr *, 4 > dictElements;
7052
7069
for (unsigned i = 0 , n = arg->getNumElements (); i < n; i++) {
7053
7070
Expr *labelExpr =
7054
7071
new (ctx) StringLiteralExpr (arg->getElementName (i).get (),
7055
7072
arg->getElementNameLoc (i),
7056
7073
/* Implicit*/ true );
7074
+ cs.setType (labelExpr, keyType);
7075
+ handleStringLiteralExpr (cast<LiteralExpr>(labelExpr));
7076
+
7057
7077
Expr *pair =
7058
7078
TupleExpr::createImplicit (ctx, { labelExpr, arg->getElement (i) }, {});
7079
+ auto eltTypes = { TupleTypeElt (keyType), TupleTypeElt (valueType) };
7080
+ cs.setType (pair, TupleType::get (eltTypes, ctx));
7059
7081
dictElements.push_back (pair);
7060
7082
}
7061
7083
argument = DictionaryExpr::create (ctx, SourceLoc (), dictElements, {},
7062
7084
SourceLoc ());
7085
+ cs.setType (argument, argumentType);
7086
+ finishDictionaryExpr (cast<DictionaryExpr>(argument));
7063
7087
}
7064
7088
argument->setImplicit ();
7065
7089
7066
7090
// Construct call to the `dynamicallyCall` method.
7067
- Expr *result = CallExpr::createImplicit (ctx, member, argument,
7068
- { argumentLabel });
7069
- cs.TC .typeCheckExpression (result, cs.DC );
7091
+ auto result = CallExpr::createImplicit (ctx, member, argument,
7092
+ { argumentLabel });
7093
+ cs.setType (result->getArg (), AnyFunctionType::composeInput (ctx, params,
7094
+ false ));
7095
+ cs.setType (result, methodType->getResult ());
7070
7096
cs.cacheExprTypes (result);
7071
7097
return result;
7072
7098
}
@@ -7367,7 +7393,7 @@ Expr *ExprRewriter::finishApply(ApplyExpr *apply, Type openedType,
7367
7393
7368
7394
// Handle @dynamicCallable applications.
7369
7395
// At this point, all other ApplyExpr cases have been handled.
7370
- return finishApplyDynamicCallable (cs, solution, apply, locator);
7396
+ return finishApplyDynamicCallable (solution, apply, locator);
7371
7397
}
7372
7398
7373
7399
0 commit comments