File: objc_error.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 (176 lines) | stat: -rw-r--r-- 7,850 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

// RUN: %empty-directory(%t)
// RUN: %build-clang-importer-objc-overlays

// RUN: %target-swift-emit-silgen(mock-sdk: %clang-importer-sdk-nosource -I %t) -module-name objc_error %s | %FileCheck %s

// REQUIRES: objc_interop

import Foundation

// CHECK-LABEL: sil hidden [ossa] @$s10objc_error20NSErrorError_erasureys0D0_pSo0C0CF : $@convention(thin) (@guaranteed NSError) -> @owned any Error {
// CHECK:         bb0([[ERROR:%.*]] : @guaranteed $NSError):
// CHECK:           [[ERROR_COPY:%.*]] = copy_value [[ERROR]]
// CHECK:           [[ERROR_TYPE:%.*]] = init_existential_ref [[ERROR_COPY]] : $NSError : $NSError, $any Error
// CHECK-NOT:           destroy_value [[ERROR]]
// CHECK:           return [[ERROR_TYPE]]
// CHECK:       } // end sil function '$s10objc_error20NSErrorError_erasureys0D0_pSo0C0CF'
func NSErrorError_erasure(_ x: NSError) -> Error {
  return x
}

// CHECK-LABEL: sil hidden [ossa] @$s10objc_error30NSErrorError_archetype_erasureys0D0_pxSo0C0CRbzlF : $@convention(thin) <T where T : NSError> (@guaranteed T) -> @owned any Error {
// CHECK:         bb0([[ERROR:%.*]] : @guaranteed $T):
// CHECK:           [[ERROR_COPY:%.*]] = copy_value [[ERROR]]
// CHECK:           [[T0:%.*]] = upcast [[ERROR_COPY]] : $T to $NSError
// CHECK:           [[ERROR_TYPE:%.*]] = init_existential_ref [[T0]] : $NSError : $NSError, $any Error
// CHECK-NOT:           destroy_value [[ERROR]]
// CHECK:           return [[ERROR_TYPE]]
// CHECK: } // end sil function '$s10objc_error30NSErrorError_archetype_erasureys0D0_pxSo0C0CRbzlF'
func NSErrorError_archetype_erasure<T : NSError>(_ t: T) -> Error {
  return t
}

// Test patterns that are non-trivial, but irrefutable.  SILGen shouldn't crash
// on these.
func test_doesnt_throw() {
  do {
    throw NSError(domain: "", code: 1, userInfo: [:])
  } catch is Error {  // expected-warning {{'is' test is always true}}
  }

  do {
    throw NSError(domain: "", code: 1, userInfo: [:])
  } catch let e as NSError {  // ok.
    _ = e
  }
}

class ErrorClass: Error {
  let _domain = ""
  let _code = 0
}

// Class-to-NSError casts must be done as indirect casts since they require
// a representation change, and checked_cast_br currently doesn't allow that.

// CHECK-LABEL: sil hidden [ossa] @$s10objc_error20test_cast_to_nserroryyF
func test_cast_to_nserror() {
  let e = ErrorClass()

  // CHECK: function_ref @$s10Foundation22_convertErrorToNSErrorySo0E0Cs0C0_pF
  let nsCoerced = e as Error as NSError

  // CHECK: unconditional_checked_cast_addr AnyObject in {{%.*}} : $*AnyObject to NSError in {{%.*}} : $*NSError
  let nsForcedCast = (e as AnyObject) as! NSError

  // CHECK: checked_cast_addr_br {{.*}} Error in {{%.*}} : $*any Error to NSError in {{%.*}} : $*NSError, bb1, bb2
  do {
    throw e
  } catch _ as NSError {
    
  }
}

// A class-constrained archetype may be NSError, so we can't use scalar casts
// in that case either.
// CHECK-LABEL: sil hidden [ossa] @$s10objc_error28test_cast_to_class_archetype{{[_0-9a-zA-Z]*}}F
func test_cast_to_class_archetype<T: AnyObject>(_: T) {
  // CHECK: unconditional_checked_cast_addr ErrorClass in {{%.*}} : $*ErrorClass to T in {{.*}} : $*T
  let e = ErrorClass()
  let forcedCast = e as! T
}

// CHECK-LABEL: sil hidden [ossa] @$s10objc_error15testAcceptError{{[_0-9a-zA-Z]*}}F
func testAcceptError(error: Error) {
  // CHECK-NOT: return
  // CHECK: function_ref @$s10Foundation22_convertErrorToNSErrorySo0E0Cs0C0_pF
  acceptError(error)
}

// CHECK-LABEL: sil hidden [ossa] @$s10objc_error16testProduceError{{[_0-9a-zA-Z]*}}F
func testProduceError() -> Error {
  // CHECK: function_ref @produceError : $@convention(c) () -> @autoreleased NSError
  // CHECK: init_existential_ref {{.*}} : $NSError : $NSError, $any Error
  return produceError()
}

// CHECK-LABEL: sil hidden [ossa] @$s10objc_error24testProduceOptionalError{{[_0-9a-zA-Z]*}}F
func testProduceOptionalError() -> Error? {
  // CHECK: function_ref @produceOptionalError
  // CHECK: init_existential_ref {{.*}} : $NSError : $NSError, $any Error
  return produceOptionalError();
}

class MyNSError : NSError {
  override init() {
    super.init(domain: "MyNSError", code: 0, userInfo: [:])
  }
}

