Xcode 10 importUniqueObjects Into<T>() issue #230

Closed
opened 2025-12-29 15:27:01 +01:00 by adam · 13 comments
Owner

Originally created by @ps-mmaierhuber on GitHub (Sep 13, 2018).

Hey there,

This works totally fine in any Xcode 9 but fails to compile in Xcode 10 (beta and GM), when trying to import:
Cannot convert value of type 'Into<T>' to expected argument type 'Into<_>'

class BaseModel: CoreStoreObject, ImportableUniqueObject {...}

func importObjects<T: BaseModel, S: Sequence>(into: T.Type, source: S, completion: @escaping ParseCompletion<T>) where S.Iterator.Element == T.ImportSource {
     CoreStore.perform(asynchronous: { (transaction) -> [T] in

    let imported = try transaction.importUniqueObjects(Into<T>(), sourceArray: source) // complaining here
    // ...
}

Any hints?

Originally created by @ps-mmaierhuber on GitHub (Sep 13, 2018). Hey there, This works totally fine in any Xcode 9 but fails to compile in Xcode 10 (beta and GM), when trying to import: `Cannot convert value of type 'Into<T>' to expected argument type 'Into<_>'` ```swift class BaseModel: CoreStoreObject, ImportableUniqueObject {...} func importObjects<T: BaseModel, S: Sequence>(into: T.Type, source: S, completion: @escaping ParseCompletion<T>) where S.Iterator.Element == T.ImportSource { CoreStore.perform(asynchronous: { (transaction) -> [T] in let imported = try transaction.importUniqueObjects(Into<T>(), sourceArray: source) // complaining here // ... } ``` Any hints?
adam added the ios/compiler bug label 2025-12-29 15:27:01 +01:00
adam closed this issue 2025-12-29 15:27:01 +01:00
Author
Owner

@JohnEstropia commented on GitHub (Sep 14, 2018):

@ps-mmaierhuber I'm more surprised this compiles in Xcode 9 at all. Into() needs a generic type, in your case try Into<T>() instead of Into().

@JohnEstropia commented on GitHub (Sep 14, 2018): @ps-mmaierhuber I'm more surprised this compiles in Xcode 9 at all. `Into()` needs a generic type, in your case try `Into<T>()` instead of `Into()`.
Author
Owner

@ps-mmaierhuber commented on GitHub (Sep 14, 2018):

@JohnEstropia i am using Into<T>() - apparently github tries to apply markdown.
I also tried
Into(T.self)

@ps-mmaierhuber commented on GitHub (Sep 14, 2018): @JohnEstropia i am using `Into<T>()` - apparently github tries to apply markdown. I also tried Into<BaseModel>(T.self)
Author
Owner

@JohnEstropia commented on GitHub (Sep 21, 2018):

I'm guessing your importObjects method isn't binding your generic types properly. Or that you have another compiler error somewhere that is masked by this error message. Can you show your whole func importObjects(...) implementation?

@JohnEstropia commented on GitHub (Sep 21, 2018): I'm guessing your `importObjects ` method isn't binding your generic types properly. Or that you have another compiler error somewhere that is masked by this error message. Can you show your whole `func importObjects(...)` implementation?
Author
Owner

@ps-mmaierhuber commented on GitHub (Sep 24, 2018):

Yeah the thing that i dont understand is that it works with any Xcode 9, but not with Xcode 10 ...
There is the code and how it is called, including the first type inference.

    func importObjects<T: BaseModel, S: Sequence>(into: T.Type, source: S, completion: @escaping ParseCompletion<T>)
        where S.Iterator.Element == T.ImportSource {

            CoreStore.perform(asynchronous: { (transaction) -> [T] in
                let imported = try transaction.importUniqueObjects(Into<T>(), sourceArray: source)
                return imported
            }, success: { (objects) in
                let fetchedObjects = CoreStore.fetchExisting(objects)
                completion(fetchedObjects, nil)
            }, failure: { (_) in
                completion(nil, nil)
            })
    }

and its called from the response parser like this:

    func parseResponse<T: BaseModel>(_ response: Response, rootObject: String? = nil, then completion: @escaping ParseCompletion<T>) throws {
        let filteredResponse = try response.filterSuccessfulStatusCodes()
        var json = try JSON(data: filteredResponse.data).preProcessedJSON
        if let rootObject = rootObject {
            json = json.first?[rootObject].preProcessedJSON ?? json
        }
        DatabaseManager.shared.importObjects(into: T.self, source: json, completion: completion)
    }
    func handleImportableResult<T: BaseModel>(_ result: Result<Moya.Response, Moya.MoyaError>, rootObject: String? = nil, then parseCompletion: @escaping ParseCompletion<T>) {
        switch result {
        case .success(let response):
            do {
                try self.parseResponse(response, rootObject: rootObject, then: parseCompletion)
            } catch let error {
                ...
            }
        case .failure(let failure):
            ...
        }
    }

Im using Moya... but here the generic T is inferred to a concrete model, User is a subclass of BaseModel.

    func getUser(then completion: @escaping ParseCompletion<User>) {
        provider.request(.getUser) { (result) in
            self.handleImportableResult(result, then: completion)
        }
    }

The ParseCompletion is a typealiased generic:

   typealias ParseCompletion<T: BaseModel> = (_ objects: [T]?, _ error: APIError?) -> Void
@ps-mmaierhuber commented on GitHub (Sep 24, 2018): Yeah the thing that i dont understand is that it works with any Xcode 9, but not with Xcode 10 ... There is the code and how it is called, including the first type inference. ```swift func importObjects<T: BaseModel, S: Sequence>(into: T.Type, source: S, completion: @escaping ParseCompletion<T>) where S.Iterator.Element == T.ImportSource { CoreStore.perform(asynchronous: { (transaction) -> [T] in let imported = try transaction.importUniqueObjects(Into<T>(), sourceArray: source) return imported }, success: { (objects) in let fetchedObjects = CoreStore.fetchExisting(objects) completion(fetchedObjects, nil) }, failure: { (_) in completion(nil, nil) }) } ``` and its called from the response parser like this: ```swift func parseResponse<T: BaseModel>(_ response: Response, rootObject: String? = nil, then completion: @escaping ParseCompletion<T>) throws { let filteredResponse = try response.filterSuccessfulStatusCodes() var json = try JSON(data: filteredResponse.data).preProcessedJSON if let rootObject = rootObject { json = json.first?[rootObject].preProcessedJSON ?? json } DatabaseManager.shared.importObjects(into: T.self, source: json, completion: completion) } ``` ```swift func handleImportableResult<T: BaseModel>(_ result: Result<Moya.Response, Moya.MoyaError>, rootObject: String? = nil, then parseCompletion: @escaping ParseCompletion<T>) { switch result { case .success(let response): do { try self.parseResponse(response, rootObject: rootObject, then: parseCompletion) } catch let error { ... } case .failure(let failure): ... } } ``` Im using Moya... but here the generic T is inferred to a concrete model, User is a subclass of BaseModel. ```swift func getUser(then completion: @escaping ParseCompletion<User>) { provider.request(.getUser) { (result) in self.handleImportableResult(result, then: completion) } } ``` The ParseCompletion is a typealiased generic: ```swift typealias ParseCompletion<T: BaseModel> = (_ objects: [T]?, _ error: APIError?) -> Void ```
Author
Owner

@JohnEstropia commented on GitHub (Sep 25, 2018):

@ps-mmaierhuber In your func importObjects implementation, can you try if this works?

transaction.importUniqueObjects(Into(into), sourceArray: source)
@JohnEstropia commented on GitHub (Sep 25, 2018): @ps-mmaierhuber In your `func importObjects` implementation, can you try if this works? ```swift transaction.importUniqueObjects(Into(into), sourceArray: source) ```
Author
Owner

@ps-mmaierhuber commented on GitHub (Sep 25, 2018):

Doesnt work. I tried:
Into<T>(into)
and
Into(into)

also tried specifying the returned objects type to T, also tried using BaseModel, doesnt work. It is always complaining about this argument in importUniqueObjects

These things works just fine if i add them there:

transaction.create(Into<T>())
let objects = transaction.fetchAll(From<T>())
@ps-mmaierhuber commented on GitHub (Sep 25, 2018): Doesnt work. I tried: `Into<T>(into)` and `Into(into)` also tried specifying the returned objects type to T, also tried using BaseModel, doesnt work. It is always complaining about this argument in importUniqueObjects These things works just fine if i add them there: ```swift transaction.create(Into<T>()) let objects = transaction.fetchAll(From<T>()) ```
Author
Owner

@bendalton commented on GitHub (Oct 3, 2018):

I too would like the answer 👍 Hi @ps-mmaierhuber !

@bendalton commented on GitHub (Oct 3, 2018): I too would like the answer 👍 Hi @ps-mmaierhuber !
Author
Owner

@JohnEstropia commented on GitHub (Oct 4, 2018):

@ps-mmaierhuber @bendalton Can any of you isolate the models and methods in a separate project? The app doesn't need to run, just a reproduction of the compiler error would greatly help.

@JohnEstropia commented on GitHub (Oct 4, 2018): @ps-mmaierhuber @bendalton Can any of you isolate the models and methods in a separate project? The app doesn't need to run, just a reproduction of the compiler error would greatly help.
Author
Owner

@puelocesar commented on GitHub (Oct 5, 2018):

@JohnEstropia Here: https://github.com/puelocesar/CoreStoreTest

Builds with Xcode 9 but not with Xcode 10

@puelocesar commented on GitHub (Oct 5, 2018): @JohnEstropia Here: https://github.com/puelocesar/CoreStoreTest Builds with Xcode 9 but not with Xcode 10
Author
Owner

@JohnEstropia commented on GitHub (Oct 5, 2018):

@puelocesar That was really helpful, thanks!

This looks bizarre. It actually works if we use where T: ImportableUniqueObject, S.Iterator.Element == T.ImportSource for the function constraint, albeit the obviously ignorable compiler warning.

I'm pretty sure we hit a compiler issue here. I'll try to raise this in the Swift bug tracker within the weekend. Let me know if any of you already have a ticket/rdar so I can duplicate.

@JohnEstropia commented on GitHub (Oct 5, 2018): @puelocesar That was really helpful, thanks! This looks bizarre. It actually works if we use `where T: ImportableUniqueObject, S.Iterator.Element == T.ImportSource` for the function constraint, albeit the obviously ignorable compiler warning. I'm pretty sure we hit a compiler issue here. I'll try to raise this in the [Swift bug tracker](https://bugs.swift.org/secure/Dashboard.jspa) within the weekend. Let me know if any of you already have a ticket/rdar so I can duplicate.
Author
Owner

@JohnEstropia commented on GitHub (Oct 5, 2018):

To clarify, the issue isn't with Into<T> but with Sequence not propagating it's element's associated type properly. You can try that this too will not compile:

func importObjects<T: BaseModel, S: Sequence>(into: Into<T>, source: S, completion: @escaping ParseCompletion<T>) throws where S.Iterator.Element == T.ImportSource

and the same workaround where T: ImportableUniqueObject, S.Iterator.Element == T.ImportSource would also work

@JohnEstropia commented on GitHub (Oct 5, 2018): To clarify, the issue isn't with `Into<T>` but with `Sequence` not propagating it's element's associated type properly. You can try that this too will not compile: ```swift func importObjects<T: BaseModel, S: Sequence>(into: Into<T>, source: S, completion: @escaping ParseCompletion<T>) throws where S.Iterator.Element == T.ImportSource ``` and the same workaround `where T: ImportableUniqueObject, S.Iterator.Element == T.ImportSource` would also work
Author
Owner

@puelocesar commented on GitHub (Oct 5, 2018):

I'm getting Redundant conformance constraint 'T': 'ImportableUniqueObject' as a Swift warning, but other then that, it works, thanks!

@puelocesar commented on GitHub (Oct 5, 2018): I'm getting `Redundant conformance constraint 'T': 'ImportableUniqueObject'` as a Swift warning, but other then that, it works, thanks!
Author
Owner

@JohnEstropia commented on GitHub (Oct 9, 2018):

Reported in Swift bug tracker: https://bugs.swift.org/browse/SR-8945

@JohnEstropia commented on GitHub (Oct 9, 2018): Reported in Swift bug tracker: https://bugs.swift.org/browse/SR-8945
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/CoreStore#230