static std::pair<ManagedValue, SILDeclRef> getNextUncurryLevelRef(SILGenFunction &SGF, SILLocation loc, SILDeclRef thunk, ManagedValue selfArg, SubstitutionMap curriedSubs) { auto *vd = thunk.getDecl(); // Reference the next uncurrying level of the function. SILDeclRef next = SILDeclRef(vd, thunk.kind); assert(!next.isCurried); auto constantInfo = SGF.SGM.Types.getConstantInfo(next); // If the function is natively foreign, reference its foreign entry point. if (requiresForeignToNativeThunk(vd)) return {ManagedValue::forUnmanaged(SGF.emitGlobalFunctionRef(loc, next)), next}; // If the thunk is a curry thunk for a direct method reference, we are // doing a direct dispatch (eg, a fragile 'super.foo()' call). if (thunk.isDirectReference) return {ManagedValue::forUnmanaged(SGF.emitGlobalFunctionRef(loc, next)), next}; if (auto *func = dyn_cast<AbstractFunctionDecl>(vd)) { if (getMethodDispatch(func) == MethodDispatch::Class) { // Use the dynamic thunk if dynamic. if (vd->isObjCDynamic()) { return {SGF.emitDynamicMethodRef(loc, next, constantInfo.SILFnType), next}; } auto methodTy = SGF.SGM.Types.getConstantOverrideType(next); SILValue result = SGF.emitClassMethodRef(loc, selfArg.getValue(), next, methodTy); return {ManagedValue::forUnmanaged(result), next.getOverriddenVTableEntry()}; } // If the fully-uncurried reference is to a generic method, look up the // witness. if (constantInfo.SILFnType->getRepresentation() == SILFunctionTypeRepresentation::WitnessMethod) { auto protocol = func->getDeclContext()->getSelfProtocolDecl(); auto origSelfType = protocol->getSelfInterfaceType()->getCanonicalType(); auto substSelfType = origSelfType.subst(curriedSubs)->getCanonicalType(); auto conformance = curriedSubs.lookupConformance(origSelfType, protocol); auto result = SGF.B.createWitnessMethod(loc, substSelfType, *conformance, next, constantInfo.getSILType()); return {ManagedValue::forUnmanaged(result), next}; } } // Otherwise, emit a direct call. return {ManagedValue::forUnmanaged(SGF.emitGlobalFunctionRef(loc, next)), next}; }