Why protocol compositions don't work when evaluating protocol conformance?

I'm using the following protocol composition:

protocol P1 { }
protocol P2 { }
protocol P3 { }

protocol A {
    var property: P1? { get set }
}

protocol B {
    var property: P2? { get set }
}

protocol C {
    var property: P3? { get set }
}

class C1: A, B, C {
    var property: (P1 & P2 & P3)?
}

However, this doesn't work:

Type 'C1' does not conform to protocol 'A'
Type 'C1' does not conform to protocol 'B'
Type 'C1' does not conform to protocol 'C'

I've tried using

typealias Composition123 = P1 & P2 & P3
typealias CompositionABC = A & B & C

class C1: CompositionABC {
    var property: Composition123?
}

but this won't work either.

Is there something logically unsound with what I'm trying to do, or is this simply a compiler limitation at this moment? Thanks!

Yes. Consider: a type that conforms to protocol A must be able to set the property property with a value of type P1? (it says so right in the requirement), but C1 only allows setting the same property with a value if it conforms to P1 and P2 and P3. C1 does not fulfill the requirements of A, just as the compiler tells you.

3 Likes

Thanks for the reply!

But I've changed the requirement to only get and tried to implement it as a computed property and still the same problem occurs.

I didn’t say that the logical problem was the only reason the code doesn’t work :wink:

There is no subtyping relationship between Optional<P1> and Optional<P1 & P2 & P3>.

1 Like

You can do this:

protocol A {}
protocol B {}
protocol P { var x: A { get } }
protocol Q { var x: B { get } }

struct S: P, Q {
  var _storage: A & B
  
  @_implements(P, x)
  var px: A { _storage }
  
  @_implements(Q, x)
  var qx: B { _storage }
}
2 Likes

So, an existential box type for a protocol composition is not a subtype for the E.B.T. for a single protocol (that was a component of the first composition)?