mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Objective-C subscripts don't have special declarations like properties; they're just specially-named methods (or method pairs), and we have to make an independent SubscriptDecl in Swift. This means that when a subclass wants to make a subscript settable, they just add the appropriately-named setter method. Swift handled this by detecting when the getter and setter weren't declared in the same type, and assuming this meant it was a subclass adding a setter. Unfortunately, the same condition /also/ picked up the case where the getter (and only the getter) is /redeclared/ in a subclass (perhaps to add an attribute), and the new subscript was getting added to the base class instead of the subclass. The fix relies on the fact that the original decl we provide is what we use to look up the other accessor. If the getter and setter are in different types, whichever one we started with must be the more-derived one. So the final change is just "did we start with the setter?" rather than "is there a setter at all?". I'm not sure why this is only just now causing problems, given that we seem to have been getting this wrong for years, but it definitely /was/ wrong and now it's not. rdar://problem/36033356
72 lines
1.5 KiB
Swift
72 lines
1.5 KiB
Swift
// RUN: %empty-directory(%t)
|
|
// RUN: %build-clang-importer-objc-overlays
|
|
|
|
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) -emit-sil -I %S/Inputs/custom-modules %s -verify
|
|
|
|
// REQUIRES: objc_interop
|
|
|
|
import ObjCSubscripts
|
|
|
|
// rdar://problem/19772357
|
|
class KeySubscript1Sub : KeySubscript1 {
|
|
override subscript (str: String!) -> Any! {
|
|
get { return self }
|
|
set { }
|
|
}
|
|
}
|
|
|
|
class KeySubscript2Sub : KeySubscript2 {
|
|
override subscript (str: String) -> Any? {
|
|
get { return self }
|
|
set { }
|
|
}
|
|
}
|
|
|
|
class KeySubscript3Sub : KeySubscript3 {
|
|
override subscript (str: String) -> String? {
|
|
get { return str }
|
|
set { }
|
|
}
|
|
}
|
|
|
|
class KeySubscript4Sub : KeySubscript4 {
|
|
override subscript (str: [Any]) -> String? {
|
|
get { return nil }
|
|
set { }
|
|
}
|
|
}
|
|
|
|
class ConformsToKeySubscriptProto1 : KeySubscriptProto1 {
|
|
@objc subscript (s: String) -> String? {
|
|
return s
|
|
}
|
|
}
|
|
|
|
class ConformsToKeySubscriptProto2 : KeySubscriptProto2 {
|
|
@objc subscript (s: String!) -> String! {
|
|
get { return s }
|
|
set { }
|
|
}
|
|
}
|
|
|
|
func testOverridesWithoutBase(
|
|
o1: KeySubscriptOverrideGetter,
|
|
o2: KeySubscriptOverrideSetter,
|
|
o3: KeySubscriptReversedOverrideGetter,
|
|
o4: KeySubscriptReversedOverrideSetter
|
|
) {
|
|
// rdar://problem/36033356 failed specifically when the base class was never
|
|
// subscripted, so please don't mention the base classes here.
|
|
_ = o1["abc"]
|
|
o1["abc"] = "xyz"
|
|
|
|
_ = o2["abc"]
|
|
o2["abc"] = "xyz"
|
|
|
|
_ = o3["abc"]
|
|
o3["abc"] = "xyz"
|
|
|
|
_ = o4["abc"]
|
|
o4["abc"] = "xyz"
|
|
}
|