@@ -130,10 +130,10 @@ bool ReabstractionInfo::prepareAndCheck(ApplySite Apply, SILFunction *Callee,
130
130
bool HasConcreteGenericParams = false ;
131
131
bool HasNonArchetypeGenericParams = false ;
132
132
HasUnboundGenericParams = false ;
133
- for (auto DT : CalleeGenericSig->getGenericParams ()) {
133
+ for (auto GP : CalleeGenericSig->getSubstitutableParams ()) {
134
134
// Check only the substitutions for the generic parameters.
135
135
// Ignore any dependent types, etc.
136
- auto Replacement = Type (DT ).subst (InterfaceSubs);
136
+ auto Replacement = Type (GP ).subst (InterfaceSubs);
137
137
if (!Replacement->is <ArchetypeType>())
138
138
HasNonArchetypeGenericParams = true ;
139
139
@@ -146,7 +146,7 @@ bool ReabstractionInfo::prepareAndCheck(ApplySite Apply, SILFunction *Callee,
146
146
if (CalleeGenericEnv) {
147
147
if (auto Archetype = Replacement->getAs <ArchetypeType>()) {
148
148
auto OrigArchetype =
149
- CalleeGenericEnv->mapTypeIntoContext (DT )->castTo <ArchetypeType>();
149
+ CalleeGenericEnv->mapTypeIntoContext (GP )->castTo <ArchetypeType>();
150
150
if (Archetype->requiresClass () && !OrigArchetype->requiresClass ())
151
151
HasNonArchetypeGenericParams = true ;
152
152
if (Archetype->getLayoutConstraint () &&
@@ -261,6 +261,7 @@ ReabstractionInfo::ReabstractionInfo(ApplySite Apply, SILFunction *Callee,
261
261
SpecializedType = CanSILFunctionType ();
262
262
SubstitutedType = CanSILFunctionType ();
263
263
SpecializedGenericSig = nullptr ;
264
+ SpecializedGenericEnv = nullptr ;
264
265
return ;
265
266
}
266
267
@@ -382,6 +383,12 @@ ReabstractionInfo::createSubstitutedType(SILFunction *OrigF,
382
383
Lowering::GenericContextScope GenericScope (M.Types ,
383
384
CanSpecializedGenericSig);
384
385
FnTy = OrigF->getLoweredFunctionType ()->substGenericArgs (M, SubstMap);
386
+ // FIXME: Some of the added new requirements may not have been taken into
387
+ // account by the substGenericArgs. So, canonicalize in the context of the
388
+ // specialized signature.
389
+ FnTy = cast<SILFunctionType>(
390
+ CanSpecializedGenericSig->getCanonicalTypeInContext (
391
+ FnTy, *M.getSwiftModule ()));
385
392
}
386
393
assert (FnTy);
387
394
@@ -454,7 +461,8 @@ getGenericEnvironmentAndSignature(GenericSignatureBuilder &Builder,
454
461
GenericSignatureBuilder TmpBuilder (
455
462
M.getASTContext (), LookUpConformanceInModule (M.getSwiftModule ()));
456
463
TmpBuilder.addGenericSignature (GenericSig);
457
- TmpBuilder.finalize (SourceLoc (), GenericSig->getGenericParams ());
464
+ TmpBuilder.finalize (SourceLoc (), GenericSig->getGenericParams (),
465
+ /* allowConcreteGenericParams=*/ true );
458
466
GenericSig =
459
467
TmpBuilder.getGenericSignature ()->getCanonicalSignature ().getPointer ();
460
468
GenericEnv = GenericSig->createGenericEnvironment (*M.getSwiftModule ());
@@ -482,7 +490,8 @@ getSignatureWithRequirements(GenericSignature *OrigGenSig,
482
490
Builder.addRequirement (Req, Source);
483
491
}
484
492
485
- Builder.finalize (SourceLoc (), OrigGenSig->getGenericParams ());
493
+ Builder.finalize (SourceLoc (), OrigGenSig->getGenericParams (),
494
+ /* allowConcreteGenericParams=*/ true );
486
495
return getGenericEnvironmentAndSignature (Builder, M);
487
496
}
488
497
@@ -861,17 +870,14 @@ static void prepareCallArguments(ApplySite AI, SILBuilder &Builder,
861
870
862
871
// / Return a substituted callee function type.
863
872
static CanSILFunctionType
864
- getCalleeSubstFunctionType (SILValue Callee, const ReabstractionInfo &ReInfo ) {
873
+ getCalleeSubstFunctionType (SILValue Callee, SubstitutionList Subs ) {
865
874
// Create a substituted callee type.
866
875
auto CanFnTy =
867
876
dyn_cast<SILFunctionType>(Callee->getType ().getSwiftRValueType ());
868
877
auto CalleeSubstFnTy = CanFnTy;
869
878
870
- if (ReInfo.getSpecializedType ()->isPolymorphic () &&
871
- !ReInfo.getCallerParamSubstitutions ().empty ()) {
872
- CalleeSubstFnTy = CanFnTy->substGenericArgs (
873
- ReInfo.getNonSpecializedFunction ()->getModule (),
874
- ReInfo.getCallerParamSubstitutions ());
879
+ if (CanFnTy->isPolymorphic () && !Subs.empty ()) {
880
+ CalleeSubstFnTy = CanFnTy->substGenericArgs (*Callee->getModule (), Subs);
875
881
assert (!CalleeSubstFnTy->isPolymorphic () &&
876
882
" Substituted callee type should not be polymorphic" );
877
883
assert (!CalleeSubstFnTy->hasTypeParameter () &&
@@ -899,7 +905,7 @@ static ApplySite replaceWithSpecializedCallee(ApplySite AI,
899
905
Subs = ReInfo.getCallerParamSubstitutions ();
900
906
}
901
907
902
- auto CalleeSubstFnTy = getCalleeSubstFunctionType (Callee, ReInfo );
908
+ auto CalleeSubstFnTy = getCalleeSubstFunctionType (Callee, Subs );
903
909
auto CalleeSILSubstFnTy = SILType::getPrimitiveObjectType (CalleeSubstFnTy);
904
910
SILFunctionConventions substConv (CalleeSubstFnTy, Builder.getModule ());
905
911
@@ -988,19 +994,35 @@ class ReabstractionThunkGenerator {
988
994
Fragile = IsFragile;
989
995
990
996
{
991
- Mangle::Mangler M;
992
- GenericSpecializationMangler OldMangler (
993
- M, OrigF, ReInfo.getOriginalParamSubstitutions (), Fragile,
994
- GenericSpecializationMangler::NotReabstracted);
995
- OldMangler.mangle ();
996
- std::string Old = M.finalize ();
997
-
998
- NewMangling::GenericSpecializationMangler NewMangler (
999
- OrigF, ReInfo.getOriginalParamSubstitutions (), Fragile,
1000
- /* isReAbstracted*/ false );
1001
-
1002
- std::string New = NewMangler.mangle ();
1003
- ThunkName = NewMangling::selectMangling (Old, New);
997
+ if (!ReInfo.isPartialSpecialization ()) {
998
+ Mangle::Mangler M;
999
+ GenericSpecializationMangler OldMangler (
1000
+ M, OrigF, ReInfo.getOriginalParamSubstitutions (), Fragile,
1001
+ GenericSpecializationMangler::NotReabstracted);
1002
+ OldMangler.mangle ();
1003
+ std::string Old = M.finalize ();
1004
+
1005
+ NewMangling::GenericSpecializationMangler NewMangler (
1006
+ OrigF, ReInfo.getOriginalParamSubstitutions (), Fragile,
1007
+ /* isReAbstracted*/ false );
1008
+
1009
+ std::string New = NewMangler.mangle ();
1010
+ ThunkName = NewMangling::selectMangling (Old, New);
1011
+ } else {
1012
+ Mangle::Mangler M;
1013
+ PartialSpecializationMangler OldMangler (
1014
+ M, OrigF, ReInfo.getSpecializedType (), Fragile,
1015
+ PartialSpecializationMangler::NotReabstracted);
1016
+ OldMangler.mangle ();
1017
+ std::string Old = M.finalize ();
1018
+
1019
+ NewMangling::PartialSpecializationMangler NewMangler (
1020
+ OrigF, ReInfo.getSpecializedType (), Fragile,
1021
+ /* isReAbstracted*/ false );
1022
+
1023
+ std::string New = NewMangler.mangle ();
1024
+ ThunkName = NewMangling::selectMangling (Old, New);
1025
+ }
1004
1026
}
1005
1027
}
1006
1028
@@ -1020,6 +1042,8 @@ SILFunction *ReabstractionThunkGenerator::createThunk() {
1020
1042
if (!Thunk->empty ())
1021
1043
return Thunk;
1022
1044
1045
+ Thunk->setGenericEnvironment (ReInfo.getSpecializedGenericEnvironment ());
1046
+
1023
1047
SILBasicBlock *EntryBB = Thunk->createBasicBlock ();
1024
1048
SILBuilder Builder (EntryBB);
1025
1049
@@ -1068,16 +1092,19 @@ SILValue ReabstractionThunkGenerator::createReabstractionThunkApply(
1068
1092
SILBuilder &Builder) {
1069
1093
SILFunction *Thunk = &Builder.getFunction ();
1070
1094
auto *FRI = Builder.createFunctionRef (Loc, SpecializedFunc);
1095
+ auto Subs = Thunk->getForwardingSubstitutions ();
1096
+ auto CalleeSubstFnTy = getCalleeSubstFunctionType (FRI, Subs);
1097
+ auto CalleeSILSubstFnTy = SILType::getPrimitiveObjectType (CalleeSubstFnTy);
1071
1098
auto specConv = SpecializedFunc->getConventions ();
1072
1099
if (!SpecializedFunc->getLoweredFunctionType ()->hasErrorResult ()) {
1073
- return Builder.createApply (Loc, FRI, SpecializedFunc-> getLoweredType () ,
1074
- specConv.getSILResultType (), {} , Arguments,
1100
+ return Builder.createApply (Loc, FRI, CalleeSILSubstFnTy ,
1101
+ specConv.getSILResultType (), Subs , Arguments,
1075
1102
false );
1076
1103
}
1077
1104
// Create the logic for calling a throwing function.
1078
1105
SILBasicBlock *NormalBB = Thunk->createBasicBlock ();
1079
1106
SILBasicBlock *ErrorBB = Thunk->createBasicBlock ();
1080
- Builder.createTryApply (Loc, FRI, SpecializedFunc-> getLoweredType (), {} ,
1107
+ Builder.createTryApply (Loc, FRI, CalleeSILSubstFnTy, Subs ,
1081
1108
Arguments, NormalBB, ErrorBB);
1082
1109
auto *ErrorVal = ErrorBB->createPHIArgument (specConv.getSILErrorType (),
1083
1110
ValueOwnershipKind::Owned);
@@ -1208,11 +1235,6 @@ void swift::trySpecializeApplyOfGeneric(
1208
1235
bool replacePartialApplyWithoutReabstraction = false ;
1209
1236
auto *PAI = dyn_cast<PartialApplyInst>(Apply);
1210
1237
1211
- // TODO: Partial specializations of partial applies are
1212
- // not supported yet.
1213
- if (PAI && ReInfo.getSpecializedType ()->isPolymorphic ())
1214
- return ;
1215
-
1216
1238
if (PAI && ReInfo.hasConversions ()) {
1217
1239
// If we have a partial_apply and we converted some results/parameters from
1218
1240
// indirect to direct there are 3 cases:
@@ -1289,11 +1311,12 @@ void swift::trySpecializeApplyOfGeneric(
1289
1311
for (auto &Op : PAI->getArgumentOperands ()) {
1290
1312
Arguments.push_back (Op.get ());
1291
1313
}
1314
+ auto Subs = ReInfo.getCallerParamSubstitutions ();
1315
+ auto CalleeSubstFnTy = getCalleeSubstFunctionType (FRI, Subs);
1316
+ auto CalleeSILSubstFnTy = SILType::getPrimitiveObjectType (CalleeSubstFnTy);
1292
1317
auto *NewPAI = Builder.createPartialApply (PAI->getLoc (), FRI,
1293
- PAI->getSubstCalleeSILType (),
1294
- {},
1295
- Arguments,
1296
- PAI->getType ());
1318
+ CalleeSILSubstFnTy, Subs,
1319
+ Arguments, PAI->getType ());
1297
1320
PAI->replaceAllUsesWith (NewPAI);
1298
1321
DeadApplies.insert (PAI);
1299
1322
return ;
0 commit comments