@@ -729,6 +729,92 @@ main() {
729729 });
730730 });
731731
732+ test ('tryFinallyStatement_finallyBegin() restores pre-try state' , () {
733+ var h = _Harness ();
734+ var x = h.addVar ('x' , 'int?' );
735+ var y = h.addVar ('y' , 'int?' );
736+ h.run ((flow) {
737+ h.declare (x, initialized: true );
738+ h.declare (y, initialized: true );
739+ h.promote (y, 'int' );
740+ flow.tryFinallyStatement_bodyBegin ();
741+ h.promote (x, 'int' );
742+ expect (flow.promotedType (x).type, 'int' );
743+ expect (flow.promotedType (y).type, 'int' );
744+ flow.tryFinallyStatement_finallyBegin ({});
745+ expect (flow.promotedType (x), isNull);
746+ expect (flow.promotedType (y).type, 'int' );
747+ flow.tryFinallyStatement_end ({});
748+ });
749+ });
750+
751+ test (
752+ 'tryFinallyStatement_finallyBegin() un-promotes variables assigned in '
753+ 'body' , () {
754+ var h = _Harness ();
755+ var x = h.addVar ('x' , 'int?' );
756+ h.run ((flow) {
757+ h.declare (x, initialized: true );
758+ h.promote (x, 'int' );
759+ expect (flow.promotedType (x).type, 'int' );
760+ flow.tryFinallyStatement_bodyBegin ();
761+ flow.write (x);
762+ h.promote (x, 'int' );
763+ expect (flow.promotedType (x).type, 'int' );
764+ flow.tryFinallyStatement_finallyBegin ({x});
765+ expect (flow.promotedType (x), isNull);
766+ flow.tryFinallyStatement_end ({});
767+ });
768+ });
769+
770+ test ('tryFinallyStatement_end() restores promotions from try body' , () {
771+ var h = _Harness ();
772+ var x = h.addVar ('x' , 'int?' );
773+ var y = h.addVar ('y' , 'int?' );
774+ h.run ((flow) {
775+ h.declare (x, initialized: true );
776+ h.declare (y, initialized: true );
777+ flow.tryFinallyStatement_bodyBegin ();
778+ h.promote (x, 'int' );
779+ expect (flow.promotedType (x).type, 'int' );
780+ flow.tryFinallyStatement_finallyBegin ({});
781+ expect (flow.promotedType (x), isNull);
782+ h.promote (y, 'int' );
783+ expect (flow.promotedType (y).type, 'int' );
784+ flow.tryFinallyStatement_end ({});
785+ // Both x and y should now be promoted.
786+ expect (flow.promotedType (x).type, 'int' );
787+ expect (flow.promotedType (y).type, 'int' );
788+ });
789+ });
790+
791+ test (
792+ 'tryFinallyStatement_end() does not restore try body promotions for '
793+ 'variables assigned in finally' , () {
794+ var h = _Harness ();
795+ var x = h.addVar ('x' , 'int?' );
796+ var y = h.addVar ('y' , 'int?' );
797+ h.run ((flow) {
798+ h.declare (x, initialized: true );
799+ h.declare (y, initialized: true );
800+ flow.tryFinallyStatement_bodyBegin ();
801+ h.promote (x, 'int' );
802+ expect (flow.promotedType (x).type, 'int' );
803+ flow.tryFinallyStatement_finallyBegin ({});
804+ expect (flow.promotedType (x), isNull);
805+ flow.write (x);
806+ flow.write (y);
807+ h.promote (y, 'int' );
808+ expect (flow.promotedType (y).type, 'int' );
809+ flow.tryFinallyStatement_end ({x, y});
810+ // x should not be re-promoted, because it might have been assigned a
811+ // non-promoted value in the "finally" block. But y's promotion still
812+ // stands, because y was promoted in the finally block.
813+ expect (flow.promotedType (x), isNull);
814+ expect (flow.promotedType (y).type, 'int' );
815+ });
816+ });
817+
732818 test ('whileStatement_conditionBegin() un-promotes' , () {
733819 var h = _Harness ();
734820 var x = h.addVar ('x' , 'int?' );
0 commit comments