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
Open
@alexandre-pod

Description

@alexandre-pod

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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0