File: do_expr.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 (185 lines) | stat: -rw-r--r-- 5,883 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
179
180
181
182
183
184
185
// RUN: %target-swift-emit-silgen -enable-experimental-feature ThenStatements -enable-experimental-feature DoExpressions %s | %FileCheck %s
// RUN: %target-swift-emit-ir -enable-experimental-feature ThenStatements -enable-experimental-feature DoExpressions %s

// Required for experimental features
// REQUIRES: asserts

@discardableResult
func throwsError(_ x: Int = 0) throws -> Int { 0 }

struct Err: Error {}

func test1() -> Int {
  do { 5 }
}
// CHECK-LABEL: sil hidden [ossa] @$s7do_expr5test1SiyF : $@convention(thin) () -> Int
// CHECK:       [[RESULT:%[0-9]+]] = alloc_stack $Int
// CHECK:       store {{%[0-9]+}} to [trivial] [[RESULT]] : $*Int
// CHECK-NEXT:  [[RET:%[0-9]+]] = load [trivial] [[RESULT]] : $*Int
// CHECK-NEXT:  dealloc_stack [[RESULT]] : $*Int
// CHECK-NEXT:  return [[RET]] : $Int

func test2() -> Int {
  return do { 5 }
}

func test3() -> Int {
  let x = do { 5 }
  return x
}

func test4() -> Int {
  do { then 5 }
}

func test5() -> Int {
  let x = do { (); then 5 }
  return x
}

func test6() -> Int {
  let x = do {
    let y = 0
    try throwsError()
    then y
  } catch {
    7
  }
  return x
}
// CHECK-LABEL: sil hidden [ossa] @$s7do_expr5test6SiyF : $@convention(thin) () -> Int
// CHECK:       [[RESULT:%[0-9]+]] = alloc_stack $Int
// CHECK:       [[Y_LIT:%[0-9]+]] = integer_literal $Builtin.IntLiteral, 0
// CHECK:       [[Y:%[0-9]+]] = apply {{%[0-9]+}}([[Y_LIT]], {{%[0-9]+}})
// CHECK:       [[THROWS_ERR_FN:%[0-9]+]] = function_ref @$s7do_expr11throwsErroryS2iKF : $@convention(thin) (Int) -> (Int, @error any Error)
// CHECK:       try_apply [[THROWS_ERR_FN]]({{%[0-9]+}}) : $@convention(thin) (Int) -> (Int, @error any Error), normal [[BB_NORMAL:bb[0-9]+]], error [[BB_ERR:bb[0-9]+]]
//
// CHECK:       [[BB_NORMAL]]
// CHECK-NEXT:  store [[Y]] to [trivial] [[RESULT]] : $*Int
// CHECK-NEXT:  br [[BB_EXIT:bb[0-9]+]]
//
// CHECK:       [[BB_EXIT]]
// CHECK:       [[RET:%[0-9]+]] = load [trivial] [[RESULT]] : $*Int
// CHECK:       dealloc_stack [[RESULT]] : $*Int
// CHECK:       return [[RET]] : $Int
//
// CHECK:       [[BB_ERR]]
// CHECK:       [[SEVEN_LIT:%[0-9]+]] = integer_literal $Builtin.IntLiteral, 7
// CHECK:       [[SEVEN:%[0-9]+]] = apply {{%[0-9]+}}([[SEVEN_LIT]], {{%[0-9]+}}) : $@convention(method) (Builtin.IntLiteral, @thin Int.Type) -> Int
// CHECK:       store [[SEVEN]] to [trivial] [[RESULT]] : $*Int
// CHECK:       br [[BB_EXIT]]

