So, my intuition of shadowing of functions is that the compiler will prefer the version from my module unless the arguments don't match, but if I shadow print like so:

import func Foundation.puts

private extension StaticString {
    @_transparent
    var cString: UnsafePointer<CChar> {
        UnsafeRawPointer(utf8Start)
            .assumingMemoryBound(to: CChar.self)
    }
}

func print(_ string: StaticString) {
    puts(string.cString)
}

// Calls Swift.print, and does a surprisingly large amount of work to print
// something that should constant propagate to a zstring and a count.
print("Hello, world!")

It calls Swift.print instead of my version that delegates to puts. That would make me think that maybe the compiler just prefers String to StaticString, except that if I wrap the definition and call of print into a smaller scope, then my version is the one that's called.

do {
    func print(_ string: StaticString) {
        puts(string.cString)
    }

    // Calls my print and constant propagates "Hello world!" into a zstring
    print("Hello, world!")
}

So, in short, I have no idea how the compiler decides which version of a shadowed function to use.

1 Like