Skip to content

Commit bcfbcad

Browse files
committed
Sema: Don't allow generic typealiases to have an unbound generic underlying type
We allow this sort of thing: struct Generic<T> {} typealias Alias = Generic ... Alias<Int> However we have to be sure to ban this if the typealias is itself generic, ie typealias Alias<T> = Generic Otherwise we will crash.
1 parent bd56b46 commit bcfbcad

File tree

5 files changed

+21
-6
lines changed

5 files changed

+21
-6
lines changed

lib/Sema/TypeCheckDecl.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3197,7 +3197,11 @@ void TypeChecker::typeCheckDecl(Decl *D) {
31973197

31983198
/// Validate the underlying type of the given typealias.
31993199
static void validateTypealiasType(TypeChecker &tc, TypeAliasDecl *typeAlias) {
3200-
TypeResolutionOptions options(TypeResolverContext::TypeAliasDecl);
3200+
TypeResolutionOptions options(
3201+
(typeAlias->getGenericParams() ?
3202+
TypeResolverContext::GenericTypeAliasDecl :
3203+
TypeResolverContext::TypeAliasDecl));
3204+
32013205
if (!typeAlias->getDeclContext()->isCascadingContextForLookup(
32023206
/*functionsAreNonCascading*/true)) {
32033207
options |= TypeResolutionFlags::KnownNonCascadingDependency;
@@ -4198,7 +4202,10 @@ void TypeChecker::validateDeclForNameLookup(ValueDecl *D) {
41984202
if (typealias->isBeingValidated()) return;
41994203

42004204
auto helper = [&] {
4201-
TypeResolutionOptions options(TypeResolverContext::TypeAliasDecl);
4205+
TypeResolutionOptions options(
4206+
(typealias->getGenericParams() ?
4207+
TypeResolverContext::GenericTypeAliasDecl :
4208+
TypeResolverContext::TypeAliasDecl));
42024209
if (validateType(typealias->getUnderlyingTypeLoc(),
42034210
TypeResolution::forStructural(typealias), options)) {
42044211
typealias->setInvalid();

lib/Sema/TypeCheckType.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2914,6 +2914,7 @@ Type TypeResolver::resolveImplicitlyUnwrappedOptionalType(
29142914
case TypeResolverContext::EnumElementDecl:
29152915
case TypeResolverContext::EnumPatternPayload:
29162916
case TypeResolverContext::TypeAliasDecl:
2917+
case TypeResolverContext::GenericTypeAliasDecl:
29172918
case TypeResolverContext::GenericRequirement:
29182919
case TypeResolverContext::ImmediateOptionalTypeArgument:
29192920
case TypeResolverContext::InExpression:

lib/Sema/TypeCheckType.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,12 @@ enum class TypeResolverContext : uint8_t {
118118
/// Whether this is the payload subpattern of an enum pattern.
119119
EnumPatternPayload,
120120

121-
/// Whether we are checking the underlying type of a typealias.
121+
/// Whether we are checking the underlying type of a non-generic typealias.
122122
TypeAliasDecl,
123123

124+
/// Whether we are checking the underlying type of a generic typealias.
125+
GenericTypeAliasDecl,
126+
124127
/// Whether we are in a requirement of a generic declaration
125128
GenericRequirement,
126129

@@ -207,6 +210,7 @@ class TypeResolutionOptions {
207210
case Context::EnumElementDecl:
208211
case Context::EnumPatternPayload:
209212
case Context::TypeAliasDecl:
213+
case Context::GenericTypeAliasDecl:
210214
case Context::GenericRequirement:
211215
case Context::ImmediateOptionalTypeArgument:
212216
case Context::AbstractFunctionDecl:

test/decl/nested/type_in_type.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -298,9 +298,9 @@ extension OuterGeneric.MidGeneric : HasAssocType {
298298
func takesAssocType(first: D, second: F) {}
299299
}
300300

301-
typealias OuterGenericMidGeneric<T> = OuterGeneric<T>.MidGeneric
301+
typealias OuterGenericMidNonGeneric<T> = OuterGeneric<T>.MidNonGeneric
302302

303-
extension OuterGenericMidGeneric {
303+
extension OuterGenericMidNonGeneric {
304304

305305
}
306306

test/decl/typealias/generic.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// RUN: %target-typecheck-verify-swift
22

3-
struct MyType<TyA, TyB> {
3+
struct MyType<TyA, TyB> { // expected-note {{generic type 'MyType' declared here}}
44
var a : TyA, b : TyB
55
}
66

@@ -105,6 +105,9 @@ _ = C(a: 42, // expected-error {{'Int' is not convertible to 'String'}}
105105
_ = G(a: "foo", b: 42)
106106
_ = G<Int, String>(a: "foo", b: 42)
107107

108+
// Generic typealias cannot have unbound generic type.
109+
typealias VeryBad1<T> = MyType // expected-error {{reference to generic type 'MyType' requires arguments in <...>}}
110+
typealias VeryBad2<T> = Swift.Array // expected-error {{reference to generic type 'Array' requires arguments in <...>}}
108111

109112
struct MyTypeWithHashable<TyA, TyB : Hashable> {
110113
}

0 commit comments

Comments
 (0)