Skip to content

Commit 538be50

Browse files
authored
Merge pull request #11125 from slavapestov/protocol-typealias-validate-for-lookup-fun
Sema/AST: Fix a couple of protocol typealias validation order bugs
2 parents 31341e6 + 1221bd8 commit 538be50

File tree

3 files changed

+40
-8
lines changed

3 files changed

+40
-8
lines changed

lib/AST/Decl.cpp

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2403,14 +2403,19 @@ void TypeAliasDecl::setUnderlyingType(Type underlying) {
24032403
underlying = mapTypeOutOfContext(underlying);
24042404
UnderlyingTy.setType(underlying);
24052405

2406-
// Create a NameAliasType which will resolve to the underlying type.
2407-
ASTContext &Ctx = getASTContext();
2408-
auto aliasTy = new (Ctx, AllocationArena::Permanent) NameAliasType(this);
2409-
aliasTy->setRecursiveProperties(getUnderlyingTypeLoc().getType()
2410-
->getRecursiveProperties());
2411-
2412-
// Set the interface type of this declaration.
2413-
setInterfaceType(MetatypeType::get(aliasTy, Ctx));
2406+
// FIXME -- if we already have an interface type, we're changing the
2407+
// underlying type. See the comment in the ProtocolDecl case of
2408+
// validateDecl().
2409+
if (!hasInterfaceType()) {
2410+
// Create a NameAliasType which will resolve to the underlying type.
2411+
ASTContext &Ctx = getASTContext();
2412+
auto aliasTy = new (Ctx, AllocationArena::Permanent) NameAliasType(this);
2413+
aliasTy->setRecursiveProperties(getUnderlyingTypeLoc().getType()
2414+
->getRecursiveProperties());
2415+
2416+
// Set the interface type of this declaration.
2417+
setInterfaceType(MetatypeType::get(aliasTy, Ctx));
2418+
}
24142419
}
24152420

24162421
UnboundGenericType *TypeAliasDecl::getUnboundGenericType() const {

lib/Sema/TypeCheckType.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3022,6 +3022,14 @@ Type TypeChecker::substMemberTypeWithBase(ModuleDecl *module,
30223022
}
30233023

30243024
if (auto *aliasDecl = dyn_cast<TypeAliasDecl>(member)) {
3025+
// FIXME: If this is a protocol typealias and we haven't built the
3026+
// protocol's generic environment yet, do so now, to ensure the
3027+
// typealias's underlying type has fully resoved dependent
3028+
// member types.
3029+
if (auto *protoDecl = dyn_cast<ProtocolDecl>(aliasDecl->getDeclContext()))
3030+
if (protoDecl->getGenericEnvironment() == nullptr)
3031+
validateDecl(protoDecl);
3032+
30253033
if (aliasDecl->getGenericParams()) {
30263034
return UnboundGenericType::get(
30273035
aliasDecl, baseTy,
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// RUN: %target-swift-frontend %s -typecheck
2+
3+
struct Bar : BarProtocol {
4+
typealias Element = Int
5+
}
6+
7+
struct Foo: FooProtocol {
8+
typealias Things = Bar
9+
func thing() -> Thing {}
10+
}
11+
12+
protocol BarProtocol {
13+
associatedtype Element
14+
}
15+
16+
protocol FooProtocol {
17+
associatedtype Things: BarProtocol
18+
typealias Thing = Things.Element
19+
}

0 commit comments

Comments
 (0)