@@ -3201,6 +3201,7 @@ impl Compiler {
32013201 emit ! ( self , PseudoInstruction :: PopBlock ) ;
32023202 self . pop_fblock ( FBlockType :: TryExcept ) ;
32033203 emit ! ( self , PseudoInstruction :: Jump { delta: else_block } ) ;
3204+ self . set_no_location ( ) ;
32043205
32053206 // except handlers:
32063207 self . switch_to_block ( handler_block) ;
@@ -3471,8 +3472,12 @@ impl Compiler {
34713472 ) -> CompileResult < ( ) > {
34723473 let handler_block = self . new_block ( ) ;
34733474 let cleanup_block = self . new_block ( ) ;
3474- let orelse_block = self . new_block ( ) ;
34753475 let end_block = self . new_block ( ) ;
3476+ let orelse_block = if orelse. is_empty ( ) {
3477+ end_block
3478+ } else {
3479+ self . new_block ( )
3480+ } ;
34763481
34773482 emit ! ( self , Instruction :: Nop ) ;
34783483 emit ! (
@@ -3619,14 +3624,16 @@ impl Compiler {
36193624 emit ! ( self , Instruction :: Reraise { depth: 1 } ) ;
36203625 self . set_no_location ( ) ;
36213626
3622- self . switch_to_block ( orelse_block) ;
3623- self . set_no_location ( ) ;
3624- self . compile_statements ( orelse) ?;
3625- emit ! (
3626- self ,
3627- PseudoInstruction :: JumpNoInterrupt { delta: end_block }
3628- ) ;
3629- self . set_no_location ( ) ;
3627+ if !orelse. is_empty ( ) {
3628+ self . switch_to_block ( orelse_block) ;
3629+ self . set_no_location ( ) ;
3630+ self . compile_statements ( orelse) ?;
3631+ emit ! (
3632+ self ,
3633+ PseudoInstruction :: JumpNoInterrupt { delta: end_block }
3634+ ) ;
3635+ self . set_no_location ( ) ;
3636+ }
36303637
36313638 self . switch_to_block ( end_block) ;
36323639 Ok ( ( ) )
@@ -3644,7 +3651,6 @@ impl Compiler {
36443651 let handler_block = self . new_block ( ) ;
36453652 let finally_block = self . new_block ( ) ;
36463653 let cleanup_block = self . new_block ( ) ;
3647- let else_block = self . new_block ( ) ;
36483654 let end_block = self . new_block ( ) ;
36493655 let reraise_star_block = self . new_block ( ) ;
36503656 let reraise_block = self . new_block ( ) ;
@@ -3654,10 +3660,11 @@ impl Compiler {
36543660 None
36553661 } ;
36563662 let exit_block = self . new_block ( ) ;
3657- let continuation_block = if finalbody. is_empty ( ) {
3658- exit_block
3663+ let continuation_block = end_block;
3664+ let else_block = if orelse. is_empty ( ) && finalbody. is_empty ( ) {
3665+ continuation_block
36593666 } else {
3660- end_block
3667+ self . new_block ( )
36613668 } ;
36623669
36633670 // Emit NOP at the try: line so LINE events fire for it
@@ -3733,22 +3740,23 @@ impl Compiler {
37333740 delta: reraise_star_block
37343741 }
37353742 ) ;
3743+ self . set_no_location ( ) ;
37363744 }
37373745 for ( i, handler) in handlers. iter ( ) . enumerate ( ) {
37383746 let ast:: ExceptHandler :: ExceptHandler ( ast:: ExceptHandlerExceptHandler {
37393747 type_,
37403748 name,
37413749 body,
3750+ range : handler_range,
37423751 ..
37433752 } ) = handler;
37443753 let is_last_handler = i == n - 1 ;
37453754
37463755 let no_match_block = self . new_block ( ) ;
3747- let except_with_error_block = self . new_block ( ) ;
3748- let handler_done_block = if is_last_handler {
3756+ let next_handler_block = if is_last_handler {
37493757 reraise_star_block
37503758 } else {
3751- except_with_error_block
3759+ self . new_block ( )
37523760 } ;
37533761
37543762 // Compile exception type
@@ -3806,7 +3814,7 @@ impl Compiler {
38063814 ) ;
38073815 self . push_fblock_full (
38083816 FBlockType :: HandlerCleanup ,
3809- handler_done_block ,
3817+ next_handler_block ,
38103818 end_block,
38113819 if let Some ( alias) = name {
38123820 FBlockDatum :: ExceptionName ( alias. as_str ( ) . to_owned ( ) )
@@ -3819,6 +3827,7 @@ impl Compiler {
38193827 self . compile_statements ( body) ?;
38203828
38213829 // Handler body completed normally
3830+ self . set_no_location ( ) ;
38223831 emit ! ( self , PseudoInstruction :: PopBlock ) ;
38233832 self . pop_fblock ( FBlockType :: HandlerCleanup ) ;
38243833
@@ -3831,12 +3840,11 @@ impl Compiler {
38313840
38323841 if is_last_handler {
38333842 emit ! ( self , Instruction :: ListAppend { i: 1 } ) ;
3834- } else {
38353843 }
38363844 emit ! (
38373845 self ,
38383846 PseudoInstruction :: Jump {
3839- delta: handler_done_block
3847+ delta: next_handler_block
38403848 }
38413849 ) ;
38423850
@@ -3846,6 +3854,7 @@ impl Compiler {
38463854 // (lasti is pushed because push_lasti=true in HANDLER_CLEANUP fblock)
38473855
38483856 // Cleanup name binding
3857+ self . set_no_location ( ) ;
38493858 if let Some ( alias) = name {
38503859 self . emit_load_const ( ConstantData :: None ) ;
38513860 self . store_name ( alias. as_str ( ) ) ?;
@@ -3876,16 +3885,18 @@ impl Compiler {
38763885 emit ! (
38773886 self ,
38783887 PseudoInstruction :: Jump {
3879- delta: except_with_error_block
3888+ delta: next_handler_block
38803889 }
38813890 ) ;
38823891 }
38833892
38843893 if is_last_handler {
38853894 self . switch_to_block ( no_match_block) ;
3895+ self . set_source_range ( * handler_range) ;
38863896 emit ! ( self , Instruction :: PopTop ) ; // pop match (None)
38873897 // Stack: [prev_exc, orig, list, new_rest]
38883898
3899+ self . set_no_location ( ) ;
38893900 emit ! ( self , Instruction :: ListAppend { i: 1 } ) ;
38903901 emit ! (
38913902 self ,
@@ -3895,10 +3906,10 @@ impl Compiler {
38953906 ) ;
38963907 } else {
38973908 self . switch_to_block ( no_match_block) ;
3909+ self . set_source_range ( * handler_range) ;
38983910 emit ! ( self , Instruction :: PopTop ) ; // pop match (None)
38993911 // Stack: [prev_exc, orig, list, new_rest]
3900-
3901- self . switch_to_block ( except_with_error_block) ;
3912+ self . switch_to_block ( next_handler_block) ;
39023913 }
39033914 }
39043915
@@ -3908,6 +3919,7 @@ impl Compiler {
39083919 // Reraise star block
39093920 self . switch_to_block ( reraise_star_block) ;
39103921 // Stack: [prev_exc, orig, list]
3922+ self . set_no_location ( ) ;
39113923
39123924 // CALL_INTRINSIC_2 PREP_RERAISE_STAR
39133925 // Takes 2 args (orig, list) and produces result
@@ -3957,6 +3969,7 @@ impl Compiler {
39573969 // Reraise the result
39583970 self . switch_to_block ( reraise_block) ;
39593971 // Stack: [prev_exc, result]
3972+ self . set_no_location ( ) ;
39603973
39613974 emit ! ( self , PseudoInstruction :: PopBlock ) ;
39623975 emit ! ( self , Instruction :: Swap { i: 2 } ) ;
@@ -3970,6 +3983,7 @@ impl Compiler {
39703983 emit ! ( self , Instruction :: Reraise { depth: 0 } ) ;
39713984
39723985 self . switch_to_block ( cleanup_block) ;
3986+ self . set_no_location ( ) ;
39733987 emit ! ( self , Instruction :: Copy { i: 3 } ) ;
39743988 emit ! ( self , Instruction :: PopExcept ) ;
39753989 emit ! ( self , Instruction :: Reraise { depth: 1 } ) ;
@@ -3993,21 +4007,23 @@ impl Compiler {
39934007 FBlockDatum :: FinallyBody ( finalbody. to_vec ( ) ) ,
39944008 ) ?;
39954009 }
3996- self . switch_to_block ( else_block) ;
3997- self . compile_statements ( orelse) ?;
3998-
3999- if !finalbody. is_empty ( ) {
4000- // Pop the FinallyTry fblock we just pushed for the else path
4001- emit ! ( self , PseudoInstruction :: PopBlock ) ;
4002- self . pop_fblock ( FBlockType :: FinallyTry ) ;
4003- }
4010+ if else_block != continuation_block {
4011+ self . switch_to_block ( else_block) ;
4012+ self . compile_statements ( orelse) ?;
40044013
4005- emit ! (
4006- self ,
4007- PseudoInstruction :: Jump {
4008- delta : continuation_block
4014+ if !finalbody . is_empty ( ) {
4015+ // Pop the FinallyTry fblock we just pushed for the else path
4016+ emit ! ( self , PseudoInstruction :: PopBlock ) ;
4017+ self . pop_fblock ( FBlockType :: FinallyTry ) ;
40094018 }
4010- ) ;
4019+
4020+ emit ! (
4021+ self ,
4022+ PseudoInstruction :: Jump {
4023+ delta: continuation_block
4024+ }
4025+ ) ;
4026+ }
40114027
40124028 if !finalbody. is_empty ( ) {
40134029 self . switch_to_block ( end_block) ;
@@ -4051,7 +4067,11 @@ impl Compiler {
40514067 }
40524068 }
40534069
4054- self . switch_to_block ( exit_block) ;
4070+ self . switch_to_block ( if finalbody. is_empty ( ) {
4071+ end_block
4072+ } else {
4073+ exit_block
4074+ } ) ;
40554075
40564076 Ok ( ( ) )
40574077 }
0 commit comments