Skip to content

Commit c52abb0

Browse files
committed
IRGen: Make sure the types we pass to SILType.subst are contextual when calling getLoweredTypeRef
rdar://54886179
1 parent ee562b9 commit c52abb0

File tree

2 files changed

+50
-4
lines changed

2 files changed

+50
-4
lines changed

lib/IRGen/GenReflection.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,11 @@ std::pair<llvm::Constant *, unsigned>
178178
IRGenModule::getLoweredTypeRef(SILType loweredType,
179179
CanGenericSignature genericSig,
180180
MangledTypeRefRole role) {
181-
auto type =
182-
substOpaqueTypesWithUnderlyingTypes(loweredType, genericSig).getASTType();
181+
auto substTy =
182+
substOpaqueTypesWithUnderlyingTypes(loweredType, genericSig);
183+
auto type = substTy.getASTType();
184+
if (substTy.hasArchetype())
185+
type = substTy.getASTType()->mapTypeOutOfContext()->getCanonicalType();
183186

184187
switch (role) {
185188
case MangledTypeRefRole::DefaultAssociatedTypeWitness:
@@ -954,9 +957,8 @@ class CaptureDescriptorBuilder : public ReflectionMetadataBuilder {
954957
})->getCanonicalType();
955958
}
956959

957-
auto InterfaceType = SwiftType->mapTypeOutOfContext();
958960
CaptureTypes.push_back(
959-
SILType::getPrimitiveObjectType(InterfaceType->getCanonicalType()));
961+
SILType::getPrimitiveObjectType(SwiftType->getCanonicalType()));
960962
}
961963

962964
return CaptureTypes;

test/IRGen/opaque_result_type_substitution.swift

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,3 +118,47 @@ struct OutterThing<Content : Thing> : Thing {
118118
}
119119
}
120120
}
121+
122+
public protocol W {}
123+
124+
struct Key : W {}
125+
126+
extension W {
127+
public static func transform(_ transform: @escaping (P1<Self>) -> ()) -> some W {
128+
return Key()
129+
}
130+
}
131+
132+
public struct P1<Key : W> { }
133+
134+
extension P1 {
135+
public func transform2<T>(_ transform: @escaping (Key) -> T) { }
136+
}
137+
138+
public struct T<Content> : W {
139+
public init(content : ()->Content) {}
140+
}
141+
142+
public struct Content<Content> : W {
143+
public init(content: Content) {}
144+
}
145+
146+
extension W {
147+
func moo() -> some W {
148+
return Content(content: self)
149+
}
150+
}
151+
152+
struct Test<Label : W> {
153+
var label: Label
154+
// This function used to crash.
155+
var dontCrash: some W {
156+
return Key.transform { y in
157+
y.transform2 { i in
158+
T() {
159+
return self.label
160+
}.moo()
161+
}
162+
}
163+
}
164+
}

0 commit comments

Comments
 (0)