|
| 1 | +// RUN: %empty-directory(%t) |
| 2 | +// RUN: %target-swift-frontend -emit-module -emit-module-path %t/UnavailableFunction.swiftmodule -module-name UnavailableFunction -warn-concurrency %S/Inputs/UnavailableFunction.swift |
| 3 | +// RUN: %target-swift-frontend -typecheck -verify -I %t %s |
| 4 | + |
| 5 | +// REQUIRES: concurrency |
| 6 | + |
| 7 | +import UnavailableFunction |
| 8 | + |
| 9 | +@available(SwiftStdlib 5.1, *) |
| 10 | +func okay() {} |
| 11 | + |
| 12 | +// expected-error@+1{{'@_unavailableFromAsync' attribute cannot be applied to this declaration}} |
| 13 | +@_unavailableFromAsync |
| 14 | +@available(SwiftStdlib 5.1, *) |
| 15 | +struct Foo { } |
| 16 | + |
| 17 | +// expected-error@+1{{'@_unavailableFromAsync' attribute cannot be applied to this declaration}} |
| 18 | +@_unavailableFromAsync |
| 19 | +@available(SwiftStdlib 5.1, *) |
| 20 | +extension Foo { } |
| 21 | + |
| 22 | +// expected-error@+1{{'@_unavailableFromAsync' attribute cannot be applied to this declaration}} |
| 23 | +@_unavailableFromAsync |
| 24 | +@available(SwiftStdlib 5.1, *) |
| 25 | +class Bar { |
| 26 | + // expected-error@+1{{'@_unavailableFromAsync' attribute cannot be applied to this declaration}} |
| 27 | + @_unavailableFromAsync |
| 28 | + deinit { } |
| 29 | +} |
| 30 | + |
| 31 | +// expected-error@+1{{'@_unavailableFromAsync' attribute cannot be applied to this declaration}} |
| 32 | +@_unavailableFromAsync |
| 33 | +@available(SwiftStdlib 5.1, *) |
| 34 | +actor Baz { } |
| 35 | + |
| 36 | +@available(SwiftStdlib 5.1, *) |
| 37 | +struct Bop { |
| 38 | + @_unavailableFromAsync |
| 39 | + init() {} // expected-note 4 {{'init()' declared here}} |
| 40 | + |
| 41 | + init(a: Int) { } |
| 42 | +} |
| 43 | + |
| 44 | +@available(SwiftStdlib 5.1, *) |
| 45 | +extension Bop { |
| 46 | + @_unavailableFromAsync |
| 47 | + func foo() {} // expected-note 4 {{'foo()' declared here}} |
| 48 | + |
| 49 | + |
| 50 | + @_unavailableFromAsync |
| 51 | + mutating func muppet() { } // expected-note 4 {{'muppet()' declared here}} |
| 52 | +} |
| 53 | + |
| 54 | +@_unavailableFromAsync |
| 55 | +@available(SwiftStdlib 5.1, *) |
| 56 | +func foo() {} // expected-note 4 {{'foo()' declared here}} |
| 57 | + |
| 58 | +@available(SwiftStdlib 5.1, *) |
| 59 | +func makeAsyncClosuresSynchronously(bop: inout Bop) -> (() async -> Void) { |
| 60 | + return { () async -> Void in |
| 61 | + // Unavailable methods |
| 62 | + _ = Bop() // expected-warning@:9{{'init' is unavailable from asynchronous contexts}} |
| 63 | + _ = Bop(a: 32) |
| 64 | + bop.foo() // expected-warning@:9{{'foo' is unavailable from asynchronous contexts}} |
| 65 | + bop.muppet() // expected-warning@:9{{'muppet' is unavailable from asynchronous contexts}} |
| 66 | + unavailableFunction() // expected-warning@:5{{'unavailableFunction' is unavailable from asynchronous contexts}} |
| 67 | + |
| 68 | + // Can use them from synchronous closures |
| 69 | + _ = { Bop() }() |
| 70 | + _ = { bop.foo() }() |
| 71 | + _ = { bop.muppet() }() |
| 72 | + |
| 73 | + // Unavailable global function |
| 74 | + foo() // expected-warning{{'foo' is unavailable from asynchronous contexts}} |
| 75 | + |
| 76 | + // Okay function |
| 77 | + okay() |
| 78 | + } |
| 79 | +} |
| 80 | + |
| 81 | +@available(SwiftStdlib 5.1, *) |
| 82 | +@_unavailableFromAsync |
| 83 | +func asyncFunc() async { // expected-error{{asynchronous global function 'asyncFunc()' must be available from asynchronous contexts}} |
| 84 | + |
| 85 | + var bop = Bop(a: 32) |
| 86 | + _ = Bop() // expected-warning@:7{{'init' is unavailable from asynchronous contexts}} |
| 87 | + bop.foo() // expected-warning@:7{{'foo' is unavailable from asynchronous contexts}} |
| 88 | + bop.muppet() // expected-warning@:7{{'muppet' is unavailable from asynchronous contexts}} |
| 89 | + unavailableFunction() // expected-warning@:3{{'unavailableFunction' is unavailable from asynchronous contexts}} |
| 90 | + |
| 91 | + // Unavailable global function |
| 92 | + foo() // expected-warning{{'foo' is unavailable from asynchronous contexts}} |
| 93 | + |
| 94 | + // Available function |
| 95 | + okay() |
| 96 | + |
| 97 | + _ = { () -> Void in |
| 98 | + // Check unavailable things inside of a nested synchronous closure |
| 99 | + _ = Bop() |
| 100 | + foo() |
| 101 | + bop.foo() |
| 102 | + bop.muppet() |
| 103 | + unavailableFunction() |
| 104 | + |
| 105 | + _ = { () async -> Void in |
| 106 | + // Check Unavailable things inside of a nested async closure |
| 107 | + foo() // expected-warning@:7{{'foo' is unavailable from asynchronous contexts}} |
| 108 | + bop.foo() // expected-warning@:11{{'foo' is unavailable from asynchronous contexts}} |
| 109 | + bop.muppet() // expected-warning@:11{{'muppet' is unavailable from asynchronous contexts}} |
| 110 | + _ = Bop() // expected-warning@:11{{'init' is unavailable from asynchronous contexts}} |
| 111 | + unavailableFunction() // expected-warning@:7{{'unavailableFunction' is unavailable from asynchronous contexts}} |
| 112 | + } |
| 113 | + } |
| 114 | + |
| 115 | + _ = { () async -> Void in |
| 116 | + _ = Bop() // expected-warning@:9{{'init' is unavailable from asynchronous contexts}} |
| 117 | + foo() // expected-warning@:5{{'foo' is unavailable from asynchronous contexts}} |
| 118 | + bop.foo() // expected-warning@:9{{'foo' is unavailable from asynchronous contexts}} |
| 119 | + bop.muppet() // expected-warning@:9{{'muppet' is unavailable from asynchronous contexts}} |
| 120 | + unavailableFunction() // expected-warning@:5{{'unavailableFunction' is unavailable from asynchronous contexts}} |
| 121 | + |
| 122 | + _ = { |
| 123 | + foo() |
| 124 | + bop.foo() |
| 125 | + _ = Bop() |
| 126 | + unavailableFunction() |
| 127 | + } |
| 128 | + } |
| 129 | + |
| 130 | +} |
0 commit comments