Skip to content

Sema: Fix substitution of opaque types with generic base class constraints. #26395

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3634,6 +3634,14 @@ OpaqueTypeArchetypeType::get(OpaqueTypeDecl *Decl,
auto opaqueInterfaceTy = Decl->getUnderlyingInterfaceType();
auto layout = signature->getLayoutConstraint(opaqueInterfaceTy);
auto superclass = signature->getSuperclassBound(opaqueInterfaceTy);
#if !DO_IT_CORRECTLY
// Ad-hoc substitute the generic parameters of the superclass.
// If we correctly applied the substitutions to the generic signature
// constraints above, this would be unnecessary.
if (superclass && superclass->hasTypeParameter()) {
superclass = superclass.subst(Substitutions);
}
#endif
SmallVector<ProtocolDecl*, 4> protos;
for (auto proto : signature->getConformsTo(opaqueInterfaceTy)) {
protos.push_back(proto);
Expand Down
3 changes: 3 additions & 0 deletions lib/Sema/TypeCheckGeneric.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,9 @@ Type TypeChecker::getOrCreateOpaqueResultType(TypeResolution resolution,
diag::opaque_type_invalid_constraint);
return constraintTypeLoc.getType();
}

if (constraintType->hasArchetype())
constraintType = constraintType->mapTypeOutOfContext();

// Create a generic signature for the opaque environment. This is the outer
// generic signature with an added generic parameter representing the opaque
Expand Down
28 changes: 28 additions & 0 deletions test/type/opaque_generic_superclass_constraint.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// RUN: %target-swift-frontend -disable-availability-checking -emit-ir -verify %s

// rdar://problem/53318811

class Foo<T> {
var x: T { fatalError() }
}

func foo<T>(_: T) -> some Foo<T> {
let localProp: some Foo<T> = Foo()
return localProp
}

class C<T> {
func bar() -> some Foo<T> {
return Foo()
}

var prop: some Foo<T> = Foo()
}

func bar() -> Int {
var x = 0
x = foo(0).x
x = C<Int>().bar().x
x = C<Int>().prop.x
return x
}