@@ -395,13 +395,16 @@ diagnoseInvalidDynamicConstructorReferences(ConstraintSystem &cs,
395
395
}
396
396
397
397
// / Form a type checked expression for the index of a @dynamicMemberLookup
398
- // / subscript index parameter.
398
+ // / subscript index parameter, using the specified name, type, and source loc .
399
399
// / The index expression will have a tuple type of `(dynamicMember: T)`.
400
+ // /
401
+ // / Note: propagating source location is necessary to prevent diagnostics with
402
+ // / unknown location.
400
403
static Expr *buildDynamicMemberLookupIndexExpr (StringRef name, Type ty,
401
404
SourceLoc loc, DeclContext *dc,
402
405
ConstraintSystem &cs) {
403
406
auto &ctx = cs.TC .Context ;
404
-
407
+
405
408
// Build and type check the string literal index value to the specific
406
409
// string type expected by the subscript.
407
410
Expr *nameExpr = new (ctx) StringLiteralExpr (name, loc, /* implicit*/ true );
@@ -7317,101 +7320,82 @@ static Expr *finishApplyDynamicCallable(ExprRewriter &rewriter,
7317
7320
Expr *memberExpr = rewriter.buildMemberRef (
7318
7321
member->getBase (), selected.openedFullType , member->getDotLoc (),
7319
7322
selected.choice , member->getNameLoc (), selected.openedType ,
7320
- cs.getConstraintLocator (member), loc, true ,
7323
+ cs.getConstraintLocator (member), loc, /* Implicit */ true ,
7321
7324
selected.choice .getFunctionRefKind (), member->getAccessSemantics (),
7322
7325
isDynamic);
7323
7326
7324
7327
// Construct argument to the method (either an array or dictionary
7325
7328
// expression).
7326
7329
Expr *argument = nullptr ;
7330
+ auto expectedParamType = methodType->getParams ().front ().getParameterType ();
7327
7331
if (!useKwargsMethod) {
7328
- auto paramArrayType = methodType->getParams ()[0 ].getParameterType ();
7329
7332
auto arrayLitProto = cs.TC .getProtocol (
7330
7333
fn->getLoc (), KnownProtocolKind::ExpressibleByArrayLiteral);
7331
7334
auto conformance =
7332
- cs.TC .conformsToProtocol (paramArrayType , arrayLitProto, cs.DC ,
7335
+ cs.TC .conformsToProtocol (expectedParamType , arrayLitProto, cs.DC ,
7333
7336
ConformanceCheckFlags::InExpression);
7334
7337
auto paramType = ProtocolConformanceRef::getTypeWitnessByName (
7335
- paramArrayType , *conformance,
7338
+ expectedParamType , *conformance,
7336
7339
cs.getASTContext ().Id_ArrayLiteralElement , &cs.TC )
7337
7340
->getDesugaredType ();
7338
7341
7339
- std::vector<Expr *> convertedElements;
7340
- for (Expr *dynamicArg : arg->getElements ()) {
7341
- convertedElements.push_back (rewriter.coerceToType (
7342
- dynamicArg, paramType,
7343
- loc.withPathElement (LocatorPathElt::getApplyArgToParam (0 , 0 ))));
7344
- }
7345
- auto *argumentTmp =
7346
- ArrayExpr::create (ctx, SourceLoc (), convertedElements, {}, SourceLoc ());
7347
- argument = argumentTmp;
7348
-
7349
- cs.setType (argument, paramArrayType);
7350
- rewriter.finishArrayExpr (argumentTmp);
7342
+ auto arrayElements =
7343
+ map<std::vector<Expr *>>(arg->getElements (), [&](Expr *origArgElt) {
7344
+ return rewriter.coerceToType (origArgElt, paramType, loc);
7345
+ });
7346
+ auto *arrayExpr = ArrayExpr::create (
7347
+ ctx, arg->getStartLoc (), arrayElements, {}, arg->getEndLoc ());
7348
+ cs.setType (arrayExpr, expectedParamType);
7349
+ rewriter.finishArrayExpr (arrayExpr);
7350
+ argument = arrayExpr;
7351
7351
} else {
7352
- // Get Key and Value associated types.
7353
- auto paramDictType = methodType->getParams ()[0 ].getParameterType ();
7354
7352
auto dictLitProto = cs.TC .getProtocol (
7355
7353
fn->getLoc (), KnownProtocolKind::ExpressibleByDictionaryLiteral);
7356
7354
auto conformance =
7357
- cs.TC .conformsToProtocol (paramDictType , dictLitProto, cs.DC ,
7355
+ cs.TC .conformsToProtocol (expectedParamType , dictLitProto, cs.DC ,
7358
7356
ConformanceCheckFlags::InExpression);
7359
7357
auto keyAssocType =
7360
7358
ProtocolConformanceRef::getTypeWitnessByName (
7361
- paramDictType , *conformance, cs. getASTContext () .Id_Key , &cs.TC )
7359
+ expectedParamType , *conformance, ctx .Id_Key , &cs.TC )
7362
7360
->getDesugaredType ();
7363
7361
auto valueAssocType =
7364
7362
ProtocolConformanceRef::getTypeWitnessByName (
7365
- paramDictType , *conformance, cs. getASTContext () .Id_Value , &cs.TC )
7363
+ expectedParamType , *conformance, ctx .Id_Value , &cs.TC )
7366
7364
->getDesugaredType ();
7367
7365
7368
- SmallVector<Identifier, 4 > names;
7369
7366
SmallVector<Expr *, 4 > dictElements;
7370
7367
for (unsigned i = 0 , n = arg->getNumElements (); i < n; i++) {
7371
7368
auto *labelExpr = new (ctx) StringLiteralExpr (
7372
7369
arg->getElementName (i).get (), arg->getElementNameLoc (i),
7373
7370
/* Implicit*/ true );
7374
7371
cs.setType (labelExpr, keyAssocType);
7375
7372
7376
- Expr *pair = TupleExpr::createImplicit (
7373
+ Expr *dictElt = TupleExpr::createImplicit (
7377
7374
ctx,
7378
7375
{rewriter.visitStringLiteralExpr (labelExpr),
7379
- rewriter.coerceToType (
7380
- arg->getElement (i), valueAssocType,
7381
- loc.withPathElement (LocatorPathElt::getApplyArgToParam (0 , 0 )))},
7376
+ rewriter.coerceToType (arg->getElement (i), valueAssocType, loc)},
7382
7377
{});
7383
-
7384
- cs.setType (pair, TupleType::get ({TupleTypeElt{keyAssocType},
7385
- TupleTypeElt{valueAssocType}},
7386
- ctx));
7387
- dictElements.push_back (pair);
7388
- }
7389
- auto *argumentTmp =
7390
- DictionaryExpr::create (ctx, SourceLoc (), dictElements, {}, SourceLoc ());
7391
-
7392
- cs.setType (argumentTmp, paramDictType);
7393
- rewriter.finishDictionaryExpr (argumentTmp);
7394
- argument = argumentTmp;
7378
+ cs.setType (dictElt, TupleType::get ({TupleTypeElt{keyAssocType},
7379
+ TupleTypeElt{valueAssocType}},
7380
+ ctx));
7381
+ dictElements.push_back (dictElt);
7382
+ }
7383
+ auto *dictExpr = DictionaryExpr::create (
7384
+ ctx, arg->getStartLoc (), dictElements, {}, arg->getEndLoc ());
7385
+ cs.setType (dictExpr, expectedParamType);
7386
+ rewriter.finishDictionaryExpr (dictExpr);
7387
+ argument = dictExpr;
7395
7388
}
7396
7389
argument->setImplicit ();
7397
7390
7398
- auto getType = [&](const Expr *E) -> Type { return cs.getType (E); };
7399
-
7400
7391
// Construct call to the `dynamicallyCall` method.
7392
+ auto getType = [&](const Expr *E) -> Type { return cs.getType (E); };
7401
7393
CallExpr *result = CallExpr::createImplicit (ctx, memberExpr, argument,
7402
7394
{argumentLabel}, getType);
7403
-
7404
7395
cs.setType (result, methodType->getResult ());
7405
-
7406
- {
7407
- // The implicitly constructed tuple_expr may have a type, but this type
7408
- // is not known in the constraint system.
7409
- Expr *arg = result->getArg ();
7410
- if (arg->getType ()) {
7411
- cs.setType (arg, arg->getType ());
7412
- }
7413
- }
7414
-
7396
+ // Set the type of the newly constructed argument in the constraint system.
7397
+ if (result->getArg ()->getType ())
7398
+ cs.setType (result->getArg (), result->getArg ()->getType ());
7415
7399
return result;
7416
7400
}
7417
7401
0 commit comments