@@ -2050,6 +2050,7 @@ impl Compiler {
20502050
20512051 fn compile_statement ( & mut self , statement : & ast:: Stmt ) -> CompileResult < ( ) > {
20522052 trace ! ( "Compiling {statement:?}" ) ;
2053+ let prev_source_range = self . current_source_range ;
20532054 self . set_source_range ( statement. range ( ) ) ;
20542055
20552056 match & statement {
@@ -2433,7 +2434,14 @@ impl Compiler {
24332434 value,
24342435 simple,
24352436 ..
2436- } ) => self . compile_annotated_assign ( target, annotation, value. as_deref ( ) , * simple) ?,
2437+ } ) => {
2438+ self . compile_annotated_assign ( target, annotation, value. as_deref ( ) , * simple) ?;
2439+ // Bare annotations in function scope emit no code; restore
2440+ // source range so subsequent instructions keep the correct line.
2441+ if value. is_none ( ) && self . ctx . in_func ( ) {
2442+ self . set_source_range ( prev_source_range) ;
2443+ }
2444+ }
24372445 ast:: Stmt :: Delete ( ast:: StmtDelete { targets, .. } ) => {
24382446 for target in targets {
24392447 self . compile_delete ( target) ?;
@@ -3807,7 +3815,6 @@ impl Compiler {
38073815 let code = self . exit_scope ( ) ;
38083816 self . ctx = prev_ctx;
38093817
3810- // Restore source range so MAKE_FUNCTION is attributed to the `def` line
38113818 self . set_source_range ( saved_range) ;
38123819
38133820 // Create function object with closure
@@ -5180,23 +5187,21 @@ impl Compiler {
51805187 // No PopBlock here - for async, POP_BLOCK is already in for_block
51815188 self . pop_fblock ( FBlockType :: ForLoop ) ;
51825189
5190+ // End-of-loop instructions are on the `for` line, not the body's last line
5191+ let saved_range = self . current_source_range ;
5192+ self . set_source_range ( iter. range ( ) ) ;
51835193 if is_async {
51845194 emit ! ( self , Instruction :: EndAsyncFor ) ;
51855195 } else {
5186- // END_FOR + POP_ITER are on the `for` line, not the body's last line
5187- let saved_range = self . current_source_range ;
5188- self . set_source_range ( iter. range ( ) ) ;
51895196 emit ! ( self , Instruction :: EndFor ) ;
51905197 emit ! ( self , Instruction :: PopIter ) ;
5191- self . set_source_range ( saved_range) ;
51925198 }
5199+ self . set_source_range ( saved_range) ;
51935200 self . compile_statements ( orelse) ?;
51945201
51955202 self . switch_to_block ( after_block) ;
51965203
5197- // Restore source range to the `for` line so any implicit return
5198- // (LOAD_CONST None, RETURN_VALUE) is attributed to the `for` line,
5199- // not the loop body's last line.
5204+ // Implicit return after for-loop should be attributed to the `for` line
52005205 self . set_source_range ( iter. range ( ) ) ;
52015206
52025207 self . leave_conditional_block ( ) ;
@@ -6233,6 +6238,8 @@ impl Compiler {
62336238 ops : & [ ast:: CmpOp ] ,
62346239 comparators : & [ ast:: Expr ] ,
62356240 ) -> CompileResult < ( ) > {
6241+ // Save the full Compare expression range for COMPARE_OP positions
6242+ let compare_range = self . current_source_range ;
62366243 let ( last_op, mid_ops) = ops. split_last ( ) . unwrap ( ) ;
62376244 let ( last_comparator, mid_comparators) = comparators. split_last ( ) . unwrap ( ) ;
62386245
@@ -6241,6 +6248,7 @@ impl Compiler {
62416248
62426249 if mid_comparators. is_empty ( ) {
62436250 self . compile_expression ( last_comparator) ?;
6251+ self . set_source_range ( compare_range) ;
62446252 self . compile_addcompare ( last_op) ;
62456253
62466254 return Ok ( ( ) ) ;
@@ -6253,6 +6261,7 @@ impl Compiler {
62536261 self . compile_expression ( comparator) ?;
62546262
62556263 // store rhs for the next comparison in chain
6264+ self . set_source_range ( compare_range) ;
62566265 emit ! ( self , Instruction :: Swap { index: 2 } ) ;
62576266 emit ! ( self , Instruction :: Copy { index: 2 } ) ;
62586267
@@ -6265,6 +6274,7 @@ impl Compiler {
62656274 }
62666275
62676276 self . compile_expression ( last_comparator) ?;
6277+ self . set_source_range ( compare_range) ;
62686278 self . compile_addcompare ( last_op) ;
62696279
62706280 let end = self . new_block ( ) ;
0 commit comments