Skip to content

Commit 62974d8

Browse files
authored
Merge pull request #11127 from slavapestov/protocol-typealias-validate-for-lookup-fun-4.0
Sema/AST: Fix a couple of protocol typealias validation order bugs [4.0]
2 parents 7c8958f + cb1685c commit 62974d8

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
@@ -2421,14 +2421,19 @@ void TypeAliasDecl::setUnderlyingType(Type underlying) {
24212421
underlying = mapTypeOutOfContext(underlying);
24222422
UnderlyingTy.setType(underlying);
24232423

2424-
// Create a NameAliasType which will resolve to the underlying type.
2425-
ASTContext &Ctx = getASTContext();
2426-
auto aliasTy = new (Ctx, AllocationArena::Permanent) NameAliasType(this);
2427-
aliasTy->setRecursiveProperties(getUnderlyingTypeLoc().getType()
2428-
->getRecursiveProperties());
2429-
2430-
// Set the interface type of this declaration.
2431-
setInterfaceType(MetatypeType::get(aliasTy, Ctx));
2424+
// FIXME -- if we already have an interface type, we're changing the
2425+
// underlying type. See the comment in the ProtocolDecl case of
2426+
// validateDecl().
2427+
if (!hasInterfaceType()) {
2428+
// Create a NameAliasType which will resolve to the underlying type.
2429+
ASTContext &Ctx = getASTContext();
2430+
auto aliasTy = new (Ctx, AllocationArena::Permanent) NameAliasType(this);
2431+
aliasTy->setRecursiveProperties(getUnderlyingTypeLoc().getType()
2432+
->getRecursiveProperties());
2433+
2434+
// Set the interface type of this declaration.
2435+
setInterfaceType(MetatypeType::get(aliasTy, Ctx));
2436+
}
24322437
}
24332438

24342439
UnboundGenericType *TypeAliasDecl::getUnboundGenericType() const {

lib/Sema/TypeCheckType.cpp

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

31853185
if (auto *aliasDecl = dyn_cast<TypeAliasDecl>(member)) {
3186+
// FIXME: If this is a protocol typealias and we haven't built the
3187+
// protocol's generic environment yet, do so now, to ensure the
3188+
// typealias's underlying type has fully resoved dependent
3189+
// member types.
3190+
if (auto *protoDecl = dyn_cast<ProtocolDecl>(aliasDecl->getDeclContext()))
3191+
if (protoDecl->getGenericEnvironment() == nullptr)
3192+
validateDecl(protoDecl);
3193+
31863194
if (aliasDecl->getGenericParams()) {
31873195
return UnboundGenericType::get(
31883196
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)