Skip to content

Commit 817554b

Browse files
authored
Merge pull request #16203 from huonw/protocol-typealias-crash-4.2
[4.2] [Sema] Ensure that NameAliasTypes record the right substitutions.
2 parents d1a828d + 6db683c commit 817554b

File tree

3 files changed

+39
-21
lines changed

3 files changed

+39
-21
lines changed

lib/Sema/TypeCheckDecl.cpp

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6938,29 +6938,26 @@ void TypeChecker::validateDecl(ValueDecl *D) {
69386938
if (!aliasDecl->isGeneric()) {
69396939
aliasDecl->setGenericEnvironment(proto->getGenericEnvironment());
69406940

6941-
// If the underlying alias declaration has a type parameter,
6942-
// we have unresolved dependent member types we will need to deal
6943-
// with. Wipe out the types and validate them again.
6944-
// FIXME: We never should have recorded such a type in the first
6945-
// place.
6946-
if (!aliasDecl->getUnderlyingTypeLoc().getType() ||
6947-
aliasDecl->getUnderlyingTypeLoc().getType()
6948-
->findUnresolvedDependentMemberType()) {
6949-
aliasDecl->getUnderlyingTypeLoc().setType(Type(),
6950-
/*validated=*/false);
6951-
validateAccessControl(aliasDecl);
6952-
6953-
// Check generic parameters, if needed.
6954-
bool validated = aliasDecl->hasValidationStarted();
6941+
// The generic environment didn't exist until now, we may have
6942+
// unresolved types we will need to deal with, and need to record the
6943+
// appropriate substitutions for that environment. Wipe out the types
6944+
// and validate them again.
6945+
aliasDecl->getUnderlyingTypeLoc().setType(Type(),
6946+
/*validated=*/false);
6947+
aliasDecl->setInterfaceType(Type());
6948+
6949+
validateAccessControl(aliasDecl);
6950+
6951+
// Check generic parameters, if needed.
6952+
bool validated = aliasDecl->hasValidationStarted();
6953+
if (!validated)
6954+
aliasDecl->setIsBeingValidated();
6955+
SWIFT_DEFER {
69556956
if (!validated)
6956-
aliasDecl->setIsBeingValidated();
6957-
SWIFT_DEFER {
6958-
if (!validated)
6959-
aliasDecl->setIsBeingValidated(false);
6960-
};
6957+
aliasDecl->setIsBeingValidated(false);
6958+
};
69616959

6962-
validateTypealiasType(*this, aliasDecl);
6963-
}
6960+
validateTypealiasType(*this, aliasDecl);
69646961
}
69656962
}
69666963
}

lib/Sema/TypeCheckGeneric.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,16 @@ Type CompleteGenericTypeResolver::resolveDependentMemberType(
193193
// base type into it.
194194
auto concrete = ref->getBoundDecl();
195195
tc.validateDeclForNameLookup(concrete);
196+
197+
if (auto typeAlias = dyn_cast<TypeAliasDecl>(concrete)) {
198+
if (auto protocol = dyn_cast<ProtocolDecl>(typeAlias->getDeclContext())) {
199+
// We need to make sure the generic environment of a surrounding protocol
200+
// propagates to the typealias, since the former may not have existed when
201+
// the typealiases type was first computed.
202+
// FIXME: See the comment in the ProtocolDecl case of validateDecl().
203+
tc.validateDecl(protocol);
204+
}
205+
}
196206
if (!concrete->hasInterfaceType())
197207
return ErrorType::get(tc.Context);
198208
if (baseTy->isTypeParameter()) {
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// RUN: %target-swift-frontend %s -emit-module
2+
3+
protocol P2 {
4+
func f1<T : P1>(_: T) -> T.T1
5+
}
6+
7+
public struct S1<U> {}
8+
9+
protocol P1 {
10+
typealias T1 = S1<Self>
11+
}

0 commit comments

Comments
 (0)