@@ -112,9 +112,11 @@ namespace {
112
112
private:
113
113
SILGenFunction &SGF;
114
114
SILLocation Loc;
115
+ bool Flattening;
115
116
116
117
public:
117
- Transform (SILGenFunction &SGF, SILLocation loc) : SGF(SGF), Loc(loc) {}
118
+ Transform (SILGenFunction &SGF, SILLocation loc, bool flattening = false )
119
+ : SGF(SGF), Loc(loc), Flattening(flattening) {}
118
120
virtual ~Transform () = default ;
119
121
120
122
// / Transform an arbitrary value.
@@ -1252,7 +1254,7 @@ namespace {
1252
1254
return SGF.emitTransformedValue (Loc, input,
1253
1255
inputOrigType, inputSubstType,
1254
1256
outputOrigType, outputSubstType,
1255
- context);
1257
+ /* isFlattening= */ false , context);
1256
1258
}
1257
1259
1258
1260
// / Force the given result into the given initialization.
@@ -2177,7 +2179,7 @@ void ResultPlanner::execute(ArrayRef<SILValue> innerDirectResults,
2177
2179
Gen.emitTransformedValue (Loc, innerResult,
2178
2180
op.InnerOrigType , op.InnerSubstType ,
2179
2181
op.OuterOrigType , op.OuterSubstType ,
2180
- outerResultCtxt);
2182
+ /* isFlattening= */ false , outerResultCtxt);
2181
2183
2182
2184
// If the outer is indirect, force it into the context.
2183
2185
if (outerIsIndirect) {
@@ -2269,26 +2271,72 @@ void ResultPlanner::execute(ArrayRef<SILValue> innerDirectResults,
2269
2271
// / \param inputSubstType Formal AST type of function value being thunked
2270
2272
// / \param outputOrigType Abstraction pattern of the thunk
2271
2273
// / \param outputSubstType Formal AST type of the thunk
2272
- static void buildThunkBody (SILGenFunction &gen, SILLocation loc,
2273
- AbstractionPattern inputOrigType,
2274
- CanAnyFunctionType inputSubstType,
2275
- AbstractionPattern outputOrigType,
2276
- CanAnyFunctionType outputSubstType) {
2274
+ static void buildThunkBody (
2275
+ SILGenFunction &gen, SILLocation loc, bool isFlattening,
2276
+ AbstractionPattern inputOrigType, CanAnyFunctionType inputSubstType,
2277
+ AbstractionPattern outputOrigType, CanAnyFunctionType outputSubstType) {
2277
2278
PrettyStackTraceSILFunction stackTrace (" emitting reabstraction thunk in" ,
2278
2279
&gen.F );
2279
2280
auto thunkType = gen.F .getLoweredFunctionType ();
2280
2281
2281
2282
FullExpr scope (gen.Cleanups , CleanupLocation::get (loc));
2282
2283
2283
- SmallVector<ManagedValue, 8 > params ;
2284
+ SmallVector<ManagedValue, 8 > paramsBuffer ;
2284
2285
// TODO: Could accept +0 arguments here when forwardFunctionArguments/
2285
2286
// emitApply can.
2286
- gen.collectThunkParams (loc, params, /* allowPlusZero*/ false );
2287
-
2288
- ManagedValue fnValue = params.pop_back_val ();
2287
+ gen.collectThunkParams (loc, paramsBuffer, /* allowPlusZero*/ false );
2288
+ ManagedValue fnValue = paramsBuffer.pop_back_val ();
2289
2289
auto fnType = fnValue.getType ().castTo <SILFunctionType>();
2290
2290
assert (!fnType->isPolymorphic ());
2291
2291
auto argTypes = fnType->getParameters ();
2292
+
2293
+ ArrayRef<ManagedValue> params (paramsBuffer);
2294
+ if (isFlattening) {
2295
+ // Flatten an instance function type.
2296
+ assert (
2297
+ inputSubstType->getCurryLevel () - outputSubstType->getCurryLevel () == 1 &&
2298
+ " Invalid (un)currying" );
2299
+
2300
+ SmallVector<SILValue, 1 > selfArg;
2301
+ forwardFunctionArguments (gen, loc, fnType, params.front (), selfArg);
2302
+ auto inner = gen.emitApplyWithRethrow (loc, fnValue.forward (gen),
2303
+ /* substFnType*/ fnValue.getType (),
2304
+ /* substitutions*/ {}, selfArg);
2305
+
2306
+ // For the next steps update the variables by dropping the already applied
2307
+ // first parameter (`self`)
2308
+ params = params.slice (1 );
2309
+ fnValue = ManagedValue::forUnmanaged (inner);
2310
+ fnType = fnValue.getType ().castTo <SILFunctionType>();
2311
+ argTypes = fnType->getParameters ();
2312
+ inputOrigType = inputOrigType.getFunctionResultType ();
2313
+ inputSubstType = cast<AnyFunctionType>(inputSubstType.getResult ());
2314
+
2315
+ Type newOrigInput, newSubstInput;
2316
+ auto origFunction = cast<AnyFunctionType>(outputOrigType.getType ());
2317
+ if (auto origInput = dyn_cast<TupleType>(origFunction.getInput ())) {
2318
+ auto substInput = cast<TupleType>(outputSubstType.getInput ());
2319
+ assert (origInput->getNumElements () == substInput->getNumElements () &&
2320
+ " invalid premise" );
2321
+ newOrigInput = TupleType::get (origInput->getElements ().slice (1 ),
2322
+ gen.getASTContext ());
2323
+ newSubstInput = TupleType::get (substInput->getElements ().slice (1 ),
2324
+ gen.getASTContext ());
2325
+ } else {
2326
+ // In this case `self` was the only parameter, which leaves us with an
2327
+ // application of `Void`
2328
+ assert (!dyn_cast<TupleType>(outputSubstType.getInput ()) &&
2329
+ " invalid premise" );
2330
+ newOrigInput = newSubstInput = TupleType::getEmpty (gen.getASTContext ());
2331
+ }
2332
+
2333
+ outputOrigType = AbstractionPattern (CanFunctionType::get (
2334
+ newOrigInput->getCanonicalType (), origFunction.getResult (),
2335
+ origFunction->getExtInfo ()));
2336
+ outputSubstType = CanFunctionType::get (newSubstInput->getCanonicalType (),
2337
+ outputSubstType.getResult (),
2338
+ outputSubstType->getExtInfo ());
2339
+ }
2292
2340
2293
2341
// Translate the argument values. Function parameters are
2294
2342
// contravariant: we want to switch the direction of transformation
@@ -2419,14 +2467,12 @@ CanSILFunctionType SILGenFunction::buildThunkType(
2419
2467
}
2420
2468
2421
2469
// / Create a reabstraction thunk.
2422
- static ManagedValue createThunk (SILGenFunction &gen,
2423
- SILLocation loc,
2424
- ManagedValue fn,
2425
- AbstractionPattern inputOrigType,
2426
- CanAnyFunctionType inputSubstType,
2427
- AbstractionPattern outputOrigType,
2428
- CanAnyFunctionType outputSubstType,
2429
- const TypeLowering &expectedTL) {
2470
+ static ManagedValue createThunk (
2471
+ SILGenFunction &gen, SILLocation loc, ManagedValue fn,
2472
+ AbstractionPattern inputOrigType, CanAnyFunctionType inputSubstType,
2473
+ AbstractionPattern outputOrigType, CanAnyFunctionType outputSubstType,
2474
+ const TypeLowering &expectedTL, bool isFlattening) {
2475
+
2430
2476
auto expectedType = expectedTL.getLoweredType ().castTo <SILFunctionType>();
2431
2477
2432
2478
// We can't do bridging here.
@@ -2452,7 +2498,7 @@ static ManagedValue createThunk(SILGenFunction &gen,
2452
2498
thunk->setContextGenericParams (gen.F .getContextGenericParams ());
2453
2499
SILGenFunction thunkSGF (gen.SGM , *thunk);
2454
2500
auto loc = RegularLocation::getAutoGeneratedLocation ();
2455
- buildThunkBody (thunkSGF, loc,
2501
+ buildThunkBody (thunkSGF, loc, isFlattening,
2456
2502
inputOrigType, inputSubstType,
2457
2503
outputOrigType, outputSubstType);
2458
2504
}
@@ -2494,7 +2540,7 @@ ManagedValue Transform::transformFunction(ManagedValue fn,
2494
2540
return createThunk (SGF, Loc, fn,
2495
2541
inputOrigType, inputSubstType,
2496
2542
outputOrigType, outputSubstType,
2497
- expectedTL);
2543
+ expectedTL, Flattening );
2498
2544
}
2499
2545
2500
2546
// We do not, conversion is trivial.
@@ -2535,7 +2581,7 @@ SILGenFunction::emitOrigToSubstValue(SILLocation loc, ManagedValue v,
2535
2581
return emitTransformedValue (loc, v,
2536
2582
origType, substType,
2537
2583
AbstractionPattern (substType), substType,
2538
- ctxt);
2584
+ /* isFlattening= */ false , ctxt);
2539
2585
}
2540
2586
2541
2587
// / Given a value with the abstraction patterns of the original formal
@@ -2561,7 +2607,7 @@ SILGenFunction::emitSubstToOrigValue(SILLocation loc, ManagedValue v,
2561
2607
return emitTransformedValue (loc, v,
2562
2608
AbstractionPattern (substType), substType,
2563
2609
origType, substType,
2564
- ctxt);
2610
+ /* isFlattening= */ false , ctxt);
2565
2611
}
2566
2612
2567
2613
// / Given a value with the abstraction patterns of the substituted
@@ -2594,10 +2640,12 @@ ManagedValue
2594
2640
SILGenFunction::emitTransformedValue (SILLocation loc, ManagedValue v,
2595
2641
CanType inputType,
2596
2642
CanType outputType,
2643
+ bool isFlattening,
2597
2644
SGFContext ctxt) {
2598
2645
return emitTransformedValue (loc, v,
2599
2646
AbstractionPattern (inputType), inputType,
2600
- AbstractionPattern (outputType), outputType);
2647
+ AbstractionPattern (outputType), outputType,
2648
+ isFlattening, ctxt);
2601
2649
}
2602
2650
2603
2651
ManagedValue
@@ -2606,8 +2654,9 @@ SILGenFunction::emitTransformedValue(SILLocation loc, ManagedValue v,
2606
2654
CanType inputSubstType,
2607
2655
AbstractionPattern outputOrigType,
2608
2656
CanType outputSubstType,
2657
+ bool isFlattening,
2609
2658
SGFContext ctxt) {
2610
- return Transform (*this , loc).transform (v,
2659
+ return Transform (*this , loc, isFlattening ).transform (v,
2611
2660
inputOrigType,
2612
2661
inputSubstType,
2613
2662
outputOrigType,
0 commit comments