@@ -1069,6 +1069,10 @@ namespace {
1069
1069
Expr *finishApply (ApplyExpr *apply, Type openedType,
1070
1070
ConstraintLocatorBuilder locator);
1071
1071
1072
+ // Resolve @dynamicCallable applications.
1073
+ Expr *finishApplyDynamicCallable (const Solution &solution, ApplyExpr *apply,
1074
+ ConstraintLocatorBuilder locator);
1075
+
1072
1076
private:
1073
1077
// / Simplify the given type by substituting all occurrences of
1074
1078
// / type variables for their fixed types.
@@ -1975,9 +1979,6 @@ namespace {
1975
1979
}
1976
1980
1977
1981
Expr *handleStringLiteralExpr (LiteralExpr *expr) {
1978
- if (cs.getType (expr) && !cs.getType (expr)->hasTypeVariable ())
1979
- return expr;
1980
-
1981
1982
auto stringLiteral = dyn_cast<StringLiteralExpr>(expr);
1982
1983
auto magicLiteral = dyn_cast<MagicIdentifierLiteralExpr>(expr);
1983
1984
assert (bool (stringLiteral) != bool (magicLiteral) &&
@@ -6791,10 +6792,10 @@ Expr *ExprRewriter::convertLiteralInPlace(Expr *literal,
6791
6792
}
6792
6793
6793
6794
// Resolve @dynamicCallable applications.
6794
- static Expr *finishApplyDynamicCallable (ConstraintSystem &cs,
6795
- const Solution &solution,
6796
- ApplyExpr *apply,
6797
- ConstraintLocatorBuilder locator) {
6795
+ Expr *
6796
+ ExprRewriter::finishApplyDynamicCallable ( const Solution &solution,
6797
+ ApplyExpr *apply,
6798
+ ConstraintLocatorBuilder locator) {
6798
6799
auto &ctx = cs.getASTContext ();
6799
6800
auto *fn = apply->getFn ();
6800
6801
@@ -6806,12 +6807,14 @@ static Expr *finishApplyDynamicCallable(ConstraintSystem &cs,
6806
6807
auto loc = locator.withPathElement (ConstraintLocator::ApplyFunction);
6807
6808
auto selected = solution.getOverloadChoice (cs.getConstraintLocator (loc));
6808
6809
auto *method = dyn_cast<FuncDecl>(selected.choice .getDecl ());
6809
- auto methodType = selected.openedType ->castTo <AnyFunctionType>();
6810
+ auto methodType = simplifyType ( selected.openedType ) ->castTo <AnyFunctionType>();
6810
6811
assert (method->getName () == ctx.Id_dynamicallyCall &&
6811
6812
" Expected 'dynamicallyCall' method" );
6812
- assert (methodType->getParams ().size () == 1 &&
6813
+ auto params = methodType->getParams ();
6814
+ assert (params.size () == 1 &&
6813
6815
" Expected 'dynamicallyCall' method with one parameter" );
6814
- auto argumentLabel = methodType->getParams ()[0 ].getLabel ();
6816
+ auto argumentType = params[0 ].getParameterType ();
6817
+ auto argumentLabel = params[0 ].getLabel ();
6815
6818
assert ((argumentLabel == ctx.Id_withArguments ||
6816
6819
argumentLabel == ctx.Id_withKeywordArguments ) &&
6817
6820
" Expected 'dynamicallyCall' method argument label 'withArguments' or "
@@ -6821,39 +6824,62 @@ static Expr *finishApplyDynamicCallable(ConstraintSystem &cs,
6821
6824
// `withKeywordArguments` method.
6822
6825
bool useKwargsMethod = argumentLabel == ctx.Id_withKeywordArguments ;
6823
6826
6824
- // Construct expression referencing the `dynamicallyCall` method.
6825
- Expr *member =
6826
- new (ctx) MemberRefExpr (fn, fn->getEndLoc (), ConcreteDeclRef (method),
6827
- DeclNameLoc (method->getNameLoc ()),
6828
- /* Implicit*/ true );
6827
+ // Construct expression referencing the `dynamicallyCall` method.
6828
+ bool isDynamic =
6829
+ selected.choice .getKind () == OverloadChoiceKind::DeclViaDynamic;
6830
+ auto member = buildMemberRef (fn, selected.openedFullType ,
6831
+ SourceLoc (), selected.choice ,
6832
+ DeclNameLoc (method->getNameLoc ()),
6833
+ selected.openedType , loc, loc, /* implicit*/ true ,
6834
+ selected.choice .getFunctionRefKind (),
6835
+ AccessSemantics::Ordinary, isDynamic);
6829
6836
6830
6837
// Construct argument to the method (either an array or dictionary
6831
6838
// expression).
6832
6839
Expr *argument = nullptr ;
6833
6840
if (!useKwargsMethod) {
6834
6841
argument = ArrayExpr::create (ctx, SourceLoc (), arg->getElements (),
6835
6842
{}, SourceLoc ());
6843
+ cs.setType (argument, argumentType);
6844
+ finishArrayExpr (cast<ArrayExpr>(argument));
6836
6845
} else {
6846
+ auto dictLitProto =
6847
+ ctx.getProtocol (KnownProtocolKind::ExpressibleByDictionaryLiteral);
6848
+ auto conformance =
6849
+ cs.TC .conformsToProtocol (argumentType, dictLitProto, cs.DC ,
6850
+ ConformanceCheckFlags::InExpression);
6851
+ auto keyType = conformance->getTypeWitnessByName (argumentType, ctx.Id_Key );
6852
+ auto valueType = conformance->getTypeWitnessByName (argumentType,
6853
+ ctx.Id_Value );
6837
6854
SmallVector<Identifier, 4 > names;
6838
6855
SmallVector<Expr *, 4 > dictElements;
6839
6856
for (unsigned i = 0 , n = arg->getNumElements (); i < n; i++) {
6840
6857
Expr *labelExpr =
6841
6858
new (ctx) StringLiteralExpr (arg->getElementName (i).get (),
6842
6859
arg->getElementNameLoc (i),
6843
6860
/* Implicit*/ true );
6861
+ cs.setType (labelExpr, keyType);
6862
+ handleStringLiteralExpr (cast<LiteralExpr>(labelExpr));
6863
+
6844
6864
Expr *pair =
6845
6865
TupleExpr::createImplicit (ctx, { labelExpr, arg->getElement (i) }, {});
6866
+ auto eltTypes = { TupleTypeElt (keyType), TupleTypeElt (valueType) };
6867
+ cs.setType (pair, TupleType::get (eltTypes, ctx));
6846
6868
dictElements.push_back (pair);
6847
6869
}
6848
6870
argument = DictionaryExpr::create (ctx, SourceLoc (), dictElements, {},
6849
6871
SourceLoc ());
6872
+ cs.setType (argument, argumentType);
6873
+ finishDictionaryExpr (cast<DictionaryExpr>(argument));
6850
6874
}
6851
6875
argument->setImplicit ();
6852
6876
6853
6877
// Construct call to the `dynamicallyCall` method.
6854
- Expr *result = CallExpr::createImplicit (ctx, member, argument,
6855
- { argumentLabel });
6856
- cs.TC .typeCheckExpression (result, cs.DC );
6878
+ auto result = CallExpr::createImplicit (ctx, member, argument,
6879
+ { argumentLabel });
6880
+ cs.setType (result->getArg (), AnyFunctionType::composeInput (ctx, params,
6881
+ false ));
6882
+ cs.setType (result, methodType->getResult ());
6857
6883
cs.cacheExprTypes (result);
6858
6884
return result;
6859
6885
}
@@ -7151,7 +7177,7 @@ Expr *ExprRewriter::finishApply(ApplyExpr *apply, Type openedType,
7151
7177
7152
7178
// Handle @dynamicCallable applications.
7153
7179
// At this point, all other ApplyExpr cases have been handled.
7154
- return finishApplyDynamicCallable (cs, solution, apply, locator);
7180
+ return finishApplyDynamicCallable (solution, apply, locator);
7155
7181
}
7156
7182
7157
7183
0 commit comments