-
Notifications
You must be signed in to change notification settings - Fork 889
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
Implement trailing_semicolon = "Preserve"
#6149
base: master
Are you sure you want to change the base?
Changes from all commits
fc7f6e1
10e6db2
8f944d0
3126770
922e8ba
1973b90
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -49,6 +49,19 @@ pub enum ControlBraceStyle { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
AlwaysNextLine, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#[config_type] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/// How to treat the semicolon that is optional for final diverging expressions | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/// (`return`/`break`/`continue`). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pub enum TrailingSemicolon { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/// Always rewrite `return;` and `break;` expressions to have a trailing semicolon, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/// unless the block is a single-line block, e.g. `let PAT = e else { return }`. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is kind of weird, but preexisting behavior, I believe. I don't exactly understand what rustfmt does to avoid adding a semicolon for single-line-style blocks. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are different kinds of blocks. What kinds of blocks are you referencing? Just To the best of my knowledge all Lines 49 to 188 in 4b1596f
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm pretty sure all block rewriting eventually calls into |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Always, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/// Always return `return` and `break` expressions to remove the trailing semicolon. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just want to avoid any confusion with the docs. Since this is the /// Never add a trailing semicolon. This removes trailing semicolon's from `return` and `break` expressions. Also, this won't remove them from |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Never, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/// Preserve an existing trailing semicolon if it exists. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Preserve, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#[config_type] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/// How to indent. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pub enum IndentStyle { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,7 +8,7 @@ use crate::rewrite::{Rewrite, RewriteContext}; | |
use crate::shape::Shape; | ||
use crate::source_map::LineRangeUtils; | ||
use crate::spanned::Spanned; | ||
use crate::utils::semicolon_for_stmt; | ||
use crate::utils::{semicolon_for_expr, semicolon_for_stmt}; | ||
|
||
pub(crate) struct Stmt<'a> { | ||
inner: &'a ast::Stmt, | ||
|
@@ -116,7 +116,7 @@ fn format_stmt( | |
|
||
let result = match stmt.kind { | ||
ast::StmtKind::Local(ref local) => local.rewrite(context, shape), | ||
ast::StmtKind::Expr(ref ex) | ast::StmtKind::Semi(ref ex) => { | ||
ast::StmtKind::Semi(ref ex) => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. was this the cause of the double semicolon counting? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See the comment below; I pointed out the reason for the the double semicolon counting in more detail. I split these two branches because we need to preserve semicolons only if we have a |
||
let suffix = if semicolon_for_stmt(context, stmt, is_last_expr) { | ||
";" | ||
} else { | ||
|
@@ -126,6 +126,16 @@ fn format_stmt( | |
let shape = shape.sub_width(suffix.len())?; | ||
format_expr(ex, expr_type, context, shape).map(|s| s + suffix) | ||
} | ||
ast::StmtKind::Expr(ref ex) => { | ||
let suffix = if semicolon_for_expr(context, ex) { | ||
";" | ||
} else { | ||
"" | ||
}; | ||
|
||
let shape = shape.sub_width(suffix.len())?; | ||
format_expr(ex, expr_type, context, shape).map(|s| s + suffix) | ||
} | ||
ast::StmtKind::MacCall(..) | ast::StmtKind::Item(..) | ast::StmtKind::Empty => None, | ||
}; | ||
result.and_then(|res| recover_comment_removed(res, stmt.span(), context)) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,7 +10,7 @@ use rustc_span::{sym, symbol, BytePos, LocalExpnId, Span, Symbol, SyntaxContext} | |
use unicode_width::UnicodeWidthStr; | ||
|
||
use crate::comment::{filter_normal_code, CharClasses, FullCodeCharKind, LineClasses}; | ||
use crate::config::{Config, Version}; | ||
use crate::config::{Config, TrailingSemicolon, Version}; | ||
use crate::rewrite::RewriteContext; | ||
use crate::shape::{Indent, Shape}; | ||
|
||
|
@@ -273,15 +273,43 @@ pub(crate) fn contains_skip(attrs: &[Attribute]) -> bool { | |
#[inline] | ||
pub(crate) fn semicolon_for_expr(context: &RewriteContext<'_>, expr: &ast::Expr) -> bool { | ||
// Never try to insert semicolons on expressions when we're inside | ||
// a macro definition - this can prevent the macro from compiling | ||
// a macro definition - this can prevent the macro from compiling | ||
// when used in expression position | ||
if context.is_macro_def { | ||
return false; | ||
} | ||
|
||
match expr.kind { | ||
ast::ExprKind::Ret(..) | ast::ExprKind::Continue(..) | ast::ExprKind::Break(..) => { | ||
context.config.trailing_semicolon() | ||
match context.config.trailing_semicolon() { | ||
TrailingSemicolon::Always => true, | ||
TrailingSemicolon::Never | TrailingSemicolon::Preserve => false, | ||
} | ||
} | ||
_ => false, | ||
} | ||
} | ||
|
||
/// Previously, we used to have `trailing_semicolon = Always` enabled, and due to | ||
/// a bug between `format_stmt` and `format_expr`, we used to subtract the size of | ||
/// `;` *TWICE* from the shape. This means that an expr that would fit onto a line | ||
/// of, e.g. 99 (limit 100) after subtracting one for the semicolon would still be | ||
/// wrapped. | ||
/// | ||
/// This function reimplements the old heuristic of double counting the "phantom" | ||
/// semicolon that should have already been accounted for, to not break existing | ||
/// formatting with the `trailing_semicolon = Preserve` behavior for Version = One. | ||
#[inline] | ||
pub(crate) fn semicolon_for_expr_extra_hacky_double_counted_spacing( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we still need this function if we're version gating the fix and only applying the old behavior for |
||
context: &RewriteContext<'_>, | ||
expr: &ast::Expr, | ||
) -> bool { | ||
match expr.kind { | ||
ast::ExprKind::Ret(..) | ast::ExprKind::Continue(..) | ast::ExprKind::Break(..) => { | ||
match context.config.trailing_semicolon() { | ||
TrailingSemicolon::Always | TrailingSemicolon::Preserve => true, | ||
TrailingSemicolon::Never => false, | ||
} | ||
} | ||
_ => false, | ||
} | ||
|
@@ -301,7 +329,14 @@ pub(crate) fn semicolon_for_stmt( | |
ast::ExprKind::Break(..) | ast::ExprKind::Continue(..) | ast::ExprKind::Ret(..) => { | ||
// The only time we can skip the semi-colon is if the config option is set to false | ||
// **and** this is the last expr (even though any following exprs are unreachable) | ||
context.config.trailing_semicolon() || !is_last_expr | ||
if !is_last_expr { | ||
true | ||
} else { | ||
match context.config.trailing_semicolon() { | ||
TrailingSemicolon::Always | TrailingSemicolon::Preserve => true, | ||
TrailingSemicolon::Never => false, | ||
} | ||
} | ||
} | ||
_ => true, | ||
}, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
// rustfmt-version: One | ||
|
||
fn main() { | ||
return hellooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo(arg); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These aren't changes we necessarily need to make, but it might also be nice to include examples with
break;
andcontinue;
to further demonstrate how this will work. Possibly adding alet-else
example.