Static String extensions don't work


(Marko Havu) #1

Consider the following code:

extension String {
    static let foo = NSLocalizedString("Foo", "Some localized string")
    // This requires a named parameter nowadays:
    // static let foo = NSLocalizedString("Foo", comment:"Some localized string")
    // That is how it is defined in SBL in Foundation_Extension.swift,
    // but for some reason it doesn't work.
}

func stringFunc(_ string: String) {
    print(string)
}

stringFunc(.foo)  // E: Parameter 1 is "Implicit member", should be "String", in call to func Test.stringFunc(_ string: String)
stringFunc(String.foo)  // E: No static member "foo" on type "String"

For some reason, the compiler can’t find String.foo either implicitly or explicitly.


(RemObjects) #2

Thanks, logged as bugs://81823


(marc hoffman) #3

FWIW, I’m not sure how the first one is supposed to work? how should the compiler know what scope to look in for “.foo”? the second part definitely looks like a bug.


(Marko Havu) #4

The first one works on Apple’s compiler. I guess the implicit type is inferred similarly to enums: if the argument is expected to be of certain type, you don’t need to explicitly give it to access its members.


(marc hoffman) #5

right, but the argument expects. string. any type can define a “foo” property that returns a string and would be viable for the call? eg:

extension String {
    static let foo = NSLocalizedString("Foo", "Some localized string")
}

extension Int {
    static let foo = NSLocalizedString("Foo", "Some localized string")
}

stringFunc(.foo)  // which .foo would to call?

(Marko Havu) #6

I don’t think anyone would expect Int.foo to be used if the argument is of type String.


(marc hoffman) #7

Why not? it’s a String, just as String.foo.

why would the type of the argument imply the scope for a member that’ will return that argument? that makes no logical sense to me…


(Marko Havu) #8

Consider this:

enum RightEnum {
    case no
    case yes
}

enum WrongEnum {
    case no
    case yes
}

func enumFunc(_ param: RightEnum) {
    // Do something
}

enumFunc(.yes)

Don’t you think RightEnum.yes is the only logical call here? By extension, String.foo is the logical option in the previous example. Implicit types should always expand to the literal type of the argument. If String.foo didn’t exist, I still wouldn’t expect Int.foo to be called.


(marc hoffman) #9

Well, yes, coz its an enum, and ends all have a fixed type. I don’t really see the same logic extending to "any method that returns the right type, and just happens to be defined on that same type).

But that’s just my own personal opinion.

If Swift allows it and thats the rues it uses, then we’ll need to fix it to support that, regardless of what I think of it ;). it’s covered by the issue I logged earlier.


(RemObjects) #10

bugs://81823 got closed with status fixed.