Avatar
omochimetaru 3/8/2024 4:18 AM
variadic generics (type pack) を使っているんですが、コンパイラのバグを踏んだかも?
4:18 AM
頑張って最小化しました
4:18 AM
protocol Controller { associatedtype Deps typealias Routes = GenericRoutes<Self> } struct Request {} protocol Provider { associatedtype ServiceType func provide(for request: Request) throws -> ServiceType } struct GenericRoutes<C: Controller> { public init<P: Provider>( provider: P ) where P.ServiceType == C.Deps { } } struct VariadicProvider< each T: Provider >: Provider { public typealias ServiceType = (repeat (each T).ServiceType) public init(_ providers: repeat each T) { self.providers = (repeat each providers) } public var providers: (repeat each T) public func provide(for request: Request) throws -> ServiceType { return (repeat try (each providers).provide(for: request)) } } protocol DKey { associatedtype Value } struct Dependencies { func get<K: DKey>(_ key: K) -> K.Value { fatalError() } func forRequest<each K: DKey>( _ keys: repeat each K ) -> VariadicProvider<repeat (each K).Value> { return VariadicProvider<repeat (each K).Value>( repeat self.get(each keys) ) } } struct A {} struct B {} struct C {} struct WController: Controller { typealias Deps = (A, B, C) } struct AP: Provider { func provide(for request: Request) throws -> A { fatalError() } } struct BP: Provider { func provide(for request: Request) throws -> B { fatalError() } } struct CP: Provider { func provide(for request: Request) throws -> C { fatalError() } } struct AK: DKey { typealias Value = AP } extension DKey where Self == AK { static var a: AK { AK() } } struct BK: DKey { typealias Value = BP } extension DKey where Self == BK { static var b: BK { BK() } } struct CK: DKey { typealias Value = CP } extension DKey where Self == CK { static var c: CK { CK() } } func main(d: Dependencies) { let vp1: VariadicProvider<AP, BP, CP> = VariadicProvider( d.get(.a), d.get(.b), d.get(.c) ) let r1 = WController.Routes( provider: vp1 ) // write direct vp let r2 = WController.Routes( provider: VariadicProvider( d.get(.a), d.get(.b), d.get(.c) ) ) // build vp from forRequest let vp3: VariadicProvider<AP, BP, CP> = d.forRequest( .a, .b, .c ) let r3 = WController.Routes( provider: vp3 ) // write direct forRequest let r4 = WController.Routes( provider: d.forRequest( .a, .b, .c ) ) }
4:18 AM
4:19 AM
r3 がコンパイルできるのに r4 ができないのはおかしいんじゃないかと
4:22 AM
Swift 5.9.2 はOKで5.10でエラーになってる・・・ https://discord.com/channels/291054398077927425/430242233468452865/1215514280141660240