|
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,39 @@ 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->getCanonicalType() == ConcreteType) { |
| 709 | + if (proto->getDecl() != Conformance.getRequirement()) { |
| 710 | + assert( |
| 711 | + Conformance.getRequirement()->inheritsFrom(proto->getDecl())); |
| 712 | + if (Conformance.isAbstract()) |
| 713 | + return ProtocolConformanceRef(proto->getDecl()); |
| 714 | + Conformance = ProtocolConformanceRef( |
| 715 | + Conformance.getConcrete()->getInheritedConformance( |
| 716 | + proto->getDecl())); |
| 717 | + } |
| 718 | + return Conformance; |
| 719 | + } |
| 720 | + return ProtocolConformanceRef(proto->getDecl()); |
| 721 | + }); |
| 722 | + FnTy->getGenericSignature()->getSubstitutions(FinalSubsMap, Substitutions); |
710 | 723 | // Handle polymorphic functions by properly substituting
|
711 | 724 | // their parameter types.
|
712 | 725 | CanSILFunctionType SFT = FnTy->substGenericArgs(
|
|
0 commit comments