Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using Nimble types with @MainActor gives a warning when SWIFT_STRICT_CONCURRENCY=targeted due to lack of Sendable conformance #1127

Open
1 task done
siddarthkalra opened this issue Mar 8, 2024 · 4 comments

Comments

@siddarthkalra
Copy link

siddarthkalra commented Mar 8, 2024

  • I have read CONTRIBUTING and have done my best to follow them.

What did you do?

I recently updated my project to use SWIFT_STRICT_CONCURRENCY=targeted. After doing so, Nimble is giving the following warnings when using toEventually():

// Non-sendable type 'SyncExpectation<FooViewModel.State>' returned by implicitly asynchronous call to nonisolated function cannot cross actor boundary

// Passing argument of non-sendable type 'Matcher<FooViewModel.State>' outside of main actor-isolated context may introduce data races

Here's some code to reproduce the problem:

The subject being tested:

@MainActor final class FooViewModel {
    struct State: Equatable {
        let val: String
    }

    var state: State {
        State(val: "val")
    }
}

The Spec:

@MainActor final class ExampleTestSpec: AsyncSpec {
    override class func spec() {
        var fooVM: FooViewModel!

        beforeEach { @MainActor in
            fooVM = FooViewModel()
        }

        it("sets states") { @MainActor in
            // This works fine
            expect(fooVM.state).to(equal(FooViewModel.State(val: "val")))
        }

        it("eventually sets state") { @MainActor in
            // This gives two warnings:
            // Non-sendable type 'SyncExpectation<FooViewModel.State>' returned by implicitly asynchronous call to nonisolated function cannot cross actor boundary
            // Passing argument of non-sendable type 'Matcher<FooViewModel.State>' outside of main actor-isolated context may introduce data races
            await expect(fooVM.state).toEventually(equal(FooViewModel.State(val: "val")))
        }
    }
}

Reasoning around @MainActor usage: Since we're testing a ViewModel here, we want to isolate everything to run on the main actor.

Please feel free to suggest an alternative way but right now, I think the only feasible workarounds available are:

  1. Use @preconcurrency import Nimble to silence the warnings
  2. Use @unchecked Sendable to silence the warnings

Neither of the above workarounds are ideal. I'm curious to understand why SyncExpectation and Matcher don't conform to Sendable. Is there a plan to add this conformance soon? If not then what approach would you suggest in this situation?

What did you expect to happen?

I expected no warnings.

What actually happened instead?

I got two warnings around SyncExpectation and Matcher being non-sendable types.

Environment

List the software versions you're using:

  • Quick: 7.3.0
  • Nimble: 13.1.2
  • Xcode Version: 15.1 (15C65)
  • Swift Version: 5.9.2

Please also mention which package manager you used and its version. Delete the
other package managers in this list:

  • Swift Package Manager: Swift Package Manager - Swift 5.9.0
@younata
Copy link
Member

younata commented Mar 8, 2024

This is being worked on for the next major version of Nimble. There's a lot involved in this, though. Especially to keep a decent experience when using with Quick.

@siddarthkalra
Copy link
Author

@younata that's great to hear. I'll continue to use @preconcurrency import for now then. Any idea what kind of time horizon, we are looking at for this release?

@younata
Copy link
Member

younata commented Mar 8, 2024

Any idea what kind of time horizon, we are looking at for this release?

I'd like to get Nimble 14 out before September, with betas running during the summer. No promises though - I'm not going to burn myself out for a hobby project.

@siddarthkalra
Copy link
Author

Thanks @younata. Totally understand. Just a rough estimate is helpful. Really appreciate your work on this project 🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants