Ian Henry
Ian Henry

Reputation: 22403

How do I resolve this ambiguous type error in Swift?

So I created a new Xcode project, and wrote this Podfile:

use_frameworks!

target 'Repro' do
  pod 'Alamofire'
  pod 'Result'
end

Then I ran pod install, opened up the workspace, and created a new file with the following contents:

import Alamofire
import Result

private func something(request: Request) -> Result<Bool, NSError> {
    fatalError()
}

And I tried to build this, but Xcode produced the error 'Result' is ambiguous for type lookup in this context. So I tried the obvious fix:

import Alamofire
import Result

private func something(request: Request) -> Result.Result<Bool, NSError> {
    fatalError()
}

But that gave me the error Reference to generic type 'Result' requires arguments in <...>, as if Swift were parsing the module name as the type name.

What's the non-obvious fix?

Upvotes: 4

Views: 5635

Answers (2)

nolanw
nolanw

Reputation: 475

If you directly import the Result module's Result type, it'll override Alamofire's Result type. You can still reach Alamofire's using its qualified name:

import Alamofire
import enum Result.Result

let a: Alamofire.Result<T, ErrorType> // Alamofire's Result
let r: Result<T, ErrorType> // Result module's Result

I found this out through trial and error after seeing detailed import mentioned in the language reference. I don't know if type name resolution is documented anywhere as working this way, so it might change without much notice.

Upvotes: 14

bshirley
bshirley

Reputation: 8357

I would suggest that the Result cocoapod is out of style with swift 2.1, and may be obviated with the language updates - they should be doing something more like

private func something(request: Request) throws -> Result {
  // TODO: implement this 
  throw RequestError()
}

which removes the need for the wrapping of return value.


I would have used a tuple in the first place (Bool, NSError) instead of a custom enum. But that's stylistic.

Upvotes: -1

Related Questions