File: sendable_erasure_to_any_in_preconcurrency.swift

package info (click to toggle)
swiftlang 6.1.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,791,532 kB
  • sloc: cpp: 9,901,743; ansic: 2,201,431; asm: 1,091,827; python: 308,252; objc: 82,166; f90: 80,126; lisp: 38,358; pascal: 25,559; sh: 20,429; ml: 5,058; perl: 4,745; makefile: 4,484; awk: 3,535; javascript: 3,018; xml: 918; fortran: 664; cs: 573; ruby: 396
file content (123 lines) | stat: -rw-r--r-- 2,612 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
// RUN: %target-run-simple-swift | %FileCheck %s

// REQUIRES: executable_test

// UNSUPPORTED: use_os_stdlib
// UNSUPPORTED: back_deployment_runtime

class C {
  @preconcurrency var dict: [String : any Sendable] = ["a": 42]
  @preconcurrency var arr: [any Sendable] = [42]
}

extension Dictionary where Key == String, Value == Any {
  func answer() -> Int { self["a"] as! Int }

  subscript(entry e: String) -> (any Sendable)? {
    get { self["Entry#" + e] }
    set { self["Entry#" + e] = newValue }
  }

  var entryB: (any Sendable)? {
    get { self["Entry#B"] }
    set { self["Entry#B"] = newValue }
  }

  mutating func addEntry() {
    self["ultimate question"] = "???"
  }
}

extension Array where Element == Any {
  func answer() -> Int { self.first! as! Int }
}

struct S<T> {
  let v: T
}

struct Test {
  @preconcurrency var data: S<any Sendable>
  @preconcurrency var funcRef: S<([any Sendable]) -> (any Sendable)?> = S(v: { $0.first })
}

func testInOut(_ dict: inout Dictionary<String, Any>) {
  dict["inout"] = "yes"
}

func testInOut(_ arr: inout [Any]) {
  arr.append("inout")
}

func test() {
  var c = C()

  print(c.dict.answer())
  // CHECK: 42
  print(c.arr.answer())
  // CHECK: 42

  print(c.dict[entry: "A"] ?? "no A")
  // CHECK: no A

  // Insert a new value
  c.dict[entry: "A"] = "forty two"

  // Make sure that the dictionary got mutated
  print(c.dict[entry: "A"] ?? "no A")
  // CHECK: forty two

  print(c.dict.entryB ?? "no B")
  // CHECK: no B

  // Insert new value
  c.dict.entryB = (q: "", a: 42)

  print(c.dict.entryB ?? "no B")
  // CHECK: (q: "", a: 42)

  c.dict.addEntry()
  print(c.dict["ultimate question"] ?? "no question")
  // CHECK: ???

  let v1 = Test(data: S(v: 42))
  let v2 = Test(data: S(v: "ultimate question"))

  func expectsAny(_ s: S<Any>) { print(s.v) }

  expectsAny(v1.data)
  // CHECK: 42
  expectsAny(v2.data)
  // CHECK: ultimate question

  func sameType<T>(_ data: S<T>, with: T.Type) -> T {
    data.v
  }

  print(sameType(v1.data, with: Any.self))
  // CHECK: 42
  print(sameType(v2.data, with: Any.self))
  // CHECK: ultimate question

  func expectsFuncAny(_ s: S<([Any]) -> Any?>) {
    print(s.v([42]) ?? 0)
  }

  expectsFuncAny(v1.funcRef)
  // CHECK: 42

  testInOut(&c.dict)
  print(c.dict["inout"] ?? "no")
  // CHECK: yes

  testInOut(&c.arr)
  print(c.arr.contains(where: { $0 as? String == "inout" }))
  // CHECK: true

  var newValues: [Any] = ["other inout"]
  c.arr += newValues // checks implicit inout injection via operator
  print(c.arr.contains(where: { $0 as? String == "other inout" }))
  // CHECK: true
}

test()