Skip to content

Commit 7c6c5fc

Browse files
committed
Sema: Fix generic type alias resolution edge case
If a type alias in generic context fixes all outer generic parameters to concrete types, we allow the type alias to be referenced without specifying the generic arguments of its parent type. However, we need to reduce the underlying type in case it was written in terms of the (fully concrete) generic parameters. Fixes rdar://problem/143707820.
1 parent 07a3189 commit 7c6c5fc

File tree

2 files changed

+16
-7
lines changed

2 files changed

+16
-7
lines changed

lib/Sema/TypeCheckType.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6136,6 +6136,8 @@ Type TypeChecker::substMemberTypeWithBase(TypeDecl *member,
61366136
// Cope with the presence of unbound generic types, which are ill-formed
61376137
// at this point but break the invariants of getContextSubstitutionMap().
61386138
if (baseTy->hasUnboundGenericType()) {
6139+
memberType = memberType->getReducedType(aliasDecl->getGenericSignature());
6140+
61396141
if (memberType->hasTypeParameter())
61406142
return ErrorType::get(memberType);
61416143

test/decl/typealias/fully_constrained.swift

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,23 @@
33
struct OtherGeneric<U> {}
44

55
struct Generic<T> {
6-
// FIXME: Should work with 'T' as well
76
typealias NonGeneric = Int where T == Int
7+
typealias FakeGeneric = T where T == Int
88

99
typealias Unbound = OtherGeneric where T == Int
1010
typealias Generic = OtherGeneric where T == Int
1111
}
1212

1313
extension Generic where T == Int {
14-
// FIXME: Should work with 'T' as well
1514
typealias NonGenericInExtension = Int
15+
typealias FakeGenericInExtension = T
1616

1717
typealias UnboundInExtension = OtherGeneric
1818
typealias GenericInExtension = OtherGeneric
1919
}
2020

2121
func use(_: Generic.NonGeneric,
22+
_: Generic.FakeGeneric,
2223
_: Generic.Unbound<String>,
2324
_: Generic.Generic<String>,
2425
_: Generic.NonGenericInExtension,
@@ -28,16 +29,20 @@ func use(_: Generic.NonGeneric,
2829
// FIXME: Get these working too
2930
#if false
3031
let _ = Generic.NonGeneric.self
32+
let _ = Generic.FakeGeneric.self
3133
let _ = Generic.Unbound<String>.self
3234
let _ = Generic.Generic<String>.self
3335

3436
let _ = Generic.NonGenericInExtension.self
37+
let _ = Generic.FakeGenericInExtension.self
3538
let _ = Generic.UnboundInExtension<String>.self
3639
let _ = Generic.GenericInExtension<String>.self
40+
#endif
3741

3842
let _: Generic.NonGeneric = 123
43+
let _: Generic.FakeGeneric = 123
3944
let _: Generic.NonGenericInExtension = 123
40-
#endif
45+
let _: Generic.FakeGenericInExtension = 123
4146

4247
let _: Generic.Unbound = OtherGeneric<String>()
4348
let _: Generic.Generic = OtherGeneric<String>()
@@ -48,11 +53,13 @@ func use(_: Generic.NonGeneric,
4853

4954
struct Use {
5055
let a1: Generic.NonGeneric
51-
let b1: Generic.Unbound<String>
52-
let c1: Generic.Generic<String>
56+
let b1: Generic.FakeGeneric
57+
let c1: Generic.Unbound<String>
58+
let d1: Generic.Generic<String>
5359
let a2: Generic.NonGenericInExtension
54-
let b2: Generic.UnboundInExtension<String>
55-
let c2: Generic.GenericInExtension<String>
60+
let b2: Generic.FakeGenericInExtension
61+
let c2: Generic.UnboundInExtension<String>
62+
let d2: Generic.GenericInExtension<String>
5663
}
5764

5865
extension Generic.NonGeneric {}

0 commit comments

Comments
 (0)