Skip to content

Commit 378eb96

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 da38e25 commit 378eb96

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
@@ -3634,6 +3634,14 @@ OpaqueTypeArchetypeType::get(OpaqueTypeDecl *Decl,
36343634
auto opaqueInterfaceTy = Decl->getUnderlyingInterfaceType();
36353635
auto layout = signature->getLayoutConstraint(opaqueInterfaceTy);
36363636
auto superclass = signature->getSuperclassBound(opaqueInterfaceTy);
3637+
#if !DO_IT_CORRECTLY
3638+
// Ad-hoc substitute the generic parameters of the superclass.
3639+
// If we correctly applied the substitutions to the generic signature
3640+
// constraints above, this would be unnecessary.
3641+
if (superclass && superclass->hasTypeParameter()) {
3642+
superclass = superclass.subst(Substitutions);
3643+
}
3644+
#endif
36373645
SmallVector<ProtocolDecl*, 4> protos;
36383646
for (auto proto : signature->getConformsTo(opaqueInterfaceTy)) {
36393647
protos.push_back(proto);

lib/Sema/TypeCheckGeneric.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,9 @@ Type TypeChecker::getOrCreateOpaqueResultType(TypeResolution resolution,
222222
diag::opaque_type_invalid_constraint);
223223
return constraintTypeLoc.getType();
224224
}
225+
226+
if (constraintType->hasArchetype())
227+
constraintType = constraintType->mapTypeOutOfContext();
225228

226229
// Create a generic signature for the opaque environment. This is the outer
227230
// 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)