blob: 0b1d4b1175da8ebb0f2d6b7c50aa4598ebc59e4f [file] [log] [blame]
// RUN: %target-typecheck-verify-swift -swift-version 5
// ---------------------------------------------------------------------------
// Property wrapper type definitions
// ---------------------------------------------------------------------------
@propertyWrapper
struct Wrapper<T> {
private var _stored: T
init(stored: T) {
self._stored = stored
}
var wrappedValue: T {
get { _stored }
set { _stored = newValue }
}
}
@propertyWrapper
struct WrapperWithInitialValue<T> {
var wrappedValue: T
init(wrappedValue initialValue: T) {
self.wrappedValue = initialValue
}
}
@propertyWrapper
struct WrapperWithDefaultInit<T> {
private var stored: T?
var wrappedValue: T {
get { stored! }
set { stored = newValue }
}
init() {
self.stored = nil
}
}
@propertyWrapper
struct WrapperAcceptingAutoclosure<T> {
private let fn: () -> T
var wrappedValue: T {
return fn()
}
init(wrappedValue fn: @autoclosure @escaping () -> T) {
self.fn = fn
}
init(body fn: @escaping () -> T) {
self.fn = fn
}
}
@propertyWrapper
struct MissingValue<T> { }
// expected-error@-1{{property wrapper type 'MissingValue' does not contain a non-static property named 'wrappedValue'}}
@propertyWrapper
struct StaticValue {
static var wrappedValue: Int = 17
}
// expected-error@-3{{property wrapper type 'StaticValue' does not contain a non-static property named 'wrappedValue'}}
// expected-error@+1{{'@propertyWrapper' attribute cannot be applied to this declaration}}
@propertyWrapper
protocol CannotBeAWrapper {
associatedtype Value
var wrappedValue: Value { get set }
}
@propertyWrapper
struct NonVisibleValueWrapper<Value> {
private var wrappedValue: Value // expected-error{{private property 'wrappedValue' cannot have more restrictive access than its enclosing property wrapper type 'NonVisibleValueWrapper' (which is internal)}}
}
@propertyWrapper
struct NonVisibleInitWrapper<Value> {
var wrappedValue: Value
private init(wrappedValue initialValue: Value) { // expected-error{{private initializer 'init(wrappedValue:)' cannot have more restrictive access than its enclosing property wrapper type 'NonVisibleInitWrapper' (which is internal)}}
self.wrappedValue = initialValue
}
}
@propertyWrapper
struct InitialValueTypeMismatch<Value> {
var wrappedValue: Value // expected-note{{'wrappedValue' declared here}}
init(wrappedValue initialValue: Value?) { // expected-error{{'init(wrappedValue:)' parameter type ('Value?') must be the same as its 'wrappedValue' property type ('Value') or an @autoclosure thereof}}
self.wrappedValue = initialValue!
}
}
@propertyWrapper
struct MultipleInitialValues<Value> {
var wrappedValue: Value? = nil // expected-note 2{{'wrappedValue' declared here}}
init(wrappedValue initialValue: Int) { // expected-error{{'init(wrappedValue:)' parameter type ('Int') must be the same as its 'wrappedValue' property type ('Value?') or an @autoclosure thereof}}
}
init(wrappedValue initialValue: Double) { // expected-error{{'init(wrappedValue:)' parameter type ('Double') must be the same as its 'wrappedValue' property type ('Value?') or an @autoclosure thereof}}
}
}
@propertyWrapper
struct InitialValueFailable<Value> {
var wrappedValue: Value
init?(wrappedValue initialValue: Value) { // expected-error{{'init(wrappedValue:)' cannot be failable}}
return nil
}
}
@propertyWrapper
struct InitialValueFailableIUO<Value> {
var wrappedValue: Value
init!(wrappedValue initialValue: Value) { // expected-error{{'init(wrappedValue:)' cannot be failable}}
return nil
}
}
// ---------------------------------------------------------------------------
// Property wrapper type definitions
// ---------------------------------------------------------------------------
@propertyWrapper
struct _lowercaseWrapper<T> {
var wrappedValue: T
}
@propertyWrapper
struct _UppercaseWrapper<T> {
var wrappedValue: T
}
// ---------------------------------------------------------------------------
// Limitations on where property wrappers can be used
// ---------------------------------------------------------------------------
func testLocalContext() {
@WrapperWithInitialValue // expected-error{{property wrappers are not yet supported on local properties}}
var x = 17
x = 42
_ = x
}
enum SomeEnum {
case foo
@Wrapper(stored: 17)
var bar: Int // expected-error{{property 'bar' declared inside an enum cannot have a wrapper}}
// expected-error@-1{{enums must not contain stored properties}}
@Wrapper(stored: 17)
static var x: Int
}
protocol SomeProtocol {
@Wrapper(stored: 17)
var bar: Int // expected-error{{property 'bar' declared inside a protocol cannot have a wrapper}}
// expected-error@-1{{property in protocol must have explicit { get } or { get set } specifier}}
@Wrapper(stored: 17)
static var x: Int // expected-error{{property 'x' declared inside a protocol cannot have a wrapper}}
// expected-error@-1{{property in protocol must have explicit { get } or { get set } specifier}}
}
struct HasWrapper { }
extension HasWrapper {
@Wrapper(stored: 17)
var inExt: Int // expected-error{{property 'inExt' declared inside an extension cannot have a wrapper}}
// expected-error@-1{{extensions must not contain stored properties}}
@Wrapper(stored: 17)
static var x: Int
}
class ClassWithWrappers {
@Wrapper(stored: 17)
var x: Int
}
class Superclass {
var x: Int = 0
}
class SubclassOfClassWithWrappers: ClassWithWrappers {
override var x: Int {
get { return super.x }
set { super.x = newValue }
}
}
class SubclassWithWrapper: Superclass {
@Wrapper(stored: 17)
override var x: Int { get { return 0 } set { } } // expected-error{{property 'x' with attached wrapper cannot override another property}}
}
class C { }
struct BadCombinations {
@WrapperWithInitialValue
lazy var x: C = C() // expected-error{{property 'x' with a wrapper cannot also be lazy}}
@Wrapper
weak var y: C? // expected-error{{property 'y' with a wrapper cannot also be weak}}
@Wrapper
unowned var z: C // expected-error{{property 'z' with a wrapper cannot also be unowned}}
}
struct MultipleWrappers {
@Wrapper(stored: 17)
@WrapperWithInitialValue // expected-error{{extra argument 'wrappedValue' in call}}
var x: Int = 17
@WrapperWithInitialValue // expected-error 2{{property wrapper can only apply to a single variable}}
var (y, z) = (1, 2)
}
// ---------------------------------------------------------------------------
// Initialization
// ---------------------------------------------------------------------------
struct Initialization {
@Wrapper(stored: 17)
var x: Int
@Wrapper(stored: 17)
var x2: Double
@Wrapper(stored: 17)
var x3 = 42 // expected-error{{extra argument 'wrappedValue' in call}}
@Wrapper(stored: 17)
var x4
@WrapperWithInitialValue
var y = true
// FIXME: For some reason this is type-checked twice, second time around solver complains about <<error type>> argument
@WrapperWithInitialValue<Int>
var y2 = true // expected-error{{cannot convert value of type 'Bool' to expected argument type 'Int'}}
// expected-error@-1 {{cannot convert value of type '<<error type>>' to expected argument type 'Int'}}
mutating func checkTypes(s: String) {
x2 = s // expected-error{{cannot assign value of type 'String' to type 'Double'}}
x4 = s // expected-error{{cannot assign value of type 'String' to type 'Int'}}
y = s // expected-error{{cannot assign value of type 'String' to type 'Bool'}}
}
}
@propertyWrapper
struct Clamping<V: Comparable> {
var value: V
let min: V
let max: V
init(wrappedValue initialValue: V, min: V, max: V) {
value = initialValue
self.min = min
self.max = max
assert(value >= min && value <= max)
}
var wrappedValue: V {
get { return value }
set {
if newValue < min {
value = min
} else if newValue > max {
value = max
} else {
value = newValue
}
}
}
}
struct Color {
@Clamping(min: 0, max: 255) var red: Int = 127
@Clamping(min: 0, max: 255) var green: Int = 127
@Clamping(min: 0, max: 255) var blue: Int = 127
@Clamping(min: 0, max: 255) var alpha: Int = 255
}
func testColor() {
_ = Color(green: 17)
}
// ---------------------------------------------------------------------------
// Wrapper type formation
// ---------------------------------------------------------------------------
@propertyWrapper
struct IntWrapper {
var wrappedValue: Int
}
@propertyWrapper
struct WrapperForHashable<T: Hashable> { // expected-note{{property wrapper type 'WrapperForHashable' declared here}}
var wrappedValue: T
}
@propertyWrapper
struct WrapperWithTwoParams<T, U> {
var wrappedValue: (T, U)
}
struct NotHashable { }
struct UseWrappersWithDifferentForm {
@IntWrapper
var x: Int
// FIXME: Diagnostic should be better here
@WrapperForHashable
var y: NotHashable // expected-error{{property type 'NotHashable' does not match that of the 'wrappedValue' property of its wrapper type 'WrapperForHashable'}}
@WrapperForHashable
var yOkay: Int
@WrapperWithTwoParams
var zOkay: (Int, Float)
// FIXME: Need a better diagnostic here
@HasNestedWrapper.NestedWrapper
var w: Int // expected-error{{property type 'Int' does not match that of the 'wrappedValue' property of its wrapper type 'HasNestedWrapper.NestedWrapper'}}
@HasNestedWrapper<Double>.NestedWrapper
var wOkay: Int
@HasNestedWrapper.ConcreteNestedWrapper
var wOkay2: Int
}
@propertyWrapper
struct Function<T, U> { // expected-note{{property wrapper type 'Function' declared here}}
var wrappedValue: (T) -> U?
}
struct TestFunction {
@Function var f: (Int) -> Float?
@Function var f2: (Int) -> Float // expected-error{{property type '(Int) -> Float' does not match that of the 'wrappedValue' property of its wrapper type 'Function'}}
func test() {
let _: Int = _f // expected-error{{cannot convert value of type 'Function<Int, Float>' to specified type 'Int'}}
}
}
// ---------------------------------------------------------------------------
// Nested wrappers
// ---------------------------------------------------------------------------
struct HasNestedWrapper<T> {
@propertyWrapper
struct NestedWrapper<U> { // expected-note{{property wrapper type 'NestedWrapper' declared here}}
var wrappedValue: U
init(wrappedValue initialValue: U) {
self.wrappedValue = initialValue
}
}
@propertyWrapper
struct ConcreteNestedWrapper {
var wrappedValue: T
init(wrappedValue initialValue: T) {
self.wrappedValue = initialValue
}
}
@NestedWrapper
var y: [T] = []
}
struct UsesNestedWrapper<V> {
@HasNestedWrapper<V>.NestedWrapper
var y: [V]
}
// ---------------------------------------------------------------------------
// Referencing the backing store
// ---------------------------------------------------------------------------
struct BackingStore<T> {
@Wrapper
var x: T
@WrapperWithInitialValue
private var y = true // expected-note{{'y' declared here}}
func getXStorage() -> Wrapper<T> {
return _x
}
func getYStorage() -> WrapperWithInitialValue<Bool> {
return self._y
}
}
func testBackingStore<T>(bs: BackingStore<T>) {
_ = bs.x
_ = bs.y // expected-error{{'y' is inaccessible due to 'private' protection level}}
}
// ---------------------------------------------------------------------------
// Explicitly-specified accessors
// ---------------------------------------------------------------------------
struct WrapperWithAccessors {
@Wrapper // expected-error{{property wrapper cannot be applied to a computed property}}
var x: Int {
return 17
}
}
struct UseWillSetDidSet {
@Wrapper
var x: Int {
willSet {
print(newValue)
}
}
@Wrapper
var y: Int {
didSet {
print(oldValue)
}
}
@Wrapper
var z: Int {
willSet {
print(newValue)
}
didSet {
print(oldValue)
}
}
}
// ---------------------------------------------------------------------------
// Mutating/nonmutating
// ---------------------------------------------------------------------------
@propertyWrapper
struct WrapperWithNonMutatingSetter<Value> {
class Box {
var wrappedValue: Value
init(wrappedValue: Value) {
self.wrappedValue = wrappedValue
}
}
var box: Box
init(wrappedValue initialValue: Value) {
self.box = Box(wrappedValue: initialValue)
}
var wrappedValue: Value {
get { return box.wrappedValue }
nonmutating set { box.wrappedValue = newValue }
}
}
@propertyWrapper
struct WrapperWithMutatingGetter<Value> {
var readCount = 0
var writeCount = 0
var stored: Value
init(wrappedValue initialValue: Value) {
self.stored = initialValue
}
var wrappedValue: Value {
mutating get {
readCount += 1
return stored
}
set {
writeCount += 1
stored = newValue
}
}
}
@propertyWrapper
class ClassWrapper<Value> {
var wrappedValue: Value
init(wrappedValue initialValue: Value) {
self.wrappedValue = initialValue
}
}
struct UseMutatingnessWrappers {
@WrapperWithNonMutatingSetter
var x = true
@WrapperWithMutatingGetter
var y = 17
@WrapperWithNonMutatingSetter // expected-error{{property wrapper can only be applied to a 'var'}}
let z = 3.14159 // expected-note 2{{change 'let' to 'var' to make it mutable}}
@ClassWrapper
var w = "Hello"
}
func testMutatingness() {
var mutable = UseMutatingnessWrappers()
_ = mutable.x
mutable.x = false
_ = mutable.y
mutable.y = 42
_ = mutable.z
mutable.z = 2.71828 // expected-error{{cannot assign to property: 'z' is a 'let' constant}}
_ = mutable.w
mutable.w = "Goodbye"
let nonmutable = UseMutatingnessWrappers() // expected-note 2{{change 'let' to 'var' to make it mutable}}
// Okay due to nonmutating setter
_ = nonmutable.x
nonmutable.x = false
_ = nonmutable.y // expected-error{{cannot use mutating getter on immutable value: 'nonmutable' is a 'let' constant}}
nonmutable.y = 42 // expected-error{{cannot use mutating getter on immutable value: 'nonmutable' is a 'let' constant}}
_ = nonmutable.z
nonmutable.z = 2.71828 // expected-error{{cannot assign to property: 'z' is a 'let' constant}}
// Okay due to implicitly nonmutating setter
_ = nonmutable.w
nonmutable.w = "World"
}
// ---------------------------------------------------------------------------
// Access control
// ---------------------------------------------------------------------------
struct HasPrivateWrapper<T> {
@propertyWrapper
private struct PrivateWrapper<U> { // expected-note{{type declared here}}
var wrappedValue: U
init(wrappedValue initialValue: U) {
self.wrappedValue = initialValue
}
}
@PrivateWrapper
var y: [T] = []
// expected-error@-1{{property must be declared private because its property wrapper type uses a private type}}
// Okay to reference private entities from a private property
@PrivateWrapper
private var z: [T]
}
public struct HasUsableFromInlineWrapper<T> {
@propertyWrapper
struct InternalWrapper<U> { // expected-note{{type declared here}}
var wrappedValue: U
init(wrappedValue initialValue: U) {
self.wrappedValue = initialValue
}
}
@InternalWrapper
@usableFromInline
var y: [T] = []
// expected-error@-1{{property wrapper type referenced from a '@usableFromInline' property must be '@usableFromInline' or public}}
}
@propertyWrapper
class Box<Value> {
private(set) var wrappedValue: Value
init(wrappedValue initialValue: Value) {
self.wrappedValue = initialValue
}
}
struct UseBox {
@Box
var x = 17 // expected-note{{'_x' declared here}}
}
func testBox(ub: UseBox) {
_ = ub.x
ub.x = 5 // expected-error{{cannot assign to property: 'x' is a get-only property}}
var mutableUB = ub
mutableUB = ub
}
func backingVarIsPrivate(ub: UseBox) {
_ = ub._x // expected-error{{'_x' is inaccessible due to 'private' protection level}}
}
// ---------------------------------------------------------------------------
// Memberwise initializers
// ---------------------------------------------------------------------------
struct MemberwiseInits<T> {
@Wrapper
var x: Bool
@WrapperWithInitialValue
var y: T
}
func testMemberwiseInits() {
// expected-error@+1{{type '(Wrapper<Bool>, Double) -> MemberwiseInits<Double>'}}
let _: Int = MemberwiseInits<Double>.init
_ = MemberwiseInits(x: Wrapper(stored: true), y: 17)
}
struct DefaultedMemberwiseInits {
@Wrapper(stored: true)
var x: Bool
@WrapperWithInitialValue
var y: Int = 17
@WrapperWithInitialValue(wrappedValue: 17)
var z: Int
@WrapperWithDefaultInit
var w: Int
@WrapperWithDefaultInit
var optViaDefaultInit: Int?
@WrapperWithInitialValue
var optViaInitialValue: Int?
}
struct CannotDefaultMemberwiseOptionalInit { // expected-note{{'init(x:)' declared here}}
@Wrapper
var x: Int?
}
func testDefaultedMemberwiseInits() {
_ = DefaultedMemberwiseInits()
_ = DefaultedMemberwiseInits(
x: Wrapper(stored: false),
y: 42,
z: WrapperWithInitialValue(wrappedValue: 42))
_ = DefaultedMemberwiseInits(y: 42)
_ = DefaultedMemberwiseInits(x: Wrapper(stored: false))
_ = DefaultedMemberwiseInits(z: WrapperWithInitialValue(wrappedValue: 42))
_ = DefaultedMemberwiseInits(w: WrapperWithDefaultInit())
_ = DefaultedMemberwiseInits(optViaDefaultInit: WrapperWithDefaultInit())
_ = DefaultedMemberwiseInits(optViaInitialValue: nil)
_ = DefaultedMemberwiseInits(optViaInitialValue: 42)
_ = CannotDefaultMemberwiseOptionalInit() // expected-error{{missing argument for parameter 'x' in call}}
_ = CannotDefaultMemberwiseOptionalInit(x: Wrapper(stored: nil))
}
// ---------------------------------------------------------------------------
// Default initializers
// ---------------------------------------------------------------------------
struct DefaultInitializerStruct {
@Wrapper(stored: true)
var x
@WrapperWithInitialValue
var y: Int = 10
}
struct NoDefaultInitializerStruct { // expected-note{{'init(x:)' declared here}}
@Wrapper
var x: Bool
}
class DefaultInitializerClass {
@Wrapper(stored: true)
var x
@WrapperWithInitialValue
final var y: Int = 10
}
class NoDefaultInitializerClass { // expected-error{{class 'NoDefaultInitializerClass' has no initializers}}
@Wrapper
final var x: Bool // expected-note{{stored property 'x' without initial value prevents synthesized initializers}}
}
func testDefaultInitializers() {
_ = DefaultInitializerStruct()
_ = DefaultInitializerClass()
_ = NoDefaultInitializerStruct() // expected-error{{missing argument for parameter 'x' in call}}
}
struct DefaultedPrivateMemberwiseLets {
@Wrapper(stored: true)
private var x: Bool
@WrapperWithInitialValue
var y: Int = 17
@WrapperWithInitialValue(wrappedValue: 17)
private var z: Int
}
func testDefaultedPrivateMemberwiseLets() {
_ = DefaultedPrivateMemberwiseLets()
_ = DefaultedPrivateMemberwiseLets(y: 42)
_ = DefaultedPrivateMemberwiseLets(x: Wrapper(stored: false)) // expected-error{{incorrect argument label in call (have 'x:', expected 'y:')}}
// expected-error@-1 {{cannot convert value of type 'Wrapper<Bool>' to expected argument type 'Int'}}
}
// ---------------------------------------------------------------------------
// Storage references
// ---------------------------------------------------------------------------
@propertyWrapper
struct WrapperWithStorageRef<T> {
var wrappedValue: T
var projectedValue: Wrapper<T> {
return Wrapper(stored: wrappedValue)
}
}
extension Wrapper {
var wrapperOnlyAPI: Int { return 17 }
}
struct TestStorageRef {
@WrapperWithStorageRef var x: Int // expected-note{{'_x' declared here}}
init(x: Int) {
self._x = WrapperWithStorageRef(wrappedValue: x)
}
mutating func test() {
let _: Wrapper = $x
let i = $x.wrapperOnlyAPI
let _: Int = i
// x is mutable, $x is not
x = 17
$x = Wrapper(stored: 42) // expected-error{{cannot assign to property: '$x' is immutable}}
}
}
func testStorageRef(tsr: TestStorageRef) {
let _: Wrapper = tsr.$x
_ = tsr._x // expected-error{{'_x' is inaccessible due to 'private' protection level}}
}
struct TestStorageRefPrivate {
@WrapperWithStorageRef private(set) var x: Int
init() {
self._x = WrapperWithStorageRef(wrappedValue: 5)
}
}
func testStorageRefPrivate() {
var tsr = TestStorageRefPrivate()
let a = tsr.$x // okay, getter is internal
tsr.$x = a // expected-error{{cannot assign to property: '$x' is immutable}}
}
// rdar://problem/50873275 - crash when using wrapper with projectedValue in
// generic type.
@propertyWrapper
struct InitialValueWrapperWithStorageRef<T> {
var wrappedValue: T
init(wrappedValue initialValue: T) {
wrappedValue = initialValue
}
var projectedValue: Wrapper<T> {
return Wrapper(stored: wrappedValue)
}
}
struct TestGenericStorageRef<T> {
struct Inner { }
@InitialValueWrapperWithStorageRef var inner: Inner = Inner()
}
// Wiring up the _projectedValueProperty attribute.
struct TestProjectionValuePropertyAttr {
@_projectedValueProperty(wrapperA)
@WrapperWithStorageRef var a: String
var wrapperA: Wrapper<String> {
Wrapper(stored: "blah")
}
@_projectedValueProperty(wrapperB) // expected-error{{could not find projection value property 'wrapperB'}}
@WrapperWithStorageRef var b: String
}
// ---------------------------------------------------------------------------
// Misc. semantic issues
// ---------------------------------------------------------------------------
@propertyWrapper
struct BrokenLazy { }
// expected-error@-1{{property wrapper type 'BrokenLazy' does not contain a non-static property named 'wrappedValue'}}
// expected-note@-2{{'BrokenLazy' declared here}}
struct S {
@BrokenLazy // expected-error{{struct 'BrokenLazy' cannot be used as an attribute}}
var wrappedValue: Int
}
// ---------------------------------------------------------------------------
// Closures in initializers
// ---------------------------------------------------------------------------
struct UsesExplicitClosures {
@WrapperAcceptingAutoclosure(body: { 42 })
var x: Int
@WrapperAcceptingAutoclosure(body: { return 42 })
var y: Int
}
// ---------------------------------------------------------------------------
// Miscellaneous bugs
// ---------------------------------------------------------------------------
// rdar://problem/50822051 - compiler assertion / hang
@propertyWrapper
struct PD<Value> {
var wrappedValue: Value
init<A>(wrappedValue initialValue: Value, a: A) {
self.wrappedValue = initialValue
}
}
struct TestPD {
@PD(a: "foo") var foo: Int = 42
}
protocol P { }
@propertyWrapper
struct WrapperRequiresP<T: P> {
var wrappedValue: T
var projectedValue: T { return wrappedValue }
}
struct UsesWrapperRequiringP {
// expected-note@-1{{in declaration of}}
@WrapperRequiresP var x.: UsesWrapperRequiringP
// expected-error@-1{{expected member name following '.'}}
// expected-error@-2{{expected declaration}}
// expected-error@-3{{type annotation missing in pattern}}
}
// SR-10899 / rdar://problem/51588022
@propertyWrapper
struct SR_10899_Wrapper { // expected-note{{property wrapper type 'SR_10899_Wrapper' declared here}}
var wrappedValue: String { "hi" }
}
struct SR_10899_Usage {
@SR_10899_Wrapper var thing: Bool // expected-error{{property type 'Bool' does not match that of the 'wrappedValue' property of its wrapper type 'SR_10899_Wrapper'}}
}
// SR-11061 / rdar://problem/52593304 assertion with DeclContext mismatches
class SomeValue {
@SomeA(closure: { $0 }) var some: Int = 100
}
@propertyWrapper
struct SomeA<T> {
var wrappedValue: T
let closure: (T) -> (T)
init(wrappedValue initialValue: T, closure: @escaping (T) -> (T)) {
self.wrappedValue = initialValue
self.closure = closure
}
}
// rdar://problem/51989272 - crash when the property wrapper is a generic type
// alias
typealias Alias<T> = WrapperWithInitialValue<T>
struct TestAlias {
@Alias var foo = 17
}
// rdar://problem/52969503 - crash due to invalid source ranges in ill-formed
// code.
@propertyWrapper
struct Wrap52969503<T> {
var wrappedValue: T
init(blah: Int, wrappedValue: T) { }
}
struct Test52969503 {
@Wrap52969503(blah: 5) var foo: Int = 1 // expected-error{{argument 'blah' must precede argument 'wrappedValue'}}
}
//
// ---------------------------------------------------------------------------
// Property wrapper composition
// ---------------------------------------------------------------------------
@propertyWrapper
struct WrapperA<Value> {
var wrappedValue: Value
init(wrappedValue initialValue: Value) {
wrappedValue = initialValue
}
}
@propertyWrapper
struct WrapperB<Value> {
var wrappedValue: Value
init(wrappedValue initialValue: Value) {
wrappedValue = initialValue
}
}
@propertyWrapper
struct WrapperC<Value> {
var wrappedValue: Value?
init(wrappedValue initialValue: Value?) {
wrappedValue = initialValue
}
}
@propertyWrapper
struct WrapperD<Value, X, Y> { // expected-note{{property wrapper type 'WrapperD' declared here}}
var wrappedValue: Value
}
@propertyWrapper
struct WrapperE<Value> {
var wrappedValue: Value
}
struct TestComposition {
@WrapperA @WrapperB @WrapperC var p1: Int?
@WrapperA @WrapperB @WrapperC var p2 = "Hello"
@WrapperD<WrapperE, Int, String> @WrapperE var p3: Int?
@WrapperD<WrapperC, Int, String> @WrapperC var p4: Int?
@WrapperD<WrapperC, Int, String> @WrapperE var p5: Int // expected-error{{property type 'Int' does not match that of the 'wrappedValue' property of its wrapper type 'WrapperD<WrapperC, Int, String>'}}
func triggerErrors(d: Double) {
p1 = d // expected-error{{cannot assign value of type 'Double' to type 'Int?'}}
p2 = d // expected-error{{cannot assign value of type 'Double' to type 'String?'}}
p3 = d // expected-error{{cannot assign value of type 'Double' to type 'Int?'}}
_p1 = d // expected-error{{cannot assign value of type 'Double' to type 'WrapperA<WrapperB<WrapperC<Int>>>'}}
_p2 = d // expected-error{{cannot assign value of type 'Double' to type 'WrapperA<WrapperB<WrapperC<String>>>'}}
_p3 = d // expected-error{{cannot assign value of type 'Double' to type 'WrapperD<WrapperE<Int?>, Int, String>'}}
}
}
// ---------------------------------------------------------------------------
// Missing Property Wrapper Unwrap Diagnostics
// ---------------------------------------------------------------------------
@propertyWrapper
struct Foo<T> { // expected-note {{arguments to generic parameter 'T' ('W' and 'Int') are expected to be equal}}
var wrappedValue: T {
get {
fatalError("boom")
}
set {
}
}
var prop: Int = 42
func foo() {}
func bar(x: Int) {}
subscript(q: String) -> Int {
get { return 42 }
set { }
}
subscript(x x: Int) -> Int {
get { return 42 }
set { }
}
subscript(q q: String, a: Int) -> Bool {
get { return false }
set { }
}
}
extension Foo : Equatable where T : Equatable {
static func == (lhs: Foo, rhs: Foo) -> Bool {
lhs.wrappedValue == rhs.wrappedValue
}
}
extension Foo : Hashable where T : Hashable {
func hash(into hasher: inout Hasher) {
hasher.combine(wrappedValue)
}
}
@propertyWrapper
struct Bar<T, V> {
var wrappedValue: T
func bar() {}
// TODO(diagnostics): We need to figure out what to do about subscripts.
// The problem standing in our way - keypath application choice
// is always added to results even if it's not applicable.
}
@propertyWrapper
struct Baz<T> {
var wrappedValue: T
func onPropertyWrapper() {}
var projectedValue: V {
return V()
}
}
extension Bar where V == String { // expected-note {{where 'V' = 'Bool'}}
func barWhereVIsString() {}
}
struct V {
func onProjectedValue() {}
}
struct W {
func onWrapped() {}
}
struct MissingPropertyWrapperUnwrap {
@Foo var w: W
@Foo var x: Int
@Bar<Int, Bool> var y: Int
@Bar<Int, String> var z: Int
@Baz var usesProjectedValue: W
func a<T>(_: Foo<T>) {}
func a<T>(named: Foo<T>) {}
func b(_: Foo<Int>) {}
func c(_: V) {}
func d(_: W) {}
func e(_: Foo<W>) {}
subscript<T : Hashable>(takesFoo x: Foo<T>) -> Foo<T> { x }
func baz() {
self.x.foo() // expected-error {{referencing instance method 'foo()' requires wrapper 'Foo<Int>'}}{{10-10=_}}
self.x.prop // expected-error {{referencing property 'prop' requires wrapper 'Foo<Int>'}} {{10-10=_}}
self.x.bar(x: 42) // expected-error {{referencing instance method 'bar(x:)' requires wrapper 'Foo<Int>'}} {{10-10=_}}
self.y.bar() // expected-error {{referencing instance method 'bar()' requires wrapper 'Bar<Int, Bool>'}}{{10-10=_}}
self.y.barWhereVIsString() // expected-error {{referencing instance method 'barWhereVIsString()' requires wrapper 'Bar<Int, Bool>'}}{{10-10=_}}
// expected-error@-1 {{referencing instance method 'barWhereVIsString()' on 'Bar' requires the types 'Bool' and 'String' be equivalent}}
self.z.barWhereVIsString() // expected-error {{referencing instance method 'barWhereVIsString()' requires wrapper 'Bar<Int, String>'}}{{10-10=_}}
self.usesProjectedValue.onPropertyWrapper() // expected-error {{referencing instance method 'onPropertyWrapper()' requires wrapper 'Baz<W>'}}{{10-10=_}}
self._w.onWrapped() // expected-error {{referencing instance method 'onWrapped()' requires wrapped value of type 'W'}}{{10-11=}}
self.usesProjectedValue.onProjectedValue() // expected-error {{referencing instance method 'onProjectedValue()' requires wrapper 'V'}}{{10-10=$}}
self.$usesProjectedValue.onWrapped() // expected-error {{referencing instance method 'onWrapped()' requires wrapped value of type 'W'}}{{10-11=}}
self._usesProjectedValue.onWrapped() // expected-error {{referencing instance method 'onWrapped()' requires wrapped value of type 'W'}}{{10-11=}}
a(self.w) // expected-error {{cannot convert value 'w' of type 'W' to expected type 'Foo<W>', use wrapper instead}}{{12-12=_}}
b(self.x) // expected-error {{cannot convert value 'x' of type 'Int' to expected type 'Foo<Int>', use wrapper instead}}{{12-12=_}}
b(self.w) // expected-error {{cannot convert value of type 'W' to expected argument type 'Foo<Int>'}}
e(self.w) // expected-error {{cannot convert value 'w' of type 'W' to expected type 'Foo<W>', use wrapper instead}}{{12-12=_}}
b(self._w) // expected-error {{cannot convert value of type 'Foo<W>' to expected argument type 'Foo<Int>'}}
c(self.usesProjectedValue) // expected-error {{cannot convert value 'usesProjectedValue' of type 'W' to expected type 'V', use wrapper instead}}{{12-12=$}}
d(self.$usesProjectedValue) // expected-error {{cannot convert value '$usesProjectedValue' of type 'V' to expected type 'W', use wrapped value instead}}{{12-13=}}
d(self._usesProjectedValue) // expected-error {{cannot convert value '_usesProjectedValue' of type 'Baz<W>' to expected type 'W', use wrapped value instead}}{{12-13=}}
self.x["ultimate question"] // expected-error {{referencing subscript 'subscript(_:)' requires wrapper 'Foo<Int>'}} {{10-10=_}}
self.x["ultimate question"] = 42 // expected-error {{referencing subscript 'subscript(_:)' requires wrapper 'Foo<Int>'}} {{10-10=_}}
self.x[x: 42] // expected-error {{referencing subscript 'subscript(x:)' requires wrapper 'Foo<Int>'}} {{10-10=_}}
self.x[x: 42] = 0 // expected-error {{referencing subscript 'subscript(x:)' requires wrapper 'Foo<Int>'}} {{10-10=_}}
self.x[q: "ultimate question", 42] // expected-error {{referencing subscript 'subscript(q:_:)' requires wrapper 'Foo<Int>'}} {{10-10=_}}
self.x[q: "ultimate question", 42] = true // expected-error {{referencing subscript 'subscript(q:_:)' requires wrapper 'Foo<Int>'}} {{10-10=_}}
// SR-11476
_ = \Self.[takesFoo: self.x] // expected-error {{cannot convert value 'x' of type 'Int' to expected type 'Foo<Int>', use wrapper instead}}{{31-31=_}}
_ = \Foo<W>.[x: self._x] // expected-error {{cannot convert value '_x' of type 'Foo<Int>' to expected type 'Int', use wrapped value instead}} {{26-27=}}
}
}
struct InvalidPropertyDelegateUse {
@Foo var x: Int = 42 // expected-error {{cannot invoke initializer for ty}}
// expected-note@-1{{overloads for 'Foo<_>' exist with these partially matching paramet}}
func test() {
self.x.foo() // expected-error {{value of type 'Int' has no member 'foo'}}
}
}
// SR-11060
class SR_11060_Class {
@SR_11060_Wrapper var property: Int = 1234 // expected-error {{missing argument for parameter 'string' in property wrapper initializer; add 'wrappedValue' and 'string' arguments in '@SR_11060_Wrapper(...)'}}
}
@propertyWrapper
struct SR_11060_Wrapper {
var wrappedValue: Int
init(wrappedValue: Int, string: String) { // expected-note {{'init(wrappedValue:string:)' declared here}}
self.wrappedValue = wrappedValue
}
}
// SR-11138
// Check that all possible compositions of nonmutating/mutating accessors
// on wrappers produce wrapped properties with the correct settability and
// mutatiness in all compositions.
@propertyWrapper
struct NonmutatingGetWrapper<T> {
var wrappedValue: T {
nonmutating get { fatalError() }
}
}
@propertyWrapper
struct MutatingGetWrapper<T> {
var wrappedValue: T {
mutating get { fatalError() }
}
}
@propertyWrapper
struct NonmutatingGetNonmutatingSetWrapper<T> {
var wrappedValue: T {
nonmutating get { fatalError() }
nonmutating set { fatalError() }
}
}
@propertyWrapper
struct MutatingGetNonmutatingSetWrapper<T> {
var wrappedValue: T {
mutating get { fatalError() }
nonmutating set { fatalError() }
}
}
@propertyWrapper
struct NonmutatingGetMutatingSetWrapper<T> {
var wrappedValue: T {
nonmutating get { fatalError() }
mutating set { fatalError() }
}
}
@propertyWrapper
struct MutatingGetMutatingSetWrapper<T> {
var wrappedValue: T {
mutating get { fatalError() }
mutating set { fatalError() }
}
}
struct AllCompositionsStruct {
// Should have nonmutating getter, undefined setter
@NonmutatingGetWrapper @NonmutatingGetWrapper
var ngxs_ngxs: Int
// Should be disallowed
@NonmutatingGetWrapper @MutatingGetWrapper // expected-error{{cannot be composed}}
var ngxs_mgxs: Int
// Should have nonmutating getter, nonmutating setter
@NonmutatingGetWrapper @NonmutatingGetNonmutatingSetWrapper
var ngxs_ngns: Int
// Should be disallowed
@NonmutatingGetWrapper @MutatingGetNonmutatingSetWrapper // expected-error{{cannot be composed}}
var ngxs_mgns: Int
// Should have nonmutating getter, undefined setter
@NonmutatingGetWrapper @NonmutatingGetMutatingSetWrapper
var ngxs_ngms: Int
// Should be disallowed
@NonmutatingGetWrapper @MutatingGetMutatingSetWrapper // expected-error{{cannot be composed}}
var ngxs_mgms: Int
////
// Should have mutating getter, undefined setter
@MutatingGetWrapper @NonmutatingGetWrapper
var mgxs_ngxs: Int
// Should be disallowed
@MutatingGetWrapper @MutatingGetWrapper // expected-error{{cannot be composed}}
var mgxs_mgxs: Int
// Should have mutating getter, mutating setter
@MutatingGetWrapper @NonmutatingGetNonmutatingSetWrapper
var mgxs_ngns: Int
// Should be disallowed
@MutatingGetWrapper @MutatingGetNonmutatingSetWrapper // expected-error{{cannot be composed}}
var mgxs_mgns: Int
// Should have mutating getter, undefined setter
@MutatingGetWrapper @NonmutatingGetMutatingSetWrapper
var mgxs_ngms: Int
// Should be disallowed
@MutatingGetWrapper @MutatingGetMutatingSetWrapper // expected-error{{cannot be composed}}
var mgxs_mgms: Int
////
// Should have nonmutating getter, undefined setter
@NonmutatingGetNonmutatingSetWrapper @NonmutatingGetWrapper
var ngns_ngxs: Int
// Should have nonmutating getter, undefined setter
@NonmutatingGetNonmutatingSetWrapper @MutatingGetWrapper
var ngns_mgxs: Int
// Should have nonmutating getter, nonmutating setter
@NonmutatingGetNonmutatingSetWrapper @NonmutatingGetNonmutatingSetWrapper
var ngns_ngns: Int
// Should have nonmutating getter, nonmutating setter
@NonmutatingGetNonmutatingSetWrapper @MutatingGetNonmutatingSetWrapper
var ngns_mgns: Int
// Should have nonmutating getter, nonmutating setter
@NonmutatingGetNonmutatingSetWrapper @NonmutatingGetMutatingSetWrapper
var ngns_ngms: Int
// Should have nonmutating getter, nonmutating setter
@NonmutatingGetNonmutatingSetWrapper @MutatingGetMutatingSetWrapper
var ngns_mgms: Int
////
// Should have mutating getter, undefined setter
@MutatingGetNonmutatingSetWrapper @NonmutatingGetWrapper
var mgns_ngxs: Int
// Should have mutating getter, undefined setter
@MutatingGetNonmutatingSetWrapper @MutatingGetWrapper
var mgns_mgxs: Int
// Should have mutating getter, mutating setter
@MutatingGetNonmutatingSetWrapper @NonmutatingGetNonmutatingSetWrapper
var mgns_ngns: Int
// Should have mutating getter, mutating setter
@MutatingGetNonmutatingSetWrapper @MutatingGetNonmutatingSetWrapper
var mgns_mgns: Int
// Should have mutating getter, mutating setter
@MutatingGetNonmutatingSetWrapper @NonmutatingGetMutatingSetWrapper
var mgns_ngms: Int
// Should have mutating getter, mutating setter
@MutatingGetNonmutatingSetWrapper @MutatingGetMutatingSetWrapper
var mgns_mgms: Int
////
// Should have nonmutating getter, undefined setter
@NonmutatingGetMutatingSetWrapper @NonmutatingGetWrapper
var ngms_ngxs: Int
// Should have mutating getter, undefined setter
@NonmutatingGetMutatingSetWrapper @MutatingGetWrapper
var ngms_mgxs: Int
// Should have nonmutating getter, nonmutating setter
@NonmutatingGetMutatingSetWrapper @NonmutatingGetNonmutatingSetWrapper
var ngms_ngns: Int
// Should have mutating getter, nonmutating setter
@NonmutatingGetMutatingSetWrapper @MutatingGetNonmutatingSetWrapper
var ngms_mgns: Int
// Should have nonmutating getter, mutating setter
@NonmutatingGetMutatingSetWrapper @NonmutatingGetMutatingSetWrapper
var ngms_ngms: Int
// Should have mutating getter, mutating setter
@NonmutatingGetMutatingSetWrapper @MutatingGetMutatingSetWrapper
var ngms_mgms: Int
////
// Should have mutating getter, undefined setter
@MutatingGetMutatingSetWrapper @NonmutatingGetWrapper
var mgms_ngxs: Int
// Should have mutating getter, undefined setter
@MutatingGetMutatingSetWrapper @MutatingGetWrapper
var mgms_mgxs: Int
// Should have mutating getter, mutating setter
@MutatingGetMutatingSetWrapper @NonmutatingGetNonmutatingSetWrapper
var mgms_ngns: Int
// Should have mutating getter, mutating setter
@MutatingGetMutatingSetWrapper @MutatingGetNonmutatingSetWrapper
var mgms_mgns: Int
// Should have mutating getter, mutating setter
@MutatingGetMutatingSetWrapper @NonmutatingGetMutatingSetWrapper
var mgms_ngms: Int
// Should have mutating getter, mutating setter
@MutatingGetMutatingSetWrapper @MutatingGetMutatingSetWrapper
var mgms_mgms: Int
func readonlyContext(x: Int) { // expected-note *{{}}
_ = ngxs_ngxs
// _ = ngxs_mgxs
_ = ngxs_ngns
// _ = ngxs_mgns
_ = ngxs_ngms
// _ = ngxs_mgms
_ = mgxs_ngxs // expected-error{{}}
// _ = mgxs_mgxs
_ = mgxs_ngns // expected-error{{}}
// _ = mgxs_mgns
_ = mgxs_ngms // expected-error{{}}
// _ = mgxs_mgms
_ = ngns_ngxs
_ = ngns_mgxs
_ = ngns_ngns
_ = ngns_mgns
_ = ngns_ngms
_ = ngns_mgms
_ = mgns_ngxs // expected-error{{}}
_ = mgns_mgxs // expected-error{{}}
_ = mgns_ngns // expected-error{{}}
_ = mgns_mgns // expected-error{{}}
_ = mgns_ngms // expected-error{{}}
_ = mgns_mgms // expected-error{{}}
_ = ngms_ngxs
_ = ngms_mgxs // expected-error{{}}
_ = ngms_ngns
_ = ngms_mgns // expected-error{{}}
_ = ngms_ngms
_ = ngms_mgms // expected-error{{}}
_ = mgms_ngxs // expected-error{{}}
_ = mgms_mgxs // expected-error{{}}
_ = mgms_ngns // expected-error{{}}
_ = mgms_mgns // expected-error{{}}
_ = mgms_ngms // expected-error{{}}
_ = mgms_mgms // expected-error{{}}
////
ngxs_ngxs = x // expected-error{{}}
// ngxs_mgxs = x
ngxs_ngns = x
// ngxs_mgns = x
ngxs_ngms = x // expected-error{{}}
// ngxs_mgms = x
mgxs_ngxs = x // expected-error{{}}
// mgxs_mgxs = x
mgxs_ngns = x // expected-error{{}}
// mgxs_mgns = x
mgxs_ngms = x // expected-error{{}}
// mgxs_mgms = x
ngns_ngxs = x // expected-error{{}}
ngns_mgxs = x // expected-error{{}}
ngns_ngns = x
ngns_mgns = x
ngns_ngms = x
ngns_mgms = x
mgns_ngxs = x // expected-error{{}}
mgns_mgxs = x // expected-error{{}}
mgns_ngns = x // expected-error{{}}
mgns_mgns = x // expected-error{{}}
mgns_ngms = x // expected-error{{}}
mgns_mgms = x // expected-error{{}}
ngms_ngxs = x // expected-error{{}}
ngms_mgxs = x // expected-error{{}}
ngms_ngns = x
// FIXME: This ought to be allowed because it's a pure set, so the mutating
// get should not come into play.
ngms_mgns = x // expected-error{{cannot use mutating getter}}
ngms_ngms = x // expected-error{{}}
ngms_mgms = x // expected-error{{}}
mgms_ngxs = x // expected-error{{}}
mgms_mgxs = x // expected-error{{}}
mgms_ngns = x // expected-error{{}}
mgms_mgns = x // expected-error{{}}
mgms_ngms = x // expected-error{{}}
mgms_mgms = x // expected-error{{}}
}
mutating func mutatingContext(x: Int) {
_ = ngxs_ngxs
// _ = ngxs_mgxs
_ = ngxs_ngns
// _ = ngxs_mgns
_ = ngxs_ngms
// _ = ngxs_mgms
_ = mgxs_ngxs
// _ = mgxs_mgxs
_ = mgxs_ngns
// _ = mgxs_mgns
_ = mgxs_ngms
// _ = mgxs_mgms
_ = ngns_ngxs
_ = ngns_mgxs
_ = ngns_ngns
_ = ngns_mgns
_ = ngns_ngms
_ = ngns_mgms
_ = mgns_ngxs
_ = mgns_mgxs
_ = mgns_ngns
_ = mgns_mgns
_ = mgns_ngms
_ = mgns_mgms
_ = ngms_ngxs
_ = ngms_mgxs
_ = ngms_ngns
_ = ngms_mgns
_ = ngms_ngms
_ = ngms_mgms
_ = mgms_ngxs
_ = mgms_mgxs
_ = mgms_ngns
_ = mgms_mgns
_ = mgms_ngms
_ = mgms_mgms
////
ngxs_ngxs = x // expected-error{{}}
// ngxs_mgxs = x
ngxs_ngns = x
// ngxs_mgns = x
ngxs_ngms = x // expected-error{{}}
// ngxs_mgms = x
mgxs_ngxs = x // expected-error{{}}
// mgxs_mgxs = x
mgxs_ngns = x
// mgxs_mgns = x
mgxs_ngms = x // expected-error{{}}
// mgxs_mgms = x
ngns_ngxs = x // expected-error{{}}
ngns_mgxs = x // expected-error{{}}
ngns_ngns = x
ngns_mgns = x
ngns_ngms = x
ngns_mgms = x
mgns_ngxs = x // expected-error{{}}
mgns_mgxs = x // expected-error{{}}
mgns_ngns = x
mgns_mgns = x
mgns_ngms = x
mgns_mgms = x
ngms_ngxs = x // expected-error{{}}
ngms_mgxs = x // expected-error{{}}
ngms_ngns = x
ngms_mgns = x
ngms_ngms = x
ngms_mgms = x
mgms_ngxs = x // expected-error{{}}
mgms_mgxs = x // expected-error{{}}
mgms_ngns = x
mgms_mgns = x
mgms_ngms = x
mgms_mgms = x
}
}
// rdar://problem/54184846 - crash while trying to retrieve wrapper info on l-value base type
func test_missing_method_with_lvalue_base() {
@propertyWrapper
struct Ref<T> {
var wrappedValue: T
}
struct S<T> where T: RandomAccessCollection, T.Element: Equatable {
@Ref var v: T.Element
init(items: T, v: Ref<T.Element>) {
self.v.binding = v // expected-error {{value of type 'T.Element' has no member 'binding'}}
}
}
}
// SR-11288
// Look into the protocols that the type conforms to
// typealias as propertyWrapper //
@propertyWrapper
struct SR_11288_S0 {
var wrappedValue: Int
}
protocol SR_11288_P1 {
typealias SR_11288_Wrapper1 = SR_11288_S0
}
struct SR_11288_S1: SR_11288_P1 {
@SR_11288_Wrapper1 var answer = 42 // Okay
}
// associatedtype as propertyWrapper //
protocol SR_11288_P2 {
associatedtype SR_11288_Wrapper2 = SR_11288_S0
}
struct SR_11288_S2: SR_11288_P2 {
@SR_11288_Wrapper2 var answer = 42 // expected-error {{unknown attribute 'SR_11288_Wrapper2'}}
}
protocol SR_11288_P3 {
associatedtype SR_11288_Wrapper3
}
struct SR_11288_S3: SR_11288_P3 {
typealias SR_11288_Wrapper3 = SR_11288_S0
@SR_11288_Wrapper3 var answer = 42 // Okay
}
// typealias as propertyWrapper in a constrained protocol extension //
protocol SR_11288_P4 {}
extension SR_11288_P4 where Self: AnyObject {
typealias SR_11288_Wrapper4 = SR_11288_S0
}
struct SR_11288_S4: SR_11288_P4 {
@SR_11288_Wrapper4 var answer = 42 // expected-error 2 {{'SR_11288_S4.SR_11288_Wrapper4.Type' (aka 'SR_11288_S0.Type') requires that 'SR_11288_S4' conform to 'AnyObject'}}
}
class SR_11288_C0: SR_11288_P4 {
@SR_11288_Wrapper4 var answer = 42 // Okay
}
// typealias as propertyWrapper in a generic type //
protocol SR_11288_P5 {
typealias SR_11288_Wrapper5 = SR_11288_S0
}
struct SR_11288_S5<T>: SR_11288_P5 {
@SR_11288_Wrapper5 var answer = 42 // Okay
}
// SR-11393
protocol Copyable: AnyObject {
func copy() -> Self
}
@propertyWrapper
struct CopyOnWrite<Value: Copyable> {
init(wrappedValue: Value) {
self.wrappedValue = wrappedValue
}
var wrappedValue: Value
var projectedValue: Value {
mutating get {
if !isKnownUniquelyReferenced(&wrappedValue) {
wrappedValue = wrappedValue.copy()
}
return wrappedValue
}
set {
wrappedValue = newValue
}
}
}
final class CopyOnWriteTest: Copyable {
let a: Int
init(a: Int) {
self.a = a
}
func copy() -> Self {
Self.init(a: a)
}
}
struct CopyOnWriteDemo1 {
@CopyOnWrite var a = CopyOnWriteTest(a: 3)
func foo() { // expected-note{{mark method 'mutating' to make 'self' mutable}}
_ = $a // expected-error{{cannot use mutating getter on immutable value: 'self' is immutable}}
}
}
@propertyWrapper
struct NonMutatingProjectedValueSetWrapper<Value> {
var wrappedValue: Value
var projectedValue: Value {
get { wrappedValue }
nonmutating set { }
}
}
struct UseNonMutatingProjectedValueSet {
@NonMutatingProjectedValueSetWrapper var x = 17
func test() { // expected-note{{mark method 'mutating' to make 'self' mutable}}
$x = 42 // okay
x = 42 // expected-error{{cannot assign to property: 'self' is immutable}}
}
}
// SR-11478
@propertyWrapper
struct SR_11478_W<Value> {
var wrappedValue: Value
}
class SR_11478_C1 {
@SR_11478_W static var bool1: Bool = true // Ok
@SR_11478_W class var bool2: Bool = true // expected-error {{class stored properties not supported in classes; did you mean 'static'?}}
@SR_11478_W class final var bool3: Bool = true // expected-error {{class stored properties not supported in classes; did you mean 'static'?}}
}
final class SR_11478_C2 {
@SR_11478_W static var bool1: Bool = true // Ok
@SR_11478_W class var bool2: Bool = true // expected-error {{class stored properties not supported in classes; did you mean 'static'?}}
@SR_11478_W class final var bool3: Bool = true // expected-error {{class stored properties not supported in classes; did you mean 'static'?}}
}
// SR-11381
@propertyWrapper
struct SR_11381_W<T> {
init(wrappedValue: T) {}
var wrappedValue: T {
fatalError()
}
}
struct SR_11381_S {
@SR_11381_W var foo: Int = nil // expected-error {{'nil' is not compatible with expected argument type 'Int'}}
}
// rdar://problem/53349209 - regression in property wrapper inference
struct Concrete1: P {}
@propertyWrapper struct ConcreteWrapper {
var wrappedValue: Concrete1 { get { fatalError() } }
}
struct TestConcrete1 {
@ConcreteWrapper() var s1
func f() {
// Good:
let _: P = self.s1
// Bad:
self.g(s1: self.s1)
// Ugly:
self.g(s1: self.s1 as P)
}
func g(s1: P) {
// ...
}
}