@@ -727,7 +727,7 @@ SILGenModule::getWitnessTable(NormalProtocolConformance *conformance) {
727
727
}
728
728
729
729
SILFunction *SILGenModule::emitProtocolWitness (
730
- ProtocolConformanceRef conformance , SILLinkage linkage,
730
+ ProtocolConformanceRef origConformance , SILLinkage linkage,
731
731
SerializedKind_t serializedKind, SILDeclRef requirement,
732
732
SILDeclRef witnessRef, IsFreeFunctionWitness_t isFree, Witness witness) {
733
733
auto requirementInfo =
@@ -767,7 +767,8 @@ SILFunction *SILGenModule::emitProtocolWitness(
767
767
// The type of the witness thunk.
768
768
auto reqtSubstTy = cast<AnyFunctionType>(
769
769
reqtOrigTy->substGenericArgs (reqtSubMap)
770
- ->getReducedType (genericSig));
770
+ ->mapTypeOutOfContext ()
771
+ ->getCanonicalType ());
771
772
772
773
// Rewrite the conformance in terms of the requirement environment's Self
773
774
// type, which might have a different generic signature than the type
@@ -777,14 +778,18 @@ SILFunction *SILGenModule::emitProtocolWitness(
777
778
// in a protocol extension, the generic signature will have an additional
778
779
// generic parameter representing Self, so the generic parameters of the
779
780
// 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 ());
783
785
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
+ }
788
793
}
789
794
790
795
// Generic signatures where all parameters are concrete are lowered away
@@ -806,20 +811,14 @@ SILFunction *SILGenModule::emitProtocolWitness(
806
811
// But this is expensive, so we only do it for coroutine lowering.
807
812
// When they're part of the AST function type, we can remove this
808
813
// parameter completely.
814
+ bool allowDuplicateThunk = false ;
809
815
std::optional<SubstitutionMap> witnessSubsForTypeLowering;
810
816
if (auto accessor = dyn_cast<AccessorDecl>(requirement.getDecl ())) {
811
817
if (accessor->isCoroutine ()) {
812
818
witnessSubsForTypeLowering =
813
819
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 ;
823
822
}
824
823
}
825
824
@@ -863,8 +862,9 @@ SILFunction *SILGenModule::emitProtocolWitness(
863
862
InlineStrategy = AlwaysInline;
864
863
865
864
SILFunction *f = M.lookUpFunction (nameBuffer);
866
- if (f)
865
+ if (allowDuplicateThunk && f)
867
866
return f;
867
+ ASSERT (!f);
868
868
869
869
SILGenFunctionBuilder builder (*this );
870
870
f = builder.createFunction (
@@ -891,7 +891,8 @@ SILFunction *SILGenModule::emitProtocolWitness(
891
891
bool isPreconcurrency = false ;
892
892
if (conformance.isConcrete ()) {
893
893
if (auto *C =
894
- dyn_cast<NormalProtocolConformance>(conformance.getConcrete ()))
894
+ dyn_cast<NormalProtocolConformance>(
895
+ conformance.getConcrete ()->getRootConformance ()))
895
896
isPreconcurrency = C->isPreconcurrency ();
896
897
}
897
898
0 commit comments