@@ -3374,8 +3374,9 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
33743374 " method does not have a witness table entry" );
33753375 }
33763376
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) {
33793380 auto &C = F.getASTContext ();
33803381
33813382 // The type of the dynamic method must match the usual type of the method,
@@ -3394,28 +3395,50 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
33943395 }
33953396 assert (!methodTy->isPolymorphic ());
33963397
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 ());
34033414
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+ }
34063428
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.
34083431 if (auto fnDecl = dyn_cast<FuncDecl>(method.getDecl ())) {
34093432 if (fnDecl->hasDynamicSelfResult ()) {
34103433 auto anyObjectTy = C.getAnyObjectType ();
3411- for (auto &dynResult : dynResults ) {
3434+ for (auto &result : results ) {
34123435 auto newResultTy =
3413- dynResult
3436+ result
34143437 .getReturnValueType (F.getModule (), methodTy,
34153438 F.getTypeExpansionContext ())
34163439 ->replaceCovariantResultType (anyObjectTy, 0 );
3417- dynResult = SILResultInfo (newResultTy->getCanonicalType (),
3418- dynResult .getConvention ());
3440+ result = SILResultInfo (newResultTy->getCanonicalType (),
3441+ result .getConvention ());
34193442 }
34203443 }
34213444 }
@@ -3424,13 +3447,14 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
34243447 methodTy->getExtInfo (),
34253448 methodTy->getCoroutineKind (),
34263449 methodTy->getCalleeConvention (),
3427- dynParams ,
3450+ params ,
34283451 methodTy->getYields (),
3429- dynResults ,
3452+ results ,
34303453 methodTy->getOptionalErrorResult (),
34313454 SubstitutionMap (), SubstitutionMap (),
34323455 F.getASTContext ());
3433- return SILType::getPrimitiveObjectType (fnTy);
3456+
3457+ return fnTy->isBindableTo (verifiedTy);
34343458 }
34353459
34363460 // / Visitor class that checks whether a given decl ref has an entry in the
@@ -4853,9 +4877,8 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
48534877 " true bb for dynamic_method_br must take an argument" );
48544878
48554879 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 ()),
48594882 " bb argument for dynamic_method_br must be of the method's type" );
48604883 }
48614884
0 commit comments