// RUN: %target-swift-frontend -emit-ir -target %target-swift-5.9-abi-triple %s protocol P { var p: Int { get } } protocol Q { func p(content: Int) -> Int } struct Zero: P { var p: Int { 0 } } struct One: P { var p: Int { 1 } } struct Add: Q { let rhs: Int func p(content: Int) -> Int { content + rhs } } struct Multiply: Q { let rhs: Int func p(content: Int) -> Int { content * rhs } } struct G: P { var content: Content var modifiers: (repeat each Modifier) init(content: Content, modifiers: (repeat each Modifier)) { self.content = content self.modifiers = modifiers } var p: Int { var r = content.p for m in repeat each modifiers { r = m.p(content: r) } return r } } extension G: Equatable where Content: Equatable, repeat each Modifier: Equatable { static func ==(lhs: Self, rhs: Self) -> Bool { guard lhs.content == rhs.content else { return false} for (left, right) in repeat (each lhs.modifiers, each rhs.modifiers) { guard left == right else { return false } } return true } } extension G { func modifier(_ modifier: T) -> G { .init(content: content, modifiers: (repeat each modifiers, modifier)) } func add(_ rhs: Int) -> G { modifier(Add(rhs: rhs)) } func multiply(_ rhs: Int) -> G { modifier(Multiply(rhs: rhs)) } } extension P { func modifier(_ modifier: T) -> G { return G(content: self, modifiers: modifier) } func add(_ rhs: Int) -> G { modifier(Add(rhs: rhs)) } func multiply(_ rhs: Int) -> G { modifier(Multiply(rhs: rhs)) } } public func test() { let r = Zero() .multiply(1) .multiply(2) .add(3) .multiply(4) .add(2) .multiply(6) .add(2) .multiply(6) .add(2) .multiply(6) print(type(of: r)) } test()