diff --git a/crates/ruff_python_formatter/src/comments/placement.rs b/crates/ruff_python_formatter/src/comments/placement.rs index 9eb26ec292..f705333a87 100644 --- a/crates/ruff_python_formatter/src/comments/placement.rs +++ b/crates/ruff_python_formatter/src/comments/placement.rs @@ -747,50 +747,49 @@ fn handle_trailing_end_of_line_condition_comment<'a>( // If the preceding is the node before the `colon` // `while true:` The node before the `colon` is the `true` constant. - if preceding.ptr_eq(last_before_colon) { - let tokens = SimpleTokenizer::new( - locator.contents(), - TextRange::new(preceding.end(), following.start()), - ) - .skip_trivia(); + if !preceding.ptr_eq(last_before_colon) { + return CommentPlacement::Default(comment); + } + let mut colon_token = SimpleTokenizer::new( + locator.contents(), + TextRange::new(preceding.end(), following.start()), + ) + .skip_trivia() + // Skip over any closing parentheses and any trailing comma + .skip_while(|token| { + token.kind == SimpleTokenKind::RParen || token.kind == SimpleTokenKind::Comma + }); - for token in tokens { - match token.kind() { - SimpleTokenKind::Colon => { - if comment.slice().start() > token.start() { - // Comment comes after the colon - // ```python - // while a: # comment - // ... - // ``` - return CommentPlacement::dangling(enclosing_node, comment); - } - - // Comment comes before the colon - // ```python - // while ( - // a # comment - // ): - // ... - // ``` - break; - } - SimpleTokenKind::RParen => { - // Skip over any closing parentheses - } - SimpleTokenKind::Comma => { - // Skip over any trailing comma - } - kind => { - unreachable!( - "Only ')' or ':' should follow the condition but encountered {kind:?}" - ) - } + match colon_token.next() { + Some(token) if token.kind == SimpleTokenKind::Colon => { + if comment.slice().start() > token.start() { + // Comment comes after the colon + // ```python + // while a: # comment + // ... + // ``` + return CommentPlacement::dangling(enclosing_node, comment); } + + // Comment comes before the colon + // ```python + // while ( + // a # comment + // ): + // ... + // ``` + return CommentPlacement::Default(comment); + } + Some(token) => { + unreachable!( + "Only ')' or ':' should follow the condition but encountered {:?}", + token.kind + ) + } + None => { + unreachable!("Expected trailing condition comment to be preceded by a token",) } } - - CommentPlacement::Default(comment) } /// Handles end of line comments after the `:` of an except clause @@ -1173,35 +1172,33 @@ fn handle_dict_unpacking_comment<'a>( locator.contents(), TextRange::new(preceding_end, comment.slice().start()), ) - .skip_trivia(); + .skip_trivia() + .skip_while(|token| token.kind == SimpleTokenKind::RParen); // if the remaining tokens from the previous node are exactly `**`, // re-assign the comment to the one that follows the stars let mut count = 0; // we start from the preceding node but we skip its token - for token in tokens.by_ref() { - // Skip closing parentheses that are not part of the node range - if token.kind == SimpleTokenKind::RParen { - continue; - } + if let Some(token) = tokens.next() { // The Keyword case if token.kind == SimpleTokenKind::Star { count += 1; - break; + } else { + // The dict case + debug_assert!( + matches!( + token, + SimpleToken { + kind: SimpleTokenKind::LBrace + | SimpleTokenKind::Comma + | SimpleTokenKind::Colon, + .. + } + ), + "{token:?}", + ); } - // The dict case - debug_assert!( - matches!( - token, - SimpleToken { - kind: SimpleTokenKind::LBrace | SimpleTokenKind::Comma | SimpleTokenKind::Colon, - .. - } - ), - "{token:?}", - ); - break; } for token in tokens {