Skip to content

Commit 0bd4e4e

Browse files
authored
Merge pull request #76486 from slavapestov/fix-issue-76479
IRGen: Workaround for type substitution limitation
2 parents 6eeb6f9 + c86ce64 commit 0bd4e4e

File tree

2 files changed

+39
-14
lines changed

2 files changed

+39
-14
lines changed

lib/IRGen/GenProto.cpp

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,24 @@ class PolymorphicConvention {
111111
FulfillmentMap Fulfillments;
112112

113113
GenericSignature::RequiredProtocols getRequiredProtocols(Type t) {
114+
// FIXME: We need to rework this to use archetypes instead of interface
115+
// types, or fix the bad interaction between interface type substitution
116+
// and concretized conformance requirements. Then we can remove the hack
117+
// from getReducedType() to handle this case, and also stop calling
118+
// getReducedType() here.
119+
t = Generics.getReducedType(t);
120+
if (!t->isTypeParameter())
121+
return {};
122+
114123
return Generics->getRequiredProtocols(t);
115124
}
116125

117126
CanType getSuperclassBound(Type t) {
127+
// See above.
128+
t = Generics.getReducedType(t);
129+
if (!t->isTypeParameter())
130+
return CanType();
131+
118132
if (auto superclassTy = Generics->getSuperclassBound(t))
119133
return superclassTy->getCanonicalType();
120134
return CanType();
@@ -143,8 +157,6 @@ class PolymorphicConvention {
143157
}
144158

145159
private:
146-
void initGenerics();
147-
148160
template <typename ...Args>
149161
void considerNewTypeSource(IsExact_t isExact, MetadataSource::Kind kind,
150162
CanType type, Args... args);
@@ -199,9 +211,8 @@ class PolymorphicConvention {
199211
PolymorphicConvention::PolymorphicConvention(IRGenModule &IGM,
200212
CanSILFunctionType fnType,
201213
bool considerParameterSources = true)
202-
: IGM(IGM), M(*IGM.getSwiftModule()), FnType(fnType){
203-
initGenerics();
204-
214+
: IGM(IGM), M(*IGM.getSwiftModule()), FnType(fnType),
215+
Generics(fnType->getInvocationGenericSignature()) {
205216
auto rep = fnType->getRepresentation();
206217

207218
if (fnType->isPseudogeneric()) {
@@ -249,11 +260,8 @@ PolymorphicConvention::PolymorphicConvention(IRGenModule &IGM,
249260

250261
void PolymorphicConvention::addPseudogenericFulfillments() {
251262
enumerateRequirements([&](GenericRequirement reqt) {
252-
auto archetype = Generics.getGenericEnvironment()
253-
->mapTypeIntoContext(reqt.getTypeParameter())
254-
->getAs<ArchetypeType>();
255-
assert(archetype && "did not get an archetype by mapping param?");
256-
auto erasedTypeParam = archetype->getExistentialType()->getCanonicalType();
263+
auto erasedTypeParam = Generics->getExistentialType(reqt.getTypeParameter())
264+
->getCanonicalType();
257265
Sources.emplace_back(MetadataSource::Kind::ErasedTypeMetadata,
258266
reqt.getTypeParameter(), erasedTypeParam);
259267

@@ -319,10 +327,6 @@ enumerateUnfulfilledRequirements(const RequirementCallback &callback) {
319327
});
320328
}
321329

322-
void PolymorphicConvention::initGenerics() {
323-
Generics = FnType->getInvocationGenericSignature();
324-
}
325-
326330
template <typename ...Args>
327331
void PolymorphicConvention::considerNewTypeSource(IsExact_t isExact,
328332
MetadataSource::Kind kind,
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// RUN: %target-swift-frontend -emit-ir %s
2+
3+
// https://github.com/swiftlang/swift/issues/76479
4+
5+
public struct G<T> where T: P1, T.A: P1, T.A.A: P1 {}
6+
7+
public protocol P1 {
8+
associatedtype A
9+
}
10+
11+
extension Int: P1 {
12+
public typealias A = Int
13+
}
14+
15+
public protocol P2 {
16+
func f()
17+
}
18+
19+
extension G: P2 where T.A == Int {
20+
public func f() {}
21+
}

0 commit comments

Comments
 (0)