ReactiveX/RxSwift

Name Conflict from Xcode 15

JCSooHwanCho opened this issue · 24 comments

Short description of the issue:
Since introduction of Observation framework, importing both RxSwift and Observation arises name conflict

Expected outcome:

compile without error

What actually happens:

compile error

Protocol 'Observable' does not have primary associated types that can be constrained

Self contained code example that reproduces the issue:

import SwiftUI
import RxSwift

struct ContentView: View {
    var body: some View {
        Color.black
    }

    func observable() -> Observable<Int> { // Protocol 'Observable' does not have primary associated types that can be constrained
        .just(1)
    }
}

RxSwift/RxCocoa/RxBlocking/RxTest version/commit

6.6.0

Platform/Environment

  • iOS
  • macOS
  • tvOS
  • watchOS
  • playgrounds

How easy is to reproduce? (chances of successful reproduce after running the self contained code)

  • easy, 100% repro
  • sometimes, 10%-100%
  • hard, 2% - 10%
  • extremely hard, %0 - 2%

Xcode version:

Xcode 15 developer beta 2

⚠️ Fields below are optional for general issues or in case those questions aren't related to your issue, but filling them out will increase the chances of getting your issue resolved. ⚠️

Installation method:

  • CocoaPods
  • Carthage
  • Git submodules
  • Swift Package Manager

I have multiple versions of Xcode installed:
(so we can know if this is a potential cause of your issue)

  • yes (which ones)
  • no

Level of RxSwift knowledge:
(this is so we can understand your level of knowledge
and formulate the response in an appropriate manner)

  • just starting
  • I have a small code base
  • I have a significant code base

A workaround to this issue is to declare a typealias of Observable inside the modules you are experiencing issues:

import RxSwift

// Needed to disambiguate between Foundation's Observable and RxSwift's Observable
typealias Observable = RxSwift.Observable

This shouldn't be needed in a future release: https://forums.swift.org/t/pitch-observation-revised/63757/98

As @0xpablo suggested, this should be solved in the next beta seed hopefully.
Thanks for flagging this!
apple/swift#66367

Is that PR really solves this issue? It just seems ensuring success resolution of macro code, not my code. As long as Observable protocol declaration is public, this problem will be persited, I think.

@JCSooHwanCho I'm unsure as well. I tried the latest dev snapshot and it doesn't solve it :(
I'm continuing the discussion here:
https://forums.swift.org/t/pitch-observation-revised/63757/101

I just tested the last nightly seed (Jul 2) of Swift 5.9 and it seems the problem is fixed!
Exciting :) I hope this will be released in an upcoming beta soon.

@freak4pc I found the PR that solves this issue. It resolves this issue by lowering priority of name look-up of standard library.

It doesn't seems the true solution though, it can allow us more time to react for language evolution.

BTW, I have a curiosity about is there any plan renaming to resolve this issue. can you let me know about it?

I don't think we will make any renames, this is against what we want to achieve with the project here, and I really don't consider it this project's problem that Apple decided to cause havoc 😅

What we can do is expose a public typealias RxObservable = RxSwift.Observable in the repo so folks can use RxObservable and Observable if they need the observability framework, which might help in that specific scenario.

Also note that I'm pretty sure people will be able to use Observability.Observable if they need it, at the worst case.

I just installed Xcode 15 Beta 3 and the problem is still not solved in our main app /: very strange.

Here's what I did for now:

  1. I have a new branch on the RxSwift called alias, it introduces a new RxObservable alias.
  2. In my main project, I did a find and replace for the following regex:
image

My project builds now. It's not really a super great solution, but it's reasonable for the time being (much more reasonable than an entire rename).

I just installed Xcode 15 Beta 3 and the problem is still not solved in our main app /: very strange.

Not fixed in Beta 4 either.

@oryonatan Mind trying the fix I suggested above? It seems to have solved it for the meanwhile for several projects.

Some more things I noticed that seem to work a bit better then before (In Xcode 15 Beta 4).

  1. In a specific file where I had SwiftUI & RxSwift imported, i removed the SwiftUI import and it knew to take the right Observable even though SwiftUI is imported in other places in the module.
  2. In my main app adding a public typealias Observable = RxSwift.Observable in some central place seems to work with a single statement. It didn't solve the issue in previous betas.

Seems that between this and the option to rename everything to RxObservable, this will be an annoying breaking change, but one with a few possible solutions, depending on the codebase.

These are all the changes I had to do to get my entire project to compile, and we have about 50 modules:
image

It seems resolved in Xcode 15 beta 5.

That's interesting, the protocol is still there.
For our huge codebase it also seems to work, but I had to import RxSwift in a single file where just doing import RxCocoa wasn't enough for some reason.

I'm closing this thread for now, seems like indeed this is fixed. If anything changes, feel free to comment here.

I had this problem in Xcode15 beta 4, then it was fixed (?) in Xcode 15 beta 5, but now it is back again in Xcode beta 6.

But I found something curious:

extension Observable {
    static func unimplemented(file: String = #file, function: String = #function, line: Int = #line)
        -> Observable<Element> { // Error does not happen here
        unimplementedFunction(file: file, function: function, line: line)
            return Observable<Element>.empty()  // <-- Error only happens here
    }
}

This error only seems to apply to return statements in my project. If I remove the Observable<Element> from the return statement so it becomes only .empty() and let the compiler infer the type, it works. It also works with just Observable.empty(). Not sure if this helps or not.

apple/swift#67815

I opened an issue about it

The same is affecting the Observable extensions in RxSwiftExt (like https://github.com/RxSwiftCommunity/RxSwiftExt/blob/main/Source/RxSwift/distinct.swift#L27)
Screenshot 2023-08-09 at 17 35 09

issue still reproducible with Xcode 15.0 Beta 7
Screenshot 2023-08-23 at 14 01 15

The RxSwiftExt issue specifically was resolved in RxSwiftExt 6.2.0.

Issue seems to be gone in Xcode 15.0 beta 8. Anyone else can confirm?

still an issue in beta 8 for me.

Apple core team suggests this PR will resolve the issue in an upcoming beta:
apple/swift#68254

See discussion:
apple/swift#67815 (comment)

Hi team I am getting this issue In Xcode 15.0.1 Using pod 'RxSwiftExt', '~> 5'
Screenshot 2023-11-24 at 11 36 44 PM
Can someone guide me here which approach I should follow?
Thanks.