-
Notifications
You must be signed in to change notification settings - Fork 888
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
struct_field_align_threshold breaks struct update syntax inside matches! macro #4926
Comments
Thank you for the report. I wonder if this stems back to not-so-long-ago addition of being able to destructure slices and structs and the splitting of the base variants to differentiate between For anyone interested in working on this, the function linked below would probably be a decent place to start hunting for the cause: Lines 1500 to 1507 in e81c393
|
Hey! I saw this issue and I thought I'd see if I could figure something out. Also @calebcartwright thanks for pointing me in the direction of
let fields_str = if struct_lit_can_be_aligned(fields, has_base)
&& context.config.struct_field_align_threshold() > 0
// get_lo in expr::rewrite_struct_lit
let span_lo = |item: &StructLitField<'_>| match *item {
StructLitField::Regular(field) => field.span().lo(),
StructLitField::Base(expr) => {
let last_field_hi = fields.last().map_or(span.lo(), |field| field.span.hi());
let snippet = context.snippet(mk_sp(last_field_hi, expr.span.lo()));
let pos = snippet.find_uncommented("..").unwrap();
last_field_hi + BytePos(pos as u32)
}
StructLitField::Rest(span) => span.lo(),
}; V.S // get_lo in vertical::rewrite_aligned_items_inner
|field| field.get_span().lo()
|
So I kept digging and I actually think I've figured out what's going on. It's partially related to the things I figured out above, but there's a bit more too it. The main reason why the code is properly formatted in the In the Above I said that the For reference here's the match arm. let rewrite = |item: &StructLitField<'_>| match *item {
StructLitField::Regular(field) => {
// The 1 taken from the v_budget is for the comma.
rewrite_field(context, field, v_shape.sub_width(1)?, 0)
}
StructLitField::Base(expr) => {
// 2 = ..
expr.rewrite(context, v_shape.offset_left(2)?)
.map(|s| format!("..{}", s))
}
StructLitField::Rest(_) => {
debug!("Writing the rest")
Some("..".to_owned()), // <--Handle ".."
}
}; I think I have a fix and I'd like to open a PR! |
Playing a bit of catch up, and while there's been some great discussion here I think there's a much simpler fix available which I'll note on the associated PR.
I suspect you have probably already gained a better feel for this in the time that's past since that comment, but the short/grossly-simplified version is: Nodes in the AST (most of them anyway) have a Span field which is essentially a pointer back to the raw contents in the input source file. rustfmt uses the compiler's internal parser to process input files so that rustfmt sees the exact same AST that's produced in the early stages of rustc's compilation process. The primary motivation for the compiler to track these spans on the AST nodes is to be able to provide solid, contextual error messages and recommended fixes, whereas in rustfmt we often use them to peek back into the input source to look for comments (other than doc-style comments, comments are not explicitly represented in the AST). The original input files and their contents are maintained in a parsing data structure called the |
Sending the following code through
rustfmt --config struct_field_align_threshold=30
removes the..
, changing the meaning of the code.becomes
The text was updated successfully, but these errors were encountered: