@@ -530,3 +530,58 @@ 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
+ // expected-error @+2 {{#assert condition not constant}}
554
+ // expected-note @+1 {{could not fold operation}}
555
+ #assert( evaluate ( intExpr: . int( 5 ) ) == 5 )
556
+ // expected-error @+2 {{#assert condition not constant}}
557
+ // expected-note @+1 {{could not fold operation}}
558
+ #assert( evaluate ( intExpr: . add( . int( 5 ) , . int( 6 ) ) ) == 11 )
559
+ // expected-error @+2 {{#assert condition not constant}}
560
+ // expected-note @+1 {{could not fold operation}}
561
+ #assert( evaluate ( intExpr: . add( . multiply( . int( 2 ) , . int( 2 ) ) , . int( 3 ) ) ) == 7 )
562
+
563
+ // Test address-only enums.
564
+ protocol IntContainerProtocol {
565
+ var value : Int { get }
566
+ }
567
+
568
+ struct IntContainer : IntContainerProtocol {
569
+ let value : Int
570
+ }
571
+
572
+ enum AddressOnlyEnum < T: IntContainerProtocol > {
573
+ case double( _ value: T )
574
+ case triple( _ value: T )
575
+ }
576
+
577
+ func evaluate< T> ( addressOnlyEnum: AddressOnlyEnum < T > ) -> Int {
578
+ switch addressOnlyEnum {
579
+ case . double( let value) :
580
+ return 2 * value. value
581
+ case . triple( let value) :
582
+ return 3 * value. value
583
+ }
584
+ }
585
+
586
+ #assert( evaluate ( addressOnlyEnum: . double( IntContainer ( value: 1 ) ) ) == 2 )
587
+ #assert( evaluate ( addressOnlyEnum: . triple( IntContainer ( value: 1 ) ) ) == 3 )
0 commit comments