1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240
|
// RUN: %target-typecheck-verify-swift
// Simple subscript of arrays:
func simpleSubscript(_ array: [Float], x: Int) -> Float {
_ = array[x]
return array[x]
}
// Subscript of archetype.
protocol IntToStringSubscript {
subscript (i : Int) -> String { get }
}
class FauxDictionary {
subscript (i : Int) -> String {
get {
return String(i)
}
}
}
func archetypeSubscript<T : IntToStringSubscript, U : FauxDictionary>(_ t: T, u: U)
-> String {
// Subscript an archetype.
if false { return t[17] }
// Subscript an archetype for which the subscript operator is in a base class.
return u[17]
}
// Subscript of existential type.
func existentialSubscript(_ a: IntToStringSubscript) -> String {
return a[17]
}
// Static of above:
// Subscript of archetype.
protocol IntToStringStaticSubscript {
static subscript (i : Int) -> String { get }
}
class FauxStaticDictionary {
static subscript (i : Int) -> String {
get {
return String(i)
}
}
}
func archetypeStaticSubscript<
T : IntToStringStaticSubscript, U : FauxStaticDictionary
>(_ t: T.Type, u: U.Type) -> String {
// Subscript an archetype.
if false { return t[17] }
// Subscript an archetype for which the subscript operator is in a base class.
return u[17]
}
// Subscript of existential type.
func existentialStaticSubscript(
_ a: IntToStringStaticSubscript.Type
) -> String {
return a[17]
}
class MyDictionary<Key, Value> {
subscript (key : Key) -> Value {
get {}
}
}
class MyStringToInt<T> : MyDictionary<String, Int> { }
// Subscript of generic type.
func genericSubscript<T>(_ t: T,
array: Array<Int>,
i2i: MyDictionary<Int, Int>,
t2i: MyDictionary<T, Int>,
s2i: MyStringToInt<()>) -> Int {
if true { return array[5] }
if true { return i2i[5] }
if true { return t2i[t] }
return s2i["hello"]
}
// <rdar://problem/21364448> QoI: Poor error message for ambiguous subscript call
extension String {
func number() -> Int { } // expected-note {{found this candidate}}
func number() -> Double { } // expected-note {{found this candidate}}
}
let _ = "a".number // expected-error {{ambiguous use of 'number()'}}
extension Int {
subscript(key: String) -> Int { get {} } // expected-note {{found this candidate}}
subscript(key: String) -> Double { get {} } // expected-note {{found this candidate}}
}
let _ = 1["1"] // expected-error {{ambiguous use of 'subscript(_:)'}}
let squares = [ 1, 2, 3 ].reduce([:]) { (dict, n) in
var dict = dict
dict[n] = n * n
return dict
}
// <rdar://problem/23670252> QoI: Misleading error message when assigning a value from [String : AnyObject]
func r23670252(_ dictionary: [String : AnyObject], someObject: AnyObject) {
let color : String?
color = dictionary["color"] // expected-error {{cannot assign value of type 'AnyObject?' to type 'String?'}}
_ = color
}
// https://github.com/apple/swift/issues/43333
// Type mismatch reported as extraneous parameter
do {
struct S {
subscript(b : Int) -> Int
{ return 0 }
subscript(a a : UInt) -> Int { return 0 }
}
S()[a: Int()] // expected-error {{cannot convert value of type 'Int' to expected argument type 'UInt'}}
}
// rdar://problem/25601561 - Qol: Bad diagnostic for failed assignment from Any to more specific type
struct S_r25601561 {
func value() -> Any? { return "hi" }
}
class C_r25601561 {
var a: [S_r25601561?] = []
func test(i: Int) -> String {
let s: String = a[i]!.value()! // expected-error {{cannot convert value of type 'Any' to specified type 'String'}}
return s
}
}
// rdar://problem/31977679 - Misleading diagnostics when using subscript with incorrect argument
func r31977679_1(_ properties: [String: String]) -> Any? {
return properties[0] // expected-error {{cannot convert value of type 'Int' to expected argument type 'String'}}
}
func r31977679_2(_ properties: [String: String]) -> Any? {
return properties["foo"] // Ok
}
// rdar://problem/45819956 - inout-to-pointer in a subscript arg could use a better diagnostic
func rdar_45819956() {
struct S {
subscript(takesPtr ptr: UnsafeMutablePointer<Int>) -> Int {
get { return 0 }
}
}
let s = S()
var i = 0
// TODO: It should be possible to suggest `withUnsafe[Mutable]Pointer` as a fix-it
_ = s[takesPtr: &i]
// expected-error@-1 {{cannot pass an inout argument to a subscript; use 'withUnsafeMutablePointer' to explicitly convert argument to a pointer}}
}
// rdar://problem/45825806
// https://github.com/apple/swift/issues/49738
// Array-to-pointer in subscript arg crashes compiler
do {
struct S {
subscript(takesPtr ptr: UnsafePointer<Int>) -> Int {
get { return 0 }
}
}
let s = S()
_ = s[takesPtr: [1, 2, 3]] // Ok
}
func test_generic_subscript_requirements_mismatch_diagnostics() {
struct S {
subscript<T: StringProtocol>(_: T) -> T { // expected-note {{where 'T' = 'Int'}}
fatalError()
}
subscript<T, U: Collection>(v v: [T]) -> U where U.Element == T {
fatalError()
}
subscript<T: Collection>(number num: T) -> Int where T.Element: BinaryInteger {
// expected-note@-1 {{'T.Element' = 'String'}}
return 42
}
}
var s = S()
_ = s[42] // expected-error {{subscript 'subscript(_:)' requires that 'Int' conform to 'StringProtocol'}}
var arr: [Int] = []
let _: [String] = s[v: arr] // expected-error {{cannot convert value of type '[Int]' to expected argument type '[String]'}}
// expected-note@-1 {{arguments to generic parameter 'Element' ('Int' and 'String') are expected to be equal}}
s[number: ["hello"]] // expected-error {{subscript 'subscript(number:)' requires that 'String' conform to 'BinaryInteger'}}
}
// rdar://61084565 - infinite recursion in dynamic member lookup
func rdar61084565() {
@dynamicMemberLookup
struct Foo {
subscript(dynamicMember _: KeyPath<Foo, Int>) -> Int {
return 42
}
}
let a = Foo()
a[] // expected-error {{value of type 'Foo' has no subscripts}}
}
// Note: In Swift >= 6 mode this would become an error.
func test_subscript_accepts_type_name_argument() {
struct A {
subscript(a: A.Type) -> Int { get { 42 } }
}
func test(a: A, optA: A?) {
let _ = a[A] // expected-warning {{expected member name or constructor call after type name; this will be an error in Swift 6}}
// expected-note@-1 {{add arguments after the type to construct a value of the type}} {{16-16=()}}
// expected-note@-2 {{use '.self' to reference the type object}} {{16-16=.self}}
let _ = optA?[A] // expected-warning {{expected member name or constructor call after type name; this will be an error in Swift 6}}
// expected-note@-1 {{add arguments after the type to construct a value of the type}} {{20-20=()}}
// expected-note@-2 {{use '.self' to reference the type object}} {{20-20=.self}}
}
}
|