Skip to content

Commit f1850ba

Browse files
authored
Merge pull request #26395 from jckarter/opaque-type-class-constraint-substitution
Sema: Fix substitution of opaque types with generic base class constraints.
2 parents a25e534 + 378eb96 commit f1850ba

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