@@ -727,7 +727,7 @@ SILGenModule::getWitnessTable(NormalProtocolConformance *conformance) {
727727}
728728
729729SILFunction *SILGenModule::emitProtocolWitness (
730- ProtocolConformanceRef conformance , SILLinkage linkage,
730+ ProtocolConformanceRef origConformance , SILLinkage linkage,
731731 SerializedKind_t serializedKind, SILDeclRef requirement,
732732 SILDeclRef witnessRef, IsFreeFunctionWitness_t isFree, Witness witness) {
733733 auto requirementInfo =
@@ -767,7 +767,8 @@ SILFunction *SILGenModule::emitProtocolWitness(
767767 // The type of the witness thunk.
768768 auto reqtSubstTy = cast<AnyFunctionType>(
769769 reqtOrigTy->substGenericArgs (reqtSubMap)
770- ->getReducedType (genericSig));
770+ ->mapTypeOutOfContext ()
771+ ->getCanonicalType ());
771772
772773 // Rewrite the conformance in terms of the requirement environment's Self
773774 // type, which might have a different generic signature than the type
@@ -777,14 +778,18 @@ SILFunction *SILGenModule::emitProtocolWitness(
777778 // in a protocol extension, the generic signature will have an additional
778779 // generic parameter representing Self, so the generic parameters of the
779780 // class will all be shifted down by one.
780- if (reqtSubMap) {
781- auto requirement = conformance.getProtocol ();
782- auto self = requirement->getSelfInterfaceType ()->getCanonicalType ();
781+ auto conformance = reqtSubMap.lookupConformance (M.getASTContext ().TheSelfType ,
782+ origConformance.getProtocol ())
783+ .mapConformanceOutOfContext ();
784+ ASSERT (conformance.isAbstract () == origConformance.isAbstract ());
783785
784- conformance = reqtSubMap.lookupConformance (self, requirement);
785-
786- if (genericEnv)
787- reqtSubMap = reqtSubMap.subst (genericEnv->getForwardingSubstitutionMap ());
786+ ProtocolConformance *manglingConformance = nullptr ;
787+ if (conformance.isConcrete ()) {
788+ manglingConformance = conformance.getConcrete ();
789+ if (auto *inherited = dyn_cast<InheritedProtocolConformance>(manglingConformance)) {
790+ manglingConformance = inherited->getInheritedConformance ();
791+ conformance = ProtocolConformanceRef (manglingConformance);
792+ }
788793 }
789794
790795 // Generic signatures where all parameters are concrete are lowered away
@@ -806,20 +811,14 @@ SILFunction *SILGenModule::emitProtocolWitness(
806811 // But this is expensive, so we only do it for coroutine lowering.
807812 // When they're part of the AST function type, we can remove this
808813 // parameter completely.
814+ bool allowDuplicateThunk = false ;
809815 std::optional<SubstitutionMap> witnessSubsForTypeLowering;
810816 if (auto accessor = dyn_cast<AccessorDecl>(requirement.getDecl ())) {
811817 if (accessor->isCoroutine ()) {
812818 witnessSubsForTypeLowering =
813819 witness.getSubstitutions ().mapReplacementTypesOutOfContext ();
814- }
815- }
816-
817- ProtocolConformance *manglingConformance = nullptr ;
818- if (conformance.isConcrete ()) {
819- manglingConformance = conformance.getConcrete ();
820- if (auto *inherited = dyn_cast<InheritedProtocolConformance>(manglingConformance)) {
821- manglingConformance = inherited->getInheritedConformance ();
822- conformance = ProtocolConformanceRef (manglingConformance);
820+ if (accessor->isRequirementWithSynthesizedDefaultImplementation ())
821+ allowDuplicateThunk = true ;
823822 }
824823 }
825824
@@ -863,8 +862,9 @@ SILFunction *SILGenModule::emitProtocolWitness(
863862 InlineStrategy = AlwaysInline;
864863
865864 SILFunction *f = M.lookUpFunction (nameBuffer);
866- if (f)
865+ if (allowDuplicateThunk && f)
867866 return f;
867+ ASSERT (!f);
868868
869869 SILGenFunctionBuilder builder (*this );
870870 f = builder.createFunction (
@@ -891,7 +891,8 @@ SILFunction *SILGenModule::emitProtocolWitness(
891891 bool isPreconcurrency = false ;
892892 if (conformance.isConcrete ()) {
893893 if (auto *C =
894- dyn_cast<NormalProtocolConformance>(conformance.getConcrete ()))
894+ dyn_cast<NormalProtocolConformance>(
895+ conformance.getConcrete ()->getRootConformance ()))
895896 isPreconcurrency = C->isPreconcurrency ();
896897 }
897898
0 commit comments