File: implicitly_unwrapped_optional.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 (127 lines) | stat: -rw-r--r-- 4,813 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

// RUN: %target-swift-emit-silgen -module-name implicitly_unwrapped_optional -disable-objc-attr-requires-foundation-module -enable-objc-interop %s | %FileCheck %s

func foo(f f: (() -> ())!) {
  var f: (() -> ())! = f
  f?()
}
// CHECK: sil hidden [ossa] @{{.*}}foo{{.*}} : $@convention(thin) (@guaranteed Optional<@callee_guaranteed () -> ()>) -> () {
// CHECK: bb0([[T0:%.*]] : @guaranteed $Optional<@callee_guaranteed () -> ()>):
// CHECK:   [[F:%.*]] = alloc_box ${ var Optional<@callee_guaranteed () -> ()> }
// CHECK:   [[F_LIFETIME:%[^,]+]] = begin_borrow [lexical] [var_decl] [[F]]
// CHECK:   [[PF:%.*]] = project_box [[F_LIFETIME]]
// CHECK:   [[T0_COPY:%.*]] = copy_value [[T0]]
// CHECK:   store [[T0_COPY]] to [init] [[PF]]
// CHECK:   [[READ:%.*]] = begin_access [read] [unknown] [[PF]] : $*Optional<@callee_guaranteed () -> ()>
// CHECK:   [[HASVALUE:%.*]] = select_enum_addr [[READ]]
// CHECK:   cond_br [[HASVALUE]], bb1, bb3
//
//   If it does, project and load the value out of the implicitly unwrapped
//   optional...
// CHECK:    bb1:
// CHECK-NEXT: [[FN0_ADDR:%.*]] = unchecked_take_enum_data_addr [[READ]]
// CHECK-NEXT: [[FN0:%.*]] = load [copy] [[FN0_ADDR]]
//   .... then call it
// CHECK:   [[B:%.*]] = begin_borrow [[FN0]]
// CHECK:   apply [[B]]() : $@callee_guaranteed () -> ()
// CHECK:   end_borrow [[B]]
// CHECK:   br bb2
// CHECK: bb2(
// CHECK:   end_borrow [[F_LIFETIME]]
// CHECK:   destroy_value [[F]]
// CHECK:   return
// CHECK: bb3:
// CHECK:   enum $Optional<()>, #Optional.none!enumelt
// CHECK:   br bb2
//   The rest of this is tested in optional.swift
// } // end sil function '{{.*}}foo{{.*}}'

func wrap<T>(x x: T) -> T! { return x }

// CHECK-LABEL: sil hidden [ossa] @$s29implicitly_unwrapped_optional16wrap_then_unwrap{{[_0-9a-zA-Z]*}}F
func wrap_then_unwrap<T>(x x: T) -> T {
  // CHECK:   switch_enum_addr {{%.*}}, case #Optional.some!enumelt: [[OK:bb[0-9]+]], case #Optional.none!enumelt: [[FAIL:bb[0-9]+]]
  // CHECK: [[FAIL]]:
  // CHECK:   unreachable
  // CHECK: [[OK]]:
  return wrap(x: x)!
}

// CHECK-LABEL: sil hidden [ossa] @$s29implicitly_unwrapped_optional10tuple_bind1xSSSgSi_SStSg_tF : $@convention(thin) (@guaranteed Optional<(Int, String)>) -> @owned Optional<String> {
func tuple_bind(x x: (Int, String)!) -> String? {
  return x?.1
  // CHECK:   switch_enum {{%.*}}, case #Optional.some!enumelt: [[NONNULL:bb[0-9]+]], case #Optional.none!enumelt: [[NULL:bb[0-9]+]]
  // CHECK: [[NONNULL]](
  // CHECK:   [[STRING:%.*]] = destructure_tuple {{%.*}} : $(Int, String)
  // CHECK-NOT: destroy_value [[STRING]]
}

// CHECK-LABEL: sil hidden [ossa] @$s29implicitly_unwrapped_optional011tuple_bind_a1_B01xSSSi_SStSg_tF
func tuple_bind_implicitly_unwrapped(x x: (Int, String)!) -> String {
  return x.1
}

func return_any() -> AnyObject! { return nil }
func bind_any() {
  let object : AnyObject? = return_any()
}

// https://github.com/apple/swift/issues/46343
//
// CHECK-LABEL: sil hidden [ossa] @$s29implicitly_unwrapped_optional7f_46343yyF
func f_46343() {
  // Verify that there are no additional reabstractions introduced.
  // CHECK: [[CLOSURE:%.+]] = function_ref @$s29implicitly_unwrapped_optional7f_46343yyFyypSgcfU_ : $@convention(thin) (@in_guaranteed Optional<Any>) -> ()
  // CHECK: [[F:%.+]] = thin_to_thick_function [[CLOSURE]] : $@convention(thin) (@in_guaranteed Optional<Any>) -> () to $@callee_guaranteed (@in_guaranteed Optional<Any>) -> ()
  // CHECK: [[MOVED_F:%.*]] = move_value [var_decl] [[F]]
  // CHECK: [[BORROWED_F:%.*]] = begin_borrow [[MOVED_F]]
  // CHECK: [[COPIED_F:%.*]] = copy_value [[BORROWED_F]]
  // CHECK: [[BORROWED_F:%.*]] = begin_borrow [[COPIED_F]]
  // CHECK: = apply [[BORROWED_F]]({{%.+}}) : $@callee_guaranteed (@in_guaranteed Optional<Any>) -> ()
  // CHECK: end_borrow [[BORROWED_F]]
  let f: ((Any?) -> Void) = { (arg: Any!) in }
  f(nil)
} // CHECK: end sil function '$s29implicitly_unwrapped_optional7f_46343yyF'

// https://github.com/apple/swift/issues/52892
// Make sure we can SILGen all of the below without crashing:

class C1_52892 {
  init!() {}
}

class C2_52892 {
  init(_ foo: C1_52892) {}
}

@objc class C {
  @objc func foo() -> C! { nil }
}

struct S {
  var i: Int!
  func foo() -> Int! { nil }
  subscript() -> Int! { 0 }

  func testParend(_ anyObj: AnyObject) {
    let _: Int? = (foo)()
    let _: Int = (foo)()
    let _: Int? = foo.self()
    let _: Int = foo.self()
    let _: Int? = (self.foo.self)()
    let _: Int = (self.foo.self)()

    // Not really paren'd, but a previous version of the compiler modeled it
    // that way.
    let _ = C2_52892(C1_52892())

    let _: C = (anyObj.foo)!()
  }

  func testCurried() {
    let _: Int? = S.foo(self)()
    let _: Int = S.foo(self)()
    let _: Int? = (S.foo(self).self)()
    let _: Int = (S.foo(self).self)()
  }
}