63

I'm trying to use Károly Lőrentey's B-tree based OrderedSet 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?

zneak
  • 134,922
  • 42
  • 253
  • 328
  • This is a great question. Can you `typealias` one of them? – NRitH Jun 18 '16 at 02:12
  • I can't "typealias away" one of them, typealiases can only create names (`OrderedSet` will remain a valid, if ambiguous, name for both types). But even to typealias one, I need to be able to refer to it... – zneak Jun 18 '16 at 02:13
  • Since I don't use Foundation in this project, I was able to unblock myself by removing `#import ` in the bridged header. However, that doesn't solve the general (and very real) problem. – zneak Jun 18 '16 at 02:22
  • Sounds like [a good bug to report](http://bugs.swift.org). – rickster Jun 18 '16 at 02:32
  • This bug has [already been reported](https://bugs.swift.org/browse/SR-898). I started a thread on swift-evolution to find a design. – zneak Jun 18 '16 at 02:53
  • Is this truly a bug? I'm genuinely curious. Wouldn't you *not* want anything to clash namespaces--even if it came from Objective-C? – KFDoom Jul 03 '16 at 08:51
  • Seems to me that we haven't exhausted possibilities to disambiguate that case and that it would be unfortunate to declare it "by design" until then. – zneak Jul 03 '16 at 08:55
  • Oh I see, thank you for the clarification @zneak – KFDoom Jul 04 '16 at 07:48

2 Answers2

95

The type can be disambiguated using the little-known import (class|struct|func|protocol|enum) Module.Symbol syntax.

import struct BTree.OrderedSet

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

If this would still be ambiguous or sub-optimal in some files, you can create a Swift file to rename imports using typealiases:

// a.swift
import struct BTree.OrderedSet
typealias BTreeOrderedSet<T> = BTree.OrderedSet<T>

 

// b.swift
let foo = OrderedSet<Int>() // from Foundation
let bar = BTreeOrderedSet<Int>() // from BTree

There was a new syntax discussed for Swift 3, but it fell through.

zneak
  • 134,922
  • 42
  • 253
  • 328
  • 7
    Thanks! One can also use `protocol`, `enum`, i.e., all keywords that define types after the import to import only a specific type. – cicerocamargo Jun 02 '17 at 18:49
  • Can I `import BTree` after this? I mean I only want to avoid the conflict only one class but the rest of them are not conflict. If I use this to disambiguated import do I also need to change all other non-conflict class to this? – SaintTail Sep 11 '19 at 04:13
  • @SaintTail, I don’t know off the top of my head. Try it and report your results! – zneak Sep 11 '19 at 04:35
  • @zneak Doesn't seem to work . I need to add all the required classes the same way as the conflict one. – SaintTail Sep 11 '19 at 04:54
  • I imported a framework with a protocol that had the same argument type name as an existing type in my project. `typealias` solved this. Amazing! – Manuel Oct 02 '19 at 23:19
5

I renamed OrderedSet to SortedSet in the Swift 3 version of BTree, which should serve as a workaround while a possible language-level fix is being discussed/implemented.

Karoy Lorentey
  • 4,843
  • 2
  • 28
  • 28
  • I brought up the issue again on the mailing list a few minutes ago. Hopefully things get going. – zneak Jul 16 '16 at 23:18