Skip to content

Commit 240e52e

Browse files
committed
DeclContext::getAsTypeOrTypeExtensionContext() generic typealiases.
This function was unable to "look through" an unbound generic typealias to find the underlying nominal type that was getting extended, which can occur if we end up performing a name lookup into this context before the extension itself has been fully-checked. Also, test that extending DictionaryIndex works.
1 parent 23b8cd1 commit 240e52e

File tree

2 files changed

+33
-8
lines changed

2 files changed

+33
-8
lines changed

lib/AST/DeclContext.cpp

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,33 @@ ASTContext &DeclContext::getASTContext() const {
4747

4848
GenericTypeDecl *
4949
DeclContext::getAsTypeOrTypeExtensionContext() const {
50-
if (auto decl = const_cast<Decl*>(getAsDeclOrDeclExtensionContext())) {
51-
if (auto ED = dyn_cast<ExtensionDecl>(decl)) {
52-
if (auto type = ED->getExtendedType())
53-
return type->getAnyNominal();
54-
return nullptr;
50+
auto decl = const_cast<Decl*>(getAsDeclOrDeclExtensionContext());
51+
if (!decl) return nullptr;
52+
53+
auto ext = dyn_cast<ExtensionDecl>(decl);
54+
if (!ext) return dyn_cast<GenericTypeDecl>(decl);
55+
56+
auto type = ext->getExtendedType();
57+
if (!type) return nullptr;
58+
59+
do {
60+
// expected case: we reference a nominal type (potentially through sugar)
61+
if (auto nominal = type->getAnyNominal())
62+
return nominal;
63+
64+
// early type checking case: we have a typealias reference that is still
65+
// unsugared, so explicitly look through the underlying type if there is
66+
// one.
67+
if (auto typealias =
68+
dyn_cast_or_null<TypeAliasDecl>(type->getAnyGeneric())) {
69+
type = typealias->getUnderlyingTypeLoc().getType();
70+
if (!type) return nullptr;
71+
72+
continue;
5573
}
56-
return dyn_cast<GenericTypeDecl>(decl);
57-
}
58-
return nullptr;
74+
75+
return nullptr;
76+
} while (true);
5977
}
6078

6179
/// If this DeclContext is a NominalType declaration or an

test/Compatibility/CountableRange.swift renamed to test/Compatibility/stdlib_generic_typealiases.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,10 @@ extension CountableRange { // expected-warning{{'CountableRange' is deprecated:
99
}
1010
}
1111

12+
struct RequiresHashable<T: Hashable> { }
13+
14+
extension DictionaryIndex {
15+
func testHashable() {
16+
_ = RequiresHashable<Key>()
17+
}
18+
}

0 commit comments

Comments
 (0)