@@ -530,3 +530,52 @@ public func weighPet(pet: Pet) -> Int {
530
530
// expected-error @+1 {{assertion failed}}
531
531
#assert( weighPet ( pet: . cat( 2 ) ) == 3 )
532
532
#assert( weighPet ( pet: . dog( 9 , 10 ) ) == 19 )
533
+
534
+ // Test indirect enums.
535
+ indirect enum IntExpr {
536
+ case int( _ value: Int )
537
+ case add( _ lhs: IntExpr , _ rhs: IntExpr )
538
+ case multiply( _ lhs: IntExpr , _ rhs: IntExpr )
539
+ }
540
+
541
+ func evaluate( intExpr: IntExpr ) -> Int {
542
+ switch intExpr {
543
+ case . int( let value) :
544
+ return value
545
+ case . add( let lhs, let rhs) :
546
+ return evaluate ( intExpr: lhs) + evaluate( intExpr: rhs)
547
+ case . multiply( let lhs, let rhs) :
548
+ return evaluate ( intExpr: lhs) * evaluate( intExpr: rhs)
549
+ }
550
+ }
551
+
552
+ // TODO: The constant evaluator can't handle indirect enums yet.
553
+ // #assert(evaluate(intExpr: .int(5)) == 5)
554
+ // #assert(evaluate(intExpr: .add(.int(5), .int(6))) == 11)
555
+ // #assert(evaluate(intExpr: .add(.multiply(.int(2), .int(2)), .int(3))) == 7)
556
+
557
+ // Test address-only enums.
558
+ protocol IntContainerProtocol {
559
+ var value : Int { get }
560
+ }
561
+
562
+ struct IntContainer : IntContainerProtocol {
563
+ let value : Int
564
+ }
565
+
566
+ enum AddressOnlyEnum < T: IntContainerProtocol > {
567
+ case double( _ value: T )
568
+ case triple( _ value: T )
569
+ }
570
+
571
+ func evaluate< T> ( addressOnlyEnum: AddressOnlyEnum < T > ) -> Int {
572
+ switch addressOnlyEnum {
573
+ case . double( let value) :
574
+ return 2 * value. value
575
+ case . triple( let value) :
576
+ return 3 * value. value
577
+ }
578
+ }
579
+
580
+ #assert( evaluate ( addressOnlyEnum: . double( IntContainer ( value: 1 ) ) ) == 2 )
581
+ #assert( evaluate ( addressOnlyEnum: . triple( IntContainer ( value: 1 ) ) ) == 3 )
0 commit comments