blob: 3af6e6008989846fa535d3ea0aa3954c5bfeaca0 [file] [log] [blame]
// RUN: %target-typecheck-verify-swift
struct X { } // expected-note * {{did you mean 'X'?}}
// Simple examples
struct X1 {
var stored : Int
subscript (i : Int) -> Int {
get {
return stored
}
mutating
set {
stored = newValue
}
}
}
struct X2 {
var stored : Int
subscript (i : Int) -> Int {
get {
return stored + i
}
set(v) {
stored = v - i
}
}
}
struct X3 {
var stored : Int
subscript (_ : Int) -> Int {
get {
return stored
}
set(v) {
stored = v
}
}
}
struct X4 {
var stored : Int
subscript (i : Int, j : Int) -> Int {
get {
return stored + i + j
}
set(v) {
stored = v + i - j
}
}
}
// Semantic errors
struct Y1 {
var x : X
subscript(i: Int) -> Int {
get {
return x // expected-error{{cannot convert return expression of type 'X' to return type 'Int'}}
}
set {
x = newValue // expected-error{{cannot assign value of type 'Int' to type 'X'}}
}
}
}
struct Y2 {
subscript(idx: Int) -> TypoType { // expected-error {{use of undeclared type 'TypoType'}}
get { repeat {} while true }
set {}
}
}
class Y3 {
subscript(idx: Int) -> TypoType { // expected-error {{use of undeclared type 'TypoType'}}
get { repeat {} while true }
set {}
}
}
protocol ProtocolGetSet0 {
subscript(i: Int) -> Int {} // expected-error {{subscript declarations must have a getter}}
}
protocol ProtocolGetSet1 {
subscript(i: Int) -> Int { get }
}
protocol ProtocolGetSet2 {
subscript(i: Int) -> Int { set } // expected-error {{subscript with a setter must also have a getter}}
}
protocol ProtocolGetSet3 {
subscript(i: Int) -> Int { get set }
}
protocol ProtocolGetSet4 {
subscript(i: Int) -> Int { set get }
}
protocol ProtocolWillSetDidSet1 {
subscript(i: Int) -> Int { willSet } // expected-error {{expected get or set in a protocol property}} expected-error {{subscript declarations must have a getter}}
}
protocol ProtocolWillSetDidSet2 {
subscript(i: Int) -> Int { didSet } // expected-error {{expected get or set in a protocol property}} expected-error {{subscript declarations must have a getter}}
}
protocol ProtocolWillSetDidSet3 {
subscript(i: Int) -> Int { willSet didSet } // expected-error 2 {{expected get or set in a protocol property}} expected-error {{subscript declarations must have a getter}}
}
protocol ProtocolWillSetDidSet4 {
subscript(i: Int) -> Int { didSet willSet } // expected-error 2 {{expected get or set in a protocol property}} expected-error {{subscript declarations must have a getter}}
}
class DidSetInSubscript {
subscript(_: Int) -> Int {
didSet { // expected-error {{'didSet' is not allowed in subscripts}}
print("eek")
}
get {}
}
}
class WillSetInSubscript {
subscript(_: Int) -> Int {
willSet { // expected-error {{'willSet' is not allowed in subscripts}}
print("eek")
}
get {}
}
}
subscript(i: Int) -> Int { // expected-error{{'subscript' functions may only be declared within a type}}
get {}
}
func f() { // expected-note * {{did you mean 'f'?}}
subscript (i: Int) -> Int { // expected-error{{'subscript' functions may only be declared within a type}}
get {}
}
}
struct NoSubscript { }
struct OverloadedSubscript {
subscript(i: Int) -> Int {
get {
return i
}
set {}
}
subscript(i: Int, j: Int) -> Int {
get { return i }
set {}
}
}
struct RetOverloadedSubscript {
subscript(i: Int) -> Int { // expected-note {{found this candidate}}
get { return i }
set {}
}
subscript(i: Int) -> Float { // expected-note {{found this candidate}}
get { return Float(i) }
set {}
}
}
struct MissingGetterSubscript1 {
subscript (i : Int) -> Int {
} // expected-error {{subscript must have accessors specified}}
}
struct MissingGetterSubscript2 {
subscript (i : Int, j : Int) -> Int {
set {} // expected-error{{subscript with a setter must also have a getter}}
}
}
func test_subscript(_ x2: inout X2, i: Int, j: Int, value: inout Int, no: NoSubscript,
ovl: inout OverloadedSubscript, ret: inout RetOverloadedSubscript) {
no[i] = value // expected-error{{value of type 'NoSubscript' has no subscripts}}
value = x2[i]
x2[i] = value
value = ovl[i]
ovl[i] = value
value = ovl[i, j]
ovl[i, j] = value
value = ovl[(i, j, i)] // expected-error{{cannot convert value of type '(Int, Int, Int)' to expected argument type 'Int'}}
ret[i] // expected-error{{ambiguous use of 'subscript(_:)'}}
value = ret[i]
ret[i] = value
}
func subscript_rvalue_materialize(_ i: inout Int) {
i = X1(stored: 0)[i]
}
func subscript_coerce(_ fn: ([UnicodeScalar], [UnicodeScalar]) -> Bool) {}
func test_subscript_coerce() {
subscript_coerce({ $0[$0.count-1] < $1[$1.count-1] })
}
struct no_index {
subscript () -> Int { return 42 }
func test() -> Int {
return self[]
}
}
struct tuple_index {
subscript (x : Int, y : Int) -> (Int, Int) { return (x, y) }
func test() -> (Int, Int) {
return self[123, 456]
}
}
struct MutableComputedGetter {
var value: Int
subscript(index: Int) -> Int {
value = 5 // expected-error{{cannot assign to property: 'self' is immutable}}
return 5
}
var getValue : Int {
value = 5 // expected-error {{cannot assign to property: 'self' is immutable}}
return 5
}
}
struct MutableSubscriptInGetter {
var value: Int
subscript(index: Int) -> Int {
get { // expected-note {{mark accessor 'mutating' to make 'self' mutable}}
value = 5 // expected-error{{cannot assign to property: 'self' is immutable}}
return 5
}
}
}
protocol Protocol {}
protocol RefinedProtocol: Protocol {}
class SuperClass {}
class SubClass: SuperClass {}
class SubSubClass: SubClass {}
class ClassConformingToProtocol: Protocol {}
class ClassConformingToRefinedProtocol: RefinedProtocol {}
struct GenSubscriptFixitTest {
subscript<T>(_ arg: T) -> Bool { return true } // expected-note {{declared here}}
}
func testGenSubscriptFixit(_ s0: GenSubscriptFixitTest) {
_ = s0.subscript("hello")
// expected-error@-1 {{value of type 'GenSubscriptFixitTest' has no property or method named 'subscript'; did you mean to use the subscript operator?}} {{9-10=}} {{10-19=}} {{19-20=[}} {{27-28=]}}
}
struct SubscriptTest1 {
subscript(keyword:String) -> Bool { return true }
// expected-note@-1 4 {{found this candidate}}
subscript(keyword:String) -> String? {return nil }
// expected-note@-1 4 {{found this candidate}}
subscript(arg: SubClass) -> Bool { return true } // expected-note {{declared here}}
subscript(arg: Protocol) -> Bool { return true } // expected-note 2 {{declared here}}
subscript(arg: (foo: Bool, bar: (Int, baz: SubClass)), arg2: String) -> Bool { return true }
// expected-note@-1 2 {{declared here}}
}
func testSubscript1(_ s1 : SubscriptTest1) {
let _ : Int = s1["hello"] // expected-error {{ambiguous subscript with base type 'SubscriptTest1' and index type 'String'}}
if s1["hello"] {}
_ = s1.subscript((true, (5, SubClass())), "hello")
// expected-error@-1 {{value of type 'SubscriptTest1' has no property or method named 'subscript'; did you mean to use the subscript operator?}} {{9-10=}} {{10-19=}} {{19-20=[}} {{52-53=]}}
_ = s1.subscript((true, (5, baz: SubSubClass())), "hello")
// expected-error@-1 {{value of type 'SubscriptTest1' has no property or method named 'subscript'; did you mean to use the subscript operator?}} {{9-10=}} {{10-19=}} {{19-20=[}} {{60-61=]}}
_ = s1.subscript((fo: true, (5, baz: SubClass())), "hello")
// expected-error@-1 {{cannot convert value of type '(fo: Bool, (Int, baz: SubClass))' to expected argument type '(foo: Bool, bar: (Int, baz: SubClass))'}}
_ = s1.subscript(SubSubClass())
// expected-error@-1 {{value of type 'SubscriptTest1' has no property or method named 'subscript'; did you mean to use the subscript operator?}} {{9-10=}} {{10-19=}} {{19-20=[}} {{33-34=]}}
_ = s1.subscript(ClassConformingToProtocol())
// expected-error@-1 {{value of type 'SubscriptTest1' has no property or method named 'subscript'; did you mean to use the subscript operator?}} {{9-10=}} {{10-19=}} {{19-20=[}} {{47-48=]}}
_ = s1.subscript(ClassConformingToRefinedProtocol())
// expected-error@-1 {{value of type 'SubscriptTest1' has no property or method named 'subscript'; did you mean to use the subscript operator?}} {{9-10=}} {{10-19=}} {{19-20=[}} {{54-55=]}}
_ = s1.subscript(true)
// expected-error@-1 {{cannot invoke 'subscript' with an argument list of type '(Bool)'}}
// expected-note@-2 {{overloads for 'subscript' exist with these partially matching parameter lists: (Protocol), (String), (SubClass)}}
_ = s1.subscript(SuperClass())
// expected-error@-1 {{cannot invoke 'subscript' with an argument list of type '(SuperClass)'}}
// expected-note@-2 {{overloads for 'subscript' exist with these partially matching parameter lists: (Protocol), (String), (SubClass)}}
_ = s1.subscript("hello")
// expected-error@-1 {{value of type 'SubscriptTest1' has no property or method named 'subscript'; did you mean to use the subscript operator?}}
_ = s1.subscript("hello"
// expected-error@-1 {{value of type 'SubscriptTest1' has no property or method named 'subscript'; did you mean to use the subscript operator?}}
// expected-note@-2 {{to match this opening '('}}
let _ = s1["hello"]
// expected-error@-1 {{ambiguous use of 'subscript(_:)'}}
// expected-error@-2 {{expected ')' in expression list}}
}
struct SubscriptTest2 {
subscript(a : String, b : Int) -> Int { return 0 }
// expected-note@-1 {{declared here}}
subscript(a : String, b : String) -> Int { return 0 }
}
func testSubscript1(_ s2 : SubscriptTest2) {
_ = s2["foo"] // expected-error {{cannot subscript a value of type 'SubscriptTest2' with an argument of type 'String'}}
// expected-note @-1 {{overloads for 'subscript' exist with these partially matching parameter lists: (String, Int), (String, String)}}
let a = s2["foo", 1.0] // expected-error {{cannot subscript a value of type 'SubscriptTest2' with an argument of type '(String, Double)'}}
// expected-note @-1 {{overloads for 'subscript' exist with these partially matching parameter lists: (String, Int), (String, String)}}
_ = s2.subscript("hello", 6)
// expected-error@-1 {{value of type 'SubscriptTest2' has no property or method named 'subscript'; did you mean to use the subscript operator?}} {{9-10=}} {{10-19=}} {{19-20=[}} {{30-31=]}}
let b = s2[1, "foo"] // expected-error {{cannot convert value of type 'Int' to expected argument type 'String'}}
// rdar://problem/27449208
let v: (Int?, [Int]?) = (nil [17]) // expected-error {{cannot subscript a nil literal value}}
}
// sr-114 & rdar://22007370
class Foo {
subscript(key: String) -> String { // expected-note {{'subscript(_:)' previously declared here}}
get { a } // expected-error {{use of unresolved identifier 'a'}}
set { b } // expected-error {{use of unresolved identifier 'b'}}
}
subscript(key: String) -> String { // expected-error {{invalid redeclaration of 'subscript(_:)'}}
get { a } // expected-error {{use of unresolved identifier 'a'}}
set { b } // expected-error {{use of unresolved identifier 'b'}}
}
}
// <rdar://problem/23952125> QoI: Subscript in protocol with missing {}, better diagnostic please
protocol r23952125 {
associatedtype ItemType
var count: Int { get }
subscript(index: Int) -> ItemType // expected-error {{subscript in protocol must have explicit { get } or { get set } specifier}} {{36-36= { get <#set#> \}}}
var c : Int // expected-error {{property in protocol must have explicit { get } or { get set } specifier}} {{14-14= { get <#set#> \}}}
}
// SR-2575
struct SR2575 {
subscript() -> Int { // expected-note {{declared here}}
return 1
}
}
SR2575().subscript()
// expected-error@-1 {{value of type 'SR2575' has no property or method named 'subscript'; did you mean to use the subscript operator?}} {{9-10=}} {{10-19=}} {{19-20=[}} {{20-21=]}}
// SR-7890
struct InOutSubscripts {
subscript(x1: inout Int) -> Int { return 0 }
// expected-error@-1 {{'inout' must not be used on subscript parameters}}
subscript(x2: inout Int, y2: inout Int) -> Int { return 0 }
// expected-error@-1 2{{'inout' must not be used on subscript parameters}}
subscript(x3: (inout Int) -> ()) -> Int { return 0 } // ok
subscript(x4: (inout Int, inout Int) -> ()) -> Int { return 0 } // ok
subscript(inout x5: Int) -> Int { return 0 }
// expected-error@-1 {{'inout' before a parameter name is not allowed, place it before the parameter type instead}}
// expected-error@-2 {{'inout' must not be used on subscript parameters}}
}