Getting weird error: "Argument type 'any XXX' does not conform to expected type 'XXX'" on Swift Package

Hi, I'm trying to migrate part of a project into its own Swift Package. There is no new code, just migrating code from a current local Framework to a local Swift Package.

I have this code

CachePolicy.swift

import Foundation

public class CachePolicy<Value: Codable> {
    public func isValid(cacheItem: CacheItem<Value>) -> Bool { fatalError("Must override") }
}

public class CachePolicyTtl<Value: Codable>: CachePolicy<Value> {
    private var ttl: TimeInterval
    private var timeProvider: TimeProviderInterface

    public init(ttl: TimeInterval, timeProvider: TimeProviderInterface) {
        self.ttl = ttl
        self.timeProvider = timeProvider
    }

    override public func isValid(cacheItem: CacheItem<Value>) -> Bool {
        let lifeTime = timeProvider.currentTimeMillis() - cacheItem.timestamp
        return lifeTime <= ttl * 1000
    }
}

TimeProvider.swift

import Foundation

public protocol TimeProviderInterface {
    //...
}

CacheDataSource.swift

public class InMemoryCacheDataSource<V: Codable> {
  //...
  private var timeProvider: TimeProviderInterface
  private var cachePolicy: CachePolicy<V>
  //...

  public init(ttl: TimeInterval, timeProvider: TimeProviderInterface) {
    self.timeProvider = timeProvider
    self.cachePolicy = CachePolicyTtl(ttl: ttl, timeProvider: timeProvider)
  }

On my current framework target this compiles perfectly, but the same code on the new Swift Package is returning this error

Argument type 'any TimeProviderInterface' does not conform to expected type 'TimeProviderInterface'

On this line

self.cachePolicy = CachePolicyTtl(ttl: ttl, timeProvider: timeProvider)

I don't know why is this happening.

I tried changing the timeProvider: TimeProviderInterface to timeProvider: some TimeProviderInterface and timeProvider: any TimeProviderInterface but didn't work either.

What can be the problem here?

Thanks for your time.

1 Like

All I can see is that all of your references to TimeProviderInterface should be changed to any TimeProviderInterface, I thought that was still a warning rather than uncompilable though (for clarity reasons using a protocol as an existential type without using the any prefix was deprecated). I assume you only tried adding any to the parameter type and not to all locations you used the protocol?

Hi, sorry for the late response. I checked again and added any on all uses of TimeProviderInterface as a parameter or a property. The only place where I'm not using it is in the protocol declaration and its only implementation,

But no luck error is still popping. Could be problem is coming from CachePolicyTtl since is using the Value generic?

import Foundation

public class CachePolicy<Value: Codable> {
    public func isValid(cacheItem: CacheItem<Value>) -> Bool { fatalError("Must override") }
}

public class CachePolicyTtl<Value: Codable>: CachePolicy<Value> {
    private var ttl: TimeInterval
    private var timeProvider: TimeProviderInterface

    public init(ttl: TimeInterval, timeProvider: TimeProviderInterface) {
        self.ttl = ttl
        self.timeProvider = timeProvider
    }

    override public func isValid(cacheItem: CacheItem<Value>) -> Bool {
        let lifeTime = timeProvider.currentTimeMillis() - cacheItem.timestamp
        return lifeTime <= ttl * 1000
    }
}

Maybe the compiler can't be sure about the type because of that?

Ok, found the root of my problem and was a silly one.

Problem was that, for whatever reason TimeProviderInterface declaration was duplicated and compiler was crazy about it, obviously.

Sorry for all the confusion and thanks for the help @stackotter

1 Like

Oh interesting, that would certainly cause issues :sweat_smile: but the diagnostic was not helpful at all, looks like that could be an area for improvement

1 Like