Semantic Diff

#9119 Keep comments and doc comments where they were written when formatting

1 commit

e63fc6fd0f2b3c5c72a41e190540c085498e9a08..pr-9119

6d2afacd9 · cknitt + Claude · Oct 28, 2026, 20:24 UTC

Keep doc comments and comments in place in four formatter cases

Why

The formatter put doc comments and comments in the wrong place in four of the cases reported in #9107, and in one of them it reordered the attributes in the AST. Doc comments after an attribute were moved in front of all attributes. A single parameter with a doc comment was hugged, so its pattern started at column 0. A comment before a list's tail spread was printed after the dots, in expressions and in patterns. A file with only a line comment got an extra newline.

Only the doc comments in front of every other attribute are now printed first; later ones stay in their place, inline. The fifth case, a comment after a parenthesized switch or if operand that moves into the block, keeps its stable output.

modifiedAST doc comment after an attribute, after formatting

type u = /** d1 */ @a /** d2 */ {x: int}
parse
Before
After
type_declaration "u"type_declaration "u"├─ attribute "res.doc"├─ attribute "res.doc"├─ attribute "res.doc" └─ attribute "a"├─ attribute "a" └─ attribute "res.doc"

modifiedFormat doc comment after an attribute

type u = /** d1 */ @a /** d2 */ {x: int}
rescript
Before
After
/** d1 *//** d1 *//** d2 */@a type u = {x: int}@a /** d2 */ type u = {x: int}

modifiedFormat doc comment on a hugged parameter

let f = (/** r */ {x, y}) => x
rescript
Before
After
let f = (/** r */{x, y}) => x let f = ( /** r */ {x, y},) => x

modifiedFormat comment before a list's tail spread

let l = list{1, /* c */ ...xs}let f = (list{a, /* c */ ...rest}) => a
rescript
Before
After
let l = list{1, .../* c */ xs}let f = (list{a, .../* c */ rest}) => alet l = list{1, /* c */ ...xs}let f = (list{a, /* c */ ...rest}) => a

modifiedFormat file with only a line comment

// c
text
Before
After
"// c\n\n""// c\n"

Review

  • Why not fix the comment after a parenthesized operand? It formats stably with the same AST; fixing it needs a token flag on comments or operand locations that include the parentheses.