@@ -43,34 +43,31 @@ RequirementEnvironment::RequirementEnvironment(
43
43
auto concreteType = conformanceDC->getSelfInterfaceType ();
44
44
auto *conformanceSig = conformanceDC->getGenericSignatureOfContext ();
45
45
46
- // Build a substitution map from the generic parameters of the conforming
47
- // type to the synthetic environment.
46
+ // This is a substitution function from the generic parameters of the
47
+ // conforming type to the synthetic environment.
48
48
//
49
49
// For structs, enums and protocols, this is a 1:1 mapping; for classes,
50
50
// we increase the depth of each generic parameter by 1 so that we can
51
51
// introduce a class-bound 'Self' parameter.
52
- auto substConcreteType = concreteType;
53
- SubstitutionMap conformanceToSyntheticEnvMap;
54
- if (conformanceSig) {
55
- conformanceToSyntheticEnvMap = conformanceSig->getSubstitutionMap (
56
- [&](SubstitutableType *type) {
57
- auto *genericParam = cast<GenericTypeParamType>(type);
58
- if (covariantSelf) {
59
- return GenericTypeParamType::get (
60
- genericParam->getDepth () + 1 ,
61
- genericParam->getIndex (),
62
- ctx);
63
- }
52
+ //
53
+ // This is a raw function rather than a substitution map because we need to
54
+ // keep generic parameters as generic, even if the conformanceSig (the best
55
+ // way to create the substitution map) equates them to concrete types.
56
+ auto conformanceToSyntheticTypeFn = [&](SubstitutableType *type) {
57
+ auto *genericParam = cast<GenericTypeParamType>(type);
58
+ if (covariantSelf) {
59
+ return GenericTypeParamType::get (genericParam->getDepth () + 1 ,
60
+ genericParam->getIndex (), ctx);
61
+ }
64
62
65
- return GenericTypeParamType::get (
66
- genericParam->getDepth (),
67
- genericParam->getIndex (),
68
- ctx);
69
- },
70
- MakeAbstractConformanceForGenericType ());
63
+ return GenericTypeParamType::get (genericParam->getDepth (),
64
+ genericParam->getIndex (), ctx);
65
+ };
66
+ auto conformanceToSyntheticConformanceFn =
67
+ MakeAbstractConformanceForGenericType ();
71
68
72
- substConcreteType = concreteType.subst (conformanceToSyntheticEnvMap);
73
- }
69
+ auto substConcreteType = concreteType.subst (
70
+ conformanceToSyntheticTypeFn, conformanceToSyntheticConformanceFn);
74
71
75
72
// Calculate the depth at which the requirement's generic parameters
76
73
// appear in the synthetic signature.
@@ -171,9 +168,9 @@ RequirementEnvironment::RequirementEnvironment(
171
168
// Now, add all generic parameters from the conforming type.
172
169
if (conformanceSig) {
173
170
for (auto param : conformanceSig->getGenericParams ()) {
174
- builder. addGenericParameter (
175
- Type (param). subst (conformanceToSyntheticEnvMap)
176
- ->castTo <GenericTypeParamType>());
171
+ auto substParam = Type (param). subst (conformanceToSyntheticTypeFn,
172
+ conformanceToSyntheticConformanceFn);
173
+ builder. addGenericParameter (substParam ->castTo <GenericTypeParamType>());
177
174
}
178
175
}
179
176
@@ -186,7 +183,8 @@ RequirementEnvironment::RequirementEnvironment(
186
183
187
184
if (conformanceSig) {
188
185
for (auto &rawReq : conformanceSig->getRequirements ()) {
189
- if (auto req = rawReq.subst (conformanceToSyntheticEnvMap))
186
+ if (auto req = rawReq.subst (conformanceToSyntheticTypeFn,
187
+ conformanceToSyntheticConformanceFn))
190
188
builder.addRequirement (*req, source, nullptr );
191
189
}
192
190
}
0 commit comments