blob: 3f16fd5da5574183a99923eac2d1fa07b031ca74 [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 must provide either a getter or 'address' if it provides 'mutableAddress'}}
return base
}
}
}
struct Repeated {
var base: UnsafeMutablePointer<Int>
subscript(index: Int) -> Int {
unsafeAddress { // expected-note {{previous definition}}
return UnsafePointer(base)
}
unsafeAddress { // expected-error {{duplicate definition}}
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 {{duplicate definition}}
return base
}
}
}
struct AddressorAndGet {
var base: UnsafePointer<Int>
subscript(index: Int) -> Int {
unsafeAddress { // expected-error {{subscript cannot provide both 'address' and a getter}}
return base
}
get {
return base.get()
}
}
}
struct AddressorAndSet {
var base: UnsafePointer<Int>
subscript(index: Int) -> Int {
unsafeAddress {
return base
}
set { // expected-error {{subscript cannot provide both 'address' and a setter; use an ordinary getter instead}}
}
}
}
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() }
}
}
// FIXME: Actually plumb the work to fix the grammar in these
// diagnostics if/when we productize them. ("a addressor")
struct RedundantAddressors1 {
var owner : Builtin.NativeObject
subscript(index: Int) -> Int {
unsafeAddress { return someValidAddress() } // expected-note {{previous definition of addressor is here}}
addressWithNativeOwner { return (someValidAddress(), owner) } // expected-error {{subscript already has a addressor}}
}
}
struct RedundantAddressors2 {
var owner : Builtin.NativeObject
subscript(index: Int) -> Int {
unsafeAddress { return someValidAddress() } // expected-note {{previous definition of addressor is here}}
addressWithPinnedNativeOwner { return (someValidAddress(), owner) } // expected-error {{subscript already has a addressor}}
}
}
struct RedundantAddressors3 {
var owner : Builtin.NativeObject
subscript(index: Int) -> Int {
addressWithNativeOwner { return someValidAddress() } // expected-note {{previous definition of addressor is here}}
addressWithPinnedNativeOwner { return (someValidAddress(), owner) } // expected-error {{subscript already has a addressor}}
}
}
struct RedundantMutableAddressors1 {
var owner : Builtin.NativeObject
subscript(index: Int) -> Int {
unsafeAddress { return someValidAddress() }
unsafeMutableAddress { return someValidAddress() } // expected-note {{previous definition of mutable addressor is here}}
mutableAddressWithNativeOwner { return (someValidAddress(), owner) } // expected-error {{subscript already has a mutable addressor}}
}
}
struct RedundantMutableAddressors2 {
var owner : Builtin.NativeObject
subscript(index: Int) -> Int {
unsafeAddress { return someValidAddress() }
unsafeMutableAddress { return someValidAddress() } // expected-note {{previous definition of mutable addressor is here}}
mutableAddressWithNativeOwner { return (someValidAddress(), owner) } // expected-error {{subscript already has a mutable addressor}}
}
}
struct RedundantMutableAddressors3 {
var owner : Builtin.NativeObject
subscript(index: Int) -> Int {
unsafeAddress { return someValidAddress() }
unsafeMutableAddress { return someValidAddress() } // expected-note {{previous definition of mutable addressor is here}}
mutableAddressWithNativeOwner { return (someValidAddress(), owner) } // expected-error {{subscript already has a mutable addressor}}
}
}