Disambiguating imports

I recently learned about a disambiguation tool when importing modules in swift:

import (struct|class|protocol|var|let|enum|protocol|typealias) Module.Symbol

So I'm working on reducing the blanket imports and only importing the bare minimum of what I need. No sense importing all of Foundation/Glibc if I'm only using 1 or two things right? (Plus I come from a Python background and I prefer to only import exactly what I need)

Unfortunately, I've ran into two issues I'm unsure of how to solve without going back to importing entire modules.

  1. The C stat(2) module includes both a stat function and a stat struct.

I would expect that when importing with import func Glibc.stat it would be able to correctly identify the right stat symbol, especially since trying to import func a non-function symbol will result in an error. I'd also expect import struct Glibc.stat to work for more or less the same reason.

However, both fail with the error ambiguous name 'stat' in module Glibc.

I also would expect to be able to specify the function signature to be able to disambiguate which symbol should be used.

ie:
Since I can do things like this:

import Glibc

let openFile = Glibc.open(_:_:)
let openFileWithMode = Glibc.open(_:_:_:)

I would expect to be able to do this:

import func Glibc.stat(_:_:)

But that also fails (with a bunch of errors).

Which brings me to my next issue...

  1. What is going on here?
import func Glibc.open

// Both these lines error with `Use of unresolved identifier 'open'`
let openFile = open(_:_:)
let openFileWithMode = open(_:_:_:)
import func Glibc.open

// This line fails with `ambiguous use of 'open'`
let openFile = open

How do I resolve ambiguity in a disambiguation tool?

3 Likes

You can blame me for this one. It's not really a well-implemented feature; its original intended use was disambiguation when two modules declare the same top-level name. I tried to rip it out at one point in the Swift 2 days but it turned out a bunch of projects were actually using it.

I agree that your examples makes sense. Unfortunately, it's also not at all how the compiler currently implements the thing, so it's not an easy fix.

2 Likes

Perhaps this is the wrong sub-forum. To me this is a good motivation to implement compound variable names as mentioned in SE-111 rationale. :grinning:

That still wouldn't help if you just wanted to import the struct. (And it also doesn't fit the implementation today, but it's probably an easier thing to fix.)

It seems like this whole feature needs to be rethought, as it would be very nice to not just get better control over imports, but have ways to disambiguate at usage sites as well, especially for extension API.

3 Likes

When it works, it works great ;)

But I do agree that it would be nice to have better control over imports and disambiguating at call sites. Along with some useful documentation about how to use it. I've only ever seen two examples of this (mostly found bc of luck) and I'm not sure whether or not it's officially documented anywhere.

This might even curb some of the desires for a more minimalistic Foundation if people knew they could just import what they need? (At least push off the need for it for a little while)

Looks like it is here:
https://docs.swift.org/swift-book/ReferenceManual/Declarations.html#ID354

1 Like

I'm curious if this is something that should go through the full evolution process at this point?