Static methods are overshadowed by static properties?

Foundation's URL.ParseStrategy has a url static property and a url(scheme:…) static function. It makes sense - the former is for "fluent"-style specification of parsing parameters, the latter for simple function parameter style. Mostly just matters of preference, but sometimes one approach suits better than the other.

Yet, the latter appears to be completely unreachable…?

import Foundation

let input = "file:///Example.jpg"

try? URL(input,
         strategy: .url.scheme(.required)) // ✅

try? URL(input,
         strategy: .url(scheme: .required)) // ❌ Cannot call value
                                            //    of non-function type
                                            //    'URL.ParseStrategy'

In my mind the conflict is bogus anyway since url is not the same name as url(scheme:…), but apparently the compiler is considering only the function name prefix, not the full name?!

Why does the static function even exist if it's impossible to call it?

(it is possible to work around this by calling the init method instead)

1 Like

This compiles fine:

try? URL(input,
         strategy: URL.ParseStrategy.url(scheme: .required))

Leading dot syntax is nice but there are...complicated rules about inferring the part you're omitting that interact with overload resolution. But that isn't tantamount to the static method being uncallable.


Notably, this also compiles:

func f(_: URL.ParseStrategy) {}

f(.url(scheme: .required))

so there's some interaction here with the URL initializer that's causing things to go wrong...

1 Like

Ah, the URL initializer in question is generic over T: ParseStrategy, but the url(scheme:) static func is defined on an extension of RegexComponent. So there's no mechanism for name lookup to find the static member. (The url static var is defined in an extension on ParseStrategy.)


Huh, interesting.

But… the documentation explicitly says to use the static function the way I was trying to:

Use the dot-notation form of this method when the call point allows the use of URL.ParseStrategy. Typically, you use this with the URL initializer init(_:strategy:).

Is that what it means? I read that paragraph as saying you should use .url.scheme(...) instead of .url(scheme:...).

It does say "…of this method…", which to me means, well, that method. But I agree it's ambiguous.

Using the "fluent" style is broadly acceptable, just not as nice (IMO). It also has a lot more runtime overhead (in debug builds, at least).

Sure, "dot-notation form of this method" is delightfully unclear, but it would make more sense that a usage note tells users to call some other related API (particularly when it anticipates difficulties with overload resolution with this method as shown here that the other API doesn't have) than it would for the usage note to exhort users to adopt a particular stylistic convention (particularly when that very style causes trouble), no?