@@ -2514,64 +2514,77 @@ TypeConverter::getConstantOverrideInfo(TypeExpansionContext context,
25142514
25152515 assert (base.requiresNewVTableEntry () && " base must not be an override" );
25162516
2517+ // Figure out the generic signature for the class method call. This is the
2518+ // signature of the derived class, with requirements transplanted from
2519+ // the base method. The derived method is allowed to have fewer
2520+ // requirements, in which case the thunk will translate the calling
2521+ // convention appropriately before calling the derived method.
2522+ bool hasGenericRequirementDifference = false ;
2523+
2524+ auto derivedSig = derived.getDecl ()->getAsGenericContext ()
2525+ ->getGenericSignature ();
2526+ auto genericSig = Context.getOverrideGenericSignature (base.getDecl (),
2527+ derived.getDecl ());
2528+ if (genericSig) {
2529+ hasGenericRequirementDifference =
2530+ !genericSig->requirementsNotSatisfiedBy (derivedSig).empty ();
2531+ }
2532+
25172533 auto baseInfo = getConstantInfo (context, base);
25182534 auto derivedInfo = getConstantInfo (context, derived);
25192535
2520- // If the derived method is ABI-compatible with the base method, give the
2521- // vtable thunk the same signature as the derived method.
2522- auto basePattern = AbstractionPattern (baseInfo.LoweredType );
2523-
2524- auto baseInterfaceTy = baseInfo.FormalType ;
2525- auto derivedInterfaceTy = derivedInfo.FormalType ;
2526-
2527- auto params = derivedInterfaceTy.getParams ();
2536+ auto params = derivedInfo.FormalType .getParams ();
25282537 assert (params.size () == 1 );
25292538 auto selfInterfaceTy = params[0 ].getPlainType ()->getMetatypeInstanceType ();
25302539
25312540 auto overrideInterfaceTy =
2541+ cast<AnyFunctionType>(
25322542 selfInterfaceTy->adjustSuperclassMemberDeclType (
2533- base.getDecl (), derived.getDecl (), baseInterfaceTy);
2534-
2535- // Copy generic signature from derived to the override type, to handle
2536- // the case where the base member is not generic (because the base class
2537- // is concrete) but the derived member is generic (because the derived
2538- // class is generic).
2539- if (auto derivedInterfaceFnTy = derivedInterfaceTy->getAs <GenericFunctionType>()) {
2540- auto overrideInterfaceFnTy = overrideInterfaceTy->castTo <FunctionType>();
2541- overrideInterfaceTy =
2542- GenericFunctionType::get (derivedInterfaceFnTy->getGenericSignature (),
2543- overrideInterfaceFnTy->getParams (),
2544- overrideInterfaceFnTy->getResult (),
2545- overrideInterfaceFnTy->getExtInfo ());
2546- }
2543+ base.getDecl (), derived.getDecl (), baseInfo.FormalType )
2544+ ->getCanonicalType ());
25472545
2548- // Lower the formal AST type.
2549- auto bridgedTypes = getLoweredFormalTypes (derived,
2550- cast<AnyFunctionType>(overrideInterfaceTy->getCanonicalType ()));
2551- auto overrideLoweredInterfaceTy = bridgedTypes.Uncurried ;
2546+ // Build the formal AST function type for the class method call.
2547+ auto basePattern = AbstractionPattern (baseInfo.LoweredType );
2548+
2549+ if (!hasGenericRequirementDifference &&
2550+ !checkASTTypeForABIDifferences (derivedInfo.FormalType ,
2551+ overrideInterfaceTy)) {
25522552
2553- if (! checkASTTypeForABIDifferences (derivedInfo. LoweredType ,
2554- overrideLoweredInterfaceTy)) {
2553+ // The derived method is ABI-compatible with the base method. Let's
2554+ // just use the derived method's formal type.
25552555 basePattern = AbstractionPattern (
25562556 copyOptionalityFromDerivedToBase (
25572557 *this ,
25582558 derivedInfo.LoweredType ,
25592559 baseInfo.LoweredType ));
2560- overrideLoweredInterfaceTy = derivedInfo.LoweredType ;
2560+ overrideInterfaceTy = derivedInfo.FormalType ;
2561+ }
2562+
2563+ if (genericSig && !genericSig->areAllParamsConcrete ()) {
2564+ overrideInterfaceTy =
2565+ cast<AnyFunctionType>(
2566+ GenericFunctionType::get (genericSig,
2567+ overrideInterfaceTy->getParams (),
2568+ overrideInterfaceTy->getResult (),
2569+ overrideInterfaceTy->getExtInfo ())
2570+ ->getCanonicalType ());
25612571 }
25622572
2563- // Build the SILFunctionType for the vtable thunk.
2573+ // Build the lowered AST function type for the class method call.
2574+ auto bridgedTypes = getLoweredFormalTypes (derived, overrideInterfaceTy);
2575+
2576+ // Build the SILFunctionType for the class method call.
25642577 CanSILFunctionType fnTy = getNativeSILFunctionType (
2565- *this , context, basePattern, overrideLoweredInterfaceTy , base, derived,
2578+ *this , context, basePattern, bridgedTypes. Uncurried , base, derived,
25662579 /* reqt subs*/ None, ProtocolConformanceRef ());
25672580
25682581 // Build the SILConstantInfo and cache it.
25692582 auto resultBuf = Context.Allocate (sizeof (SILConstantInfo),
25702583 alignof (SILConstantInfo));
25712584 auto result = ::new (resultBuf) SILConstantInfo{
2572- derivedInterfaceTy ,
2573- bridgedTypes. Pattern ,
2574- overrideLoweredInterfaceTy ,
2585+ overrideInterfaceTy ,
2586+ basePattern ,
2587+ bridgedTypes. Uncurried ,
25752588 fnTy};
25762589
25772590 auto inserted = ConstantOverrideTypes.insert ({{derived, base}, result});
0 commit comments