@@ -692,41 +692,54 @@ SILCombiner::createApplyWithConcreteType(FullApplySite AI,
692
692
// replaced by a concrete type.
693
693
SmallVector<Substitution, 8 > Substitutions;
694
694
for (auto Subst : AI.getSubstitutions ()) {
695
- auto NewSubst = Subst.subst (
696
- AI.getModule ().getSwiftModule (),
697
- [&](SubstitutableType *type) -> Type {
698
- if (type == OpenedArchetype)
699
- return ConcreteType;
700
- return type;
701
- },
702
- [&](Type origTy, Type substTy, ProtocolType *protoType)
703
- -> Optional<ProtocolConformanceRef> {
704
- assert (origTy->isEqual (OpenedArchetype));
705
- return Conformance;
706
- });
707
- Substitutions.push_back (NewSubst);
695
+ auto *A = Subst.getReplacement ()->getAs <ArchetypeType>();
696
+ if (A && A == OpenedArchetype) {
697
+ auto Conformances = AI.getModule ().getASTContext ()
698
+ .AllocateUninitialized <ProtocolConformanceRef>(1 );
699
+ Conformances[0 ] = Conformance;
700
+ Substitution NewSubst (ConcreteType, Conformances);
701
+ Substitutions.push_back (NewSubst);
702
+ } else
703
+ Substitutions.push_back (Subst);
708
704
}
709
705
710
- auto FnTy = AI.getCallee ()->getType ().castTo <SILFunctionType>();
711
- assert (FnTy->isPolymorphic ());
706
+ SILType SubstCalleeType = AI.getSubstCalleeSILType ();
707
+
708
+ SILType NewSubstCalleeType;
712
709
713
- auto SFT = FnTy->substGenericArgs (AI.getModule (), Substitutions);
714
- auto NewSubstCalleeType = SILType::getPrimitiveObjectType (SFT);
710
+ auto FnTy = AI.getCallee ()->getType ().castTo <SILFunctionType>();
711
+ if (FnTy->isPolymorphic ()) {
712
+ // Handle polymorphic functions by properly substituting
713
+ // their parameter types.
714
+ CanSILFunctionType SFT = FnTy->substGenericArgs (
715
+ AI.getModule (),
716
+ Substitutions);
717
+ NewSubstCalleeType = SILType::getPrimitiveObjectType (SFT);
718
+ } else {
719
+ NewSubstCalleeType =
720
+ SubstCalleeType.subst (AI.getModule (),
721
+ [&](SubstitutableType *type) -> Type {
722
+ if (type == OpenedArchetype)
723
+ return ConcreteType;
724
+ return type;
725
+ },
726
+ MakeAbstractConformanceForGenericType ());
727
+ }
715
728
716
729
FullApplySite NewAI;
717
730
Builder.setCurrentDebugScope (AI.getDebugScope ());
718
731
Builder.addOpenedArchetypeOperands (AI.getInstruction ());
719
732
720
733
if (auto *TAI = dyn_cast<TryApplyInst>(AI))
721
734
NewAI = Builder.createTryApply (AI.getLoc (), AI.getCallee (),
722
- NewSubstCalleeType,
723
- Substitutions, Args,
724
- TAI->getNormalBB (), TAI->getErrorBB ());
735
+ NewSubstCalleeType,
736
+ Substitutions, Args,
737
+ TAI->getNormalBB (), TAI->getErrorBB ());
725
738
else
726
739
NewAI = Builder.createApply (AI.getLoc (), AI.getCallee (),
727
- NewSubstCalleeType,
728
- AI.getType (), Substitutions, Args,
729
- cast<ApplyInst>(AI)->isNonThrowing ());
740
+ NewSubstCalleeType,
741
+ AI.getType (), Substitutions, Args,
742
+ cast<ApplyInst>(AI)->isNonThrowing ());
730
743
731
744
if (isa<ApplyInst>(NewAI))
732
745
replaceInstUsesWith (*AI.getInstruction (), NewAI.getInstruction ());
@@ -873,6 +886,21 @@ SILCombiner::propagateConcreteTypeOfInitExistential(FullApplySite AI,
873
886
if (WMI->getConformance ().isConcrete ())
874
887
return nullptr ;
875
888
889
+ // Don't specialize Apply instructions that return the Self type.
890
+ // Notice that it is sufficient to compare the return type to the
891
+ // substituted type because types that depend on the Self type are
892
+ // not allowed (for example [Self] is not allowed).
893
+ if (AI.getType ().getSwiftRValueType () == WMI->getLookupType ())
894
+ return nullptr ;
895
+
896
+ // We need to handle the Self return type.
897
+ // In we find arguments that are not the 'self' argument and if
898
+ // they are of the Self type then we abort the optimization.
899
+ for (auto Arg : AI.getArgumentsWithoutSelf ()) {
900
+ if (Arg->getType ().getSwiftRValueType () == WMI->getLookupType ())
901
+ return nullptr ;
902
+ }
903
+
876
904
// The lookup type is not an opened existential type,
877
905
// thus it cannot be made more concrete.
878
906
if (!WMI->getLookupType ()->isOpenedExistential ())
@@ -888,10 +916,10 @@ SILCombiner::propagateConcreteTypeOfInitExistential(FullApplySite AI,
888
916
// Keep around the dependence on the open instruction unless we've
889
917
// actually eliminated the use.
890
918
auto *NewWMI = Builder.createWitnessMethod (WMI->getLoc (),
891
- ConcreteType,
892
- Conformance, WMI->getMember (),
893
- WMI->getType (),
894
- WMI->isVolatile ());
919
+ ConcreteType,
920
+ Conformance, WMI->getMember (),
921
+ WMI->getType (),
922
+ WMI->isVolatile ());
895
923
// Replace only uses of the witness_method in the apply that is going to
896
924
// be changed.
897
925
MutableArrayRef<Operand> Operands = AI.getInstruction ()->getAllOperands ();
@@ -929,6 +957,15 @@ SILCombiner::propagateConcreteTypeOfInitExistential(FullApplySite AI) {
929
957
if (!Self)
930
958
return nullptr ;
931
959
960
+ // We need to handle the Self return type.
961
+ // In we find arguments that are not the 'self' argument and if
962
+ // they are of the Self type then we abort the optimization.
963
+ for (auto Arg : AI.getArgumentsWithoutSelf ()) {
964
+ if (Arg->getType ().getSwiftRValueType () ==
965
+ AI.getArguments ().back ()->getType ().getSwiftRValueType ())
966
+ return nullptr ;
967
+ }
968
+
932
969
// Obtain the protocol whose which should be used by the conformance.
933
970
auto *AFD = dyn_cast<AbstractFunctionDecl>(Callee->getDeclContext ());
934
971
if (!AFD)
0 commit comments