File: explicit_lifetime_dependence_specifiers.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 (156 lines) | stat: -rw-r--r-- 4,797 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
// RUN: %target-typecheck-verify-swift -disable-availability-checking -enable-experimental-feature NonescapableTypes -enable-builtin-module
// REQUIRES: asserts

import Builtin

struct BufferView : ~Escapable {
  let ptr: UnsafeRawBufferPointer
  @_unsafeNonescapableResult
  init(_ ptr: UnsafeRawBufferPointer) {
    self.ptr = ptr
  }
  @_unsafeNonescapableResult
  init?(_ ptr: UnsafeRawBufferPointer, _ i: Int) {
    if (i % 2 == 0) {
      return nil
    } 
    self.ptr = ptr
  }
  init(_ ptr: UnsafeRawBufferPointer, _ a: borrowing Array<Int>) -> dependsOn(a) Self {
    self.ptr = ptr
    return self
  }
  init(_ ptr: UnsafeRawBufferPointer, _ a: consuming Wrapper) -> dependsOn(a) Self {
    self.ptr = ptr
    return self
  }
  init(_ ptr: UnsafeRawBufferPointer, _ a: consuming Wrapper, b: borrowing Array<Int>) -> dependsOn(a) dependsOn(scoped b) Self {
    self.ptr = ptr
    return self
  }
  init(_ ptr: UnsafeRawBufferPointer, _ a: borrowing Array<Double>, b: borrowing Array<Int>, c: Double) -> dependsOn(scoped a) dependsOn(b) Int { // expected-error{{expected Self return type for initializers with lifetime dependence specifiers}}
    self.ptr = ptr
    return 0
  }
  /* TODO: Enable this test once Optional is ~Escapable
  init?(_ ptr: UnsafeRawBufferPointer, _ a: borrowing Array<Int>, _ i: Int) -> dependsOn(a) Self? {
    if (i % 2 == 0) {
      self.ptr = ptr
      return self
    }
    return nil
  }
  */
}

struct MutableBufferView : ~Escapable, ~Copyable {
  let ptr: UnsafeMutableRawBufferPointer
  @_unsafeNonescapableResult
  init(_ ptr: UnsafeMutableRawBufferPointer) {
    self.ptr = ptr
  }
}

func testBasic() {
  let capacity = 4
  let a = Array(0..<capacity)
  a.withUnsafeBytes {
    let view = BufferView($0)
    let derivedView = derive(view)
    let newView = consumeAndCreate(derivedView)
    use(newView)    
  }
}

func derive(_ x: borrowing BufferView) -> dependsOn(x) BufferView {
  return BufferView(x.ptr)
}

func consumeAndCreate(_ x: consuming BufferView) -> dependsOn(x) BufferView {
  return BufferView(x.ptr)
}

func use(_ x: borrowing BufferView) {}

func deriveMultiView1(_ x: borrowing BufferView, _ y: borrowing BufferView) -> dependsOn(x, y) BufferView {
  if (Int.random(in: 1..<100) % 2 == 0) {
    return BufferView(x.ptr)
  }
  return BufferView(y.ptr)
}

func deriveMultiView2(_ x: borrowing BufferView, _ y: borrowing BufferView) -> dependsOn(x) dependsOn(y) BufferView {
  if (Int.random(in: 1..<100) % 2 == 0) {
    return BufferView(x.ptr)
  }
  return BufferView(y.ptr)
}

func consumeAndCreateMultiView1(_ x: consuming BufferView, _ y: consuming BufferView) -> dependsOn(x, y) BufferView {
  if (Int.random(in: 1..<100) % 2 == 0) {
    return BufferView(x.ptr)
  }
  return BufferView(y.ptr)
}

func consumeAndCreateMultiView2(_ x: consuming BufferView, _ y: consuming BufferView) -> dependsOn(x) dependsOn(y) BufferView {
  if (Int.random(in: 1..<100) % 2 == 0) {
    return BufferView(x.ptr)
  }
  return BufferView(y.ptr)
}

func mixedMultiView(_ x: consuming BufferView, _ y: borrowing BufferView) -> dependsOn(x) dependsOn(y) BufferView {
  if (Int.random(in: 1..<100) % 2 == 0) {
    return BufferView(x.ptr)
  }
  return BufferView(y.ptr)
}

func modifiedViewDependsOnInput(_ x: inout MutableBufferView) -> dependsOn(x) MutableBufferView {
  return MutableBufferView(x.ptr)
}

func modifiedViewDependsOnParent(_ x: inout MutableBufferView) -> dependsOn(x) MutableBufferView {
  return MutableBufferView(x.ptr)
}

func invalidSpecifier1(_ x: borrowing BufferView) -> dependsOn BufferView { // expected-error{{expected '(' after lifetime dependence specifier}}
  return BufferView(x.ptr)
}

func invalidSpecifier2(_ x: borrowing BufferView) -> dependsOn() BufferView {// expected-error{{expected identifier, index or self in lifetime dependence specifier}}
  return BufferView(x.ptr)
}

func invalidSpecifier3(_ x: borrowing BufferView) -> dependsOn(*) BufferView { // expected-error{{expected identifier, index or self in lifetime dependence specifier}}
  return BufferView(x.ptr)
} 

// TODO: Diagnose using param indices on func decls in sema
func invalidSpecifier4(_ x: borrowing BufferView) -> dependsOn(self) BufferView { // expected-error{{invalid lifetime dependence specifier on non-existent self}}
  return BufferView(x.ptr)
}

struct Wrapper : ~Escapable {
  let view: BufferView
  init(_ view: consuming BufferView) -> dependsOn(view) Self {
    self.view = view
    return self
  }
  borrowing func getView1() -> dependsOn(self) BufferView {
    return view
  }

  consuming func getView2() -> dependsOn(self) BufferView {
    return view
  }

  mutating func getView3() -> dependsOn(self) BufferView {
    return view
  }

  borrowing func getView4() -> dependsOn(self) BufferView {
    return view
  }
}