// RUN: %target-typecheck-verify-swift -parse-stdlib import Swift func someValidAddress() -> UnsafeMutablePointer { fatalError() } func someValidAddress() -> UnsafePointer { fatalError() } struct ValidImmutable { var base: UnsafePointer subscript(index: Int) -> Int { unsafeAddress { return base } } } struct ValidBoth { var base: UnsafeMutablePointer subscript(index: Int) -> Int { unsafeAddress { return UnsafePointer(base) } unsafeMutableAddress { return base } } } struct OnlyMutable { var base: UnsafeMutablePointer subscript(index: Int) -> Int { unsafeMutableAddress { // expected-error {{subscript with a mutable addressor must also have a getter, addressor, or 'read' accessor}} return base } } } struct Repeated { var base: UnsafeMutablePointer subscript(index: Int) -> Int { unsafeAddress { // expected-note {{previous definition}} return UnsafePointer(base) } unsafeAddress { // expected-error {{subscript already has an addressor}} return base // expected-error {{cannot convert return expression of type 'UnsafeMutablePointer' to return type 'UnsafePointer'}} } } } struct RepeatedMutable { var base: UnsafeMutablePointer subscript(index: Int) -> Int { unsafeAddress { return UnsafePointer(base) } unsafeMutableAddress { // expected-note {{previous definition}} return base } unsafeMutableAddress { // expected-error {{subscript already has a mutable addressor}} return base } } } struct AddressorAndGet { var base: UnsafePointer subscript(index: Int) -> Int { unsafeAddress { // expected-error {{subscript cannot provide both an addressor and a getter}} return base } get { // expected-note {{getter defined here}} return base.get() // expected-error {{value of type 'UnsafePointer' has no member 'get'}} } } } struct AddressorAndSet { var base: UnsafePointer subscript(index: Int) -> Int { unsafeAddress { return base } set { } } } struct MutableAddressorAndGet { var base: UnsafeMutablePointer subscript(index: Int) -> Int { unsafeMutableAddress { return base } get { return base.pointee } } } protocol HasImmutableSubscript { subscript(index: Int) -> Int { get } } protocol HasMutableSubscript { subscript(index: Int) -> Int { get set } // expected-note {{protocol requires}} } struct DisobedientImmutableAddressor: HasMutableSubscript { // expected-error {{does not conform}} expected-note {{add stubs for conformance}} subscript(index: Int) -> Int { // expected-note {{candidate is not settable}} unsafeAddress { return someValidAddress() } } } struct ObedientImmutableAddressor: HasImmutableSubscript { subscript(index: Int) -> Int { unsafeAddress { return someValidAddress() } } } struct ObedientMutableAddressor: HasMutableSubscript { subscript(index: Int) -> Int { unsafeAddress { return someValidAddress() } unsafeMutableAddress { return someValidAddress() } } } protocol HasMutatingImmutableSubscript { subscript(index: Int) -> Int { mutating get } } protocol HasMutatingMutableSubscript { subscript(index: Int) -> Int { mutating get set } // expected-note {{protocol requires}} } // We allow mutating accessor requirements to be implemented by non-mutating accessors. struct DisobedientImmutableAddressor2: HasMutatingMutableSubscript { // expected-error {{does not conform}} expected-note {{add stubs for conformance}} subscript(index: Int) -> Int { // expected-note {{candidate is not settable}} unsafeAddress { return someValidAddress() } } } struct ObedientImmutableAddressor2: HasMutatingImmutableSubscript { subscript(index: Int) -> Int { unsafeAddress { return someValidAddress() } } } struct ObedientMutableAddressor2: HasMutatingMutableSubscript { subscript(index: Int) -> Int { unsafeAddress { return someValidAddress() } unsafeMutableAddress { return someValidAddress() } } } // Non-mutating accessor requirements cannot be implemented by mutating accessors. protocol HasNonMutatingMutableSubscript { subscript(index: Int) -> Int { get nonmutating set } // expected-note {{protocol requires}} } struct DisobedientNonMutatingMutableAddressor: HasNonMutatingMutableSubscript { // expected-error {{does not conform}} expected-note {{add stubs for conformance}} subscript(index: Int) -> Int { unsafeAddress { return someValidAddress() } unsafeMutableAddress { return someValidAddress() } // expected-note {{candidate is marked 'mutating' but protocol does not allow it}} } } struct ObedientNonMutatingMutableAddressor: HasNonMutatingMutableSubscript { subscript(index: Int) -> Int { unsafeAddress { return someValidAddress() } nonmutating unsafeMutableAddress { return someValidAddress() } } } struct RedundantAddressors { var owner : Builtin.NativeObject subscript(index: Int) -> Int { unsafeAddress { return someValidAddress() } // expected-note {{previous definition of addressor here}} unsafeAddress { return someValidAddress() } // expected-error {{subscript already has an addressor}} } } struct RedundantMutableAddressors { var owner : Builtin.NativeObject subscript(index: Int) -> Int { unsafeAddress { return someValidAddress() } unsafeMutableAddress { return someValidAddress() } // expected-note {{previous definition of mutable addressor here}} unsafeMutableAddress { return someValidAddress() } // expected-error {{subscript already has a mutable addressor}} } }