@@ -584,24 +584,43 @@ def accept_loop(
584584 * ,
585585 exit_condition : Expression | None = None ,
586586 ) -> None :
587- """Repeatedly type check a loop body until the frame doesn't change.
588- If exit_condition is set, assume it must be False on exit from the loop.
587+ """Repeatedly type check a loop body until the frame doesn't change."""
589588
590- Then check the else_body.
591- """
592- # The outer frame accumulates the results of all iterations
589+ # The outer frame accumulates the results of all iterations:
593590 with self .binder .frame_context (can_skip = False , conditional_frame = True ):
591+
592+ # Check for potential decreases in the number of partial types so as not to stop the
593+ # iteration too early:
594594 partials_old = sum (len (pts .map ) for pts in self .partial_types )
595+
596+ # Disable error types that we cannot safely identify in intermediate iteration steps:
597+ warn_unreachable = self .options .warn_unreachable
598+ warn_redundant = codes .REDUNDANT_EXPR in self .options .enabled_error_codes
599+ self .options .warn_unreachable = False
600+ self .options .enabled_error_codes .discard (codes .REDUNDANT_EXPR )
601+
595602 while True :
596603 with self .binder .frame_context (can_skip = True , break_frame = 2 , continue_frame = 1 ):
597604 self .accept (body )
598605 partials_new = sum (len (pts .map ) for pts in self .partial_types )
599606 if (partials_new == partials_old ) and not self .binder .last_pop_changed :
600607 break
601608 partials_old = partials_new
609+
610+ # If necessary, reset the modified options and make up for the postponed error checks:
611+ self .options .warn_unreachable = warn_unreachable
612+ if warn_redundant :
613+ self .options .enabled_error_codes .add (codes .REDUNDANT_EXPR )
614+ if warn_unreachable or warn_redundant :
615+ with self .binder .frame_context (can_skip = True , break_frame = 2 , continue_frame = 1 ):
616+ self .accept (body )
617+
618+ # If exit_condition is set, assume it must be False on exit from the loop:
602619 if exit_condition :
603620 _ , else_map = self .find_isinstance_check (exit_condition )
604621 self .push_type_map (else_map )
622+
623+ # Check the else body:
605624 if else_body :
606625 self .accept (else_body )
607626
0 commit comments