func test7() throws -> Int {
  let x = do {
    let y = 0
    then try throwsError(y)
  } catch _ where .random() {
    then try throwsError()
  } catch {
    7
  }
  return x
}
// CHECK-LABEL: sil hidden [ossa] @$s7do_expr5test7SiyKF : $@convention(thin) () -> (Int, @error any Error)
// CHECK:       [[RESULT:%[0-9]+]] = alloc_stack $Int
// CHECK:       [[Y_LIT:%[0-9]]] = integer_literal $Builtin.IntLiteral, 0
// CHECK:       [[Y:%[0-9]+]] = apply {{%[0-9]+}}([[Y_LIT]], {{%[0-9]+}})
// CHECK:       [[THROWS_ERR_FN:%[0-9]]] = function_ref @$s7do_expr11throwsErroryS2iKF : $@convention(thin) (Int) -> (Int, @error any Error)
// CHECK:       try_apply [[THROWS_ERR_FN]]([[Y]]) : $@convention(thin) (Int) -> (Int, @error any Error), normal [[BB_NORMAL:bb[0-9]+]], error [[BB_ERR:bb[0-9]+]]
//
// CHECK:       [[BB_NORMAL]]([[I:%[0-9]+]] : $Int)
// CHECK-NEXT:  store [[I]] to [trivial] [[RESULT]] : $*Int
// CHECK-NEXT:  br [[BB_EXIT:bb[0-9]+]]
//
// CHECK:       [[BB_EXIT]]
// CHECK:       [[RET:%[0-9]+]] = load [trivial] [[RESULT]] : $*Int
// CHECK:       dealloc_stack [[RESULT]] : $*Int
// CHECK:       return [[RET]] : $Int
//
// CHECK:       [[BB_ERR]]
// CHECK:       function_ref @$sSb6randomSbyFZ : $@convention(method) (@thin Bool.Type) -> Bool
// CHECK:       cond_br {{%[0-9]+}}, [[BB_FIRST_CATCH:bb[0-9]+]], [[BB_SECOND_CATCH:bb[0-9]+]]
//
// CHECK:       [[BB_FIRST_CATCH]]
// CHECK:       [[THROWS_ERR_FN:%[0-9]+]] = function_ref @$s7do_expr11throwsErroryS2iKF : $@convention(thin) (Int) -> (Int, @error any Error)
// CHECK:       try_apply [[THROWS_ERR_FN]]({{%[0-9]+}}) : $@convention(thin) (Int) -> (Int, @error any Error), normal [[BB_NORMAL2:bb[0-9]+]], error [[BB_ERR2:bb[0-9]+]]
//
// CHECK:       [[BB_NORMAL2]]([[I:%[0-9]+]] : $Int):
// CHECK-NEXT:  store [[I]] to [trivial] [[RESULT]] : $*Int
// CHECK:       br [[BB_EXIT:bb[0-9]+]]
//
// CHECK:       [[BB_SECOND_CATCH]]
// CHECK:       [[SEVEN_LIT:%[0-9]+]] = integer_literal $Builtin.IntLiteral, 7
// CHECK:       [[SEVEN:%[0-9]+]] = apply {{%[0-9]+}}([[SEVEN_LIT]], {{%[0-9]+}}) : $@convention(method) (Builtin.IntLiteral, @thin Int.Type) -> Int
// CHECK:       store [[SEVEN]] to [trivial] [[RESULT]] : $*Int
// CHECK:       br [[BB_EXIT]]
//
// CHECK:       [[BB_ERR2]]([[ERR:%[0-9]+]] : @owned $any Error)
// CHECK:       dealloc_stack [[RESULT]] : $*Int
// CHECK:       throw [[ERR]] : $any Error

func test8() throws -> Int {
  var x = 0
  x = do {
    let y = 0
    then try throwsError(y)
  } catch _ where .random() {
    then try throwsError()
  } catch {
    8
  }
  return x
}

func test9() throws -> Int {
  let fn = {
    do {
      let y = 0
      then try throwsError(y)
    } catch _ where .random() {
      then try throwsError()
    } catch {
      8
    }
  }
  return try fn()
}

func test10() -> Int {
  do { 5 } as Int
}

func testExhaustive1() -> Error {
  // We can syntactically determine that 'let x' is a non-refutable pattern.
  let err = do {
    try throwsError()
    then Err() as Error
  } catch let x {
    x
  }
  return err
}

func testExhaustive2() -> Error {
  do {
    try throwsError()
    then Err() as Error
  } catch let x {
    x
  }
}

func throwAndReturnError() throws -> Error { fatalError() }

func testExhaustive3() -> Error {
  do {
    try throwAndReturnError()
  } catch let x {
    x
  }
}

func testExhaustive4() {
  // We can syntactically determine that '_' is a non-refutable pattern.
  let _ = do { try throwsError() } catch _ { 0 }
}