@@ -3374,8 +3374,9 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
3374
3374
" method does not have a witness table entry" );
3375
3375
}
3376
3376
3377
- // Get the expected type of a dynamic method reference.
3378
- SILType getDynamicMethodType (SILType selfType, SILDeclRef method) {
3377
+ // / Verify the given type of a dynamic or @objc optional method reference.
3378
+ bool verifyDynamicMethodType (CanSILFunctionType verifiedTy, SILType selfType,
3379
+ SILDeclRef method) {
3379
3380
auto &C = F.getASTContext ();
3380
3381
3381
3382
// The type of the dynamic method must match the usual type of the method,
@@ -3394,28 +3395,50 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
3394
3395
}
3395
3396
assert (!methodTy->isPolymorphic ());
3396
3397
3397
- // Replace Self parameter with type of 'self' at the call site.
3398
- auto params = methodTy->getParameters ();
3399
- SmallVector<SILParameterInfo, 4 >
3400
- dynParams (params.begin (), params.end () - 1 );
3401
- dynParams.push_back (SILParameterInfo (selfType.getASTType (),
3402
- params.back ().getConvention ()));
3398
+ // Assume the parameter conventions are correct.
3399
+ SmallVector<SILParameterInfo, 4 > params;
3400
+ {
3401
+ const auto actualParams = methodTy->getParameters ();
3402
+ const auto verifiedParams = verifiedTy->getParameters ();
3403
+ if (actualParams.size () != verifiedParams.size ())
3404
+ return false ;
3405
+
3406
+ for (const auto idx : indices (actualParams)) {
3407
+ params.push_back (actualParams[idx].getWithConvention (
3408
+ verifiedParams[idx].getConvention ()));
3409
+ }
3410
+ }
3411
+
3412
+ // Have the 'self' parameter assume the type of 'self' at the call site.
3413
+ params.back () = params.back ().getWithInterfaceType (selfType.getASTType ());
3403
3414
3404
- auto results = methodTy->getResults ();
3405
- SmallVector<SILResultInfo, 4 > dynResults (results.begin (), results.end ());
3415
+ // Assume the result conventions are correct.
3416
+ SmallVector<SILResultInfo, 4 > results;
3417
+ {
3418
+ const auto actualResults = methodTy->getResults ();
3419
+ const auto verifiedResults = verifiedTy->getResults ();
3420
+ if (actualResults.size () != verifiedResults.size ())
3421
+ return false ;
3422
+
3423
+ for (const auto idx : indices (actualResults)) {
3424
+ results.push_back (actualResults[idx].getWithConvention (
3425
+ verifiedResults[idx].getConvention ()));
3426
+ }
3427
+ }
3406
3428
3407
- // If the method returns Self, substitute AnyObject for the result type.
3429
+ // If the method returns dynamic Self, substitute AnyObject for the
3430
+ // result type.
3408
3431
if (auto fnDecl = dyn_cast<FuncDecl>(method.getDecl ())) {
3409
3432
if (fnDecl->hasDynamicSelfResult ()) {
3410
3433
auto anyObjectTy = C.getAnyObjectType ();
3411
- for (auto &dynResult : dynResults ) {
3434
+ for (auto &result : results ) {
3412
3435
auto newResultTy =
3413
- dynResult
3436
+ result
3414
3437
.getReturnValueType (F.getModule (), methodTy,
3415
3438
F.getTypeExpansionContext ())
3416
3439
->replaceCovariantResultType (anyObjectTy, 0 );
3417
- dynResult = SILResultInfo (newResultTy->getCanonicalType (),
3418
- dynResult .getConvention ());
3440
+ result = SILResultInfo (newResultTy->getCanonicalType (),
3441
+ result .getConvention ());
3419
3442
}
3420
3443
}
3421
3444
}
@@ -3424,13 +3447,14 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
3424
3447
methodTy->getExtInfo (),
3425
3448
methodTy->getCoroutineKind (),
3426
3449
methodTy->getCalleeConvention (),
3427
- dynParams ,
3450
+ params ,
3428
3451
methodTy->getYields (),
3429
- dynResults ,
3452
+ results ,
3430
3453
methodTy->getOptionalErrorResult (),
3431
3454
SubstitutionMap (), SubstitutionMap (),
3432
3455
F.getASTContext ());
3433
- return SILType::getPrimitiveObjectType (fnTy);
3456
+
3457
+ return fnTy->isBindableTo (verifiedTy);
3434
3458
}
3435
3459
3436
3460
// / Visitor class that checks whether a given decl ref has an entry in the
@@ -4853,9 +4877,8 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
4853
4877
" true bb for dynamic_method_br must take an argument" );
4854
4878
4855
4879
auto bbArgTy = DMBI->getHasMethodBB ()->args_begin ()[0 ]->getType ();
4856
- require (getDynamicMethodType (operandType, DMBI->getMember ())
4857
- .getASTType ()
4858
- ->isBindableTo (bbArgTy.getASTType ()),
4880
+ require (verifyDynamicMethodType (cast<SILFunctionType>(bbArgTy.getASTType ()),
4881
+ operandType, DMBI->getMember ()),
4859
4882
" bb argument for dynamic_method_br must be of the method's type" );
4860
4883
}
4861
4884
0 commit comments