8000 Swift 6 source-breaking change cause `Container.resolve(_:arguments:)` to change behavior from Swift 5 · Issue #571 · Swinject/Swinject · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Swift 6 source-breaking change cause Container.resolve(_:arguments:) to change behavior from Swift 5 #571

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

Open
alexandre-pod opened this issue Jul 28, 2024 · 1 comment

Comments

@alexandre-pod
Copy link

Hi, by trying using Swinject on a project I am working on migrating to Swift 6, I encountered an issue caused by the a new behavior introduced by SE-0352 when using Swift 6.

Here the issue, that I tried in form of a test in ContainerTests_Arguments test suite :

This test pass when using Swift 5, but when using the new Swift 6 language mode (done with SWIFT_VERSION = 6 in build settings) the test no longer pass, and we got a nil from the resolve call.

func testContainerArgumentsWorksWithExistentials() throws {
    container.register(Person.self) { (r, animal: Animal) in PetOwner(pet: animal) }

    let animal: Animal = Cat(name: "cat")
    let person = container.resolve(Person.self, argument: animal)

    let petOwner = try XCTUnwrap(person as? PetOwner) // error: XCTUnwrap failed: expected non-nil value of type "PetOwner"
    let cat = try XCTUnwrap(petOwner.pet as? Cat)
    XCTAssertEqual(cat.name, "cat")
}

And here is what is printed in the console:

Swinject: Resolution failed. Expected registration:
    { Service: Person, Factory: (Resolver, Cat) -> Person }
Available registrations:
    { Service: Person, Factory: (Resolver, Animal) -> Person, ObjectScope: graph }

After some investigation, this behavior change from Swift is documented in the section ""Losing" constraints when type-erasing resulting values" of SE-0352.
The solution is also provided by the proposal: opting out from this new implicit existential opening with as any P / as! any P. So in my example replacing the line resolving the person with this line makes the test pass in Swift 6:

let person = container.resolve(Person.self, argument: animal as Animal)

I didn't find another way to fix this issue, but at least I was able to understand what was happening. I am not sure what's the next step for this issue, maybe at least more documentation warning about this issue ?

You can find the project with some changes on top of main to make it compile with Swift 6 here: https://github.com/alexandre-pod/Swinject/tree/swift-6-support

(This was tried on Xcode 16.0 beta 3)

@niorko
Copy link
niorko commented Feb 21, 2025

Any updates please @maxim-chipeev?

alexandre-pod added a commit to faberNovel/ccios that referenced this issue Feb 21, 2025
…h Swift 6

Swift 6 implicitly open existentials, causing issue with Swinject without those explicit types.
See Swinject/Swinject#571 for more details
alexandre-pod added a commit to faberNovel/ccios that referenced this issue Feb 28, 2025
…h Swift 6

Swift 6 implicitly open existentials, causing issue with Swinject without those explicit types.
See Swinject/Swinject#571 for more details
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
0