Skip to content

Commit 94849de

Browse files
committed
ReplaceOpaqueTypesWithUnderlyingTypes: Handle a type being "substituted" with itself.
SIL type lowering might have already substituted away an opaque type during a SIL substitution. Fixes rdar://problem/62072397.
1 parent db8c500 commit 94849de

File tree

2 files changed

+29
-4
lines changed

2 files changed

+29
-4
lines changed

lib/AST/Type.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3044,12 +3044,21 @@ ProtocolConformanceRef ReplaceOpaqueTypesWithUnderlyingTypes::
30443044
operator()(CanType maybeOpaqueType, Type replacementType,
30453045
ProtocolDecl *protocol) const {
30463046
auto abstractRef = ProtocolConformanceRef(protocol);
3047-
3047+
30483048
auto archetypeAndRoot = getArchetypeAndRootOpaqueArchetype(maybeOpaqueType);
30493049
if (!archetypeAndRoot) {
3050-
assert(maybeOpaqueType->isTypeParameter() ||
3051-
maybeOpaqueType->is<ArchetypeType>());
3052-
return abstractRef;
3050+
if (maybeOpaqueType->isTypeParameter() ||
3051+
maybeOpaqueType->is<ArchetypeType>())
3052+
return abstractRef;
3053+
3054+
// SIL type lowering may have already substituted away the opaque type, in
3055+
// which case we'll end up "substituting" the same type.
3056+
if (maybeOpaqueType->isEqual(replacementType)) {
3057+
return inContext->getParentModule()
3058+
->lookupConformance(replacementType, protocol);
3059+
}
3060+
3061+
llvm_unreachable("origType should have been an opaque type or type parameter");
30533062
}
30543063

30553064
auto archetype = archetypeAndRoot->first;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// RUN: %target-swift-emit-silgen -disable-availability-checking -verify %s
2+
protocol P {}
3+
extension Int: P {}
4+
5+
func foo() -> some P { return 0 }
6+
func bar<T: P>(_ x: T) -> some P { return x }
7+
8+
struct Bas<T: P> { init(_: T) {} }
9+
10+
func abstraction_level<T>(x: T) -> (T) -> () {
11+
return { _ in () }
12+
}
13+
14+
func test() {
15+
abstraction_level(x: Bas(bar(foo())))(Bas(bar(foo())))
16+
}

0 commit comments

Comments
 (0)