`ambiguous use of init` for `Double` in certain circumstances

I've run into a strange issue (which might be a Swift compiler bug) where I can't initialise a Double from an Int like so, Double(myInt), without the compiler throwing an error when the initialisation is performed in certain positions within my code. Here's a working example and a non-working example:

// Working example:
let width = Double(width)
textureDescriptor.mipmapLevelCount = 1 + Int(log2(width).rounded(.down))

// Non-working example
textureDescriptor.mipmapLevelCount = 1 + Int(log2(Double(width)).rounded(.down))

Here's the error that the second one gets:

error: ambiguous use of 'init(_:)'
    textureDescriptor.mipmapLevelCount = 1 + Int(log2(Double(width)).rounded(.down))
                                                      ^
Swift.Double:2:12: note: found this candidate
    public init(_ v: Int)
           ^
Swift.Double:3:23: note: found this candidate
    @inlinable public init<Source>(_ value: Source) where Source : BinaryInteger
                      ^
Swift.BinaryFloatingPoint:3:23: note: found this candidate
    @inlinable public init<Source>(_ value: Source) where Source : BinaryInteger
                      ^

Strangely all 3 implementations seem to be within the standard library so it's not something that I introduced with my code (unless it's a Swift bug as far as I can see).

I haven't changed anything in that file for quite a while so somehow some other code changes have affected the resolution of the initialiser in that one particular spot.

Sadly I don't have the time at the moment to create a minimum reproducing case so I'm more just posting this in case it's useful to anyone working on a related issue.

Classic, the instant I posted it I figured out some more useful information :sweat_smile: This might be a bit more helpful now.

Essentially the root cause seems to be that it's actually an ambiguous use of log2 (I'm using a library that has its own implementation of log2) and for some reason that got picked up as an ambiguous use of Double.init even though afaict the selection process for which Double.init gets used shouldn't be affected at all by which log2 implementation is being referred to.

Hopefully that's a bit more helpful.

Can you provide the signature(s) of log2 that the library provides?

Let me guess, "CGFloat" ↔ "Double" inter-op oddity?

1 Like

Can you provide the signature(s) of log2 that the library provides?

It provides the following two functions:

public func log2(_ float: Float) -> Float
public func log2(_ double: Double) -> Double