Skip to content

Commit e93a6b9

Browse files
committed
[TypeCheckAttr] Allow a typealias to be a type eraser and add additional
typeEraser tests.
1 parent fe4ba8a commit e93a6b9

File tree

2 files changed

+20
-2
lines changed

2 files changed

+20
-2
lines changed

lib/Sema/TypeCheckAttr.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2400,6 +2400,9 @@ TypeEraserHasViableInitRequest::evaluate(Evaluator &evaluator,
24002400

24012401
// The type eraser must be a concrete nominal type
24022402
auto nominalTypeDecl = typeEraser->getAnyNominal();
2403+
if (auto typeAliasDecl = dyn_cast_or_null<TypeAliasDecl>(nominalTypeDecl))
2404+
nominalTypeDecl = typeAliasDecl->getUnderlyingType()->getAnyNominal();
2405+
24032406
if (!nominalTypeDecl || isa<ProtocolDecl>(nominalTypeDecl)) {
24042407
diags.diagnose(typeEraserLoc.getLoc(), diag::non_nominal_type_eraser);
24052408
return false;

test/attr/typeEraser.swift

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,20 @@
55
class AnyP: P1 {
66
init<T: P1>(erasing t: T) {}
77
}
8-
98
@_typeEraser(AnyP) // okay
109
protocol P1 {}
1110

11+
class AnyP2: P2 {
12+
init<T: P2>(erasing t: T) {}
13+
}
14+
typealias AnyP2Alias = AnyP2
15+
@_typeEraser(AnyP2Alias)
16+
protocol P2 {}
17+
1218
class AnyCollection<Element> : Collection {
1319
typealias Element = Element
1420
init<C: Collection>(erasing c: C) where Element == C.Element {}
1521
}
16-
1722
@_typeEraser(AnyCollection<Self.Element>)
1823
protocol Collection {
1924
associatedtype Element
@@ -59,6 +64,10 @@ class MoreRestrictive: B6 { // expected-note {{type eraser declared here}}
5964
@_typeEraser(MoreRestrictive) // expected-error {{internal type eraser 'MoreRestrictive' cannot have more restrictive access than protocol 'B6' (which is public)}}
6065
public protocol B6 {}
6166

67+
typealias FnAlias = () -> Void
68+
@_typeEraser(FnAlias) // expected-error {{type eraser must be a class, struct, or enum}}
69+
protocol B7 {}
70+
6271
// MARK: - Type eraser must conform to the annotated protocol
6372

6473
class DoesNotConform {} // expected-note {{type eraser declared here}}
@@ -95,6 +104,12 @@ class NoLabel: D5 { // expected-note {{type eraser declared here}}
95104
@_typeEraser(NoLabel) // expected-error {{type eraser 'NoLabel' must have an initializer of the form 'init<T: D5>(erasing: T)'}}
96105
protocol D5 {}
97106

107+
class NonGenericInit<T: D6>: D6 { // expected-note {{type eraser declared here}}
108+
init(_ t: T) {}
109+
}
110+
@_typeEraser(NonGenericInit<Self>) // expected-error {{type eraser 'NonGenericInit<Self>' must have an initializer of the form 'init<T: D6>(erasing: T)'}}
111+
protocol D6 {}
112+
98113
// MARK: - Unviable initializers
99114

100115
public class UnviableInits: E1 {

0 commit comments

Comments
 (0)