zneak zneak - 4 months ago 18
Swift Question

How can I disambiguate a type and a module with the same name?

I'm trying to use Károly Lőrentey's B-tree based

in a project. However, I'm running into an issue where I can't declare an unqualified
OrderedSet<T>
because the name conflicts between Foundation's
NSOrderedSet
(imported as
OrderedSet
in Swift 3) and
BTree
's
OrderedSet
.

let set = OrderedSet<Int>()
// error: 'OrderedSet' is ambiguous for type lookup in this context
// Found this candidate: Foundation.OrderedSet:3:14
// Found this candidate: BTree.OrderedSet:12:15


To resolve this conflict, you would normally qualify the name, and that would give you
BTree.OrderedSet<T>
. However, the
BTree
module also contains a class named
BTree
. If I write
BTree.OrderedSet
, Swift thinks that I'm referring to a type named
OrderedSet
that is nested in the
BTree.BTree
type.

let set = BTree.OrderedSet<Int>()
// error: reference to generic type 'BTree' requires arguments in <...>


If I don't
import BTree
, I can't use the
BTree
name at all.

// no import BTree
let set = BTree.OrderedSet<Int>()
// error: use of undeclared type 'BTree'


How can I resolve this ambiguity between the
BTree
type and the
BTree
module?

Answer

In Swift prior to 3 (a new syntax currently being discussed), the type can be disambiguated using the (extremely little-known) import (class|struct|func) Module.Symbol syntax.

import struct BTree.OrderedSet

From this point on, OrderedSet unambiguously refers to the one in BTree.

Comments