Skip to content

Chain comments after . prevent chain from being formatted because comment would be lost #5563

Open
@ytmimi

Description

@ytmimi

If a comment follows the . in a chain, then the chain is not formatted because a comment would be lost. This behavior can be seen when running rustfmt with error_on_unformatted=true. However the chain is rewritten if the comment comes before the .

tested using rustfmt 1.5.1-nightly (ef911542 2022-09-19).

Input

fn not_formatted() {
    let a = b./*cc*/       ddd;
    let e = f.// gg
hhh;
}

fn formated() {
    let i = j/*kk*/       .lll;
    let m = n// oo
.ppp;
}

Output

fn not_formatted() {
    let a = b./*cc*/       ddd;
    let e = f.// gg
hhh;
}

fn formated() {
    let i = j /*kk*/
        .lll;
    let m = n // oo
        .ppp;
}

Error Output

error[internal]: not formatted because a comment would be lost
 --> <stdin>:2
  |
2 |     let a = b./*cc*/       ddd;
  |
  = note: set `error_on_unformatted = false` to suppress the warning against comments or string literals

error[internal]: not formatted because a comment would be lost
 --> <stdin>:3
  |
3 |     let e = f.// gg
  |
  = note: set `error_on_unformatted = false` to suppress the warning against comments or string literals


I think the issue is that we don't expect to find comments after the . when rewriting ChainItem, and the examples above specifically highlight the ChainItemKind::StructField match arm:

rustfmt/src/chains.rs

Lines 246 to 271 in ef91154

impl Rewrite for ChainItem {
fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
let shape = shape.sub_width(self.tries)?;
let rewrite = match self.kind {
ChainItemKind::Parent(ref expr) => expr.rewrite(context, shape)?,
ChainItemKind::MethodCall(ref segment, ref types, ref exprs) => {
Self::rewrite_method_call(segment.ident, types, exprs, self.span, context, shape)?
}
ChainItemKind::StructField(ident) => format!(".{}", rewrite_ident(context, ident)),
ChainItemKind::TupleField(ident, nested) => format!(
"{}.{}",
if nested && context.config.version() == Version::One {
" "
} else {
""
},
rewrite_ident(context, ident)
),
ChainItemKind::Await => ".await".to_owned(),
ChainItemKind::Comment(ref comment, _) => {
rewrite_comment(comment, false, shape, context.config)?
}
};
Some(format!("{}{}", rewrite, "?".repeat(self.tries)))
}
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions