File: typeEraser.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (178 lines) | stat: -rw-r--r-- 7,579 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
// RUN: %target-swift-frontend -typecheck %s -verify -package-name myPkg

// MARK: - Correct type eraser

class AnyP: P1 {
  init<T: P1>(erasing t: T) {}
}
@_typeEraser(AnyP) // okay
protocol P1 {}

class AnyP2: P2 {
  init<T: P2>(erasing t: T) {}
}
typealias AnyP2Alias = AnyP2
@_typeEraser(AnyP2Alias)
protocol P2 {}

class AnyCollection<Element> : Collection {
  typealias Element = Element
  init<C: Collection>(erasing c: C) where Element == C.Element {}
}
@_typeEraser(AnyCollection<Self.Element>)
protocol Collection {
  associatedtype Element
}

// MARK: - Parsing Errors

@_typeEraser // expected-error {{expected '(' in '_typeEraser' attribute}}
protocol A1 {}

@_typeEraser() // expected-error {{expected a type name in @_typeEraser()}}
protocol A2 {}

@_typeEraser(AnyP // expected-note {{to match this opening '('}}
protocol A3 {} // expected-error {{expected ')' after type name for @_typeEraser}}

@_typeEraser(AnyP) // expected-error {{@_typeEraser may only be used on 'protocol' declarations}}
func notAProtocol() {}

// MARK: - Type eraser must be a concrete nominal type

@_typeEraser(Undeclared) // expected-error {{cannot find type 'Undeclared' in scope}}
protocol B1 {}

@_typeEraser((Int, Int)) // expected-error {{type eraser must be a class, struct, or enum}}
protocol B2 {}

protocol InvalidTypeEraser {}
@_typeEraser(InvalidTypeEraser) // expected-error {{type eraser must be a class, struct, or enum}}
protocol B3 {}

class Generic<Param>: B5 { // expected-note {{generic type 'Generic' declared here}}
  init<T: B5>(erasing t: T) {}
}
@_typeEraser(Generic) // expected-error {{reference to generic type 'Generic' requires arguments in <...>}}
protocol B4 {}
@_typeEraser(Generic<Int>) // bound generic is okay
protocol B5 {}

class MoreRestrictive: B6 { // expected-note {{type eraser declared here}}
  init<T: B6>(erasing t: T) {}
}
@_typeEraser(MoreRestrictive) // expected-error {{internal type eraser 'MoreRestrictive' cannot have more restrictive access than protocol 'B6' (which is public)}}
public protocol B6 {}

class MoreRestrictive1: B66 { // expected-note {{type eraser declared here}}
 init<T: B66>(erasing t: T) {}
}
@_typeEraser(MoreRestrictive1) // expected-error {{internal type eraser 'MoreRestrictive1' cannot have more restrictive access than protocol 'B66' (which is package)}}
package protocol B66 {}

package class PkgMoreRestrictive: PB6 { // expected-note {{type eraser declared here}}
 init<T: B6>(erasing t: T) {}
}
@_typeEraser(PkgMoreRestrictive) // expected-error {{package type eraser 'PkgMoreRestrictive' cannot have more restrictive access than protocol 'PB6' (which is public)}}
public protocol PB6 {}

typealias FnAlias = () -> Void
@_typeEraser(FnAlias) // expected-error {{type eraser must be a class, struct, or enum}}
protocol B7 {}

// MARK: - Type eraser must conform to the annotated protocol

class DoesNotConform {} // expected-note {{type eraser declared here}}
@_typeEraser(DoesNotConform) // expected-error {{type eraser 'DoesNotConform' must conform to protocol 'C1'}}
protocol C1 {}

// MARK: - Type eraser must have an initializer in the form init<T>(erasing: T) with T constrained to annotated protocol

class NoArgInit: D1 {} // expected-note {{type eraser declared here}}
@_typeEraser(NoArgInit) // expected-error {{type eraser 'NoArgInit' must have an initializer of the form 'init<T: D1>(erasing: T)'}}
protocol D1 {}

class InvalidArgInit: D2 { // expected-note {{type eraser declared here}}
  init<T>(erasing t: T) {}
}
@_typeEraser(InvalidArgInit) // expected-error {{type eraser 'InvalidArgInit' must have an initializer of the form 'init<T: D2>(erasing: T)'}}
protocol D2 {}

class ExtraArgInit: D3 { // expected-note {{type eraser declared here}}
  init<T: D3>(erasing t: T, extraArg: Int) {}
}
@_typeEraser(ExtraArgInit) // expected-error {{type eraser 'ExtraArgInit' must have an initializer of the form 'init<T: D3>(erasing: T)'}}
protocol D3 {}

class WrongLabelInit: D4 { // expected-note {{type eraser declared here}}
  init<T: D4>(wrongLabel: T) {}
}
@_typeEraser(WrongLabelInit) // expected-error {{type eraser 'WrongLabelInit' must have an initializer of the form 'init<T: D4>(erasing: T)'}}
protocol D4 {}

class NoLabel: D5 { // expected-note {{type eraser declared here}}
  init<T: D5>(_ t: T) {}
}
@_typeEraser(NoLabel) // expected-error {{type eraser 'NoLabel' must have an initializer of the form 'init<T: D5>(erasing: T)'}}
protocol D5 {}

class NonGenericInit<T: D6>: D6 { // expected-note {{type eraser declared here}}
  init(_ t: T) {}
}
@_typeEraser(NonGenericInit<Self>) // expected-error {{type eraser 'NonGenericInit<Self>' must have an initializer of the form 'init<T: D6>(erasing: T)'}}
protocol D6 {}

// MARK: - Unviable initializers

public class UnviableInits: E1 {
  public init<T: E1>(erasing t: T) where T: Hashable {} // expected-note {{'init(erasing:)' cannot have unsatisfied requirements when 'T' = 'some E1'}}
  init<T: E1>(erasing t: T) {} // expected-note {{internal 'init(erasing:)' cannot have more restrictive access than protocol 'E1' (which is public)}}
}
@_typeEraser(UnviableInits) // expected-error {{type eraser 'UnviableInits' has no viable initializer of the form 'init<T: E1>(erasing: T)'}}
public protocol E1 {}

public class UnviableInits11: E11 {
 public init<T: E11>(erasing t: T) where T: Hashable {} // expected-note {{'init(erasing:)' cannot have unsatisfied requirements when 'T' = 'some E11'}}
 package init<T: E11>(erasing t: T) {} // expected-note {{package 'init(erasing:)' cannot have more restrictive access than protocol 'E11' (which is public)}}
}
@_typeEraser(UnviableInits11) // expected-error {{type eraser 'UnviableInits11' has no viable initializer of the form 'init<T: E11>(erasing: T)'}}
public protocol E11 {}

package class PkgUnviableInits: PE1 {
  package init<T: PE1>(erasing t: T) where T: Hashable {} // expected-note {{'init(erasing:)' cannot have unsatisfied requirements when 'T' = 'some PE1'}}
  init<T: PE1>(erasing t: T) {} // expected-note {{internal 'init(erasing:)' cannot have more restrictive access than protocol 'PE1' (which is package)}}
}
@_typeEraser(PkgUnviableInits) // expected-error {{type eraser 'PkgUnviableInits' has no viable initializer of the form 'init<T: PE1>(erasing: T)'}}
package protocol PE1 {}

class FailableInit: E2 {
  init?<T: E2>(erasing t: T) {} // expected-note {{'init(erasing:)' cannot be failable}}
}
@_typeEraser(FailableInit) // expected-error {{type eraser 'FailableInit' has no viable initializer of the form 'init<T: E2>(erasing: T)'}}
protocol E2 {}

// SPI type eraser and non-SPI protocol
@_spi(SPI)
public struct AnyE3_SPI: E3 {
  public init<T: E3>(erasing: T) {} // expected-note {{'init(erasing:)' is SPI, but protocol 'E3' is not}}
}
@_typeEraser(AnyE3_SPI) // expected-error {{type eraser 'AnyE3_SPI' has no viable initializer of the form 'init<T: E3>(erasing: T)'}}
public protocol E3 {}

// SPI type eraser and SPI protocol of different groups
@_spi(SPI2)
public struct AnyE4_SPI: E4 {
  public init<T: E4>(erasing: T) {} // expected-note {{'init(erasing:)' is SPI, but protocol 'E4' is not in the same SPI groups as 'init(erasing:)'}}
}
@_spi(SPI1) @_spi(SPI2)
@_typeEraser(AnyE4_SPI) // expected-error {{type eraser 'AnyE4_SPI' has no viable initializer of the form 'init<T: E4>(erasing: T)'}}
public protocol E4 {}

// Same-group SPI type eraser and protocol
@_spi(SPI1) @_spi(SPI2)
public struct AnyE5_SPI: E5 {
  public init<T: E5>(erasing: T) {}
}
@_spi(SPI2) @_spi(SPI1)
@_typeEraser(AnyE5_SPI) // same SPI groups, okay
public protocol E5 {}