|
17 | 17 | #include "swift/AST/AST.h"
|
18 | 18 | #include "swift/AST/DiagnosticsSIL.h"
|
19 | 19 | #include "swift/AST/ForeignErrorConvention.h"
|
| 20 | +#include "swift/AST/GenericEnvironment.h" |
20 | 21 | #include "swift/AST/ParameterList.h"
|
21 | 22 | #include "swift/Basic/Fallthrough.h"
|
22 | 23 | #include "swift/SIL/SILArgument.h"
|
@@ -61,9 +62,50 @@ emitBridgeNativeToObjectiveC(SILGenFunction &gen,
|
61 | 62 | auto witnessFnTy = witnessRef->getType();
|
62 | 63 |
|
63 | 64 | // Compute the substitutions.
|
64 |
| - ArrayRef<Substitution> substitutions = |
65 |
| - swiftValueType->gatherAllSubstitutions( |
66 |
| - gen.SGM.SwiftModule, nullptr); |
| 65 | + ArrayRef<Substitution> witnessSubstitutions = witness.getSubstitutions(); |
| 66 | + ArrayRef<Substitution> typeSubstitutions = |
| 67 | + swiftValueType->gatherAllSubstitutions(gen.SGM.SwiftModule, nullptr); |
| 68 | + |
| 69 | + // FIXME: Methods of generic types don't have substitutions in their |
| 70 | + // ConcreteDeclRefs for some reason. Furthermore, |
| 71 | + // SubsitutedProtocolConformances don't substitute their witness |
| 72 | + // ConcreteDeclRefs, so we need to do it ourselves. |
| 73 | + ArrayRef<Substitution> substitutions; |
| 74 | + SmallVector<Substitution, 4> substitutionsBuf; |
| 75 | + if (typeSubstitutions.empty()) { |
| 76 | + substitutions = witnessSubstitutions; |
| 77 | + } else if (witnessSubstitutions.empty()) { |
| 78 | + substitutions = typeSubstitutions; |
| 79 | + } else { |
| 80 | + // FIXME: The substitutions in a witness ConcreteDeclRef really ought to |
| 81 | + // be interface types. Instead, we get archetypes from a generic environment |
| 82 | + // that's either the extension method's generic environment, for a witness |
| 83 | + // from a nominal extension, or the conforming type's original declaration |
| 84 | + // generic environment, for a witness from a protocol extension. |
| 85 | + auto swiftValueTypeDecl = swiftValueType->getAnyNominal(); |
| 86 | + GenericEnvironment *witnessEnv; |
| 87 | + GenericSignature *witnessSig; |
| 88 | + |
| 89 | + if (witness.getDecl()->getDeclContext()->getDeclaredTypeOfContext() |
| 90 | + ->isExistentialType()) { |
| 91 | + witnessEnv = swiftValueTypeDecl->getGenericEnvironment(); |
| 92 | + witnessSig = swiftValueTypeDecl->getGenericSignature(); |
| 93 | + } else { |
| 94 | + witnessEnv = witness.getDecl()->getDeclContext() |
| 95 | + ->getGenericEnvironmentOfContext(); |
| 96 | + witnessSig = witness.getDecl()->getDeclContext() |
| 97 | + ->getGenericSignatureOfContext(); |
| 98 | + } |
| 99 | + |
| 100 | + SubstitutionMap typeSubMap = witnessEnv |
| 101 | + ->getSubstitutionMap(gen.SGM.SwiftModule, |
| 102 | + witnessSig, |
| 103 | + typeSubstitutions); |
| 104 | + for (auto sub : witnessSubstitutions) { |
| 105 | + substitutionsBuf.push_back(sub.subst(gen.SGM.SwiftModule, typeSubMap)); |
| 106 | + } |
| 107 | + substitutions = substitutionsBuf; |
| 108 | + } |
67 | 109 |
|
68 | 110 | if (!substitutions.empty()) {
|
69 | 111 | // Substitute into the witness function type.
|
|
0 commit comments