@@ -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.
@@ -6827,11 +6831,10 @@ Expr *ExprRewriter::convertLiteralInPlace(Expr *literal,
6827
6831
}
6828
6832
6829
6833
// 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) {
6835
6838
auto &ctx = cs.getASTContext ();
6836
6839
auto *fn = apply->getFn ();
6837
6840
@@ -6843,13 +6846,13 @@ static Expr *finishApplyDynamicCallable(ExprRewriter &rewriter,
6843
6846
auto loc = locator.withPathElement (ConstraintLocator::ApplyFunction);
6844
6847
auto selected = solution.getOverloadChoice (cs.getConstraintLocator (loc));
6845
6848
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>();
6848
6850
assert (method->getName () == ctx.Id_dynamicallyCall &&
6849
6851
" Expected 'dynamicallyCall' method" );
6850
6852
auto params = methodType->getParams ();
6851
6853
assert (params.size () == 1 &&
6852
6854
" Expected 'dynamicallyCall' method with one parameter" );
6855
+ auto argumentType = params[0 ].getParameterType ();
6853
6856
auto argumentLabel = params[0 ].getLabel ();
6854
6857
assert ((argumentLabel == ctx.Id_withArguments ||
6855
6858
argumentLabel == ctx.Id_withKeywordArguments ) &&
@@ -6860,92 +6863,65 @@ static Expr *finishApplyDynamicCallable(ExprRewriter &rewriter,
6860
6863
// `withKeywordArguments` method.
6861
6864
bool useKwargsMethod = argumentLabel == ctx.Id_withKeywordArguments ;
6862
6865
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.
6871
6867
bool isDynamic =
6872
6868
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);
6879
6875
6880
6876
// Construct argument to the method (either an array or dictionary
6881
6877
// expression).
6882
6878
Expr *argument = nullptr ;
6883
- auto expectedParamType = methodType->getParams ().front ().getParameterType ();
6884
6879
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));
6903
6884
} else {
6904
- auto dictLitProto = cs. TC . getProtocol (
6905
- fn-> getLoc (), KnownProtocolKind::ExpressibleByDictionaryLiteral);
6885
+ auto dictLitProto =
6886
+ ctx. getProtocol ( KnownProtocolKind::ExpressibleByDictionaryLiteral);
6906
6887
auto conformance =
6907
- cs.TC .conformsToProtocol (expectedParamType , dictLitProto, cs.DC ,
6888
+ cs.TC .conformsToProtocol (argumentType , dictLitProto, cs.DC ,
6908
6889
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;
6916
6894
SmallVector<Expr *, 4 > dictElements;
6917
6895
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));
6938
6915
}
6939
6916
argument->setImplicit ();
6940
6917
6941
6918
// 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 ));
6945
6923
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);
6949
6925
return result;
6950
6926
}
6951
6927
@@ -7299,7 +7275,7 @@ Expr *ExprRewriter::finishApply(ApplyExpr *apply, Type openedType,
7299
7275
7300
7276
// Handle @dynamicCallable applications.
7301
7277
// At this point, all other ApplyExpr cases have been handled.
7302
- return finishApplyDynamicCallable (* this , cs, solution, apply, locator);
7278
+ return finishApplyDynamicCallable (solution, apply, locator);
7303
7279
}
7304
7280
7305
7281
0 commit comments