How to specify a specific overload of `SomeType.init`?

Inside regex builders I often want to do something like:

TryCapture(OneOrMore(.digit), transform: Int.init)

Unfortunately this doesn't work, resulting in the compiler error (for the overall Regex):

Type of expression is ambiguous without a type annotation

If rewritten as the following, the error goes away:

TryCapture(OneOrMore(.digit), transform: { Int($0) })

It appears type inference is failing in the simpler case of just referencing the init method directly. Ironic.

Is there some other way to write this that convinces the compiler it's valid and to use the intended init overload (specifically Int.init?(_ description: String))?

How's about Int.init(_:) as (String) -> Int?

1 Like

what happens if you just do Int.init(_:)?

Both result in:

Generic parameter 'C1' could not be inferred

(on the overall Regex builder expression)

your problem (which is really the API’s problem) is that you are calling a conditionally-available overload on TryCapture called init(_:transform:), which is gated on Output == (Substring, NewCapture).

since LosslessStringConvertible.init(_:) takes a String and not a Substring, it’s falling back to the generic init(_:radix:) overload which takes some StringProtocol.

a lot of times LosslessStringConvertible.init(_:) gets implemented generically, which might be why you were surprised this time, but in this case, Int is inheriting the default implementation ss17FixedWidthIntegerPsEyxSgSScfc from FixedWidthInteger, which itself inherits from LosslessStringConvertible.

(for those keeping score, lib/SymbolGraphGen falsely believes FixedWidthInteger.init(_:) is implementing a completely different overload, which is a known issue. as always, we are severely limited by the sorry state of SymbolGraphGen.)

2 Likes

I commented on the issue with a suggested solution, if anyone wants to take a look.

3 Likes