@@ -2356,23 +2356,39 @@ void irgen::emitWitnessTableRefs(IRGenFunction &IGF,
2356
2356
}
2357
2357
}
2358
2358
2359
- static CanType getSubstSelfType (CanSILFunctionType substFnType) {
2359
+ static CanType getSubstSelfType (CanSILFunctionType origFnType,
2360
+ ArrayRef<Substitution> subs) {
2360
2361
// Grab the apparent 'self' type. If there isn't a 'self' type,
2361
2362
// we're not going to try to access this anyway.
2362
- assert (!substFnType ->getParameters ().empty ());
2363
+ assert (!origFnType ->getParameters ().empty ());
2363
2364
2364
- auto selfParam = substFnType ->getParameters ().back ();
2365
- CanType substInputType = selfParam.getType ();
2365
+ auto selfParam = origFnType ->getParameters ().back ();
2366
+ CanType inputType = selfParam.getType ();
2366
2367
// If the parameter is a direct metatype parameter, this is a static method
2367
2368
// of the instance type. We can assume this because:
2368
2369
// - metatypes cannot directly conform to protocols
2369
2370
// - even if they could, they would conform as a value type 'self' and thus
2370
2371
// be passed indirectly as an @in or @inout parameter.
2371
- if (auto meta = dyn_cast<MetatypeType>(substInputType )) {
2372
+ if (auto meta = dyn_cast<MetatypeType>(inputType )) {
2372
2373
if (!selfParam.isIndirect ())
2373
- substInputType = meta.getInstanceType ();
2374
+ inputType = meta.getInstanceType ();
2374
2375
}
2375
- return substInputType;
2376
+
2377
+ // Substitute the `self` type.
2378
+ // FIXME: This has to be done as a formal AST type substitution rather than
2379
+ // a SIL function type substitution, because some nominal types (viz
2380
+ // Optional) have type lowering recursively applied to their type parameters.
2381
+ // Substituting into the original lowered function type like this is still
2382
+ // problematic if we ever allow methods or protocol conformances on structural
2383
+ // types; we'd really need to separately record the formal Self type in the
2384
+ // SIL function type to make that work, which could be managed by having a
2385
+ // "substituted generic signature" concept.
2386
+ if (!subs.empty ()) {
2387
+ auto subMap = origFnType->getGenericSignature ()->getSubstitutionMap (subs);
2388
+ inputType = inputType.subst (subMap)->getCanonicalType ();
2389
+ }
2390
+
2391
+ return inputType;
2376
2392
}
2377
2393
2378
2394
namespace {
@@ -2387,7 +2403,7 @@ namespace {
2387
2403
WitnessMetadata *witnessMetadata, Explosion &out);
2388
2404
2389
2405
private:
2390
- void emitEarlySources (CanSILFunctionType substFnType , Explosion &out) {
2406
+ void emitEarlySources (ArrayRef<Substitution> subs , Explosion &out) {
2391
2407
for (auto &source : getSources ()) {
2392
2408
switch (source.getKind ()) {
2393
2409
// Already accounted for in the parameters.
@@ -2397,7 +2413,7 @@ namespace {
2397
2413
2398
2414
// Needs a special argument.
2399
2415
case MetadataSource::Kind::GenericLValueMetadata: {
2400
- out.add (IGF.emitTypeMetadataRef (getSubstSelfType (substFnType )));
2416
+ out.add (IGF.emitTypeMetadataRef (getSubstSelfType (FnType, subs )));
2401
2417
continue ;
2402
2418
}
2403
2419
@@ -2429,7 +2445,7 @@ void EmitPolymorphicArguments::emit(CanSILFunctionType substFnType,
2429
2445
WitnessMetadata *witnessMetadata,
2430
2446
Explosion &out) {
2431
2447
// Add all the early sources.
2432
- emitEarlySources (substFnType , out);
2448
+ emitEarlySources (subs , out);
2433
2449
2434
2450
// For now, treat all archetypes independently.
2435
2451
enumerateUnfulfilledRequirements ([&](GenericRequirement requirement) {
@@ -2453,7 +2469,7 @@ void EmitPolymorphicArguments::emit(CanSILFunctionType substFnType,
2453
2469
2454
2470
case MetadataSource::Kind::SelfMetadata: {
2455
2471
assert (witnessMetadata && " no metadata structure for witness method" );
2456
- auto self = IGF.emitTypeMetadataRef (getSubstSelfType (substFnType ));
2472
+ auto self = IGF.emitTypeMetadataRef (getSubstSelfType (FnType, subs ));
2457
2473
witnessMetadata->SelfMetadata = self;
2458
2474
continue ;
2459
2475
}
@@ -2513,11 +2529,11 @@ NecessaryBindings::forFunctionInvocations(IRGenModule &IGM,
2513
2529
continue ;
2514
2530
2515
2531
case MetadataSource::Kind::GenericLValueMetadata:
2516
- bindings.addTypeMetadata (getSubstSelfType (substType ));
2532
+ bindings.addTypeMetadata (getSubstSelfType (origType, subs ));
2517
2533
continue ;
2518
2534
2519
2535
case MetadataSource::Kind::SelfMetadata:
2520
- bindings.addTypeMetadata (getSubstSelfType (substType ));
2536
+ bindings.addTypeMetadata (getSubstSelfType (origType, subs ));
2521
2537
continue ;
2522
2538
2523
2539
case MetadataSource::Kind::SelfWitnessTable:
0 commit comments