@@ -11,11 +11,33 @@ precedencegroup AssignmentPrecedence {
11
11
assignment : true
12
12
}
13
13
14
+ public protocol ExpressibleByNilLiteral {
15
+ init ( nilLiteral: ( ) )
16
+ }
17
+
18
+ protocol IteratorProtocol {
19
+ associatedtype Element
20
+ mutating func next( ) -> Element ?
21
+ }
22
+
23
+ protocol Sequence {
24
+ associatedtype Element
25
+ associatedtype Iterator : IteratorProtocol where Iterator. Element == Element
26
+
27
+ func makeIterator( ) -> Iterator
28
+ }
29
+
14
30
enum Optional < T> {
15
31
case none
16
32
case some( T )
17
33
}
18
34
35
+ extension Optional : ExpressibleByNilLiteral {
36
+ public init ( nilLiteral: ( ) ) {
37
+ self = . none
38
+ }
39
+ }
40
+
19
41
func _diagnoseUnexpectedNilOptional( _filenameStart: Builtin . RawPointer ,
20
42
_filenameLength: Builtin . Word ,
21
43
_filenameIsASCII: Builtin . Int1 ,
@@ -42,6 +64,41 @@ protocol Protocol {
42
64
static func useInput( _ input: Builtin . Int32 , into processInput: ( AssocType ) -> ( ) )
43
65
}
44
66
67
+ struct FakeArray < Element> {
68
+ // Just to make this type non-trivial
69
+ var k : Klass
70
+
71
+ // We are only interested in this being called. We are not interested in its
72
+ // implementation.
73
+ mutating func append( _ t: Element ) { }
74
+ }
75
+
76
+ struct FakeDictionary < Key, Value> {
77
+ }
78
+
79
+ struct FakeDictionaryIterator < Key, Value> {
80
+ var dictionary : FakeDictionary < Key , Value > ?
81
+
82
+ init ( _ newDictionary: FakeDictionary < Key , Value > ) {
83
+ dictionary = newDictionary
84
+ }
85
+ }
86
+
87
+ extension FakeDictionaryIterator : IteratorProtocol {
88
+ public typealias Element = ( Key , Value )
89
+ public mutating func next( ) -> Element ? {
90
+ return . none
91
+ }
92
+ }
93
+
94
+ extension FakeDictionary : Sequence {
95
+ public typealias Element = ( Key , Value )
96
+ public typealias Iterator = FakeDictionaryIterator < Key , Value >
97
+ public func makeIterator( ) -> FakeDictionaryIterator < Key , Value > {
98
+ return FakeDictionaryIterator ( self )
99
+ }
100
+ }
101
+
45
102
///////////
46
103
// Tests //
47
104
///////////
@@ -108,3 +165,36 @@ struct ReabstractionThunkTest : Protocol {
108
165
}
109
166
}
110
167
168
+ // Make sure that we provide a cleanup to x properly before we pass it to
169
+ // result.
170
+ extension FakeDictionary {
171
+ // CHECK-LABEL: sil hidden @$Ss14FakeDictionaryV20makeSureToCopyTuplesyyF : $@convention(method) <Key, Value> (FakeDictionary<Key, Value>) -> () {
172
+ // CHECK: [[X:%.*]] = alloc_stack $(Key, Value), let, name "x"
173
+ // CHECK: [[INDUCTION_VAR:%.*]] = unchecked_take_enum_data_addr {{%.*}} : $*Optional<(Key, Value)>, #Optional.some!enumelt.1
174
+ // CHECK: [[INDUCTION_VAR_0:%.*]] = tuple_element_addr [[INDUCTION_VAR]] : $*(Key, Value), 0
175
+ // CHECK: [[INDUCTION_VAR_1:%.*]] = tuple_element_addr [[INDUCTION_VAR]] : $*(Key, Value), 1
176
+ // CHECK: [[X_0:%.*]] = tuple_element_addr [[X]] : $*(Key, Value), 0
177
+ // CHECK: [[X_1:%.*]] = tuple_element_addr [[X]] : $*(Key, Value), 1
178
+ // CHECK: copy_addr [take] [[INDUCTION_VAR_0]] to [initialization] [[X_0]]
179
+ // CHECK: copy_addr [take] [[INDUCTION_VAR_1]] to [initialization] [[X_1]]
180
+ // CHECK: [[X_0:%.*]] = tuple_element_addr [[X]] : $*(Key, Value), 0
181
+ // CHECK: [[X_1:%.*]] = tuple_element_addr [[X]] : $*(Key, Value), 1
182
+ // CHECK: [[TMP_X:%.*]] = alloc_stack $(Key, Value)
183
+ // CHECK: [[TMP_X_0:%.*]] = tuple_element_addr [[TMP_X]] : $*(Key, Value), 0
184
+ // CHECK: [[TMP_0:%.*]] = alloc_stack $Key
185
+ // CHECK: copy_addr [[X_0]] to [initialization] [[TMP_0]]
186
+ // CHECK: copy_addr [take] [[TMP_0]] to [initialization] [[TMP_X_0]]
187
+ // CHECK: [[TMP_X_1:%.*]] = tuple_element_addr [[TMP_X]] : $*(Key, Value), 1
188
+ // CHECK: [[TMP_1:%.*]] = alloc_stack $Value
189
+ // CHECK: copy_addr [[X_1]] to [initialization] [[TMP_1]]
190
+ // CHECK: copy_addr [take] [[TMP_1]] to [initialization] [[TMP_X_1]]
191
+ // CHECK: [[FUNC:%.*]] = function_ref @$Ss9FakeArrayV6appendyyxF : $@convention(method) <τ_0_0> (@in_guaranteed τ_0_0, @inout FakeArray<τ_0_0>) -> ()
192
+ // CHECK: apply [[FUNC]]<(Key, Value)>([[TMP_X]],
193
+ // CHECK: } // end sil function '$Ss14FakeDictionaryV20makeSureToCopyTuplesyyF'
194
+ func makeSureToCopyTuples( ) {
195
+ var result = FakeArray < Element > ( k: Klass ( ) )
196
+ for x in self {
197
+ result. append ( x)
198
+ }
199
+ }
200
+ }
0 commit comments