// CHECK-LABEL: sil hidden [ossa] @$s10objc_error14eraseMyNSError{{[_0-9a-zA-Z]*}}F : $@convention(thin) () -> @owned any Error {
// CHECK: bb0:
// CHECK:   [[NSERROR_SUBCLASS:%.*]] = apply {{.*}}({{.*}}) : $@convention(method) (@thick MyNSError.Type) -> @owned MyNSError
// CHECK:   [[UPCAST:%.*]] = upcast [[NSERROR_SUBCLASS]] : $MyNSError to $NSError
// CHECK:   [[EXISTENTIAL_REF:%.*]] = init_existential_ref [[UPCAST]]
// CHECK:   [[MOVED_EXISTENTIAL_REF:%.*]] = move_value [lexical] [var_decl] [[EXISTENTIAL_REF]]
// CHECK:   [[BORROWED_EXISTENTIAL_REF:%.*]] = begin_borrow [[MOVED_EXISTENTIAL_REF]]
// CHECK:   [[COPY_BORROWED_EXISTENTIAL_REF:%.*]] = copy_value [[BORROWED_EXISTENTIAL_REF]]
// CHECK:   end_borrow [[BORROWED_EXISTENTIAL_REF]]
// CHECK:   destroy_value [[MOVED_EXISTENTIAL_REF]]
// CHECK:   return [[COPY_BORROWED_EXISTENTIAL_REF]]
// CHECK: } // end sil function '$s10objc_error14eraseMyNSError{{[_0-9a-zA-Z]*}}F'
func eraseMyNSError() -> Error {
  let x: Error = MyNSError()
  return x
}

// CHECK-LABEL: sil hidden [ossa] @$s10objc_error25eraseFictionalServerErrors0F0_pyF
func eraseFictionalServerError() -> Error {
  // CHECK-NOT: return
  // CHECK: [[NSERROR:%[0-9]+]] = struct_extract {{.*}} : $FictionalServerError, #FictionalServerError._nsError
  // CHECK: [[NSERROR_COPY:%.*]] = copy_value [[NSERROR]]
  // CHECK: [[ERROR:%[0-9]+]] = init_existential_ref [[NSERROR_COPY]]
  // CHECK: return [[ERROR]]
  return FictionalServerError(.meltedDown)
}
// CHECK: } // end sil function '$s10objc_error25eraseFictionalServerErrors0F0_pyF'

// https://github.com/apple/swift/issues/44171
extension Error {
  // CHECK-LABEL: sil hidden [ossa] @$ss5ErrorP10objc_errorE16convertToNSErrorSo0F0CyF
  // CHECK: bb0([[SELF:%[0-9]+]] : $*Self)
	func convertToNSError() -> NSError {
    // CHECK: [[COPY:%.*]] = alloc_stack $Self
    // CHECK: copy_addr [[SELF]] to [init] [[COPY]]
    // CHECK: [[COPY2:%.*]] = alloc_stack $Self
    // CHECK: copy_addr [[COPY]] to [init] [[COPY2]]
    // CHECK: [[GET_EMBEDDED_FN:%[0-9]+]] = function_ref @$ss24_getErrorEmbeddedNSErroryyXlSgxs0B0RzlF
    // CHECK: [[EMBEDDED_RESULT_OPT:%[0-9]+]] = apply [[GET_EMBEDDED_FN]]<Self>([[COPY2]])
    // CHECK: switch_enum [[EMBEDDED_RESULT_OPT]] : $Optional<AnyObject>,
    // CHECK-SAME: case #Optional.some!enumelt: [[SUCCESS:bb[0-9]+]],
    // CHECK-SAME: case #Optional.none!enumelt: [[FAILURE:bb[0-9]+]]

    // CHECK: [[SUCCESS]]([[EMBEDDED_RESULT:%.*]] : @owned $AnyObject):
    // CHECK: [[EMBEDDED_NSERROR:%[0-9]+]] = unchecked_ref_cast [[EMBEDDED_RESULT]] : $AnyObject to $NSError
    // CHECK: [[ERROR:%[0-9]+]] = init_existential_ref [[EMBEDDED_NSERROR]] : $NSError : $NSError, $any Error
    // CHECK: destroy_addr [[COPY]] : $*Self
    // CHECK: br [[CONTINUATION:bb[0-9]+]]([[ERROR]] : $any Error)

    // CHECK: [[FAILURE]]:
    // CHECK: [[ERROR_BOX:%[0-9]+]] = alloc_existential_box $any Error, $Self
    // CHECK: [[ERROR_PROJECTED:%[0-9]+]] = project_existential_box $Self in [[ERROR_BOX]] : $any Error
    // CHECK: store [[ERROR_BOX]] to [init] [[ERROR_BUF:%.*]] :
    // CHECK: copy_addr [take] [[COPY]] to [init] [[ERROR_PROJECTED]] : $*Self
    // CHECK: [[ERROR_BOX2:%.*]] = load [take] [[ERROR_BUF]]
    // CHECK: br [[CONTINUATION]]([[ERROR_BOX2]] : $any Error)

    // CHECK: [[CONTINUATION]]([[ERROR_ARG:%[0-9]+]] : @owned $any Error):
		return self as NSError
	}
}

class Gizmoid : NSObject {
  // CHECK-LABEL: sil private [thunk] [ossa] @$s10objc_error7GizmoidC3fooACyt_tKcfcTo : $@convention(objc_method) (Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>, @owned Gizmoid) -> @owned Optional<Gizmoid>
  @objc init(foo: ()) throws {}
}