Skip to content

Commit 65705a6

Browse files
committed
Sema: Fix substitution of opaque types with generic base class constraints.
They weren't always mapped out of context before building the interface type for the opaque type decl, and we failed to substitute the base class constraint when forming an opaque archetype with specific substitutions. Fixes rdar://problem/53318811.
1 parent 63235de commit 65705a6

File tree

3 files changed

+39
-0
lines changed

3 files changed

+39
-0
lines changed

lib/AST/ASTContext.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4382,6 +4382,14 @@ OpaqueTypeArchetypeType::get(OpaqueTypeDecl *Decl,
43824382
auto opaqueInterfaceTy = Decl->getUnderlyingInterfaceType();
43834383
auto layout = signature->getLayoutConstraint(opaqueInterfaceTy);
43844384
auto superclass = signature->getSuperclassBound(opaqueInterfaceTy);
4385+
#if !DO_IT_CORRECTLY
4386+
// Ad-hoc substitute the generic parameters of the superclass.
4387+
// If we correctly applied the substitutions to the generic signature
4388+
// constraints above, this would be unnecessary.
4389+
if (superclass && superclass->hasTypeParameter()) {
4390+
superclass = superclass.subst(Substitutions);
4391+
}
4392+
#endif
43854393
SmallVector<ProtocolDecl*, 4> protos;
43864394
for (auto proto : signature->getConformsTo(opaqueInterfaceTy)) {
43874395
protos.push_back(proto);

lib/Sema/TypeCheckGeneric.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,9 @@ Type TypeChecker::getOrCreateOpaqueResultType(TypeResolution resolution,
231231
diag::opaque_type_invalid_constraint);
232232
return constraintTypeLoc.getType();
233233
}
234+
235+
if (constraintType->hasArchetype())
236+
constraintType = constraintType->mapTypeOutOfContext();
234237

235238
// Create a generic signature for the opaque environment. This is the outer
236239
// generic signature with an added generic parameter representing the opaque
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// RUN: %target-swift-frontend -disable-availability-checking -emit-ir -verify %s
2+
3+
// rdar://problem/53318811
4+
5+
class Foo<T> {
6+
var x: T { fatalError() }
7+
}
8+
9+
func foo<T>(_: T) -> some Foo<T> {
10+
let localProp: some Foo<T> = Foo()
11+
return localProp
12+
}
13+
14+
class C<T> {
15+
func bar() -> some Foo<T> {
16+
return Foo()
17+
}
18+
19+
var prop: some Foo<T> = Foo()
20+
}
21+
22+
func bar() -> Int {
23+
var x = 0
24+
x = foo(0).x
25+
x = C<Int>().bar().x
26+
x = C<Int>().prop.x
27+
return x
28+
}

0 commit comments

Comments
 (0)