Files
swift-mirror/test/protocol_composition.swift
Doug Gregor c079874625 Implement parsing, AST, type canonicalization, and type validation for
protocol conformance types, e.g., 'protocol<P, Q>'. A few things
people *might* want to scream about, or at least scrutinize:

  - The parsing of the '<' and '>' is odd, because '<' and '>' aren't
    tokens, but are part of the operator grammar. Neither are '>>',
    '>>>', '<>', etc., which also come up and need to be parsed
    here. Rather than turning anything starting with '<' or '>' into a
    different kind of token, I instead parse the initial '<' or '>'
    from an operator token and leave the rest of the token as the
    remaining operator.
  - The canonical form of a protocol-composition type is minimized by
    removing any protocols in the list that were inherited by other
    protocols in the list, then sorting it. If a singleton list is
    left, then the canonical type is simply that protocol type.
  - It's a little unfortunate that we now have two existential types
    in the system (ProtocolType and ProtocolCompositionType), because
    many places will have to check both. Once ProtocolCompositionTypes
    are working, we should consider whether it makes sense to remove
    ProtocolType.

Still to come: name lookup, coercions.



Swift SVN r2066
2012-05-30 00:39:08 +00:00

34 lines
1004 B
Swift

// RUN: %swift %s -verify
protocol P1 { func p1() }
protocol P2 : P1 { func p2() }
protocol P3 { func p3() }
protocol P4 : P3 { func p4() }
typealias Any = protocol<>
typealias Any2 = protocol< >
func testEquality() {
// Remove duplicates from protocol-conformance types.
var x1 : (_ : protocol<P2, P4>) -> ()
var x2 : (_ : protocol<P3, P4, P2, P1>) -> ()
x1 = x2
// Singleton protocol-conformance types, after duplication, are the same as
// simply naming the protocol type.
var x3 : (_ : protocol<P2, P1>) -> ()
var x4 : (_ : P2) -> ()
x3 = x4
// Empty protocol-conformance types are empty.
var x5 : (_ : Any) -> ()
var x6 : (_ : Any2) -> ()
x5 = x6
var x7 : (_ : protocol<P1, P3>) -> ()
var x8 : (_ : protocol<P2>) -> ()
x7 = x8 // expected-error{{invalid conversion from type '(_ : protocol<P2>) -> ()' to '(_ : protocol<P1, P3>) -> ()'}}
}
typealias Bogus = protocol<P1, Int> // expected-error{{non-protocol type 'Int' cannot be used within 'protocol<...>'}}