blob: e048638f3e085438a4d1bba2e4e61e57c253b870 [file] [log] [blame]
// RUN: %target-typecheck-verify-swift -parse-stdlib
import Swift
func someValidAddress<T>() -> UnsafeMutablePointer<T> { fatalError() }
func someValidAddress<T>() -> UnsafePointer<T> { fatalError() }
struct ValidImmutable {
var base: UnsafePointer<Int>
subscript(index: Int) -> Int {
unsafeAddress {
return base
}
}
}
struct ValidBoth {
var base: UnsafeMutablePointer<Int>
subscript(index: Int) -> Int {
unsafeAddress {
return UnsafePointer(base)
}
unsafeMutableAddress {
return base
}
}
}
struct OnlyMutable {
var base: UnsafeMutablePointer<Int>
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<Int>
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<Int>' to return type 'UnsafePointer<Int>'}}
}
}
}
struct RepeatedMutable {
var base: UnsafeMutablePointer<Int>
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<Int>
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<Int>' has no member 'get'}}
}
}
}
struct AddressorAndSet {
var base: UnsafePointer<Int>
subscript(index: Int) -> Int {
unsafeAddress {
return base
}
set {
}
}
}
struct MutableAddressorAndGet {
var base: UnsafeMutablePointer<Int>
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}}
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}}
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}}
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}}
}
}