algolia / algoliasearch-client-swift

⚑️ A fully-featured and blazing-fast Swift API client to interact with Algolia.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Algolia's use of custom operators clashes with custom operators defined in applications that consume this library

Killectro opened this issue Β· comments

Describe the bug πŸ›
Algolia's use of custom operators (>>>) clashes with custom operators defined in applications, preventing applications that define their own versions of custom operators from compiling.

To Reproduce πŸ”
Steps to reproduce the behavior:

  1. Create a new project
  2. Define a >>> operator in that project
  3. Include AlgoliaSearchClient in that project
  4. Attempt to use >>> operator
  5. See compile the following compile error: Ambiguous operator declarations found for operator

Expected behavior πŸ’­
Applications that use common custom operators such as >>> can compile their code while including Algolia library

Additional context
Swift's operator declaration statements do not allow you to specify access control and therefore operator declarations are publicly visible by default. This means that if two different modules declare the same operator with different precedence the compile will be unable to resolve which operator to use.

Given that this is a Swift language limitation I think the Algolia library should avoid declaring custom operators that clash with operators likely to be defined in client applications such as >>>.

Hi @Killectro,

Thank you for reporting this issue.
Could you provide more details about the reproduction steps:

  • The dependency manager you use in your project
  • The code snippet triggering the compilation error

I tried to create a test Swift package using the Swift API client as a dependency via SPM and the declaration of the custom operator >>> internally used in the API client haven't caused any issue.

Here is the code:

import AlgoliaSearchClient

public struct TestOperator {
  
    public init() {}
  
}

func >>> (lhs: TestOperator, rhs: TestOperator) -> TestOperator {
  return lhs
}

precedencegroup CustomPrecedence {
  lowerThan: DefaultPrecedence
  associativity: left
}

infix operator >>>: CustomPrecedence

And the test case:

import XCTest
@testable import TestOperator

final class TestOperatorTests: XCTestCase {
    func testExample() throws {
      let a = TestOperator()
      let b = TestOperator()
      let _ = a >>> b
    }
}

Hey @VladislavFitz tacos for taking a look at this! I'm on my phone at the moment but I can sketch out our setup.

We have a module that holds our operator definition called Prelude. It defines the >>> infix operator itself as well as the definition of >>> as function composition (seen here).

Then we have an application module that imports both Prelude and AlgoliaSearchClient and tried to compose two functions using the operator. We include Algolia via Cocoapods.

Hopefully that's enough to reproduce it!

Hi @Killectro,
Thank you for provided details.
I created a PR removing custom operator to build paths in the client. Not sure how the internal custom operator declaration leaks outside of the module, anyway it worth refactoring πŸ™‚
Could you test your project with refactor/paths branch to confirm that the issue is resolved?