|
12 | 12 |
|
13 | 13 | #define DEBUG_TYPE "sil-combine"
|
14 | 14 | #include "SILCombiner.h"
|
| 15 | +#include "swift/AST/SubstitutionMap.h" |
15 | 16 | #include "swift/SIL/DynamicCasts.h"
|
16 | 17 | #include "swift/SIL/PatternMatch.h"
|
17 | 18 | #include "swift/SIL/SILBuilder.h"
|
@@ -686,27 +687,30 @@ SILCombiner::createApplyWithConcreteType(FullApplySite AI,
|
686 | 687 | }
|
687 | 688 | Args.push_back(NewSelf);
|
688 | 689 |
|
689 |
| - // Form a new set of substitutions where Self is |
690 |
| - // replaced by a concrete type. |
691 |
| - SmallVector<Substitution, 8> Substitutions; |
692 |
| - for (auto Subst : AI.getSubstitutions()) { |
693 |
| - auto *A = Subst.getReplacement()->getAs<ArchetypeType>(); |
694 |
| - if (A && A == OpenedArchetype) { |
695 |
| - auto Conformances = AI.getModule().getASTContext() |
696 |
| - .AllocateUninitialized<ProtocolConformanceRef>(1); |
697 |
| - Conformances[0] = Conformance; |
698 |
| - Substitution NewSubst(ConcreteType, Conformances); |
699 |
| - Substitutions.push_back(NewSubst); |
700 |
| - } else |
701 |
| - Substitutions.push_back(Subst); |
702 |
| - } |
703 |
| - |
| 690 | + auto FnTy = AI.getCallee()->getType().castTo<SILFunctionType>(); |
704 | 691 | SILType SubstCalleeType = AI.getSubstCalleeSILType();
|
705 |
| - |
706 | 692 | SILType NewSubstCalleeType;
|
707 | 693 |
|
708 |
| - auto FnTy = AI.getCallee()->getType().castTo<SILFunctionType>(); |
| 694 | + // Form a new set of substitutions where Self is |
| 695 | + // replaced by a concrete type. |
| 696 | + SmallVector<Substitution, 8> Substitutions; |
709 | 697 | if (FnTy->isPolymorphic()) {
|
| 698 | + auto FnSubsMap = |
| 699 | + FnTy->getGenericSignature()->getSubstitutionMap(AI.getSubstitutions()); |
| 700 | + auto FinalSubsMap = FnSubsMap.subst( |
| 701 | + [&](SubstitutableType *type) -> Type { |
| 702 | + if (type == OpenedArchetype) |
| 703 | + return ConcreteType; |
| 704 | + return type; |
| 705 | + }, |
| 706 | + [&](CanType origTy, Type substTy, |
| 707 | + ProtocolType *proto) -> Optional<ProtocolConformanceRef> { |
| 708 | + if (substTy->isEqual(ConcreteType)) { |
| 709 | + return Conformance.getInherited(proto->getDecl()); |
| 710 | + } |
| 711 | + return ProtocolConformanceRef(proto->getDecl()); |
| 712 | + }); |
| 713 | + FnTy->getGenericSignature()->getSubstitutions(FinalSubsMap, Substitutions); |
710 | 714 | // Handle polymorphic functions by properly substituting
|
711 | 715 | // their parameter types.
|
712 | 716 | CanSILFunctionType SFT = FnTy->substGenericArgs(
|
@@ -794,10 +798,8 @@ getConformanceAndConcreteType(FullApplySite AI,
|
794 | 798 | if (Requirement->inheritsFrom(Protocol)) {
|
795 | 799 | // If Requirement != Protocol, then the abstract conformance cannot be used
|
796 | 800 | // as is and we need to create a proper conformance.
|
797 |
| - return std::make_tuple(Conformance.isAbstract() |
798 |
| - ? ProtocolConformanceRef(Protocol) |
799 |
| - : Conformance, |
800 |
| - ConcreteType, ConcreteTypeDef); |
| 801 | + return std::make_tuple(Conformance.getInherited(Protocol), ConcreteType, |
| 802 | + ConcreteTypeDef); |
801 | 803 | }
|
802 | 804 | }
|
803 | 805 |
|
|
0 commit comments