@@ -589,3 +589,174 @@ public func klassNoImplicitCopyArgumentError(@_noImplicitCopy _ x: Klass) -> Kla
589589 print ( y)
590590 return x // expected-note {{consuming use}}
591591}
592+
593+ /////////////////////
594+ // Enum Test Cases //
595+ /////////////////////
596+
597+ public enum EnumTy {
598+ case klass( Klass )
599+ case int( Int )
600+
601+ func doSomething( ) -> Bool { true }
602+ }
603+
604+ public func enumUseMoveOnlyWithoutEscaping( _ x: EnumTy ) {
605+ }
606+ public func enumConsume( _ x: __owned EnumTy) {
607+ }
608+
609+ public func enumSimpleChainTest( _ x: EnumTy ) {
610+ @_noImplicitCopy let x2 = x
611+ let y2 = x2
612+ let k2 = y2
613+ enumUseMoveOnlyWithoutEscaping ( k2)
614+ }
615+
616+ public func enumSimpleNonConsumingUseTest( _ x: EnumTy ) {
617+ @_noImplicitCopy let x2 = x
618+ enumUseMoveOnlyWithoutEscaping ( x2)
619+ }
620+
621+ public func enumMultipleNonConsumingUseTest( _ x: EnumTy ) {
622+ @_noImplicitCopy let x2 = x
623+ enumUseMoveOnlyWithoutEscaping ( x2)
624+ enumUseMoveOnlyWithoutEscaping ( x2)
625+ print ( x2)
626+ }
627+
628+ public func enumUseAfterConsume( _ x: EnumTy ) {
629+ @_noImplicitCopy let x2 = x // expected-error {{'x2' consumed more than once}}
630+ enumUseMoveOnlyWithoutEscaping ( x2)
631+ enumConsume ( x2) // expected-note {{consuming use}}
632+ print ( x2) // expected-note {{consuming use}}
633+ }
634+
635+ public func enumDoubleConsume( _ x: EnumTy ) {
636+ @_noImplicitCopy let x2 = x // expected-error {{'x2' consumed more than once}}
637+ enumConsume ( x2) // expected-note {{consuming use}}
638+ enumConsume ( x2) // expected-note {{consuming use}}
639+ }
640+
641+ public func enumLoopConsume( _ x: EnumTy ) {
642+ @_noImplicitCopy let x2 = x // expected-error {{'x2' consumed more than once}}
643+ for _ in 0 ..< 1024 {
644+ enumConsume ( x2) // expected-note {{consuming use}}
645+ }
646+ }
647+
648+ public func enumDiamond( _ x: EnumTy ) {
649+ @_noImplicitCopy let x2 = x
650+ if boolValue {
651+ enumConsume ( x2)
652+ } else {
653+ enumConsume ( x2)
654+ }
655+ }
656+
657+ public func enumDiamondInLoop( _ x: EnumTy ) {
658+ @_noImplicitCopy let x2 = x // expected-error {{'x2' consumed more than once}}
659+ for _ in 0 ..< 1024 {
660+ if boolValue {
661+ enumConsume ( x2) // expected-note {{consuming use}}
662+ } else {
663+ enumConsume ( x2) // expected-note {{consuming use}}
664+ }
665+ }
666+ }
667+
668+ public func enumAssignToVar1( _ x: EnumTy ) {
669+ @_noImplicitCopy let x2 = x // expected-error {{'x2' consumed more than once}}
670+ var x3 = x2 // expected-note {{consuming use}}
671+ x3 = x2 // expected-note {{consuming use}}
672+ x3 = x
673+ print ( x3)
674+ }
675+
676+ public func enumAssignToVar2( _ x: EnumTy ) {
677+ @_noImplicitCopy let x2 = x // expected-error {{'x2' consumed more than once}}
678+ var x3 = x2 // expected-note {{consuming use}}
679+ x3 = x2 // expected-note {{consuming use}}
680+ enumUseMoveOnlyWithoutEscaping ( x3)
681+ }
682+
683+ public func enumAssignToVar3( _ x: EnumTy ) {
684+ @_noImplicitCopy let x2 = x
685+ var x3 = x2
686+ x3 = x
687+ print ( x3)
688+ }
689+
690+ public func enumAssignToVar4( _ x: EnumTy ) {
691+ @_noImplicitCopy let x2 = x // expected-error {{'x2' consumed more than once}}
692+ let x3 = x2 // expected-note {{consuming use}}
693+ print ( x2) // expected-note {{consuming use}}
694+ print ( x3)
695+ }
696+
697+ public func enumAssignToVar5( _ x: EnumTy ) {
698+ @_noImplicitCopy let x2 = x // expected-error {{'x2' consumed more than once}}
699+ var x3 = x2 // expected-note {{consuming use}}
700+ // TODO: Need to mark this as the lifetime extending use. We fail
701+ // appropriately though.
702+ enumUseMoveOnlyWithoutEscaping ( x2)
703+ x3 = x
704+ print ( x3)
705+ }
706+
707+ public func enumPatternMatchIfLet1( _ x: EnumTy ) {
708+ @_noImplicitCopy let x2 = x // expected-error {{'x2' consumed more than once}}
709+ if case let . klass( x) = x2 { // expected-note {{consuming use}}
710+ classUseMoveOnlyWithoutEscaping ( x)
711+ }
712+ if case let . klass( x) = x2 { // expected-note {{consuming use}}
713+ classUseMoveOnlyWithoutEscaping ( x)
714+ }
715+ }
716+
717+ public func enumPatternMatchIfLet2( _ x: EnumTy ) {
718+ @_noImplicitCopy let x2 = x // expected-error {{'x2' consumed more than once}}
719+ for _ in 0 ..< 1024 {
720+ if case let . klass( x) = x2 { // expected-note {{consuming use}}
721+ classUseMoveOnlyWithoutEscaping ( x)
722+ }
723+ }
724+ }
725+
726+ // This is wrong.
727+ public func enumPatternMatchSwitch1( _ x: EnumTy ) {
728+ @_noImplicitCopy let x2 = x // expected-error {{'x2' consumed more than once}}
729+ switch x2 {
730+ case let . klass( k) : // expected-note {{consuming use}}
731+ classUseMoveOnlyWithoutEscaping ( k)
732+ // TODO: This should be flagged as a consuming use!
733+ enumUseMoveOnlyWithoutEscaping ( x2)
734+ case . int:
735+ break
736+ }
737+ }
738+
739+ // This is wrong.
740+ public func enumPatternMatchSwitch2( _ x: EnumTy ) {
741+ @_noImplicitCopy let x2 = x // expected-error {{'x2' consumed more than once}}
742+ switch x2 {
743+ case let . klass( k) : // expected-note {{consuming use}}
744+ classUseMoveOnlyWithoutEscaping ( k)
745+ case . int:
746+ break
747+ }
748+ }
749+
750+ // This is wrong today. We should error on x2.
751+ public func enumPatternMatchSwitch2WhereClause( _ x: EnumTy ) {
752+ @_noImplicitCopy let x2 = x // expected-error {{'x2' consumed more than once}}
753+ switch x2 {
754+ case let . klass( k) // expected-note {{consuming use}}
755+ where x2. doSomething ( ) :
756+ classUseMoveOnlyWithoutEscaping ( k)
757+ case . int:
758+ break
759+ case . klass:
760+ break
761+ }
762+ }
0 commit comments