Skip to content

Commit f2c3870

Browse files
authored
Merge pull request #14588 from huonw/conditional-concrete-crash
[AST] Keep generic type params generic in RequirementEnvironments.
2 parents 56cf077 + 63a5093 commit f2c3870

File tree

2 files changed

+32
-26
lines changed

2 files changed

+32
-26
lines changed

lib/AST/RequirementEnvironment.cpp

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -43,34 +43,31 @@ RequirementEnvironment::RequirementEnvironment(
4343
auto concreteType = conformanceDC->getSelfInterfaceType();
4444
auto *conformanceSig = conformanceDC->getGenericSignatureOfContext();
4545

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.
4848
//
4949
// For structs, enums and protocols, this is a 1:1 mapping; for classes,
5050
// we increase the depth of each generic parameter by 1 so that we can
5151
// 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+
}
6462

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();
7168

72-
substConcreteType = concreteType.subst(conformanceToSyntheticEnvMap);
73-
}
69+
auto substConcreteType = concreteType.subst(
70+
conformanceToSyntheticTypeFn, conformanceToSyntheticConformanceFn);
7471

7572
// Calculate the depth at which the requirement's generic parameters
7673
// appear in the synthetic signature.
@@ -171,9 +168,9 @@ RequirementEnvironment::RequirementEnvironment(
171168
// Now, add all generic parameters from the conforming type.
172169
if (conformanceSig) {
173170
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>());
177174
}
178175
}
179176

@@ -186,7 +183,8 @@ RequirementEnvironment::RequirementEnvironment(
186183

187184
if (conformanceSig) {
188185
for (auto &rawReq : conformanceSig->getRequirements()) {
189-
if (auto req = rawReq.subst(conformanceToSyntheticEnvMap))
186+
if (auto req = rawReq.subst(conformanceToSyntheticTypeFn,
187+
conformanceToSyntheticConformanceFn))
190188
builder.addRequirement(*req, source, nullptr);
191189
}
192190
}

test/Generics/conditional_conformances.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,3 +360,11 @@ func passesConditionallyNotF7(x21: X2<X1>) {
360360
// expected-note@-2{{requirement specified as 'X1.A' (aka 'X0') : 'P7'}}
361361
// expected-note@-3{{requirement from conditional conformance of 'X2<X1>' to 'P7'}}
362362
}
363+
364+
365+
public struct SR6990<T, U> {}
366+
extension SR6990: Sequence where T == Int {
367+
public typealias Element = Float
368+
public typealias Iterator = IndexingIterator<[Float]>
369+
public func makeIterator() -> Iterator { fatalError() }
370+
}

0 commit comments

Comments
 (0)