From 75765f656ebae28dbbc6f93d36a1e851473aeec9 Mon Sep 17 00:00:00 2001 From: Ruby Lazuli Date: Sat, 22 May 2021 08:22:42 -0500 Subject: [PATCH 001/111] Allow `--edition 2021` to be passed to rustfmt This was added to Configurations.md in #4618, but the option wasn't actually made available. This should let people who are using Rust 2021 on nightly rustc run `cargo fmt` again. --- src/bin/main.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bin/main.rs b/src/bin/main.rs index 56b07222212f..92fe8b9c5143 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -689,6 +689,7 @@ fn edition_from_edition_str(edition_str: &str) -> Result { match edition_str { "2015" => Ok(Edition::Edition2015), "2018" => Ok(Edition::Edition2018), + "2021" => Ok(Edition::Edition2021), _ => Err(format_err!("Invalid value for `--edition`")), } } From 1ca3798d2c961c43b02e312e8aa0e4bfa3f1b37e Mon Sep 17 00:00:00 2001 From: Casey Rodarmor Date: Sun, 9 May 2021 20:01:24 -0700 Subject: [PATCH 002/111] Improve pasta copyability of `merge_imports` deprecation message Add double quotes around `Crate` so that it can be copied directly into a `Cargo.toml` file --- src/config/config_type.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config/config_type.rs b/src/config/config_type.rs index 2f567b255210..7fc4486ddcd3 100644 --- a/src/config/config_type.rs +++ b/src/config/config_type.rs @@ -409,7 +409,7 @@ macro_rules! create_config { if self.was_set().merge_imports() { eprintln!( "Warning: the `merge_imports` option is deprecated. \ - Use `imports_granularity=Crate` instead" + Use `imports_granularity=\"Crate\"` instead" ); if !self.was_set().imports_granularity() { self.imports_granularity.2 = if self.merge_imports() { From 486e774fbfbbe2be98cdd2ebdbfc3e8b92fc2a95 Mon Sep 17 00:00:00 2001 From: Michael Murphy Date: Fri, 11 Jun 2021 02:39:28 +0100 Subject: [PATCH 003/111] Adjusting help message (#4865) On stable, running with `--help|-h` shows information about `file-lines` which is a nightly-only option. This commit removes all mention of `file-lines` from the help message on stable. There is room for improvement here; perhaps a new struct called, e.g., `StableOptions` could be added to complement the existing `GetOptsOptions` struct. `StableOptions` could have a field for each field in `GetOptsOptions`, with each field's value being a `bool` that specifies whether or not the option exists on stable. Or is this adding too much complexity? --- src/bin/main.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/bin/main.rs b/src/bin/main.rs index 92fe8b9c5143..4b4aa42d9359 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -178,12 +178,15 @@ fn make_opts() -> Options { opts.optflag("v", "verbose", "Print verbose output"); opts.optflag("q", "quiet", "Print less output"); opts.optflag("V", "version", "Show version information"); - opts.optflagopt( - "h", - "help", - "Show this message or help about a specific topic: `config` or `file-lines`", - "=TOPIC", - ); + let help_topics = if is_nightly { + "`config` or `file-lines`" + } else { + "`config`" + }; + let mut help_topic_msg = "Show this message or help about a specific topic: ".to_owned(); + help_topic_msg.push_str(help_topics); + + opts.optflagopt("h", "help", &help_topic_msg, "=TOPIC"); opts } @@ -437,7 +440,7 @@ fn determine_operation(matches: &Matches) -> Result { return Ok(Operation::Help(HelpOp::None)); } else if topic == Some("config".to_owned()) { return Ok(Operation::Help(HelpOp::Config)); - } else if topic == Some("file-lines".to_owned()) { + } else if topic == Some("file-lines".to_owned()) && is_nightly() { return Ok(Operation::Help(HelpOp::FileLines)); } else { return Err(OperationError::UnknownHelpTopic(topic.unwrap())); From e634a6f9a8ad9435f2d9f6bbfb6a8eb018ee8e3f Mon Sep 17 00:00:00 2001 From: Michael Murphy Date: Wed, 16 Jun 2021 04:33:34 +0100 Subject: [PATCH 004/111] Updating outdated links (#4869) * Updating outdated links Updating the links to the docs and source code for `ast.rs`. Seems like it was moved to a new crate at some point. * Updating more outdated links This time, the links to the `fmt-rfcs` repository, which is now owned by `rust-dev-tools` (although GitHub was redirecting anyway). * Update Contributing.md Co-authored-by: Caleb Cartwright Co-authored-by: Caleb Cartwright --- Contributing.md | 4 ++-- README.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Contributing.md b/Contributing.md index 1b77dad11f0f..a108195beb9a 100644 --- a/Contributing.md +++ b/Contributing.md @@ -138,8 +138,8 @@ format. There are different nodes for every kind of item and expression in Rust. For more details see the source code in the compiler - -[ast.rs](https://dxr.mozilla.org/rust/source/src/libsyntax/ast.rs) - and/or the -[docs](https://doc.rust-lang.org/nightly/nightly-rustc/syntax/ast/index.html). +[ast.rs](https://github.com/rust-lang/rust/blob/master/compiler/rustc_ast/src/ast.rs) - and/or the +[docs](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/ast/index.html). Many nodes in the AST (but not all, annoyingly) have a `Span`. A `Span` is a range in the source code, it can easily be converted to a snippet of source diff --git a/README.md b/README.md index 500a9f9a37c8..9c7a1c4bc341 100644 --- a/README.md +++ b/README.md @@ -230,5 +230,5 @@ Apache License (Version 2.0). See [LICENSE-APACHE](LICENSE-APACHE) and [LICENSE-MIT](LICENSE-MIT) for details. [rust]: https://github.com/rust-lang/rust -[fmt rfcs]: https://github.com/rust-lang-nursery/fmt-rfcs -[style guide]: https://github.com/rust-lang-nursery/fmt-rfcs/blob/master/guide/guide.md +[fmt rfcs]: https://github.com/rust-dev-tools/fmt-rfcs +[style guide]: https://github.com/rust-dev-tools/fmt-rfcs/blob/master/guide/guide.md From b305d62e5b9e08c6f4540de0a349fbf6da3dc0e4 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Thu, 24 Jun 2021 18:22:28 -0500 Subject: [PATCH 005/111] fix: correct arm leading pipe check (#4880) In the event a pattern starts with a leading pipe the pattern span will contain, and begin with, the pipe. This updates the process to see if a match arm contains a leading pipe by leveraging this recent(ish) change to the patterns in the AST, and avoids an indexing bug that occurs when a pattern starts with a non-ascii char in the old implementation. --- src/matches.rs | 7 ++++--- .../configs/match_arm_leading_pipes/preserve.rs | 8 ++++++++ .../configs/match_arm_leading_pipes/preserve.rs | 8 ++++++++ tests/target/issue_4868.rs | 17 +++++++++++++++++ 4 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 tests/target/issue_4868.rs diff --git a/src/matches.rs b/src/matches.rs index f33fedce92da..140ec226c02e 100644 --- a/src/matches.rs +++ b/src/matches.rs @@ -19,7 +19,7 @@ use crate::source_map::SpanUtils; use crate::spanned::Spanned; use crate::utils::{ contains_skip, extra_offset, first_line_width, inner_attributes, last_line_extendable, mk_sp, - mk_sp_lo_plus_one, semicolon_for_expr, trimmed_last_line_width, unicode_str_width, + semicolon_for_expr, trimmed_last_line_width, unicode_str_width, }; /// A simple wrapper type against `ast::Arm`. Used inside `write_list()`. @@ -167,8 +167,9 @@ fn collect_beginning_verts( arms.iter() .map(|a| { context - .snippet_provider - .opt_span_before(mk_sp_lo_plus_one(a.pat.span.lo()), "|") + .snippet(a.pat.span) + .starts_with("|") + .then(|| a.pat.span().lo()) }) .collect() } diff --git a/tests/source/configs/match_arm_leading_pipes/preserve.rs b/tests/source/configs/match_arm_leading_pipes/preserve.rs index ea303e857def..5486877bde19 100644 --- a/tests/source/configs/match_arm_leading_pipes/preserve.rs +++ b/tests/source/configs/match_arm_leading_pipes/preserve.rs @@ -26,3 +26,11 @@ fn bar() { _ => {} } } + +fn f(x: NonAscii) -> bool { + match x { + // foo + | Éfgh => true, + _ => false, + } +} \ No newline at end of file diff --git a/tests/target/configs/match_arm_leading_pipes/preserve.rs b/tests/target/configs/match_arm_leading_pipes/preserve.rs index 2beb1f5d8133..4775575842ab 100644 --- a/tests/target/configs/match_arm_leading_pipes/preserve.rs +++ b/tests/target/configs/match_arm_leading_pipes/preserve.rs @@ -25,3 +25,11 @@ fn bar() { _ => {} } } + +fn f(x: NonAscii) -> bool { + match x { + // foo + | Éfgh => true, + _ => false, + } +} diff --git a/tests/target/issue_4868.rs b/tests/target/issue_4868.rs new file mode 100644 index 000000000000..763a82c3231f --- /dev/null +++ b/tests/target/issue_4868.rs @@ -0,0 +1,17 @@ +enum NonAscii { + Abcd, + Éfgh, +} + +use NonAscii::*; + +fn f(x: NonAscii) -> bool { + match x { + Éfgh => true, + _ => false, + } +} + +fn main() { + dbg!(f(Abcd)); +} From 19733f19f18e2f2a1510667c078c7fc7739b3c54 Mon Sep 17 00:00:00 2001 From: Jethro Beekman Date: Fri, 25 Jun 2021 16:17:43 +0200 Subject: [PATCH 006/111] Change line endings from CRLF to LF --- appveyor.yml | 110 +++++++++++++++++++++++++-------------------------- 1 file changed, 55 insertions(+), 55 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 7bfe696009fa..5ac99fd71f8f 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,55 +1,55 @@ -# This is based on https://github.com/japaric/rust-everywhere/blob/master/appveyor.yml -# and modified (mainly removal of deployment) to suit rustfmt. - -environment: - global: - PROJECT_NAME: rustfmt - matrix: - # Stable channel - # - TARGET: i686-pc-windows-gnu - # CHANNEL: stable - # - TARGET: i686-pc-windows-msvc - # CHANNEL: stable - # - TARGET: x86_64-pc-windows-gnu - # CHANNEL: stable - # - TARGET: x86_64-pc-windows-msvc - # CHANNEL: stable - # Beta channel - # - TARGET: i686-pc-windows-gnu - # CHANNEL: beta - # - TARGET: i686-pc-windows-msvc - # CHANNEL: beta - # - TARGET: x86_64-pc-windows-gnu - # CHANNEL: beta - # - TARGET: x86_64-pc-windows-msvc - # CHANNEL: beta - # Nightly channel - - TARGET: i686-pc-windows-gnu - CHANNEL: nightly - - TARGET: i686-pc-windows-msvc - CHANNEL: nightly - - TARGET: x86_64-pc-windows-gnu - CHANNEL: nightly - - TARGET: x86_64-pc-windows-msvc - CHANNEL: nightly - -# Install Rust and Cargo -# (Based on from https://github.com/rust-lang/libc/blob/master/appveyor.yml) -install: - - appveyor-retry appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe - - if "%TARGET%" == "i686-pc-windows-gnu" set PATH=%PATH%;C:\msys64\mingw32\bin - - if "%TARGET%" == "x86_64-pc-windows-gnu" set PATH=%PATH%;C:\msys64\mingw64\bin - - set PATH=%PATH%;C:\Users\appveyor\.cargo\bin - - rustup-init.exe --default-host %TARGET% --default-toolchain %CHANNEL% -y - - rustc -Vv - - cargo -V - -# ??? -build: false - -test_script: - - set CFG_RELEASE_CHANNEL=nightly - - set CFG_RELEASE=nightly - - cargo build --verbose - - cargo test - - cargo test -- --ignored +# This is based on https://github.com/japaric/rust-everywhere/blob/master/appveyor.yml +# and modified (mainly removal of deployment) to suit rustfmt. + +environment: + global: + PROJECT_NAME: rustfmt + matrix: + # Stable channel + # - TARGET: i686-pc-windows-gnu + # CHANNEL: stable + # - TARGET: i686-pc-windows-msvc + # CHANNEL: stable + # - TARGET: x86_64-pc-windows-gnu + # CHANNEL: stable + # - TARGET: x86_64-pc-windows-msvc + # CHANNEL: stable + # Beta channel + # - TARGET: i686-pc-windows-gnu + # CHANNEL: beta + # - TARGET: i686-pc-windows-msvc + # CHANNEL: beta + # - TARGET: x86_64-pc-windows-gnu + # CHANNEL: beta + # - TARGET: x86_64-pc-windows-msvc + # CHANNEL: beta + # Nightly channel + - TARGET: i686-pc-windows-gnu + CHANNEL: nightly + - TARGET: i686-pc-windows-msvc + CHANNEL: nightly + - TARGET: x86_64-pc-windows-gnu + CHANNEL: nightly + - TARGET: x86_64-pc-windows-msvc + CHANNEL: nightly + +# Install Rust and Cargo +# (Based on from https://github.com/rust-lang/libc/blob/master/appveyor.yml) +install: + - appveyor-retry appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe + - if "%TARGET%" == "i686-pc-windows-gnu" set PATH=%PATH%;C:\msys64\mingw32\bin + - if "%TARGET%" == "x86_64-pc-windows-gnu" set PATH=%PATH%;C:\msys64\mingw64\bin + - set PATH=%PATH%;C:\Users\appveyor\.cargo\bin + - rustup-init.exe --default-host %TARGET% --default-toolchain %CHANNEL% -y + - rustc -Vv + - cargo -V + +# ??? +build: false + +test_script: + - set CFG_RELEASE_CHANNEL=nightly + - set CFG_RELEASE=nightly + - cargo build --verbose + - cargo test + - cargo test -- --ignored From 2cf280ed1ba84001aa4e14152ae37cea18ebcb1c Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Sun, 4 Jul 2021 22:26:08 -0500 Subject: [PATCH 007/111] docs: clarify match_arm_blocks config documentation --- Configurations.md | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/Configurations.md b/Configurations.md index 9daa70653797..d2e5613eba96 100644 --- a/Configurations.md +++ b/Configurations.md @@ -1475,7 +1475,9 @@ Copyright 2018 The Rust Project Developers.`, etc.: ## `match_arm_blocks` -Wrap the body of arms in blocks when it does not fit on the same line with the pattern of arms +Controls whether arm bodies are wrapped in cases where the first line of the body cannot fit on the same line as the `=>` operator. + +The Style Guide requires that bodies are block wrapped by default if a line break is required after the `=>`, but this option can be used to disable that behavior to prevent wrapping arm bodies in that event, so long as the body does not contain multiple statements nor line comments. - **Default value**: `true` - **Possible values**: `true`, `false` @@ -1486,10 +1488,16 @@ Wrap the body of arms in blocks when it does not fit on the same line with the p ```rust fn main() { match lorem { - true => { + ipsum => { foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo(x) } - false => println!("{}", sit), + dolor => println!("{}", sit), + sit => foo( + "foooooooooooooooooooooooo", + "baaaaaaaaaaaaaaaaaaaaaaaarr", + "baaaaaaaaaaaaaaaaaaaazzzzzzzzzzzzz", + "qqqqqqqqquuuuuuuuuuuuuuuuuuuuuuuuuuxxx", + ), } } ``` @@ -1499,9 +1507,15 @@ fn main() { ```rust fn main() { match lorem { - true => + lorem => foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo(x), - false => println!("{}", sit), + ipsum => println!("{}", sit), + sit => foo( + "foooooooooooooooooooooooo", + "baaaaaaaaaaaaaaaaaaaaaaaarr", + "baaaaaaaaaaaaaaaaaaaazzzzzzzzzzzzz", + "qqqqqqqqquuuuuuuuuuuuuuuuuuuuuuuuuuxxx", + ), } } ``` From 4c2959fb12a6bd083003ec4371126211402e265d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Sun, 18 Jul 2021 10:44:39 +0200 Subject: [PATCH 008/111] fix a bunch of clippy warnings clippy::bind_instead_of_map clippy::branches_sharing_code clippy::collapsible_match clippy::inconsistent_struct_constructor clippy::int_plus_one clippy::iter_count clippy::iter_nth_zero clippy::manual_range_contains clippy::match_like_matches_macro clippy::needless::collect clippy::needless_question_mark clippy::needless_return clippy::op_ref clippy::option_as_ref_deref clippy::ptr_arg clippy::redundant_clone clippy::redundant_closure clippy::redundant_static_lifetimes clippy::search_is_some clippy::#single_char_add_str clippy::single_char_pattern clippy::single_component_path_imports clippy::single_match clippy::skip_while_next clippy::unnecessary_lazy_evaluations clippy::unnecessary_unwrap clippy::useless_conversion clippy::useless_format --- src/attr.rs | 2 +- src/cargo-fmt/main.rs | 4 ++-- src/chains.rs | 5 +---- src/closures.rs | 15 +++++-------- src/comment.rs | 21 ++++++++---------- src/config/file_lines.rs | 4 ++-- src/config/license.rs | 1 - src/emitter/diff.rs | 2 +- src/expr.rs | 30 +++++++++---------------- src/formatting/newline_style.rs | 2 +- src/imports.rs | 30 ++++++++++--------------- src/issues.rs | 14 +++--------- src/items.rs | 26 +++++++++------------- src/lib.rs | 6 +---- src/lists.rs | 11 ++++------ src/macros.rs | 39 +++++++++++++++------------------ src/missed_spans.rs | 8 +++---- src/overflow.rs | 28 ++++++++++------------- src/patterns.rs | 25 ++++++++++----------- src/rustfmt_diff.rs | 7 ++---- src/skip.rs | 6 ++--- src/source_file.rs | 2 +- src/string.rs | 4 ++-- src/syntux/parser.rs | 5 ++--- src/types.rs | 15 ++++--------- src/utils.rs | 5 ++--- src/visitor.rs | 18 +++++++-------- 27 files changed, 130 insertions(+), 205 deletions(-) diff --git a/src/attr.rs b/src/attr.rs index c5ffb074ba55..315eb10a9dbc 100644 --- a/src/attr.rs +++ b/src/attr.rs @@ -183,7 +183,7 @@ fn format_derive( } else if let SeparatorTactic::Always = context.config.trailing_comma() { // Retain the trailing comma. result.push_str(&item_str); - } else if item_str.ends_with(",") { + } else if item_str.ends_with(',') { // Remove the trailing comma. result.push_str(&item_str[..item_str.len() - 1]); } else { diff --git a/src/cargo-fmt/main.rs b/src/cargo-fmt/main.rs index 9062a2952ec1..ba693e852ffa 100644 --- a/src/cargo-fmt/main.rs +++ b/src/cargo-fmt/main.rs @@ -405,8 +405,8 @@ fn get_targets_recursive( .packages .iter() .find(|p| p.name == dependency.name && p.source.is_none()); - let manifest_path = if dependency_package.is_some() { - PathBuf::from(&dependency_package.unwrap().manifest_path) + let manifest_path = if let Some(dep_pkg) = dependency_package { + PathBuf::from(&dep_pkg.manifest_path) } else { let mut package_manifest_path = PathBuf::from(&package.manifest_path); package_manifest_path.pop(); diff --git a/src/chains.rs b/src/chains.rs index 8053f0e8fecc..614638ea2abf 100644 --- a/src/chains.rs +++ b/src/chains.rs @@ -231,10 +231,7 @@ impl ChainItem { } fn is_comment(&self) -> bool { - match self.kind { - ChainItemKind::Comment(..) => true, - _ => false, - } + matches!(self.kind, ChainItemKind::Comment(..)) } fn rewrite_method_call( diff --git a/src/closures.rs b/src/closures.rs index 3d65077ddc20..c9d46aef294a 100644 --- a/src/closures.rs +++ b/src/closures.rs @@ -336,7 +336,7 @@ pub(crate) fn rewrite_last_closure( // We force to use block for the body of the closure for certain kinds of expressions. if is_block_closure_forced(context, body) { - return rewrite_closure_with_block(body, &prefix, context, body_shape).and_then( + return rewrite_closure_with_block(body, &prefix, context, body_shape).map( |body_str| { match fn_decl.output { ast::FnRetTy::Default(..) if body_str.lines().count() <= 7 => { @@ -344,15 +344,15 @@ pub(crate) fn rewrite_last_closure( // closure. However, if the closure has a return type, then we must // keep the blocks. match rewrite_closure_expr(body, &prefix, context, shape) { - Some(ref single_line_body_str) + Some(single_line_body_str) if !single_line_body_str.contains('\n') => { - Some(single_line_body_str.clone()) + single_line_body_str } - _ => Some(body_str), + _ => body_str, } } - _ => Some(body_str), + _ => body_str, } }, ); @@ -377,10 +377,7 @@ pub(crate) fn rewrite_last_closure( pub(crate) fn args_have_many_closure(args: &[OverflowableItem<'_>]) -> bool { args.iter() .filter_map(OverflowableItem::to_expr) - .filter(|expr| match expr.kind { - ast::ExprKind::Closure(..) => true, - _ => false, - }) + .filter(|expr| matches!(expr.kind, ast::ExprKind::Closure(..))) .count() > 1 } diff --git a/src/comment.rs b/src/comment.rs index c71302fdd182..0f8118a408ec 100644 --- a/src/comment.rs +++ b/src/comment.rs @@ -67,10 +67,7 @@ impl<'a> CommentStyle<'a> { /// Returns `true` if the commenting style is for documentation. pub(crate) fn is_doc_comment(&self) -> bool { - match *self { - CommentStyle::TripleSlash | CommentStyle::Doc => true, - _ => false, - } + matches!(*self, CommentStyle::TripleSlash | CommentStyle::Doc) } pub(crate) fn opener(&self) -> &'a str { @@ -689,8 +686,8 @@ impl<'a> CommentRewrite<'a> { self.code_block_attr = None; self.item_block = None; - if line.starts_with("```") { - self.code_block_attr = Some(CodeBlockAttribute::new(&line[3..])) + if let Some(stripped) = line.strip_prefix("```") { + self.code_block_attr = Some(CodeBlockAttribute::new(stripped)) } else if self.fmt.config.wrap_comments() && ItemizedBlock::is_itemized_line(&line) { let ib = ItemizedBlock::new(&line); self.item_block = Some(ib); @@ -948,8 +945,8 @@ fn left_trim_comment_line<'a>(line: &'a str, style: &CommentStyle<'_>) -> (&'a s { (&line[4..], true) } else if let CommentStyle::Custom(opener) = *style { - if line.starts_with(opener) { - (&line[opener.len()..], true) + if let Some(ref stripped) = line.strip_prefix(opener) { + (stripped, true) } else { (&line[opener.trim_end().len()..], false) } @@ -968,8 +965,8 @@ fn left_trim_comment_line<'a>(line: &'a str, style: &CommentStyle<'_>) -> (&'a s || line.starts_with("**") { (&line[2..], line.chars().nth(1).unwrap() == ' ') - } else if line.starts_with('*') { - (&line[1..], false) + } else if let Some(stripped) = line.strip_prefix('*') { + (stripped, false) } else { (line, line.starts_with(' ')) } @@ -1682,8 +1679,8 @@ impl<'a> Iterator for CommentReducer<'a> { fn remove_comment_header(comment: &str) -> &str { if comment.starts_with("///") || comment.starts_with("//!") { &comment[3..] - } else if comment.starts_with("//") { - &comment[2..] + } else if let Some(ref stripped) = comment.strip_prefix("//") { + stripped } else if (comment.starts_with("/**") && !comment.starts_with("/**/")) || comment.starts_with("/*!") { diff --git a/src/config/file_lines.rs b/src/config/file_lines.rs index 22dd091cb510..4b799780d85d 100644 --- a/src/config/file_lines.rs +++ b/src/config/file_lines.rs @@ -305,7 +305,7 @@ impl str::FromStr for FileLines { let mut m = HashMap::new(); for js in v { let (s, r) = JsonSpan::into_tuple(js)?; - m.entry(s).or_insert_with(|| vec![]).push(r); + m.entry(s).or_insert_with(Vec::new).push(r); } Ok(FileLines::from_ranges(m)) } @@ -322,7 +322,7 @@ impl JsonSpan { fn into_tuple(self) -> Result<(FileName, Range), FileLinesError> { let (lo, hi) = self.range; let canonical = canonicalize_path_string(&self.file) - .ok_or_else(|| FileLinesError::CannotCanonicalize(self.file))?; + .ok_or(FileLinesError::CannotCanonicalize(self.file))?; Ok((canonical, Range::new(lo, hi))) } } diff --git a/src/config/license.rs b/src/config/license.rs index 121a1b1c151f..c7feb502ea91 100644 --- a/src/config/license.rs +++ b/src/config/license.rs @@ -3,7 +3,6 @@ use std::fs::File; use std::io; use std::io::Read; -use regex; use regex::Regex; #[derive(Debug)] diff --git a/src/emitter/diff.rs b/src/emitter/diff.rs index 9be4fb28f993..2fbbfedb566d 100644 --- a/src/emitter/diff.rs +++ b/src/emitter/diff.rs @@ -45,7 +45,7 @@ impl Emitter for DiffEmitter { return Ok(EmitterResult { has_diff: true }); } - return Ok(EmitterResult { has_diff }); + Ok(EmitterResult { has_diff }) } } diff --git a/src/expr.rs b/src/expr.rs index bca9f77f959e..6cfeb9977a96 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -263,15 +263,12 @@ pub(crate) fn format_expr( } fn needs_space_after_range(rhs: &ast::Expr) -> bool { - match rhs.kind { - // Don't format `.. ..` into `....`, which is invalid. - // - // This check is unnecessary for `lhs`, because a range - // starting from another range needs parentheses as `(x ..) ..` - // (`x .. ..` is a range from `x` to `..`). - ast::ExprKind::Range(None, _, _) => true, - _ => false, - } + // Don't format `.. ..` into `....`, which is invalid. + // + // This check is unnecessary for `lhs`, because a range + // starting from another range needs parentheses as `(x ..) ..` + // (`x .. ..` is a range from `x` to `..`). + matches!(rhs.kind, ast::ExprKind::Range(None, _, _)) } let default_sp_delim = |lhs: Option<&ast::Expr>, rhs: Option<&ast::Expr>| { @@ -531,7 +528,7 @@ pub(crate) fn rewrite_block_with_visitor( let inner_attrs = attrs.map(inner_attributes); let label_str = rewrite_label(label); - visitor.visit_block(block, inner_attrs.as_ref().map(|a| &**a), has_braces); + visitor.visit_block(block, inner_attrs.as_deref(), has_braces); let visitor_context = visitor.get_context(); context .skipped_range @@ -595,7 +592,7 @@ pub(crate) fn rewrite_cond( String::from("\n") + &shape.indent.block_only().to_string(context.config); control_flow .rewrite_cond(context, shape, &alt_block_sep) - .and_then(|rw| Some(rw.0)) + .map(|rw| rw.0) }), } } @@ -1157,18 +1154,11 @@ pub(crate) fn is_empty_block( } pub(crate) fn stmt_is_expr(stmt: &ast::Stmt) -> bool { - match stmt.kind { - ast::StmtKind::Expr(..) => true, - _ => false, - } + matches!(stmt.kind, ast::StmtKind::Expr(..)) } pub(crate) fn is_unsafe_block(block: &ast::Block) -> bool { - if let ast::BlockCheckMode::Unsafe(..) = block.rules { - true - } else { - false - } + matches!(block.rules, ast::BlockCheckMode::Unsafe(..)) } pub(crate) fn rewrite_literal( diff --git a/src/formatting/newline_style.rs b/src/formatting/newline_style.rs index ac6200949000..97c4fc16d6f5 100644 --- a/src/formatting/newline_style.rs +++ b/src/formatting/newline_style.rs @@ -77,7 +77,7 @@ fn convert_to_windows_newlines(formatted_text: &String) -> String { transformed } -fn convert_to_unix_newlines(formatted_text: &String) -> String { +fn convert_to_unix_newlines(formatted_text: &str) -> String { formatted_text.replace(WINDOWS_NEWLINE, UNIX_NEWLINE) } diff --git a/src/imports.rs b/src/imports.rs index 0f635fe1ccb3..64d78605f0c5 100644 --- a/src/imports.rs +++ b/src/imports.rs @@ -374,7 +374,7 @@ impl UseTree { UseTreeKind::Nested(ref list) => { // Extract comments between nested use items. // This needs to be done before sorting use items. - let items: Vec<_> = itemize_list( + let items = itemize_list( context.snippet_provider, list.iter().map(|(tree, _)| tree), "}", @@ -385,8 +385,8 @@ impl UseTree { context.snippet_provider.span_after(a.span, "{"), a.span.hi(), false, - ) - .collect(); + ); + // in case of a global path and the nested list starts at the root, // e.g., "::{foo, bar}" if a.prefix.segments.len() == 1 && leading_modsep { @@ -394,7 +394,7 @@ impl UseTree { } result.path.push(UseSegment::List( list.iter() - .zip(items.into_iter()) + .zip(items) .map(|(t, list_item)| { Self::from_ast(context, &t.0, Some(list_item), None, None, None) }) @@ -466,11 +466,8 @@ impl UseTree { // Normalise foo::self as bar -> foo as bar. if let UseSegment::Slf(_) = last { - match self.path.last() { - Some(UseSegment::Ident(_, None)) => { - aliased_self = true; - } - _ => {} + if let Some(UseSegment::Ident(_, None)) = self.path.last() { + aliased_self = true; } } @@ -572,9 +569,8 @@ impl UseTree { match self.path.clone().last().unwrap() { UseSegment::List(list) => { if list.len() == 1 && list[0].path.len() == 1 { - match list[0].path[0] { - UseSegment::Slf(..) => return vec![self], - _ => (), + if let UseSegment::Slf(..) = list[0].path[0] { + return vec![self]; }; } let prefix = &self.path[..self.path.len() - 1]; @@ -790,13 +786,9 @@ fn rewrite_nested_use_tree( } } let has_nested_list = use_tree_list.iter().any(|use_segment| { - use_segment - .path - .last() - .map_or(false, |last_segment| match last_segment { - UseSegment::List(..) => true, - _ => false, - }) + use_segment.path.last().map_or(false, |last_segment| { + matches!(last_segment, UseSegment::List(..)) + }) }); let remaining_width = if has_nested_list { diff --git a/src/issues.rs b/src/issues.rs index d369b75541ef..33fb5522aeae 100644 --- a/src/issues.rs +++ b/src/issues.rs @@ -126,11 +126,7 @@ impl BadIssueSeeker { return Seeking::Number { issue: Issue { issue_type: IssueType::Todo, - missing_number: if let ReportTactic::Unnumbered = self.report_todo { - true - } else { - false - }, + missing_number: matches!(self.report_todo, ReportTactic::Unnumbered), }, part: NumberPart::OpenParen, }; @@ -144,11 +140,7 @@ impl BadIssueSeeker { return Seeking::Number { issue: Issue { issue_type: IssueType::Fixme, - missing_number: if let ReportTactic::Unnumbered = self.report_fixme { - true - } else { - false - }, + missing_number: matches!(self.report_fixme, ReportTactic::Unnumbered), }, part: NumberPart::OpenParen, }; @@ -196,7 +188,7 @@ impl BadIssueSeeker { } } NumberPart::Number => { - if c >= '0' && c <= '9' { + if ('0'..='9').contains(&c) { part = NumberPart::CloseParen; } else { return IssueClassification::Bad(issue); diff --git a/src/items.rs b/src/items.rs index 420484c0ba11..0542358c6e7c 100644 --- a/src/items.rs +++ b/src/items.rs @@ -741,7 +741,7 @@ pub(crate) fn format_impl( // there is only one where-clause predicate // recover the suppressed comma in single line where_clause formatting if generics.where_clause.predicates.len() == 1 { - result.push_str(","); + result.push(','); } result.push_str(&format!("{}{{{}}}", sep, sep)); } else { @@ -1207,7 +1207,7 @@ impl<'a> Rewrite for TraitAliasBounds<'a> { let fits_single_line = !generic_bounds_str.contains('\n') && !where_str.contains('\n') - && generic_bounds_str.len() + where_str.len() + 1 <= shape.width; + && generic_bounds_str.len() + where_str.len() < shape.width; let space = if generic_bounds_str.is_empty() || where_str.is_empty() { Cow::from("") } else if fits_single_line { @@ -1236,8 +1236,8 @@ pub(crate) fn format_trait_alias( let lhs = format!("{}trait {} =", vis_str, generics_str); // 1 = ";" let trait_alias_bounds = TraitAliasBounds { - generics, generic_bounds, + generics, }; rewrite_assign_rhs(context, lhs, &trait_alias_bounds, shape.sub_width(1)?).map(|s| s + ";") } @@ -1993,7 +1993,7 @@ impl Rewrite for ast::Param { let num_attrs = self.attrs.len(); ( mk_sp(self.attrs[num_attrs - 1].span.hi(), self.pat.span.lo()), - param_attrs_result.contains("\n"), + param_attrs_result.contains('\n'), ) } else { (mk_sp(self.span.lo(), self.span.lo()), false) @@ -3265,22 +3265,16 @@ pub(crate) fn rewrite_extern_crate( /// Returns `true` for `mod foo;`, false for `mod foo { .. }`. pub(crate) fn is_mod_decl(item: &ast::Item) -> bool { - match item.kind { - ast::ItemKind::Mod(_, ast::ModKind::Loaded(_, ast::Inline::Yes, _)) => false, - _ => true, - } + !matches!( + item.kind, + ast::ItemKind::Mod(_, ast::ModKind::Loaded(_, ast::Inline::Yes, _)) + ) } pub(crate) fn is_use_item(item: &ast::Item) -> bool { - match item.kind { - ast::ItemKind::Use(_) => true, - _ => false, - } + matches!(item.kind, ast::ItemKind::Use(_)) } pub(crate) fn is_extern_crate(item: &ast::Item) -> bool { - match item.kind { - ast::ItemKind::ExternCrate(..) => true, - _ => false, - } + matches!(item.kind, ast::ItemKind::ExternCrate(..)) } diff --git a/src/lib.rs b/src/lib.rs index ce8a45eea653..eb314e63de36 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -30,7 +30,6 @@ use std::panic; use std::path::PathBuf; use std::rc::Rc; -use ignore; use rustc_ast::ast; use rustc_span::{symbol, DUMMY_SP}; use thiserror::Error; @@ -149,10 +148,7 @@ pub enum ErrorKind { impl ErrorKind { fn is_comment(&self) -> bool { - match self { - ErrorKind::LostComment => true, - _ => false, - } + matches!(self, ErrorKind::LostComment) } } diff --git a/src/lists.rs b/src/lists.rs index ccf8f784c045..73e886c55637 100644 --- a/src/lists.rs +++ b/src/lists.rs @@ -194,10 +194,7 @@ impl ListItem { // Returns `true` if the item causes something to be written. fn is_substantial(&self) -> bool { fn empty(s: &Option) -> bool { - match *s { - Some(ref s) if !s.is_empty() => false, - _ => true, - } + !matches!(*s, Some(ref s) if !s.is_empty()) } !(empty(&self.pre_comment) && empty(&self.item) && empty(&self.post_comment)) @@ -618,8 +615,8 @@ pub(crate) fn extract_post_comment( let post_snippet = post_snippet[..comment_end].trim(); let post_snippet_trimmed = if post_snippet.starts_with(|c| c == ',' || c == ':') { post_snippet[1..].trim_matches(white_space) - } else if post_snippet.starts_with(separator) { - post_snippet[separator.len()..].trim_matches(white_space) + } else if let Some(stripped) = post_snippet.strip_prefix(separator) { + stripped.trim_matches(white_space) } // not comment or over two lines else if post_snippet.ends_with(',') @@ -823,7 +820,7 @@ where pub(crate) fn total_item_width(item: &ListItem) -> usize { comment_len(item.pre_comment.as_ref().map(|x| &(*x)[..])) + comment_len(item.post_comment.as_ref().map(|x| &(*x)[..])) - + &item.item.as_ref().map_or(0, |s| unicode_str_width(&s)) + + item.item.as_ref().map_or(0, |s| unicode_str_width(&s)) } fn comment_len(comment: Option<&str>) -> usize { diff --git a/src/macros.rs b/src/macros.rs index bf4769b34aa8..6c5e32716c01 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -179,10 +179,10 @@ fn return_macro_parse_failure_fallback( .lines() .last() .map(|closing_line| { - closing_line.trim().chars().all(|ch| match ch { - '}' | ')' | ']' => true, - _ => false, - }) + closing_line + .trim() + .chars() + .all(|ch| matches!(ch, '}' | ')' | ']')) }) .unwrap_or(false); if is_like_block_indent_style { @@ -690,25 +690,22 @@ fn delim_token_to_str( impl MacroArgKind { fn starts_with_brace(&self) -> bool { - match *self { + matches!( + *self, MacroArgKind::Repeat(DelimToken::Brace, _, _, _) - | MacroArgKind::Delimited(DelimToken::Brace, _) => true, - _ => false, - } + | MacroArgKind::Delimited(DelimToken::Brace, _) + ) } fn starts_with_dollar(&self) -> bool { - match *self { - MacroArgKind::Repeat(..) | MacroArgKind::MetaVariable(..) => true, - _ => false, - } + matches!( + *self, + MacroArgKind::Repeat(..) | MacroArgKind::MetaVariable(..) + ) } fn ends_with_space(&self) -> bool { - match *self { - MacroArgKind::Separator(..) => true, - _ => false, - } + matches!(*self, MacroArgKind::Separator(..)) } fn has_meta_var(&self) -> bool { @@ -1162,10 +1159,10 @@ fn force_space_before(tok: &TokenKind) -> bool { } fn ident_like(tok: &Token) -> bool { - match tok.kind { - TokenKind::Ident(..) | TokenKind::Literal(..) | TokenKind::Lifetime(_) => true, - _ => false, - } + matches!( + tok.kind, + TokenKind::Ident(..) | TokenKind::Literal(..) | TokenKind::Lifetime(_) + ) } fn next_space(tok: &TokenKind) -> SpaceState { @@ -1399,7 +1396,7 @@ impl MacroBranch { // Undo our replacement of macro variables. // FIXME: this could be *much* more efficient. for (old, new) in &substs { - if old_body.find(new).is_some() { + if old_body.contains(new) { debug!("rewrite_macro_def: bailing matching variable: `{}`", new); return None; } diff --git a/src/missed_spans.rs b/src/missed_spans.rs index 17b11ed6cf49..263d840785a2 100644 --- a/src/missed_spans.rs +++ b/src/missed_spans.rs @@ -230,8 +230,7 @@ impl<'a> FmtVisitor<'a> { let last_char = big_snippet .chars() .rev() - .skip_while(|rev_c| [' ', '\t'].contains(rev_c)) - .next(); + .find(|rev_c| ![' ', '\t'].contains(rev_c)); let fix_indent = last_char.map_or(true, |rev_c| ['{', '\n'].contains(&rev_c)); let mut on_same_line = false; @@ -262,7 +261,7 @@ impl<'a> FmtVisitor<'a> { let comment_shape = Shape::legacy(comment_width, comment_indent); if on_same_line { - match subslice.find("\n") { + match subslice.find('\n') { None => { self.push_str(subslice); } @@ -299,8 +298,7 @@ impl<'a> FmtVisitor<'a> { match snippet[status.line_start..] .chars() // skip trailing whitespaces - .skip_while(|c| *c == ' ' || *c == '\t') - .next() + .find(|c| !(*c == ' ' || *c == '\t')) { Some('\n') | Some('\r') => { if !is_last_comment_block(subslice) { diff --git a/src/overflow.rs b/src/overflow.rs index d670b0a41e81..e32213467a51 100644 --- a/src/overflow.rs +++ b/src/overflow.rs @@ -126,21 +126,19 @@ impl<'a> OverflowableItem<'a> { OverflowableItem::MacroArg(MacroArg::Expr(expr)) => is_simple_expr(expr), OverflowableItem::NestedMetaItem(nested_meta_item) => match nested_meta_item { ast::NestedMetaItem::Literal(..) => true, - ast::NestedMetaItem::MetaItem(ref meta_item) => match meta_item.kind { - ast::MetaItemKind::Word => true, - _ => false, - }, + ast::NestedMetaItem::MetaItem(ref meta_item) => { + matches!(meta_item.kind, ast::MetaItemKind::Word) + } }, _ => false, } } pub(crate) fn is_expr(&self) -> bool { - match self { - OverflowableItem::Expr(..) => true, - OverflowableItem::MacroArg(MacroArg::Expr(..)) => true, - _ => false, - } + matches!( + self, + OverflowableItem::Expr(..) | OverflowableItem::MacroArg(MacroArg::Expr(..)) + ) } pub(crate) fn is_nested_call(&self) -> bool { @@ -154,10 +152,7 @@ impl<'a> OverflowableItem<'a> { pub(crate) fn to_expr(&self) -> Option<&'a ast::Expr> { match self { OverflowableItem::Expr(expr) => Some(expr), - OverflowableItem::MacroArg(macro_arg) => match macro_arg { - MacroArg::Expr(ref expr) => Some(expr), - _ => None, - }, + OverflowableItem::MacroArg(MacroArg::Expr(ref expr)) => Some(expr), _ => None, } } @@ -178,10 +173,9 @@ impl<'a> OverflowableItem<'a> { ast::NestedMetaItem::MetaItem(..) => true, } } - OverflowableItem::SegmentParam(seg) => match seg { - SegmentParam::Type(ty) => can_be_overflowed_type(context, ty, len), - _ => false, - }, + OverflowableItem::SegmentParam(SegmentParam::Type(ty)) => { + can_be_overflowed_type(context, ty, len) + } OverflowableItem::TuplePatField(pat) => can_be_overflowed_pat(context, pat, len), OverflowableItem::Ty(ty) => can_be_overflowed_type(context, ty, len), _ => false, diff --git a/src/patterns.rs b/src/patterns.rs index fa0ef260991d..062e9cef9bbd 100644 --- a/src/patterns.rs +++ b/src/patterns.rs @@ -238,7 +238,7 @@ impl Rewrite for Pat { if let Some(rw) = p.rewrite(context, shape) { rw } else { - format!("{}", context.snippet(p.span)) + context.snippet(p.span).to_string() } }) .collect(); @@ -310,23 +310,22 @@ fn rewrite_struct_pat( if fields_str.contains('\n') || fields_str.len() > one_line_width { // Add a missing trailing comma. if context.config.trailing_comma() == SeparatorTactic::Never { - fields_str.push_str(","); + fields_str.push(','); } - fields_str.push_str("\n"); + fields_str.push('\n'); fields_str.push_str(&nested_shape.indent.to_string(context.config)); - fields_str.push_str(".."); } else { if !fields_str.is_empty() { // there are preceding struct fields being matched on if tactic == DefinitiveListTactic::Vertical { // if the tactic is Vertical, write_list already added a trailing , - fields_str.push_str(" "); + fields_str.push(' '); } else { fields_str.push_str(", "); } } - fields_str.push_str(".."); } + fields_str.push_str(".."); } // ast::Pat doesn't have attrs so use &[] @@ -411,10 +410,7 @@ impl<'a> Spanned for TuplePatField<'a> { impl<'a> TuplePatField<'a> { fn is_dotdot(&self) -> bool { match self { - TuplePatField::Pat(pat) => match pat.kind { - ast::PatKind::Rest => true, - _ => false, - }, + TuplePatField::Pat(pat) => matches!(pat.kind, ast::PatKind::Rest), TuplePatField::Dotdot(_) => true, } } @@ -510,10 +506,11 @@ fn count_wildcard_suffix_len( ) .collect(); - for item in items.iter().rev().take_while(|i| match i.item { - Some(ref internal_string) if internal_string == "_" => true, - _ => false, - }) { + for item in items + .iter() + .rev() + .take_while(|i| matches!(i.item, Some(ref internal_string) if internal_string == "_")) + { suffix_len += 1; if item.has_comment() { diff --git a/src/rustfmt_diff.rs b/src/rustfmt_diff.rs index fc2c7d06e264..a394ce07398e 100644 --- a/src/rustfmt_diff.rs +++ b/src/rustfmt_diff.rs @@ -56,10 +56,7 @@ impl From> for ModifiedLines { let chunks = mismatches.into_iter().map(|mismatch| { let lines = mismatch.lines.iter(); let num_removed = lines - .filter(|line| match line { - DiffLine::Resulting(_) => true, - _ => false, - }) + .filter(|line| matches!(line, DiffLine::Resulting(_))) .count(); let new_lines = mismatch.lines.into_iter().filter_map(|line| match line { @@ -94,7 +91,7 @@ impl fmt::Display for ModifiedLines { "{} {} {}", chunk.line_number_orig, chunk.lines_removed, - chunk.lines.iter().count() + chunk.lines.len() )?; for line in &chunk.lines { diff --git a/src/skip.rs b/src/skip.rs index 6c500635a955..0fdc097efc23 100644 --- a/src/skip.rs +++ b/src/skip.rs @@ -32,8 +32,8 @@ impl SkipContext { } } -static RUSTFMT: &'static str = "rustfmt"; -static SKIP: &'static str = "skip"; +static RUSTFMT: &str = "rustfmt"; +static SKIP: &str = "skip"; /// Say if you're playing with `rustfmt`'s skip attribute pub(crate) fn is_skip_attr(segments: &[ast::PathSegment]) -> bool { @@ -46,7 +46,7 @@ pub(crate) fn is_skip_attr(segments: &[ast::PathSegment]) -> bool { segments[1].ident.to_string() == SKIP && ["macros", "attributes"] .iter() - .any(|&n| n == &pprust::path_segment_to_string(&segments[2])) + .any(|&n| n == pprust::path_segment_to_string(&segments[2])) } _ => false, } diff --git a/src/source_file.rs b/src/source_file.rs index 5a9a2cbd80c7..853336004d8b 100644 --- a/src/source_file.rs +++ b/src/source_file.rs @@ -18,7 +18,7 @@ use rustc_data_structures::sync::Lrc; // Append a newline to the end of each file. pub(crate) fn append_newline(s: &mut String) { - s.push_str("\n"); + s.push('\n'); } #[cfg(test)] diff --git a/src/string.rs b/src/string.rs index 080c4f177882..0cb9d817ca2d 100644 --- a/src/string.rs +++ b/src/string.rs @@ -57,7 +57,7 @@ impl<'a> StringFormat<'a> { /// This allows to fit more graphemes from the string on a line when /// SnippetState::EndWithLineFeed. fn max_width_without_indent(&self) -> Option { - Some(self.config.max_width().checked_sub(self.line_end.len())?) + self.config.max_width().checked_sub(self.line_end.len()) } } @@ -99,7 +99,7 @@ pub(crate) fn rewrite_string<'a>( if is_new_line(grapheme) { // take care of blank lines result = trim_end_but_line_feed(fmt.trim_end, result); - result.push_str("\n"); + result.push('\n'); if !is_bareline_ok && cur_start + i + 1 < graphemes.len() { result.push_str(&indent_without_newline); result.push_str(fmt.line_start); diff --git a/src/syntux/parser.rs b/src/syntux/parser.rs index 0b94749f3c6f..b5fe4335dd33 100644 --- a/src/syntux/parser.rs +++ b/src/syntux/parser.rs @@ -79,7 +79,7 @@ impl<'a> ParserBuilder<'a> { rustc_span::FileName::Custom("stdin".to_owned()), text, ) - .map_err(|db| Some(db)), + .map_err(Some), } } } @@ -196,8 +196,7 @@ impl<'a> Parser<'a> { mac: &'a ast::MacCall, ) -> Result, &'static str> { let token_stream = mac.args.inner_tokens(); - let mut parser = - rustc_parse::stream_to_parser(sess.inner(), token_stream.clone(), Some("")); + let mut parser = rustc_parse::stream_to_parser(sess.inner(), token_stream, Some("")); let mut items = vec![]; let mut process_if_cfg = true; diff --git a/src/types.rs b/src/types.rs index 974c0c5990c7..c6f89c310650 100644 --- a/src/types.rs +++ b/src/types.rs @@ -662,7 +662,7 @@ impl Rewrite for ast::Ty { let mut_str = format_mutability(mt.mutbl); let mut_len = mut_str.len(); let mut result = String::with_capacity(128); - result.push_str("&"); + result.push('&'); let ref_hi = context.snippet_provider.span_after(self.span(), "&"); let mut cmnt_lo = ref_hi; @@ -685,7 +685,7 @@ impl Rewrite for ast::Ty { } else { result.push_str(<_str); } - result.push_str(" "); + result.push(' '); cmnt_lo = lifetime.ident.span.hi(); } @@ -1048,11 +1048,7 @@ fn join_bounds_inner( true, ) .map(|v| (v, trailing_span, extendable)), - _ => Some(( - String::from(strs) + &trailing_str, - trailing_span, - extendable, - )), + _ => Some((strs + &trailing_str, trailing_span, extendable)), } }, )?; @@ -1089,10 +1085,7 @@ fn rewrite_lifetime_param( ) -> Option { let result = generic_params .iter() - .filter(|p| match p.kind { - ast::GenericParamKind::Lifetime => true, - _ => false, - }) + .filter(|p| matches!(p.kind, ast::GenericParamKind::Lifetime)) .map(|lt| lt.rewrite(context, shape)) .collect::>>()? .join(", "); diff --git a/src/utils.rs b/src/utils.rs index 614cda5f911c..06159a1b26e8 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -191,7 +191,7 @@ pub(crate) fn outer_attributes(attrs: &[ast::Attribute]) -> Vec #[inline] pub(crate) fn is_single_line(s: &str) -> bool { - s.chars().find(|&c| c == '\n').is_none() + !s.chars().any(|c| c == '\n') } #[inline] @@ -260,8 +260,7 @@ fn is_skip(meta_item: &MetaItem) -> bool { match meta_item.kind { MetaItemKind::Word => { let path_str = pprust::path_to_string(&meta_item.path); - path_str == &*skip_annotation().as_str() - || path_str == &*depr_skip_annotation().as_str() + path_str == *skip_annotation().as_str() || path_str == *depr_skip_annotation().as_str() } MetaItemKind::List(ref l) => { meta_item.has_name(sym::cfg_attr) && l.len() == 2 && is_skip_nested(&l[1]) diff --git a/src/visitor.rs b/src/visitor.rs index 079568630cf5..3f251bf7c16b 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -198,7 +198,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { let missing_span = self.next_span(hi); let snippet = self.snippet(missing_span); let len = CommentCodeSlices::new(snippet) - .nth(0) + .next() .and_then(|(kind, _, s)| { if kind == CodeCharKind::Normal { s.rfind('\n') @@ -293,7 +293,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { } let span_in_between = mk_sp(last_hi, span.lo() + BytePos::from_usize(offset)); let snippet_in_between = self.snippet(span_in_between); - let mut comment_on_same_line = !snippet_in_between.contains("\n"); + let mut comment_on_same_line = !snippet_in_between.contains('\n'); let mut comment_shape = Shape::indented(self.block_indent, config).comment(config); @@ -301,7 +301,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { self.push_str(" "); // put the first line of the comment on the same line as the // block's last line - match sub_slice.find("\n") { + match sub_slice.find('\n') { None => { self.push_str(&sub_slice); } @@ -764,7 +764,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { let hi = self.snippet_provider.span_before(search_span, ";"); let target_span = mk_sp(mac.span().lo(), hi + BytePos(1)); let rewrite = rewrite.map(|rw| { - if !rw.ends_with(";") { + if !rw.ends_with(';') { format!("{};", rw) } else { rw @@ -921,7 +921,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { !is_skip_attr(segments) } - fn walk_mod_items(&mut self, items: &Vec>) { + fn walk_mod_items(&mut self, items: &[rustc_ast::ptr::P]) { self.visit_items_with_reordering(&ptr_vec_to_ref_vec(&items)); } @@ -953,10 +953,10 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { // break the Stability Guarantee // N.B. This could be updated to utilize the version gates. let include_next_empty = if stmts.len() > 1 { - match (&stmts[0].as_ast_node().kind, &stmts[1].as_ast_node().kind) { - (ast::StmtKind::Item(_), ast::StmtKind::Empty) => true, - _ => false, - } + matches!( + (&stmts[0].as_ast_node().kind, &stmts[1].as_ast_node().kind), + (ast::StmtKind::Item(_), ast::StmtKind::Empty) + ) } else { false }; From d42be80bf772688089b90a7f2c8651adc366a3c4 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Sun, 18 Jul 2021 12:14:23 -0500 Subject: [PATCH 009/111] chore: disable clippy::matches_like_macro lint --- Cargo.lock | 24 +++++++++++++++--------- src/cargo-fmt/main.rs | 1 + src/lib.rs | 1 + 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0e12e81904c9..03bb5598007c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -73,7 +73,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "924c76597f0d9ca25d762c25a4d369d51267536465dc5064bdf0eb073ed477ea" dependencies = [ "backtrace-sys", - "cfg-if", + "cfg-if 0.1.10", "libc", "rustc-demangle", ] @@ -162,6 +162,12 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + [[package]] name = "clap" version = "2.33.0" @@ -207,7 +213,7 @@ version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "lazy_static", ] @@ -218,7 +224,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce446db02cdc3165b94ae73111e570793400d0794e46125cc4056c81cbb039f4" dependencies = [ "autocfg", - "cfg-if", + "cfg-if 0.1.10", "lazy_static", ] @@ -245,7 +251,7 @@ version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "dirs-sys", ] @@ -255,7 +261,7 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "afa0b23de8fd801745c471deffa6e12d248f962c9fd4b4c33787b055599bde7b" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "libc", "redox_users", "winapi", @@ -401,11 +407,11 @@ checksum = "f2f96b10ec2560088a8e76961b00d47107b3a625fecb76dedb29ee7ccbf98235" [[package]] name = "log" -version = "0.4.8" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", ] [[package]] @@ -426,7 +432,7 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a85ea9fc0d4ac0deb6fe7911d38786b32fc11119afd9e9d38b84ff691ce64220" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", ] [[package]] diff --git a/src/cargo-fmt/main.rs b/src/cargo-fmt/main.rs index ba693e852ffa..90ffad927e2c 100644 --- a/src/cargo-fmt/main.rs +++ b/src/cargo-fmt/main.rs @@ -1,6 +1,7 @@ // Inspired by Paul Woolcock's cargo-fmt (https://github.com/pwoolcoc/cargo-fmt/). #![deny(warnings)] +#![allow(clippy::match_like_matches_macro)] use std::cmp::Ordering; use std::collections::{BTreeMap, BTreeSet}; diff --git a/src/lib.rs b/src/lib.rs index eb314e63de36..206d2f782909 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,6 +2,7 @@ #![deny(rust_2018_idioms)] #![warn(unreachable_pub)] #![recursion_limit = "256"] +#![allow(clippy::match_like_matches_macro)] #[macro_use] extern crate derive_new; From 0832137b9e72cf639d46f42d4801db8bc6d798e0 Mon Sep 17 00:00:00 2001 From: Elliot Bobrow <77182873+ebobrow@users.noreply.github.com> Date: Mon, 19 Jul 2021 14:50:05 -0700 Subject: [PATCH 010/111] fix link in Contributing.md --- Contributing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Contributing.md b/Contributing.md index a108195beb9a..e6dc6a220376 100644 --- a/Contributing.md +++ b/Contributing.md @@ -65,7 +65,7 @@ and get a better grasp on the execution flow. ## Hack! -Here are some [good starting issues](https://github.com/rust-lang/rustfmt/issues?q=is%3Aopen+is%3Aissue+label%3Agood-first-issue). +Here are some [good starting issues](https://github.com/rust-lang/rustfmt/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22). If you've found areas which need polish and don't have issues, please submit a PR, don't feel there needs to be an issue. From 4236289b75ee55c78538c749512cdbeea5e1c332 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Sun, 25 Jul 2021 22:27:33 -0500 Subject: [PATCH 011/111] chore: bump toolchain --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 7c9d02d933d0..b0cd4464df8e 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2021-05-13" +channel = "nightly-2021-07-23" components = ["rustc-dev"] From 778f03530f8fba92ae0d87644b8cef71d351a859 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Mon, 26 Jul 2021 21:17:15 -0500 Subject: [PATCH 012/111] ci: remove unnecessary cargo-make install on windows jobs --- .github/workflows/windows.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 08cb52eedaea..c05e8d4896ac 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -54,9 +54,6 @@ jobs: if: matrix.target == 'x86_64-pc-windows-gnu' && matrix.channel == 'nightly' shell: bash - - name: cargo-make - run: cargo install --force cargo-make - - name: build run: | rustc -Vv From e7fa07036fa3e87f536fa3bedd3daad51dfeaf16 Mon Sep 17 00:00:00 2001 From: Outvi V <19144373+outloudvi@users.noreply.github.com> Date: Thu, 22 Jul 2021 21:24:07 +0800 Subject: [PATCH 013/111] fix: make --edition 2021 visible in --help --- src/bin/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bin/main.rs b/src/bin/main.rs index 4b4aa42d9359..1bcc5c0dada3 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -121,7 +121,7 @@ fn make_opts() -> Options { found reverts to the input file path", "[Path for the configuration file]", ); - opts.optopt("", "edition", "Rust edition to use", "[2015|2018]"); + opts.optopt("", "edition", "Rust edition to use", "[2015|2018|2021]"); opts.optopt( "", "color", From 0b21ea2161923a87f65932b6abb5e7a94003ec3a Mon Sep 17 00:00:00 2001 From: Ellen Date: Wed, 28 Apr 2021 20:44:40 +0100 Subject: [PATCH 014/111] Unyeet const param defaults --- src/types.rs | 12 +++++++++++- tests/source/issue-4816/lib.rs | 10 ++++++++++ tests/target/issue-4816/lib.rs | 35 ++++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 tests/source/issue-4816/lib.rs create mode 100644 tests/target/issue-4816/lib.rs diff --git a/src/types.rs b/src/types.rs index c6f89c310650..1d3f4669fcd6 100644 --- a/src/types.rs +++ b/src/types.rs @@ -571,13 +571,23 @@ impl Rewrite for ast::GenericParam { if let ast::GenericParamKind::Const { ref ty, kw_span: _, - default: _, + default, } = &self.kind { result.push_str("const "); result.push_str(rewrite_ident(context, self.ident)); result.push_str(": "); result.push_str(&ty.rewrite(context, shape)?); + if let Some(default) = default { + let eq_str = match context.config.type_punctuation_density() { + TypeDensity::Compressed => "=", + TypeDensity::Wide => " = ", + }; + result.push_str(eq_str); + let budget = shape.width.checked_sub(result.len())?; + let rewrite = default.rewrite(context, Shape::legacy(budget, shape.indent))?; + result.push_str(&rewrite); + } } else { result.push_str(rewrite_ident(context, self.ident)); } diff --git a/tests/source/issue-4816/lib.rs b/tests/source/issue-4816/lib.rs new file mode 100644 index 000000000000..43d540c4a5d7 --- /dev/null +++ b/tests/source/issue-4816/lib.rs @@ -0,0 +1,10 @@ +#![feature(const_generics_defaults)] +struct Foo; +struct Bar; +struct Lots; +struct NamesRHard; +struct FooBar< + const LessThan100ButClose: usize = {1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1} +>; +struct FooBarrrrrrrr; diff --git a/tests/target/issue-4816/lib.rs b/tests/target/issue-4816/lib.rs new file mode 100644 index 000000000000..246e775e1feb --- /dev/null +++ b/tests/target/issue-4816/lib.rs @@ -0,0 +1,35 @@ +#![feature(const_generics_defaults)] +struct Foo; +struct Bar; +struct Lots< + const N1BlahFooUwU: usize = { 10 + 28 + 1872 / 10 * 3 }, + const N2SecondParamOhmyyy: usize = { N1BlahFooUwU / 2 + 10 * 2 }, +>; +struct NamesRHard; +struct FooBar< + const LessThan100ButClose: usize = { + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + }, +>; +struct FooBarrrrrrrr< + const N: usize = { + 13478234326456456444323871 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + }, +>; From 8c52aae10a099abf3f481a42bef60bc5db3aba47 Mon Sep 17 00:00:00 2001 From: klensy Date: Thu, 3 Jun 2021 05:28:20 +0300 Subject: [PATCH 015/111] Bump deps * dirs-sys v0.3.4 -> v0.3.6 to drop a lot of deps regex v1.3.1 -> v1.4.3 drops thread_local 0.3.6 bytecount v0.6.0 -> v0.6.2 replaces packed_simd with packed_simd_2 ignore v0.4.11 -> v0.4.17 drop crossbeam-channel v0.4.0 * itertools 8.0 -> 9.0 bump `ignore` version in Cargo.toml * cargo_metadata 0.8 -> 0.12 * env_logger 0.6 -> 0.8 --- Cargo.lock | 380 ++++++++++++------------------------------ Cargo.toml | 8 +- src/cargo-fmt/main.rs | 2 +- 3 files changed, 110 insertions(+), 280 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 03bb5598007c..be134f3e9754 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -35,21 +35,6 @@ version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9267dff192e68f3399525901e709a48c1d3982c9c072fa32f2127a0cb0babf14" -[[package]] -name = "arrayref" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee" - -[[package]] -name = "arrayvec" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" -dependencies = [ - "nodrop", -] - [[package]] name = "atty" version = "0.2.13" @@ -62,40 +47,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "0.1.7" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" - -[[package]] -name = "backtrace" -version = "0.3.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "924c76597f0d9ca25d762c25a4d369d51267536465dc5064bdf0eb073ed477ea" -dependencies = [ - "backtrace-sys", - "cfg-if 0.1.10", - "libc", - "rustc-demangle", -] - -[[package]] -name = "backtrace-sys" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d6575f128516de27e3ce99689419835fce9643a9b215a14d2b5b685be018491" -dependencies = [ - "cc", - "libc", -] - -[[package]] -name = "base64" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" -dependencies = [ - "byteorder", -] +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" [[package]] name = "bitflags" @@ -103,17 +57,6 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" -[[package]] -name = "blake2b_simd" -version = "0.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5850aeee1552f495dd0250014cf64b82b7c8879a89d83b33bbdace2cc4f63182" -dependencies = [ - "arrayref", - "arrayvec", - "constant_time_eq", -] - [[package]] name = "bstr" version = "0.2.8" @@ -125,37 +68,35 @@ dependencies = [ [[package]] name = "bytecount" -version = "0.6.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0017894339f586ccb943b01b9555de56770c11cda818e7e3d8bd93f4ed7f46e" +checksum = "72feb31ffc86498dacdbd0fcebb56138e7177a8cc5cea4516031d15ae85a742e" dependencies = [ - "packed_simd", + "packed_simd_2", ] [[package]] -name = "byteorder" -version = "1.3.2" +name = "cargo-platform" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" +checksum = "0226944a63d1bf35a3b5f948dd7c59e263db83695c9e8bffc4037de02e30f1d7" +dependencies = [ + "serde", +] [[package]] name = "cargo_metadata" -version = "0.8.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "700b3731fd7d357223d0000f4dbf1808401b694609035c3c411fbc0cd375c426" +checksum = "7714a157da7991e23d90686b9524b9e12e0407a108647f52e9328f4b3d51ac7f" dependencies = [ + "cargo-platform", "semver", + "semver-parser", "serde", - "serde_derive", "serde_json", ] -[[package]] -name = "cc" -version = "1.0.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0213d356d3c4ea2c18c40b037c3be23cd639825c18f25ee670ac7813beeef99c" - [[package]] name = "cfg-if" version = "0.1.10" @@ -183,48 +124,14 @@ dependencies = [ "vec_map", ] -[[package]] -name = "cloudabi" -version = "0.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -dependencies = [ - "bitflags", -] - -[[package]] -name = "constant_time_eq" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "995a44c877f9212528ccc74b21a232f66ad69001e40ede5bcee2ac9ef2657120" - -[[package]] -name = "crossbeam-channel" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acec9a3b0b3559f15aee4f90746c4e5e293b701c0f7d3925d24e01645267b68c" -dependencies = [ - "crossbeam-utils 0.7.0", -] - [[package]] name = "crossbeam-utils" -version = "0.6.6" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6" -dependencies = [ - "cfg-if 0.1.10", - "lazy_static", -] - -[[package]] -name = "crossbeam-utils" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce446db02cdc3165b94ae73111e570793400d0794e46125cc4056c81cbb039f4" +checksum = "e7e9d99fa91428effe99c5c6d4634cdeba32b8cf784fc428a2a687f61a952c49" dependencies = [ "autocfg", - "cfg-if 0.1.10", + "cfg-if 1.0.0", "lazy_static", ] @@ -257,11 +164,10 @@ dependencies = [ [[package]] name = "dirs-sys" -version = "0.3.4" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afa0b23de8fd801745c471deffa6e12d248f962c9fd4b4c33787b055599bde7b" +checksum = "03d86534ed367a67548dc68113a0f5db55432fdfbb6e6f9d77704397d95d5780" dependencies = [ - "cfg-if 0.1.10", "libc", "redox_users", "winapi", @@ -275,9 +181,9 @@ checksum = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" [[package]] name = "env_logger" -version = "0.6.2" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aafcde04e90a5226a6443b7aabdb016ba2f8307c847d524724bd9b346dd1a2d3" +checksum = "54532e3223c5af90a6a757c90b5c5521564b07e5e7a958681bcd2afad421cdcd" dependencies = [ "atty", "humantime", @@ -286,40 +192,12 @@ dependencies = [ "termcolor", ] -[[package]] -name = "failure" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8273f13c977665c5db7eb2b99ae520952fe5ac831ae4cd09d80c4c7042b5ed9" -dependencies = [ - "backtrace", - "failure_derive", -] - -[[package]] -name = "failure_derive" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - [[package]] name = "fnv" version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" -[[package]] -name = "fuchsia-cprng" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" - [[package]] name = "getopts" version = "0.2.21" @@ -330,10 +208,21 @@ dependencies = [ ] [[package]] -name = "globset" -version = "0.4.4" +name = "getrandom" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "925aa2cac82d8834e2b2a4415b6f6879757fb5c0928fc445ae76461a12eed8f2" +checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "wasi", +] + +[[package]] +name = "globset" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c152169ef1e421390738366d2f796655fec62621dabbd0fd476f905934061e4a" dependencies = [ "aho-corasick", "bstr", @@ -353,36 +242,33 @@ dependencies = [ [[package]] name = "humantime" -version = "1.3.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" -dependencies = [ - "quick-error", -] +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "ignore" -version = "0.4.11" +version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "522daefc3b69036f80c7d2990b28ff9e0471c683bad05ca258e0a01dd22c5a1e" +checksum = "b287fb45c60bb826a0dc68ff08742b9d88a2fea13d6e0c286b3172065aaf878c" dependencies = [ - "crossbeam-channel", + "crossbeam-utils", "globset", "lazy_static", "log", "memchr", "regex", "same-file", - "thread_local 1.0.1", + "thread_local", "walkdir", "winapi-util", ] [[package]] name = "itertools" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358" +checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" dependencies = [ "either", ] @@ -405,6 +291,12 @@ version = "0.2.77" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2f96b10ec2560088a8e76961b00d47107b3a625fecb76dedb29ee7ccbf98235" +[[package]] +name = "libm" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a" + [[package]] name = "log" version = "0.4.14" @@ -421,18 +313,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" [[package]] -name = "nodrop" -version = "0.1.14" +name = "packed_simd_2" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" - -[[package]] -name = "packed_simd" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a85ea9fc0d4ac0deb6fe7911d38786b32fc11119afd9e9d38b84ff691ce64220" +checksum = "3278e0492f961fd4ae70909f56b2723a7e8d01a228427294e19cdfdebda89a17" dependencies = [ "cfg-if 0.1.10", + "libm", +] + +[[package]] +name = "pest" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" +dependencies = [ + "ucd-trie", ] [[package]] @@ -463,19 +359,13 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.6" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9e470a8dc4aeae2dee2f335e8f533e2d4b347e1434e5671afc49b054592f27" +checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec" dependencies = [ "unicode-xid", ] -[[package]] -name = "quick-error" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" - [[package]] name = "quote" version = "1.0.6" @@ -485,96 +375,42 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "rand_core" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" -dependencies = [ - "rand_core 0.4.2", -] - -[[package]] -name = "rand_core" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" - -[[package]] -name = "rand_os" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" -dependencies = [ - "cloudabi", - "fuchsia-cprng", - "libc", - "rand_core 0.4.2", - "rdrand", - "winapi", -] - -[[package]] -name = "rdrand" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" -dependencies = [ - "rand_core 0.3.1", -] - [[package]] name = "redox_syscall" -version = "0.1.56" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" +checksum = "05ec8ca9416c5ea37062b502703cd7fcb207736bc294f6e0cf367ac6fc234570" +dependencies = [ + "bitflags", +] [[package]] name = "redox_users" -version = "0.3.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ecedbca3bf205f8d8f5c2b44d83cd0690e39ee84b951ed649e9f1841132b66d" +checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" dependencies = [ - "failure", - "rand_os", + "getrandom", "redox_syscall", - "rust-argon2", ] [[package]] name = "regex" -version = "1.3.1" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc220bd33bdce8f093101afe22a037b8eb0e5af33592e6a9caafff0d4cb81cbd" +checksum = "d9251239e129e16308e70d853559389de218ac275b515068abc96829d05b948a" dependencies = [ "aho-corasick", "memchr", "regex-syntax", - "thread_local 0.3.6", + "thread_local", ] [[package]] name = "regex-syntax" -version = "0.6.12" +version = "0.6.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716" - -[[package]] -name = "rust-argon2" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ca4eaef519b494d1f2848fc602d18816fed808a981aedf4f1f00ceb7c9d32cf" -dependencies = [ - "base64", - "blake2b_simd", - "crossbeam-utils 0.6.6", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" +checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581" [[package]] name = "rustc-workspace-hack" @@ -639,9 +475,9 @@ dependencies = [ [[package]] name = "semver" -version = "0.9.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" dependencies = [ "semver-parser", "serde", @@ -649,24 +485,27 @@ dependencies = [ [[package]] name = "semver-parser" -version = "0.7.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" +checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" +dependencies = [ + "pest", +] [[package]] name = "serde" -version = "1.0.101" +version = "1.0.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9796c9b7ba2ffe7a9ce53c2287dfc48080f4b2b362fcc245a259b3a7201119dd" +checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.101" +version = "1.0.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b133a43a1ecd55d4086bd5b4dc6c1751c68b1bfbeba7a5040442022c7e7c02e" +checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43" dependencies = [ "proc-macro2", "quote", @@ -675,9 +514,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.41" +version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f72eb2a68a7dc3f9a691bfda9305a1c017a6215e5a4545c258500d2099a37c2" +checksum = "dcac07dbffa1c65e7f816ab9eba78eb142c6d44410f4eeba1e26e4f5dfa56b95" dependencies = [ "itoa", "ryu", @@ -716,9 +555,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.11" +version = "1.0.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff0acdb207ae2fe6d5976617f887eb1e35a2ba52c13c7234c790960cdad9238" +checksum = "f3a1d708c221c5a612956ef9f75b37e454e88d1f7b899fbd3a18d4252012d663" dependencies = [ "proc-macro2", "quote", @@ -736,18 +575,6 @@ dependencies = [ "syn", ] -[[package]] -name = "synstructure" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f085a5855930c0441ca1288cf044ea4aecf4f43a91668abdb870b4ba546a203" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "unicode-xid", -] - [[package]] name = "term" version = "0.6.1" @@ -796,15 +623,6 @@ dependencies = [ "syn", ] -[[package]] -name = "thread_local" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" -dependencies = [ - "lazy_static", -] - [[package]] name = "thread_local" version = "1.0.1" @@ -823,6 +641,12 @@ dependencies = [ "serde", ] +[[package]] +name = "ucd-trie" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" + [[package]] name = "unicode-segmentation" version = "1.3.0" @@ -870,6 +694,12 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + [[package]] name = "winapi" version = "0.3.8" diff --git a/Cargo.toml b/Cargo.toml index 3a04fb28f7cb..e368f3eb1ec0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,7 +34,7 @@ rustfmt-format-diff = [] generic-simd = ["bytecount/generic-simd"] [dependencies] -itertools = "0.8" +itertools = "0.9" toml = "0.5" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" @@ -43,15 +43,15 @@ regex = "1.0" term = "0.6" diff = "0.1" log = "0.4.14" -env_logger = "0.6" +env_logger = "0.8" getopts = "0.2" derive-new = "0.5" -cargo_metadata = "0.8" +cargo_metadata = "0.12" bytecount = "0.6" unicode-width = "0.1.5" unicode_categories = "0.1.1" dirs = "2.0.1" -ignore = "0.4.11" +ignore = "0.4.17" annotate-snippets = { version = "0.8", features = ["color"] } structopt = "0.3" rustfmt-config_proc_macro = { version = "0.2", path = "config_proc_macro" } diff --git a/src/cargo-fmt/main.rs b/src/cargo-fmt/main.rs index 90ffad927e2c..f8cf698525ba 100644 --- a/src/cargo-fmt/main.rs +++ b/src/cargo-fmt/main.rs @@ -528,7 +528,7 @@ fn get_cargo_metadata( if let Some(manifest_path) = manifest_path { cmd.manifest_path(manifest_path); } - cmd.other_options(&[String::from("--offline")]); + cmd.other_options(vec![String::from("--offline")]); match cmd.exec() { Ok(metadata) => Ok(metadata), From 8cbee5604a069bf8426f0848fd4fd2c86cfff0fa Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Thu, 29 Jul 2021 21:15:56 -0500 Subject: [PATCH 016/111] ci: functionally delete appveyor --- appveyor.yml | 49 +------------------------------------------------ 1 file changed, 1 insertion(+), 48 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 5ac99fd71f8f..b3dda091e0a9 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,55 +1,8 @@ -# This is based on https://github.com/japaric/rust-everywhere/blob/master/appveyor.yml -# and modified (mainly removal of deployment) to suit rustfmt. - environment: global: PROJECT_NAME: rustfmt - matrix: - # Stable channel - # - TARGET: i686-pc-windows-gnu - # CHANNEL: stable - # - TARGET: i686-pc-windows-msvc - # CHANNEL: stable - # - TARGET: x86_64-pc-windows-gnu - # CHANNEL: stable - # - TARGET: x86_64-pc-windows-msvc - # CHANNEL: stable - # Beta channel - # - TARGET: i686-pc-windows-gnu - # CHANNEL: beta - # - TARGET: i686-pc-windows-msvc - # CHANNEL: beta - # - TARGET: x86_64-pc-windows-gnu - # CHANNEL: beta - # - TARGET: x86_64-pc-windows-msvc - # CHANNEL: beta - # Nightly channel - - TARGET: i686-pc-windows-gnu - CHANNEL: nightly - - TARGET: i686-pc-windows-msvc - CHANNEL: nightly - - TARGET: x86_64-pc-windows-gnu - CHANNEL: nightly - - TARGET: x86_64-pc-windows-msvc - CHANNEL: nightly -# Install Rust and Cargo -# (Based on from https://github.com/rust-lang/libc/blob/master/appveyor.yml) -install: - - appveyor-retry appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe - - if "%TARGET%" == "i686-pc-windows-gnu" set PATH=%PATH%;C:\msys64\mingw32\bin - - if "%TARGET%" == "x86_64-pc-windows-gnu" set PATH=%PATH%;C:\msys64\mingw64\bin - - set PATH=%PATH%;C:\Users\appveyor\.cargo\bin - - rustup-init.exe --default-host %TARGET% --default-toolchain %CHANNEL% -y - - rustc -Vv - - cargo -V - -# ??? build: false test_script: - - set CFG_RELEASE_CHANNEL=nightly - - set CFG_RELEASE=nightly - - cargo build --verbose - - cargo test - - cargo test -- --ignored + - echo Why does no one have access to delete me? From fefb5427a2fb28459f91a776948fca0ab0f2d11c Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Fri, 6 Aug 2021 21:26:27 -0500 Subject: [PATCH 017/111] fix: handle GAT types in impls with self bounds --- src/items.rs | 82 ++++++++++++-------------------------- src/visitor.rs | 49 +++++++++-------------- tests/source/issue_4911.rs | 6 +++ tests/target/issue_4911.rs | 9 +++++ 4 files changed, 59 insertions(+), 87 deletions(-) create mode 100644 tests/source/issue_4911.rs create mode 100644 tests/target/issue_4911.rs diff --git a/src/items.rs b/src/items.rs index 0542358c6e7c..1a56acc7de1b 100644 --- a/src/items.rs +++ b/src/items.rs @@ -1497,7 +1497,7 @@ fn format_tuple_struct( Some(result) } -fn rewrite_type( +pub(crate) fn rewrite_type( context: &RewriteContext<'_>, indent: Indent, ident: symbol::Ident, @@ -1841,29 +1841,6 @@ fn rewrite_static( Some(format!("{}{};", prefix, ty_str)) } } - -pub(crate) fn rewrite_type_alias( - ident: symbol::Ident, - ty_opt: Option<&ptr::P>, - generics: &ast::Generics, - generic_bounds_opt: Option<&ast::GenericBounds>, - context: &RewriteContext<'_>, - indent: Indent, - vis: &ast::Visibility, - span: Span, -) -> Option { - rewrite_type( - context, - indent, - ident, - vis, - generics, - generic_bounds_opt, - ty_opt, - span, - ) -} - struct OpaqueType<'a> { bounds: &'a ast::GenericBounds, } @@ -1877,32 +1854,7 @@ impl<'a> Rewrite for OpaqueType<'a> { } } -pub(crate) fn rewrite_opaque_impl_type( - context: &RewriteContext<'_>, - ident: symbol::Ident, - generics: &ast::Generics, - generic_bounds: &ast::GenericBounds, - indent: Indent, -) -> Option { - let ident_str = rewrite_ident(context, ident); - // 5 = "type " - let generics_shape = Shape::indented(indent, context.config).offset_left(5)?; - let generics_str = rewrite_generics(context, ident_str, generics, generics_shape)?; - let prefix = format!("type {} =", generics_str); - let rhs = OpaqueType { - bounds: generic_bounds, - }; - - rewrite_assign_rhs( - context, - &prefix, - &rhs, - Shape::indented(indent, context.config).sub_width(1)?, - ) - .map(|s| s + ";") -} - -pub(crate) fn rewrite_associated_impl_type( +pub(crate) fn rewrite_impl_type( ident: symbol::Ident, vis: &ast::Visibility, defaultness: ast::Defaultness, @@ -1912,7 +1864,25 @@ pub(crate) fn rewrite_associated_impl_type( indent: Indent, span: Span, ) -> Option { - let result = rewrite_type_alias(ident, ty_opt, generics, None, context, indent, vis, span)?; + // Opaque type + let result = if let Some(rustc_ast::ast::Ty { + kind: ast::TyKind::ImplTrait(_, ref bounds), + .. + }) = ty_opt.map(|t| &**t) + { + rewrite_type( + context, + indent, + ident, + &DEFAULT_VISIBILITY, + generics, + None, + Some(&OpaqueType { bounds }), + span, + ) + } else { + rewrite_type(context, indent, ident, vis, generics, None, ty_opt, span) + }?; match defaultness { ast::Defaultness::Default(..) => Some(format!("default {}", result)), @@ -3164,14 +3134,14 @@ impl Rewrite for ast::ForeignItem { ast::ForeignItemKind::TyAlias(ref ty_alias_kind) => { let ast::TyAliasKind(_, ref generics, ref generic_bounds, ref type_default) = **ty_alias_kind; - rewrite_type_alias( - self.ident, - type_default.as_ref(), - generics, - Some(generic_bounds), + rewrite_type( &context, shape.indent, + self.ident, &self.vis, + generics, + Some(generic_bounds), + type_default.as_ref(), self.span, ) } diff --git a/src/visitor.rs b/src/visitor.rs index 3f251bf7c16b..12a3281eda55 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -11,9 +11,9 @@ use crate::config::Version; use crate::config::{BraceStyle, Config}; use crate::coverage::transform_missing_snippet; use crate::items::{ - format_impl, format_trait, format_trait_alias, is_mod_decl, is_use_item, - rewrite_associated_impl_type, rewrite_extern_crate, rewrite_opaque_impl_type, - rewrite_opaque_type, rewrite_type_alias, FnBraceStyle, FnSig, StaticParts, StructParts, + format_impl, format_trait, format_trait_alias, is_mod_decl, is_use_item, rewrite_extern_crate, + rewrite_impl_type, rewrite_opaque_type, rewrite_type, FnBraceStyle, FnSig, StaticParts, + StructParts, }; use crate::macros::{macro_style, rewrite_macro, rewrite_macro_def, MacroPosition}; use crate::modules::Module; @@ -579,14 +579,14 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { **alias_kind; match ty { Some(ty) => { - let rewrite = rewrite_type_alias( - item.ident, - Some(&*ty), - generics, - Some(generic_bounds), + let rewrite = rewrite_type( &self.get_context(), self.block_indent, + item.ident, &item.vis, + generics, + Some(generic_bounds), + Some(&*ty), item.span, ); self.push_rewrite(item.span, rewrite); @@ -665,14 +665,14 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { ast::AssocItemKind::TyAlias(ref ty_alias_kind) => { let ast::TyAliasKind(_, ref generics, ref generic_bounds, ref type_default) = **ty_alias_kind; - let rewrite = rewrite_type_alias( - ti.ident, - type_default.as_ref(), - generics, - Some(generic_bounds), + let rewrite = rewrite_type( &self.get_context(), self.block_indent, + ti.ident, &ti.vis, + generics, + Some(generic_bounds), + type_default.as_ref(), ti.span, ); self.push_rewrite(ti.span, rewrite); @@ -715,8 +715,9 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { ast::AssocItemKind::Const(..) => self.visit_static(&StaticParts::from_impl_item(ii)), ast::AssocItemKind::TyAlias(ref ty_alias_kind) => { let ast::TyAliasKind(defaultness, ref generics, _, ref ty) = **ty_alias_kind; - let rewrite_associated = || { - rewrite_associated_impl_type( + self.push_rewrite( + ii.span, + rewrite_impl_type( ii.ident, &ii.vis, defaultness, @@ -725,22 +726,8 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { &self.get_context(), self.block_indent, ii.span, - ) - }; - let rewrite = match ty { - None => rewrite_associated(), - Some(ty) => match ty.kind { - ast::TyKind::ImplTrait(_, ref bounds) => rewrite_opaque_impl_type( - &self.get_context(), - ii.ident, - generics, - bounds, - self.block_indent, - ), - _ => rewrite_associated(), - }, - }; - self.push_rewrite(ii.span, rewrite); + ), + ); } ast::AssocItemKind::MacCall(ref mac) => { self.visit_mac(mac, Some(ii.ident), MacroPosition::Item); diff --git a/tests/source/issue_4911.rs b/tests/source/issue_4911.rs new file mode 100644 index 000000000000..21ef6c6c491a --- /dev/null +++ b/tests/source/issue_4911.rs @@ -0,0 +1,6 @@ +#![feature(generic_associated_types)] +#![feature(min_type_alias_impl_trait)] + +impl SomeTrait for SomeType { + type SomeGAT<'a> where Self: 'a = impl SomeOtherTrait; +} \ No newline at end of file diff --git a/tests/target/issue_4911.rs b/tests/target/issue_4911.rs new file mode 100644 index 000000000000..890a62267ce6 --- /dev/null +++ b/tests/target/issue_4911.rs @@ -0,0 +1,9 @@ +#![feature(generic_associated_types)] +#![feature(min_type_alias_impl_trait)] + +impl SomeTrait for SomeType { + type SomeGAT<'a> + where + Self: 'a, + = impl SomeOtherTrait; +} From 5d8eb8d79ce01571e468df9a0dfad8b2730bdf58 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Sat, 7 Aug 2021 20:24:14 -0500 Subject: [PATCH 018/111] fix: don't drop drop generic args on assoc ty constraints --- src/types.rs | 125 ++++++++++++++++++++----------------- tests/target/issue_4943.rs | 8 +++ 2 files changed, 76 insertions(+), 57 deletions(-) create mode 100644 tests/target/issue_4943.rs diff --git a/src/types.rs b/src/types.rs index 1d3f4669fcd6..9a0d31e51dfc 100644 --- a/src/types.rs +++ b/src/types.rs @@ -174,34 +174,41 @@ impl<'a> Rewrite for SegmentParam<'a> { SegmentParam::Const(const_) => const_.rewrite(context, shape), SegmentParam::LifeTime(lt) => lt.rewrite(context, shape), SegmentParam::Type(ty) => ty.rewrite(context, shape), - SegmentParam::Binding(assoc_ty_constraint) => { - let mut result = match assoc_ty_constraint.kind { - ast::AssocTyConstraintKind::Bound { .. } => { - format!("{}: ", rewrite_ident(context, assoc_ty_constraint.ident)) - } - ast::AssocTyConstraintKind::Equality { .. } => { - match context.config.type_punctuation_density() { - TypeDensity::Wide => { - format!("{} = ", rewrite_ident(context, assoc_ty_constraint.ident)) - } - TypeDensity::Compressed => { - format!("{}=", rewrite_ident(context, assoc_ty_constraint.ident)) - } - } - } - }; - - let budget = shape.width.checked_sub(result.len())?; - let rewrite = assoc_ty_constraint - .kind - .rewrite(context, Shape::legacy(budget, shape.indent + result.len()))?; - result.push_str(&rewrite); - Some(result) - } + SegmentParam::Binding(atc) => atc.rewrite(context, shape), } } } +impl Rewrite for ast::AssocTyConstraint { + fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option { + use ast::AssocTyConstraintKind::{Bound, Equality}; + + let mut result = String::with_capacity(128); + result.push_str(rewrite_ident(context, self.ident)); + + if let Some(ref gen_args) = self.gen_args { + let budget = shape.width.checked_sub(result.len())?; + let shape = Shape::legacy(budget, shape.indent + result.len()); + let gen_str = rewrite_generic_args(gen_args, context, shape, gen_args.span())?; + result.push_str(&gen_str); + } + + let infix = match (&self.kind, context.config.type_punctuation_density()) { + (Bound { .. }, _) => ": ", + (Equality { .. }, TypeDensity::Wide) => " = ", + (Equality { .. }, TypeDensity::Compressed) => "=", + }; + result.push_str(infix); + + let budget = shape.width.checked_sub(result.len())?; + let shape = Shape::legacy(budget, shape.indent + result.len()); + let rewrite = self.kind.rewrite(context, shape)?; + result.push_str(&rewrite); + + Some(result) + } +} + impl Rewrite for ast::AssocTyConstraintKind { fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option { match self { @@ -240,21 +247,9 @@ fn rewrite_segment( }; if let Some(ref args) = segment.args { + let generics_str = rewrite_generic_args(args, context, shape, mk_sp(*span_lo, span_hi))?; match **args { ast::GenericArgs::AngleBracketed(ref data) if !data.args.is_empty() => { - let param_list = data - .args - .iter() - .map(|x| match x { - ast::AngleBracketedArg::Arg(generic_arg) => { - SegmentParam::from_generic_arg(generic_arg) - } - ast::AngleBracketedArg::Constraint(constraint) => { - SegmentParam::Binding(constraint) - } - }) - .collect::>(); - // HACK: squeeze out the span between the identifier and the parameters. // The hack is requried so that we don't remove the separator inside macro calls. // This does not work in the presence of comment, hoping that people are @@ -270,33 +265,14 @@ fn rewrite_segment( }; result.push_str(separator); - let generics_str = overflow::rewrite_with_angle_brackets( - context, - "", - param_list.iter(), - shape, - mk_sp(*span_lo, span_hi), - )?; - // Update position of last bracket. *span_lo = context .snippet_provider .span_after(mk_sp(*span_lo, span_hi), "<"); - - result.push_str(&generics_str) - } - ast::GenericArgs::Parenthesized(ref data) => { - result.push_str(&format_function_type( - data.inputs.iter().map(|x| &**x), - &data.output, - false, - data.span, - context, - shape, - )?); } _ => (), } + result.push_str(&generics_str) } Some(result) @@ -489,6 +465,41 @@ impl Rewrite for ast::GenericArg { } } +fn rewrite_generic_args( + gen_args: &ast::GenericArgs, + context: &RewriteContext<'_>, + shape: Shape, + span: Span, +) -> Option { + match gen_args { + ast::GenericArgs::AngleBracketed(ref data) if !data.args.is_empty() => { + let args = data + .args + .iter() + .map(|x| match x { + ast::AngleBracketedArg::Arg(generic_arg) => { + SegmentParam::from_generic_arg(generic_arg) + } + ast::AngleBracketedArg::Constraint(constraint) => { + SegmentParam::Binding(constraint) + } + }) + .collect::>(); + + overflow::rewrite_with_angle_brackets(context, "", args.iter(), shape, span) + } + ast::GenericArgs::Parenthesized(ref data) => format_function_type( + data.inputs.iter().map(|x| &**x), + &data.output, + false, + data.span, + context, + shape, + ), + _ => Some("".to_owned()), + } +} + fn rewrite_bounded_lifetime( lt: &ast::Lifetime, bounds: &[ast::GenericBound], diff --git a/tests/target/issue_4943.rs b/tests/target/issue_4943.rs new file mode 100644 index 000000000000..bc8f1a366da2 --- /dev/null +++ b/tests/target/issue_4943.rs @@ -0,0 +1,8 @@ +impl SomeStruct { + fn process(v: T) -> ::R + where + Self: GAT = T>, + { + SomeStruct::do_something(v) + } +} From 1d6002ae3887536578e87b17935a83b94953a8d8 Mon Sep 17 00:00:00 2001 From: Nipunn Koorapati Date: Sat, 7 Aug 2021 18:08:38 -0700 Subject: [PATCH 019/111] Enable triagebot assignment in rustfmt --- triagebot.toml | 1 + 1 file changed, 1 insertion(+) create mode 100644 triagebot.toml diff --git a/triagebot.toml b/triagebot.toml new file mode 100644 index 000000000000..fa0824ac53c0 --- /dev/null +++ b/triagebot.toml @@ -0,0 +1 @@ +[assign] From 667a2da7af0ed32361f1ea195f7a42911a54f1a8 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Sun, 31 May 2020 09:23:39 -0700 Subject: [PATCH 020/111] Fix stable toggle on gh pages configuration site A demonstration of the fix is included in the PR associated with this commit. --- docs/index.html | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/index.html b/docs/index.html index 56d1917e2b61..1af435103985 100644 --- a/docs/index.html +++ b/docs/index.html @@ -155,7 +155,9 @@ head: val[0].text, value: val, stable: val.some((elem) => { - return !!elem.text && elem.text.includes("**Stable**: Yes") + return elem.type === "list" && + !!elem.raw && + elem.raw.includes("**Stable**: Yes"); }), text: val.reduce((result, next) => { return next.text != null @@ -188,4 +190,4 @@ } - \ No newline at end of file + From 6959d03a3aab11515acb5ca2f0e3e5940b451dee Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Sun, 31 May 2020 17:12:09 -0700 Subject: [PATCH 021/111] Show configs from different versions on github pages See https://gushiermainecoon.htmlpasta.com/ for a demo of this change. Part of #4178 --- docs/index.html | 102 ++++++++++++++++++++++++++++++------------------ 1 file changed, 65 insertions(+), 37 deletions(-) diff --git a/docs/index.html b/docs/index.html index 1af435103985..49435e6ab368 100644 --- a/docs/index.html +++ b/docs/index.html @@ -5,6 +5,7 @@ + @@ -137,12 +146,27 @@ }, []); ast.links = {}; + queryParams.set('version', this.version); + queryParams.set('search', this.searchCondition); + const curUrl = window.location.pathname + + '?' + queryParams.toString() + window.location.hash; + history.pushState(null, '', curUrl); + + const renderer = new marked.Renderer(); + renderer.heading = function(text, level) { + const id = htmlToId(text); + return ` + ${text} + `; + }; + return marked.parser(ast, { highlight(code, lang) { return hljs.highlight(lang ? lang : 'rust', code).value; }, headerIds: true, - headerPrefix: '' + headerPrefix: '', + renderer, }); } }, @@ -156,13 +180,10 @@ }, mounted() { if (UrlHash === '') return; - const interval = setInterval(() => { - const target = document.querySelector(`#${UrlHash}`); - if (target != null) { - target.scrollIntoView(true); - clearInterval(interval); - } - }, 100); + const target = document.querySelector(`#${UrlHash}`); + if (target != null) { + target.scrollIntoView(true); + } } }); const extractDepthOnes = (ast) => { @@ -228,6 +249,11 @@ configurationDescriptions }; } + function htmlToId(text) { + const tmpl = document.createElement('template'); + tmpl.innerHTML = text.trim(); + return encodeURIComponent(CSS.escape(tmpl.content.textContent)); + } From bf47fc17a3bbcf93f665ec2b19fbe794ead555af Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Wed, 15 Jul 2020 17:50:43 -0700 Subject: [PATCH 027/111] Ensure that doc url hash IDs are scrolled to on page load I broke this a few weeks ago so I'll fix it Demo: https://5f0fa445faca4aff5f580029--naughty-borg-09b903.netlify.app/?version=master&search=#brace_style --- docs/index.html | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/docs/index.html b/docs/index.html index 40fafd44428b..1f299b918205 100644 --- a/docs/index.html +++ b/docs/index.html @@ -108,7 +108,8 @@ shouldStable: false, version: versionNumber, oldVersion: undefined, - versionOptions: ['master'] + versionOptions: ['master'], + scrolledOnce: false, }, asyncComputed: { async outputHtml() { @@ -156,11 +157,11 @@ renderer.heading = function(text, level) { const id = htmlToId(text); return ` - ${text} + ${text} `; }; - return marked.parser(ast, { + const html = marked.parser(ast, { highlight(code, lang) { return hljs.highlight(lang ? lang : 'rust', code).value; }, @@ -168,6 +169,8 @@ headerPrefix: '', renderer, }); + document.dispatchEvent(new Event('htmlbuilt')); + return html; } }, created: async function() { @@ -178,12 +181,15 @@ .filter(tag => tag.startsWith('v')); this.versionOptions = this.versionOptions.concat(tagOptions); }, - mounted() { + updated: function() { if (UrlHash === '') return; - const target = document.querySelector(`#${UrlHash}`); - if (target != null) { - target.scrollIntoView(true); - } + this.$nextTick(() => { + const target = document.querySelector(`#${UrlHash}`); + if (target != null && !this.scrolledOnce) { + target.scrollIntoView(true); + this.scrolledOnce = true; + } + }); } }); const extractDepthOnes = (ast) => { From f5c782f321572e7eece7d42c51a049c1ae825b5a Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Wed, 15 Jul 2020 17:52:52 -0700 Subject: [PATCH 028/111] fixup! Ensure that doc url hash IDs are scrolled to on page load --- docs/index.html | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/index.html b/docs/index.html index 1f299b918205..3cc0c45a7591 100644 --- a/docs/index.html +++ b/docs/index.html @@ -161,7 +161,7 @@ `; }; - const html = marked.parser(ast, { + return marked.parser(ast, { highlight(code, lang) { return hljs.highlight(lang ? lang : 'rust', code).value; }, @@ -169,8 +169,6 @@ headerPrefix: '', renderer, }); - document.dispatchEvent(new Event('htmlbuilt')); - return html; } }, created: async function() { @@ -181,7 +179,7 @@ .filter(tag => tag.startsWith('v')); this.versionOptions = this.versionOptions.concat(tagOptions); }, - updated: function() { + updated() { if (UrlHash === '') return; this.$nextTick(() => { const target = document.querySelector(`#${UrlHash}`); From 5c7ac69393a20e18bcc07f0d69383bc6254d1b40 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Wed, 15 Jul 2020 18:27:19 -0700 Subject: [PATCH 029/111] Warn when rate limit is on docs page Demo: https://5f0fad2f06c62143ac519413--festive-golick-afb5e0.netlify.app --- docs/index.html | 58 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 45 insertions(+), 13 deletions(-) diff --git a/docs/index.html b/docs/index.html index 3cc0c45a7591..eb5ded4ac30e 100644 --- a/docs/index.html +++ b/docs/index.html @@ -116,20 +116,22 @@ if (this.version !== this.oldVersion) { const ConfigurationMdUrl = `https://raw.githubusercontent.com/rust-lang/rustfmt/${this.version}/Configurations.md`; + let res; try { - const res = await axios.get(ConfigurationMdUrl); - const { - about, - configurationAbout, - configurationDescriptions - } = parseMarkdownAst(res.data); - this.aboutHtml = marked.parser(about); - this.configurationAboutHtml = marked.parser(configurationAbout); - this.configurationDescriptions = configurationDescriptions; - this.oldVersion = this.version; - } catch(error) { - this.aboutHtml = "

Failed to get configuration options for this version, please select the version from the dropdown above.

"; + res = await axios.get(ConfigurationMdUrl).catch(e => { throw e }); + } catch(e) { + this.handleReqFailure(e); + return; } + const { + about, + configurationAbout, + configurationDescriptions + } = parseMarkdownAst(res.data); + this.aboutHtml = marked.parser(about); + this.configurationAboutHtml = marked.parser(configurationAbout); + this.configurationDescriptions = configurationDescriptions; + this.oldVersion = this.version; } const ast = this.configurationDescriptions @@ -172,7 +174,13 @@ } }, created: async function() { - const {data: tags} = await axios.get(RusfmtTagsUrl); + let tags; + try { + tags = (await axios.get(RusfmtTagsUrl)).data; + } catch(e) { + this.handleReqFailure(e); + return; + } const reMajorVersion = /v(\d+)/; const tagOptions = tags .map(tag => tag.name) @@ -188,6 +196,30 @@ this.scrolledOnce = true; } }); + }, + methods: { + handleReqFailure(e) { + if (e.response.status === 404) { + this.aboutHtml = + "

Failed to get configuration options for this version, please select the version from the dropdown above.

"; + } else if ( + e.response.status === 403 && + e.response.headers["X-RateLimit-Remaining"] === 0 + ) { + const resetDate = new Date( + e.response.headers['X-RateLimit-Reset'] * 1000 + ).toLocaleString(); + this.aboutHtml = + `

You have hit the GitHub API rate limit; documentation cannot be updated.` + + `

The rate limit will be reset at ${resetDate}.

`; + } else { + this.aboutHtml = + `

Ecountered an error when fetching documentation data:

` + + `
${e.response.data}
` + + `

We would appreciate a bug report.` + + `

Try refreshing the page.

`; + } + } } }); const extractDepthOnes = (ast) => { From 3c36a0c0b74c2e5cb4c27a53e596b5729a5b3c65 Mon Sep 17 00:00:00 2001 From: jdollar Date: Sat, 3 Oct 2020 19:05:31 -0400 Subject: [PATCH 030/111] Exluding v0.8.1 and v0.7 from the config dropdown Older tags of the repo don't have the configuration.md file that the docs/index.html file uses to display configuration options. Removing them from the list since they don't apply to the use case of the documentation page. --- docs/index.html | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/index.html b/docs/index.html index eb5ded4ac30e..bab4d2ec63bb 100644 --- a/docs/index.html +++ b/docs/index.html @@ -181,10 +181,12 @@ this.handleReqFailure(e); return; } - const reMajorVersion = /v(\d+)/; + + const excludedTagVersions = new Set(['v0.7', 'v0.8.1']); + const tagOptions = tags .map(tag => tag.name) - .filter(tag => tag.startsWith('v')); + .filter(tag => tag.startsWith('v') && !excludedTagVersions.has(tag)); this.versionOptions = this.versionOptions.concat(tagOptions); }, updated() { From 042c2ec369a61d52cef935cbb67ae9b81da03d0f Mon Sep 17 00:00:00 2001 From: gunadhya <6939749+gunadhya@users.noreply.github.com> Date: Sat, 16 Jan 2021 01:34:11 +0530 Subject: [PATCH 031/111] Added Updated default version to Rustfmt docs config --- docs/index.html | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/index.html b/docs/index.html index bab4d2ec63bb..f31c695f7ca0 100644 --- a/docs/index.html +++ b/docs/index.html @@ -87,6 +87,7 @@ From d19f69cd7106d8e84d4e92dad4d94249128a9d35 Mon Sep 17 00:00:00 2001 From: Eric Date: Mon, 30 Aug 2021 20:59:45 +1200 Subject: [PATCH 039/111] test: add missing source for #4943 --- tests/source/issue_4943.rs | 9 +++++++++ tests/target/issue_4943.rs | 2 ++ 2 files changed, 11 insertions(+) create mode 100644 tests/source/issue_4943.rs diff --git a/tests/source/issue_4943.rs b/tests/source/issue_4943.rs new file mode 100644 index 000000000000..0793b7b4fe1c --- /dev/null +++ b/tests/source/issue_4943.rs @@ -0,0 +1,9 @@ +#![feature(generic_associated_types)] + +impl SomeStruct { + fn process(v: T) -> ::R + where Self: GAT = T> + { + SomeStruct::do_something(v) + } +} diff --git a/tests/target/issue_4943.rs b/tests/target/issue_4943.rs index bc8f1a366da2..318f7ebed6e0 100644 --- a/tests/target/issue_4943.rs +++ b/tests/target/issue_4943.rs @@ -1,3 +1,5 @@ +#![feature(generic_associated_types)] + impl SomeStruct { fn process(v: T) -> ::R where From 33d1368674be78b5f058e1fb83d08e0d381ed2d6 Mon Sep 17 00:00:00 2001 From: Eric Date: Mon, 30 Aug 2021 21:09:21 +1200 Subject: [PATCH 040/111] test: add test for #4257 --- tests/source/issue_4257.rs | 13 +++++++++++++ tests/target/issue_4257.rs | 18 ++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 tests/source/issue_4257.rs create mode 100644 tests/target/issue_4257.rs diff --git a/tests/source/issue_4257.rs b/tests/source/issue_4257.rs new file mode 100644 index 000000000000..2b887fadb621 --- /dev/null +++ b/tests/source/issue_4257.rs @@ -0,0 +1,13 @@ +#![feature(generic_associated_types)] +#![allow(incomplete_features)] + +trait Trait { + type Type<'a> where T: 'a; + fn foo(x: &T) -> Self::Type<'_>; +} +impl Trait for () { + type Type<'a> where T: 'a = &'a T; + fn foo(x: &T) -> Self::Type<'_> { + x + } +} diff --git a/tests/target/issue_4257.rs b/tests/target/issue_4257.rs new file mode 100644 index 000000000000..1ebaaf2b6001 --- /dev/null +++ b/tests/target/issue_4257.rs @@ -0,0 +1,18 @@ +#![feature(generic_associated_types)] +#![allow(incomplete_features)] + +trait Trait { + type Type<'a> + where + T: 'a; + fn foo(x: &T) -> Self::Type<'_>; +} +impl Trait for () { + type Type<'a> + where + T: 'a, + = &'a T; + fn foo(x: &T) -> Self::Type<'_> { + x + } +} From bfc60466bdbab90d578c6912083fe2e238e29166 Mon Sep 17 00:00:00 2001 From: Eric Date: Mon, 30 Aug 2021 21:13:42 +1200 Subject: [PATCH 041/111] test: add test for #4954 --- tests/source/issue_4954.rs | 5 +++++ tests/target/issue_4954.rs | 7 +++++++ 2 files changed, 12 insertions(+) create mode 100644 tests/source/issue_4954.rs create mode 100644 tests/target/issue_4954.rs diff --git a/tests/source/issue_4954.rs b/tests/source/issue_4954.rs new file mode 100644 index 000000000000..8011c601b654 --- /dev/null +++ b/tests/source/issue_4954.rs @@ -0,0 +1,5 @@ +trait Foo { + type Arg<'a>; +} + +struct Bar(T) where for<'a> T: Foo = ()>; diff --git a/tests/target/issue_4954.rs b/tests/target/issue_4954.rs new file mode 100644 index 000000000000..aa5e79befe9c --- /dev/null +++ b/tests/target/issue_4954.rs @@ -0,0 +1,7 @@ +trait Foo { + type Arg<'a>; +} + +struct Bar(T) +where + for<'a> T: Foo = ()>; From ae5696a7c4c2edf642c37f06c526eb6bdf78c23b Mon Sep 17 00:00:00 2001 From: Eric Date: Mon, 30 Aug 2021 21:17:43 +1200 Subject: [PATCH 042/111] test: add test for #4322 --- tests/source/issue_4322.rs | 3 +++ tests/target/issue_4322.rs | 5 +++++ 2 files changed, 8 insertions(+) create mode 100644 tests/source/issue_4322.rs create mode 100644 tests/target/issue_4322.rs diff --git a/tests/source/issue_4322.rs b/tests/source/issue_4322.rs new file mode 100644 index 000000000000..b28cc7cdd12f --- /dev/null +++ b/tests/source/issue_4322.rs @@ -0,0 +1,3 @@ +trait Bar { + type X<'a> where Self: 'a; +} diff --git a/tests/target/issue_4322.rs b/tests/target/issue_4322.rs new file mode 100644 index 000000000000..0ec0547119f4 --- /dev/null +++ b/tests/target/issue_4322.rs @@ -0,0 +1,5 @@ +trait Bar { + type X<'a> + where + Self: 'a; +} From 59063e8b407acf2d187ba12616f9f36d041eff8c Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Thu, 16 Apr 2020 07:52:47 -0500 Subject: [PATCH 043/111] fix: newline width calc in combine w/ comments (#4123) --- src/comment.rs | 2 +- tests/target/issue_4031.rs | 21 +++++++++++++++ tests/target/issue_4110.rs | 55 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 tests/target/issue_4031.rs create mode 100644 tests/target/issue_4110.rs diff --git a/src/comment.rs b/src/comment.rs index 0f8118a408ec..62b624acd495 100644 --- a/src/comment.rs +++ b/src/comment.rs @@ -184,7 +184,7 @@ pub(crate) fn combine_strs_with_missing_comments( let missing_comment = rewrite_missing_comment(span, shape, context)?; if missing_comment.is_empty() { - if allow_extend && prev_str.len() + first_sep.len() + next_str.len() <= shape.width { + if allow_extend && one_line_width <= shape.width { result.push_str(first_sep); } else if !prev_str.is_empty() { result.push_str(&indent.to_string_with_newline(config)) diff --git a/tests/target/issue_4031.rs b/tests/target/issue_4031.rs new file mode 100644 index 000000000000..065d5395c7e7 --- /dev/null +++ b/tests/target/issue_4031.rs @@ -0,0 +1,21 @@ +fn foo() { + with_woff2_glyf_table("tests/fonts/woff2/SFNT-TTF-Composite.woff2", |glyf| { + let actual = glyf + .records + .iter() + .map(|glyph| match glyph { + GlyfRecord::Parsed( + found @ Glyph { + data: GlyphData::Composite { .. }, + .. + }, + ) => Some(found), + _ => None, + }) + .find(|candidate| candidate.is_some()) + .unwrap() + .unwrap(); + + assert_eq!(*actual, expected) + }); +} diff --git a/tests/target/issue_4110.rs b/tests/target/issue_4110.rs new file mode 100644 index 000000000000..4a58c3946e12 --- /dev/null +++ b/tests/target/issue_4110.rs @@ -0,0 +1,55 @@ +fn bindings() { + let err = match (place_desc, explanation) { + ( + Some(ref name), + BorrowExplanation::MustBeValidFor { + category: + category @ (ConstraintCategory::Return + | ConstraintCategory::CallArgument + | ConstraintCategory::OpaqueType), + from_closure: false, + ref region_name, + span, + .. + }, + ) if borrow_spans.for_generator() | borrow_spans.for_closure() => self + .report_escaping_closure_capture( + borrow_spans, + borrow_span, + region_name, + category, + span, + &format!("`{}`", name), + ), + ( + ref name, + BorrowExplanation::MustBeValidFor { + category: ConstraintCategory::Assignment, + from_closure: false, + region_name: + RegionName { + source: RegionNameSource::AnonRegionFromUpvar(upvar_span, ref upvar_name), + .. + }, + span, + .. + }, + ) => self.report_escaping_data(borrow_span, name, upvar_span, upvar_name, span), + (Some(name), explanation) => self.report_local_value_does_not_live_long_enough( + location, + &name, + &borrow, + drop_span, + borrow_spans, + explanation, + ), + (None, explanation) => self.report_temporary_value_does_not_live_long_enough( + location, + &borrow, + drop_span, + borrow_spans, + proper_span, + explanation, + ), + }; +} From a59cac29f4dcfd6e9aba03db07b33767809fcea0 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Mon, 6 Sep 2021 15:35:25 -0500 Subject: [PATCH 044/111] fix: use correct spans for params with attrs --- src/spanned.rs | 2 +- tests/source/issue_4032.rs | 4 ++++ tests/target/issue_4032.rs | 18 ++++++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 tests/source/issue_4032.rs create mode 100644 tests/target/issue_4032.rs diff --git a/src/spanned.rs b/src/spanned.rs index 7e3786b7cd94..8e6c75a3744a 100644 --- a/src/spanned.rs +++ b/src/spanned.rs @@ -104,7 +104,7 @@ impl Spanned for ast::Arm { impl Spanned for ast::Param { fn span(&self) -> Span { if crate::items::is_named_param(self) { - mk_sp(self.pat.span.lo(), self.ty.span.hi()) + mk_sp(crate::items::span_lo_for_param(self), self.ty.span.hi()) } else { self.ty.span } diff --git a/tests/source/issue_4032.rs b/tests/source/issue_4032.rs new file mode 100644 index 000000000000..11ded074c345 --- /dev/null +++ b/tests/source/issue_4032.rs @@ -0,0 +1,4 @@ +fn a1(#[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa] a: u8) {} +fn b1(#[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa] bb: u8) {} +fn a2(#[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa] a: u8) {} +fn b2(#[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa] bb: u8) {} diff --git a/tests/target/issue_4032.rs b/tests/target/issue_4032.rs new file mode 100644 index 000000000000..2e7e624ca6e6 --- /dev/null +++ b/tests/target/issue_4032.rs @@ -0,0 +1,18 @@ +fn a1( + #[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa] + a: u8, +) { +} +fn b1( + #[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa] + bb: u8, +) { +} +fn a2( + #[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa] a: u8, +) { +} +fn b2( + #[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa] bb: u8, +) { +} From c2f0e99d854d399880d05f546953659c2d170d54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Campinas?= Date: Tue, 6 Oct 2020 03:44:48 +0200 Subject: [PATCH 045/111] try to write the parameter on a new line in case the attribute/parameter together are over max_width --- src/comment.rs | 14 ++++++++------ src/items.rs | 33 +++++++++++++++++++++++++++------ 2 files changed, 35 insertions(+), 12 deletions(-) diff --git a/src/comment.rs b/src/comment.rs index 62b624acd495..42449d1060f7 100644 --- a/src/comment.rs +++ b/src/comment.rs @@ -10,7 +10,8 @@ use crate::rewrite::RewriteContext; use crate::shape::{Indent, Shape}; use crate::string::{rewrite_string, StringFormat}; use crate::utils::{ - count_newlines, first_line_width, last_line_width, trim_left_preserve_layout, unicode_str_width, + count_newlines, first_line_width, last_line_width, trim_left_preserve_layout, + trimmed_last_line_width, unicode_str_width, }; use crate::{ErrorKind, FormattingError}; @@ -171,11 +172,12 @@ pub(crate) fn combine_strs_with_missing_comments( String::with_capacity(prev_str.len() + next_str.len() + shape.indent.width() + 128); result.push_str(prev_str); let mut allow_one_line = !prev_str.contains('\n') && !next_str.contains('\n'); - let first_sep = if prev_str.is_empty() || next_str.is_empty() { - "" - } else { - " " - }; + let first_sep = + if prev_str.is_empty() || next_str.is_empty() || trimmed_last_line_width(prev_str) == 0 { + "" + } else { + " " + }; let mut one_line_width = last_line_width(prev_str) + first_line_width(next_str) + first_sep.len(); diff --git a/src/items.rs b/src/items.rs index 4fa7190c138d..6ba83b577ae2 100644 --- a/src/items.rs +++ b/src/items.rs @@ -1980,12 +1980,13 @@ impl Rewrite for ast::Param { has_multiple_attr_lines, ) } else if is_named_param(self) { + let param_name = &self + .pat + .rewrite(context, Shape::legacy(shape.width, shape.indent))?; let mut result = combine_strs_with_missing_comments( context, ¶m_attrs_result, - &self - .pat - .rewrite(context, Shape::legacy(shape.width, shape.indent))?, + param_name, span, shape, !has_multiple_attr_lines, @@ -1999,10 +2000,30 @@ impl Rewrite for ast::Param { result.push_str(&after_comment); let overhead = last_line_width(&result); let max_width = shape.width.checked_sub(overhead)?; - let ty_str = self + if let Some(ty_str) = self .ty - .rewrite(context, Shape::legacy(max_width, shape.indent))?; - result.push_str(&ty_str); + .rewrite(context, Shape::legacy(max_width, shape.indent)) + { + result.push_str(&ty_str); + } else { + result = combine_strs_with_missing_comments( + context, + &(param_attrs_result + &shape.to_string_with_newline(context.config)), + param_name, + span, + shape, + !has_multiple_attr_lines, + )?; + result.push_str(&before_comment); + result.push_str(colon_spaces(context.config)); + result.push_str(&after_comment); + let overhead = last_line_width(&result); + let max_width = shape.width.checked_sub(overhead)?; + let ty_str = self + .ty + .rewrite(context, Shape::legacy(max_width, shape.indent))?; + result.push_str(&ty_str); + } } Some(result) From 3d8cd57c2f166cb92204e95a5f4c73ab20fed4f2 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Mon, 6 Sep 2021 17:30:16 -0500 Subject: [PATCH 046/111] tests: add files for issue 4579 --- tests/source/issue_4579.rs | 15 +++++++++++++++ tests/target/issue_4579.rs | 16 ++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 tests/source/issue_4579.rs create mode 100644 tests/target/issue_4579.rs diff --git a/tests/source/issue_4579.rs b/tests/source/issue_4579.rs new file mode 100644 index 000000000000..73f345233ba7 --- /dev/null +++ b/tests/source/issue_4579.rs @@ -0,0 +1,15 @@ +// rustfmt-hard_tabs: true + +#[macro_export] +macro_rules! main { + () => { + #[spirv(fragment)] + pub fn main_fs( + mut out_color: ::spirv_std::storage_class::Output, + #[spirv(descriptor_set = 1)]iChannelResolution: ::spirv_std::storage_class::UniformConstant< + [::spirv_std::glam::Vec3A; 4], + >, + ) { + } + }; +} diff --git a/tests/target/issue_4579.rs b/tests/target/issue_4579.rs new file mode 100644 index 000000000000..7b0a5f3a62e4 --- /dev/null +++ b/tests/target/issue_4579.rs @@ -0,0 +1,16 @@ +// rustfmt-hard_tabs: true + +#[macro_export] +macro_rules! main { + () => { + #[spirv(fragment)] + pub fn main_fs( + mut out_color: ::spirv_std::storage_class::Output, + #[spirv(descriptor_set = 1)] + iChannelResolution: ::spirv_std::storage_class::UniformConstant< + [::spirv_std::glam::Vec3A; 4], + >, + ) { + } + }; +} From 57548aa096f31d90b9606f882f5815a93b2570b3 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Tue, 7 Sep 2021 19:49:56 -0500 Subject: [PATCH 047/111] fix: resolve idempotency issue in extern body elements --- src/missed_spans.rs | 20 ++++++++++++-------- tests/source/issue_4963.rs | 5 +++++ tests/target/issue_4963.rs | 9 +++++++++ 3 files changed, 26 insertions(+), 8 deletions(-) create mode 100644 tests/source/issue_4963.rs create mode 100644 tests/target/issue_4963.rs diff --git a/src/missed_spans.rs b/src/missed_spans.rs index 263d840785a2..28edcb784b40 100644 --- a/src/missed_spans.rs +++ b/src/missed_spans.rs @@ -51,6 +51,14 @@ impl<'a> FmtVisitor<'a> { } pub(crate) fn format_missing_with_indent(&mut self, end: BytePos) { + self.format_missing_indent(end, true) + } + + pub(crate) fn format_missing_no_indent(&mut self, end: BytePos) { + self.format_missing_indent(end, false) + } + + fn format_missing_indent(&mut self, end: BytePos, should_indent: bool) { let config = self.config; self.format_missing_inner(end, |this, last_snippet, snippet| { this.push_str(last_snippet.trim_end()); @@ -58,14 +66,10 @@ impl<'a> FmtVisitor<'a> { // No new lines in the snippet. this.push_str("\n"); } - let indent = this.block_indent.to_string(config); - this.push_str(&indent); - }) - } - - pub(crate) fn format_missing_no_indent(&mut self, end: BytePos) { - self.format_missing_inner(end, |this, last_snippet, _| { - this.push_str(last_snippet.trim_end()); + if should_indent { + let indent = this.block_indent.to_string(config); + this.push_str(&indent); + } }) } diff --git a/tests/source/issue_4963.rs b/tests/source/issue_4963.rs new file mode 100644 index 000000000000..32e1f6cd41bf --- /dev/null +++ b/tests/source/issue_4963.rs @@ -0,0 +1,5 @@ +mod test { + extern "C" {fn test();} +} + +extern "C" {fn test();} \ No newline at end of file diff --git a/tests/target/issue_4963.rs b/tests/target/issue_4963.rs new file mode 100644 index 000000000000..0c3c13579c13 --- /dev/null +++ b/tests/target/issue_4963.rs @@ -0,0 +1,9 @@ +mod test { + extern "C" { + fn test(); + } +} + +extern "C" { + fn test(); +} From a80688329c7bf696245b5ed6f3eeda6a80ab3721 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Wed, 8 Sep 2021 18:59:49 -0500 Subject: [PATCH 048/111] fix: handle param doc comments for macro scenarios --- src/items.rs | 9 ++++++--- tests/target/issue_4936.rs | 10 ++++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) create mode 100644 tests/target/issue_4936.rs diff --git a/src/items.rs b/src/items.rs index 6ba83b577ae2..e8eb1c5dfbb5 100644 --- a/src/items.rs +++ b/src/items.rs @@ -1960,14 +1960,17 @@ impl Rewrite for ast::Param { let param_attrs_result = self .attrs .rewrite(context, Shape::legacy(shape.width, shape.indent))?; - let (span, has_multiple_attr_lines) = if !self.attrs.is_empty() { + // N.B. Doc comments aren't typically valid syntax, but could appear + // in the presence of certain macros - https://github.com/rust-lang/rustfmt/issues/4936 + let (span, has_multiple_attr_lines, has_doc_comments) = if !self.attrs.is_empty() { let num_attrs = self.attrs.len(); ( mk_sp(self.attrs[num_attrs - 1].span.hi(), self.pat.span.lo()), param_attrs_result.contains('\n'), + self.attrs.iter().any(|a| a.is_doc_comment()), ) } else { - (mk_sp(self.span.lo(), self.span.lo()), false) + (mk_sp(self.span.lo(), self.span.lo()), false, false) }; if let Some(ref explicit_self) = self.to_self() { @@ -1989,7 +1992,7 @@ impl Rewrite for ast::Param { param_name, span, shape, - !has_multiple_attr_lines, + !has_multiple_attr_lines && !has_doc_comments, )?; if !is_empty_infer(&*self.ty, self.pat.span) { diff --git a/tests/target/issue_4936.rs b/tests/target/issue_4936.rs new file mode 100644 index 000000000000..c19e505fd03a --- /dev/null +++ b/tests/target/issue_4936.rs @@ -0,0 +1,10 @@ +#[discard_params_doc] +trait Trait { + fn foo( + &self, + /// some docs + bar: String, + /// another docs + baz: i32, + ); +} From b10ab51fed62f54010a786e3f7d018700464b786 Mon Sep 17 00:00:00 2001 From: Nipunn Koorapati Date: Sat, 7 Aug 2021 18:00:51 -0700 Subject: [PATCH 049/111] rustfmt doc code blocks with multiple comma-separated attributes Added test covering this. Chose to treat the code block as rust if and only if all of the comma-separated attributes are rust-valid. Chose to allow/preserve whitespace around commas Fixes #3158 --- src/comment.rs | 52 ++++++++++++--------------- tests/source/issue-3158.rs | 74 ++++++++++++++++++++++++++++++++++++++ tests/target/issue-3158.rs | 74 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 171 insertions(+), 29 deletions(-) create mode 100644 tests/source/issue-3158.rs create mode 100644 tests/target/issue-3158.rs diff --git a/src/comment.rs b/src/comment.rs index 42449d1060f7..608254248585 100644 --- a/src/comment.rs +++ b/src/comment.rs @@ -394,28 +394,26 @@ fn identify_comment( } } -/// Attributes for code blocks in rustdoc. -/// See https://doc.rust-lang.org/rustdoc/print.html#attributes +/// Enum indicating if the code block contains rust based on attributes enum CodeBlockAttribute { Rust, - Ignore, - Text, - ShouldPanic, - NoRun, - CompileFail, + NotRust, } impl CodeBlockAttribute { - fn new(attribute: &str) -> CodeBlockAttribute { - match attribute { - "rust" | "" => CodeBlockAttribute::Rust, - "ignore" => CodeBlockAttribute::Ignore, - "text" => CodeBlockAttribute::Text, - "should_panic" => CodeBlockAttribute::ShouldPanic, - "no_run" => CodeBlockAttribute::NoRun, - "compile_fail" => CodeBlockAttribute::CompileFail, - _ => CodeBlockAttribute::Text, + /// Parse comma separated attributes list. Return rust only if all + /// attributes are valid rust attributes + /// See https://doc.rust-lang.org/rustdoc/print.html#attributes + fn new(attributes: &str) -> CodeBlockAttribute { + for attribute in attributes.split(",") { + match attribute.trim() { + "" | "rust" | "should_panic" | "no_run" | "edition2015" | "edition2018" + | "edition2021" => (), + "ignore" | "compile_fail" | "text" => return CodeBlockAttribute::NotRust, + _ => return CodeBlockAttribute::NotRust, + } } + CodeBlockAttribute::Rust } } @@ -649,25 +647,21 @@ impl<'a> CommentRewrite<'a> { } else if self.code_block_attr.is_some() { if line.starts_with("```") { let code_block = match self.code_block_attr.as_ref().unwrap() { - CodeBlockAttribute::Ignore | CodeBlockAttribute::Text => { - trim_custom_comment_prefix(&self.code_block_buffer) - } - _ if self.code_block_buffer.is_empty() => String::new(), - _ => { + CodeBlockAttribute::Rust + if self.fmt.config.format_code_in_doc_comments() + && !self.code_block_buffer.is_empty() => + { let mut config = self.fmt.config.clone(); config.set().wrap_comments(false); - if config.format_code_in_doc_comments() { - if let Some(s) = - crate::format_code_block(&self.code_block_buffer, &config, false) - { - trim_custom_comment_prefix(&s.snippet) - } else { - trim_custom_comment_prefix(&self.code_block_buffer) - } + if let Some(s) = + crate::format_code_block(&self.code_block_buffer, &config, false) + { + trim_custom_comment_prefix(&s.snippet) } else { trim_custom_comment_prefix(&self.code_block_buffer) } } + _ => trim_custom_comment_prefix(&self.code_block_buffer), }; if !code_block.is_empty() { self.result.push_str(&self.comment_line_separator); diff --git a/tests/source/issue-3158.rs b/tests/source/issue-3158.rs new file mode 100644 index 000000000000..315073db6af5 --- /dev/null +++ b/tests/source/issue-3158.rs @@ -0,0 +1,74 @@ +// rustfmt-format_code_in_doc_comments: true + +/// Should format +/// ```rust +/// assert!( false ); +/// ``` +/// +/// Should format +/// ```rust,should_panic +/// assert!( false ); +/// ``` +/// +/// Should format +/// ```rust,should_panic,edition2018 +/// assert!( false ); +/// ``` +/// +/// Should format +/// ```rust , should_panic , edition2018 +/// assert!( false ); +/// ``` +/// +/// Should not format +/// ```ignore +/// assert!( false ); +/// ``` +/// +/// Should not format (not all are rust) +/// ```rust,ignore +/// assert!( false ); +/// ``` +/// +/// Should not format (rust compile_fail) +/// ```compile_fail +/// assert!( false ); +/// ``` +/// +/// Should not format (rust compile_fail) +/// ```rust,compile_fail +/// assert!( false ); +/// ``` +/// +/// Various unspecified ones that should format +/// ``` +/// assert!( false ); +/// ``` +/// +/// ```, +/// assert!( false ); +/// ``` +/// +/// ```,,,,, +/// assert!( false ); +/// ``` +/// +/// ```,,, rust ,, +/// assert!( false ); +/// ``` +/// +/// Should not format +/// ```,,, rust , ignore, +/// assert!( false ); +/// ``` +/// +/// Few empty ones +/// ``` +/// ``` +/// +/// ```rust +/// ``` +/// +/// ```ignore +/// ``` +fn foo() {} diff --git a/tests/target/issue-3158.rs b/tests/target/issue-3158.rs new file mode 100644 index 000000000000..4bbbdc1d0392 --- /dev/null +++ b/tests/target/issue-3158.rs @@ -0,0 +1,74 @@ +// rustfmt-format_code_in_doc_comments: true + +/// Should format +/// ```rust +/// assert!(false); +/// ``` +/// +/// Should format +/// ```rust,should_panic +/// assert!(false); +/// ``` +/// +/// Should format +/// ```rust,should_panic,edition2018 +/// assert!(false); +/// ``` +/// +/// Should format +/// ```rust , should_panic , edition2018 +/// assert!(false); +/// ``` +/// +/// Should not format +/// ```ignore +/// assert!( false ); +/// ``` +/// +/// Should not format (not all are rust) +/// ```rust,ignore +/// assert!( false ); +/// ``` +/// +/// Should not format (rust compile_fail) +/// ```compile_fail +/// assert!( false ); +/// ``` +/// +/// Should not format (rust compile_fail) +/// ```rust,compile_fail +/// assert!( false ); +/// ``` +/// +/// Various unspecified ones that should format +/// ``` +/// assert!(false); +/// ``` +/// +/// ```, +/// assert!(false); +/// ``` +/// +/// ```,,,,, +/// assert!(false); +/// ``` +/// +/// ```,,, rust ,, +/// assert!(false); +/// ``` +/// +/// Should not format +/// ```,,, rust , ignore, +/// assert!( false ); +/// ``` +/// +/// Few empty ones +/// ``` +/// ``` +/// +/// ```rust +/// ``` +/// +/// ```ignore +/// ``` +fn foo() {} From 67a59f6ee35c3cfd75e2aab5a8475608e167840b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= Date: Fri, 8 Nov 2019 23:50:18 +0200 Subject: [PATCH 050/111] opts: rephrase wording for --all and -p --- src/cargo-fmt/main.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cargo-fmt/main.rs b/src/cargo-fmt/main.rs index f8cf698525ba..f1125fa0bda1 100644 --- a/src/cargo-fmt/main.rs +++ b/src/cargo-fmt/main.rs @@ -36,7 +36,7 @@ pub struct Opts { #[structopt(long = "version")] version: bool, - /// Specify package to format (only usable in workspaces) + /// Specify package to format #[structopt(short = "p", long = "package", value_name = "package")] packages: Vec, @@ -53,7 +53,7 @@ pub struct Opts { #[structopt(name = "rustfmt_options", raw(true))] rustfmt_options: Vec, - /// Format all packages (only usable in workspaces) + /// Format all packages, and also their local path-based dependencies #[structopt(long = "all")] format_all: bool, } From d4ffd1efa4c83084f05f6e83585ae0a70450bcfd Mon Sep 17 00:00:00 2001 From: Seiichi Uchida Date: Fri, 10 Jul 2020 11:23:12 +0900 Subject: [PATCH 051/111] Support @generated marker to skip code formatting This is a copy of #4296 with these changes: * file is not reopened again to find if the file is generated * first five lines are scanned for `@generated` marker instead of one * no attempt is made to only search for marker in comments `@generated` marker is used by certain tools to understand that the file is generated, so it should be treated differently than a file written by a human: * linters should not be invoked on these files, * diffs in these files are less important, * and these files should not be reformatted. This PR proposes builtin support for `@generated` marker. I have not found a standard for a generated file marker, but: * Facebook [uses `@generated` marker](https://tinyurl.com/fb-generated) * Phabricator tool which was spawned from Facebook internal tool [also understands `@generated` marker](https://git.io/JnVHa) * Cargo inserts `@generated` marker into [generated Cargo.lock files](https://git.io/JnVHP) My personal story is that rust-protobuf project which I maintain was broken twice because of incompatibilities/bugs in rustfmt marker handling: [one](https://github.com/stepancheg/rust-protobuf/issues/493), [two](https://github.com/stepancheg/rust-protobuf/issues/551). (Also, rust-protobuf started generating `@generated` marker [6 years ago](https://git.io/JnV5h)). While rustfmt AST markers are useful to apply to a certain AST elements, disable whole-file-at-once all-tools-at-once text level marker might be easier to use and more reliable for generated code. --- Configurations.md | 9 +++++++++ src/config/mod.rs | 2 ++ src/formatting.rs | 9 ++++++++- src/formatting/generated.rs | 7 +++++++ src/syntux/session.rs | 6 ++++++ src/test/mod.rs | 2 +- tests/source/configs/format_generated_files/false.rs | 8 ++++++++ tests/source/configs/format_generated_files/true.rs | 8 ++++++++ tests/target/configs/format_generated_files/false.rs | 8 ++++++++ tests/target/configs/format_generated_files/true.rs | 6 ++++++ 10 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 src/formatting/generated.rs create mode 100644 tests/source/configs/format_generated_files/false.rs create mode 100644 tests/source/configs/format_generated_files/true.rs create mode 100644 tests/target/configs/format_generated_files/false.rs create mode 100644 tests/target/configs/format_generated_files/true.rs diff --git a/Configurations.md b/Configurations.md index 469deccc56ef..84e8c3f7db61 100644 --- a/Configurations.md +++ b/Configurations.md @@ -924,6 +924,15 @@ fn add_one(x: i32) -> i32 { } ``` +## `format_generated_files` + +Format generated files. A file is considered generated +if any of the first five lines contains `@generated` marker. + +- **Default value**: `false` +- **Possible values**: `true`, `false` +- **Stable**: No + ## `format_macro_matchers` Format the metavariable matching patterns in macros. diff --git a/src/config/mod.rs b/src/config/mod.rs index 8c04363b1fd4..3d6e32fdb60f 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -136,6 +136,7 @@ create_config! { inline_attribute_width: usize, 0, false, "Write an item and its attribute on the same line \ if their combined width is below a threshold"; + format_generated_files: bool, false, false, "Format generated files"; // Options that can change the source code beyond whitespace/blocks (somewhat linty things) merge_derives: bool, true, true, "Merge multiple `#[derive(...)]` into a single one"; @@ -604,6 +605,7 @@ blank_lines_lower_bound = 0 edition = "2015" version = "One" inline_attribute_width = 0 +format_generated_files = false merge_derives = true use_try_shorthand = false use_field_init_shorthand = false diff --git a/src/formatting.rs b/src/formatting.rs index e0403574eebc..9ef47b887cad 100644 --- a/src/formatting.rs +++ b/src/formatting.rs @@ -10,6 +10,7 @@ use rustc_span::Span; use self::newline_style::apply_newline_style; use crate::comment::{CharClasses, FullCodeCharKind}; use crate::config::{Config, FileName, Verbosity}; +use crate::formatting::generated::is_generated_file; use crate::issues::BadIssueSeeker; use crate::modules::Module; use crate::syntux::parser::{DirectoryOwnership, Parser, ParserError}; @@ -18,6 +19,7 @@ use crate::utils::count_newlines; use crate::visitor::FmtVisitor; use crate::{modules, source_file, ErrorKind, FormatReport, Input, Session}; +mod generated; mod newline_style; // A map of the files of a crate, with their new content @@ -103,7 +105,12 @@ fn format_project( context.parse_session.set_silent_emitter(); for (path, module) in files { - let should_ignore = !input_is_stdin && context.ignore_file(&path); + let source_file = context.parse_session.span_to_file_contents(module.span); + let src = source_file.src.as_ref().expect("SourceFile without src"); + + let should_ignore = (!input_is_stdin && context.ignore_file(&path)) + || (!config.format_generated_files() && is_generated_file(src)); + if (config.skip_children() && path != main_file) || should_ignore { continue; } diff --git a/src/formatting/generated.rs b/src/formatting/generated.rs new file mode 100644 index 000000000000..58f43f17ee15 --- /dev/null +++ b/src/formatting/generated.rs @@ -0,0 +1,7 @@ +/// Returns `true` if the given span is a part of generated files. +pub(super) fn is_generated_file(original_snippet: &str) -> bool { + original_snippet + .lines() + .take(5) // looking for marker only in the beginning of the file + .any(|line| line.contains("@generated")) +} diff --git a/src/syntux/session.rs b/src/syntux/session.rs index 870f0acfe395..94257e1ce7f1 100644 --- a/src/syntux/session.rs +++ b/src/syntux/session.rs @@ -175,6 +175,12 @@ impl ParseSess { self.parse_sess.source_map().span_to_filename(span).into() } + pub(crate) fn span_to_file_contents(&self, span: Span) -> Lrc { + self.parse_sess + .source_map() + .lookup_source_file(span.data().lo) + } + pub(crate) fn span_to_first_line_string(&self, span: Span) -> String { let file_lines = self.parse_sess.source_map().span_to_lines(span).ok(); diff --git a/src/test/mod.rs b/src/test/mod.rs index cb52346a13a4..ece1b91bfd7c 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -694,7 +694,7 @@ fn read_significant_comments(file_name: &Path) -> HashMap { reader .lines() .map(|line| line.expect("failed getting line")) - .take_while(|line| line_regex.is_match(line)) + .filter(|line| line_regex.is_match(line)) .filter_map(|line| { regex.captures_iter(&line).next().map(|capture| { ( diff --git a/tests/source/configs/format_generated_files/false.rs b/tests/source/configs/format_generated_files/false.rs new file mode 100644 index 000000000000..dec1e00d117b --- /dev/null +++ b/tests/source/configs/format_generated_files/false.rs @@ -0,0 +1,8 @@ +// @generated +// rustfmt-format_generated_files: false + +fn main() +{ + println!("hello, world") + ; +} diff --git a/tests/source/configs/format_generated_files/true.rs b/tests/source/configs/format_generated_files/true.rs new file mode 100644 index 000000000000..a25ddc25a6a4 --- /dev/null +++ b/tests/source/configs/format_generated_files/true.rs @@ -0,0 +1,8 @@ +// @generated +// rustfmt-format_generated_files: true + +fn main() +{ + println!("hello, world") + ; +} diff --git a/tests/target/configs/format_generated_files/false.rs b/tests/target/configs/format_generated_files/false.rs new file mode 100644 index 000000000000..dec1e00d117b --- /dev/null +++ b/tests/target/configs/format_generated_files/false.rs @@ -0,0 +1,8 @@ +// @generated +// rustfmt-format_generated_files: false + +fn main() +{ + println!("hello, world") + ; +} diff --git a/tests/target/configs/format_generated_files/true.rs b/tests/target/configs/format_generated_files/true.rs new file mode 100644 index 000000000000..5fea7e8b3413 --- /dev/null +++ b/tests/target/configs/format_generated_files/true.rs @@ -0,0 +1,6 @@ +// @generated +// rustfmt-format_generated_files: true + +fn main() { + println!("hello, world"); +} From 9d65b7dcd19557bca9aa4b175efa14a35db6d713 Mon Sep 17 00:00:00 2001 From: Arjen Laarhoven Date: Thu, 15 Jul 2021 19:55:52 +0200 Subject: [PATCH 052/111] feat: upper- or lowercase hexadecimal literals --- Configurations.md | 7 ++++++ src/config/mod.rs | 3 +++ src/config/options.rs | 11 ++++++++++ src/expr.rs | 33 +++++++++++++++++++++++++++- tests/source/hex_literal_lower.rs | 5 +++++ tests/source/hex_literal_upper.rs | 5 +++++ tests/target/hex_literal_lower.rs | 5 +++++ tests/target/hex_literal_preserve.rs | 5 +++++ tests/target/hex_literal_upper.rs | 5 +++++ 9 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 tests/source/hex_literal_lower.rs create mode 100644 tests/source/hex_literal_upper.rs create mode 100644 tests/target/hex_literal_lower.rs create mode 100644 tests/target/hex_literal_preserve.rs create mode 100644 tests/target/hex_literal_upper.rs diff --git a/Configurations.md b/Configurations.md index 84e8c3f7db61..b8f8f3053968 100644 --- a/Configurations.md +++ b/Configurations.md @@ -1056,6 +1056,13 @@ fn lorem() -> usize { See also: [`tab_spaces`](#tab_spaces). +## `hex_literal_case` + +Control the case of the letters in hexadecimal literal values + +- **Default value**: `Preserve` +- **Possible values**: `Upper`, `Lower` +- **Stable**: No ## `hide_parse_errors` diff --git a/src/config/mod.rs b/src/config/mod.rs index 3d6e32fdb60f..c6cee8ed2273 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -69,6 +69,8 @@ create_config! { format_macro_matchers: bool, false, false, "Format the metavariable matching patterns in macros"; format_macro_bodies: bool, true, false, "Format the bodies of macros"; + hex_literal_case: HexLiteralCase, HexLiteralCase::Preserve, false, + "Format hexadecimal integer literals"; // Single line expressions and items empty_item_single_line: bool, true, false, @@ -570,6 +572,7 @@ license_template_path = "" format_strings = false format_macro_matchers = false format_macro_bodies = true +hex_literal_case = "Preserve" empty_item_single_line = true struct_lit_single_line = true fn_single_line = false diff --git a/src/config/options.rs b/src/config/options.rs index db15ee97a40a..e92f8e8a5315 100644 --- a/src/config/options.rs +++ b/src/config/options.rs @@ -129,6 +129,17 @@ pub enum ImportGranularity { One, } +/// Controls how rustfmt should handle case in hexadecimal literals. +#[config_type] +pub enum HexLiteralCase { + /// Leave the literal as-is + Preserve, + /// Ensure all literals use uppercase lettering + Upper, + /// Ensure all literals use lowercase lettering + Lower, +} + #[config_type] pub enum ReportTactic { Always, diff --git a/src/expr.rs b/src/expr.rs index 6cfeb9977a96..01cc388c186e 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -13,7 +13,7 @@ use crate::comment::{ rewrite_missing_comment, CharClasses, FindUncommented, }; use crate::config::lists::*; -use crate::config::{Config, ControlBraceStyle, IndentStyle, Version}; +use crate::config::{Config, ControlBraceStyle, HexLiteralCase, IndentStyle, Version}; use crate::lists::{ definitive_tactic, itemize_list, shape_for_tactic, struct_lit_formatting, struct_lit_shape, struct_lit_tactic, write_list, ListFormatting, Separator, @@ -1168,6 +1168,7 @@ pub(crate) fn rewrite_literal( ) -> Option { match l.kind { ast::LitKind::Str(_, ast::StrStyle::Cooked) => rewrite_string_lit(context, l.span, shape), + ast::LitKind::Int(..) => rewrite_int_lit(context, l, shape), _ => wrap_str( context.snippet(l.span).to_owned(), context.config.max_width(), @@ -1202,6 +1203,36 @@ fn rewrite_string_lit(context: &RewriteContext<'_>, span: Span, shape: Shape) -> ) } +fn rewrite_int_lit(context: &RewriteContext<'_>, lit: &ast::Lit, shape: Shape) -> Option { + let span = lit.span; + let symbol = lit.token.symbol.as_str(); + + if symbol.starts_with("0x") { + let hex_lit = match context.config.hex_literal_case() { + HexLiteralCase::Preserve => None, + HexLiteralCase::Upper => Some(symbol[2..].to_ascii_uppercase()), + HexLiteralCase::Lower => Some(symbol[2..].to_ascii_lowercase()), + }; + if let Some(hex_lit) = hex_lit { + return wrap_str( + format!( + "0x{}{}", + hex_lit, + lit.token.suffix.map_or(String::new(), |s| s.to_string()) + ), + context.config.max_width(), + shape, + ); + } + } + + wrap_str( + context.snippet(span).to_owned(), + context.config.max_width(), + shape, + ) +} + fn choose_separator_tactic(context: &RewriteContext<'_>, span: Span) -> Option { if context.inside_macro() { if span_ends_with_comma(context, span) { diff --git a/tests/source/hex_literal_lower.rs b/tests/source/hex_literal_lower.rs new file mode 100644 index 000000000000..ce307b3aa521 --- /dev/null +++ b/tests/source/hex_literal_lower.rs @@ -0,0 +1,5 @@ +// rustfmt-hex_literal_case: Lower +fn main() { + let h1 = 0xCAFE_5EA7; + let h2 = 0xCAFE_F00Du32; +} diff --git a/tests/source/hex_literal_upper.rs b/tests/source/hex_literal_upper.rs new file mode 100644 index 000000000000..b1092ad71ba1 --- /dev/null +++ b/tests/source/hex_literal_upper.rs @@ -0,0 +1,5 @@ +// rustfmt-hex_literal_case: Upper +fn main() { + let h1 = 0xCaFE_5ea7; + let h2 = 0xCAFE_F00Du32; +} diff --git a/tests/target/hex_literal_lower.rs b/tests/target/hex_literal_lower.rs new file mode 100644 index 000000000000..5c27fded1674 --- /dev/null +++ b/tests/target/hex_literal_lower.rs @@ -0,0 +1,5 @@ +// rustfmt-hex_literal_case: Lower +fn main() { + let h1 = 0xcafe_5ea7; + let h2 = 0xcafe_f00du32; +} diff --git a/tests/target/hex_literal_preserve.rs b/tests/target/hex_literal_preserve.rs new file mode 100644 index 000000000000..e8774d0bb24e --- /dev/null +++ b/tests/target/hex_literal_preserve.rs @@ -0,0 +1,5 @@ +// rustfmt-hex_literal_case: Preserve +fn main() { + let h1 = 0xcAfE_5Ea7; + let h2 = 0xCaFe_F00du32; +} diff --git a/tests/target/hex_literal_upper.rs b/tests/target/hex_literal_upper.rs new file mode 100644 index 000000000000..48bb93d2c1c0 --- /dev/null +++ b/tests/target/hex_literal_upper.rs @@ -0,0 +1,5 @@ +// rustfmt-hex_literal_case: Upper +fn main() { + let h1 = 0xCAFE_5EA7; + let h2 = 0xCAFE_F00Du32; +} From 17cb2b147e11c9ad274b316026b1001fbd7007d4 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Sat, 26 Oct 2019 21:07:04 -0500 Subject: [PATCH 053/111] feat: add --check flag to cargo fmt (#3890) --- src/cargo-fmt/main.rs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/cargo-fmt/main.rs b/src/cargo-fmt/main.rs index f1125fa0bda1..89ce454ac4d0 100644 --- a/src/cargo-fmt/main.rs +++ b/src/cargo-fmt/main.rs @@ -56,6 +56,10 @@ pub struct Opts { /// Format all packages, and also their local path-based dependencies #[structopt(long = "all")] format_all: bool, + + /// Run rustfmt in check mode + #[structopt(long = "check")] + check: bool, } fn main() { @@ -104,6 +108,12 @@ fn execute() -> i32 { let strategy = CargoFmtStrategy::from_opts(&opts); let mut rustfmt_args = opts.rustfmt_options; + if opts.check { + let check_flag = String::from("--check"); + if !rustfmt_args.contains(&check_flag) { + rustfmt_args.push(check_flag); + } + } if let Some(message_format) = opts.message_format { if let Err(msg) = convert_message_format_to_rustfmt_args(&message_format, &mut rustfmt_args) { @@ -553,6 +563,7 @@ mod cargo_fmt_tests { assert_eq!(false, o.quiet); assert_eq!(false, o.verbose); assert_eq!(false, o.version); + assert_eq!(false, o.check); assert_eq!(empty, o.packages); assert_eq!(empty, o.rustfmt_options); assert_eq!(false, o.format_all); @@ -571,6 +582,7 @@ mod cargo_fmt_tests { "p2", "--message-format", "short", + "--check", "--", "--edition", "2018", @@ -578,6 +590,7 @@ mod cargo_fmt_tests { assert_eq!(true, o.quiet); assert_eq!(false, o.verbose); assert_eq!(false, o.version); + assert_eq!(true, o.check); assert_eq!(vec!["p1", "p2"], o.packages); assert_eq!(vec!["--edition", "2018"], o.rustfmt_options); assert_eq!(false, o.format_all); @@ -606,12 +619,12 @@ mod cargo_fmt_tests { fn mandatory_separator() { assert!( Opts::clap() - .get_matches_from_safe(&["test", "--check"]) + .get_matches_from_safe(&["test", "--emit"]) .is_err() ); assert!( !Opts::clap() - .get_matches_from_safe(&["test", "--", "--check"]) + .get_matches_from_safe(&["test", "--", "--emit"]) .is_err() ); } From 7aa69e5bc87f32fdcbf037abce2d575335480b9a Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Thu, 16 Sep 2021 21:25:09 -0500 Subject: [PATCH 054/111] refactor: use iter workaround for contains() gap --- src/cargo-fmt/main.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cargo-fmt/main.rs b/src/cargo-fmt/main.rs index 89ce454ac4d0..147b19d7a48c 100644 --- a/src/cargo-fmt/main.rs +++ b/src/cargo-fmt/main.rs @@ -109,9 +109,9 @@ fn execute() -> i32 { let strategy = CargoFmtStrategy::from_opts(&opts); let mut rustfmt_args = opts.rustfmt_options; if opts.check { - let check_flag = String::from("--check"); - if !rustfmt_args.contains(&check_flag) { - rustfmt_args.push(check_flag); + let check_flag = "--check"; + if !rustfmt_args.iter().any(|o| o == check_flag) { + rustfmt_args.push(check_flag.to_owned()); } } if let Some(message_format) = opts.message_format { From dd445aba080cd337300644c77137fedcad482623 Mon Sep 17 00:00:00 2001 From: Ulyssa Date: Wed, 15 Sep 2021 08:58:23 -0700 Subject: [PATCH 055/111] Trailing comma on match block goes missing when guard is on its own line --- src/matches.rs | 1 + tests/source/match-block-trailing-comma.rs | 8 ++++++++ tests/target/match-block-trailing-comma.rs | 10 ++++++++++ 3 files changed, 19 insertions(+) diff --git a/src/matches.rs b/src/matches.rs index 140ec226c02e..5a6ed0ec06e5 100644 --- a/src/matches.rs +++ b/src/matches.rs @@ -409,6 +409,7 @@ fn rewrite_match_body( } result.push_str(&nested_indent_str); result.push_str(&body_str); + result.push_str(&comma); return Some(result); } diff --git a/tests/source/match-block-trailing-comma.rs b/tests/source/match-block-trailing-comma.rs index e9daac13bf96..baa05b79c161 100644 --- a/tests/source/match-block-trailing-comma.rs +++ b/tests/source/match-block-trailing-comma.rs @@ -8,6 +8,14 @@ fn foo() { "line1"; "line2" } + ThisIsA::Guard if true => { + "line1"; + "line2" + } + ThisIsA::ReallyLongPattern(ThatWillForce::TheGuard, ToWrapOnto::TheFollowingLine) if true => { + "line1"; + "line2" + } b => (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb), } diff --git a/tests/target/match-block-trailing-comma.rs b/tests/target/match-block-trailing-comma.rs index 44d1f289f8e0..5ab433a2e6cf 100644 --- a/tests/target/match-block-trailing-comma.rs +++ b/tests/target/match-block-trailing-comma.rs @@ -8,6 +8,16 @@ fn foo() { "line1"; "line2" }, + ThisIsA::Guard if true => { + "line1"; + "line2" + }, + ThisIsA::ReallyLongPattern(ThatWillForce::TheGuard, ToWrapOnto::TheFollowingLine) + if true => + { + "line1"; + "line2" + }, b => ( aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, From 74df7b3265702949105161b36aee8b0975907210 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Sun, 19 Sep 2021 22:15:50 -0500 Subject: [PATCH 056/111] deps: update cargo_metadata to include 'path' --- Cargo.lock | 44 ++++++++++++++------------------------------ Cargo.toml | 2 +- 2 files changed, 15 insertions(+), 31 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index be134f3e9754..7263f0474770 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -75,6 +75,15 @@ dependencies = [ "packed_simd_2", ] +[[package]] +name = "camino" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52d74260d9bf6944e2208aa46841b4b8f0d7ffc0849a06837b2f510337f86b2b" +dependencies = [ + "serde", +] + [[package]] name = "cargo-platform" version = "0.1.1" @@ -86,13 +95,13 @@ dependencies = [ [[package]] name = "cargo_metadata" -version = "0.12.3" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7714a157da7991e23d90686b9524b9e12e0407a108647f52e9328f4b3d51ac7f" +checksum = "c297bd3135f558552f99a0daa180876984ea2c4ffa7470314540dff8c654109a" dependencies = [ + "camino", "cargo-platform", "semver", - "semver-parser", "serde", "serde_json", ] @@ -322,15 +331,6 @@ dependencies = [ "libm", ] -[[package]] -name = "pest" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" -dependencies = [ - "ucd-trie", -] - [[package]] name = "proc-macro-error" version = "0.4.11" @@ -475,23 +475,13 @@ dependencies = [ [[package]] name = "semver" -version = "0.11.0" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012" dependencies = [ - "semver-parser", "serde", ] -[[package]] -name = "semver-parser" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" -dependencies = [ - "pest", -] - [[package]] name = "serde" version = "1.0.126" @@ -641,12 +631,6 @@ dependencies = [ "serde", ] -[[package]] -name = "ucd-trie" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" - [[package]] name = "unicode-segmentation" version = "1.3.0" diff --git a/Cargo.toml b/Cargo.toml index e368f3eb1ec0..970b13eab353 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,7 +46,7 @@ log = "0.4.14" env_logger = "0.8" getopts = "0.2" derive-new = "0.5" -cargo_metadata = "0.12" +cargo_metadata = "0.14" bytecount = "0.6" unicode-width = "0.1.5" unicode_categories = "0.1.1" From 7f6229b9aada69389be4ead0ecbec8aed5892a24 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Mon, 20 Sep 2021 18:58:38 -0500 Subject: [PATCH 057/111] tests: restructure and extend cargo-fmt tests --- .gitignore | 1 + src/cargo-fmt/test/message_format.rs | 80 ++++++++++ src/cargo-fmt/test/mod.rs | 137 ++++++++++++++++++ src/cargo-fmt/test/targets.rs | 134 +++++++++++++++++ .../divergent-crate-dir-names/Cargo.toml | 13 ++ .../dependency-dir-name/Cargo.toml | 10 ++ .../dependency-dir-name/src/lib.rs | 7 + .../subdep-dir-name/Cargo.toml | 7 + .../subdep-dir-name/src/lib.rs | 7 + .../divergent-crate-dir-names/src/main.rs | 3 + .../workspaces/path-dep-above/e/Cargo.toml | 6 + .../workspaces/path-dep-above/e/src/main.rs | 1 + .../workspaces/path-dep-above/ws/Cargo.toml | 5 + .../workspaces/path-dep-above/ws/a/Cargo.toml | 6 + .../path-dep-above/ws/a/d/Cargo.toml | 7 + .../path-dep-above/ws/a/d/f/Cargo.toml | 4 + .../path-dep-above/ws/a/d/f/src/lib.rs | 1 + .../path-dep-above/ws/a/d/src/lib.rs | 1 + .../path-dep-above/ws/a/src/main.rs | 1 + .../workspaces/path-dep-above/ws/b/Cargo.toml | 6 + .../path-dep-above/ws/b/src/main.rs | 1 + .../workspaces/path-dep-above/ws/c/Cargo.toml | 4 + .../workspaces/path-dep-above/ws/c/src/lib.rs | 1 + 23 files changed, 443 insertions(+) create mode 100644 src/cargo-fmt/test/message_format.rs create mode 100644 src/cargo-fmt/test/mod.rs create mode 100644 src/cargo-fmt/test/targets.rs create mode 100644 tests/cargo-fmt/source/divergent-crate-dir-names/Cargo.toml create mode 100644 tests/cargo-fmt/source/divergent-crate-dir-names/dependency-dir-name/Cargo.toml create mode 100644 tests/cargo-fmt/source/divergent-crate-dir-names/dependency-dir-name/src/lib.rs create mode 100644 tests/cargo-fmt/source/divergent-crate-dir-names/dependency-dir-name/subdep-dir-name/Cargo.toml create mode 100644 tests/cargo-fmt/source/divergent-crate-dir-names/dependency-dir-name/subdep-dir-name/src/lib.rs create mode 100644 tests/cargo-fmt/source/divergent-crate-dir-names/src/main.rs create mode 100644 tests/cargo-fmt/source/workspaces/path-dep-above/e/Cargo.toml create mode 100644 tests/cargo-fmt/source/workspaces/path-dep-above/e/src/main.rs create mode 100644 tests/cargo-fmt/source/workspaces/path-dep-above/ws/Cargo.toml create mode 100644 tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/Cargo.toml create mode 100644 tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/d/Cargo.toml create mode 100644 tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/d/f/Cargo.toml create mode 100644 tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/d/f/src/lib.rs create mode 100644 tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/d/src/lib.rs create mode 100644 tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/src/main.rs create mode 100644 tests/cargo-fmt/source/workspaces/path-dep-above/ws/b/Cargo.toml create mode 100644 tests/cargo-fmt/source/workspaces/path-dep-above/ws/b/src/main.rs create mode 100644 tests/cargo-fmt/source/workspaces/path-dep-above/ws/c/Cargo.toml create mode 100644 tests/cargo-fmt/source/workspaces/path-dep-above/ws/c/src/lib.rs diff --git a/.gitignore b/.gitignore index 37adf8751ca8..71cf88f79e67 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ # Generated by Cargo # will have compiled files and executables /target +tests/cargo-fmt/**/target # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries # More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock diff --git a/src/cargo-fmt/test/message_format.rs b/src/cargo-fmt/test/message_format.rs new file mode 100644 index 000000000000..bf44924f13c3 --- /dev/null +++ b/src/cargo-fmt/test/message_format.rs @@ -0,0 +1,80 @@ +use super::*; + +#[test] +fn invalid_message_format() { + assert_eq!( + convert_message_format_to_rustfmt_args("awesome", &mut vec![]), + Err(String::from( + "invalid --message-format value: awesome. Allowed values are: short|json|human" + )), + ); +} + +#[test] +fn json_message_format_and_check_arg() { + let mut args = vec![String::from("--check")]; + assert_eq!( + convert_message_format_to_rustfmt_args("json", &mut args), + Err(String::from( + "cannot include --check arg when --message-format is set to json" + )), + ); +} + +#[test] +fn json_message_format_and_emit_arg() { + let mut args = vec![String::from("--emit"), String::from("checkstyle")]; + assert_eq!( + convert_message_format_to_rustfmt_args("json", &mut args), + Err(String::from( + "cannot include --emit arg when --message-format is set to json" + )), + ); +} + +#[test] +fn json_message_format() { + let mut args = vec![String::from("--edition"), String::from("2018")]; + assert!(convert_message_format_to_rustfmt_args("json", &mut args).is_ok()); + assert_eq!( + args, + vec![ + String::from("--edition"), + String::from("2018"), + String::from("--emit"), + String::from("json") + ] + ); +} + +#[test] +fn human_message_format() { + let exp_args = vec![String::from("--emit"), String::from("json")]; + let mut act_args = exp_args.clone(); + assert!(convert_message_format_to_rustfmt_args("human", &mut act_args).is_ok()); + assert_eq!(act_args, exp_args); +} + +#[test] +fn short_message_format() { + let mut args = vec![String::from("--check")]; + assert!(convert_message_format_to_rustfmt_args("short", &mut args).is_ok()); + assert_eq!(args, vec![String::from("--check"), String::from("-l")]); +} + +#[test] +fn short_message_format_included_short_list_files_flag() { + let mut args = vec![String::from("--check"), String::from("-l")]; + assert!(convert_message_format_to_rustfmt_args("short", &mut args).is_ok()); + assert_eq!(args, vec![String::from("--check"), String::from("-l")]); +} + +#[test] +fn short_message_format_included_long_list_files_flag() { + let mut args = vec![String::from("--check"), String::from("--files-with-diff")]; + assert!(convert_message_format_to_rustfmt_args("short", &mut args).is_ok()); + assert_eq!( + args, + vec![String::from("--check"), String::from("--files-with-diff")] + ); +} diff --git a/src/cargo-fmt/test/mod.rs b/src/cargo-fmt/test/mod.rs new file mode 100644 index 000000000000..360503632c7e --- /dev/null +++ b/src/cargo-fmt/test/mod.rs @@ -0,0 +1,137 @@ +use super::*; + +mod message_format; +mod targets; + +#[test] +fn default_options() { + let empty: Vec = vec![]; + let o = Opts::from_iter(&empty); + assert_eq!(false, o.quiet); + assert_eq!(false, o.verbose); + assert_eq!(false, o.version); + assert_eq!(false, o.check); + assert_eq!(empty, o.packages); + assert_eq!(empty, o.rustfmt_options); + assert_eq!(false, o.format_all); + assert_eq!(None, o.manifest_path); + assert_eq!(None, o.message_format); +} + +#[test] +fn good_options() { + let o = Opts::from_iter(&[ + "test", + "-q", + "-p", + "p1", + "-p", + "p2", + "--message-format", + "short", + "--check", + "--", + "--edition", + "2018", + ]); + assert_eq!(true, o.quiet); + assert_eq!(false, o.verbose); + assert_eq!(false, o.version); + assert_eq!(true, o.check); + assert_eq!(vec!["p1", "p2"], o.packages); + assert_eq!(vec!["--edition", "2018"], o.rustfmt_options); + assert_eq!(false, o.format_all); + assert_eq!(Some(String::from("short")), o.message_format); +} + +#[test] +fn unexpected_option() { + assert!( + Opts::clap() + .get_matches_from_safe(&["test", "unexpected"]) + .is_err() + ); +} + +#[test] +fn unexpected_flag() { + assert!( + Opts::clap() + .get_matches_from_safe(&["test", "--flag"]) + .is_err() + ); +} + +#[test] +fn mandatory_separator() { + assert!( + Opts::clap() + .get_matches_from_safe(&["test", "--emit"]) + .is_err() + ); + assert!( + !Opts::clap() + .get_matches_from_safe(&["test", "--", "--emit"]) + .is_err() + ); +} + +#[test] +fn multiple_packages_one_by_one() { + let o = Opts::from_iter(&[ + "test", + "-p", + "package1", + "--package", + "package2", + "-p", + "package3", + ]); + assert_eq!(3, o.packages.len()); +} + +#[test] +fn multiple_packages_grouped() { + let o = Opts::from_iter(&[ + "test", + "--package", + "package1", + "package2", + "-p", + "package3", + "package4", + ]); + assert_eq!(4, o.packages.len()); +} + +#[test] +fn empty_packages_1() { + assert!(Opts::clap().get_matches_from_safe(&["test", "-p"]).is_err()); +} + +#[test] +fn empty_packages_2() { + assert!( + Opts::clap() + .get_matches_from_safe(&["test", "-p", "--", "--check"]) + .is_err() + ); +} + +#[test] +fn empty_packages_3() { + assert!( + Opts::clap() + .get_matches_from_safe(&["test", "-p", "--verbose"]) + .is_err() + ); +} + +#[test] +fn empty_packages_4() { + assert!( + Opts::clap() + .get_matches_from_safe(&["test", "-p", "--check"]) + .is_err() + ); +} diff --git a/src/cargo-fmt/test/targets.rs b/src/cargo-fmt/test/targets.rs new file mode 100644 index 000000000000..b7e7fabdf715 --- /dev/null +++ b/src/cargo-fmt/test/targets.rs @@ -0,0 +1,134 @@ +use super::*; + +struct ExpTarget { + path: &'static str, + edition: &'static str, + kind: &'static str, +} + +mod all_targets { + use super::*; + + fn assert_correct_targets_loaded( + manifest_suffix: &str, + source_root: &str, + exp_targets: &[ExpTarget], + exp_num_targets: usize, + ) { + let root_path = Path::new("tests/cargo-fmt/source").join(source_root); + let get_path = |exp: &str| PathBuf::from(&root_path).join(exp).canonicalize().unwrap(); + let manifest_path = Path::new(&root_path).join(manifest_suffix); + let targets = get_targets(&CargoFmtStrategy::All, Some(manifest_path.as_path())) + .expect("Targets should have been loaded"); + + assert_eq!(targets.len(), exp_num_targets); + + for target in exp_targets { + assert!(targets.contains(&Target { + path: get_path(target.path), + edition: target.edition.to_owned(), + kind: target.kind.to_owned(), + })); + } + } + + mod different_crate_and_dir_names { + use super::*; + + fn assert_correct_targets_loaded(manifest_suffix: &str) { + let exp_targets = vec![ + ExpTarget { + path: "dependency-dir-name/subdep-dir-name/src/lib.rs", + edition: "2018", + kind: "lib", + }, + ExpTarget { + path: "dependency-dir-name/src/lib.rs", + edition: "2018", + kind: "lib", + }, + ExpTarget { + path: "src/main.rs", + edition: "2018", + kind: "main", + }, + ]; + super::assert_correct_targets_loaded( + manifest_suffix, + "divergent-crate-dir-names", + &exp_targets, + 3, + ); + } + + #[test] + fn correct_targets_from_root() { + assert_correct_targets_loaded("Cargo.toml"); + } + + #[test] + fn correct_targets_from_sub_local_dep() { + assert_correct_targets_loaded("dependency-dir-name/Cargo.toml"); + } + } + + mod workspaces { + use super::*; + + fn assert_correct_targets_loaded(manifest_suffix: &str) { + let exp_targets = vec![ + ExpTarget { + path: "ws/a/src/main.rs", + edition: "2018", + kind: "bin", + }, + ExpTarget { + path: "ws/b/src/main.rs", + edition: "2018", + kind: "bin", + }, + ExpTarget { + path: "ws/c/src/lib.rs", + edition: "2018", + kind: "lib", + }, + ExpTarget { + path: "ws/a/d/src/lib.rs", + edition: "2018", + kind: "lib", + }, + ExpTarget { + path: "e/src/main.rs", + edition: "2018", + kind: "main", + }, + ExpTarget { + path: "ws/a/d/f/src/lib.rs", + edition: "2018", + kind: "lib", + }, + ]; + super::assert_correct_targets_loaded( + manifest_suffix, + "workspaces/path-dep-above", + &exp_targets, + 6, + ); + } + + #[test] + fn includes_outside_workspace_deps() { + assert_correct_targets_loaded("ws/Cargo.toml"); + } + + #[test] + fn includes_workspace_from_dep_above() { + assert_correct_targets_loaded("e/Cargo.toml"); + } + + #[test] + fn includes_all_packages_from_workspace_subdir() { + assert_correct_targets_loaded("ws/a/d/f/Cargo.toml"); + } + } +} diff --git a/tests/cargo-fmt/source/divergent-crate-dir-names/Cargo.toml b/tests/cargo-fmt/source/divergent-crate-dir-names/Cargo.toml new file mode 100644 index 000000000000..315364a64573 --- /dev/null +++ b/tests/cargo-fmt/source/divergent-crate-dir-names/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "cargo-fmt-test" +version = "0.1.0" +authors = ["calebcartwright"] +edition = "2018" + +[dependencies] +indexmap = "1.0.2" + +[workspace] +members = [ + "dependency-dir-name", +] \ No newline at end of file diff --git a/tests/cargo-fmt/source/divergent-crate-dir-names/dependency-dir-name/Cargo.toml b/tests/cargo-fmt/source/divergent-crate-dir-names/dependency-dir-name/Cargo.toml new file mode 100644 index 000000000000..4493882bf40a --- /dev/null +++ b/tests/cargo-fmt/source/divergent-crate-dir-names/dependency-dir-name/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "dependency-crate-name" +version = "0.1.0" +authors = ["calebcartwright"] +edition = "2018" + +[dependencies] +subdep-crate-name = { path = "subdep-dir-name" } +indexmap = "1.0.2" +rusty-hook = "0.8.4" \ No newline at end of file diff --git a/tests/cargo-fmt/source/divergent-crate-dir-names/dependency-dir-name/src/lib.rs b/tests/cargo-fmt/source/divergent-crate-dir-names/dependency-dir-name/src/lib.rs new file mode 100644 index 000000000000..e93b18d725b9 --- /dev/null +++ b/tests/cargo-fmt/source/divergent-crate-dir-names/dependency-dir-name/src/lib.rs @@ -0,0 +1,7 @@ +#[cfg(test)] +mod tests { +#[test] +fn it_works() { + assert_eq!(2 + 2, 4); +} +} diff --git a/tests/cargo-fmt/source/divergent-crate-dir-names/dependency-dir-name/subdep-dir-name/Cargo.toml b/tests/cargo-fmt/source/divergent-crate-dir-names/dependency-dir-name/subdep-dir-name/Cargo.toml new file mode 100644 index 000000000000..7dad09f4077b --- /dev/null +++ b/tests/cargo-fmt/source/divergent-crate-dir-names/dependency-dir-name/subdep-dir-name/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "subdep-crate-name" +version = "0.1.0" +authors = ["calebcartwright"] +edition = "2018" + +[dependencies] diff --git a/tests/cargo-fmt/source/divergent-crate-dir-names/dependency-dir-name/subdep-dir-name/src/lib.rs b/tests/cargo-fmt/source/divergent-crate-dir-names/dependency-dir-name/subdep-dir-name/src/lib.rs new file mode 100644 index 000000000000..1c08c1c4fd38 --- /dev/null +++ b/tests/cargo-fmt/source/divergent-crate-dir-names/dependency-dir-name/subdep-dir-name/src/lib.rs @@ -0,0 +1,7 @@ +#[cfg(test)] +mod tests { +#[test] +fn sub_test_that_works() { + assert_eq!(3 + 3, 6); +} + } diff --git a/tests/cargo-fmt/source/divergent-crate-dir-names/src/main.rs b/tests/cargo-fmt/source/divergent-crate-dir-names/src/main.rs new file mode 100644 index 000000000000..f5c339a8dd14 --- /dev/null +++ b/tests/cargo-fmt/source/divergent-crate-dir-names/src/main.rs @@ -0,0 +1,3 @@ +fn main() { +println!("Hello, world!"); +} diff --git a/tests/cargo-fmt/source/workspaces/path-dep-above/e/Cargo.toml b/tests/cargo-fmt/source/workspaces/path-dep-above/e/Cargo.toml new file mode 100644 index 000000000000..df1886c82be3 --- /dev/null +++ b/tests/cargo-fmt/source/workspaces/path-dep-above/e/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "e" +version = "0.1.0" +edition = "2018" +[dependencies] +c = { path = "../ws/c" } diff --git a/tests/cargo-fmt/source/workspaces/path-dep-above/e/src/main.rs b/tests/cargo-fmt/source/workspaces/path-dep-above/e/src/main.rs new file mode 100644 index 000000000000..1c26a3895f37 --- /dev/null +++ b/tests/cargo-fmt/source/workspaces/path-dep-above/e/src/main.rs @@ -0,0 +1 @@ +struct E{ } diff --git a/tests/cargo-fmt/source/workspaces/path-dep-above/ws/Cargo.toml b/tests/cargo-fmt/source/workspaces/path-dep-above/ws/Cargo.toml new file mode 100644 index 000000000000..202739b613b8 --- /dev/null +++ b/tests/cargo-fmt/source/workspaces/path-dep-above/ws/Cargo.toml @@ -0,0 +1,5 @@ +[workspace] +members = [ + "a", + "b" +] \ No newline at end of file diff --git a/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/Cargo.toml b/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/Cargo.toml new file mode 100644 index 000000000000..712a113448fb --- /dev/null +++ b/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "a" +version = "0.1.0" +edition = "2018" +[dependencies] +d = { path = "./d" } diff --git a/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/d/Cargo.toml b/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/d/Cargo.toml new file mode 100644 index 000000000000..fb0f06fe5fce --- /dev/null +++ b/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/d/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "d" +version = "0.1.0" +edition = "2018" +[dependencies] +e = { path = "../../../e" } +f = { path = "f" } diff --git a/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/d/f/Cargo.toml b/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/d/f/Cargo.toml new file mode 100644 index 000000000000..5c4fa5617886 --- /dev/null +++ b/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/d/f/Cargo.toml @@ -0,0 +1,4 @@ +[package] +name = "f" +version = "0.1.0" +edition = "2018" diff --git a/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/d/f/src/lib.rs b/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/d/f/src/lib.rs new file mode 100644 index 000000000000..c655c4d5e1a8 --- /dev/null +++ b/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/d/f/src/lib.rs @@ -0,0 +1 @@ +struct F{ } \ No newline at end of file diff --git a/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/d/src/lib.rs b/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/d/src/lib.rs new file mode 100644 index 000000000000..04e6e4cb9402 --- /dev/null +++ b/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/d/src/lib.rs @@ -0,0 +1 @@ +struct D{ } \ No newline at end of file diff --git a/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/src/main.rs b/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/src/main.rs new file mode 100644 index 000000000000..04e6e4cb9402 --- /dev/null +++ b/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/src/main.rs @@ -0,0 +1 @@ +struct D{ } \ No newline at end of file diff --git a/tests/cargo-fmt/source/workspaces/path-dep-above/ws/b/Cargo.toml b/tests/cargo-fmt/source/workspaces/path-dep-above/ws/b/Cargo.toml new file mode 100644 index 000000000000..47a24ff4f275 --- /dev/null +++ b/tests/cargo-fmt/source/workspaces/path-dep-above/ws/b/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "b" +version = "0.1.0" +edition = "2018" +[dependencies] +c = { path = "../c" } diff --git a/tests/cargo-fmt/source/workspaces/path-dep-above/ws/b/src/main.rs b/tests/cargo-fmt/source/workspaces/path-dep-above/ws/b/src/main.rs new file mode 100644 index 000000000000..4833bbc69b48 --- /dev/null +++ b/tests/cargo-fmt/source/workspaces/path-dep-above/ws/b/src/main.rs @@ -0,0 +1 @@ +struct B{ } \ No newline at end of file diff --git a/tests/cargo-fmt/source/workspaces/path-dep-above/ws/c/Cargo.toml b/tests/cargo-fmt/source/workspaces/path-dep-above/ws/c/Cargo.toml new file mode 100644 index 000000000000..49fa6c395eb6 --- /dev/null +++ b/tests/cargo-fmt/source/workspaces/path-dep-above/ws/c/Cargo.toml @@ -0,0 +1,4 @@ +[package] +name = "c" +version = "0.1.0" +edition = "2018" diff --git a/tests/cargo-fmt/source/workspaces/path-dep-above/ws/c/src/lib.rs b/tests/cargo-fmt/source/workspaces/path-dep-above/ws/c/src/lib.rs new file mode 100644 index 000000000000..1245ac91d60a --- /dev/null +++ b/tests/cargo-fmt/source/workspaces/path-dep-above/ws/c/src/lib.rs @@ -0,0 +1 @@ +struct C{ } \ No newline at end of file From 4b9d637f5846b92f2c17b98985c47dea795064d2 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Mon, 20 Sep 2021 19:09:16 -0500 Subject: [PATCH 058/111] refactor: simplify local dep lookups --- src/cargo-fmt/main.rs | 280 ++++-------------------------------------- 1 file changed, 26 insertions(+), 254 deletions(-) diff --git a/src/cargo-fmt/main.rs b/src/cargo-fmt/main.rs index 147b19d7a48c..1d423ac34919 100644 --- a/src/cargo-fmt/main.rs +++ b/src/cargo-fmt/main.rs @@ -17,6 +17,10 @@ use std::str; use structopt::StructOpt; +#[path = "test/mod.rs"] +#[cfg(test)] +mod cargo_fmt_tests; + #[derive(StructOpt, Debug)] #[structopt( bin_name = "cargo fmt", @@ -356,7 +360,7 @@ fn get_targets_root_only( manifest_path: Option<&Path>, targets: &mut BTreeSet, ) -> Result<(), io::Error> { - let metadata = get_cargo_metadata(manifest_path, false)?; + let metadata = get_cargo_metadata(manifest_path)?; let workspace_root_path = PathBuf::from(&metadata.workspace_root).canonicalize()?; let (in_workspace_root, current_dir_manifest) = if let Some(target_manifest) = manifest_path { ( @@ -400,34 +404,29 @@ fn get_targets_recursive( mut targets: &mut BTreeSet, visited: &mut BTreeSet, ) -> Result<(), io::Error> { - let metadata = get_cargo_metadata(manifest_path, false)?; - let metadata_with_deps = get_cargo_metadata(manifest_path, true)?; - - for package in metadata.packages { + let metadata = get_cargo_metadata(manifest_path)?; + for package in &metadata.packages { add_targets(&package.targets, &mut targets); - // Look for local dependencies. - for dependency in package.dependencies { - if dependency.source.is_some() || visited.contains(&dependency.name) { + // Look for local dependencies using information available since cargo v1.51 + // It's theoretically possible someone could use a newer version of rustfmt with + // a much older version of `cargo`, but we don't try to explicitly support that scenario. + // If someone reports an issue with path-based deps not being formatted, be sure to + // confirm their version of `cargo` (not `cargo-fmt`) is >= v1.51 + // https://github.com/rust-lang/cargo/pull/8994 + for dependency in &package.dependencies { + if dependency.path.is_none() || visited.contains(&dependency.name) { continue; } - let dependency_package = metadata_with_deps - .packages - .iter() - .find(|p| p.name == dependency.name && p.source.is_none()); - let manifest_path = if let Some(dep_pkg) = dependency_package { - PathBuf::from(&dep_pkg.manifest_path) - } else { - let mut package_manifest_path = PathBuf::from(&package.manifest_path); - package_manifest_path.pop(); - package_manifest_path.push(&dependency.name); - package_manifest_path.push("Cargo.toml"); - package_manifest_path - }; - - if manifest_path.exists() { - visited.insert(dependency.name); + let manifest_path = PathBuf::from(dependency.path.as_ref().unwrap()).join("Cargo.toml"); + if manifest_path.exists() + && !metadata + .packages + .iter() + .any(|p| p.manifest_path.eq(&manifest_path)) + { + visited.insert(dependency.name.to_owned()); get_targets_recursive(Some(&manifest_path), &mut targets, visited)?; } } @@ -441,8 +440,7 @@ fn get_targets_with_hitlist( hitlist: &[String], targets: &mut BTreeSet, ) -> Result<(), io::Error> { - let metadata = get_cargo_metadata(manifest_path, false)?; - + let metadata = get_cargo_metadata(manifest_path)?; let mut workspace_hitlist: BTreeSet<&String> = BTreeSet::from_iter(hitlist); for package in metadata.packages { @@ -527,14 +525,9 @@ fn run_rustfmt( .unwrap_or(SUCCESS)) } -fn get_cargo_metadata( - manifest_path: Option<&Path>, - include_deps: bool, -) -> Result { +fn get_cargo_metadata(manifest_path: Option<&Path>) -> Result { let mut cmd = cargo_metadata::MetadataCommand::new(); - if !include_deps { - cmd.no_deps(); - } + cmd.no_deps(); if let Some(manifest_path) = manifest_path { cmd.manifest_path(manifest_path); } @@ -551,224 +544,3 @@ fn get_cargo_metadata( } } } - -#[cfg(test)] -mod cargo_fmt_tests { - use super::*; - - #[test] - fn default_options() { - let empty: Vec = vec![]; - let o = Opts::from_iter(&empty); - assert_eq!(false, o.quiet); - assert_eq!(false, o.verbose); - assert_eq!(false, o.version); - assert_eq!(false, o.check); - assert_eq!(empty, o.packages); - assert_eq!(empty, o.rustfmt_options); - assert_eq!(false, o.format_all); - assert_eq!(None, o.manifest_path); - assert_eq!(None, o.message_format); - } - - #[test] - fn good_options() { - let o = Opts::from_iter(&[ - "test", - "-q", - "-p", - "p1", - "-p", - "p2", - "--message-format", - "short", - "--check", - "--", - "--edition", - "2018", - ]); - assert_eq!(true, o.quiet); - assert_eq!(false, o.verbose); - assert_eq!(false, o.version); - assert_eq!(true, o.check); - assert_eq!(vec!["p1", "p2"], o.packages); - assert_eq!(vec!["--edition", "2018"], o.rustfmt_options); - assert_eq!(false, o.format_all); - assert_eq!(Some(String::from("short")), o.message_format); - } - - #[test] - fn unexpected_option() { - assert!( - Opts::clap() - .get_matches_from_safe(&["test", "unexpected"]) - .is_err() - ); - } - - #[test] - fn unexpected_flag() { - assert!( - Opts::clap() - .get_matches_from_safe(&["test", "--flag"]) - .is_err() - ); - } - - #[test] - fn mandatory_separator() { - assert!( - Opts::clap() - .get_matches_from_safe(&["test", "--emit"]) - .is_err() - ); - assert!( - !Opts::clap() - .get_matches_from_safe(&["test", "--", "--emit"]) - .is_err() - ); - } - - #[test] - fn multiple_packages_one_by_one() { - let o = Opts::from_iter(&[ - "test", - "-p", - "package1", - "--package", - "package2", - "-p", - "package3", - ]); - assert_eq!(3, o.packages.len()); - } - - #[test] - fn multiple_packages_grouped() { - let o = Opts::from_iter(&[ - "test", - "--package", - "package1", - "package2", - "-p", - "package3", - "package4", - ]); - assert_eq!(4, o.packages.len()); - } - - #[test] - fn empty_packages_1() { - assert!(Opts::clap().get_matches_from_safe(&["test", "-p"]).is_err()); - } - - #[test] - fn empty_packages_2() { - assert!( - Opts::clap() - .get_matches_from_safe(&["test", "-p", "--", "--check"]) - .is_err() - ); - } - - #[test] - fn empty_packages_3() { - assert!( - Opts::clap() - .get_matches_from_safe(&["test", "-p", "--verbose"]) - .is_err() - ); - } - - #[test] - fn empty_packages_4() { - assert!( - Opts::clap() - .get_matches_from_safe(&["test", "-p", "--check"]) - .is_err() - ); - } - - mod convert_message_format_to_rustfmt_args_tests { - use super::*; - - #[test] - fn invalid_message_format() { - assert_eq!( - convert_message_format_to_rustfmt_args("awesome", &mut vec![]), - Err(String::from( - "invalid --message-format value: awesome. Allowed values are: short|json|human" - )), - ); - } - - #[test] - fn json_message_format_and_check_arg() { - let mut args = vec![String::from("--check")]; - assert_eq!( - convert_message_format_to_rustfmt_args("json", &mut args), - Err(String::from( - "cannot include --check arg when --message-format is set to json" - )), - ); - } - - #[test] - fn json_message_format_and_emit_arg() { - let mut args = vec![String::from("--emit"), String::from("checkstyle")]; - assert_eq!( - convert_message_format_to_rustfmt_args("json", &mut args), - Err(String::from( - "cannot include --emit arg when --message-format is set to json" - )), - ); - } - - #[test] - fn json_message_format() { - let mut args = vec![String::from("--edition"), String::from("2018")]; - assert!(convert_message_format_to_rustfmt_args("json", &mut args).is_ok()); - assert_eq!( - args, - vec![ - String::from("--edition"), - String::from("2018"), - String::from("--emit"), - String::from("json") - ] - ); - } - - #[test] - fn human_message_format() { - let exp_args = vec![String::from("--emit"), String::from("json")]; - let mut act_args = exp_args.clone(); - assert!(convert_message_format_to_rustfmt_args("human", &mut act_args).is_ok()); - assert_eq!(act_args, exp_args); - } - - #[test] - fn short_message_format() { - let mut args = vec![String::from("--check")]; - assert!(convert_message_format_to_rustfmt_args("short", &mut args).is_ok()); - assert_eq!(args, vec![String::from("--check"), String::from("-l")]); - } - - #[test] - fn short_message_format_included_short_list_files_flag() { - let mut args = vec![String::from("--check"), String::from("-l")]; - assert!(convert_message_format_to_rustfmt_args("short", &mut args).is_ok()); - assert_eq!(args, vec![String::from("--check"), String::from("-l")]); - } - - #[test] - fn short_message_format_included_long_list_files_flag() { - let mut args = vec![String::from("--check"), String::from("--files-with-diff")]; - assert!(convert_message_format_to_rustfmt_args("short", &mut args).is_ok()); - assert_eq!( - args, - vec![String::from("--check"), String::from("--files-with-diff")] - ); - } - } -} From cb144c35e7d7151bb4b6ccd9b30a4141959166d1 Mon Sep 17 00:00:00 2001 From: Lucas Kent Date: Fri, 10 Sep 2021 17:50:40 +1000 Subject: [PATCH 059/111] In Configurations.md demonstrate both cases for noop selections --- Configurations.md | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/Configurations.md b/Configurations.md index b8f8f3053968..ff83f02f87ba 100644 --- a/Configurations.md +++ b/Configurations.md @@ -1684,6 +1684,9 @@ pub enum Foo {} #### `false`: ```rust +#[derive(Eq, PartialEq, Debug, Copy, Clone)] +pub enum Bar {} + #[derive(Eq, PartialEq)] #[derive(Debug)] #[derive(Copy, Clone)] @@ -1857,6 +1860,9 @@ Convert `#![doc]` and `#[doc]` attributes to `//!` and `///` doc comments. #![doc = "Example documentation"] #[doc = "Example item documentation"] +pub enum Bar {} + +/// Example item documentation pub enum Foo {} ``` @@ -1971,6 +1977,8 @@ fn main() { #### `false`: ```rust fn main() { + (foo()); + ((((foo())))); } ``` @@ -1996,6 +2004,14 @@ impl Iterator for Dummy { type Item = i32; } + +impl Iterator for Dummy { + type Item = i32; + + fn next(&mut self) -> Option { + None + } +} ``` #### `true` @@ -2552,7 +2568,8 @@ fn main() { let x = 1; let y = 2; let z = 3; - let a = Foo { x: x, y: y, z: z }; + let a = Foo { x, y, z }; + let b = Foo { x: x, y: y, z: z }; } ``` @@ -2721,6 +2738,8 @@ Replace uses of the try! macro by the ? shorthand ```rust fn main() { + let lorem = ipsum.map(|dolor| dolor.sit())?; + let lorem = try!(ipsum.map(|dolor| dolor.sit())); } ``` @@ -2792,6 +2811,12 @@ Break comments to fit on the line #### `false` (default): ```rust +// Lorem ipsum dolor sit amet, consectetur adipiscing elit, +// sed do eiusmod tempor incididunt ut labore et dolore +// magna aliqua. Ut enim ad minim veniam, quis nostrud +// exercitation ullamco laboris nisi ut aliquip ex ea +// commodo consequat. + // Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. ``` From a5138b34d5f2644d916e906a3d460856a1b1a42a Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Mon, 27 Sep 2021 16:55:23 -0400 Subject: [PATCH 060/111] Prevent removal of qualified path for tuple struct inside macro fixes 5005 This was very similar to 4964 and the fix was to extract and pass along the qself of the ``PatKind::TupleStruct`` --- src/patterns.rs | 5 +++-- tests/target/issue-5005/minimum_example.rs | 9 +++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 tests/target/issue-5005/minimum_example.rs diff --git a/src/patterns.rs b/src/patterns.rs index 0c6a6f3e8143..4c6a2d5d75b9 100644 --- a/src/patterns.rs +++ b/src/patterns.rs @@ -226,8 +226,9 @@ impl Rewrite for Pat { PatKind::Path(ref q_self, ref path) => { rewrite_path(context, PathContext::Expr, q_self.as_ref(), path, shape) } - PatKind::TupleStruct(_, ref path, ref pat_vec) => { - let path_str = rewrite_path(context, PathContext::Expr, None, path, shape)?; + PatKind::TupleStruct(ref q_self, ref path, ref pat_vec) => { + let path_str = + rewrite_path(context, PathContext::Expr, q_self.as_ref(), path, shape)?; rewrite_tuple_pat(pat_vec, Some(path_str), self.span, context, shape) } PatKind::Lit(ref expr) => expr.rewrite(context, shape), diff --git a/tests/target/issue-5005/minimum_example.rs b/tests/target/issue-5005/minimum_example.rs new file mode 100644 index 000000000000..11cc645fa535 --- /dev/null +++ b/tests/target/issue-5005/minimum_example.rs @@ -0,0 +1,9 @@ +#![feature(more_qualified_paths)] +macro_rules! show { + ($ty:ty, $ex:expr) => { + match $ex { + <$ty>::A(_val) => println!("got a"), // formatting should not remove <$ty>:: + <$ty>::B => println!("got b"), + } + }; +} From e3203ef5e6902e0bbb7b62ebd34b3d53cb5d28b8 Mon Sep 17 00:00:00 2001 From: Ulyssa Date: Mon, 20 Sep 2021 16:29:28 -0700 Subject: [PATCH 061/111] Add tests for binop_separator = Back --- tests/source/binop-separator-back/bitwise.rs | 14 ++++++++ tests/source/binop-separator-back/comp.rs | 23 +++++++++++++ tests/source/binop-separator-back/logic.rs | 7 ++++ tests/source/binop-separator-back/math.rs | 7 ++++ tests/source/binop-separator-back/patterns.rs | 9 +++++ tests/source/binop-separator-back/range.rs | 7 ++++ tests/target/binop-separator-back/bitwise.rs | 18 ++++++++++ tests/target/binop-separator-back/comp.rs | 33 +++++++++++++++++++ tests/target/binop-separator-back/logic.rs | 10 ++++++ tests/target/binop-separator-back/math.rs | 23 +++++++++++++ tests/target/binop-separator-back/patterns.rs | 11 +++++++ tests/target/binop-separator-back/range.rs | 9 +++++ 12 files changed, 171 insertions(+) create mode 100644 tests/source/binop-separator-back/bitwise.rs create mode 100644 tests/source/binop-separator-back/comp.rs create mode 100644 tests/source/binop-separator-back/logic.rs create mode 100644 tests/source/binop-separator-back/math.rs create mode 100644 tests/source/binop-separator-back/patterns.rs create mode 100644 tests/source/binop-separator-back/range.rs create mode 100644 tests/target/binop-separator-back/bitwise.rs create mode 100644 tests/target/binop-separator-back/comp.rs create mode 100644 tests/target/binop-separator-back/logic.rs create mode 100644 tests/target/binop-separator-back/math.rs create mode 100644 tests/target/binop-separator-back/patterns.rs create mode 100644 tests/target/binop-separator-back/range.rs diff --git a/tests/source/binop-separator-back/bitwise.rs b/tests/source/binop-separator-back/bitwise.rs new file mode 100644 index 000000000000..3804bf3215b1 --- /dev/null +++ b/tests/source/binop-separator-back/bitwise.rs @@ -0,0 +1,14 @@ +// rustfmt-binop_separator: Back + +fn main() { + let value = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ^ abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ; + + let value = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ & abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ; + + let value = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ | abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ; + + let value = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ << abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ; + + let value = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ >> abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ; + +} diff --git a/tests/source/binop-separator-back/comp.rs b/tests/source/binop-separator-back/comp.rs new file mode 100644 index 000000000000..50a27127445d --- /dev/null +++ b/tests/source/binop-separator-back/comp.rs @@ -0,0 +1,23 @@ +// rustfmt-binop_separator: Back + +fn main() { + if abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ < abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ { + // + } + + if abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ <= abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ { + // + } + + if abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ > abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ { + // + } + + if abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ >= abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ { + // + } + + if abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ == abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ { + // + } +} diff --git a/tests/source/binop-separator-back/logic.rs b/tests/source/binop-separator-back/logic.rs new file mode 100644 index 000000000000..8c297e5a6750 --- /dev/null +++ b/tests/source/binop-separator-back/logic.rs @@ -0,0 +1,7 @@ +// rustfmt-binop_separator: Back + +fn main() { + if abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ && abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ || abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ { + // + } +} diff --git a/tests/source/binop-separator-back/math.rs b/tests/source/binop-separator-back/math.rs new file mode 100644 index 000000000000..3af4aad16051 --- /dev/null +++ b/tests/source/binop-separator-back/math.rs @@ -0,0 +1,7 @@ +// rustfmt-binop_separator: Back + +fn main() { + let value = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ; + + let value = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ * abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ - abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ / abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ * abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ * abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ / abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ / abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ; +} diff --git a/tests/source/binop-separator-back/patterns.rs b/tests/source/binop-separator-back/patterns.rs new file mode 100644 index 000000000000..a8c3b5cdd9b1 --- /dev/null +++ b/tests/source/binop-separator-back/patterns.rs @@ -0,0 +1,9 @@ +// rustfmt-binop_separator: Back + +fn main() { + match val { + ThisIsA::ReallyLongPatternNameToHelpOverflowTheNextValueOntoTheNextLine | ThisIsA::SecondValueSeparatedByAPipe | ThisIsA::ThirdValueSeparatedByAPipe => { + // + } + } +} diff --git a/tests/source/binop-separator-back/range.rs b/tests/source/binop-separator-back/range.rs new file mode 100644 index 000000000000..bdd3de9922b0 --- /dev/null +++ b/tests/source/binop-separator-back/range.rs @@ -0,0 +1,7 @@ +// rustfmt-binop_separator: Back + +fn main() { + let value = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ..abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ; + + let value = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ..=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ; +} diff --git a/tests/target/binop-separator-back/bitwise.rs b/tests/target/binop-separator-back/bitwise.rs new file mode 100644 index 000000000000..ce32c05ef703 --- /dev/null +++ b/tests/target/binop-separator-back/bitwise.rs @@ -0,0 +1,18 @@ +// rustfmt-binop_separator: Back + +fn main() { + let value = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ^ + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ; + + let value = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ & + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ; + + let value = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ | + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ; + + let value = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ << + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ; + + let value = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ >> + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ; +} diff --git a/tests/target/binop-separator-back/comp.rs b/tests/target/binop-separator-back/comp.rs new file mode 100644 index 000000000000..efd837bcfe38 --- /dev/null +++ b/tests/target/binop-separator-back/comp.rs @@ -0,0 +1,33 @@ +// rustfmt-binop_separator: Back + +fn main() { + if abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ < + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + { + // + } + + if abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ <= + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + { + // + } + + if abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ > + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + { + // + } + + if abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ >= + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + { + // + } + + if abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ == + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + { + // + } +} diff --git a/tests/target/binop-separator-back/logic.rs b/tests/target/binop-separator-back/logic.rs new file mode 100644 index 000000000000..5f69fd5f55e4 --- /dev/null +++ b/tests/target/binop-separator-back/logic.rs @@ -0,0 +1,10 @@ +// rustfmt-binop_separator: Back + +fn main() { + if abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ && + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ || + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + { + // + } +} diff --git a/tests/target/binop-separator-back/math.rs b/tests/target/binop-separator-back/math.rs new file mode 100644 index 000000000000..7a3f27e733b2 --- /dev/null +++ b/tests/target/binop-separator-back/math.rs @@ -0,0 +1,23 @@ +// rustfmt-binop_separator: Back + +fn main() { + let value = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ; + + let value = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ * + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ - + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ / + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ * + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ * + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ / + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ / + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ + + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ; +} diff --git a/tests/target/binop-separator-back/patterns.rs b/tests/target/binop-separator-back/patterns.rs new file mode 100644 index 000000000000..2e59713526a0 --- /dev/null +++ b/tests/target/binop-separator-back/patterns.rs @@ -0,0 +1,11 @@ +// rustfmt-binop_separator: Back + +fn main() { + match val { + ThisIsA::ReallyLongPatternNameToHelpOverflowTheNextValueOntoTheNextLine | + ThisIsA::SecondValueSeparatedByAPipe | + ThisIsA::ThirdValueSeparatedByAPipe => { + // + } + } +} diff --git a/tests/target/binop-separator-back/range.rs b/tests/target/binop-separator-back/range.rs new file mode 100644 index 000000000000..19e5a81cd9cd --- /dev/null +++ b/tests/target/binop-separator-back/range.rs @@ -0,0 +1,9 @@ +// rustfmt-binop_separator: Back + +fn main() { + let value = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.. + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ; + + let value = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ..= + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ; +} From f0f449d6edda5a40057fc82ea02cc9abeae4d012 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Fri, 17 Sep 2021 18:56:30 -0700 Subject: [PATCH 062/111] Wrap long array and slice patterns. Closes #4530. --- src/overflow.rs | 4 +++- src/patterns.rs | 12 +++++++++++- tests/source/issue-4530.rs | 4 ++++ tests/target/issue-4530.rs | 9 +++++++++ 4 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 tests/source/issue-4530.rs create mode 100644 tests/target/issue-4530.rs diff --git a/src/overflow.rs b/src/overflow.rs index e32213467a51..ac24181c7805 100644 --- a/src/overflow.rs +++ b/src/overflow.rs @@ -77,6 +77,7 @@ pub(crate) enum OverflowableItem<'a> { FieldDef(&'a ast::FieldDef), TuplePatField(&'a TuplePatField<'a>), Ty(&'a ast::Ty), + Pat(&'a ast::Pat), } impl<'a> Rewrite for OverflowableItem<'a> { @@ -116,6 +117,7 @@ impl<'a> OverflowableItem<'a> { OverflowableItem::FieldDef(sf) => f(*sf), OverflowableItem::TuplePatField(pat) => f(*pat), OverflowableItem::Ty(ty) => f(*ty), + OverflowableItem::Pat(pat) => f(*pat), } } @@ -232,7 +234,7 @@ macro_rules! impl_into_overflowable_item_for_rustfmt_types { } } -impl_into_overflowable_item_for_ast_node!(Expr, GenericParam, NestedMetaItem, FieldDef, Ty); +impl_into_overflowable_item_for_ast_node!(Expr, GenericParam, NestedMetaItem, FieldDef, Ty, Pat); impl_into_overflowable_item_for_rustfmt_types!([MacroArg], [SegmentParam, TuplePatField]); pub(crate) fn into_overflowable_list<'a, T>( diff --git a/src/patterns.rs b/src/patterns.rs index 4c6a2d5d75b9..34987b1d59e4 100644 --- a/src/patterns.rs +++ b/src/patterns.rs @@ -4,6 +4,7 @@ use rustc_span::{BytePos, Span}; use crate::comment::{combine_strs_with_missing_comments, FindUncommented}; use crate::config::lists::*; +use crate::config::Version; use crate::expr::{can_be_overflowed_expr, rewrite_unary_prefix, wrap_struct_field}; use crate::lists::{ definitive_tactic, itemize_list, shape_for_tactic, struct_lit_formatting, struct_lit_shape, @@ -232,7 +233,7 @@ impl Rewrite for Pat { rewrite_tuple_pat(pat_vec, Some(path_str), self.span, context, shape) } PatKind::Lit(ref expr) => expr.rewrite(context, shape), - PatKind::Slice(ref slice_pat) => { + PatKind::Slice(ref slice_pat) if context.config.version() == Version::One => { let rw: Vec = slice_pat .iter() .map(|p| { @@ -245,6 +246,15 @@ impl Rewrite for Pat { .collect(); Some(format!("[{}]", rw.join(", "))) } + PatKind::Slice(ref slice_pat) => overflow::rewrite_with_square_brackets( + context, + "", + slice_pat.iter(), + shape, + self.span, + None, + None, + ), PatKind::Struct(ref qself, ref path, ref fields, ellipsis) => { rewrite_struct_pat(qself, path, fields, ellipsis, self.span, context, shape) } diff --git a/tests/source/issue-4530.rs b/tests/source/issue-4530.rs new file mode 100644 index 000000000000..9d2882abb3c1 --- /dev/null +++ b/tests/source/issue-4530.rs @@ -0,0 +1,4 @@ +// rustfmt-version: Two +fn main() { + let [aaaaaaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, cccccccccccccccccccccccccc, ddddddddddddddddddddddddd] = panic!(); +} diff --git a/tests/target/issue-4530.rs b/tests/target/issue-4530.rs new file mode 100644 index 000000000000..296dc559a934 --- /dev/null +++ b/tests/target/issue-4530.rs @@ -0,0 +1,9 @@ +// rustfmt-version: Two +fn main() { + let [ + aaaaaaaaaaaaaaaaaaaaaaaaaa, + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, + cccccccccccccccccccccccccc, + ddddddddddddddddddddddddd, + ] = panic!(); +} From 40f4993c67ff54e413da17496769407ab85f3924 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Thu, 23 Sep 2021 22:43:03 -0400 Subject: [PATCH 063/111] Update derive attibute span to start after opening '(' Fixes 4984 When parsing derive attributes we're only concerned about the traits and comments listed between the opening and closing parentheses. Derive attribute spans currently start at the '#'. Span starts here | v #[derive(...)] After this update the derive spans start after the opening '('. Span starts here | V #[derive(...)] --- src/attr.rs | 5 +++- tests/source/issue-4984/minimum_example.rs | 2 ++ tests/source/issue-4984/multi_line_derive.rs | 20 +++++++++++++++ tests/target/issue-4984/minimum_example.rs | 2 ++ tests/target/issue-4984/multi_line_derive.rs | 26 ++++++++++++++++++++ 5 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 tests/source/issue-4984/minimum_example.rs create mode 100644 tests/source/issue-4984/multi_line_derive.rs create mode 100644 tests/target/issue-4984/minimum_example.rs create mode 100644 tests/target/issue-4984/multi_line_derive.rs diff --git a/src/attr.rs b/src/attr.rs index 315eb10a9dbc..a5982820e3de 100644 --- a/src/attr.rs +++ b/src/attr.rs @@ -13,6 +13,7 @@ use crate::lists::{definitive_tactic, itemize_list, write_list, ListFormatting, use crate::overflow; use crate::rewrite::{Rewrite, RewriteContext}; use crate::shape::Shape; +use crate::source_map::SpanUtils; use crate::types::{rewrite_path, PathContext}; use crate::utils::{count_newlines, mk_sp}; @@ -116,7 +117,9 @@ fn format_derive( |span| span.lo(), |span| span.hi(), |span| Some(context.snippet(*span).to_owned()), - attr.span.lo(), + // We update derive attribute spans to start after the opening '(' + // This helps us focus parsing to just what's inside #[derive(...)] + context.snippet_provider.span_after(attr.span, "("), attr.span.hi(), false, ); diff --git a/tests/source/issue-4984/minimum_example.rs b/tests/source/issue-4984/minimum_example.rs new file mode 100644 index 000000000000..677f87377169 --- /dev/null +++ b/tests/source/issue-4984/minimum_example.rs @@ -0,0 +1,2 @@ +#[derive(/*Debug, */Clone)] +struct Foo; diff --git a/tests/source/issue-4984/multi_line_derive.rs b/tests/source/issue-4984/multi_line_derive.rs new file mode 100644 index 000000000000..73921dd17354 --- /dev/null +++ b/tests/source/issue-4984/multi_line_derive.rs @@ -0,0 +1,20 @@ +#[derive( +/* ---------- Some really important comment that just had to go inside the derive --------- */ +Debug, Clone, Eq, PartialEq, +)] +struct Foo { + a: i32, + b: T, +} + +#[derive( +/* + Some really important comment that just had to go inside the derive. + Also had to be put over multiple lines +*/ +Debug, Clone, Eq, PartialEq, +)] +struct Bar { + a: i32, + b: T, +} diff --git a/tests/target/issue-4984/minimum_example.rs b/tests/target/issue-4984/minimum_example.rs new file mode 100644 index 000000000000..f0599c5d694b --- /dev/null +++ b/tests/target/issue-4984/minimum_example.rs @@ -0,0 +1,2 @@ +#[derive(/*Debug, */ Clone)] +struct Foo; diff --git a/tests/target/issue-4984/multi_line_derive.rs b/tests/target/issue-4984/multi_line_derive.rs new file mode 100644 index 000000000000..5fbd9784adc9 --- /dev/null +++ b/tests/target/issue-4984/multi_line_derive.rs @@ -0,0 +1,26 @@ +#[derive( + /* ---------- Some really important comment that just had to go inside the derive --------- */ + Debug, + Clone, + Eq, + PartialEq, +)] +struct Foo { + a: i32, + b: T, +} + +#[derive( + /* + Some really important comment that just had to go inside the derive. + Also had to be put over multiple lines + */ + Debug, + Clone, + Eq, + PartialEq, +)] +struct Bar { + a: i32, + b: T, +} From 365a2f8f6e710f67d6485fe9004bb3f64da977bc Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Wed, 29 Sep 2021 14:18:54 -0400 Subject: [PATCH 064/111] Add additional test cases for issue 4984 --- tests/source/issue-4984/multiple_comments_within.rs | 8 ++++++++ tests/target/issue-4984/multiple_comments_within.rs | 11 +++++++++++ tests/target/issue-4984/should_not_change.rs | 5 +++++ 3 files changed, 24 insertions(+) create mode 100644 tests/source/issue-4984/multiple_comments_within.rs create mode 100644 tests/target/issue-4984/multiple_comments_within.rs create mode 100644 tests/target/issue-4984/should_not_change.rs diff --git a/tests/source/issue-4984/multiple_comments_within.rs b/tests/source/issue-4984/multiple_comments_within.rs new file mode 100644 index 000000000000..eb474a723d01 --- /dev/null +++ b/tests/source/issue-4984/multiple_comments_within.rs @@ -0,0 +1,8 @@ +#[derive( +/* ---------- Some really important comment that just had to go inside the derive --------- */ +Debug, Clone,/* Another comment */Eq, PartialEq, +)] +struct Foo { + a: i32, + b: T, +} diff --git a/tests/target/issue-4984/multiple_comments_within.rs b/tests/target/issue-4984/multiple_comments_within.rs new file mode 100644 index 000000000000..d2924f0d0f2e --- /dev/null +++ b/tests/target/issue-4984/multiple_comments_within.rs @@ -0,0 +1,11 @@ +#[derive( + /* ---------- Some really important comment that just had to go inside the derive --------- */ + Debug, + Clone, + /* Another comment */ Eq, + PartialEq, +)] +struct Foo { + a: i32, + b: T, +} diff --git a/tests/target/issue-4984/should_not_change.rs b/tests/target/issue-4984/should_not_change.rs new file mode 100644 index 000000000000..e46ee511084f --- /dev/null +++ b/tests/target/issue-4984/should_not_change.rs @@ -0,0 +1,5 @@ +#[derive(Clone, Debug, Eq, PartialEq)] +struct Foo; + +#[derive(Clone)] +struct Bar; From 8b58cce673d6ae4fbc1f3a8d28859bc100a72ed8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sat, 16 May 2020 22:20:51 +0200 Subject: [PATCH 065/111] Stabilize match_block_trailing_comma. (#4145) Servo has used this since forever, and it'd be useful to be able to use rustfmt stable there so that we can use the same rustfmt version in both Firefox and Servo. Feel free to close this if there's any reason it shouldn't be done. --- Configurations.md | 2 +- src/config/mod.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Configurations.md b/Configurations.md index ff83f02f87ba..06db897a42e7 100644 --- a/Configurations.md +++ b/Configurations.md @@ -1626,7 +1626,7 @@ Put a trailing comma after a block based match arm (non-block arms are not affec - **Default value**: `false` - **Possible values**: `true`, `false` -- **Stable**: No (tracking issue: #3380) +- **Stable**: Yes #### `false` (default): diff --git a/src/config/mod.rs b/src/config/mod.rs index c6cee8ed2273..398a1814d8d1 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -127,7 +127,7 @@ create_config! { "Add trailing semicolon after break, continue and return"; trailing_comma: SeparatorTactic, SeparatorTactic::Vertical, false, "How to handle trailing commas for lists"; - match_block_trailing_comma: bool, false, false, + match_block_trailing_comma: bool, false, true, "Put a trailing comma after a block based match arm (non-block arms are not affected)"; blank_lines_upper_bound: usize, 1, false, "Maximum number of blank lines which can be put between items"; From d41805704d4a07ac77e0bc59ea5c91cdb69dea26 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Mon, 11 Oct 2021 18:30:35 -0400 Subject: [PATCH 066/111] Prevent structs with ".." from being rewritten with alignment rustfmt should only support rewriting a struct in an expression position with alignment (non-default behavior) when there is no rest (with or without a base) and all of the fields are non-shorthand. --- src/expr.rs | 11 ++-- .../source/issue-4926/deeply_nested_struct.rs | 35 ++++++++++++ ...ply_nested_struct_with_long_field_names.rs | 43 +++++++++++++++ .../deeply_nested_struct_with_many_fields.rs | 44 +++++++++++++++ tests/source/issue-4926/enum_struct_field.rs | 35 ++++++++++++ tests/source/issue-4926/minimum_example.rs | 10 ++++ .../struct_with_long_field_names.rs | 21 ++++++++ .../issue-4926/struct_with_many_fields.rs | 21 ++++++++ .../target/issue-4926/deeply_nested_struct.rs | 38 +++++++++++++ ...ply_nested_struct_with_long_field_names.rs | 44 +++++++++++++++ .../deeply_nested_struct_with_many_fields.rs | 54 +++++++++++++++++++ tests/target/issue-4926/enum_struct_field.rs | 41 ++++++++++++++ tests/target/issue-4926/minimum_example.rs | 10 ++++ .../struct_with_long_field_names.rs | 24 +++++++++ .../issue-4926/struct_with_many_fields.rs | 34 ++++++++++++ 15 files changed, 458 insertions(+), 7 deletions(-) create mode 100644 tests/source/issue-4926/deeply_nested_struct.rs create mode 100644 tests/source/issue-4926/deeply_nested_struct_with_long_field_names.rs create mode 100644 tests/source/issue-4926/deeply_nested_struct_with_many_fields.rs create mode 100644 tests/source/issue-4926/enum_struct_field.rs create mode 100644 tests/source/issue-4926/minimum_example.rs create mode 100644 tests/source/issue-4926/struct_with_long_field_names.rs create mode 100644 tests/source/issue-4926/struct_with_many_fields.rs create mode 100644 tests/target/issue-4926/deeply_nested_struct.rs create mode 100644 tests/target/issue-4926/deeply_nested_struct_with_long_field_names.rs create mode 100644 tests/target/issue-4926/deeply_nested_struct_with_many_fields.rs create mode 100644 tests/target/issue-4926/enum_struct_field.rs create mode 100644 tests/target/issue-4926/minimum_example.rs create mode 100644 tests/target/issue-4926/struct_with_long_field_names.rs create mode 100644 tests/target/issue-4926/struct_with_many_fields.rs diff --git a/src/expr.rs b/src/expr.rs index 01cc388c186e..3a54426b0ddb 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -1528,12 +1528,12 @@ fn rewrite_struct_lit<'a>( let path_shape = shape.sub_width(2)?; let path_str = rewrite_path(context, PathContext::Expr, None, path, path_shape)?; - let has_base = match struct_rest { + let has_base_or_rest = match struct_rest { ast::StructRest::None if fields.is_empty() => return Some(format!("{} {{}}", path_str)), ast::StructRest::Rest(_) if fields.is_empty() => { return Some(format!("{} {{ .. }}", path_str)); } - ast::StructRest::Base(_) => true, + ast::StructRest::Rest(_) | ast::StructRest::Base(_) => true, _ => false, }; @@ -1542,7 +1542,7 @@ fn rewrite_struct_lit<'a>( let one_line_width = h_shape.map_or(0, |shape| shape.width); let body_lo = context.snippet_provider.span_after(span, "{"); - let fields_str = if struct_lit_can_be_aligned(fields, has_base) + let fields_str = if struct_lit_can_be_aligned(fields, has_base_or_rest) && context.config.struct_field_align_threshold() > 0 { rewrite_with_alignment( @@ -1614,10 +1614,7 @@ fn rewrite_struct_lit<'a>( nested_shape, tactic, context, - force_no_trailing_comma - || has_base - || !context.use_block_indent() - || matches!(struct_rest, ast::StructRest::Rest(_)), + force_no_trailing_comma || has_base_or_rest || !context.use_block_indent(), ); write_list(&item_vec, &fmt)? diff --git a/tests/source/issue-4926/deeply_nested_struct.rs b/tests/source/issue-4926/deeply_nested_struct.rs new file mode 100644 index 000000000000..e55e41bd1a58 --- /dev/null +++ b/tests/source/issue-4926/deeply_nested_struct.rs @@ -0,0 +1,35 @@ + +// rustfmt-struct_field_align_threshold: 30 + +struct X { + a: i32, + b: i32, + c: i32, +} + +fn test(x: X) { + let d = { + let e = { + let f = { + let g = { + let h = { + let i = { + let j = { + matches!( + x, + X { a: 1_000, b: 1_000, .. } + ) + }; + j + }; + i + }; + h + }; + g + }; + f + }; + e + }; +} \ No newline at end of file diff --git a/tests/source/issue-4926/deeply_nested_struct_with_long_field_names.rs b/tests/source/issue-4926/deeply_nested_struct_with_long_field_names.rs new file mode 100644 index 000000000000..516699fa2b8b --- /dev/null +++ b/tests/source/issue-4926/deeply_nested_struct_with_long_field_names.rs @@ -0,0 +1,43 @@ +// rustfmt-struct_field_align_threshold: 30 + +struct X { + really_really_long_field_a: i32, + really_really_really_long_field_b: i32, + really_really_really_really_long_field_c: i32, + really_really_really_really_really_long_field_d: i32, + really_really_really_really_really_really_long_field_e: i32, + f: i32, +} + +fn test(x: X) { + let d = { + let e = { + let f = { + let g = { + let h = { + let i = { + let j = { + matches!( + x, + X { + really_really_long_field_a: 10, + really_really_really_long_field_b: 10, + really_really_really_really_long_field_c: 10, + really_really_really_really_really_long_field_d: 10, + really_really_really_really_really_really_long_field_e: 10, .. + } + ) + }; + j + }; + i + }; + h + }; + g + }; + f + }; + e + }; +} diff --git a/tests/source/issue-4926/deeply_nested_struct_with_many_fields.rs b/tests/source/issue-4926/deeply_nested_struct_with_many_fields.rs new file mode 100644 index 000000000000..38fd6f02cf06 --- /dev/null +++ b/tests/source/issue-4926/deeply_nested_struct_with_many_fields.rs @@ -0,0 +1,44 @@ +// rustfmt-struct_field_align_threshold: 30 + +struct X { + a: i32, + b: i32, + c: i32, + d: i32, + e: i32, + f: i32, + g: i32, + h: i32, + i: i32, + j: i32, + k: i32, +} + +fn test(x: X) { + let d = { + let e = { + let f = { + let g = { + let h = { + let i = { + let j = { + matches!( + x, + X { + a: 1_000, b: 1_000, c: 1_000, d: 1_000, e: 1_000, f: 1_000, g: 1_000, h: 1_000, i: 1_000, j: 1_000, .. + } + ) + }; + j + }; + i + }; + h + }; + g + }; + f + }; + e + }; +} diff --git a/tests/source/issue-4926/enum_struct_field.rs b/tests/source/issue-4926/enum_struct_field.rs new file mode 100644 index 000000000000..336378537df3 --- /dev/null +++ b/tests/source/issue-4926/enum_struct_field.rs @@ -0,0 +1,35 @@ +// rustfmt-struct_field_align_threshold: 30 +// rustfmt-enum_discrim_align_threshold: 30 +// rustfmt-imports_layout: HorizontalVertical + +#[derive(Default)] +struct InnerStructA { bbbbbbbbb: i32, cccccccc: i32 } + +enum SomeEnumNamedD { + E(InnerStructA), + F { + ggggggggggggggggggggggggg: bool, + h: bool, + } +} + +impl SomeEnumNamedD { + fn f_variant() -> Self { + Self::F { ggggggggggggggggggggggggg: true, h: true } + } +} + +fn main() { + let kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk = SomeEnumNamedD::f_variant(); + let something_we_care_about = matches!( + kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk, + SomeEnumNamedD::F { + ggggggggggggggggggggggggg: true, + .. + } + ); + + if something_we_care_about { + println!("Yup it happened"); + } +} diff --git a/tests/source/issue-4926/minimum_example.rs b/tests/source/issue-4926/minimum_example.rs new file mode 100644 index 000000000000..2c3045dea489 --- /dev/null +++ b/tests/source/issue-4926/minimum_example.rs @@ -0,0 +1,10 @@ +// rustfmt-struct_field_align_threshold: 30 + +struct X { a: i32, b: i32 } + +fn test(x: X) { + let y = matches!(x, X { + a: 1, + .. + }); +} diff --git a/tests/source/issue-4926/struct_with_long_field_names.rs b/tests/source/issue-4926/struct_with_long_field_names.rs new file mode 100644 index 000000000000..b8a37f0714ee --- /dev/null +++ b/tests/source/issue-4926/struct_with_long_field_names.rs @@ -0,0 +1,21 @@ +// rustfmt-struct_field_align_threshold: 30 + +struct X { + really_really_long_field_a: i32, + really_really_really_long_field_b: i32, + really_really_really_really_long_field_c: i32, + really_really_really_really_really_long_field_d: i32, + really_really_really_really_really_really_long_field_e: i32, + f: i32, +} + +fn test(x: X) { + let y = matches!(x, X { + really_really_long_field_a: 10, + really_really_really_long_field_b: 10, + really_really_really_really_long_field_c: 10, + really_really_really_really_really_long_field_d: 10, + really_really_really_really_really_really_long_field_e: 10, + .. + }); +} diff --git a/tests/source/issue-4926/struct_with_many_fields.rs b/tests/source/issue-4926/struct_with_many_fields.rs new file mode 100644 index 000000000000..4adfd3b30629 --- /dev/null +++ b/tests/source/issue-4926/struct_with_many_fields.rs @@ -0,0 +1,21 @@ +// rustfmt-struct_field_align_threshold: 30 + +struct X { + a: i32, + b: i32, + c: i32, + d: i32, + e: i32, + f: i32, + g: i32, + h: i32, + i: i32, + j: i32, + k: i32, +} + +fn test(x: X) { + let y = matches!(x, X { + a: 1_000, b: 1_000, c: 1_000, d: 1_000, e: 1_000, f: 1_000, g: 1_000, h: 1_000, i: 1_000, j: 1_000, .. + }); +} \ No newline at end of file diff --git a/tests/target/issue-4926/deeply_nested_struct.rs b/tests/target/issue-4926/deeply_nested_struct.rs new file mode 100644 index 000000000000..072cf2f6674a --- /dev/null +++ b/tests/target/issue-4926/deeply_nested_struct.rs @@ -0,0 +1,38 @@ +// rustfmt-struct_field_align_threshold: 30 + +struct X { + a: i32, + b: i32, + c: i32, +} + +fn test(x: X) { + let d = { + let e = { + let f = { + let g = { + let h = { + let i = { + let j = { + matches!( + x, + X { + a: 1_000, + b: 1_000, + .. + } + ) + }; + j + }; + i + }; + h + }; + g + }; + f + }; + e + }; +} diff --git a/tests/target/issue-4926/deeply_nested_struct_with_long_field_names.rs b/tests/target/issue-4926/deeply_nested_struct_with_long_field_names.rs new file mode 100644 index 000000000000..c7bc7f7296d6 --- /dev/null +++ b/tests/target/issue-4926/deeply_nested_struct_with_long_field_names.rs @@ -0,0 +1,44 @@ +// rustfmt-struct_field_align_threshold: 30 + +struct X { + really_really_long_field_a: i32, + really_really_really_long_field_b: i32, + really_really_really_really_long_field_c: i32, + really_really_really_really_really_long_field_d: i32, + really_really_really_really_really_really_long_field_e: i32, + f: i32, +} + +fn test(x: X) { + let d = { + let e = { + let f = { + let g = { + let h = { + let i = { + let j = { + matches!( + x, + X { + really_really_long_field_a: 10, + really_really_really_long_field_b: 10, + really_really_really_really_long_field_c: 10, + really_really_really_really_really_long_field_d: 10, + really_really_really_really_really_really_long_field_e: 10, + .. + } + ) + }; + j + }; + i + }; + h + }; + g + }; + f + }; + e + }; +} diff --git a/tests/target/issue-4926/deeply_nested_struct_with_many_fields.rs b/tests/target/issue-4926/deeply_nested_struct_with_many_fields.rs new file mode 100644 index 000000000000..69793162519a --- /dev/null +++ b/tests/target/issue-4926/deeply_nested_struct_with_many_fields.rs @@ -0,0 +1,54 @@ +// rustfmt-struct_field_align_threshold: 30 + +struct X { + a: i32, + b: i32, + c: i32, + d: i32, + e: i32, + f: i32, + g: i32, + h: i32, + i: i32, + j: i32, + k: i32, +} + +fn test(x: X) { + let d = { + let e = { + let f = { + let g = { + let h = { + let i = { + let j = { + matches!( + x, + X { + a: 1_000, + b: 1_000, + c: 1_000, + d: 1_000, + e: 1_000, + f: 1_000, + g: 1_000, + h: 1_000, + i: 1_000, + j: 1_000, + .. + } + ) + }; + j + }; + i + }; + h + }; + g + }; + f + }; + e + }; +} diff --git a/tests/target/issue-4926/enum_struct_field.rs b/tests/target/issue-4926/enum_struct_field.rs new file mode 100644 index 000000000000..2471df84653c --- /dev/null +++ b/tests/target/issue-4926/enum_struct_field.rs @@ -0,0 +1,41 @@ +// rustfmt-struct_field_align_threshold: 30 +// rustfmt-enum_discrim_align_threshold: 30 +// rustfmt-imports_layout: HorizontalVertical + +#[derive(Default)] +struct InnerStructA { + bbbbbbbbb: i32, + cccccccc: i32, +} + +enum SomeEnumNamedD { + E(InnerStructA), + F { + ggggggggggggggggggggggggg: bool, + h: bool, + }, +} + +impl SomeEnumNamedD { + fn f_variant() -> Self { + Self::F { + ggggggggggggggggggggggggg: true, + h: true, + } + } +} + +fn main() { + let kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk = SomeEnumNamedD::f_variant(); + let something_we_care_about = matches!( + kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk, + SomeEnumNamedD::F { + ggggggggggggggggggggggggg: true, + .. + } + ); + + if something_we_care_about { + println!("Yup it happened"); + } +} diff --git a/tests/target/issue-4926/minimum_example.rs b/tests/target/issue-4926/minimum_example.rs new file mode 100644 index 000000000000..06e18427465c --- /dev/null +++ b/tests/target/issue-4926/minimum_example.rs @@ -0,0 +1,10 @@ +// rustfmt-struct_field_align_threshold: 30 + +struct X { + a: i32, + b: i32, +} + +fn test(x: X) { + let y = matches!(x, X { a: 1, .. }); +} diff --git a/tests/target/issue-4926/struct_with_long_field_names.rs b/tests/target/issue-4926/struct_with_long_field_names.rs new file mode 100644 index 000000000000..ac4674ab5d52 --- /dev/null +++ b/tests/target/issue-4926/struct_with_long_field_names.rs @@ -0,0 +1,24 @@ +// rustfmt-struct_field_align_threshold: 30 + +struct X { + really_really_long_field_a: i32, + really_really_really_long_field_b: i32, + really_really_really_really_long_field_c: i32, + really_really_really_really_really_long_field_d: i32, + really_really_really_really_really_really_long_field_e: i32, + f: i32, +} + +fn test(x: X) { + let y = matches!( + x, + X { + really_really_long_field_a: 10, + really_really_really_long_field_b: 10, + really_really_really_really_long_field_c: 10, + really_really_really_really_really_long_field_d: 10, + really_really_really_really_really_really_long_field_e: 10, + .. + } + ); +} diff --git a/tests/target/issue-4926/struct_with_many_fields.rs b/tests/target/issue-4926/struct_with_many_fields.rs new file mode 100644 index 000000000000..96dfe14bf7dd --- /dev/null +++ b/tests/target/issue-4926/struct_with_many_fields.rs @@ -0,0 +1,34 @@ +// rustfmt-struct_field_align_threshold: 30 + +struct X { + a: i32, + b: i32, + c: i32, + d: i32, + e: i32, + f: i32, + g: i32, + h: i32, + i: i32, + j: i32, + k: i32, +} + +fn test(x: X) { + let y = matches!( + x, + X { + a: 1_000, + b: 1_000, + c: 1_000, + d: 1_000, + e: 1_000, + f: 1_000, + g: 1_000, + h: 1_000, + i: 1_000, + j: 1_000, + .. + } + ); +} From f7c4a44149b4e3a683f5506929050f2b50117328 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Tue, 5 Oct 2021 01:24:10 -0400 Subject: [PATCH 067/111] Adjust non-empty tuple struct span to start before fields Resolves 5011 Tuple structs with visibility modifiers and comments before the first field were incorrectly formatted. Comments would duplicate part of the visibility modifier and struct name. When trying to parse the tuple fields the ``items::Context`` searches for the opening '(', but because the visibility modifier introduces another '(' -- for example ``pub(crate)`` -- the parsing gets messed up. Now the span is adjusted to start after the struct identifier, or after any generics. Adjusting the span in this way ensures that the ``items::Contex`` will correctly find the tuple fields. --- src/items.rs | 7 ++++++- tests/source/issue-5011.rs | 12 ++++++++++++ tests/target/issue-5011.rs | 8 ++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 tests/source/issue-5011.rs create mode 100644 tests/target/issue-5011.rs diff --git a/src/items.rs b/src/items.rs index e8eb1c5dfbb5..471a365e4706 100644 --- a/src/items.rs +++ b/src/items.rs @@ -1469,12 +1469,17 @@ fn format_tuple_struct( format_empty_struct_or_tuple(context, inner_span, offset, &mut result, "(", ")"); } else { let shape = Shape::indented(offset, context.config).sub_width(1)?; + let lo = if let Some(generics) = struct_parts.generics { + generics.span.hi() + } else { + struct_parts.ident.span.hi() + }; result = overflow::rewrite_with_parens( context, &result, fields.iter(), shape, - span, + mk_sp(lo, span.hi()), context.config.fn_call_width(), None, )?; diff --git a/tests/source/issue-5011.rs b/tests/source/issue-5011.rs new file mode 100644 index 000000000000..b48292164e43 --- /dev/null +++ b/tests/source/issue-5011.rs @@ -0,0 +1,12 @@ +pub(crate) struct ASlash( + // hello + i32 +); + +pub(crate) struct AStar( + /* hello */ + i32 +); + +pub(crate) struct BStar(/* hello */ i32); + diff --git a/tests/target/issue-5011.rs b/tests/target/issue-5011.rs new file mode 100644 index 000000000000..9ad4a1929bdb --- /dev/null +++ b/tests/target/issue-5011.rs @@ -0,0 +1,8 @@ +pub(crate) struct ASlash( + // hello + i32, +); + +pub(crate) struct AStar(/* hello */ i32); + +pub(crate) struct BStar(/* hello */ i32); From f2fb3c9659e072d7df6315906f1adbd06c3bc9e3 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Wed, 6 Oct 2021 13:09:24 -0400 Subject: [PATCH 068/111] Update connector search in ControlFlow::rewrite_pat_expr for for loops Resolves 5009 For loops represented by a ControlFlow object use " in" as their connector. rustfmt searches for the first uncommented occurrence of the word "in" within the current span and adjusts it's starting point to look for comments right after that. visually this looks like this: rustfmt starts looking for comments here | V for x in /* ... */ 0..1 {} This works well in most cases, however when the pattern also contains the word "in", this leads to issues. rustfmt starts looking for comments here | V for in_here in /* ... */ 0..1 {} ------- pattern In order to correctly identify the connector, the new approach first updates the span to start after the pattern and then searches for the first uncommented occurrence of "in". --- src/expr.rs | 2 +- tests/target/issue-5009/1_minimum_example.rs | 4 +++ .../2_many_in_connectors_in_pattern.rs | 3 ++ ...sted_for_loop_with_connector_in_pattern.rs | 5 +++ .../4_nested_for_loop_with_if_elseif_else.rs | 13 ++++++++ ...r_loop_with_connector_in_if_elseif_else.rs | 15 +++++++++ ...sted_for_loop_with_connector_in_pattern.rs | 32 +++++++++++++++++++ 7 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 tests/target/issue-5009/1_minimum_example.rs create mode 100644 tests/target/issue-5009/2_many_in_connectors_in_pattern.rs create mode 100644 tests/target/issue-5009/3_nested_for_loop_with_connector_in_pattern.rs create mode 100644 tests/target/issue-5009/4_nested_for_loop_with_if_elseif_else.rs create mode 100644 tests/target/issue-5009/5_nested_for_loop_with_connector_in_if_elseif_else.rs create mode 100644 tests/target/issue-5009/6_deeply_nested_for_loop_with_connector_in_pattern.rs diff --git a/src/expr.rs b/src/expr.rs index 3a54426b0ddb..f40f80e42532 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -822,7 +822,7 @@ impl<'a> ControlFlow<'a> { let pat_string = pat.rewrite(context, pat_shape)?; let comments_lo = context .snippet_provider - .span_after(self.span, self.connector.trim()); + .span_after(self.span.with_lo(pat.span.hi()), self.connector.trim()); let comments_span = mk_sp(comments_lo, expr.span.lo()); return rewrite_assign_rhs_with_comments( context, diff --git a/tests/target/issue-5009/1_minimum_example.rs b/tests/target/issue-5009/1_minimum_example.rs new file mode 100644 index 000000000000..55836f4bf52c --- /dev/null +++ b/tests/target/issue-5009/1_minimum_example.rs @@ -0,0 +1,4 @@ +fn main() { + // the "in" inside the pattern produced invalid syntax + for variable_in_here /* ... */ in 0..1 {} +} diff --git a/tests/target/issue-5009/2_many_in_connectors_in_pattern.rs b/tests/target/issue-5009/2_many_in_connectors_in_pattern.rs new file mode 100644 index 000000000000..d83590c6852f --- /dev/null +++ b/tests/target/issue-5009/2_many_in_connectors_in_pattern.rs @@ -0,0 +1,3 @@ +fn main() { + for in_in_in_in_in_in_in_in /* ... */ in 0..1 {} +} diff --git a/tests/target/issue-5009/3_nested_for_loop_with_connector_in_pattern.rs b/tests/target/issue-5009/3_nested_for_loop_with_connector_in_pattern.rs new file mode 100644 index 000000000000..9c800723939b --- /dev/null +++ b/tests/target/issue-5009/3_nested_for_loop_with_connector_in_pattern.rs @@ -0,0 +1,5 @@ +fn main() { + for variable_in_x /* ... */ in 0..1 { + for variable_in_y /* ... */ in 0..1 {} + } +} diff --git a/tests/target/issue-5009/4_nested_for_loop_with_if_elseif_else.rs b/tests/target/issue-5009/4_nested_for_loop_with_if_elseif_else.rs new file mode 100644 index 000000000000..a716d0d3082a --- /dev/null +++ b/tests/target/issue-5009/4_nested_for_loop_with_if_elseif_else.rs @@ -0,0 +1,13 @@ +fn main() { + for variable_in_x /* ... */ in 0..1 { + for variable_in_y /* ... */ in 0..1 { + if false { + + } else if false { + + } else { + + } + } + } +} diff --git a/tests/target/issue-5009/5_nested_for_loop_with_connector_in_if_elseif_else.rs b/tests/target/issue-5009/5_nested_for_loop_with_connector_in_if_elseif_else.rs new file mode 100644 index 000000000000..41ea46d4cb9b --- /dev/null +++ b/tests/target/issue-5009/5_nested_for_loop_with_connector_in_if_elseif_else.rs @@ -0,0 +1,15 @@ +fn main() { + let in_ = false; + + for variable_in_x /* ... */ in 0..1 { + for variable_in_y /* ... */ in 0..1 { + if in_ { + + } else if in_ { + + } else { + + } + } + } +} diff --git a/tests/target/issue-5009/6_deeply_nested_for_loop_with_connector_in_pattern.rs b/tests/target/issue-5009/6_deeply_nested_for_loop_with_connector_in_pattern.rs new file mode 100644 index 000000000000..789e54f7e5fb --- /dev/null +++ b/tests/target/issue-5009/6_deeply_nested_for_loop_with_connector_in_pattern.rs @@ -0,0 +1,32 @@ +fn main() { + for variable_in_a /* ... */ in 0..1 { + for variable_in_b /* ... */ in 0..1 { + for variable_in_c /* ... */ in 0..1 { + for variable_in_d /* ... */ in 0..1 { + for variable_in_e /* ... */ in 0..1 { + for variable_in_f /* ... */ in 0..1 { + for variable_in_g /* ... */ in 0..1 { + for variable_in_h /* ... */ in 0..1 { + for variable_in_i /* ... */ in 0..1 { + for variable_in_j /* ... */ in 0..1 { + for variable_in_k /* ... */ in 0..1 { + for variable_in_l /* ... */ in 0..1 { + for variable_in_m /* ... */ in 0..1 { + for variable_in_n /* ... */ in 0..1 { + for variable_in_o /* ... */ in 0..1 { + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } +} From c9c1932be3299b40eab63106deeb5d5ad2283b61 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Wed, 13 Oct 2021 21:22:34 -0500 Subject: [PATCH 069/111] feat: stabilize disable_all_formatting --- Configurations.md | 6 ++++-- src/config/mod.rs | 2 +- src/test/mod.rs | 5 ----- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/Configurations.md b/Configurations.md index 06db897a42e7..7a77dbe154b6 100644 --- a/Configurations.md +++ b/Configurations.md @@ -521,11 +521,13 @@ fn main() { ## `disable_all_formatting` -Don't reformat anything +Don't reformat anything. + +Note that this option may be soft-deprecated in the future once the [ignore](#ignore) option is stabilized. Nightly toolchain users are encouraged to use [ignore](#ignore) instead when possible. - **Default value**: `false` - **Possible values**: `true`, `false` -- **Stable**: No (tracking issue: #3388) +- **Stable**: Yes ## `edition` diff --git a/src/config/mod.rs b/src/config/mod.rs index 398a1814d8d1..c5419d860c94 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -155,7 +155,7 @@ create_config! { "Require a specific version of rustfmt"; unstable_features: bool, false, false, "Enables unstable features. Only available on nightly channel"; - disable_all_formatting: bool, false, false, "Don't reformat anything"; + disable_all_formatting: bool, false, true, "Don't reformat anything"; skip_children: bool, false, false, "Don't reformat out of line modules"; hide_parse_errors: bool, false, false, "Hide errors from the parser"; error_on_line_overflow: bool, false, false, "Error if unable to get all lines within max_width"; diff --git a/src/test/mod.rs b/src/test/mod.rs index ece1b91bfd7c..48d61289a9b8 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -469,11 +469,6 @@ fn stdin_works_with_modified_lines() { #[test] fn stdin_disable_all_formatting_test() { init_log(); - match option_env!("CFG_RELEASE_CHANNEL") { - None | Some("nightly") => {} - // These tests require nightly. - _ => return, - } let input = String::from("fn main() { println!(\"This should not be formatted.\"); }"); let mut child = Command::new(rustfmt().to_str().unwrap()) .stdin(Stdio::piped()) From 0cff306b61922ed5f460a4f6cbd4134498a3c42f Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Wed, 13 Oct 2021 21:41:50 -0500 Subject: [PATCH 070/111] ci: fix release asset upload job --- .github/workflows/upload-assets.yml | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/.github/workflows/upload-assets.yml b/.github/workflows/upload-assets.yml index 9a5fd0dd1d31..f4dd39444530 100644 --- a/.github/workflows/upload-assets.yml +++ b/.github/workflows/upload-assets.yml @@ -1,8 +1,10 @@ name: upload on: + push: release: types: [created] + workflow_dispatch: jobs: build-release: @@ -14,42 +16,40 @@ jobs: - build: linux-x86_64 os: ubuntu-latest rust: nightly + target: x86_64-unknown-linux-gnu - build: macos-x86_64 os: macos-latest rust: nightly + target: x86_64-apple-darwin - build: windows-x86_64-gnu os: windows-latest rust: nightly-x86_64-gnu + target: x86_64-pc-windows-gnu - build: windows-x86_64-msvc os: windows-latest rust: nightly-x86_64-msvc + target: x86_64-pc-windows-msvc runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v2 - - name: Install Rust - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: ${{ matrix.rust }} - override: true + # Run build + - name: install rustup + run: | + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs > rustup-init.sh + sh rustup-init.sh -y --default-toolchain none + rustup target add ${{ matrix.target }} - name: Add mingw64 to path for x86_64-gnu run: echo "C:\msys64\mingw64\bin" >> $GITHUB_PATH if: matrix.rust == 'nightly-x86_64-gnu' shell: bash - - name: Install cargo-make - uses: actions-rs/cargo@v1 - with: - command: install - args: --force cargo-make - - name: Build release binaries uses: actions-rs/cargo@v1 with: - command: make - args: release + command: build + args: --release - name: Build archive shell: bash @@ -70,6 +70,7 @@ jobs: fi - name: Upload Release Asset + if: github.event_name == 'release' uses: actions/upload-release-asset@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 5f4811ed7bc600e0cbe40c962e8933adb9baaddf Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Thu, 14 Oct 2021 17:16:28 -0400 Subject: [PATCH 071/111] Handle DefinitiveListTactic::SpecialMacro when writing pre-comments Resolves 4615 Previously only Vertical and Mixed enum variants of DefinitiveListTactic were considered when rewriting pre-comments for inner items in lists::write_list. Because we failed to considering the SpecialMacro variant we ended up in a scenario where a ListItem with a pre_comment and a pre_comment_style of ListItemCommentStyle::DifferentLine was written on the same line as the list item itself. Now we apply the same pre-comment formatting to SpecialMacro, Vertical, and Mixed variants of DefinitiveListTactic. --- src/lists.rs | 46 +++++++++++----------- tests/source/issue-4615/minimum_example.rs | 4 ++ tests/target/issue-4615/minimum_example.rs | 5 +++ 3 files changed, 33 insertions(+), 22 deletions(-) create mode 100644 tests/source/issue-4615/minimum_example.rs create mode 100644 tests/target/issue-4615/minimum_example.rs diff --git a/src/lists.rs b/src/lists.rs index 73e886c55637..f0c2ae1499f0 100644 --- a/src/lists.rs +++ b/src/lists.rs @@ -367,29 +367,31 @@ where result.push_str(&comment); if !inner_item.is_empty() { - if tactic == DefinitiveListTactic::Vertical || tactic == DefinitiveListTactic::Mixed - { - // We cannot keep pre-comments on the same line if the comment if normalized. - let keep_comment = if formatting.config.normalize_comments() - || item.pre_comment_style == ListItemCommentStyle::DifferentLine - { - false - } else { - // We will try to keep the comment on the same line with the item here. - // 1 = ` ` - let total_width = total_item_width(item) + item_sep_len + 1; - total_width <= formatting.shape.width - }; - if keep_comment { - result.push(' '); - } else { - result.push('\n'); - result.push_str(indent_str); - // This is the width of the item (without comments). - line_len = item.item.as_ref().map_or(0, |s| unicode_str_width(&s)); + match tactic { + DefinitiveListTactic::SpecialMacro(_) + | DefinitiveListTactic::Vertical + | DefinitiveListTactic::Mixed => { + // We cannot keep pre-comments on the same line if the comment is normalized + let keep_comment = if formatting.config.normalize_comments() + || item.pre_comment_style == ListItemCommentStyle::DifferentLine + { + false + } else { + // We will try to keep the comment on the same line with the item here. + // 1 = ` ` + let total_width = total_item_width(item) + item_sep_len + 1; + total_width <= formatting.shape.width + }; + if keep_comment { + result.push(' '); + } else { + result.push('\n'); + result.push_str(indent_str); + // This is the width of the item (without comments). + line_len = item.item.as_ref().map_or(0, |s| unicode_str_width(&s)); + } } - } else { - result.push(' '); + _ => result.push(' '), } } item_max_width = None; diff --git a/tests/source/issue-4615/minimum_example.rs b/tests/source/issue-4615/minimum_example.rs new file mode 100644 index 000000000000..89af5d1239dd --- /dev/null +++ b/tests/source/issue-4615/minimum_example.rs @@ -0,0 +1,4 @@ +info!(//debug + "{}: sending function_code={:04x} data={:04x} crc=0x{:04X} data={:02X?}", + self.name, function_code, data, crc, output_cmd +); diff --git a/tests/target/issue-4615/minimum_example.rs b/tests/target/issue-4615/minimum_example.rs new file mode 100644 index 000000000000..223b89b812d3 --- /dev/null +++ b/tests/target/issue-4615/minimum_example.rs @@ -0,0 +1,5 @@ +info!( + //debug + "{}: sending function_code={:04x} data={:04x} crc=0x{:04X} data={:02X?}", + self.name, function_code, data, crc, output_cmd +); From 1ae5c35f8d2a0d2ce5d914a479839dc0f3eb70f9 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Mon, 18 Oct 2021 20:48:58 -0400 Subject: [PATCH 072/111] Replace match expression with match! macro This is a follow up to 5f4811ed7bc600e0cbe40c962e8933adb9baaddf The matches! macro expresses the condition more succinctly and avoids the extra level of indentation introduced with the match arm body. --- src/lists.rs | 46 ++++++++++++++++++++++------------------------ 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/src/lists.rs b/src/lists.rs index f0c2ae1499f0..c04b47876169 100644 --- a/src/lists.rs +++ b/src/lists.rs @@ -367,31 +367,29 @@ where result.push_str(&comment); if !inner_item.is_empty() { - match tactic { - DefinitiveListTactic::SpecialMacro(_) - | DefinitiveListTactic::Vertical - | DefinitiveListTactic::Mixed => { - // We cannot keep pre-comments on the same line if the comment is normalized - let keep_comment = if formatting.config.normalize_comments() - || item.pre_comment_style == ListItemCommentStyle::DifferentLine - { - false - } else { - // We will try to keep the comment on the same line with the item here. - // 1 = ` ` - let total_width = total_item_width(item) + item_sep_len + 1; - total_width <= formatting.shape.width - }; - if keep_comment { - result.push(' '); - } else { - result.push('\n'); - result.push_str(indent_str); - // This is the width of the item (without comments). - line_len = item.item.as_ref().map_or(0, |s| unicode_str_width(&s)); - } + use DefinitiveListTactic::*; + if matches!(tactic, Vertical | Mixed | SpecialMacro(_)) { + // We cannot keep pre-comments on the same line if the comment is normalized. + let keep_comment = if formatting.config.normalize_comments() + || item.pre_comment_style == ListItemCommentStyle::DifferentLine + { + false + } else { + // We will try to keep the comment on the same line with the item here. + // 1 = ` ` + let total_width = total_item_width(item) + item_sep_len + 1; + total_width <= formatting.shape.width + }; + if keep_comment { + result.push(' '); + } else { + result.push('\n'); + result.push_str(indent_str); + // This is the width of the item (without comments). + line_len = item.item.as_ref().map_or(0, |s| unicode_str_width(&s)); } - _ => result.push(' '), + } else { + result.push(' ') } } item_max_width = None; From 5f79583c3c83aa3b8a832e4effacb9141de4c2aa Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Tue, 19 Oct 2021 23:13:06 -0500 Subject: [PATCH 073/111] chore: bump toolchain, fix conflict --- Cargo.lock | 6 ------ rust-toolchain | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8e4f90989652..7263f0474770 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -118,12 +118,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - [[package]] name = "clap" version = "2.33.0" diff --git a/rust-toolchain b/rust-toolchain index b0cd4464df8e..b19ecbdb07c4 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2021-07-23" +channel = "nightly-2021-10-20" components = ["rustc-dev"] From efa8f5521d3813cc897ba29ea0ef98c7aef66bb6 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Wed, 20 Oct 2021 00:00:30 -0500 Subject: [PATCH 074/111] chore: bump version and changelog --- CHANGELOG.md | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.lock | 2 +- Cargo.toml | 2 +- 3 files changed, 69 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 68354b6ceaf2..b59438dc4fe7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,73 @@ ## [Unreleased] +## [1.4.38] 2021-10-20 + +### Changed + +- Switched from `rustc-ap-*` crates to `rustc_private` for consumption model of rustc internals +- `annotate-snippets` updated to v0.8 [PR #4762](https://github.com/rust-lang/rustfmt/pull/4762) +- Greatly improved the performance of `cargo fmt` in large workspaces utilizing the `--all` flag by updating to a newer version of `cargo_metadata` that leverages updated `cargo` output from v1.51+ [PR #4997](https://github.com/rust-lang/rustfmt/pull/4997) +- Improved formatting of long slice patterns [#4530](https://github.com/rust-lang/rustfmt/issues/4530) + - **Note you must have `version = Two` in your configuration to take advantage of the new formatting** +- Stabilized `match_block_trailing_comma` configuration option [#3380](https://github.com/rust-lang/rustfmt/issues/3380) - [https://rust-lang.github.io/rustfmt/?version=v1.4.38&search=#match_block_trailing_comma](https://rust-lang.github.io/rustfmt/?version=v1.4.38&search=#match_block_trailing_comma) +- Stabilized `disable_all_formatting` configuration option [#5026](https://github.com/rust-lang/rustfmt/pull/5026) - [https://rust-lang.github.io/rustfmt/?version=v1.4.38&search=#disable_all_formatting](https://rust-lang.github.io/rustfmt/?version=v1.4.38&search=#disable_all_formatting) +- Various improvements to the configuration documentation website [https://rust-lang.github.io/rustfmt/?version=v1.4.38]([https://rust-lang.github.io/rustfmt/?version=v1.4.38]) +- Addressed various clippy and rustc warnings + + +### Fixed + +- Resolved issue where specious whitespace would be inserted when a block style comment was terminated within string literal processing [#4312](https://github.com/rust-lang/rustfmt/issues/4312) +- Nested out-of-line mods are again parsed and formatted [#4874](https://github.com/rust-lang/rustfmt/issues/4874) +- Accepts `2021` for edition value from rustfmt command line [PR #4847](https://github.com/rust-lang/rustfmt/pull/4847) +- Unstable command line options are no longer displayed in `--help` text on stable [PR #4798](https://github.com/rust-lang/rustfmt/issues/4798) +- Stopped panicking on patterns in match arms which start with non-ascii characters [#4868](https://github.com/rust-lang/rustfmt/issues/4868) +- Stopped stripping defaults on const params [#4816](https://github.com/rust-lang/rustfmt/issues/4816) +- Fixed issue with dropped content with GAT aliases with self bounds in impls [#4911](https://github.com/rust-lang/rustfmt/issues/4911) +- Stopped removing generic args on associated type constraints [#4943](https://github.com/rust-lang/rustfmt/issues/4943) +- Stopped dropping visibility on certain trait and impl items [#4960](https://github.com/rust-lang/rustfmt/issues/4960) +- Fixed dropping of qualified paths in struct patterns [#4908](https://github.com/rust-lang/rustfmt/issues/4908) and [#5005](https://github.com/rust-lang/rustfmt/issues/5005) +- Fixed bug in line width calculation that was causing specious formatting of certain patterns [#4031](https://github.com/rust-lang/rustfmt/issues/4031) + - **Note that this bug fix may cause observable formatting changes in cases where code had been formatted with prior versions of rustfmt that contained the bug** +- Fixed bug where rustfmt would drop parameter attributes if they were too long in certain cases [#4579](https://github.com/rust-lang/rustfmt/issues/4579) +- Resolved idempotency issue with extern body elements [#4963](https://github.com/rust-lang/rustfmt/issues/4963) +- rustfmt will now handle doc-style comments on function parameters, since they could appear with certain macro usage patterns even though it's generally invalid syntax [#4936](https://github.com/rust-lang/rustfmt/issues/4936) +- Fixed bug in `match_block_trailing_comma` where commas were not added to the blocks of bodies whose arm had a guard that did not fit on the same line as the pattern [#4998](https://github.com/rust-lang/rustfmt/pull/4998) +- Fixed bug in cases where derive attributes started with a block style comment [#4984](https://github.com/rust-lang/rustfmt/issues/4984) +- Fixed issue where the struct rest could be lost when `struct_field_align_threshold` was enabled [#4926](https://github.com/rust-lang/rustfmt/issues/4926) +- Handles cases where certain control flow type expressions have comments between patterns/keywords and the pattern ident contains the keyword [#5009](https://github.com/rust-lang/rustfmt/issues/5009) +- Handles tuple structs that have explicit visibilities and start with a block style comment [#5011](https://github.com/rust-lang/rustfmt/issues/5011) +- Handles leading line-style comments in certain types of macro calls [#4615](https://github.com/rust-lang/rustfmt/issues/4615) + + +### Added +- Granular width heuristic options made available for user control [PR #4782](https://github.com/rust-lang/rustfmt/pull/4782). This includes the following: + - [`array_width`](https://rust-lang.github.io/rustfmt/?version=v1.4.38&search=#array_width) + - [`attr_fn_like_width`](https://rust-lang.github.io/rustfmt/?version=v1.4.38&search=#attr_fn_like_width) + - [`chain_width`](https://rust-lang.github.io/rustfmt/?version=v1.4.38&search=#chain_width) + - [`fn_call_width`](https://rust-lang.github.io/rustfmt/?version=v1.4.38&search=#fn_call_width) + - [`single_line_if_else_max_width`](https://rust-lang.github.io/rustfmt/?version=v1.4.38&search=#single_line_if_else_max_width) + - [`struct_lit_width`](https://rust-lang.github.io/rustfmt/?version=v1.4.38&search=#struct_lit_width) + - [`struct_variant_width`](https://rust-lang.github.io/rustfmt/?version=v1.4.38&search=#struct_variant_width) + +Note this hit the rustup distributions prior to the v1.4.38 release as part of an out-of-cycle updates, but is listed in this version because the feature was not in the other v1.4.37 releases. See also the `use_small_heuristics` section on the configuration site for more information +[https://rust-lang.github.io/rustfmt/?version=v1.4.38&search=#use_small_heuristics](https://rust-lang.github.io/rustfmt/?version=v1.4.38&search=#use_small_heuristics) + +- New `One` variant added to `imports_granularity` configuration option which can be used to reformat all imports into a single use statement [#4669](https://github.com/rust-lang/rustfmt/issues/4669) +- rustfmt will now skip files that are annotated with `@generated` at the top of the file [#3958](https://github.com/rust-lang/rustfmt/issues/3958) +- New configuration option `hex_literal_case` that allows user to control the casing utilized for hex literals [PR #4903](https://github.com/rust-lang/rustfmt/pull/4903) + +See the section on the configuration site for more information +https://rust-lang.github.io/rustfmt/?version=v1.4.38&search=#hex_literal_case + +- `cargo fmt` now directly supports the `--check` flag, which means it's now possible to run `cargo fmt --check` instead of the more verbose `cargo fmt -- --check` [#3888](https://github.com/rust-lang/rustfmt/issues/3888) + +### Install/Download Options +- **rustup (nightly)** - *pending* +- **GitHub Release Binaries** - [Release v1.4.38](https://github.com/rust-lang/rustfmt/releases/tag/v1.4.38) +- **Build from source** - [Tag v1.4.38](https://github.com/rust-lang/rustfmt/tree/v1.4.38), see instructions for how to [install rustfmt from source][install-from-source] + ## [1.4.37] 2021-04-03 ### Changed diff --git a/Cargo.lock b/Cargo.lock index 7263f0474770..2ef83ddd1ae6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -429,7 +429,7 @@ dependencies = [ [[package]] name = "rustfmt-nightly" -version = "1.4.37" +version = "1.4.38" dependencies = [ "annotate-snippets", "anyhow", diff --git a/Cargo.toml b/Cargo.toml index d282766e00b4..8d9c4a7fb20c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustfmt-nightly" -version = "1.4.37" +version = "1.4.38" description = "Tool to find and fix Rust formatting issues" repository = "https://github.com/rust-lang/rustfmt" readme = "README.md" From 599b2fd9c47f913c6c3540b4805528d8bacd3d7e Mon Sep 17 00:00:00 2001 From: Martinez Date: Sat, 23 Oct 2021 19:01:48 +0300 Subject: [PATCH 075/111] Add One option to group_imports (#4966) * Add Together option to group_imports * Rename option to One * Rename files from Together to One --- Configurations.md | 19 ++++++++++++++++++- src/config/options.rs | 2 ++ src/reorder.rs | 4 +++- .../group_imports/One-merge_imports.rs | 17 +++++++++++++++++ .../configs/group_imports/One-nested.rs | 7 +++++++ .../configs/group_imports/One-no_reorder.rs | 16 ++++++++++++++++ tests/source/configs/group_imports/One.rs | 15 +++++++++++++++ .../group_imports/One-merge_imports.rs | 14 ++++++++++++++ .../configs/group_imports/One-nested.rs | 6 ++++++ .../configs/group_imports/One-no_reorder.rs | 12 ++++++++++++ tests/target/configs/group_imports/One.rs | 11 +++++++++++ 11 files changed, 121 insertions(+), 2 deletions(-) create mode 100644 tests/source/configs/group_imports/One-merge_imports.rs create mode 100644 tests/source/configs/group_imports/One-nested.rs create mode 100644 tests/source/configs/group_imports/One-no_reorder.rs create mode 100644 tests/source/configs/group_imports/One.rs create mode 100644 tests/target/configs/group_imports/One-merge_imports.rs create mode 100644 tests/target/configs/group_imports/One-nested.rs create mode 100644 tests/target/configs/group_imports/One-no_reorder.rs create mode 100644 tests/target/configs/group_imports/One.rs diff --git a/Configurations.md b/Configurations.md index 7a77dbe154b6..13826883d2f4 100644 --- a/Configurations.md +++ b/Configurations.md @@ -2062,7 +2062,7 @@ use sit; Controls the strategy for how imports are grouped together. - **Default value**: `Preserve` -- **Possible values**: `Preserve`, `StdExternalCrate` +- **Possible values**: `Preserve`, `StdExternalCrate`, `One` - **Stable**: No #### `Preserve` (default): @@ -2108,6 +2108,23 @@ use super::update::convert_publish_payload; use crate::models::Event; ``` +#### `One`: + +Discard existing import groups, and create a single group for everything + +```rust +use super::schema::{Context, Payload}; +use super::update::convert_publish_payload; +use crate::models::Event; +use alloc::alloc::Layout; +use broker::database::PooledConnection; +use chrono::Utc; +use core::f32; +use juniper::{FieldError, FieldResult}; +use std::sync::Arc; +use uuid::Uuid; +``` + ## `reorder_modules` Reorder `mod` declarations alphabetically in group. diff --git a/src/config/options.rs b/src/config/options.rs index e92f8e8a5315..a17d48349c05 100644 --- a/src/config/options.rs +++ b/src/config/options.rs @@ -112,6 +112,8 @@ pub enum GroupImportsTactic { /// 2. other imports /// 3. `self` / `crate` / `super` imports StdExternalCrate, + /// Discard existing groups, and create a single group for everything + One, } #[config_type] diff --git a/src/reorder.rs b/src/reorder.rs index 2c58350d4feb..0732c8ee7005 100644 --- a/src/reorder.rs +++ b/src/reorder.rs @@ -118,7 +118,9 @@ fn rewrite_reorderable_or_regroupable_items( }; let mut regrouped_items = match context.config.group_imports() { - GroupImportsTactic::Preserve => vec![normalized_items], + GroupImportsTactic::Preserve | GroupImportsTactic::One => { + vec![normalized_items] + } GroupImportsTactic::StdExternalCrate => group_imports(normalized_items), }; diff --git a/tests/source/configs/group_imports/One-merge_imports.rs b/tests/source/configs/group_imports/One-merge_imports.rs new file mode 100644 index 000000000000..157d3857908a --- /dev/null +++ b/tests/source/configs/group_imports/One-merge_imports.rs @@ -0,0 +1,17 @@ +// rustfmt-group_imports: One +// rustfmt-imports_granularity: Crate +use chrono::Utc; +use super::update::convert_publish_payload; + +use juniper::{FieldError, FieldResult}; +use uuid::Uuid; +use alloc::alloc::Layout; + +use std::sync::Arc; +use alloc::vec::Vec; + +use broker::database::PooledConnection; + +use super::schema::{Context, Payload}; +use core::f32; +use crate::models::Event; diff --git a/tests/source/configs/group_imports/One-nested.rs b/tests/source/configs/group_imports/One-nested.rs new file mode 100644 index 000000000000..109bd07e1ee2 --- /dev/null +++ b/tests/source/configs/group_imports/One-nested.rs @@ -0,0 +1,7 @@ +// rustfmt-group_imports: One +mod test { + use crate::foo::bar; + + use std::path; + use crate::foo::bar2; +} diff --git a/tests/source/configs/group_imports/One-no_reorder.rs b/tests/source/configs/group_imports/One-no_reorder.rs new file mode 100644 index 000000000000..f82f62c7f5b2 --- /dev/null +++ b/tests/source/configs/group_imports/One-no_reorder.rs @@ -0,0 +1,16 @@ +// rustfmt-group_imports: One +// rustfmt-reorder_imports: false +use chrono::Utc; +use super::update::convert_publish_payload; + +use juniper::{FieldError, FieldResult}; +use uuid::Uuid; +use alloc::alloc::Layout; + +use std::sync::Arc; + +use broker::database::PooledConnection; + +use super::schema::{Context, Payload}; +use core::f32; +use crate::models::Event; diff --git a/tests/source/configs/group_imports/One.rs b/tests/source/configs/group_imports/One.rs new file mode 100644 index 000000000000..5ab7a950805b --- /dev/null +++ b/tests/source/configs/group_imports/One.rs @@ -0,0 +1,15 @@ +// rustfmt-group_imports: One +use chrono::Utc; +use super::update::convert_publish_payload; + +use juniper::{FieldError, FieldResult}; +use uuid::Uuid; +use alloc::alloc::Layout; + +use std::sync::Arc; + +use broker::database::PooledConnection; + +use super::schema::{Context, Payload}; +use core::f32; +use crate::models::Event; diff --git a/tests/target/configs/group_imports/One-merge_imports.rs b/tests/target/configs/group_imports/One-merge_imports.rs new file mode 100644 index 000000000000..52e0e1c5ac21 --- /dev/null +++ b/tests/target/configs/group_imports/One-merge_imports.rs @@ -0,0 +1,14 @@ +// rustfmt-group_imports: One +// rustfmt-imports_granularity: Crate +use super::{ + schema::{Context, Payload}, + update::convert_publish_payload, +}; +use crate::models::Event; +use alloc::{alloc::Layout, vec::Vec}; +use broker::database::PooledConnection; +use chrono::Utc; +use core::f32; +use juniper::{FieldError, FieldResult}; +use std::sync::Arc; +use uuid::Uuid; diff --git a/tests/target/configs/group_imports/One-nested.rs b/tests/target/configs/group_imports/One-nested.rs new file mode 100644 index 000000000000..5b648548260f --- /dev/null +++ b/tests/target/configs/group_imports/One-nested.rs @@ -0,0 +1,6 @@ +// rustfmt-group_imports: One +mod test { + use crate::foo::bar; + use crate::foo::bar2; + use std::path; +} diff --git a/tests/target/configs/group_imports/One-no_reorder.rs b/tests/target/configs/group_imports/One-no_reorder.rs new file mode 100644 index 000000000000..015e841d0148 --- /dev/null +++ b/tests/target/configs/group_imports/One-no_reorder.rs @@ -0,0 +1,12 @@ +// rustfmt-group_imports: One +// rustfmt-reorder_imports: false +use chrono::Utc; +use super::update::convert_publish_payload; +use juniper::{FieldError, FieldResult}; +use uuid::Uuid; +use alloc::alloc::Layout; +use std::sync::Arc; +use broker::database::PooledConnection; +use super::schema::{Context, Payload}; +use core::f32; +use crate::models::Event; diff --git a/tests/target/configs/group_imports/One.rs b/tests/target/configs/group_imports/One.rs new file mode 100644 index 000000000000..3094c7ae1157 --- /dev/null +++ b/tests/target/configs/group_imports/One.rs @@ -0,0 +1,11 @@ +// rustfmt-group_imports: One +use super::schema::{Context, Payload}; +use super::update::convert_publish_payload; +use crate::models::Event; +use alloc::alloc::Layout; +use broker::database::PooledConnection; +use chrono::Utc; +use core::f32; +use juniper::{FieldError, FieldResult}; +use std::sync::Arc; +use uuid::Uuid; From d454e8106024fcb517d8fc20d4bdd2c54229695a Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Sat, 23 Oct 2021 17:18:47 -0400 Subject: [PATCH 076/111] Add rustdoc CI check Resolves 5038 rust-lang/rust builds now document rustfmt (rust-lang/rust#87119). The build process is updated with doc checks to ensure that rustfmt doesn't introduce warnings. Warnings are treated as hard errors in rust-lang/rust and won't show until bors tests the changes (refs rust-lang/rust#90087). --- .github/workflows/rustdoc_check.yml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 .github/workflows/rustdoc_check.yml diff --git a/.github/workflows/rustdoc_check.yml b/.github/workflows/rustdoc_check.yml new file mode 100644 index 000000000000..ca96d30f5863 --- /dev/null +++ b/.github/workflows/rustdoc_check.yml @@ -0,0 +1,25 @@ +name: rustdoc check +on: + push: + branches: + - master + pull_request: + +jobs: + rustdoc_check: + runs-on: ubuntu-latest + name: rustdoc check + steps: + - name: checkout + uses: actions/checkout@v2 + + - name: install rustup + run: | + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs > rustup-init.sh + sh rustup-init.sh -y --default-toolchain none + rustup target add x86_64-unknown-linux-gnu + + - name: document rustfmt + env: + RUSTDOCFLAGS: --document-private-items --enable-index-page --show-type-layout --generate-link-to-definition -Zunstable-options -Dwarnings + run: cargo doc -Zskip-rustdoc-fingerprint --no-deps -p rustfmt-nightly -p rustfmt-config_proc_macro From c493ee4828ab8e94ed175ec781afe7351bf89784 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Sat, 23 Oct 2021 23:07:57 +0200 Subject: [PATCH 077/111] fix clippy::needless_borrow --- src/attr.rs | 4 ++-- src/attr/doc_comment.rs | 2 +- src/cargo-fmt/main.rs | 6 +++--- src/chains.rs | 4 ++-- src/comment.rs | 14 +++++++------- src/emitter/checkstyle.rs | 4 ++-- src/emitter/diff.rs | 2 +- src/expr.rs | 12 ++++++------ src/formatting.rs | 4 ++-- src/imports.rs | 4 ++-- src/items.rs | 30 +++++++++++++++--------------- src/lib.rs | 4 ++-- src/lists.rs | 4 ++-- src/macros.rs | 16 ++++++++-------- src/matches.rs | 10 +++++----- src/modules.rs | 4 ++-- src/overflow.rs | 2 +- src/pairs.rs | 16 ++++++++-------- src/patterns.rs | 2 +- src/syntux/parser.rs | 2 +- src/syntux/session.rs | 2 +- src/test/mod.rs | 4 ++-- src/types.rs | 4 ++-- src/utils.rs | 6 +++--- src/visitor.rs | 20 ++++++++++---------- 25 files changed, 91 insertions(+), 91 deletions(-) diff --git a/src/attr.rs b/src/attr.rs index a5982820e3de..76b66e9da809 100644 --- a/src/attr.rs +++ b/src/attr.rs @@ -451,7 +451,7 @@ impl Rewrite for [ast::Attribute] { if next.is_doc_comment() { let snippet = context.snippet(missing_span); let (_, mlb) = has_newlines_before_after_comment(snippet); - result.push_str(&mlb); + result.push_str(mlb); } } result.push('\n'); @@ -484,7 +484,7 @@ impl Rewrite for [ast::Attribute] { if next.is_doc_comment() { let snippet = context.snippet(missing_span); let (_, mlb) = has_newlines_before_after_comment(snippet); - result.push_str(&mlb); + result.push_str(mlb); } } result.push('\n'); diff --git a/src/attr/doc_comment.rs b/src/attr/doc_comment.rs index c3dcb84c9488..f653a12a8afe 100644 --- a/src/attr/doc_comment.rs +++ b/src/attr/doc_comment.rs @@ -77,7 +77,7 @@ mod tests { ) { assert_eq!( expected_comment, - format!("{}", DocCommentFormatter::new(&literal, style)) + format!("{}", DocCommentFormatter::new(literal, style)) ); } } diff --git a/src/cargo-fmt/main.rs b/src/cargo-fmt/main.rs index 1d423ac34919..759b21218c35 100644 --- a/src/cargo-fmt/main.rs +++ b/src/cargo-fmt/main.rs @@ -401,12 +401,12 @@ fn get_targets_root_only( fn get_targets_recursive( manifest_path: Option<&Path>, - mut targets: &mut BTreeSet, + targets: &mut BTreeSet, visited: &mut BTreeSet, ) -> Result<(), io::Error> { let metadata = get_cargo_metadata(manifest_path)?; for package in &metadata.packages { - add_targets(&package.targets, &mut targets); + add_targets(&package.targets, targets); // Look for local dependencies using information available since cargo v1.51 // It's theoretically possible someone could use a newer version of rustfmt with @@ -427,7 +427,7 @@ fn get_targets_recursive( .any(|p| p.manifest_path.eq(&manifest_path)) { visited.insert(dependency.name.to_owned()); - get_targets_recursive(Some(&manifest_path), &mut targets, visited)?; + get_targets_recursive(Some(&manifest_path), targets, visited)?; } } } diff --git a/src/chains.rs b/src/chains.rs index 614638ea2abf..e26e24ec55ad 100644 --- a/src/chains.rs +++ b/src/chains.rs @@ -568,7 +568,7 @@ impl<'a> ChainFormatterShared<'a> { } else { self.rewrites .iter() - .map(|rw| utils::unicode_str_width(&rw)) + .map(|rw| utils::unicode_str_width(rw)) .sum() } + last.tries; let one_line_budget = if self.child_count == 1 { @@ -673,7 +673,7 @@ impl<'a> ChainFormatterShared<'a> { ChainItemKind::Comment(_, CommentPosition::Top) => result.push_str(&connector), _ => result.push_str(&connector), } - result.push_str(&rewrite); + result.push_str(rewrite); } Some(result) diff --git a/src/comment.rs b/src/comment.rs index dc4f4516252b..a3cd0359e6ba 100644 --- a/src/comment.rs +++ b/src/comment.rs @@ -563,7 +563,7 @@ impl<'a> CommentRewrite<'a> { result.push_str(line); result.push_str(match iter.peek() { Some(next_line) if next_line.is_empty() => sep.trim_end(), - Some(..) => &sep, + Some(..) => sep, None => "", }); } @@ -622,7 +622,7 @@ impl<'a> CommentRewrite<'a> { let is_last = i == count_newlines(orig); if let Some(ref mut ib) = self.item_block { - if ib.add_line(&line) { + if ib.add_line(line) { return false; } self.is_prev_line_multi_line = false; @@ -684,8 +684,8 @@ impl<'a> CommentRewrite<'a> { self.item_block = None; if let Some(stripped) = line.strip_prefix("```") { self.code_block_attr = Some(CodeBlockAttribute::new(stripped)) - } else if self.fmt.config.wrap_comments() && ItemizedBlock::is_itemized_line(&line) { - let ib = ItemizedBlock::new(&line); + } else if self.fmt.config.wrap_comments() && ItemizedBlock::is_itemized_line(line) { + let ib = ItemizedBlock::new(line); self.item_block = Some(ib); return false; } @@ -941,7 +941,7 @@ fn left_trim_comment_line<'a>(line: &'a str, style: &CommentStyle<'_>) -> (&'a s { (&line[4..], true) } else if let CommentStyle::Custom(opener) = *style { - if let Some(ref stripped) = line.strip_prefix(opener) { + if let Some(stripped) = line.strip_prefix(opener) { (stripped, true) } else { (&line[opener.trim_end().len()..], false) @@ -1570,7 +1570,7 @@ pub(crate) fn recover_comment_removed( context.parse_sess.span_to_filename(span), vec![FormattingError::from_span( span, - &context.parse_sess, + context.parse_sess, ErrorKind::LostComment, )], ); @@ -1675,7 +1675,7 @@ impl<'a> Iterator for CommentReducer<'a> { fn remove_comment_header(comment: &str) -> &str { if comment.starts_with("///") || comment.starts_with("//!") { &comment[3..] - } else if let Some(ref stripped) = comment.strip_prefix("//") { + } else if let Some(stripped) = comment.strip_prefix("//") { stripped } else if (comment.starts_with("/**") && !comment.starts_with("/**/")) || comment.starts_with("/*!") diff --git a/src/emitter/checkstyle.rs b/src/emitter/checkstyle.rs index 4448214f3ff2..76f2527db3da 100644 --- a/src/emitter/checkstyle.rs +++ b/src/emitter/checkstyle.rs @@ -121,7 +121,7 @@ mod tests { format!(r#""#, bin_file), format!( r#""#, - XmlEscaped(&r#" println!("Hello, world!");"#), + XmlEscaped(r#" println!("Hello, world!");"#), ), String::from(""), ]; @@ -129,7 +129,7 @@ mod tests { format!(r#""#, lib_file), format!( r#""#, - XmlEscaped(&r#" println!("Greetings!");"#), + XmlEscaped(r#" println!("Greetings!");"#), ), String::from(""), ]; diff --git a/src/emitter/diff.rs b/src/emitter/diff.rs index 2fbbfedb566d..7264ad8bbf36 100644 --- a/src/emitter/diff.rs +++ b/src/emitter/diff.rs @@ -23,7 +23,7 @@ impl Emitter for DiffEmitter { }: FormattedFile<'_>, ) -> Result { const CONTEXT_SIZE: usize = 3; - let mismatch = make_diff(&original_text, formatted_text, CONTEXT_SIZE); + let mismatch = make_diff(original_text, formatted_text, CONTEXT_SIZE); let has_diff = !mismatch.is_empty(); if has_diff { diff --git a/src/expr.rs b/src/expr.rs index 7f1dd363f937..c67c14b19852 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -257,7 +257,7 @@ pub(crate) fn format_expr( } _ => false, }, - ast::ExprKind::Unary(_, ref expr) => needs_space_before_range(context, &expr), + ast::ExprKind::Unary(_, ref expr) => needs_space_before_range(context, expr), _ => false, } } @@ -423,7 +423,7 @@ fn rewrite_empty_block( prefix: &str, shape: Shape, ) -> Option { - if block_has_statements(&block) { + if block_has_statements(block) { return None; } @@ -1148,7 +1148,7 @@ pub(crate) fn is_empty_block( block: &ast::Block, attrs: Option<&[ast::Attribute]>, ) -> bool { - !block_has_statements(&block) + !block_has_statements(block) && !block_contains_comment(context, block) && attrs.map_or(true, |a| inner_attributes(a).is_empty()) } @@ -1621,7 +1621,7 @@ fn rewrite_struct_lit<'a>( }; let fields_str = - wrap_struct_field(context, &attrs, &fields_str, shape, v_shape, one_line_width)?; + wrap_struct_field(context, attrs, &fields_str, shape, v_shape, one_line_width)?; Some(format!("{} {{{}}}", path_str, fields_str)) // FIXME if context.config.indent_style() == Visual, but we run out @@ -1888,7 +1888,7 @@ pub(crate) fn rewrite_assign_rhs_expr( shape: Shape, rhs_tactics: RhsTactics, ) -> Option { - let last_line_width = last_line_width(&lhs).saturating_sub(if lhs.contains('\n') { + let last_line_width = last_line_width(lhs).saturating_sub(if lhs.contains('\n') { shape.indent.width() } else { 0 @@ -1947,7 +1947,7 @@ pub(crate) fn rewrite_assign_rhs_with_comments, R: Rewrite>( if contains_comment { let rhs = rhs.trim_start(); - combine_strs_with_missing_comments(context, &lhs, &rhs, between_span, shape, allow_extend) + combine_strs_with_missing_comments(context, &lhs, rhs, between_span, shape, allow_extend) } else { Some(lhs + &rhs) } diff --git a/src/formatting.rs b/src/formatting.rs index 9ef47b887cad..7d0facb8f12c 100644 --- a/src/formatting.rs +++ b/src/formatting.rs @@ -155,7 +155,7 @@ impl<'a, T: FormatHandler + 'a> FormatContext<'a, T> { let snippet_provider = self.parse_session.snippet_provider(module.span); let mut visitor = FmtVisitor::from_parse_sess( &self.parse_session, - &self.config, + self.config, &snippet_provider, self.report.clone(), ); @@ -180,7 +180,7 @@ impl<'a, T: FormatHandler + 'a> FormatContext<'a, T> { &mut visitor.buffer, &path, &visitor.skipped_range.borrow(), - &self.config, + self.config, &self.report, ); diff --git a/src/imports.rs b/src/imports.rs index 5ac799366894..40e0d06f99df 100644 --- a/src/imports.rs +++ b/src/imports.rs @@ -275,7 +275,7 @@ impl UseTree { shape: Shape, ) -> Option { let vis = self.visibility.as_ref().map_or(Cow::from(""), |vis| { - crate::utils::format_visibility(context, &vis) + crate::utils::format_visibility(context, vis) }); let use_str = self .rewrite(context, shape.offset_left(vis.len())?) @@ -929,7 +929,7 @@ impl Rewrite for UseTree { fn rewrite(&self, context: &RewriteContext<'_>, mut shape: Shape) -> Option { let mut result = String::with_capacity(256); let mut iter = self.path.iter().peekable(); - while let Some(ref segment) = iter.next() { + while let Some(segment) = iter.next() { let segment_str = segment.rewrite(context, shape)?; result.push_str(&segment_str); if iter.peek().is_some() { diff --git a/src/items.rs b/src/items.rs index 1cb1a2701c36..1c7899b3ac3b 100644 --- a/src/items.rs +++ b/src/items.rs @@ -226,7 +226,7 @@ impl<'a> FnSig<'a> { fn to_str(&self, context: &RewriteContext<'_>) -> String { let mut result = String::with_capacity(128); // Vis defaultness constness unsafety abi. - result.push_str(&*format_visibility(context, &self.visibility)); + result.push_str(&*format_visibility(context, self.visibility)); result.push_str(format_defaultness(self.defaultness)); result.push_str(format_constness(self.constness)); result.push_str(format_async(&self.is_async)); @@ -1220,7 +1220,7 @@ impl<'a> Rewrite for TraitAliasBounds<'a> { } else if fits_single_line { Cow::from(" ") } else { - shape.indent.to_string_with_newline(&context.config) + shape.indent.to_string_with_newline(context.config) }; Some(format!("{}{}{}", generic_bounds_str, space, where_str)) @@ -1238,7 +1238,7 @@ pub(crate) fn format_trait_alias( let alias = rewrite_ident(context, ident); // 6 = "trait ", 2 = " =" let g_shape = shape.offset_left(6)?.sub_width(2)?; - let generics_str = rewrite_generics(context, &alias, generics, g_shape)?; + let generics_str = rewrite_generics(context, alias, generics, g_shape)?; let vis_str = format_visibility(context, vis); let lhs = format!("{}trait {} =", vis_str, generics_str); // 1 = ";" @@ -1386,7 +1386,7 @@ fn format_empty_struct_or_tuple( closer: &str, ) { // 3 = " {}" or "();" - let used_width = last_line_used_width(&result, offset.width()) + 3; + let used_width = last_line_used_width(result, offset.width()) + 3; if used_width > context.config.max_width() { result.push_str(&offset.to_string_with_newline(context.config)) } @@ -2066,7 +2066,7 @@ fn rewrite_explicit_self( )?; Some(combine_strs_with_missing_comments( context, - ¶m_attrs, + param_attrs, &format!("&{} {}self", lifetime_str, mut_str), span, shape, @@ -2075,7 +2075,7 @@ fn rewrite_explicit_self( } None => Some(combine_strs_with_missing_comments( context, - ¶m_attrs, + param_attrs, &format!("&{}self", mut_str), span, shape, @@ -2091,7 +2091,7 @@ fn rewrite_explicit_self( Some(combine_strs_with_missing_comments( context, - ¶m_attrs, + param_attrs, &format!("{}self: {}", format_mutability(mutability), type_str), span, shape, @@ -2100,7 +2100,7 @@ fn rewrite_explicit_self( } ast::SelfKind::Value(mutability) => Some(combine_strs_with_missing_comments( context, - ¶m_attrs, + param_attrs, &format!("{}self", format_mutability(mutability)), span, shape, @@ -2226,7 +2226,7 @@ fn rewrite_fn_base( } // Skip `pub(crate)`. - let lo_after_visibility = get_bytepos_after_visibility(&fn_sig.visibility, span); + let lo_after_visibility = get_bytepos_after_visibility(fn_sig.visibility, span); // A conservative estimation, the goal is to be over all parens in generics let params_start = fn_sig .generics @@ -2984,7 +2984,7 @@ fn format_header( let mut result = String::with_capacity(128); let shape = Shape::indented(offset, context.config); - result.push_str(&format_visibility(context, vis).trim()); + result.push_str(format_visibility(context, vis).trim()); // Check for a missing comment between the visibility and the item name. let after_vis = vis.span.hi(); @@ -3005,7 +3005,7 @@ fn format_header( } } - result.push_str(&rewrite_ident(context, ident)); + result.push_str(rewrite_ident(context, ident)); result } @@ -3133,7 +3133,7 @@ impl Rewrite for ast::ForeignItem { let inner_attrs = inner_attributes(&self.attrs); let fn_ctxt = visit::FnCtxt::Foreign; visitor.visit_fn( - visit::FnKind::Fn(fn_ctxt, self.ident, &fn_sig, &self.vis, Some(body)), + visit::FnKind::Fn(fn_ctxt, self.ident, fn_sig, &self.vis, Some(body)), generics, &fn_sig.decl, self.span, @@ -3146,7 +3146,7 @@ impl Rewrite for ast::ForeignItem { context, shape.indent, self.ident, - &FnSig::from_method_sig(&fn_sig, generics, &self.vis), + &FnSig::from_method_sig(fn_sig, generics, &self.vis), span, FnBraceStyle::None, ) @@ -3171,7 +3171,7 @@ impl Rewrite for ast::ForeignItem { let ast::TyAliasKind(_, ref generics, ref generic_bounds, ref type_default) = **ty_alias_kind; rewrite_type( - &context, + context, shape.indent, self.ident, &self.vis, @@ -3229,7 +3229,7 @@ fn rewrite_attrs( combine_strs_with_missing_comments( context, &attrs_str, - &item_str, + item_str, missed_span, shape, allow_extend, diff --git a/src/lib.rs b/src/lib.rs index 47a7b9d4dbe3..792a1080f0e9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -283,7 +283,7 @@ impl FormatReport { writeln!( t, "{}", - FormatReportFormatterBuilder::new(&self) + FormatReportFormatterBuilder::new(self) .enable_colors(true) .build() )?; @@ -297,7 +297,7 @@ impl FormatReport { impl fmt::Display for FormatReport { // Prints all the formatting errors. fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - write!(fmt, "{}", FormatReportFormatterBuilder::new(&self).build())?; + write!(fmt, "{}", FormatReportFormatterBuilder::new(self).build())?; Ok(()) } } diff --git a/src/lists.rs b/src/lists.rs index c04b47876169..d341ec8e6b0e 100644 --- a/src/lists.rs +++ b/src/lists.rs @@ -386,7 +386,7 @@ where result.push('\n'); result.push_str(indent_str); // This is the width of the item (without comments). - line_len = item.item.as_ref().map_or(0, |s| unicode_str_width(&s)); + line_len = item.item.as_ref().map_or(0, |s| unicode_str_width(s)); } } else { result.push(' ') @@ -820,7 +820,7 @@ where pub(crate) fn total_item_width(item: &ListItem) -> usize { comment_len(item.pre_comment.as_ref().map(|x| &(*x)[..])) + comment_len(item.post_comment.as_ref().map(|x| &(*x)[..])) - + item.item.as_ref().map_or(0, |s| unicode_str_width(&s)) + + item.item.as_ref().map_or(0, |s| unicode_str_width(s)) } fn comment_len(comment: Option<&str>) -> usize { diff --git a/src/macros.rs b/src/macros.rs index 927187dfd8a2..ef747638e33e 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -186,7 +186,7 @@ fn return_macro_parse_failure_fallback( }) .unwrap_or(false); if is_like_block_indent_style { - return trim_left_preserve_layout(context.snippet(span), indent, &context.config); + return trim_left_preserve_layout(context.snippet(span), indent, context.config); } context.skipped_range.borrow_mut().push(( @@ -437,7 +437,7 @@ fn rewrite_macro_inner( // the `macro_name!` and `{ /* macro_body */ }` but skip modifying // anything in between the braces (for now). let snippet = context.snippet(mac.span()).trim_start_matches(|c| c != '{'); - match trim_left_preserve_layout(snippet, shape.indent, &context.config) { + match trim_left_preserve_layout(snippet, shape.indent, context.config) { Some(macro_body) => Some(format!("{} {}", macro_name, macro_body)), None => Some(format!("{} {}", macro_name, snippet)), } @@ -901,7 +901,7 @@ impl MacroArgParser { break; } TokenTree::Token(ref t) => { - buffer.push_str(&pprust::token_to_string(&t)); + buffer.push_str(&pprust::token_to_string(t)); } _ => return None, } @@ -1045,7 +1045,7 @@ fn wrap_macro_args_inner( let mut iter = args.iter().peekable(); let indent_str = shape.indent.to_string_with_newline(context.config); - while let Some(ref arg) = iter.next() { + while let Some(arg) = iter.next() { result.push_str(&arg.rewrite(context, shape, use_multiple_lines)?); if use_multiple_lines @@ -1055,7 +1055,7 @@ fn wrap_macro_args_inner( result.pop(); } result.push_str(&indent_str); - } else if let Some(ref next_arg) = iter.peek() { + } else if let Some(next_arg) = iter.peek() { let space_before_dollar = !arg.kind.ends_with_space() && next_arg.kind.starts_with_dollar(); let space_before_brace = next_arg.kind.starts_with_brace(); @@ -1370,7 +1370,7 @@ impl MacroBranch { { s += &indent_str; } - (s + l + "\n", indent_next_line(kind, &l, &config)) + (s + l + "\n", indent_next_line(kind, l, &config)) }, ) .0; @@ -1514,11 +1514,11 @@ fn rewrite_macro_with_items( MacroArg::Item(item) => item, _ => return None, }; - visitor.visit_item(&item); + visitor.visit_item(item); } let mut result = String::with_capacity(256); - result.push_str(¯o_name); + result.push_str(macro_name); result.push_str(opener); result.push_str(&visitor.block_indent.to_string_with_newline(context.config)); result.push_str(visitor.buffer.trim()); diff --git a/src/matches.rs b/src/matches.rs index 5a6ed0ec06e5..25b953ef4257 100644 --- a/src/matches.rs +++ b/src/matches.rs @@ -319,7 +319,7 @@ fn flatten_arm_body<'a>( let can_extend = |expr| !context.config.force_multiline_blocks() && can_flatten_block_around_this(expr); - if let Some(ref block) = block_can_be_flattened(context, body) { + if let Some(block) = block_can_be_flattened(context, body) { if let ast::StmtKind::Expr(ref expr) = block.stmts[0].kind { if let ast::ExprKind::Block(..) = expr.kind { flatten_arm_body(context, expr, None) @@ -393,7 +393,7 @@ fn rewrite_match_body( if comment_str.is_empty() { String::new() } else { - rewrite_comment(comment_str, false, shape, &context.config)? + rewrite_comment(comment_str, false, shape, context.config)? } }; @@ -408,8 +408,8 @@ fn rewrite_match_body( result.push_str(&arrow_comment); } result.push_str(&nested_indent_str); - result.push_str(&body_str); - result.push_str(&comma); + result.push_str(body_str); + result.push_str(comma); return Some(result); } @@ -451,7 +451,7 @@ fn rewrite_match_body( result.push_str(&arrow_comment); } result.push_str(&block_sep); - result.push_str(&body_str); + result.push_str(body_str); result.push_str(&body_suffix); Some(result) }; diff --git a/src/modules.rs b/src/modules.rs index ded34d9032f9..b0c1604a6027 100644 --- a/src/modules.rs +++ b/src/modules.rs @@ -290,7 +290,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> { }; self.visit_sub_mod_after_directory_update(sub_mod, Some(directory)) } - SubModKind::Internal(ref item) => { + SubModKind::Internal(item) => { self.push_inline_mod_directory(item.ident, &item.attrs); self.visit_sub_mod_after_directory_update(sub_mod, None) } @@ -317,7 +317,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> { } match (sub_mod.ast_mod_kind, sub_mod.items) { (Some(Cow::Borrowed(ast::ModKind::Loaded(items, _, _))), _) => { - self.visit_mod_from_ast(&items) + self.visit_mod_from_ast(items) } (Some(Cow::Owned(..)), Cow::Owned(items)) => self.visit_mod_outside_ast(items), (_, _) => Ok(()), diff --git a/src/overflow.rs b/src/overflow.rs index ac24181c7805..3475f5c378cd 100644 --- a/src/overflow.rs +++ b/src/overflow.rs @@ -394,7 +394,7 @@ impl<'a> Context<'a> { ) -> Option { let last_item = self.last_item()?; let rewrite = match last_item { - OverflowableItem::Expr(ref expr) => { + OverflowableItem::Expr(expr) => { match expr.kind { // When overflowing the closure which consists of a single control flow // expression, force to use block if its condition uses multi line. diff --git a/src/pairs.rs b/src/pairs.rs index 0f3d5e8f878b..d1c75126ea4a 100644 --- a/src/pairs.rs +++ b/src/pairs.rs @@ -55,11 +55,11 @@ fn rewrite_pairs_one_line( for ((_, rewrite), s) in list.list.iter().zip(list.separators.iter()) { if let Some(rewrite) = rewrite { - if !is_single_line(&rewrite) || result.len() > shape.width { + if !is_single_line(rewrite) || result.len() > shape.width { return None; } - result.push_str(&rewrite); + result.push_str(rewrite); result.push(' '); result.push_str(s); result.push(' '); @@ -94,18 +94,18 @@ fn rewrite_pairs_multiline( shape: Shape, context: &RewriteContext<'_>, ) -> Option { - let rhs_offset = shape.rhs_overhead(&context.config); + let rhs_offset = shape.rhs_overhead(context.config); let nested_shape = (match context.config.indent_style() { IndentStyle::Visual => shape.visual_indent(0), IndentStyle::Block => shape.block_indent(context.config.tab_spaces()), }) - .with_max_width(&context.config) + .with_max_width(context.config) .sub_width(rhs_offset)?; let indent_str = nested_shape.indent.to_string_with_newline(context.config); let mut result = String::new(); - result.push_str(&list.list[0].1.as_ref()?); + result.push_str(list.list[0].1.as_ref()?); for ((e, default_rw), s) in list.list[1..].iter().zip(list.separators.iter()) { // The following test checks if we should keep two subexprs on the same @@ -144,7 +144,7 @@ fn rewrite_pairs_multiline( } } - result.push_str(&default_rw.as_ref()?); + result.push_str(default_rw.as_ref()?); } Some(result) } @@ -264,12 +264,12 @@ impl FlattenPair for ast::Expr { return node.rewrite(context, shape); } let nested_overhead = sep + 1; - let rhs_offset = shape.rhs_overhead(&context.config); + let rhs_offset = shape.rhs_overhead(context.config); let nested_shape = (match context.config.indent_style() { IndentStyle::Visual => shape.visual_indent(0), IndentStyle::Block => shape.block_indent(context.config.tab_spaces()), }) - .with_max_width(&context.config) + .with_max_width(context.config) .sub_width(rhs_offset)?; let default_shape = match context.config.binop_separator() { SeparatorPlace::Back => nested_shape.sub_width(nested_overhead)?, diff --git a/src/patterns.rs b/src/patterns.rs index ba8d8024a970..2676c6473556 100644 --- a/src/patterns.rs +++ b/src/patterns.rs @@ -482,7 +482,7 @@ fn rewrite_tuple_pat( let path_str = path_str.unwrap_or_default(); overflow::rewrite_with_parens( - &context, + context, &path_str, pat_vec.iter(), shape, diff --git a/src/syntux/parser.rs b/src/syntux/parser.rs index b5fe4335dd33..14b92238cfa6 100644 --- a/src/syntux/parser.rs +++ b/src/syntux/parser.rs @@ -112,7 +112,7 @@ impl<'a> Parser<'a> { span: Span, ) -> Result<(Vec, Vec>, Span), ParserError> { let result = catch_unwind(AssertUnwindSafe(|| { - let mut parser = new_parser_from_file(sess.inner(), &path, Some(span)); + let mut parser = new_parser_from_file(sess.inner(), path, Some(span)); match parser.parse_mod(&TokenKind::Eof) { Ok(result) => Some(result), Err(mut e) => { diff --git a/src/syntux/session.rs b/src/syntux/session.rs index 946c076d9f2d..cdb4893d443b 100644 --- a/src/syntux/session.rs +++ b/src/syntux/session.rs @@ -164,7 +164,7 @@ impl ParseSess { } pub(crate) fn ignore_file(&self, path: &FileName) -> bool { - self.ignore_path_set.as_ref().is_match(&path) + self.ignore_path_set.as_ref().is_match(path) } pub(crate) fn set_silent_emitter(&mut self) { diff --git a/src/test/mod.rs b/src/test/mod.rs index 48d61289a9b8..e2620508c340 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -535,9 +535,9 @@ fn check_files(files: Vec, opt_config: &Option) -> (Vec { - print!("{}", FormatReportFormatterBuilder::new(&report).build()); + print!("{}", FormatReportFormatterBuilder::new(report).build()); fails += 1; } Ok(report) => reports.push(report), diff --git a/src/types.rs b/src/types.rs index 62c05ba078c5..9ea90c5e46dd 100644 --- a/src/types.rs +++ b/src/types.rs @@ -728,7 +728,7 @@ impl Rewrite for ast::Ty { result = combine_strs_with_missing_comments( context, result.trim_end(), - &mt.ty.rewrite(&context, shape)?, + &mt.ty.rewrite(context, shape)?, before_ty_span, shape, true, @@ -738,7 +738,7 @@ impl Rewrite for ast::Ty { let budget = shape.width.checked_sub(used_width)?; let ty_str = mt .ty - .rewrite(&context, Shape::legacy(budget, shape.indent + used_width))?; + .rewrite(context, Shape::legacy(budget, shape.indent + used_width))?; result.push_str(&ty_str); } diff --git a/src/utils.rs b/src/utils.rs index 29e1e070d411..3a8713c5bdb0 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -42,7 +42,7 @@ pub(crate) fn is_same_visibility(a: &Visibility, b: &Visibility) -> bool { ( VisibilityKind::Restricted { path: p, .. }, VisibilityKind::Restricted { path: q, .. }, - ) => pprust::path_to_string(&p) == pprust::path_to_string(&q), + ) => pprust::path_to_string(p) == pprust::path_to_string(q), (VisibilityKind::Public, VisibilityKind::Public) | (VisibilityKind::Inherited, VisibilityKind::Inherited) | ( @@ -689,7 +689,7 @@ mod test { #[test] fn test_remove_trailing_white_spaces() { let s = " r#\"\n test\n \"#"; - assert_eq!(remove_trailing_white_spaces(&s), s); + assert_eq!(remove_trailing_white_spaces(s), s); } #[test] @@ -698,7 +698,7 @@ mod test { let config = Config::default(); let indent = Indent::new(4, 0); assert_eq!( - trim_left_preserve_layout(&s, indent, &config), + trim_left_preserve_layout(s, indent, &config), Some("aaa\n bbb\n ccc".to_string()) ); } diff --git a/src/visitor.rs b/src/visitor.rs index d854d90b40b6..c37e1cb10117 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -164,7 +164,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { ); } else { let shape = self.shape(); - let rewrite = self.with_context(|ctx| stmt.rewrite(&ctx, shape)); + let rewrite = self.with_context(|ctx| stmt.rewrite(ctx, shape)); self.push_rewrite(stmt.span(), rewrite) } } @@ -273,9 +273,9 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { let comment_snippet = self.snippet(span); - let align_to_right = if unindent_comment && contains_comment(&comment_snippet) { + let align_to_right = if unindent_comment && contains_comment(comment_snippet) { let first_lines = comment_snippet.splitn(2, '/').next().unwrap_or(""); - last_line_width(first_lines) > last_line_width(&comment_snippet) + last_line_width(first_lines) > last_line_width(comment_snippet) } else { false }; @@ -439,7 +439,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { let filtered_attrs; let mut attrs = &item.attrs; let skip_context_saved = self.skip_context.clone(); - self.skip_context.update_with_attrs(&attrs); + self.skip_context.update_with_attrs(attrs); let should_visit_node_again = match item.kind { // For use/extern crate items, skip rewriting attributes but check for a skip attribute. @@ -488,12 +488,12 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { ast::ItemKind::Use(ref tree) => self.format_import(item, tree), ast::ItemKind::Impl { .. } => { let block_indent = self.block_indent; - let rw = self.with_context(|ctx| format_impl(&ctx, item, block_indent)); + let rw = self.with_context(|ctx| format_impl(ctx, item, block_indent)); self.push_rewrite(item.span, rw); } ast::ItemKind::Trait(..) => { let block_indent = self.block_indent; - let rw = self.with_context(|ctx| format_trait(&ctx, item, block_indent)); + let rw = self.with_context(|ctx| format_trait(ctx, item, block_indent)); self.push_rewrite(item.span, rw); } ast::ItemKind::TraitAlias(ref generics, ref generic_bounds) => { @@ -552,7 +552,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { visit::FnKind::Fn( fn_ctxt, item.ident, - &fn_signature, + fn_signature, &item.vis, Some(body), ), @@ -567,7 +567,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { let rewrite = self.rewrite_required_fn( indent, item.ident, - &fn_signature, + fn_signature, &item.vis, generics, item.span, @@ -718,7 +718,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { &ii.vis, defaultness, ty.as_ref(), - &generics, + generics, &self.get_context(), self.block_indent, ii.span, @@ -905,7 +905,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { } fn walk_mod_items(&mut self, items: &[rustc_ast::ptr::P]) { - self.visit_items_with_reordering(&ptr_vec_to_ref_vec(&items)); + self.visit_items_with_reordering(&ptr_vec_to_ref_vec(items)); } fn walk_stmts(&mut self, stmts: &[Stmt<'_>], include_current_empty_semi: bool) { From 0b8ffac0297a46d7d2d2f8328cbc49de7e7144f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Sat, 23 Oct 2021 23:21:52 +0200 Subject: [PATCH 078/111] fix a bunch of the other clippy warnings that look interesting --- src/comment.rs | 4 ++-- src/expr.rs | 6 +++--- src/matches.rs | 2 +- src/modules.rs | 2 +- src/patterns.rs | 6 +++--- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/comment.rs b/src/comment.rs index a3cd0359e6ba..7b76c232937d 100644 --- a/src/comment.rs +++ b/src/comment.rs @@ -405,7 +405,7 @@ impl CodeBlockAttribute { /// attributes are valid rust attributes /// See fn new(attributes: &str) -> CodeBlockAttribute { - for attribute in attributes.split(",") { + for attribute in attributes.split(',') { match attribute.trim() { "" | "rust" | "should_panic" | "no_run" | "edition2015" | "edition2018" | "edition2021" => (), @@ -1384,7 +1384,7 @@ impl<'a> Iterator for LineClasses<'a> { None => unreachable!(), }; - while let Some((kind, c)) = self.base.next() { + for (kind, c) in self.base.by_ref() { // needed to set the kind of the ending character on the last line self.kind = kind; if c == '\n' { diff --git a/src/expr.rs b/src/expr.rs index c67c14b19852..1ca01f9db9a4 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -1207,11 +1207,11 @@ fn rewrite_int_lit(context: &RewriteContext<'_>, lit: &ast::Lit, shape: Shape) - let span = lit.span; let symbol = lit.token.symbol.as_str(); - if symbol.starts_with("0x") { + if let Some(symbol_stripped) = symbol.strip_prefix("0x") { let hex_lit = match context.config.hex_literal_case() { HexLiteralCase::Preserve => None, - HexLiteralCase::Upper => Some(symbol[2..].to_ascii_uppercase()), - HexLiteralCase::Lower => Some(symbol[2..].to_ascii_lowercase()), + HexLiteralCase::Upper => Some(symbol_stripped.to_ascii_uppercase()), + HexLiteralCase::Lower => Some(symbol_stripped.to_ascii_lowercase()), }; if let Some(hex_lit) = hex_lit { return wrap_str( diff --git a/src/matches.rs b/src/matches.rs index 25b953ef4257..22d23fc1cdba 100644 --- a/src/matches.rs +++ b/src/matches.rs @@ -168,7 +168,7 @@ fn collect_beginning_verts( .map(|a| { context .snippet(a.pat.span) - .starts_with("|") + .starts_with('|') .then(|| a.pat.span().lo()) }) .collect() diff --git a/src/modules.rs b/src/modules.rs index b0c1604a6027..88d434d759db 100644 --- a/src/modules.rs +++ b/src/modules.rs @@ -197,7 +197,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> { /// Visit modules from AST. fn visit_mod_from_ast( &mut self, - items: &'ast Vec>, + items: &'ast [rustc_ast::ptr::P], ) -> Result<(), ModuleResolutionError> { for item in items { if is_cfg_if(item) { diff --git a/src/patterns.rs b/src/patterns.rs index 2676c6473556..a80d63201f98 100644 --- a/src/patterns.rs +++ b/src/patterns.rs @@ -456,11 +456,11 @@ fn rewrite_tuple_pat( context: &RewriteContext<'_>, shape: Shape, ) -> Option { - let mut pat_vec: Vec<_> = pats.iter().map(|x| TuplePatField::Pat(x)).collect(); - - if pat_vec.is_empty() { + if pats.is_empty() { return Some(format!("{}()", path_str.unwrap_or_default())); } + let mut pat_vec: Vec<_> = pats.iter().map(TuplePatField::Pat).collect(); + let wildcard_suffix_len = count_wildcard_suffix_len(context, &pat_vec, span, shape); let (pat_vec, span) = if context.config.condense_wildcard_suffixes() && wildcard_suffix_len >= 2 { From 8b766f35bcf0b2c2dcd82bd4e4ec82af49c16367 Mon Sep 17 00:00:00 2001 From: Seiichi Uchida Date: Mon, 11 May 2020 09:50:41 +0900 Subject: [PATCH 079/111] Remove legacy-rustfmt.toml (#4169) --- legacy-rustfmt.toml | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 legacy-rustfmt.toml diff --git a/legacy-rustfmt.toml b/legacy-rustfmt.toml deleted file mode 100644 index f976fa68e4c7..000000000000 --- a/legacy-rustfmt.toml +++ /dev/null @@ -1,2 +0,0 @@ -indent_style = "Visual" -combine_control_expr = false From bc46af97423cef7484a806e8282c545d7607889e Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Tue, 19 Oct 2021 01:14:51 -0400 Subject: [PATCH 080/111] Retain trailing comments in module when using rustfmt::skip attribute Resolves 5033 Trailing comments at the end of the root Module were removed because the module span did not extend until the end of the file. The root Module's span now encompasses the entire file, which ensures that no comments are lost when using ``#![rustfmt::skip]`` --- src/modules.rs | 6 ++++-- tests/target/issue-5033/minimum_example.rs | 8 ++++++++ tests/target/issue-5033/nested_modules.rs | 11 +++++++++++ 3 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 tests/target/issue-5033/minimum_example.rs create mode 100644 tests/target/issue-5033/nested_modules.rs diff --git a/src/modules.rs b/src/modules.rs index 88d434d759db..9e75f41ae36e 100644 --- a/src/modules.rs +++ b/src/modules.rs @@ -16,7 +16,7 @@ use crate::syntux::parser::{ Directory, DirectoryOwnership, ModError, ModulePathSuccess, Parser, ParserError, }; use crate::syntux::session::ParseSess; -use crate::utils::contains_skip; +use crate::utils::{contains_skip, mk_sp}; mod visitor; @@ -135,10 +135,12 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> { self.visit_mod_from_ast(&krate.items)?; } + let snippet_provider = self.parse_sess.snippet_provider(krate.span); + self.file_map.insert( root_filename, Module::new( - krate.span, + mk_sp(snippet_provider.start_pos(), snippet_provider.end_pos()), None, Cow::Borrowed(&krate.items), Cow::Borrowed(&krate.attrs), diff --git a/tests/target/issue-5033/minimum_example.rs b/tests/target/issue-5033/minimum_example.rs new file mode 100644 index 000000000000..0e7df41deb2d --- /dev/null +++ b/tests/target/issue-5033/minimum_example.rs @@ -0,0 +1,8 @@ +// leading comment + +#![rustfmt::skip] +fn main() { + println!("main"); // commented +} + +// post comment diff --git a/tests/target/issue-5033/nested_modules.rs b/tests/target/issue-5033/nested_modules.rs new file mode 100644 index 000000000000..7a11133b60bb --- /dev/null +++ b/tests/target/issue-5033/nested_modules.rs @@ -0,0 +1,11 @@ +#![rustfmt::skip] + +mod a { + mod b { + + } + + // trailing comment b +} + +// trailing comment a From ed5a0250d3f9401046253ebaf25105f2be7749f2 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Sat, 30 Oct 2021 10:10:08 -0500 Subject: [PATCH 081/111] refactor: minor parser cleanup --- src/syntux/parser.rs | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/syntux/parser.rs b/src/syntux/parser.rs index 14b92238cfa6..d1bb2f80004a 100644 --- a/src/syntux/parser.rs +++ b/src/syntux/parser.rs @@ -125,18 +125,12 @@ impl<'a> Parser<'a> { } })); match result { - Ok(Some(m)) => { - if !sess.has_errors() { - return Ok(m); - } - - if sess.can_reset_errors() { - sess.reset_errors(); - return Ok(m); - } - Err(ParserError::ParseError) + Ok(Some(m)) if !sess.has_errors() => Ok(m), + Ok(Some(m)) if sess.can_reset_errors() => { + sess.reset_errors(); + Ok(m) } - Ok(None) => Err(ParserError::ParseError), + Ok(_) => Err(ParserError::ParseError), Err(..) if path.exists() => Err(ParserError::ParseError), Err(_) => Err(ParserError::ParsePanicError), } From 54b1e0bb15934bedad7c3df4626b291bfe742522 Mon Sep 17 00:00:00 2001 From: enterprisey Date: Thu, 14 Nov 2019 09:44:59 -0500 Subject: [PATCH 082/111] README grammar fix (#3926) Remove comma splice --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9c7a1c4bc341..62e8ea608913 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ cargo +nightly fmt ## Limitations -Rustfmt tries to work on as much Rust code as possible, sometimes, the code +Rustfmt tries to work on as much Rust code as possible. Sometimes, the code doesn't even need to compile! As we approach a 1.0 release we are also looking to limit areas of instability; in particular, post-1.0, the formatting of most code should not change as Rustfmt improves. However, there are some things that From a24ed3c322b9b9a6b7dc9f3f18e4142d3adabf46 Mon Sep 17 00:00:00 2001 From: chansuke Date: Wed, 25 Nov 2020 19:31:02 +0900 Subject: [PATCH 083/111] Fix MSRV --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 62e8ea608913..eb39468d4d14 100644 --- a/README.md +++ b/README.md @@ -129,7 +129,7 @@ rustfmt to exit with an error code if the input is not formatted correctly. It will also print any found differences. (Older versions of Rustfmt don't support `--check`, use `--write-mode diff`). -A minimal Travis setup could look like this (requires Rust 1.24.0 or greater): +A minimal Travis setup could look like this (requires Rust 1.31.0 or greater): ```yaml language: rust From a4d7011c18eeae7fbb11286822b9519dc9a9325f Mon Sep 17 00:00:00 2001 From: Jonathan <30177086+MonliH@users.noreply.github.com> Date: Sun, 11 Oct 2020 16:28:45 +0000 Subject: [PATCH 084/111] Document RUSTFMT environment variable (#4464) * Document RUSTFMT env var * Move documentation up * Apply suggestions from code review Co-authored-by: Caleb Cartwright * Fix accedental removal Co-authored-by: Caleb Cartwright # Conflicts: # README.md --- README.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/README.md b/README.md index eb39468d4d14..b3d21e6fb87c 100644 --- a/README.md +++ b/README.md @@ -102,6 +102,25 @@ read data from stdin. Alternatively, you can use `cargo fmt` to format all binary and library targets of your crate. You can run `rustfmt --help` for information about available arguments. +The easiest way to run rustfmt against a project is with `cargo fmt`. `cargo fmt` works on both +single-crate projects and [cargo workspaces](https://doc.rust-lang.org/book/ch14-03-cargo-workspaces.html). +Please see `cargo fmt --help` for usage information. + +You can specify the path to your own `rustfmt` binary for cargo to use by setting the`RUSTFMT` +environment variable. This was added in v1.4.22, so you must have this version or newer to leverage this feature (`cargo fmt --version`) + +### Running `rustfmt` directly + +To format individual files or arbitrary codes from stdin, the `rustfmt` binary should be used. Some +examples follow: + +- `rustfmt lib.rs main.rs` will format "lib.rs" and "main.rs" in place +- `rustfmt` will read a code from stdin and write formatting to stdout + - `echo "fn main() {}" | rustfmt` would emit "fn main() {}". + +For more information, including arguments and emit options, see `rustfmt --help`. + +### Verifying code is formatted When running with `--check`, Rustfmt will exit with `0` if Rustfmt would not make any formatting changes to the input, and `1` if Rustfmt would make changes. From 5ce82e15133501cdfa96d58370e9b4c3873546b1 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Fri, 8 Oct 2021 19:22:12 -0400 Subject: [PATCH 085/111] Prevent trailing whitespace in where clause bound predicate resolves 5012 resolves 4850 This behavior was noticed when using the ``trailing_comma = "Never"`` configuration option (5012). This behavior was also noticed when using default configurations (4850). rustfmt would add a trailing space to where clause bounds that had an empty right hand side. Now no trailing space is added to the end of these where clause bounds. --- src/expr.rs | 3 +++ tests/target/issue-5012/trailing_comma_always.rs | 8 ++++++++ tests/target/issue-5012/trailing_comma_never.rs | 8 ++++++++ tests/target/issue_4850.rs | 4 ++++ 4 files changed, 23 insertions(+) create mode 100644 tests/target/issue-5012/trailing_comma_always.rs create mode 100644 tests/target/issue-5012/trailing_comma_never.rs create mode 100644 tests/target/issue_4850.rs diff --git a/src/expr.rs b/src/expr.rs index 1ca01f9db9a4..58942e442de0 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -1962,6 +1962,9 @@ fn choose_rhs( has_rhs_comment: bool, ) -> Option { match orig_rhs { + Some(ref new_str) if new_str.is_empty() => { + return Some(String::new()); + } Some(ref new_str) if !new_str.contains('\n') && unicode_str_width(new_str) <= shape.width => { diff --git a/tests/target/issue-5012/trailing_comma_always.rs b/tests/target/issue-5012/trailing_comma_always.rs new file mode 100644 index 000000000000..ff9c40fbbd8d --- /dev/null +++ b/tests/target/issue-5012/trailing_comma_always.rs @@ -0,0 +1,8 @@ +// rustfmt-trailing_comma: Always + +pub struct Matrix +where + [T; R * C]:, +{ + contents: [T; R * C], +} diff --git a/tests/target/issue-5012/trailing_comma_never.rs b/tests/target/issue-5012/trailing_comma_never.rs new file mode 100644 index 000000000000..2fac8eae52b8 --- /dev/null +++ b/tests/target/issue-5012/trailing_comma_never.rs @@ -0,0 +1,8 @@ +// rustfmt-trailing_comma: Never + +pub struct Matrix +where + [T; R * C]: +{ + contents: [T; R * C] +} diff --git a/tests/target/issue_4850.rs b/tests/target/issue_4850.rs new file mode 100644 index 000000000000..7d4da9022fe4 --- /dev/null +++ b/tests/target/issue_4850.rs @@ -0,0 +1,4 @@ +impl ThisIsALongStructNameToPushTheWhereToWrapLolololol where + [(); this_is_a_long_const_function_name()]: +{ +} From c1eab154c9139a281d17c5ae70151bac4fcbf60f Mon Sep 17 00:00:00 2001 From: Peter Hall Date: Wed, 7 Oct 2020 12:55:01 +0100 Subject: [PATCH 086/111] Use a custom env var for log settings intead of default RUST_LOG # Conflicts: # src/rustfmt/main.rs --- Contributing.md | 2 +- src/bin/main.rs | 2 +- src/format-diff/main.rs | 2 +- src/git-rustfmt/main.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Contributing.md b/Contributing.md index e6dc6a220376..3073996019ee 100644 --- a/Contributing.md +++ b/Contributing.md @@ -59,7 +59,7 @@ example, the `issue-1111.rs` test file is configured by the file ## Debugging Some `rewrite_*` methods use the `debug!` macro for printing useful information. -These messages can be printed by using the environment variable `RUST_LOG=rustfmt=DEBUG`. +These messages can be printed by using the environment variable `RUSTFMT_LOG=rustfmt=DEBUG`. These traces can be helpful in understanding which part of the code was used and get a better grasp on the execution flow. diff --git a/src/bin/main.rs b/src/bin/main.rs index 1bcc5c0dada3..9d2e97c9479f 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -20,7 +20,7 @@ use crate::rustfmt::{ }; fn main() { - env_logger::init(); + env_logger::Builder::from_env("RUSTFMT_LOG").init(); let opts = make_opts(); let exit_code = match execute(&opts) { diff --git a/src/format-diff/main.rs b/src/format-diff/main.rs index c751932273b0..655aeda42bf2 100644 --- a/src/format-diff/main.rs +++ b/src/format-diff/main.rs @@ -64,7 +64,7 @@ pub struct Opts { } fn main() { - env_logger::init(); + env_logger::Builder::from_env("RUSTFMT_LOG").init(); let opts = Opts::from_args(); if let Err(e) = run(opts) { println!("{}", e); diff --git a/src/git-rustfmt/main.rs b/src/git-rustfmt/main.rs index 16f5d1dd4f23..579778edbe74 100644 --- a/src/git-rustfmt/main.rs +++ b/src/git-rustfmt/main.rs @@ -170,7 +170,7 @@ impl Config { } fn main() { - env_logger::init(); + env_logger::Builder::from_env("RUSTFMT_LOG").init(); let opts = make_opts(); let matches = opts From bd86077c58b0460a17ae071edbca9e6bba0aa6b1 Mon Sep 17 00:00:00 2001 From: r00ster Date: Mon, 1 Nov 2021 19:53:35 +0100 Subject: [PATCH 087/111] Remove grave accent that shouldn't be there --- src/config/options.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config/options.rs b/src/config/options.rs index a17d48349c05..bce9e5d07f26 100644 --- a/src/config/options.rs +++ b/src/config/options.rs @@ -20,7 +20,7 @@ pub enum NewlineStyle { Windows, /// Force CR (`\n). Unix, - /// `\r\n` in Windows, `\n`` on other platforms. + /// `\r\n` in Windows, `\n` on other platforms. Native, } From e75c4d7ee9a48b8599a3a61d3b79ccbe0a18d77e Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Wed, 3 Nov 2021 21:10:01 -0500 Subject: [PATCH 088/111] ci: drop appveyor --- appveyor.yml | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 appveyor.yml diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index b3dda091e0a9..000000000000 --- a/appveyor.yml +++ /dev/null @@ -1,8 +0,0 @@ -environment: - global: - PROJECT_NAME: rustfmt - -build: false - -test_script: - - echo Why does no one have access to delete me? From a5f85058ac2e3f330bd48dd8de26bf429fc28c30 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Thu, 4 Nov 2021 18:00:22 -0500 Subject: [PATCH 089/111] fix: handle external mods imported via external->inline load hierarchy --- src/modules.rs | 4 +- src/test/mod_resolver.rs | 42 ++++++++++++++------ tests/mod-resolver/issue-5063/foo.rs | 2 + tests/mod-resolver/issue-5063/foo/bar/baz.rs | 1 + tests/mod-resolver/issue-5063/main.rs | 5 +++ 5 files changed, 41 insertions(+), 13 deletions(-) create mode 100644 tests/mod-resolver/issue-5063/foo.rs create mode 100644 tests/mod-resolver/issue-5063/foo/bar/baz.rs create mode 100644 tests/mod-resolver/issue-5063/main.rs diff --git a/src/modules.rs b/src/modules.rs index 9e75f41ae36e..b1f229d9daaf 100644 --- a/src/modules.rs +++ b/src/modules.rs @@ -321,7 +321,9 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> { (Some(Cow::Borrowed(ast::ModKind::Loaded(items, _, _))), _) => { self.visit_mod_from_ast(items) } - (Some(Cow::Owned(..)), Cow::Owned(items)) => self.visit_mod_outside_ast(items), + (Some(Cow::Owned(ast::ModKind::Loaded(items, _, _))), _) | (_, Cow::Owned(items)) => { + self.visit_mod_outside_ast(items) + } (_, _) => Ok(()), } } diff --git a/src/test/mod_resolver.rs b/src/test/mod_resolver.rs index e0b55e3efb2c..ae4a0d0fccb1 100644 --- a/src/test/mod_resolver.rs +++ b/src/test/mod_resolver.rs @@ -5,21 +5,39 @@ use super::read_config; use crate::{FileName, Input, Session}; -#[test] -fn nested_out_of_line_mods_loaded() { - // See also https://github.com/rust-lang/rustfmt/issues/4874 - let filename = "tests/mod-resolver/issue-4874/main.rs"; - let input_file = PathBuf::from(filename); +fn verify_mod_resolution(input_file_name: &str, exp_misformatted_files: &[&str]) { + let input_file = PathBuf::from(input_file_name); let config = read_config(&input_file); let mut session = Session::::new(config, None); let report = session - .format(Input::File(filename.into())) + .format(Input::File(input_file_name.into())) .expect("Should not have had any execution errors"); let errors_by_file = &report.internal.borrow().0; - assert!(errors_by_file.contains_key(&FileName::Real(PathBuf::from( - "tests/mod-resolver/issue-4874/bar/baz.rs", - )))); - assert!(errors_by_file.contains_key(&FileName::Real(PathBuf::from( - "tests/mod-resolver/issue-4874/foo/qux.rs", - )))); + for exp_file in exp_misformatted_files { + assert!(errors_by_file.contains_key(&FileName::Real(PathBuf::from(exp_file)))); + } +} + +#[test] +fn nested_out_of_line_mods_loaded() { + // See also https://github.com/rust-lang/rustfmt/issues/4874 + verify_mod_resolution( + "tests/mod-resolver/issue-4874/main.rs", + &[ + "tests/mod-resolver/issue-4874/bar/baz.rs", + "tests/mod-resolver/issue-4874/foo/qux.rs", + ], + ); +} + +#[test] +fn out_of_line_nested_inline_within_out_of_line() { + // See also https://github.com/rust-lang/rustfmt/issues/5063 + verify_mod_resolution( + "tests/mod-resolver/issue-5063/main.rs", + &[ + "tests/mod-resolver/issue-5063/foo/bar/baz.rs", + "tests/mod-resolver/issue-5063/foo.rs", + ], + ); } diff --git a/tests/mod-resolver/issue-5063/foo.rs b/tests/mod-resolver/issue-5063/foo.rs new file mode 100644 index 000000000000..d56974773fb9 --- /dev/null +++ b/tests/mod-resolver/issue-5063/foo.rs @@ -0,0 +1,2 @@ +mod bar { + mod baz;} \ No newline at end of file diff --git a/tests/mod-resolver/issue-5063/foo/bar/baz.rs b/tests/mod-resolver/issue-5063/foo/bar/baz.rs new file mode 100644 index 000000000000..3519b0ee59c8 --- /dev/null +++ b/tests/mod-resolver/issue-5063/foo/bar/baz.rs @@ -0,0 +1 @@ +fn baz() { } \ No newline at end of file diff --git a/tests/mod-resolver/issue-5063/main.rs b/tests/mod-resolver/issue-5063/main.rs new file mode 100644 index 000000000000..41c81c7bb433 --- /dev/null +++ b/tests/mod-resolver/issue-5063/main.rs @@ -0,0 +1,5 @@ +fn main() { + println!("Hello, world!"); +} + +mod foo; \ No newline at end of file From 9027db984be06dc99fd88264e9dbe84541547f08 Mon Sep 17 00:00:00 2001 From: Dmitry Murzin Date: Sat, 6 Jun 2020 17:19:50 +0300 Subject: [PATCH 090/111] Update IntelliJ Integration (#4238) --- intellij.md | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/intellij.md b/intellij.md index 7aea6222b8bc..6a711c0171ae 100644 --- a/intellij.md +++ b/intellij.md @@ -3,19 +3,28 @@ ## Installation - Install [CLion](https://www.jetbrains.com/clion/), [IntelliJ Ultimate or CE](https://www.jetbrains.com/idea/) through the direct download link or using the [JetBrains Toolbox](https://www.jetbrains.com/toolbox/). - CLion provides a built-in debugger interface but its not free like IntelliJ CE - which does not provide the debugger interface. (IntelliJ seems to lack the toolchain for that, see this discussion [intellij-rust/issues/535](https://github.com/intellij-rust/intellij-rust/issues/535)) - -- Install the [Rust Plugin](https://intellij-rust.github.io/) by navigating to File -> Settings -> Plugins and press "Install JetBrains Plugin" - ![plugins](https://user-images.githubusercontent.com/1133787/47240861-f40af680-d3e9-11e8-9b82-cdd5c8d5f5b8.png) + CLion and IntelliJ Ultimate [provide a built-in debugger interface](https://github.com/intellij-rust/intellij-rust#compatible-ides) but they are not free like IntelliJ CE. -- Press "Install" on the rust plugin - ![install rust](https://user-images.githubusercontent.com/1133787/47240803-c0c86780-d3e9-11e8-9265-22f735e4d7ed.png) +- Install the [Rust Plugin](https://intellij-rust.github.io/) by navigating to File → Settings → Plugins and searching the plugin in the Marketplace + ![plugins](https://user-images.githubusercontent.com/6505554/83944518-6f1e5c00-a81d-11ea-9c35-e16948811ba8.png) + +- Press "Install" on the Rust plugin + ![install rust](https://user-images.githubusercontent.com/6505554/83944533-82c9c280-a81d-11ea-86b3-ee2e31bc7d12.png) - Restart CLion/IntelliJ ## Configuration -- Open the settings window (File -> Settings) and search for "reformat" +### Run Rustfmt on save + +- Open Rustfmt settings (File → Settings → Languages & Frameworks → Rust → Rustfmt) and enable "Run rustfmt on Save" + ![run_rustfmt_on_save](https://user-images.githubusercontent.com/6505554/83944610-3468f380-a81e-11ea-9c34-0cbd18dd4969.png) + +- IntellJ uses autosave, so now your files will always be formatted according to rustfmt. Alternatively you can use Ctrl+S to reformat file manually + +### Bind shortcut to "Reformat File with Rustfmt" action + +- Open the settings window (File → Settings) and search for "reformat" ![keymap](https://user-images.githubusercontent.com/1133787/47240922-2ae10c80-d3ea-11e8-9d8f-c798d9749240.png) - Right-click on "Reformat File with Rustfmt" and assign a keyboard shortcut From 4d50e7c7606efca32bd937a4c60772a616fdbc33 Mon Sep 17 00:00:00 2001 From: mujpao Date: Mon, 1 Nov 2021 23:13:30 -0700 Subject: [PATCH 091/111] Put empty trait braces on same line if possible --- src/items.rs | 15 ++++-- tests/source/empty-item-single-line-false.rs | 46 +++++++++++++++++++ .../item-brace-style-always-next-line.rs | 35 ++++++++++++++ tests/target/empty-item-single-line-false.rs | 41 +++++++++++++++++ .../item-brace-style-always-next-line.rs | 29 ++++++++++++ 5 files changed, 163 insertions(+), 3 deletions(-) create mode 100644 tests/source/empty-item-single-line-false.rs create mode 100644 tests/target/empty-item-single-line-false.rs diff --git a/src/items.rs b/src/items.rs index 1c7899b3ac3b..e37a1b696584 100644 --- a/src/items.rs +++ b/src/items.rs @@ -1122,12 +1122,24 @@ pub(crate) fn format_trait( } } + let block_span = mk_sp(generics.where_clause.span.hi(), item.span.hi()); + let snippet = context.snippet(block_span); + let open_pos = snippet.find_uncommented("{")? + 1; + match context.config.brace_style() { _ if last_line_contains_single_line_comment(&result) || last_line_width(&result) + 2 > context.budget(offset.width()) => { result.push_str(&offset.to_string_with_newline(context.config)); } + _ if context.config.empty_item_single_line() + && trait_items.is_empty() + && !result.contains('\n') + && !contains_comment(&snippet[open_pos..]) => + { + result.push_str(" {}"); + return Some(result); + } BraceStyle::AlwaysNextLine => { result.push_str(&offset.to_string_with_newline(context.config)); } @@ -1144,9 +1156,6 @@ pub(crate) fn format_trait( } result.push('{'); - let block_span = mk_sp(generics.where_clause.span.hi(), item.span.hi()); - let snippet = context.snippet(block_span); - let open_pos = snippet.find_uncommented("{")? + 1; let outer_indent_str = offset.block_only().to_string_with_newline(context.config); if !trait_items.is_empty() || contains_comment(&snippet[open_pos..]) { diff --git a/tests/source/empty-item-single-line-false.rs b/tests/source/empty-item-single-line-false.rs new file mode 100644 index 000000000000..20c5bc83b466 --- /dev/null +++ b/tests/source/empty-item-single-line-false.rs @@ -0,0 +1,46 @@ +// rustfmt-brace_style: AlwaysNextLine +// rustfmt-empty_item_single_line: false + +fn function() +{ + +} + +struct Struct +{ + +} + +enum Enum +{ + +} + +trait Trait +{ + +} + +impl Trait for T +{ + +} + +trait Trait2 +where + T: Copy + Display + Write + Read + FromStr, {} + +trait Trait3 +where + T: Something + + SomethingElse + + Sync + + Send + + Display + + Debug + + Copy + + Hash + + Debug + + Display + + Write + + Read, {} diff --git a/tests/source/item-brace-style-always-next-line.rs b/tests/source/item-brace-style-always-next-line.rs index 38094d67a773..0fb6405120aa 100644 --- a/tests/source/item-brace-style-always-next-line.rs +++ b/tests/source/item-brace-style-always-next-line.rs @@ -27,3 +27,38 @@ mod M { struct D where T: Copy {} } + + +fn function() +{ + +} + +trait Trait +{ + +} + +impl Trait for T +{ + +} + +trait Trait2 +where + T: Copy + Display + Write + Read + FromStr, {} + +trait Trait3 +where + T: Something + + SomethingElse + + Sync + + Send + + Display + + Debug + + Copy + + Hash + + Debug + + Display + + Write + + Read, {} diff --git a/tests/target/empty-item-single-line-false.rs b/tests/target/empty-item-single-line-false.rs new file mode 100644 index 000000000000..bf7f70e7c432 --- /dev/null +++ b/tests/target/empty-item-single-line-false.rs @@ -0,0 +1,41 @@ +// rustfmt-brace_style: AlwaysNextLine +// rustfmt-empty_item_single_line: false + +fn function() +{ +} + +struct Struct {} + +enum Enum {} + +trait Trait +{ +} + +impl Trait for T +{ +} + +trait Trait2 +where + T: Copy + Display + Write + Read + FromStr, +{ +} + +trait Trait3 +where + T: Something + + SomethingElse + + Sync + + Send + + Display + + Debug + + Copy + + Hash + + Debug + + Display + + Write + + Read, +{ +} diff --git a/tests/target/item-brace-style-always-next-line.rs b/tests/target/item-brace-style-always-next-line.rs index 531ac5986831..4935fac04f11 100644 --- a/tests/target/item-brace-style-always-next-line.rs +++ b/tests/target/item-brace-style-always-next-line.rs @@ -40,3 +40,32 @@ mod M where T: Copy, {} } + +fn function() {} + +trait Trait {} + +impl Trait for T {} + +trait Trait2 +where + T: Copy + Display + Write + Read + FromStr, +{ +} + +trait Trait3 +where + T: Something + + SomethingElse + + Sync + + Send + + Display + + Debug + + Copy + + Hash + + Debug + + Display + + Write + + Read, +{ +} From 19c5c74951db8673aa3e3edba8393ce90346f96f Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Sat, 6 Nov 2021 12:59:06 -0500 Subject: [PATCH 092/111] refactor: dedupe & simplify ty alias formatting --- src/items.rs | 166 ++++++++++++++++++++++--------------------------- src/visitor.rs | 81 +++++++----------------- 2 files changed, 97 insertions(+), 150 deletions(-) diff --git a/src/items.rs b/src/items.rs index e37a1b696584..13d8a416a1ef 100644 --- a/src/items.rs +++ b/src/items.rs @@ -1185,18 +1185,6 @@ pub(crate) fn format_trait( } } -struct OpaqueTypeBounds<'a> { - generic_bounds: &'a ast::GenericBounds, -} - -impl<'a> Rewrite for OpaqueTypeBounds<'a> { - fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option { - self.generic_bounds - .rewrite(context, shape) - .map(|s| format!("impl {}", s)) - } -} - pub(crate) struct TraitAliasBounds<'a> { generic_bounds: &'a ast::GenericBounds, generics: &'a ast::Generics, @@ -1518,17 +1506,79 @@ fn format_tuple_struct( Some(result) } -pub(crate) fn rewrite_type( - context: &RewriteContext<'_>, +pub(crate) enum ItemVisitorKind<'a> { + Item(&'a ast::Item), + AssocTraitItem(&'a ast::AssocItem), + AssocImplItem(&'a ast::AssocItem), + ForeignItem(&'a ast::ForeignItem), +} + +struct TyAliasRewriteInfo<'c, 'g>( + &'c RewriteContext<'c>, + Indent, + &'g ast::Generics, + symbol::Ident, + Span, +); + +pub(crate) fn rewrite_type_alias<'a, 'b>( + ty_alias_kind: &ast::TyAliasKind, + context: &RewriteContext<'a>, indent: Indent, - ident: symbol::Ident, - vis: &ast::Visibility, - generics: &ast::Generics, - generic_bounds_opt: Option<&ast::GenericBounds>, - rhs: Option<&R>, + visitor_kind: &ItemVisitorKind<'b>, span: Span, +) -> Option { + use ItemVisitorKind::*; + + let ast::TyAliasKind(defaultness, ref generics, ref generic_bounds, ref ty) = *ty_alias_kind; + let ty_opt = ty.as_ref().map(|t| &**t); + let (ident, vis) = match visitor_kind { + Item(i) => (i.ident, &i.vis), + AssocTraitItem(i) | AssocImplItem(i) => (i.ident, &i.vis), + ForeignItem(i) => (i.ident, &i.vis), + }; + let rw_info = &TyAliasRewriteInfo(context, indent, generics, ident, span); + + // Type Aliases are formatted slightly differently depending on the context + // in which they appear, whether they are opaque, and whether they are associated. + // https://rustc-dev-guide.rust-lang.org/opaque-types-type-alias-impl-trait.html + // https://github.com/rust-dev-tools/fmt-rfcs/blob/master/guide/items.md#type-aliases + match (visitor_kind, ty_opt) { + (Item(_), None) => { + let op_ty = OpaqueType { generic_bounds }; + rewrite_ty(rw_info, Some(generic_bounds), Some(&op_ty), vis) + } + (Item(_), Some(ty)) => rewrite_ty(rw_info, Some(generic_bounds), Some(&*ty), vis), + (AssocImplItem(_), _) => { + let result = if let Some(ast::Ty { + kind: ast::TyKind::ImplTrait(_, ref generic_bounds), + .. + }) = ty_opt + { + let op_ty = OpaqueType { generic_bounds }; + rewrite_ty(rw_info, None, Some(&op_ty), &DEFAULT_VISIBILITY) + } else { + rewrite_ty(rw_info, None, ty.as_ref(), vis) + }?; + match defaultness { + ast::Defaultness::Default(..) => Some(format!("default {}", result)), + _ => Some(result), + } + } + (AssocTraitItem(_), _) | (ForeignItem(_), _) => { + rewrite_ty(rw_info, Some(generic_bounds), ty.as_ref(), vis) + } + } +} + +fn rewrite_ty( + rw_info: &TyAliasRewriteInfo<'_, '_>, + generic_bounds_opt: Option<&ast::GenericBounds>, + rhs: Option<&R>, + vis: &ast::Visibility, ) -> Option { let mut result = String::with_capacity(128); + let TyAliasRewriteInfo(context, indent, generics, ident, span) = *rw_info; result.push_str(&format!("{}type ", format_visibility(context, vis))); let ident_str = rewrite_ident(context, ident); @@ -1616,28 +1666,6 @@ pub(crate) fn rewrite_type( } } -pub(crate) fn rewrite_opaque_type( - context: &RewriteContext<'_>, - indent: Indent, - ident: symbol::Ident, - generic_bounds: &ast::GenericBounds, - generics: &ast::Generics, - vis: &ast::Visibility, - span: Span, -) -> Option { - let opaque_type_bounds = OpaqueTypeBounds { generic_bounds }; - rewrite_type( - context, - indent, - ident, - vis, - generics, - Some(generic_bounds), - Some(&opaque_type_bounds), - span, - ) -} - fn type_annotation_spacing(config: &Config) -> (&str, &str) { ( if config.space_before_colon() { " " } else { "" }, @@ -1863,54 +1891,18 @@ fn rewrite_static( } } struct OpaqueType<'a> { - bounds: &'a ast::GenericBounds, + generic_bounds: &'a ast::GenericBounds, } impl<'a> Rewrite for OpaqueType<'a> { fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option { let shape = shape.offset_left(5)?; // `impl ` - self.bounds + self.generic_bounds .rewrite(context, shape) .map(|s| format!("impl {}", s)) } } -pub(crate) fn rewrite_impl_type( - ident: symbol::Ident, - vis: &ast::Visibility, - defaultness: ast::Defaultness, - ty_opt: Option<&ptr::P>, - generics: &ast::Generics, - context: &RewriteContext<'_>, - indent: Indent, - span: Span, -) -> Option { - // Opaque type - let result = if let Some(rustc_ast::ast::Ty { - kind: ast::TyKind::ImplTrait(_, ref bounds), - .. - }) = ty_opt.map(|t| &**t) - { - rewrite_type( - context, - indent, - ident, - &DEFAULT_VISIBILITY, - generics, - None, - Some(&OpaqueType { bounds }), - span, - ) - } else { - rewrite_type(context, indent, ident, vis, generics, None, ty_opt, span) - }?; - - match defaultness { - ast::Defaultness::Default(..) => Some(format!("default {}", result)), - _ => Some(result), - } -} - impl Rewrite for ast::FnRetTy { fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option { match *self { @@ -3176,19 +3168,9 @@ impl Rewrite for ast::ForeignItem { // 1 = ; rewrite_assign_rhs(context, prefix, &**ty, shape.sub_width(1)?).map(|s| s + ";") } - ast::ForeignItemKind::TyAlias(ref ty_alias_kind) => { - let ast::TyAliasKind(_, ref generics, ref generic_bounds, ref type_default) = - **ty_alias_kind; - rewrite_type( - context, - shape.indent, - self.ident, - &self.vis, - generics, - Some(generic_bounds), - type_default.as_ref(), - self.span, - ) + ast::ForeignItemKind::TyAlias(ref ty_alias) => { + let (kind, span) = (&ItemVisitorKind::ForeignItem(&self), self.span); + rewrite_type_alias(ty_alias, context, shape.indent, kind, span) } ast::ForeignItemKind::MacCall(ref mac) => { rewrite_macro(mac, None, context, shape, MacroPosition::Item) diff --git a/src/visitor.rs b/src/visitor.rs index c37e1cb10117..f385245248da 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -12,8 +12,7 @@ use crate::config::{BraceStyle, Config}; use crate::coverage::transform_missing_snippet; use crate::items::{ format_impl, format_trait, format_trait_alias, is_mod_decl, is_use_item, rewrite_extern_crate, - rewrite_impl_type, rewrite_opaque_type, rewrite_type, FnBraceStyle, FnSig, StaticParts, - StructParts, + rewrite_type_alias, FnBraceStyle, FnSig, ItemVisitorKind, StaticParts, StructParts, }; use crate::macros::{macro_style, rewrite_macro, rewrite_macro_def, MacroPosition}; use crate::modules::Module; @@ -576,35 +575,8 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { } } ast::ItemKind::TyAlias(ref alias_kind) => { - let ast::TyAliasKind(_, ref generics, ref generic_bounds, ref ty) = - **alias_kind; - match ty { - Some(ty) => { - let rewrite = rewrite_type( - &self.get_context(), - self.block_indent, - item.ident, - &item.vis, - generics, - Some(generic_bounds), - Some(&*ty), - item.span, - ); - self.push_rewrite(item.span, rewrite); - } - None => { - let rewrite = rewrite_opaque_type( - &self.get_context(), - self.block_indent, - item.ident, - generic_bounds, - generics, - &item.vis, - item.span, - ); - self.push_rewrite(item.span, rewrite); - } - } + use ItemVisitorKind::Item; + self.visit_ty_alias_kind(alias_kind, &Item(&item), item.span); } ast::ItemKind::GlobalAsm(..) => { let snippet = Some(self.snippet(item.span).to_owned()); @@ -627,6 +599,22 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { self.skip_context = skip_context_saved; } + fn visit_ty_alias_kind( + &mut self, + ty_kind: &ast::TyAliasKind, + visitor_kind: &ItemVisitorKind<'_>, + span: Span, + ) { + let rewrite = rewrite_type_alias( + ty_kind, + &self.get_context(), + self.block_indent, + visitor_kind, + span, + ); + self.push_rewrite(span, rewrite); + } + pub(crate) fn visit_trait_item(&mut self, ti: &ast::AssocItem) { skip_out_of_file_lines_range_visitor!(self, ti.span); @@ -659,19 +647,8 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { } } ast::AssocItemKind::TyAlias(ref ty_alias_kind) => { - let ast::TyAliasKind(_, ref generics, ref generic_bounds, ref type_default) = - **ty_alias_kind; - let rewrite = rewrite_type( - &self.get_context(), - self.block_indent, - ti.ident, - &ti.vis, - generics, - Some(generic_bounds), - type_default.as_ref(), - ti.span, - ); - self.push_rewrite(ti.span, rewrite); + use ItemVisitorKind::AssocTraitItem; + self.visit_ty_alias_kind(ty_alias_kind, &AssocTraitItem(&ti), ti.span); } ast::AssocItemKind::MacCall(ref mac) => { self.visit_mac(mac, Some(ti.ident), MacroPosition::Item); @@ -710,20 +687,8 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { } ast::AssocItemKind::Const(..) => self.visit_static(&StaticParts::from_impl_item(ii)), ast::AssocItemKind::TyAlias(ref ty_alias_kind) => { - let ast::TyAliasKind(defaultness, ref generics, _, ref ty) = **ty_alias_kind; - self.push_rewrite( - ii.span, - rewrite_impl_type( - ii.ident, - &ii.vis, - defaultness, - ty.as_ref(), - generics, - &self.get_context(), - self.block_indent, - ii.span, - ), - ); + use ItemVisitorKind::AssocImplItem; + self.visit_ty_alias_kind(ty_alias_kind, &AssocImplItem(&ii), ii.span); } ast::AssocItemKind::MacCall(ref mac) => { self.visit_mac(mac, Some(ii.ident), MacroPosition::Item); From e4472d3b07b2c34b27688303745d4cc0e74da9a5 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Sat, 6 Nov 2021 17:12:25 -0500 Subject: [PATCH 093/111] refactor: dedupe associated item visitation --- src/visitor.rs | 90 ++++++++++++++++++++------------------------------ 1 file changed, 35 insertions(+), 55 deletions(-) diff --git a/src/visitor.rs b/src/visitor.rs index f385245248da..25b0085b3eff 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -615,85 +615,65 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { self.push_rewrite(span, rewrite); } - pub(crate) fn visit_trait_item(&mut self, ti: &ast::AssocItem) { - skip_out_of_file_lines_range_visitor!(self, ti.span); + fn visit_assoc_item(&mut self, visitor_kind: &ItemVisitorKind<'_>) { + use ItemVisitorKind::*; + // TODO(calebcartwright): Not sure the skip spans are correct + let (ai, skip_span, assoc_ctxt) = match visitor_kind { + AssocTraitItem(ai) => (*ai, ai.span(), visit::AssocCtxt::Trait), + AssocImplItem(ai) => (*ai, ai.span, visit::AssocCtxt::Impl), + _ => unreachable!(), + }; + skip_out_of_file_lines_range_visitor!(self, ai.span); - if self.visit_attrs(&ti.attrs, ast::AttrStyle::Outer) { - self.push_skipped_with_span(ti.attrs.as_slice(), ti.span(), ti.span()); + if self.visit_attrs(&ai.attrs, ast::AttrStyle::Outer) { + self.push_skipped_with_span(&ai.attrs.as_slice(), skip_span, skip_span); return; } // TODO(calebcartwright): consider enabling box_patterns feature gate - match ti.kind { - ast::AssocItemKind::Const(..) => self.visit_static(&StaticParts::from_trait_item(ti)), - ast::AssocItemKind::Fn(ref fn_kind) => { + match (&ai.kind, visitor_kind) { + (ast::AssocItemKind::Const(..), AssocTraitItem(_)) => { + self.visit_static(&StaticParts::from_trait_item(&ai)) + } + (ast::AssocItemKind::Const(..), AssocImplItem(_)) => { + self.visit_static(&StaticParts::from_impl_item(&ai)) + } + (ast::AssocItemKind::Fn(ref fn_kind), _) => { let ast::FnKind(defaultness, ref sig, ref generics, ref block) = **fn_kind; if let Some(ref body) = block { - let inner_attrs = inner_attributes(&ti.attrs); - let fn_ctxt = visit::FnCtxt::Assoc(visit::AssocCtxt::Trait); + let inner_attrs = inner_attributes(&ai.attrs); + let fn_ctxt = visit::FnCtxt::Assoc(assoc_ctxt); self.visit_fn( - visit::FnKind::Fn(fn_ctxt, ti.ident, sig, &ti.vis, Some(body)), + visit::FnKind::Fn(fn_ctxt, ai.ident, sig, &ai.vis, Some(body)), generics, &sig.decl, - ti.span, + ai.span, defaultness, Some(&inner_attrs), ); } else { let indent = self.block_indent; let rewrite = - self.rewrite_required_fn(indent, ti.ident, sig, &ti.vis, generics, ti.span); - self.push_rewrite(ti.span, rewrite); + self.rewrite_required_fn(indent, ai.ident, sig, &ai.vis, generics, ai.span); + self.push_rewrite(ai.span, rewrite); } } - ast::AssocItemKind::TyAlias(ref ty_alias_kind) => { - use ItemVisitorKind::AssocTraitItem; - self.visit_ty_alias_kind(ty_alias_kind, &AssocTraitItem(&ti), ti.span); + (ast::AssocItemKind::TyAlias(ref ty_alias_kind), _) => { + self.visit_ty_alias_kind(ty_alias_kind, visitor_kind, ai.span); } - ast::AssocItemKind::MacCall(ref mac) => { - self.visit_mac(mac, Some(ti.ident), MacroPosition::Item); + (ast::AssocItemKind::MacCall(ref mac), _) => { + self.visit_mac(mac, Some(ai.ident), MacroPosition::Item); } + _ => unreachable!(), } } + pub(crate) fn visit_trait_item(&mut self, ti: &ast::AssocItem) { + self.visit_assoc_item(&ItemVisitorKind::AssocTraitItem(ti)); + } + pub(crate) fn visit_impl_item(&mut self, ii: &ast::AssocItem) { - skip_out_of_file_lines_range_visitor!(self, ii.span); - - if self.visit_attrs(&ii.attrs, ast::AttrStyle::Outer) { - self.push_skipped_with_span(ii.attrs.as_slice(), ii.span, ii.span); - return; - } - - match ii.kind { - ast::AssocItemKind::Fn(ref fn_kind) => { - let ast::FnKind(defaultness, ref sig, ref generics, ref block) = **fn_kind; - if let Some(ref body) = block { - let inner_attrs = inner_attributes(&ii.attrs); - let fn_ctxt = visit::FnCtxt::Assoc(visit::AssocCtxt::Impl); - self.visit_fn( - visit::FnKind::Fn(fn_ctxt, ii.ident, sig, &ii.vis, Some(body)), - generics, - &sig.decl, - ii.span, - defaultness, - Some(&inner_attrs), - ); - } else { - let indent = self.block_indent; - let rewrite = - self.rewrite_required_fn(indent, ii.ident, sig, &ii.vis, generics, ii.span); - self.push_rewrite(ii.span, rewrite); - } - } - ast::AssocItemKind::Const(..) => self.visit_static(&StaticParts::from_impl_item(ii)), - ast::AssocItemKind::TyAlias(ref ty_alias_kind) => { - use ItemVisitorKind::AssocImplItem; - self.visit_ty_alias_kind(ty_alias_kind, &AssocImplItem(&ii), ii.span); - } - ast::AssocItemKind::MacCall(ref mac) => { - self.visit_mac(mac, Some(ii.ident), MacroPosition::Item); - } - } + self.visit_assoc_item(&ItemVisitorKind::AssocImplItem(ii)); } fn visit_mac(&mut self, mac: &ast::MacCall, ident: Option, pos: MacroPosition) { From 31bc54a9a8d556ddb124dc177ea82569250651d1 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Sun, 7 Nov 2021 19:06:24 -0600 Subject: [PATCH 094/111] chore: bump toolchain --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index b19ecbdb07c4..1d2cad667511 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2021-10-20" +channel = "nightly-2021-11-08" components = ["rustc-dev"] From e6d1bf5acba29a8944f3bd537bcefb5e5972e5f1 Mon Sep 17 00:00:00 2001 From: Wu Yu Wei Date: Tue, 31 Mar 2020 14:36:12 +0800 Subject: [PATCH 095/111] Link tracking issues in Configurations.md (#4096) # Conflicts: # Configurations.md --- Configurations.md | 94 +++++++++++++++++++++++------------------------ 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/Configurations.md b/Configurations.md index 13826883d2f4..4a281251f227 100644 --- a/Configurations.md +++ b/Configurations.md @@ -47,7 +47,7 @@ Where to put a binary operator when a binary expression goes multiline. - **Default value**: `"Front"` - **Possible values**: `"Front"`, `"Back"` -- **Stable**: No (tracking issue: #3368) +- **Stable**: No (tracking issue: [#3368](https://github.com/rust-lang/rustfmt/issues/3368)) #### `"Front"` (default): @@ -88,7 +88,7 @@ them, additional blank lines are inserted. - **Default value**: `0` - **Possible values**: *unsigned integer* -- **Stable**: No (tracking issue: #3382) +- **Stable**: No (tracking issue: [#3382](https://github.com/rust-lang/rustfmt/issues/3382)) ### Example Original Code (rustfmt will not change it with the default value of `0`): @@ -128,7 +128,7 @@ lines are found, they are trimmed down to match this integer. - **Default value**: `1` - **Possible values**: any non-negative integer -- **Stable**: No (tracking issue: #3381) +- **Stable**: No (tracking issue: [#3381](https://github.com/rust-lang/rustfmt/issues/3381)) ### Example Original Code: @@ -186,7 +186,7 @@ Brace style for items - **Default value**: `"SameLineWhere"` - **Possible values**: `"AlwaysNextLine"`, `"PreferSameLine"`, `"SameLineWhere"` -- **Stable**: No (tracking issue: #3376) +- **Stable**: No (tracking issue: [#3376](https://github.com/rust-lang/rustfmt/issues/3376)) ### Functions @@ -313,7 +313,7 @@ Whether to use colored output or not. - **Default value**: `"Auto"` - **Possible values**: "Auto", "Always", "Never" -- **Stable**: No (tracking issue: #3385) +- **Stable**: No (tracking issue: [#3385](https://github.com/rust-lang/rustfmt/issues/3385)) ## `combine_control_expr` @@ -321,7 +321,7 @@ Combine control expressions with function calls. - **Default value**: `true` - **Possible values**: `true`, `false` -- **Stable**: No (tracking issue: #3369) +- **Stable**: No (tracking issue: [#3369](https://github.com/rust-lang/rustfmt/issues/3369)) #### `true` (default): @@ -429,7 +429,7 @@ Maximum length of comments. No effect unless`wrap_comments = true`. - **Default value**: `80` - **Possible values**: any positive integer -- **Stable**: No (tracking issue: #3349) +- **Stable**: No (tracking issue: [#3349](https://github.com/rust-lang/rustfmt/issues/3349)) **Note:** A value of `0` results in [`wrap_comments`](#wrap_comments) being applied regardless of a line's width. @@ -452,7 +452,7 @@ Replace strings of _ wildcards by a single .. in tuple patterns - **Default value**: `false` - **Possible values**: `true`, `false` -- **Stable**: No (tracking issue: #3384) +- **Stable**: No (tracking issue: [#3384](https://github.com/rust-lang/rustfmt/issues/3384)) #### `false` (default): @@ -477,7 +477,7 @@ Brace style for control flow constructs - **Default value**: `"AlwaysSameLine"` - **Possible values**: `"AlwaysNextLine"`, `"AlwaysSameLine"`, `"ClosingNextLine"` -- **Stable**: No (tracking issue: #3377) +- **Stable**: No (tracking issue: [#3377](https://github.com/rust-lang/rustfmt/issues/3377)) #### `"AlwaysSameLine"` (default): @@ -551,7 +551,7 @@ Put empty-body functions and impls on a single line - **Default value**: `true` - **Possible values**: `true`, `false` -- **Stable**: No (tracking issue: #3356) +- **Stable**: No (tracking issue: [#3356](https://github.com/rust-lang/rustfmt/issues/3356)) #### `true` (default): @@ -584,7 +584,7 @@ doesn't get ignored when aligning. - **Default value** : 0 - **Possible values**: any positive integer -- **Stable**: No (tracking issue: #3372) +- **Stable**: No (tracking issue: [#3372](https://github.com/rust-lang/rustfmt/issues/3372)) #### `0` (default): @@ -630,7 +630,7 @@ using a shorter name. - **Default value**: `false` - **Possible values**: `true`, `false` -- **Stable**: No (tracking issue: #3391) +- **Stable**: No (tracking issue: [#3391](https://github.com/rust-lang/rustfmt/issues/3391)) See also [`max_width`](#max_width). @@ -641,7 +641,7 @@ trailing whitespaces. - **Default value**: `false` - **Possible values**: `true`, `false` -- **Stable**: No (tracking issue: #3392) +- **Stable**: No (tracking issue: [#3392](https://github.com/rust-lang/rustfmt/issues/3392)) ## `fn_args_layout` @@ -771,7 +771,7 @@ Put single-expression functions on a single line - **Default value**: `false` - **Possible values**: `true`, `false` -- **Stable**: No (tracking issue: #3358) +- **Stable**: No (tracking issue: [#3358](https://github.com/rust-lang/rustfmt/issues/3358)) #### `false` (default): @@ -832,7 +832,7 @@ Force multiline closure and match arm bodies to be wrapped in a block - **Default value**: `false` - **Possible values**: `false`, `true` -- **Stable**: No (tracking issue: #3374) +- **Stable**: No (tracking issue: [#3374](https://github.com/rust-lang/rustfmt/issues/3374)) #### `false` (default): @@ -881,7 +881,7 @@ Format code snippet included in doc comments. - **Default value**: `false` - **Possible values**: `true`, `false` -- **Stable**: No (tracking issue: #3348) +- **Stable**: No (tracking issue: [#3348](https://github.com/rust-lang/rustfmt/issues/3348)) #### `false` (default): @@ -941,7 +941,7 @@ Format the metavariable matching patterns in macros. - **Default value**: `false` - **Possible values**: `true`, `false` -- **Stable**: No (tracking issue: #3354) +- **Stable**: No (tracking issue: [#3354](https://github.com/rust-lang/rustfmt/issues/3354)) #### `false` (default): @@ -978,7 +978,7 @@ Format the bodies of macros. - **Default value**: `true` - **Possible values**: `true`, `false` -- **Stable**: No (tracking issue: #3355) +- **Stable**: No (tracking issue: [#3355](https://github.com/rust-lang/rustfmt/issues/3355)) #### `true` (default): @@ -1011,7 +1011,7 @@ Format string literals where necessary - **Default value**: `false` - **Possible values**: `true`, `false` -- **Stable**: No (tracking issue: #3353) +- **Stable**: No (tracking issue: [#3353](https://github.com/rust-lang/rustfmt/issues/3353)) #### `false` (default): @@ -1072,7 +1072,7 @@ Do not show parse errors if the parser failed to parse files. - **Default value**: `false` - **Possible values**: `true`, `false` -- **Stable**: No (tracking issue: #3390) +- **Stable**: No (tracking issue: [#3390](https://github.com/rust-lang/rustfmt/issues/3390)) ## `ignore` @@ -1081,7 +1081,7 @@ The pattern format is the same as [.gitignore](https://git-scm.com/docs/gitignor - **Default value**: format every file - **Possible values**: See an example below -- **Stable**: No (tracking issue: #3395) +- **Stable**: No (tracking issue: [#3395](https://github.com/rust-lang/rustfmt/issues/3395)) ### Example @@ -1114,7 +1114,7 @@ Indent style of imports - **Default Value**: `"Block"` - **Possible values**: `"Block"`, `"Visual"` -- **Stable**: No (tracking issue: #3360) +- **Stable**: No (tracking issue: [#3360](https://github.com/rust-lang/rustfmt/issues/3360)) #### `"Block"` (default): @@ -1140,7 +1140,7 @@ Item layout inside a imports block - **Default value**: "Mixed" - **Possible values**: "Horizontal", "HorizontalVertical", "Mixed", "Vertical" -- **Stable**: No (tracking issue: #3361) +- **Stable**: No (tracking issue: [#3361](https://github.com/rust-lang/rustfmt/issues/3361)) #### `"Mixed"` (default): @@ -1203,7 +1203,7 @@ Indent on expressions or items. - **Default value**: `"Block"` - **Possible values**: `"Block"`, `"Visual"` -- **Stable**: No (tracking issue: #3346) +- **Stable**: No (tracking issue: [#3346](https://github.com/rust-lang/rustfmt/issues/3346)) ### Array @@ -1456,7 +1456,7 @@ Write an item and its attribute on the same line if their combined width is belo - **Default value**: 0 - **Possible values**: any positive integer -- **Stable**: No (tracking issue: #3343) +- **Stable**: No (tracking issue: [#3343](https://github.com/rust-lang/rustfmt/issues/3343)) ### Example @@ -1477,7 +1477,7 @@ Check whether beginnings of files match a license template. - **Default value**: `""` - **Possible values**: path to a license template file -- **Stable**: No (tracking issue: #3352) +- **Stable**: No (tracking issue: [#3352](https://github.com/rust-lang/rustfmt/issues/3352)) A license template is a plain text file which is matched literally against the beginning of each source file, except for `{}`-delimited blocks, which are @@ -1499,7 +1499,7 @@ The Style Guide requires that bodies are block wrapped by default if a line brea - **Default value**: `true` - **Possible values**: `true`, `false` -- **Stable**: No (tracking issue: #3373) +- **Stable**: No (tracking issue: [#3373](https://github.com/rust-lang/rustfmt/issues/3373)) #### `true` (default): @@ -1826,7 +1826,7 @@ Convert /* */ comments to // comments where possible - **Default value**: `false` - **Possible values**: `true`, `false` -- **Stable**: No (tracking issue: #3350) +- **Stable**: No (tracking issue: [#3350](https://github.com/rust-lang/rustfmt/issues/3350)) #### `false` (default): @@ -1854,7 +1854,7 @@ Convert `#![doc]` and `#[doc]` attributes to `//!` and `///` doc comments. - **Default value**: `false` - **Possible values**: `true`, `false` -- **Stable**: No (tracking issue: #3351) +- **Stable**: No (tracking issue: [#3351](https://github.com/rust-lang/rustfmt/issues/3351)) #### `false` (default): @@ -1885,7 +1885,7 @@ instead of being indented on a new line. - **Default value**: `false` - **Possible values**: `true`, `false` -- **Stable**: No (tracking issue: #3370) +- **Stable**: No (tracking issue: [#3370](https://github.com/rust-lang/rustfmt/issues/3370)) #### `false` (default): @@ -1992,7 +1992,7 @@ Reorder impl items. `type` and `const` are put first, then macros and methods. - **Default value**: `false` - **Possible values**: `true`, `false` -- **Stable**: No (tracking issue: #3363) +- **Stable**: No (tracking issue: [#3363](https://github.com/rust-lang/rustfmt/issues/3363)) #### `false` (default) @@ -2166,7 +2166,7 @@ Report `FIXME` items in comments. - **Default value**: `"Never"` - **Possible values**: `"Always"`, `"Unnumbered"`, `"Never"` -- **Stable**: No (tracking issue: #3394) +- **Stable**: No (tracking issue: [#3394](https://github.com/rust-lang/rustfmt/issues/3394)) Warns about any comments containing `FIXME` in them when set to `"Always"`. If it contains a `#X` (with `X` being a number) in parentheses following the @@ -2181,7 +2181,7 @@ Report `TODO` items in comments. - **Default value**: `"Never"` - **Possible values**: `"Always"`, `"Unnumbered"`, `"Never"` -- **Stable**: No (tracking issue: #3393) +- **Stable**: No (tracking issue: [#3393](https://github.com/rust-lang/rustfmt/issues/3393)) Warns about any comments containing `TODO` in them when set to `"Always"`. If it contains a `#X` (with `X` being a number) in parentheses following the @@ -2196,7 +2196,7 @@ specific version of rustfmt is used in your CI, use this option. - **Default value**: `CARGO_PKG_VERSION` - **Possible values**: any published version (e.g. `"0.3.8"`) -- **Stable**: No (tracking issue: #3386) +- **Stable**: No (tracking issue: [#3386](https://github.com/rust-lang/rustfmt/issues/3386)) ## `skip_children` @@ -2204,7 +2204,7 @@ Don't reformat out of line modules - **Default value**: `false` - **Possible values**: `true`, `false` -- **Stable**: No (tracking issue: #3389) +- **Stable**: No (tracking issue: [#3389](https://github.com/rust-lang/rustfmt/issues/3386)) ## `single_line_if_else_max_width` @@ -2224,7 +2224,7 @@ Leave a space after the colon. - **Default value**: `true` - **Possible values**: `true`, `false` -- **Stable**: No (tracking issue: #3366) +- **Stable**: No (tracking issue: [#3366](https://github.com/rust-lang/rustfmt/issues/3366)) #### `true` (default): @@ -2256,7 +2256,7 @@ Leave a space before the colon. - **Default value**: `false` - **Possible values**: `true`, `false` -- **Stable**: No (tracking issue: #3365) +- **Stable**: No (tracking issue: [#3365](https://github.com/rust-lang/rustfmt/issues/3365)) #### `false` (default): @@ -2288,7 +2288,7 @@ Put spaces around the .., ..=, and ... range operators - **Default value**: `false` - **Possible values**: `true`, `false` -- **Stable**: No (tracking issue: #3367) +- **Stable**: No (tracking issue: [#3367](https://github.com/rust-lang/rustfmt/issues/3367)) #### `false` (default): @@ -2344,7 +2344,7 @@ The maximum diff of width between struct fields to be aligned with each other. - **Default value** : 0 - **Possible values**: any non-negative integer -- **Stable**: No (tracking issue: #3371) +- **Stable**: No (tracking issue: [#3371](https://github.com/rust-lang/rustfmt/issues/3371)) #### `0` (default): @@ -2372,7 +2372,7 @@ Put small struct literals on a single line - **Default value**: `true` - **Possible values**: `true`, `false` -- **Stable**: No (tracking issue: #3357) +- **Stable**: No (tracking issue: [#3357](https://github.com/rust-lang/rustfmt/issues/3357)) #### `true` (default): @@ -2460,7 +2460,7 @@ How to handle trailing commas for lists - **Default value**: `"Vertical"` - **Possible values**: `"Always"`, `"Never"`, `"Vertical"` -- **Stable**: No (tracking issue: #3379) +- **Stable**: No (tracking issue: [#3379](https://github.com/rust-lang/rustfmt/issues/3379)) #### `"Vertical"` (default): @@ -2518,7 +2518,7 @@ Add trailing semicolon after break, continue and return - **Default value**: `true` - **Possible values**: `true`, `false` -- **Stable**: No (tracking issue: #3378) +- **Stable**: No (tracking issue: [#3378](https://github.com/rust-lang/rustfmt/issues/3378)) #### `true` (default): ```rust @@ -2540,7 +2540,7 @@ Determines if `+` or `=` are wrapped in spaces in the punctuation of types - **Default value**: `"Wide"` - **Possible values**: `"Compressed"`, `"Wide"` -- **Stable**: No (tracking issue: #3364) +- **Stable**: No (tracking issue: [#3364](https://github.com/rust-lang/rustfmt/issues/3364)) #### `"Wide"` (default): @@ -2564,7 +2564,7 @@ Enable unstable features on the unstable channel. - **Default value**: `false` - **Possible values**: `true`, `false` -- **Stable**: No (tracking issue: #3387) +- **Stable**: No (tracking issue: [#3387](https://github.com/rust-lang/rustfmt/issues/3387)) ## `use_field_init_shorthand` @@ -2779,7 +2779,7 @@ version number. - **Default value**: `One` - **Possible values**: `One`, `Two` -- **Stable**: No (tracking issue: #3383) +- **Stable**: No (tracking issue: [#3383](https://github.com/rust-lang/rustfmt/issues/3383)) ### Example @@ -2793,7 +2793,7 @@ Forces the `where` clause to be laid out on a single line. - **Default value**: `false` - **Possible values**: `true`, `false` -- **Stable**: No (tracking issue: #3359) +- **Stable**: No (tracking issue: [#3359](https://github.com/rust-lang/rustfmt/issues/3359)) #### `false` (default): @@ -2825,7 +2825,7 @@ Break comments to fit on the line - **Default value**: `false` - **Possible values**: `true`, `false` -- **Stable**: No (tracking issue: #3347) +- **Stable**: No (tracking issue: [#3347](https://github.com/rust-lang/rustfmt/issues/3347)) #### `false` (default): From eee8f0419dca910187350ac38fe9694b8b7919b9 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Wed, 17 Nov 2021 12:51:37 -0600 Subject: [PATCH 096/111] refactor: cleanup duplicative Impl handling code --- src/items.rs | 503 +++++++++++++++++++++++-------------------------- src/visitor.rs | 4 +- 2 files changed, 237 insertions(+), 270 deletions(-) diff --git a/src/items.rs b/src/items.rs index 50121a8b6b50..849e6c06218f 100644 --- a/src/items.rs +++ b/src/items.rs @@ -579,6 +579,25 @@ impl<'a> FmtVisitor<'a> { fn visit_impl_items(&mut self, items: &[ptr::P]) { if self.get_context().config.reorder_impl_items() { + type TyOpt = Option>; + use crate::ast::AssocItemKind::*; + let is_type = |ty: &TyOpt| { + ty.as_ref() + .map_or(true, |t| !matches!(t.kind, ast::TyKind::ImplTrait(..))) + }; + let is_opaque = |ty: &TyOpt| !is_type(ty); + let both_type = |left: &TyOpt, right: &TyOpt| is_type(left) && is_type(right); + let both_opaque = |left: &TyOpt, right: &TyOpt| is_opaque(left) && is_opaque(right); + let need_empty_line = |a: &ast::AssocItemKind, b: &ast::AssocItemKind| match (a, b) { + (TyAlias(lty), TyAlias(rty)) + if both_type(<y.ty, &rty.ty) || both_opaque(<y.ty, &rty.ty) => + { + false + } + (Const(..), Const(..)) => false, + _ => true, + }; + // Create visitor for each items, then reorder them. let mut buffer = vec![]; for item in items { @@ -587,50 +606,6 @@ impl<'a> FmtVisitor<'a> { self.buffer.clear(); } - fn is_type(ty: &Option>) -> bool { - if let Some(lty) = ty { - if let ast::TyKind::ImplTrait(..) = lty.kind { - return false; - } - } - true - } - - fn is_opaque(ty: &Option>) -> bool { - !is_type(ty) - } - - fn both_type( - a: &Option>, - b: &Option>, - ) -> bool { - is_type(a) && is_type(b) - } - - fn both_opaque( - a: &Option>, - b: &Option>, - ) -> bool { - is_opaque(a) && is_opaque(b) - } - - // In rustc-ap-v638 the `OpaqueTy` AssocItemKind variant was removed but - // we still need to differentiate to maintain sorting order. - - // type -> opaque -> const -> macro -> method - use crate::ast::AssocItemKind::*; - fn need_empty_line(a: &ast::AssocItemKind, b: &ast::AssocItemKind) -> bool { - match (a, b) { - (TyAlias(lty), TyAlias(rty)) - if both_type(<y.ty, &rty.ty) || both_opaque(<y.ty, &rty.ty) => - { - false - } - (Const(..), Const(..)) => false, - _ => true, - } - } - buffer.sort_by(|(_, a), (_, b)| match (&a.kind, &b.kind) { (TyAlias(lty), TyAlias(rty)) if both_type(<y.ty, &rty.ty) || both_opaque(<y.ty, &rty.ty) => @@ -676,136 +651,133 @@ impl<'a> FmtVisitor<'a> { pub(crate) fn format_impl( context: &RewriteContext<'_>, item: &ast::Item, + iimpl: &ast::Impl, offset: Indent, ) -> Option { - if let ast::ItemKind::Impl(impl_kind) = &item.kind { - let ast::Impl { - ref generics, - ref self_ty, - ref items, - .. - } = **impl_kind; - let mut result = String::with_capacity(128); - let ref_and_type = format_impl_ref_and_type(context, item, offset)?; - let sep = offset.to_string_with_newline(context.config); - result.push_str(&ref_and_type); + let ast::Impl { + generics, + self_ty, + items, + .. + } = iimpl; + let mut result = String::with_capacity(128); + let ref_and_type = format_impl_ref_and_type(context, item, iimpl, offset)?; + let sep = offset.to_string_with_newline(context.config); + result.push_str(&ref_and_type); - let where_budget = if result.contains('\n') { - context.config.max_width() - } else { - context.budget(last_line_width(&result)) - }; - - let mut option = WhereClauseOption::snuggled(&ref_and_type); - let snippet = context.snippet(item.span); - let open_pos = snippet.find_uncommented("{")? + 1; - if !contains_comment(&snippet[open_pos..]) - && items.is_empty() - && generics.where_clause.predicates.len() == 1 - && !result.contains('\n') - { - option.suppress_comma(); - option.snuggle(); - option.allow_single_line(); - } - - let missing_span = mk_sp(self_ty.span.hi(), item.span.hi()); - let where_span_end = context.snippet_provider.opt_span_before(missing_span, "{"); - let where_clause_str = rewrite_where_clause( - context, - &generics.where_clause, - context.config.brace_style(), - Shape::legacy(where_budget, offset.block_only()), - false, - "{", - where_span_end, - self_ty.span.hi(), - option, - )?; - - // If there is no where-clause, we may have missing comments between the trait name and - // the opening brace. - if generics.where_clause.predicates.is_empty() { - if let Some(hi) = where_span_end { - match recover_missing_comment_in_span( - mk_sp(self_ty.span.hi(), hi), - Shape::indented(offset, context.config), - context, - last_line_width(&result), - ) { - Some(ref missing_comment) if !missing_comment.is_empty() => { - result.push_str(missing_comment); - } - _ => (), - } - } - } - - if is_impl_single_line(context, items.as_slice(), &result, &where_clause_str, item)? { - result.push_str(&where_clause_str); - if where_clause_str.contains('\n') || last_line_contains_single_line_comment(&result) { - // if the where_clause contains extra comments AND - // there is only one where-clause predicate - // recover the suppressed comma in single line where_clause formatting - if generics.where_clause.predicates.len() == 1 { - result.push(','); - } - result.push_str(&format!("{}{{{}}}", sep, sep)); - } else { - result.push_str(" {}"); - } - return Some(result); - } - - result.push_str(&where_clause_str); - - let need_newline = last_line_contains_single_line_comment(&result) || result.contains('\n'); - match context.config.brace_style() { - _ if need_newline => result.push_str(&sep), - BraceStyle::AlwaysNextLine => result.push_str(&sep), - BraceStyle::PreferSameLine => result.push(' '), - BraceStyle::SameLineWhere => { - if !where_clause_str.is_empty() { - result.push_str(&sep); - } else { - result.push(' '); - } - } - } - - result.push('{'); - // this is an impl body snippet(impl SampleImpl { /* here */ }) - let lo = max(self_ty.span.hi(), generics.where_clause.span.hi()); - let snippet = context.snippet(mk_sp(lo, item.span.hi())); - let open_pos = snippet.find_uncommented("{")? + 1; - - if !items.is_empty() || contains_comment(&snippet[open_pos..]) { - let mut visitor = FmtVisitor::from_context(context); - let item_indent = offset.block_only().block_indent(context.config); - visitor.block_indent = item_indent; - visitor.last_pos = lo + BytePos(open_pos as u32); - - visitor.visit_attrs(&item.attrs, ast::AttrStyle::Inner); - visitor.visit_impl_items(items); - - visitor.format_missing(item.span.hi() - BytePos(1)); - - let inner_indent_str = visitor.block_indent.to_string_with_newline(context.config); - let outer_indent_str = offset.block_only().to_string_with_newline(context.config); - - result.push_str(&inner_indent_str); - result.push_str(visitor.buffer.trim()); - result.push_str(&outer_indent_str); - } else if need_newline || !context.config.empty_item_single_line() { - result.push_str(&sep); - } - - result.push('}'); - - Some(result) + let where_budget = if result.contains('\n') { + context.config.max_width() } else { - unreachable!(); + context.budget(last_line_width(&result)) + }; + + let mut option = WhereClauseOption::snuggled(&ref_and_type); + let snippet = context.snippet(item.span); + let open_pos = snippet.find_uncommented("{")? + 1; + if !contains_comment(&snippet[open_pos..]) + && items.is_empty() + && generics.where_clause.predicates.len() == 1 + && !result.contains('\n') + { + option.suppress_comma(); + option.snuggle(); + option.allow_single_line(); } + + let missing_span = mk_sp(self_ty.span.hi(), item.span.hi()); + let where_span_end = context.snippet_provider.opt_span_before(missing_span, "{"); + let where_clause_str = rewrite_where_clause( + context, + &generics.where_clause, + context.config.brace_style(), + Shape::legacy(where_budget, offset.block_only()), + false, + "{", + where_span_end, + self_ty.span.hi(), + option, + )?; + + // If there is no where-clause, we may have missing comments between the trait name and + // the opening brace. + if generics.where_clause.predicates.is_empty() { + if let Some(hi) = where_span_end { + match recover_missing_comment_in_span( + mk_sp(self_ty.span.hi(), hi), + Shape::indented(offset, context.config), + context, + last_line_width(&result), + ) { + Some(ref missing_comment) if !missing_comment.is_empty() => { + result.push_str(missing_comment); + } + _ => (), + } + } + } + + if is_impl_single_line(context, items.as_slice(), &result, &where_clause_str, item)? { + result.push_str(&where_clause_str); + if where_clause_str.contains('\n') || last_line_contains_single_line_comment(&result) { + // if the where_clause contains extra comments AND + // there is only one where-clause predicate + // recover the suppressed comma in single line where_clause formatting + if generics.where_clause.predicates.len() == 1 { + result.push(','); + } + result.push_str(&format!("{}{{{}}}", sep, sep)); + } else { + result.push_str(" {}"); + } + return Some(result); + } + + result.push_str(&where_clause_str); + + let need_newline = last_line_contains_single_line_comment(&result) || result.contains('\n'); + match context.config.brace_style() { + _ if need_newline => result.push_str(&sep), + BraceStyle::AlwaysNextLine => result.push_str(&sep), + BraceStyle::PreferSameLine => result.push(' '), + BraceStyle::SameLineWhere => { + if !where_clause_str.is_empty() { + result.push_str(&sep); + } else { + result.push(' '); + } + } + } + + result.push('{'); + // this is an impl body snippet(impl SampleImpl { /* here */ }) + let lo = max(self_ty.span.hi(), generics.where_clause.span.hi()); + let snippet = context.snippet(mk_sp(lo, item.span.hi())); + let open_pos = snippet.find_uncommented("{")? + 1; + + if !items.is_empty() || contains_comment(&snippet[open_pos..]) { + let mut visitor = FmtVisitor::from_context(context); + let item_indent = offset.block_only().block_indent(context.config); + visitor.block_indent = item_indent; + visitor.last_pos = lo + BytePos(open_pos as u32); + + visitor.visit_attrs(&item.attrs, ast::AttrStyle::Inner); + visitor.visit_impl_items(items); + + visitor.format_missing(item.span.hi() - BytePos(1)); + + let inner_indent_str = visitor.block_indent.to_string_with_newline(context.config); + let outer_indent_str = offset.block_only().to_string_with_newline(context.config); + + result.push_str(&inner_indent_str); + result.push_str(visitor.buffer.trim()); + result.push_str(&outer_indent_str); + } else if need_newline || !context.config.empty_item_single_line() { + result.push_str(&sep); + } + + result.push('}'); + + Some(result) } fn is_impl_single_line( @@ -830,111 +802,106 @@ fn is_impl_single_line( fn format_impl_ref_and_type( context: &RewriteContext<'_>, item: &ast::Item, + iimpl: &ast::Impl, offset: Indent, ) -> Option { - if let ast::ItemKind::Impl(impl_kind) = &item.kind { - let ast::Impl { - unsafety, - polarity, - defaultness, - constness, - ref generics, - of_trait: ref trait_ref, - ref self_ty, - .. - } = **impl_kind; - let mut result = String::with_capacity(128); + let ast::Impl { + unsafety, + polarity, + defaultness, + constness, + ref generics, + of_trait: ref trait_ref, + ref self_ty, + .. + } = *iimpl; + let mut result = String::with_capacity(128); - result.push_str(&format_visibility(context, &item.vis)); - result.push_str(format_defaultness(defaultness)); - result.push_str(format_unsafety(unsafety)); + result.push_str(&format_visibility(context, &item.vis)); + result.push_str(format_defaultness(defaultness)); + result.push_str(format_unsafety(unsafety)); - let shape = if context.config.version() == Version::Two { - Shape::indented(offset + last_line_width(&result), context.config) - } else { - generics_shape_from_config( - context.config, - Shape::indented(offset + last_line_width(&result), context.config), - 0, - )? - }; - let generics_str = rewrite_generics(context, "impl", generics, shape)?; - result.push_str(&generics_str); - result.push_str(format_constness_right(constness)); - - let polarity_str = match polarity { - ast::ImplPolarity::Negative(_) => "!", - ast::ImplPolarity::Positive => "", - }; - - let polarity_overhead; - let trait_ref_overhead; - if let Some(ref trait_ref) = *trait_ref { - let result_len = last_line_width(&result); - result.push_str(&rewrite_trait_ref( - context, - trait_ref, - offset, - polarity_str, - result_len, - )?); - polarity_overhead = 0; // already written - trait_ref_overhead = " for".len(); - } else { - polarity_overhead = polarity_str.len(); - trait_ref_overhead = 0; - } - - // Try to put the self type in a single line. - let curly_brace_overhead = if generics.where_clause.predicates.is_empty() { - // If there is no where-clause adapt budget for type formatting to take space and curly - // brace into account. - match context.config.brace_style() { - BraceStyle::AlwaysNextLine => 0, - _ => 2, - } - } else { - 0 - }; - let used_space = last_line_width(&result) - + polarity_overhead - + trait_ref_overhead - + curly_brace_overhead; - // 1 = space before the type. - let budget = context.budget(used_space + 1); - if let Some(self_ty_str) = self_ty.rewrite(context, Shape::legacy(budget, offset)) { - if !self_ty_str.contains('\n') { - if trait_ref.is_some() { - result.push_str(" for "); - } else { - result.push(' '); - result.push_str(polarity_str); - } - result.push_str(&self_ty_str); - return Some(result); - } - } - - // Couldn't fit the self type on a single line, put it on a new line. - result.push('\n'); - // Add indentation of one additional tab. - let new_line_offset = offset.block_indent(context.config); - result.push_str(&new_line_offset.to_string(context.config)); - if trait_ref.is_some() { - result.push_str("for "); - } else { - result.push_str(polarity_str); - } - let budget = context.budget(last_line_width(&result) + polarity_overhead); - let type_offset = match context.config.indent_style() { - IndentStyle::Visual => new_line_offset + trait_ref_overhead, - IndentStyle::Block => new_line_offset, - }; - result.push_str(&*self_ty.rewrite(context, Shape::legacy(budget, type_offset))?); - Some(result) + let shape = if context.config.version() == Version::Two { + Shape::indented(offset + last_line_width(&result), context.config) } else { - unreachable!(); + generics_shape_from_config( + context.config, + Shape::indented(offset + last_line_width(&result), context.config), + 0, + )? + }; + let generics_str = rewrite_generics(context, "impl", generics, shape)?; + result.push_str(&generics_str); + result.push_str(format_constness_right(constness)); + + let polarity_str = match polarity { + ast::ImplPolarity::Negative(_) => "!", + ast::ImplPolarity::Positive => "", + }; + + let polarity_overhead; + let trait_ref_overhead; + if let Some(ref trait_ref) = *trait_ref { + let result_len = last_line_width(&result); + result.push_str(&rewrite_trait_ref( + context, + trait_ref, + offset, + polarity_str, + result_len, + )?); + polarity_overhead = 0; // already written + trait_ref_overhead = " for".len(); + } else { + polarity_overhead = polarity_str.len(); + trait_ref_overhead = 0; } + + // Try to put the self type in a single line. + let curly_brace_overhead = if generics.where_clause.predicates.is_empty() { + // If there is no where-clause adapt budget for type formatting to take space and curly + // brace into account. + match context.config.brace_style() { + BraceStyle::AlwaysNextLine => 0, + _ => 2, + } + } else { + 0 + }; + let used_space = + last_line_width(&result) + polarity_overhead + trait_ref_overhead + curly_brace_overhead; + // 1 = space before the type. + let budget = context.budget(used_space + 1); + if let Some(self_ty_str) = self_ty.rewrite(context, Shape::legacy(budget, offset)) { + if !self_ty_str.contains('\n') { + if trait_ref.is_some() { + result.push_str(" for "); + } else { + result.push(' '); + result.push_str(polarity_str); + } + result.push_str(&self_ty_str); + return Some(result); + } + } + + // Couldn't fit the self type on a single line, put it on a new line. + result.push('\n'); + // Add indentation of one additional tab. + let new_line_offset = offset.block_indent(context.config); + result.push_str(&new_line_offset.to_string(context.config)); + if trait_ref.is_some() { + result.push_str("for "); + } else { + result.push_str(polarity_str); + } + let budget = context.budget(last_line_width(&result) + polarity_overhead); + let type_offset = match context.config.indent_style() { + IndentStyle::Visual => new_line_offset + trait_ref_overhead, + IndentStyle::Block => new_line_offset, + }; + result.push_str(&*self_ty.rewrite(context, Shape::legacy(budget, type_offset))?); + Some(result) } fn rewrite_trait_ref( diff --git a/src/visitor.rs b/src/visitor.rs index 527042d098a1..e4a7be742abc 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -485,9 +485,9 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { if should_visit_node_again { match item.kind { ast::ItemKind::Use(ref tree) => self.format_import(item, tree), - ast::ItemKind::Impl { .. } => { + ast::ItemKind::Impl(ref iimpl) => { let block_indent = self.block_indent; - let rw = self.with_context(|ctx| format_impl(ctx, item, block_indent)); + let rw = self.with_context(|ctx| format_impl(ctx, item, iimpl, block_indent)); self.push_rewrite(item.span, rw); } ast::ItemKind::Trait(..) => { From 0023abfb2c826d8a9ff74146ece513b22b86fdce Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Thu, 18 Nov 2021 12:38:34 -0600 Subject: [PATCH 097/111] tests: add cases for type alias issues --- tests/source/issue_4823.rs | 5 +++++ tests/source/issue_5027.rs | 7 +++++++ tests/source/issue_5086.rs | 2 ++ tests/target/issue_4823.rs | 5 +++++ tests/target/issue_5027.rs | 17 +++++++++++++++++ tests/target/issue_5086.rs | 2 ++ 6 files changed, 38 insertions(+) create mode 100644 tests/source/issue_4823.rs create mode 100644 tests/source/issue_5027.rs create mode 100644 tests/source/issue_5086.rs create mode 100644 tests/target/issue_4823.rs create mode 100644 tests/target/issue_5027.rs create mode 100644 tests/target/issue_5086.rs diff --git a/tests/source/issue_4823.rs b/tests/source/issue_4823.rs new file mode 100644 index 000000000000..a008dd3d8381 --- /dev/null +++ b/tests/source/issue_4823.rs @@ -0,0 +1,5 @@ +macro_rules! m { +() => { +type Type; +}; +} diff --git a/tests/source/issue_5027.rs b/tests/source/issue_5027.rs new file mode 100644 index 000000000000..67beeb23b711 --- /dev/null +++ b/tests/source/issue_5027.rs @@ -0,0 +1,7 @@ +// rustfmt-version: Two + +pub type Iter<'a, D> = impl DoubleEndedIterator)>+ ExactSizeIterator+ 'a; + +trait FOo {pub type Iter<'a, D> = impl DoubleEndedIterator)>+ ExactSizeIterator+ 'a;} + +impl Bar {pub type Iter<'a, D> = impl DoubleEndedIterator)>+ ExactSizeIterator+ 'a;} \ No newline at end of file diff --git a/tests/source/issue_5086.rs b/tests/source/issue_5086.rs new file mode 100644 index 000000000000..1644c9d2ccbb --- /dev/null +++ b/tests/source/issue_5086.rs @@ -0,0 +1,2 @@ +#[cfg(any())] + type Type : Bound ; \ No newline at end of file diff --git a/tests/target/issue_4823.rs b/tests/target/issue_4823.rs new file mode 100644 index 000000000000..de17467c0efa --- /dev/null +++ b/tests/target/issue_4823.rs @@ -0,0 +1,5 @@ +macro_rules! m { + () => { + type Type; + }; +} diff --git a/tests/target/issue_5027.rs b/tests/target/issue_5027.rs new file mode 100644 index 000000000000..26d771720b6c --- /dev/null +++ b/tests/target/issue_5027.rs @@ -0,0 +1,17 @@ +// rustfmt-version: Two + +pub type Iter<'a, D> = impl DoubleEndedIterator)> + + ExactSizeIterator + + 'a; + +trait FOo { + pub type Iter<'a, D> = impl DoubleEndedIterator)> + + ExactSizeIterator + + 'a; +} + +impl Bar { + type Iter<'a, D> = impl DoubleEndedIterator)> + + ExactSizeIterator + + 'a; +} diff --git a/tests/target/issue_5086.rs b/tests/target/issue_5086.rs new file mode 100644 index 000000000000..7a0be06f7917 --- /dev/null +++ b/tests/target/issue_5086.rs @@ -0,0 +1,2 @@ +#[cfg(any())] +type Type: Bound; From 2c442ccf25a98c9e8f0a972d94f10ef44b7b09bf Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Thu, 18 Nov 2021 12:39:38 -0600 Subject: [PATCH 098/111] fix: correct some type alias issues --- src/items.rs | 49 ++++++++++++++++++++++++------------------------- src/types.rs | 8 ++++++++ 2 files changed, 32 insertions(+), 25 deletions(-) diff --git a/src/items.rs b/src/items.rs index 849e6c06218f..63c32e012df7 100644 --- a/src/items.rs +++ b/src/items.rs @@ -28,6 +28,7 @@ use crate::shape::{Indent, Shape}; use crate::source_map::{LineRangeUtils, SpanUtils}; use crate::spanned::Spanned; use crate::stmt::Stmt; +use crate::types::opaque_ty; use crate::utils::*; use crate::vertical::rewrite_with_alignment; use crate::visitor::FmtVisitor; @@ -581,13 +582,10 @@ impl<'a> FmtVisitor<'a> { if self.get_context().config.reorder_impl_items() { type TyOpt = Option>; use crate::ast::AssocItemKind::*; - let is_type = |ty: &TyOpt| { - ty.as_ref() - .map_or(true, |t| !matches!(t.kind, ast::TyKind::ImplTrait(..))) - }; - let is_opaque = |ty: &TyOpt| !is_type(ty); - let both_type = |left: &TyOpt, right: &TyOpt| is_type(left) && is_type(right); - let both_opaque = |left: &TyOpt, right: &TyOpt| is_opaque(left) && is_opaque(right); + let is_type = |ty: &TyOpt| opaque_ty(ty).is_none(); + let is_opaque = |ty: &TyOpt| opaque_ty(ty).is_some(); + let both_type = |l: &TyOpt, r: &TyOpt| is_type(l) && is_type(r); + let both_opaque = |l: &TyOpt, r: &TyOpt| is_opaque(l) && is_opaque(r); let need_empty_line = |a: &ast::AssocItemKind, b: &ast::AssocItemKind| match (a, b) { (TyAlias(lty), TyAlias(rty)) if both_type(<y.ty, &rty.ty) || both_opaque(<y.ty, &rty.ty) => @@ -1508,43 +1506,38 @@ pub(crate) fn rewrite_type_alias<'a, 'b>( ref bounds, ref ty, } = *ty_alias_kind; - let ty_opt = ty.as_ref().map(|t| &**t); + let ty_opt = ty.as_ref(); let (ident, vis) = match visitor_kind { Item(i) => (i.ident, &i.vis), AssocTraitItem(i) | AssocImplItem(i) => (i.ident, &i.vis), ForeignItem(i) => (i.ident, &i.vis), }; let rw_info = &TyAliasRewriteInfo(context, indent, generics, ident, span); - + let op_ty = opaque_ty(ty); // Type Aliases are formatted slightly differently depending on the context // in which they appear, whether they are opaque, and whether they are associated. // https://rustc-dev-guide.rust-lang.org/opaque-types-type-alias-impl-trait.html // https://github.com/rust-dev-tools/fmt-rfcs/blob/master/guide/items.md#type-aliases - match (visitor_kind, ty_opt) { - (Item(_), None) => { - let op_ty = OpaqueType { bounds }; - rewrite_ty(rw_info, Some(bounds), Some(&op_ty), vis) + match (visitor_kind, &op_ty) { + (Item(_) | AssocTraitItem(_) | ForeignItem(_), Some(ref op_bounds)) => { + let op = OpaqueType { bounds: op_bounds }; + rewrite_ty(rw_info, Some(bounds), Some(&op), vis) + } + (Item(_) | AssocTraitItem(_) | ForeignItem(_), None) => { + rewrite_ty(rw_info, Some(bounds), ty_opt, vis) } - (Item(_), Some(ty)) => rewrite_ty(rw_info, Some(bounds), Some(&*ty), vis), (AssocImplItem(_), _) => { - let result = if let Some(ast::Ty { - kind: ast::TyKind::ImplTrait(_, ref bounds), - .. - }) = ty_opt - { - let op_ty = OpaqueType { bounds }; - rewrite_ty(rw_info, None, Some(&op_ty), &DEFAULT_VISIBILITY) + let result = if let Some(ref op_bounds) = op_ty { + let op = OpaqueType { bounds: op_bounds }; + rewrite_ty(rw_info, Some(bounds), Some(&op), &DEFAULT_VISIBILITY) } else { - rewrite_ty(rw_info, None, ty.as_ref(), vis) + rewrite_ty(rw_info, Some(bounds), ty_opt, vis) }?; match defaultness { ast::Defaultness::Default(..) => Some(format!("default {}", result)), _ => Some(result), } } - (AssocTraitItem(_), _) | (ForeignItem(_), _) => { - rewrite_ty(rw_info, Some(bounds), ty.as_ref(), vis) - } } } @@ -1867,6 +1860,12 @@ fn rewrite_static( Some(format!("{}{};", prefix, ty_str)) } } + +// FIXME(calebcartwright) - This is a hack around a bug in the handling of TyKind::ImplTrait. +// This should be removed once that bug is resolved, with the type alias formatting using the +// defined Ty for the RHS directly. +// https://github.com/rust-lang/rustfmt/issues/4373 +// https://github.com/rust-lang/rustfmt/issues/5027 struct OpaqueType<'a> { bounds: &'a ast::GenericBounds, } diff --git a/src/types.rs b/src/types.rs index 9ea90c5e46dd..891609783b61 100644 --- a/src/types.rs +++ b/src/types.rs @@ -2,6 +2,7 @@ use std::iter::ExactSizeIterator; use std::ops::Deref; use rustc_ast::ast::{self, FnRetTy, Mutability}; +use rustc_ast::ptr; use rustc_span::{symbol::kw, BytePos, Pos, Span}; use crate::comment::{combine_strs_with_missing_comments, contains_comment}; @@ -1031,6 +1032,13 @@ fn join_bounds_inner( } } +pub(crate) fn opaque_ty(ty: &Option>) -> Option<&ast::GenericBounds> { + ty.as_ref().and_then(|t| match &t.kind { + ast::TyKind::ImplTrait(_, bounds) => Some(bounds), + _ => None, + }) +} + pub(crate) fn can_be_overflowed_type( context: &RewriteContext<'_>, ty: &ast::Ty, From 196e6765048b8306208ac88d743ab02e8faf4b6b Mon Sep 17 00:00:00 2001 From: mujpao Date: Thu, 18 Nov 2021 17:06:49 -0800 Subject: [PATCH 099/111] Preserve normalized comments after last list item --- src/lists.rs | 13 +- .../wrap-comments-not-normalized.rs | 108 ++++++++++++++++ tests/source/issue-4909/wrap-comments-true.rs | 109 ++++++++++++++++ .../target/issue-4909/wrap-comments-false.rs | 72 +++++++++++ .../wrap-comments-not-normalized.rs | 118 +++++++++++++++++ tests/target/issue-4909/wrap-comments-true.rs | 119 ++++++++++++++++++ 6 files changed, 535 insertions(+), 4 deletions(-) create mode 100644 tests/source/issue-4909/wrap-comments-not-normalized.rs create mode 100644 tests/source/issue-4909/wrap-comments-true.rs create mode 100644 tests/target/issue-4909/wrap-comments-false.rs create mode 100644 tests/target/issue-4909/wrap-comments-not-normalized.rs create mode 100644 tests/target/issue-4909/wrap-comments-true.rs diff --git a/src/lists.rs b/src/lists.rs index d341ec8e6b0e..3515dd172510 100644 --- a/src/lists.rs +++ b/src/lists.rs @@ -444,10 +444,15 @@ where let offset = formatting.shape.indent + overhead; let comment_shape = Shape::legacy(width, offset); - // Use block-style only for the last item or multiline comments. - let block_style = !formatting.ends_with_newline && last - || comment.trim().contains('\n') - || comment.trim().len() > width; + let block_style = if !formatting.ends_with_newline && last { + true + } else if starts_with_newline(comment) { + false + } else if comment.trim().contains('\n') || comment.trim().len() > width { + true + } else { + false + }; rewrite_comment( comment.trim_start(), diff --git a/tests/source/issue-4909/wrap-comments-not-normalized.rs b/tests/source/issue-4909/wrap-comments-not-normalized.rs new file mode 100644 index 000000000000..cd8de2707f16 --- /dev/null +++ b/tests/source/issue-4909/wrap-comments-not-normalized.rs @@ -0,0 +1,108 @@ +// rustfmt-wrap_comments: true + +pub enum E { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + Variant1, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + Variant2, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +} + +pub enum E2 { + // This can be changed once https://github.com/rust-lang/rustfmt/issues/4854 is fixed +// Expand as needed, numbers should be ascending according to the stage +// through the inclusion pipeline, or according to the descriptions +} + +pub enum E3 { + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + Variant1, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + Variant2, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + +} + +pub struct S { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + some_field: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + last_field: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +} + +pub struct S2 { + // This can be changed once https://github.com/rust-lang/rustfmt/issues/4854 is fixed +// Expand as needed, numbers should be ascending according to the stage +// through the inclusion pipeline, or according to the descriptions +} + +pub struct S3 { + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + some_field: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + last_field: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions +} + +fn foo( + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + a: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + b: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +) -> usize { + 5 +} + +fn foo2(// Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +) -> usize { + 5 +} + +fn foo3( + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + a: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + b: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + +) -> usize { + 5 +} + +fn main() { + let v = vec![ + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + 1, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + 2, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + ]; + + let v2: Vec = vec![ + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + ]; + + let v3 = vec![ + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + 1, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + 2, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + ]; +} diff --git a/tests/source/issue-4909/wrap-comments-true.rs b/tests/source/issue-4909/wrap-comments-true.rs new file mode 100644 index 000000000000..f18d8d686e1f --- /dev/null +++ b/tests/source/issue-4909/wrap-comments-true.rs @@ -0,0 +1,109 @@ +// rustfmt-normalize_comments: true +// rustfmt-wrap_comments: true + +pub enum E { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + Variant1, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + Variant2, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +} + +pub enum E2 { + // This can be changed once https://github.com/rust-lang/rustfmt/issues/4854 is fixed +// Expand as needed, numbers should be ascending according to the stage +// through the inclusion pipeline, or according to the descriptions +} + +pub enum E3 { + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + Variant1, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + Variant2, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + +} + +pub struct S { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + some_field: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + last_field: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +} + +pub struct S2 { + // This can be changed once https://github.com/rust-lang/rustfmt/issues/4854 is fixed +// Expand as needed, numbers should be ascending according to the stage +// through the inclusion pipeline, or according to the descriptions +} + +pub struct S3 { + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + some_field: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + last_field: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions +} + +fn foo( + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + a: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + b: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +) -> usize { + 5 +} + +fn foo2(// Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +) -> usize { + 5 +} + +fn foo3( + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + a: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + b: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + +) -> usize { + 5 +} + +fn main() { + let v = vec![ + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + 1, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + 2, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + ]; + + let v2: Vec = vec![ + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + ]; + + let v3 = vec![ + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + 1, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + 2, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + ]; +} diff --git a/tests/target/issue-4909/wrap-comments-false.rs b/tests/target/issue-4909/wrap-comments-false.rs new file mode 100644 index 000000000000..a8ead584f445 --- /dev/null +++ b/tests/target/issue-4909/wrap-comments-false.rs @@ -0,0 +1,72 @@ +// rustfmt-normalize_comments: true + +pub enum E { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + Variant1, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + Variant2, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +} + +pub enum E2 { + // This can be changed once https://github.com/rust-lang/rustfmt/issues/4854 is fixed +// Expand as needed, numbers should be ascending according to the stage +// through the inclusion pipeline, or according to the descriptions +} + +pub struct S { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + some_field: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + last_field: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +} + +pub struct S2 { + // This can be changed once https://github.com/rust-lang/rustfmt/issues/4854 is fixed +// Expand as needed, numbers should be ascending according to the stage +// through the inclusion pipeline, or according to the descriptions +} + +fn foo( + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + a: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + b: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +) -> usize { + 5 +} + +fn foo2(// Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +) -> usize { + 5 +} + +fn main() { + let v = vec![ + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + 1, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + 2, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + ]; + + let v2: Vec = vec![ + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + ]; +} diff --git a/tests/target/issue-4909/wrap-comments-not-normalized.rs b/tests/target/issue-4909/wrap-comments-not-normalized.rs new file mode 100644 index 000000000000..2a3d803b3b1e --- /dev/null +++ b/tests/target/issue-4909/wrap-comments-not-normalized.rs @@ -0,0 +1,118 @@ +// rustfmt-wrap_comments: true + +pub enum E { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + Variant1, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + Variant2, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +} + +pub enum E2 { + // This can be changed once https://github.com/rust-lang/rustfmt/issues/4854 is fixed +// Expand as needed, numbers should be ascending according to the stage +// through the inclusion pipeline, or according to the descriptions +} + +pub enum E3 { + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions + Variant1, + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions + Variant2, + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions +} + +pub struct S { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + some_field: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + last_field: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +} + +pub struct S2 { + // This can be changed once https://github.com/rust-lang/rustfmt/issues/4854 is fixed +// Expand as needed, numbers should be ascending according to the stage +// through the inclusion pipeline, or according to the descriptions +} + +pub struct S3 { + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions + some_field: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions + last_field: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions +} + +fn foo( + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + a: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + b: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +) -> usize { + 5 +} + +fn foo2(// Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +) -> usize { + 5 +} + +fn foo3( + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions + a: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions + b: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions +) -> usize { + 5 +} + +fn main() { + let v = vec![ + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + 1, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + 2, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + ]; + + let v2: Vec = vec![ + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + ]; + + let v3 = vec![ + // Expand as needed, numbers should be ascending according to the stage through the + // inclusion pipeline, or according to the descriptions + 1, + // Expand as needed, numbers should be ascending according to the stage through the + // inclusion pipeline, or according to the descriptions + 2, + // Expand as needed, numbers should be ascending according to the stage through the + // inclusion pipeline, or according to the descriptions + ]; +} diff --git a/tests/target/issue-4909/wrap-comments-true.rs b/tests/target/issue-4909/wrap-comments-true.rs new file mode 100644 index 000000000000..5376962a2ee4 --- /dev/null +++ b/tests/target/issue-4909/wrap-comments-true.rs @@ -0,0 +1,119 @@ +// rustfmt-normalize_comments: true +// rustfmt-wrap_comments: true + +pub enum E { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + Variant1, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + Variant2, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +} + +pub enum E2 { + // This can be changed once https://github.com/rust-lang/rustfmt/issues/4854 is fixed +// Expand as needed, numbers should be ascending according to the stage +// through the inclusion pipeline, or according to the descriptions +} + +pub enum E3 { + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions + Variant1, + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions + Variant2, + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions +} + +pub struct S { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + some_field: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + last_field: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +} + +pub struct S2 { + // This can be changed once https://github.com/rust-lang/rustfmt/issues/4854 is fixed +// Expand as needed, numbers should be ascending according to the stage +// through the inclusion pipeline, or according to the descriptions +} + +pub struct S3 { + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions + some_field: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions + last_field: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions +} + +fn foo( + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + a: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + b: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +) -> usize { + 5 +} + +fn foo2(// Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +) -> usize { + 5 +} + +fn foo3( + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions + a: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions + b: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions +) -> usize { + 5 +} + +fn main() { + let v = vec![ + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + 1, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + 2, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + ]; + + let v2: Vec = vec![ + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + ]; + + let v3 = vec![ + // Expand as needed, numbers should be ascending according to the stage through the + // inclusion pipeline, or according to the descriptions + 1, + // Expand as needed, numbers should be ascending according to the stage through the + // inclusion pipeline, or according to the descriptions + 2, + // Expand as needed, numbers should be ascending according to the stage through the + // inclusion pipeline, or according to the descriptions + ]; +} From 826eba8984690b7c23aab8604b6a85587bb93edb Mon Sep 17 00:00:00 2001 From: Johannes Linke Date: Sat, 20 Nov 2021 02:22:50 +0100 Subject: [PATCH 100/111] Add a few missing tracking issues in Configurations.md (#5084) * Add a few missing tracking issues in Configurations.md * fix: tracking issue for imports_granularity stabilization Co-authored-by: Caleb Cartwright --- Configurations.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Configurations.md b/Configurations.md index 4a281251f227..a89fbe863e65 100644 --- a/Configurations.md +++ b/Configurations.md @@ -933,7 +933,7 @@ if any of the first five lines contains `@generated` marker. - **Default value**: `false` - **Possible values**: `true`, `false` -- **Stable**: No +- **Stable**: No (tracking issue: [#5080](https://github.com/rust-lang/rustfmt/issues/5080)) ## `format_macro_matchers` @@ -1064,7 +1064,7 @@ Control the case of the letters in hexadecimal literal values - **Default value**: `Preserve` - **Possible values**: `Upper`, `Lower` -- **Stable**: No +- **Stable**: No (tracking issue: [#5081](https://github.com/rust-lang/rustfmt/issues/5081)) ## `hide_parse_errors` @@ -1701,7 +1701,7 @@ How imports should be grouped into `use` statements. Imports will be merged or s - **Default value**: `Preserve` - **Possible values**: `Preserve`, `Crate`, `Module`, `Item`, `One` -- **Stable**: No +- **Stable**: No (tracking issue: [#4991](https://github.com/rust-lang/rustfmt/issues/4991)) #### `Preserve` (default): @@ -2063,7 +2063,7 @@ Controls the strategy for how imports are grouped together. - **Default value**: `Preserve` - **Possible values**: `Preserve`, `StdExternalCrate`, `One` -- **Stable**: No +- **Stable**: No (tracking issue: [#5083](https://github.com/rust-lang/rustfmt/issues/5083)) #### `Preserve` (default): From 4389a4ce49e737915af1f1b27b96b05598a4e388 Mon Sep 17 00:00:00 2001 From: Dom Date: Fri, 19 Nov 2021 20:15:33 +0100 Subject: [PATCH 101/111] fix: do not wrap reference-style doc links Prevents wrap_comments from incorrectly wrapping reference-style doc links. --- src/comment.rs | 19 ++++++++++++++++++- tests/target/issue-5095.rs | 27 +++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 tests/target/issue-5095.rs diff --git a/src/comment.rs b/src/comment.rs index 7b76c232937d..830d2b50aad8 100644 --- a/src/comment.rs +++ b/src/comment.rs @@ -3,6 +3,8 @@ use std::{self, borrow::Cow, iter}; use itertools::{multipeek, MultiPeek}; +use lazy_static::lazy_static; +use regex::Regex; use rustc_span::Span; use crate::config::Config; @@ -15,6 +17,17 @@ use crate::utils::{ }; use crate::{ErrorKind, FormattingError}; +lazy_static! { + /// A regex matching reference doc links. + /// + /// ```markdown + /// /// An [example]. + /// /// + /// /// [example]: this::is::a::link + /// ``` + static ref REFERENCE_LINK_URL: Regex = Regex::new(r"^\[.+\]\s?:").unwrap(); +} + fn is_custom_comment(comment: &str) -> bool { if !comment.starts_with("//") { false @@ -842,7 +855,11 @@ fn trim_custom_comment_prefix(s: &str) -> String { /// Returns `true` if the given string MAY include URLs or alike. fn has_url(s: &str) -> bool { // This function may return false positive, but should get its job done in most cases. - s.contains("https://") || s.contains("http://") || s.contains("ftp://") || s.contains("file://") + s.contains("https://") + || s.contains("http://") + || s.contains("ftp://") + || s.contains("file://") + || REFERENCE_LINK_URL.is_match(s) } /// Given the span, rewrite the missing comment inside it if available. diff --git a/tests/target/issue-5095.rs b/tests/target/issue-5095.rs new file mode 100644 index 000000000000..6981a65808c9 --- /dev/null +++ b/tests/target/issue-5095.rs @@ -0,0 +1,27 @@ +// rustfmt-wrap_comments: true + +pub mod a_long_name { + pub mod b_long_name { + pub mod c_long_name { + pub mod d_long_name { + pub mod e_long_name { + pub struct Bananas; + impl Bananas { + pub fn fantastic() {} + } + + pub mod f_long_name { + pub struct Apples; + } + } + } + } + } +} + +/// Check out [my other struct] ([`Bananas`]) and [the method it has]. +/// +/// [my other struct]: a_long_name::b_long_name::c_long_name::d_long_name::e_long_name::f_long_name::Apples +/// [`Bananas`]: a_long_name::b_long_name::c_long_name::d_long_name::e_long_name::Bananas::fantastic() +/// [the method it has]: a_long_name::b_long_name::c_long_name::d_long_name::e_long_name::Bananas::fantastic() +pub struct A; From 243cec7a0b9cc0ba3fba6e5ed849b0635f3496db Mon Sep 17 00:00:00 2001 From: Fabian Keller Date: Wed, 24 Nov 2021 10:38:55 +0100 Subject: [PATCH 102/111] Update README.md --- README.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index b3d21e6fb87c..b3a968f0c043 100644 --- a/README.md +++ b/README.md @@ -48,12 +48,11 @@ cargo +nightly fmt ## Limitations Rustfmt tries to work on as much Rust code as possible. Sometimes, the code -doesn't even need to compile! As we approach a 1.0 release we are also looking -to limit areas of instability; in particular, post-1.0, the formatting of most -code should not change as Rustfmt improves. However, there are some things that -Rustfmt can't do or can't do well (and thus where formatting might change -significantly, even post-1.0). We would like to reduce the list of limitations -over time. +doesn't even need to compile! In general, we are looking to limit areas of +instability; in particular, post-1.0, the formatting of most code should not +change as Rustfmt improves. However, there are some things that Rustfmt can't +do or can't do well (and thus where formatting might change significantly, +even post-1.0). We would like to reduce the list of limitations over time. The following list enumerates areas where Rustfmt does not work or where the stability guarantees do not apply (we don't make a distinction between the two From ea042b90c9b66cf5431acddd29e54468c05ea65b Mon Sep 17 00:00:00 2001 From: mujpao Date: Wed, 24 Nov 2021 15:05:23 -0800 Subject: [PATCH 103/111] Add more tests for comments in lists --- .../wrap-comments-not-normalized.rs | 21 ++++ .../wrap-comments-true.rs | 21 ++++ .../comments-in-lists/format-doc-comments.rs | 96 +++++++++++++++++++ .../wrap-comments-false.rs | 13 +++ .../wrap-comments-not-normalized.rs | 24 +++++ .../wrap-comments-true.rs | 24 +++++ 6 files changed, 199 insertions(+) rename tests/source/{issue-4909 => comments-in-lists}/wrap-comments-not-normalized.rs (81%) rename tests/source/{issue-4909 => comments-in-lists}/wrap-comments-true.rs (81%) create mode 100644 tests/target/comments-in-lists/format-doc-comments.rs rename tests/target/{issue-4909 => comments-in-lists}/wrap-comments-false.rs (82%) rename tests/target/{issue-4909 => comments-in-lists}/wrap-comments-not-normalized.rs (81%) rename tests/target/{issue-4909 => comments-in-lists}/wrap-comments-true.rs (81%) diff --git a/tests/source/issue-4909/wrap-comments-not-normalized.rs b/tests/source/comments-in-lists/wrap-comments-not-normalized.rs similarity index 81% rename from tests/source/issue-4909/wrap-comments-not-normalized.rs rename to tests/source/comments-in-lists/wrap-comments-not-normalized.rs index cd8de2707f16..b96c02802d69 100644 --- a/tests/source/issue-4909/wrap-comments-not-normalized.rs +++ b/tests/source/comments-in-lists/wrap-comments-not-normalized.rs @@ -1,5 +1,6 @@ // rustfmt-wrap_comments: true +// https://github.com/rust-lang/rustfmt/issues/4909 pub enum E { // Expand as needed, numbers should be ascending according to the stage // through the inclusion pipeline, or according to the descriptions @@ -105,4 +106,24 @@ fn main() { 2, // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions ]; + + // https://github.com/rust-lang/rustfmt/issues/4430 + match a { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + b => c, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + d => e, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + } + + match a { + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + b => c, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + d => e, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + } } diff --git a/tests/source/issue-4909/wrap-comments-true.rs b/tests/source/comments-in-lists/wrap-comments-true.rs similarity index 81% rename from tests/source/issue-4909/wrap-comments-true.rs rename to tests/source/comments-in-lists/wrap-comments-true.rs index f18d8d686e1f..360b838520ed 100644 --- a/tests/source/issue-4909/wrap-comments-true.rs +++ b/tests/source/comments-in-lists/wrap-comments-true.rs @@ -1,6 +1,7 @@ // rustfmt-normalize_comments: true // rustfmt-wrap_comments: true +// https://github.com/rust-lang/rustfmt/issues/4909 pub enum E { // Expand as needed, numbers should be ascending according to the stage // through the inclusion pipeline, or according to the descriptions @@ -106,4 +107,24 @@ fn main() { 2, // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions ]; + + // https://github.com/rust-lang/rustfmt/issues/4430 + match a { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + b => c, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + d => e, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + } + + match a { + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + b => c, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + d => e, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + } } diff --git a/tests/target/comments-in-lists/format-doc-comments.rs b/tests/target/comments-in-lists/format-doc-comments.rs new file mode 100644 index 000000000000..be31bf0a3319 --- /dev/null +++ b/tests/target/comments-in-lists/format-doc-comments.rs @@ -0,0 +1,96 @@ +// rustfmt-format_code_in_doc_comments: true + +// https://github.com/rust-lang/rustfmt/issues/4420 +enum Minimal { + Example, + //[thisisremoved thatsleft + // canbeanything +} + +struct Minimal2 { + Example: usize, + //[thisisremoved thatsleft + // canbeanything +} + +pub enum E { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + Variant1, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + Variant2, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +} + +pub enum E2 { + // This can be changed once https://github.com/rust-lang/rustfmt/issues/4854 is fixed +// Expand as needed, numbers should be ascending according to the stage +// through the inclusion pipeline, or according to the descriptions +} + +pub struct S { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + some_field: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + last_field: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +} + +pub struct S2 { + // This can be changed once https://github.com/rust-lang/rustfmt/issues/4854 is fixed +// Expand as needed, numbers should be ascending according to the stage +// through the inclusion pipeline, or according to the descriptions +} + +fn foo( + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + a: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + b: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +) -> usize { + 5 +} + +fn foo2(// Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +) -> usize { + 5 +} + +fn main() { + let v = vec![ + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + 1, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + 2, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + ]; + + let v2: Vec = vec![ + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + ]; + + match a { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + b => c, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + d => e, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + } +} diff --git a/tests/target/issue-4909/wrap-comments-false.rs b/tests/target/comments-in-lists/wrap-comments-false.rs similarity index 82% rename from tests/target/issue-4909/wrap-comments-false.rs rename to tests/target/comments-in-lists/wrap-comments-false.rs index a8ead584f445..80aea59d1b52 100644 --- a/tests/target/issue-4909/wrap-comments-false.rs +++ b/tests/target/comments-in-lists/wrap-comments-false.rs @@ -1,5 +1,6 @@ // rustfmt-normalize_comments: true +// https://github.com/rust-lang/rustfmt/issues/4909 pub enum E { // Expand as needed, numbers should be ascending according to the stage // through the inclusion pipeline, or according to the descriptions @@ -69,4 +70,16 @@ fn main() { // Expand as needed, numbers should be ascending according to the stage // through the inclusion pipeline, or according to the descriptions ]; + + // https://github.com/rust-lang/rustfmt/issues/4430 + match a { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + b => c, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + d => e, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + } } diff --git a/tests/target/issue-4909/wrap-comments-not-normalized.rs b/tests/target/comments-in-lists/wrap-comments-not-normalized.rs similarity index 81% rename from tests/target/issue-4909/wrap-comments-not-normalized.rs rename to tests/target/comments-in-lists/wrap-comments-not-normalized.rs index 2a3d803b3b1e..52315f470e4b 100644 --- a/tests/target/issue-4909/wrap-comments-not-normalized.rs +++ b/tests/target/comments-in-lists/wrap-comments-not-normalized.rs @@ -1,5 +1,6 @@ // rustfmt-wrap_comments: true +// https://github.com/rust-lang/rustfmt/issues/4909 pub enum E { // Expand as needed, numbers should be ascending according to the stage // through the inclusion pipeline, or according to the descriptions @@ -115,4 +116,27 @@ fn main() { // Expand as needed, numbers should be ascending according to the stage through the // inclusion pipeline, or according to the descriptions ]; + + // https://github.com/rust-lang/rustfmt/issues/4430 + match a { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + b => c, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + d => e, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + } + + match a { + // Expand as needed, numbers should be ascending according to the stage through the + // inclusion pipeline, or according to the descriptions + b => c, + // Expand as needed, numbers should be ascending according to the stage through the + // inclusion pipeline, or according to the descriptions + d => e, + // Expand as needed, numbers should be ascending according to the stage through the + // inclusion pipeline, or according to the descriptions + } } diff --git a/tests/target/issue-4909/wrap-comments-true.rs b/tests/target/comments-in-lists/wrap-comments-true.rs similarity index 81% rename from tests/target/issue-4909/wrap-comments-true.rs rename to tests/target/comments-in-lists/wrap-comments-true.rs index 5376962a2ee4..e0bfcf0b5007 100644 --- a/tests/target/issue-4909/wrap-comments-true.rs +++ b/tests/target/comments-in-lists/wrap-comments-true.rs @@ -1,6 +1,7 @@ // rustfmt-normalize_comments: true // rustfmt-wrap_comments: true +// https://github.com/rust-lang/rustfmt/issues/4909 pub enum E { // Expand as needed, numbers should be ascending according to the stage // through the inclusion pipeline, or according to the descriptions @@ -116,4 +117,27 @@ fn main() { // Expand as needed, numbers should be ascending according to the stage through the // inclusion pipeline, or according to the descriptions ]; + + // https://github.com/rust-lang/rustfmt/issues/4430 + match a { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + b => c, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + d => e, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + } + + match a { + // Expand as needed, numbers should be ascending according to the stage through the + // inclusion pipeline, or according to the descriptions + b => c, + // Expand as needed, numbers should be ascending according to the stage through the + // inclusion pipeline, or according to the descriptions + d => e, + // Expand as needed, numbers should be ascending according to the stage through the + // inclusion pipeline, or according to the descriptions + } } From 67fd9ec3002d269c272f68fa0e34a1cb2ca5fd08 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Wed, 24 Nov 2021 03:35:01 -0500 Subject: [PATCH 104/111] Run Windows, Linux, and Mac CI tests with nightly and stable channels --- .github/workflows/linux.yml | 5 ++++- .github/workflows/mac.yml | 5 ++++- .github/workflows/windows.yml | 5 ++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 6eaae69c7080..db4979416421 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -8,7 +8,9 @@ on: jobs: test: runs-on: ubuntu-latest - name: (${{ matrix.target }}, nightly) + name: (${{ matrix.target }}, ${{ matrix.cfg_release_channel }}) + env: + CFG_RELEASE_CHANNEL: ${{ matrix.cfg_release_channel }} strategy: # https://help.github.com/en/actions/getting-started-with-github-actions/about-github-actions#usage-limits # There's a limit of 60 concurrent jobs across all repos in the rust-lang organization. @@ -20,6 +22,7 @@ jobs: target: [ x86_64-unknown-linux-gnu, ] + cfg_release_channel: [nightly, stable] steps: - name: checkout diff --git a/.github/workflows/mac.yml b/.github/workflows/mac.yml index 79e4f69163e0..55e1cc9539b8 100644 --- a/.github/workflows/mac.yml +++ b/.github/workflows/mac.yml @@ -10,13 +10,16 @@ jobs: # https://help.github.com/en/actions/automating-your-workflow-with-github-actions/virtual-environments-for-github-hosted-runners#supported-runners-and-hardware-resources # macOS Catalina 10.15 runs-on: macos-latest - name: (${{ matrix.target }}, nightly) + name: (${{ matrix.target }}, ${{ matrix.cfg_release_channel }}) + env: + CFG_RELEASE_CHANNEL: ${{ matrix.cfg_release_channel }} strategy: fail-fast: false matrix: target: [ x86_64-apple-darwin, ] + cfg_release_channel: [nightly, stable] steps: - name: checkout diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index c05e8d4896ac..dcb08b5412ea 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -8,7 +8,9 @@ on: jobs: test: runs-on: windows-latest - name: (${{ matrix.target }}, nightly) + name: (${{ matrix.target }}, ${{ matrix.cfg_release_channel }}) + env: + CFG_RELEASE_CHANNEL: ${{ matrix.cfg_release_channel }} strategy: # https://help.github.com/en/actions/getting-started-with-github-actions/about-github-actions#usage-limits # There's a limit of 60 concurrent jobs across all repos in the rust-lang organization. @@ -23,6 +25,7 @@ jobs: x86_64-pc-windows-gnu, x86_64-pc-windows-msvc, ] + cfg_release_channel: [nightly, stable] steps: # The Windows runners have autocrlf enabled by default From a21f1b6c2a5734f39a1efe3fa84d6475843d14fe Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Sat, 27 Nov 2021 17:14:15 -0500 Subject: [PATCH 105/111] Conditionally compile tests based on CFG_RELEASE_CHANNEL env var Adds the ``nightly_only_test`` and ``stable_only_test`` attribute macros that prevent or allow certain tests to compile on nightly and stable respectively. This is achieved through conditionally outputting the tests TokenStream. If CFG_RELEASE_CHANNEL is not set, it's assumed that we're running in a nightly environment. To mark a test as nightly only: #[nightly_only_test] #[test] fn only_run_on_nightly() { ... } To mark a test a stable only: #[stable_only_test] #[test] fn only_run_on_stable() { ... } --- config_proc_macro/src/lib.rs | 42 ++++++++++++++++++ src/config/mod.rs | 82 +++++++++++++++--------------------- src/syntux/session.rs | 15 +++---- src/test/mod.rs | 13 +++--- 4 files changed, 86 insertions(+), 66 deletions(-) diff --git a/config_proc_macro/src/lib.rs b/config_proc_macro/src/lib.rs index 78e7e098ed9e..513018213192 100644 --- a/config_proc_macro/src/lib.rs +++ b/config_proc_macro/src/lib.rs @@ -8,6 +8,8 @@ mod item_enum; mod item_struct; mod utils; +use std::str::FromStr; + use proc_macro::TokenStream; use syn::parse_macro_input; @@ -23,3 +25,43 @@ pub fn config_type(_args: TokenStream, input: TokenStream) -> TokenStream { TokenStream::from(output) } + +/// Used to conditionally output the TokenStream for tests that need to be run on nightly only. +/// +/// ```rust +/// #[nightly_only_test] +/// #[test] +/// fn test_needs_nightly_rustfmt() { +/// assert!(true); +/// } +/// ``` +#[proc_macro_attribute] +pub fn nightly_only_test(_args: TokenStream, input: TokenStream) -> TokenStream { + // if CFG_RELEASE_CHANNEL is not set we default to nightly, hence why the default is true + if option_env!("CFG_RELEASE_CHANNEL").map_or(true, |c| c == "nightly" || c == "dev") { + input + } else { + // output an empty token stream if CFG_RELEASE_CHANNEL is not set to "nightly" or "dev" + TokenStream::from_str("").unwrap() + } +} + +/// Used to conditionally output the TokenStream for tests that need to be run on stable only. +/// +/// ```rust +/// #[stable_only_test] +/// #[test] +/// fn test_needs_stable_rustfmt() { +/// assert!(true); +/// } +/// ``` +#[proc_macro_attribute] +pub fn stable_only_test(_args: TokenStream, input: TokenStream) -> TokenStream { + // if CFG_RELEASE_CHANNEL is not set we default to nightly, hence why the default is false + if option_env!("CFG_RELEASE_CHANNEL").map_or(false, |c| c == "stable") { + input + } else { + // output an empty token stream if CFG_RELEASE_CHANNEL is not set or is not 'stable' + TokenStream::from_str("").unwrap() + } +} diff --git a/src/config/mod.rs b/src/config/mod.rs index c5419d860c94..5dbe532ac388 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -405,6 +405,8 @@ mod test { use super::*; use std::str; + use rustfmt_config_proc_macro::{nightly_only_test, stable_only_test}; + #[allow(dead_code)] mod mock { use super::super::*; @@ -525,21 +527,17 @@ mod test { assert!(config.license_template.is_none()); } + #[nightly_only_test] #[test] fn test_valid_license_template_path() { - if !crate::is_nightly_channel!() { - return; - } let toml = r#"license_template_path = "tests/license-template/lt.txt""#; let config = Config::from_toml(toml, Path::new("")).unwrap(); assert!(config.license_template.is_some()); } + #[nightly_only_test] #[test] fn test_override_existing_license_with_no_license() { - if !crate::is_nightly_channel!() { - return; - } let toml = r#"license_template_path = "tests/license-template/lt.txt""#; let mut config = Config::from_toml(toml, Path::new("")).unwrap(); assert!(config.license_template.is_some()); @@ -634,48 +632,42 @@ make_backup = false assert_eq!(&toml, &default_config); } - // FIXME(#2183): these tests cannot be run in parallel because they use env vars. - // #[test] - // fn test_as_not_nightly_channel() { - // let mut config = Config::default(); - // assert_eq!(config.was_set().unstable_features(), false); - // config.set().unstable_features(true); - // assert_eq!(config.was_set().unstable_features(), false); - // } + #[stable_only_test] + #[test] + fn test_as_not_nightly_channel() { + let mut config = Config::default(); + assert_eq!(config.was_set().unstable_features(), false); + config.set().unstable_features(true); + assert_eq!(config.was_set().unstable_features(), false); + } - // #[test] - // fn test_as_nightly_channel() { - // let v = ::std::env::var("CFG_RELEASE_CHANNEL").unwrap_or(String::from("")); - // ::std::env::set_var("CFG_RELEASE_CHANNEL", "nightly"); - // let mut config = Config::default(); - // config.set().unstable_features(true); - // assert_eq!(config.was_set().unstable_features(), false); - // config.set().unstable_features(true); - // assert_eq!(config.unstable_features(), true); - // ::std::env::set_var("CFG_RELEASE_CHANNEL", v); - // } + #[nightly_only_test] + #[test] + fn test_as_nightly_channel() { + let mut config = Config::default(); + config.set().unstable_features(true); + // When we don't set the config from toml or command line options it + // doesn't get marked as set by the user. + assert_eq!(config.was_set().unstable_features(), false); + config.set().unstable_features(true); + assert_eq!(config.unstable_features(), true); + } - // #[test] - // fn test_unstable_from_toml() { - // let mut config = Config::from_toml("unstable_features = true").unwrap(); - // assert_eq!(config.was_set().unstable_features(), false); - // let v = ::std::env::var("CFG_RELEASE_CHANNEL").unwrap_or(String::from("")); - // ::std::env::set_var("CFG_RELEASE_CHANNEL", "nightly"); - // config = Config::from_toml("unstable_features = true").unwrap(); - // assert_eq!(config.was_set().unstable_features(), true); - // assert_eq!(config.unstable_features(), true); - // ::std::env::set_var("CFG_RELEASE_CHANNEL", v); - // } + #[nightly_only_test] + #[test] + fn test_unstable_from_toml() { + let config = Config::from_toml("unstable_features = true", Path::new("")).unwrap(); + assert_eq!(config.was_set().unstable_features(), true); + assert_eq!(config.unstable_features(), true); + } #[cfg(test)] mod deprecated_option_merge_imports { use super::*; + #[nightly_only_test] #[test] fn test_old_option_set() { - if !crate::is_nightly_channel!() { - return; - } let toml = r#" unstable_features = true merge_imports = true @@ -684,11 +676,9 @@ make_backup = false assert_eq!(config.imports_granularity(), ImportGranularity::Crate); } + #[nightly_only_test] #[test] fn test_both_set() { - if !crate::is_nightly_channel!() { - return; - } let toml = r#" unstable_features = true merge_imports = true @@ -698,11 +688,9 @@ make_backup = false assert_eq!(config.imports_granularity(), ImportGranularity::Preserve); } + #[nightly_only_test] #[test] fn test_new_overridden() { - if !crate::is_nightly_channel!() { - return; - } let toml = r#" unstable_features = true merge_imports = true @@ -712,11 +700,9 @@ make_backup = false assert_eq!(config.imports_granularity(), ImportGranularity::Preserve); } + #[nightly_only_test] #[test] fn test_old_overridden() { - if !crate::is_nightly_channel!() { - return; - } let toml = r#" unstable_features = true imports_granularity = "Module" diff --git a/src/syntux/session.rs b/src/syntux/session.rs index cdb4893d443b..dd7c7352686e 100644 --- a/src/syntux/session.rs +++ b/src/syntux/session.rs @@ -286,10 +286,11 @@ impl LineRangeUtils for ParseSess { mod tests { use super::*; + use rustfmt_config_proc_macro::nightly_only_test; + mod emitter { use super::*; use crate::config::IgnoreList; - use crate::is_nightly_channel; use crate::utils::mk_sp; use rustc_span::{FileName as SourceMapFileName, MultiSpan, RealFileName, DUMMY_SP}; use std::path::PathBuf; @@ -371,11 +372,9 @@ mod tests { assert_eq!(can_reset_errors.load(Ordering::Acquire), false); } + #[nightly_only_test] #[test] fn handles_recoverable_parse_error_in_ignored_file() { - if !is_nightly_channel!() { - return; - } let num_emitted_errors = Lrc::new(AtomicU32::new(0)); let can_reset_errors = Lrc::new(AtomicBool::new(false)); let ignore_list = get_ignore_list(r#"ignore = ["foo.rs"]"#); @@ -398,11 +397,9 @@ mod tests { assert_eq!(can_reset_errors.load(Ordering::Acquire), true); } + #[nightly_only_test] #[test] fn handles_recoverable_parse_error_in_non_ignored_file() { - if !is_nightly_channel!() { - return; - } let num_emitted_errors = Lrc::new(AtomicU32::new(0)); let can_reset_errors = Lrc::new(AtomicBool::new(false)); let source_map = Lrc::new(SourceMap::new(FilePathMapping::empty())); @@ -424,11 +421,9 @@ mod tests { assert_eq!(can_reset_errors.load(Ordering::Acquire), false); } + #[nightly_only_test] #[test] fn handles_mix_of_recoverable_parse_error() { - if !is_nightly_channel!() { - return; - } let num_emitted_errors = Lrc::new(AtomicU32::new(0)); let can_reset_errors = Lrc::new(AtomicBool::new(false)); let source_map = Lrc::new(SourceMap::new(FilePathMapping::empty())); diff --git a/src/test/mod.rs b/src/test/mod.rs index e2620508c340..cceb28dfea6d 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -15,6 +15,8 @@ use crate::rustfmt_diff::{make_diff, print_diff, DiffLine, Mismatch, ModifiedChu use crate::source_file; use crate::{is_nightly_channel, FormatReport, FormatReportFormatterBuilder, Input, Session}; +use rustfmt_config_proc_macro::nightly_only_test; + mod configuration_snippet; mod mod_resolver; mod parser; @@ -307,14 +309,11 @@ fn assert_output(source: &Path, expected_filename: &Path) { // Idempotence tests. Files in tests/target are checked to be unaltered by // rustfmt. +#[nightly_only_test] #[test] fn idempotence_tests() { init_log(); run_test_with(&TestSetting::default(), || { - // these tests require nightly - if !is_nightly_channel!() { - return; - } // Get all files in the tests/target directory. let files = get_test_files(Path::new("tests/target"), true); let (_reports, count, fails) = check_files(files, &None); @@ -332,13 +331,11 @@ fn idempotence_tests() { // Run rustfmt on itself. This operation must be idempotent. We also check that // no warnings are emitted. +// Issue-3443: these tests require nightly +#[nightly_only_test] #[test] fn self_tests() { init_log(); - // Issue-3443: these tests require nightly - if !is_nightly_channel!() { - return; - } let mut files = get_test_files(Path::new("tests"), false); let bin_directories = vec!["cargo-fmt", "git-rustfmt", "bin", "format-diff"]; for dir in bin_directories { From 0fc846f979bc20d556cc07177b384094a421c54c Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Sun, 28 Nov 2021 15:22:49 -0600 Subject: [PATCH 106/111] refactor: maintain more AST info when formatting a RHS --- src/expr.rs | 57 +++++++++++++++++++++++++++++++++++++++++++-------- src/items.rs | 38 +++++++++++++++++++++++++++------- src/macros.rs | 5 +++-- src/types.rs | 5 +++-- 4 files changed, 86 insertions(+), 19 deletions(-) diff --git a/src/expr.rs b/src/expr.rs index 58942e442de0..5fd86c1a4ead 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -196,9 +196,10 @@ pub(crate) fn format_expr( capture, is_async, movability, fn_decl, body, expr.span, context, shape, ) } - ast::ExprKind::Try(..) | ast::ExprKind::Field(..) | ast::ExprKind::MethodCall(..) => { - rewrite_chain(expr, context, shape) - } + ast::ExprKind::Try(..) + | ast::ExprKind::Field(..) + | ast::ExprKind::MethodCall(..) + | ast::ExprKind::Await(_) => rewrite_chain(expr, context, shape), ast::ExprKind::MacCall(ref mac) => { rewrite_macro(mac, None, context, shape, MacroPosition::Expression).or_else(|| { wrap_str( @@ -377,7 +378,6 @@ pub(crate) fn format_expr( )) } } - ast::ExprKind::Await(_) => rewrite_chain(expr, context, shape), ast::ExprKind::Underscore => Some("_".to_owned()), ast::ExprKind::Err => None, }; @@ -829,6 +829,7 @@ impl<'a> ControlFlow<'a> { &format!("{}{}{}", matcher, pat_string, self.connector), expr, cond_shape, + &RhsAssignKind::Expr(&expr.kind, expr.span), RhsTactics::Default, comments_span, true, @@ -1839,6 +1840,34 @@ fn rewrite_unary_op( rewrite_unary_prefix(context, ast::UnOp::to_string(op), expr, shape) } +pub(crate) enum RhsAssignKind<'ast> { + Expr(&'ast ast::ExprKind, Span), + Bounds, + Ty, +} + +impl<'ast> RhsAssignKind<'ast> { + // TODO(calebcartwright) + // Preemptive addition for handling RHS with chains, not yet utilized. + // It may make more sense to construct the chain first and then check + // whether there are actually chain elements. + #[allow(dead_code)] + fn is_chain(&self) -> bool { + match self { + RhsAssignKind::Expr(kind, _) => { + matches!( + kind, + ast::ExprKind::Try(..) + | ast::ExprKind::Field(..) + | ast::ExprKind::MethodCall(..) + | ast::ExprKind::Await(_) + ) + } + _ => false, + } + } +} + fn rewrite_assignment( context: &RewriteContext<'_>, lhs: &ast::Expr, @@ -1855,7 +1884,13 @@ fn rewrite_assignment( let lhs_shape = shape.sub_width(operator_str.len() + 1)?; let lhs_str = format!("{} {}", lhs.rewrite(context, lhs_shape)?, operator_str); - rewrite_assign_rhs(context, lhs_str, rhs, shape) + rewrite_assign_rhs( + context, + lhs_str, + rhs, + &RhsAssignKind::Expr(&rhs.kind, rhs.span), + shape, + ) } /// Controls where to put the rhs. @@ -1876,9 +1911,10 @@ pub(crate) fn rewrite_assign_rhs, R: Rewrite>( context: &RewriteContext<'_>, lhs: S, ex: &R, + rhs_kind: &RhsAssignKind<'_>, shape: Shape, ) -> Option { - rewrite_assign_rhs_with(context, lhs, ex, shape, RhsTactics::Default) + rewrite_assign_rhs_with(context, lhs, ex, shape, rhs_kind, RhsTactics::Default) } pub(crate) fn rewrite_assign_rhs_expr( @@ -1886,6 +1922,7 @@ pub(crate) fn rewrite_assign_rhs_expr( lhs: &str, ex: &R, shape: Shape, + rhs_kind: &RhsAssignKind<'_>, rhs_tactics: RhsTactics, ) -> Option { let last_line_width = last_line_width(lhs).saturating_sub(if lhs.contains('\n') { @@ -1910,6 +1947,7 @@ pub(crate) fn rewrite_assign_rhs_expr( ex, orig_shape, ex.rewrite(context, orig_shape), + rhs_kind, rhs_tactics, has_rhs_comment, ) @@ -1920,10 +1958,11 @@ pub(crate) fn rewrite_assign_rhs_with, R: Rewrite>( lhs: S, ex: &R, shape: Shape, + rhs_kind: &RhsAssignKind<'_>, rhs_tactics: RhsTactics, ) -> Option { let lhs = lhs.into(); - let rhs = rewrite_assign_rhs_expr(context, &lhs, ex, shape, rhs_tactics)?; + let rhs = rewrite_assign_rhs_expr(context, &lhs, ex, shape, rhs_kind, rhs_tactics)?; Some(lhs + &rhs) } @@ -1932,6 +1971,7 @@ pub(crate) fn rewrite_assign_rhs_with_comments, R: Rewrite>( lhs: S, ex: &R, shape: Shape, + rhs_kind: &RhsAssignKind<'_>, rhs_tactics: RhsTactics, between_span: Span, allow_extend: bool, @@ -1943,7 +1983,7 @@ pub(crate) fn rewrite_assign_rhs_with_comments, R: Rewrite>( } else { shape }; - let rhs = rewrite_assign_rhs_expr(context, &lhs, ex, shape, rhs_tactics)?; + let rhs = rewrite_assign_rhs_expr(context, &lhs, ex, shape, rhs_kind, rhs_tactics)?; if contains_comment { let rhs = rhs.trim_start(); @@ -1958,6 +1998,7 @@ fn choose_rhs( expr: &R, shape: Shape, orig_rhs: Option, + _rhs_kind: &RhsAssignKind<'_>, rhs_tactics: RhsTactics, has_rhs_comment: bool, ) -> Option { diff --git a/src/items.rs b/src/items.rs index 63c32e012df7..3fe827ce696d 100644 --- a/src/items.rs +++ b/src/items.rs @@ -18,7 +18,7 @@ use crate::config::lists::*; use crate::config::{BraceStyle, Config, IndentStyle, Version}; use crate::expr::{ is_empty_block, is_simple_block_stmt, rewrite_assign_rhs, rewrite_assign_rhs_with, - rewrite_assign_rhs_with_comments, RhsTactics, + rewrite_assign_rhs_with_comments, RhsAssignKind, RhsTactics, }; use crate::lists::{definitive_tactic, itemize_list, write_list, ListFormatting, Separator}; use crate::macros::{rewrite_macro, MacroPosition}; @@ -116,7 +116,13 @@ impl Rewrite for ast::Local { // 1 = trailing semicolon; let nested_shape = shape.sub_width(1)?; - result = rewrite_assign_rhs(context, result, init, nested_shape)?; + result = rewrite_assign_rhs( + context, + result, + init, + &RhsAssignKind::Expr(&init.kind, init.span), + nested_shape, + )?; // todo else } @@ -564,11 +570,13 @@ impl<'a> FmtVisitor<'a> { let variant_body = if let Some(ref expr) = field.disr_expr { let lhs = format!("{:1$} =", variant_body, pad_discrim_ident_to); + let ex = &*expr.value; rewrite_assign_rhs_with( &context, lhs, - &*expr.value, + ex, shape, + &RhsAssignKind::Expr(&ex.kind, ex.span), RhsTactics::AllowOverflow, )? } else { @@ -1033,6 +1041,7 @@ pub(crate) fn format_trait( result + ":", bounds, shape, + &RhsAssignKind::Bounds, RhsTactics::ForceNextLineWithoutIndent, )?; } @@ -1213,7 +1222,14 @@ pub(crate) fn format_trait_alias( generic_bounds, generics, }; - rewrite_assign_rhs(context, lhs, &trait_alias_bounds, shape.sub_width(1)?).map(|s| s + ";") + rewrite_assign_rhs( + context, + lhs, + &trait_alias_bounds, + &RhsAssignKind::Bounds, + shape.sub_width(1)?, + ) + .map(|s| s + ";") } fn format_unit_struct( @@ -1630,7 +1646,7 @@ fn rewrite_ty( // 1 = `;` let shape = Shape::indented(indent, context.config).sub_width(1)?; - rewrite_assign_rhs(context, lhs, &*ty, shape).map(|s| s + ";") + rewrite_assign_rhs(context, lhs, &*ty, &RhsAssignKind::Ty, shape).map(|s| s + ";") } else { Some(format!("{};", result)) } @@ -1720,7 +1736,7 @@ pub(crate) fn rewrite_struct_field( let is_prefix_empty = prefix.is_empty(); // We must use multiline. We are going to put attributes and a field on different lines. - let field_str = rewrite_assign_rhs(context, prefix, &*field.ty, shape)?; + let field_str = rewrite_assign_rhs(context, prefix, &*field.ty, &RhsAssignKind::Ty, shape)?; // Remove a leading white-space from `rewrite_assign_rhs()` when rewriting a tuple struct. let field_str = if is_prefix_empty { field_str.trim_start() @@ -1850,6 +1866,7 @@ fn rewrite_static( &lhs, &**expr, Shape::legacy(remaining_width, offset.block_only()), + &RhsAssignKind::Expr(&expr.kind, expr.span), RhsTactics::Default, comments_span, true, @@ -3147,7 +3164,14 @@ impl Rewrite for ast::ForeignItem { rewrite_ident(context, self.ident) ); // 1 = ; - rewrite_assign_rhs(context, prefix, &**ty, shape.sub_width(1)?).map(|s| s + ";") + rewrite_assign_rhs( + context, + prefix, + &**ty, + &RhsAssignKind::Ty, + shape.sub_width(1)?, + ) + .map(|s| s + ";") } ast::ForeignItemKind::TyAlias(ref ty_alias) => { let (kind, span) = (&ItemVisitorKind::ForeignItem(&self), self.span); diff --git a/src/macros.rs b/src/macros.rs index ef747638e33e..a52568be9eac 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -27,7 +27,7 @@ use crate::comment::{ contains_comment, CharClasses, FindUncommented, FullCodeCharKind, LineClasses, }; use crate::config::lists::*; -use crate::expr::rewrite_array; +use crate::expr::{rewrite_array, rewrite_assign_rhs, RhsAssignKind}; use crate::lists::{itemize_list, write_list, ListFormatting}; use crate::overflow; use crate::rewrite::{Rewrite, RewriteContext}; @@ -1468,10 +1468,11 @@ fn format_lazy_static( id, ty.rewrite(context, nested_shape)? )); - result.push_str(&crate::expr::rewrite_assign_rhs( + result.push_str(&rewrite_assign_rhs( context, stmt, &*expr, + &RhsAssignKind::Expr(&expr.kind, expr.span), nested_shape.sub_width(1)?, )?); result.push(';'); diff --git a/src/types.rs b/src/types.rs index 891609783b61..88f5dc432451 100644 --- a/src/types.rs +++ b/src/types.rs @@ -10,6 +10,7 @@ use crate::config::lists::*; use crate::config::{IndentStyle, TypeDensity, Version}; use crate::expr::{ format_expr, rewrite_assign_rhs, rewrite_call, rewrite_tuple, rewrite_unary_prefix, ExprType, + RhsAssignKind, }; use crate::lists::{ definitive_tactic, itemize_list, write_list, ListFormatting, ListItem, Separator, @@ -430,7 +431,7 @@ impl Rewrite for ast::WherePredicate { format!("{}{}", type_str, colon) }; - rewrite_assign_rhs(context, lhs, bounds, shape)? + rewrite_assign_rhs(context, lhs, bounds, &RhsAssignKind::Bounds, shape)? } ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate { ref lifetime, @@ -443,7 +444,7 @@ impl Rewrite for ast::WherePredicate { .. }) => { let lhs_ty_str = lhs_ty.rewrite(context, shape).map(|lhs| lhs + " =")?; - rewrite_assign_rhs(context, lhs_ty_str, &**rhs_ty, shape)? + rewrite_assign_rhs(context, lhs_ty_str, &**rhs_ty, &RhsAssignKind::Ty, shape)? } }; From 1f28683ffacebc91b3bc47b94c56690633226ff9 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Sun, 28 Nov 2021 23:39:31 -0500 Subject: [PATCH 107/111] Update nightly only test with #[nightly_only_test] attribute --- src/ignore_path.rs | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/ignore_path.rs b/src/ignore_path.rs index d8974e12b8f5..7738eee0a760 100644 --- a/src/ignore_path.rs +++ b/src/ignore_path.rs @@ -37,21 +37,17 @@ mod test { use crate::config::{Config, FileName}; use crate::ignore_path::IgnorePathSet; + use rustfmt_config_proc_macro::nightly_only_test; + + #[nightly_only_test] #[test] fn test_ignore_path_set() { - match option_env!("CFG_RELEASE_CHANNEL") { - // this test requires nightly - None | Some("nightly") => { - let config = - Config::from_toml(r#"ignore = ["foo.rs", "bar_dir/*"]"#, Path::new("")) - .unwrap(); - let ignore_path_set = IgnorePathSet::from_ignore_list(&config.ignore()).unwrap(); + let config = + Config::from_toml(r#"ignore = ["foo.rs", "bar_dir/*"]"#, Path::new("")).unwrap(); + let ignore_path_set = IgnorePathSet::from_ignore_list(&config.ignore()).unwrap(); - assert!(ignore_path_set.is_match(&FileName::Real(PathBuf::from("src/foo.rs")))); - assert!(ignore_path_set.is_match(&FileName::Real(PathBuf::from("bar_dir/baz.rs")))); - assert!(!ignore_path_set.is_match(&FileName::Real(PathBuf::from("src/bar.rs")))); - } - _ => (), - }; + assert!(ignore_path_set.is_match(&FileName::Real(PathBuf::from("src/foo.rs")))); + assert!(ignore_path_set.is_match(&FileName::Real(PathBuf::from("bar_dir/baz.rs")))); + assert!(!ignore_path_set.is_match(&FileName::Real(PathBuf::from("src/bar.rs")))); } } From ec46ffd981d3d50572f1ad3f6033a7c33d27033f Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Fri, 19 Nov 2021 18:52:52 -0500 Subject: [PATCH 108/111] Determine when new comment lines are needed for itemized blocks Fixes 5088 Previously, rustfmt would add a new comment line anytime it reformatted an itemized block within a comment when ``wrap_comments=true``. This would lead to rustfmt adding empty comments with trailing whitespace. Now, new comment lines are only added if the original comment spanned multiple lines, if the comment needs to be wrapped, or if the comment originally started with an empty comment line. --- src/comment.rs | 43 +++++++++++++--- ..._nested_long_comment_wrap_comments_true.rs | 33 +++++++++++++ ..._long_itemized_block_wrap_comments_true.rs | 19 +++++++ .../very_long_comment_wrap_comments_true.rs | 13 +++++ ...nested_long_comment_wrap_comments_false.rs | 33 +++++++++++++ ..._nested_long_comment_wrap_comments_true.rs | 49 +++++++++++++++++++ ...line_itemized_block_wrap_comments_false.rs | 17 +++++++ ..._line_itemized_block_wrap_comments_true.rs | 17 +++++++ ...with_itemized_block_wrap_comments_false.rs | 37 ++++++++++++++ ..._with_itemized_block_wrap_comments_true.rs | 37 ++++++++++++++ ...line_itemized_block_wrap_comments_false.rs | 9 ++++ ..._line_itemized_block_wrap_comments_true.rs | 9 ++++ ...long_itemized_block_wrap_comments_false.rs | 19 +++++++ ..._long_itemized_block_wrap_comments_true.rs | 27 ++++++++++ ..._with_empty_comment_wrap_comments_false.rs | 17 +++++++ ...t_with_empty_comment_wrap_comments_true.rs | 17 +++++++ .../very_long_comment_wrap_comments_false.rs | 13 +++++ .../very_long_comment_wrap_comments_true.rs | 21 ++++++++ 18 files changed, 424 insertions(+), 6 deletions(-) create mode 100644 tests/source/issue-5088/deeply_nested_long_comment_wrap_comments_true.rs create mode 100644 tests/source/issue-5088/start_with_empty_comment_very_long_itemized_block_wrap_comments_true.rs create mode 100644 tests/source/issue-5088/very_long_comment_wrap_comments_true.rs create mode 100644 tests/target/issue-5088/deeply_nested_long_comment_wrap_comments_false.rs create mode 100644 tests/target/issue-5088/deeply_nested_long_comment_wrap_comments_true.rs create mode 100644 tests/target/issue-5088/multi_line_itemized_block_wrap_comments_false.rs create mode 100644 tests/target/issue-5088/multi_line_itemized_block_wrap_comments_true.rs create mode 100644 tests/target/issue-5088/multi_line_text_with_itemized_block_wrap_comments_false.rs create mode 100644 tests/target/issue-5088/multi_line_text_with_itemized_block_wrap_comments_true.rs create mode 100644 tests/target/issue-5088/single_line_itemized_block_wrap_comments_false.rs create mode 100644 tests/target/issue-5088/single_line_itemized_block_wrap_comments_true.rs create mode 100644 tests/target/issue-5088/start_with_empty_comment_very_long_itemized_block_wrap_comments_false.rs create mode 100644 tests/target/issue-5088/start_with_empty_comment_very_long_itemized_block_wrap_comments_true.rs create mode 100644 tests/target/issue-5088/start_with_empty_comment_wrap_comments_false.rs create mode 100644 tests/target/issue-5088/start_with_empty_comment_wrap_comments_true.rs create mode 100644 tests/target/issue-5088/very_long_comment_wrap_comments_false.rs create mode 100644 tests/target/issue-5088/very_long_comment_wrap_comments_true.rs diff --git a/src/comment.rs b/src/comment.rs index 830d2b50aad8..0f850b9b2f2f 100644 --- a/src/comment.rs +++ b/src/comment.rs @@ -519,6 +519,7 @@ struct CommentRewrite<'a> { opener: String, closer: String, line_start: String, + style: CommentStyle<'a>, } impl<'a> CommentRewrite<'a> { @@ -528,10 +529,14 @@ impl<'a> CommentRewrite<'a> { shape: Shape, config: &'a Config, ) -> CommentRewrite<'a> { - let (opener, closer, line_start) = if block_style { - CommentStyle::SingleBullet.to_str_tuplet() + let ((opener, closer, line_start), style) = if block_style { + ( + CommentStyle::SingleBullet.to_str_tuplet(), + CommentStyle::SingleBullet, + ) } else { - comment_style(orig, config.normalize_comments()).to_str_tuplet() + let style = comment_style(orig, config.normalize_comments()); + (style.to_str_tuplet(), style) }; let max_width = shape @@ -564,6 +569,7 @@ impl<'a> CommentRewrite<'a> { opener: opener.to_owned(), closer: closer.to_owned(), line_start: line_start.to_owned(), + style, }; cr.result.push_str(opener); cr @@ -583,6 +589,15 @@ impl<'a> CommentRewrite<'a> { result } + /// Check if any characters were written to the result buffer after the start of the comment. + /// when calling [`CommentRewrite::new()`] the result buffer is initiazlied with the opening + /// characters for the comment. + fn buffer_contains_comment(&self) -> bool { + // if self.result.len() < self.opener.len() then an empty comment is in the buffer + // if self.result.len() > self.opener.len() then a non empty comment is in the buffer + self.result.len() != self.opener.len() + } + fn finish(mut self) -> String { if !self.code_block_buffer.is_empty() { // There is a code block that is not properly enclosed by backticks. @@ -598,7 +613,12 @@ impl<'a> CommentRewrite<'a> { // the last few lines are part of an itemized block self.fmt.shape = Shape::legacy(self.max_width, self.fmt_indent); let item_fmt = ib.create_string_format(&self.fmt); - self.result.push_str(&self.comment_line_separator); + + // only push a comment_line_separator for ItemizedBlocks if the comment is not empty + if self.buffer_contains_comment() { + self.result.push_str(&self.comment_line_separator); + } + self.result.push_str(&ib.opener); match rewrite_string( &ib.trimmed_block_as_string(), @@ -632,7 +652,13 @@ impl<'a> CommentRewrite<'a> { line: &'a str, has_leading_whitespace: bool, ) -> bool { - let is_last = i == count_newlines(orig); + let num_newlines = count_newlines(orig); + let is_last = i == num_newlines; + let needs_new_comment_line = if self.style.is_block_comment() { + num_newlines > 0 || self.buffer_contains_comment() + } else { + self.buffer_contains_comment() + }; if let Some(ref mut ib) = self.item_block { if ib.add_line(line) { @@ -641,7 +667,12 @@ impl<'a> CommentRewrite<'a> { self.is_prev_line_multi_line = false; self.fmt.shape = Shape::legacy(self.max_width, self.fmt_indent); let item_fmt = ib.create_string_format(&self.fmt); - self.result.push_str(&self.comment_line_separator); + + // only push a comment_line_separator if we need to start a new comment line + if needs_new_comment_line { + self.result.push_str(&self.comment_line_separator); + } + self.result.push_str(&ib.opener); match rewrite_string( &ib.trimmed_block_as_string(), diff --git a/tests/source/issue-5088/deeply_nested_long_comment_wrap_comments_true.rs b/tests/source/issue-5088/deeply_nested_long_comment_wrap_comments_true.rs new file mode 100644 index 000000000000..09f68cae4240 --- /dev/null +++ b/tests/source/issue-5088/deeply_nested_long_comment_wrap_comments_true.rs @@ -0,0 +1,33 @@ +// rustfmt-wrap_comments: true + +fn main() { + { + { + { + { + { + { + { + { + { + { + { + // - aaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa bbbbbbbbbb bbbbbbbbb bbbbbbbbb ccc cccccccccc ccccccc cccccccc + + // * aaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa bbbbbbbbbb bbbbbbbbb bbbbbbbbb ccc cccccccccc ccccccc cccccccc + + /* - aaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa bbbbbbbbbb bbbbbbbbb bbbbbbbbb ccc cccccccccc ccccccc cccccccc */ + + /* * aaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa bbbbbbbbbb bbbbbbbbb bbbbbbbbb ccc cccccccccc ccccccc cccccccc */ + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; +} diff --git a/tests/source/issue-5088/start_with_empty_comment_very_long_itemized_block_wrap_comments_true.rs b/tests/source/issue-5088/start_with_empty_comment_very_long_itemized_block_wrap_comments_true.rs new file mode 100644 index 000000000000..75f748000f9b --- /dev/null +++ b/tests/source/issue-5088/start_with_empty_comment_very_long_itemized_block_wrap_comments_true.rs @@ -0,0 +1,19 @@ +// rustfmt-wrap_comments: true + +// +// - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +// - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + +// +// * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +// * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + +/* + * - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ +/* + * - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ + +/* + * * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ +/* + * * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ diff --git a/tests/source/issue-5088/very_long_comment_wrap_comments_true.rs b/tests/source/issue-5088/very_long_comment_wrap_comments_true.rs new file mode 100644 index 000000000000..00437f00216b --- /dev/null +++ b/tests/source/issue-5088/very_long_comment_wrap_comments_true.rs @@ -0,0 +1,13 @@ +// rustfmt-wrap_comments: true + +// - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +// - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + +// * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +// * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + +/* - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ +/* - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ + +/* * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ +/* * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ diff --git a/tests/target/issue-5088/deeply_nested_long_comment_wrap_comments_false.rs b/tests/target/issue-5088/deeply_nested_long_comment_wrap_comments_false.rs new file mode 100644 index 000000000000..f4801de01848 --- /dev/null +++ b/tests/target/issue-5088/deeply_nested_long_comment_wrap_comments_false.rs @@ -0,0 +1,33 @@ +// rustfmt-wrap_comments: false + +fn main() { + { + { + { + { + { + { + { + { + { + { + { + // - aaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa bbbbbbbbbb bbbbbbbbb bbbbbbbbb ccc cccccccccc ccccccc cccccccc + + // * aaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa bbbbbbbbbb bbbbbbbbb bbbbbbbbb ccc cccccccccc ccccccc cccccccc + + /* - aaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa bbbbbbbbbb bbbbbbbbb bbbbbbbbb ccc cccccccccc ccccccc cccccccc */ + + /* * aaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa bbbbbbbbbb bbbbbbbbb bbbbbbbbb ccc cccccccccc ccccccc cccccccc */ + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; +} diff --git a/tests/target/issue-5088/deeply_nested_long_comment_wrap_comments_true.rs b/tests/target/issue-5088/deeply_nested_long_comment_wrap_comments_true.rs new file mode 100644 index 000000000000..b289c9f859e0 --- /dev/null +++ b/tests/target/issue-5088/deeply_nested_long_comment_wrap_comments_true.rs @@ -0,0 +1,49 @@ +// rustfmt-wrap_comments: true + +fn main() { + { + { + { + { + { + { + { + { + { + { + { + // - aaaa aaaaaaaaa aaaaaaaaa + // aaaaaaaaa aaaaaaaaa + // bbbbbbbbbb bbbbbbbbb + // bbbbbbbbb ccc cccccccccc + // ccccccc cccccccc + + // * aaaa aaaaaaaaa aaaaaaaaa + // aaaaaaaaa aaaaaaaaa + // bbbbbbbbbb bbbbbbbbb + // bbbbbbbbb ccc cccccccccc + // ccccccc cccccccc + + /* - aaaa aaaaaaaaa aaaaaaaaa + * aaaaaaaaa aaaaaaaaa + * bbbbbbbbbb bbbbbbbbb + * bbbbbbbbb ccc cccccccccc + * ccccccc cccccccc */ + + /* * aaaa aaaaaaaaa aaaaaaaaa + * aaaaaaaaa aaaaaaaaa + * bbbbbbbbbb bbbbbbbbb + * bbbbbbbbb ccc cccccccccc + * ccccccc cccccccc */ + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; +} diff --git a/tests/target/issue-5088/multi_line_itemized_block_wrap_comments_false.rs b/tests/target/issue-5088/multi_line_itemized_block_wrap_comments_false.rs new file mode 100644 index 000000000000..60beed1b0482 --- /dev/null +++ b/tests/target/issue-5088/multi_line_itemized_block_wrap_comments_false.rs @@ -0,0 +1,17 @@ +// rustfmt-wrap_comments: false + +// - some itemized block 1 +// - some itemized block 2 + +// * some itemized block 3 +// * some itemized block 4 + +/* + * - some itemized block 5 + * - some itemized block 6 + */ + +/* + * * some itemized block 7 + * * some itemized block 8 + */ diff --git a/tests/target/issue-5088/multi_line_itemized_block_wrap_comments_true.rs b/tests/target/issue-5088/multi_line_itemized_block_wrap_comments_true.rs new file mode 100644 index 000000000000..84fba4b7c198 --- /dev/null +++ b/tests/target/issue-5088/multi_line_itemized_block_wrap_comments_true.rs @@ -0,0 +1,17 @@ +// rustfmt-wrap_comments: true + +// - some itemized block 1 +// - some itemized block 2 + +// * some itemized block 3 +// * some itemized block 4 + +/* + * - some itemized block 5 + * - some itemized block 6 + */ + +/* + * * some itemized block 7 + * * some itemized block 8 + */ diff --git a/tests/target/issue-5088/multi_line_text_with_itemized_block_wrap_comments_false.rs b/tests/target/issue-5088/multi_line_text_with_itemized_block_wrap_comments_false.rs new file mode 100644 index 000000000000..d1bf44f6c741 --- /dev/null +++ b/tests/target/issue-5088/multi_line_text_with_itemized_block_wrap_comments_false.rs @@ -0,0 +1,37 @@ +// rustfmt-wrap_comments: false + +// Some text +// - some itemized block 1 +// - some itemized block 2 +// Some more text +// - some itemized block 3 +// - some itemized block 4 +// Even more text + +// Some text +// * some itemized block 5 +// * some itemized block 6 +// Some more text +// * some itemized block 7 +// * some itemized block 8 +// Even more text + +/* + * Some text + * - some itemized block 9 + * - some itemized block 10 + * Some more text + * - some itemized block 11 + * - some itemized block 12 + * Even more text + */ + +/* + * Some text + * * some itemized block 13 + * * some itemized block 14 + * Some more text + * * some itemized block 15 + * * some itemized block 16 + * Even more text + */ diff --git a/tests/target/issue-5088/multi_line_text_with_itemized_block_wrap_comments_true.rs b/tests/target/issue-5088/multi_line_text_with_itemized_block_wrap_comments_true.rs new file mode 100644 index 000000000000..f767491f902d --- /dev/null +++ b/tests/target/issue-5088/multi_line_text_with_itemized_block_wrap_comments_true.rs @@ -0,0 +1,37 @@ +// rustfmt-wrap_comments: true + +// Some text +// - some itemized block 1 +// - some itemized block 2 +// Some more text +// - some itemized block 3 +// - some itemized block 4 +// Even more text + +// Some text +// * some itemized block 5 +// * some itemized block 6 +// Some more text +// * some itemized block 7 +// * some itemized block 8 +// Even more text + +/* + * Some text + * - some itemized block 9 + * - some itemized block 10 + * Some more text + * - some itemized block 11 + * - some itemized block 12 + * Even more text + */ + +/* + * Some text + * * some itemized block 13 + * * some itemized block 14 + * Some more text + * * some itemized block 15 + * * some itemized block 16 + * Even more text + */ diff --git a/tests/target/issue-5088/single_line_itemized_block_wrap_comments_false.rs b/tests/target/issue-5088/single_line_itemized_block_wrap_comments_false.rs new file mode 100644 index 000000000000..2cd85c787f97 --- /dev/null +++ b/tests/target/issue-5088/single_line_itemized_block_wrap_comments_false.rs @@ -0,0 +1,9 @@ +// rustfmt-wrap_comments: false + +// - some itemized block 1 + +// * some itemized block 2 + +/* - some itemized block 3 */ + +/* * some itemized block 4 */ diff --git a/tests/target/issue-5088/single_line_itemized_block_wrap_comments_true.rs b/tests/target/issue-5088/single_line_itemized_block_wrap_comments_true.rs new file mode 100644 index 000000000000..e9f343d75d5e --- /dev/null +++ b/tests/target/issue-5088/single_line_itemized_block_wrap_comments_true.rs @@ -0,0 +1,9 @@ +// rustfmt-wrap_comments: true + +// - some itemized block 1 + +// * some itemized block 2 + +/* - some itemized block 3 */ + +/* * some itemized block 4 */ diff --git a/tests/target/issue-5088/start_with_empty_comment_very_long_itemized_block_wrap_comments_false.rs b/tests/target/issue-5088/start_with_empty_comment_very_long_itemized_block_wrap_comments_false.rs new file mode 100644 index 000000000000..97bb7733d189 --- /dev/null +++ b/tests/target/issue-5088/start_with_empty_comment_very_long_itemized_block_wrap_comments_false.rs @@ -0,0 +1,19 @@ +// rustfmt-wrap_comments: false + +// +// - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +// - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + +// +// * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +// * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + +/* + * - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ +/* + * - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ + +/* + * * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ +/* + * * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ diff --git a/tests/target/issue-5088/start_with_empty_comment_very_long_itemized_block_wrap_comments_true.rs b/tests/target/issue-5088/start_with_empty_comment_very_long_itemized_block_wrap_comments_true.rs new file mode 100644 index 000000000000..c8af8383e058 --- /dev/null +++ b/tests/target/issue-5088/start_with_empty_comment_very_long_itemized_block_wrap_comments_true.rs @@ -0,0 +1,27 @@ +// rustfmt-wrap_comments: true + +// +// - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod +// tempor incididunt ut labore et dolore magna aliqua. +// - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod +// tempor incididunt ut labore et dolore magna aliqua. + +// +// * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod +// tempor incididunt ut labore et dolore magna aliqua. +// * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod +// tempor incididunt ut labore et dolore magna aliqua. + +/* + * - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod + * tempor incididunt ut labore et dolore magna aliqua. */ +/* + * - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod + * tempor incididunt ut labore et dolore magna aliqua. */ + +/* + * * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod + * tempor incididunt ut labore et dolore magna aliqua. */ +/* + * * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod + * tempor incididunt ut labore et dolore magna aliqua. */ diff --git a/tests/target/issue-5088/start_with_empty_comment_wrap_comments_false.rs b/tests/target/issue-5088/start_with_empty_comment_wrap_comments_false.rs new file mode 100644 index 000000000000..75cc42c0e66b --- /dev/null +++ b/tests/target/issue-5088/start_with_empty_comment_wrap_comments_false.rs @@ -0,0 +1,17 @@ +// rustfmt-wrap_comments: false + +// +// - some itemized block 1 +// - some itemized block 2 + +// +// * some itemized block 3 +// * some itemized block 4 + +/* + * - some itemized block 5 + * - some itemized block 6 */ + +/* + * * some itemized block 7 + * * some itemized block 8 */ diff --git a/tests/target/issue-5088/start_with_empty_comment_wrap_comments_true.rs b/tests/target/issue-5088/start_with_empty_comment_wrap_comments_true.rs new file mode 100644 index 000000000000..ef2c8f90cd30 --- /dev/null +++ b/tests/target/issue-5088/start_with_empty_comment_wrap_comments_true.rs @@ -0,0 +1,17 @@ +// rustfmt-wrap_comments: true + +// +// - some itemized block 1 +// - some itemized block 2 + +// +// * some itemized block 3 +// * some itemized block 4 + +/* + * - some itemized block 5 + * - some itemized block 6 */ + +/* + * * some itemized block 7 + * * some itemized block 8 */ diff --git a/tests/target/issue-5088/very_long_comment_wrap_comments_false.rs b/tests/target/issue-5088/very_long_comment_wrap_comments_false.rs new file mode 100644 index 000000000000..c826cc5d4da6 --- /dev/null +++ b/tests/target/issue-5088/very_long_comment_wrap_comments_false.rs @@ -0,0 +1,13 @@ +// rustfmt-wrap_comments: false + +// - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +// - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + +// * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +// * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + +/* - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ +/* - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ + +/* * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ +/* * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ diff --git a/tests/target/issue-5088/very_long_comment_wrap_comments_true.rs b/tests/target/issue-5088/very_long_comment_wrap_comments_true.rs new file mode 100644 index 000000000000..7f764dbd8a22 --- /dev/null +++ b/tests/target/issue-5088/very_long_comment_wrap_comments_true.rs @@ -0,0 +1,21 @@ +// rustfmt-wrap_comments: true + +// - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod +// tempor incididunt ut labore et dolore magna aliqua. +// - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod +// tempor incididunt ut labore et dolore magna aliqua. + +// * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod +// tempor incididunt ut labore et dolore magna aliqua. +// * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod +// tempor incididunt ut labore et dolore magna aliqua. + +/* - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod + * tempor incididunt ut labore et dolore magna aliqua. */ +/* - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod + * tempor incididunt ut labore et dolore magna aliqua. */ + +/* * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod + * tempor incididunt ut labore et dolore magna aliqua. */ +/* * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod + * tempor incididunt ut labore et dolore magna aliqua. */ From f40b1d9f1aeabca7a6e28d2d32d8458943111957 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Wed, 24 Nov 2021 18:47:37 -0500 Subject: [PATCH 109/111] Backport: Do not touch module with #![rustfmt::skip] (4297) Although the implementation is slightly different than the original PR, the general idea is the same. After collecting all modules we want to exclude formatting those that contain the #![rustfmt::skip] attribute. --- src/formatting.rs | 52 +++++++++++++++---- src/test/configuration_snippet.rs | 21 +++++--- src/test/mod_resolver.rs | 9 ++++ src/visitor.rs | 13 ++--- .../mod-resolver/skip-files-issue-5065/foo.rs | 5 ++ .../skip-files-issue-5065/foo/bar/baz.rs | 1 + .../skip-files-issue-5065/main.rs | 9 ++++ .../mod-resolver/skip-files-issue-5065/one.rs | 1 + .../target/skip/preserve_trailing_comment.rs | 7 +++ 9 files changed, 93 insertions(+), 25 deletions(-) create mode 100644 tests/mod-resolver/skip-files-issue-5065/foo.rs create mode 100644 tests/mod-resolver/skip-files-issue-5065/foo/bar/baz.rs create mode 100644 tests/mod-resolver/skip-files-issue-5065/main.rs create mode 100644 tests/mod-resolver/skip-files-issue-5065/one.rs create mode 100644 tests/target/skip/preserve_trailing_comment.rs diff --git a/src/formatting.rs b/src/formatting.rs index 7d0facb8f12c..1972b5a87a5e 100644 --- a/src/formatting.rs +++ b/src/formatting.rs @@ -5,6 +5,7 @@ use std::io::{self, Write}; use std::time::{Duration, Instant}; use rustc_ast::ast; +use rustc_ast::AstLike; use rustc_span::Span; use self::newline_style::apply_newline_style; @@ -15,7 +16,7 @@ use crate::issues::BadIssueSeeker; use crate::modules::Module; use crate::syntux::parser::{DirectoryOwnership, Parser, ParserError}; use crate::syntux::session::ParseSess; -use crate::utils::count_newlines; +use crate::utils::{contains_skip, count_newlines}; use crate::visitor::FmtVisitor; use crate::{modules, source_file, ErrorKind, FormatReport, Input, Session}; @@ -58,6 +59,39 @@ impl<'b, T: Write + 'b> Session<'b, T> { } } +/// Determine if a module should be skipped. True if the module should be skipped, false otherwise. +fn should_skip_module( + config: &Config, + context: &FormatContext<'_, T>, + input_is_stdin: bool, + main_file: &FileName, + path: &FileName, + module: &Module<'_>, +) -> bool { + if contains_skip(module.attrs()) { + return true; + } + + if config.skip_children() && path != main_file { + return true; + } + + if !input_is_stdin && context.ignore_file(&path) { + return true; + } + + if !config.format_generated_files() { + let source_file = context.parse_session.span_to_file_contents(module.span); + let src = source_file.src.as_ref().expect("SourceFile without src"); + + if is_generated_file(src) { + return true; + } + } + + false +} + // Format an entire crate (or subset of the module tree). fn format_project( input: Input, @@ -97,7 +131,12 @@ fn format_project( directory_ownership.unwrap_or(DirectoryOwnership::UnownedViaBlock), !input_is_stdin && !config.skip_children(), ) - .visit_crate(&krate)?; + .visit_crate(&krate)? + .into_iter() + .filter(|(path, module)| { + !should_skip_module(config, &context, input_is_stdin, &main_file, path, module) + }) + .collect::>(); timer = timer.done_parsing(); @@ -105,15 +144,6 @@ fn format_project( context.parse_session.set_silent_emitter(); for (path, module) in files { - let source_file = context.parse_session.span_to_file_contents(module.span); - let src = source_file.src.as_ref().expect("SourceFile without src"); - - let should_ignore = (!input_is_stdin && context.ignore_file(&path)) - || (!config.format_generated_files() && is_generated_file(src)); - - if (config.skip_children() && path != main_file) || should_ignore { - continue; - } should_emit_verbose(input_is_stdin, config, || println!("Formatting {}", path)); context.format_file(path, &module, is_macro_def)?; } diff --git a/src/test/configuration_snippet.rs b/src/test/configuration_snippet.rs index ef7dd0ddcd12..92949ab576a6 100644 --- a/src/test/configuration_snippet.rs +++ b/src/test/configuration_snippet.rs @@ -110,14 +110,7 @@ impl ConfigCodeBlock { assert!(self.code_block.is_some() && self.code_block_start.is_some()); // See if code block begins with #![rustfmt::skip]. - let fmt_skip = self - .code_block - .as_ref() - .unwrap() - .lines() - .nth(0) - .unwrap_or("") - == "#![rustfmt::skip]"; + let fmt_skip = self.fmt_skip(); if self.config_name.is_none() && !fmt_skip { write_message(&format!( @@ -138,6 +131,17 @@ impl ConfigCodeBlock { true } + /// True if the code block starts with #![rustfmt::skip] + fn fmt_skip(&self) -> bool { + self.code_block + .as_ref() + .unwrap() + .lines() + .nth(0) + .unwrap_or("") + == "#![rustfmt::skip]" + } + fn has_parsing_errors(&self, session: &Session<'_, T>) -> bool { if session.has_parsing_errors() { write_message(&format!( @@ -251,6 +255,7 @@ fn configuration_snippet_tests() { let blocks = get_code_blocks(); let failures = blocks .iter() + .filter(|block| !block.fmt_skip()) .map(ConfigCodeBlock::formatted_is_idempotent) .fold(0, |acc, r| acc + (!r as u32)); diff --git a/src/test/mod_resolver.rs b/src/test/mod_resolver.rs index ae4a0d0fccb1..ec9ed0f0b8d6 100644 --- a/src/test/mod_resolver.rs +++ b/src/test/mod_resolver.rs @@ -41,3 +41,12 @@ fn out_of_line_nested_inline_within_out_of_line() { ], ); } + +#[test] +fn skip_out_of_line_nested_inline_within_out_of_line() { + // See also https://github.com/rust-lang/rustfmt/issues/5065 + verify_mod_resolution( + "tests/mod-resolver/skip-files-issue-5065/main.rs", + &["tests/mod-resolver/skip-files-issue-5065/one.rs"], + ); +} diff --git a/src/visitor.rs b/src/visitor.rs index e4a7be742abc..ba446200232b 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -948,12 +948,13 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { pub(crate) fn format_separate_mod(&mut self, m: &Module<'_>, end_pos: BytePos) { self.block_indent = Indent::empty(); - if self.visit_attrs(m.attrs(), ast::AttrStyle::Inner) { - self.push_skipped_with_span(m.attrs(), m.span, m.span); - } else { - self.walk_mod_items(&m.items); - self.format_missing_with_indent(end_pos); - } + let skipped = self.visit_attrs(m.attrs(), ast::AttrStyle::Inner); + assert!( + !skipped, + "Skipping module must be handled before reaching this line." + ); + self.walk_mod_items(&m.items); + self.format_missing_with_indent(end_pos); } pub(crate) fn skip_empty_lines(&mut self, end_pos: BytePos) { diff --git a/tests/mod-resolver/skip-files-issue-5065/foo.rs b/tests/mod-resolver/skip-files-issue-5065/foo.rs new file mode 100644 index 000000000000..74889acf0c38 --- /dev/null +++ b/tests/mod-resolver/skip-files-issue-5065/foo.rs @@ -0,0 +1,5 @@ +#![rustfmt::skip] + +mod bar { + + mod baz;} \ No newline at end of file diff --git a/tests/mod-resolver/skip-files-issue-5065/foo/bar/baz.rs b/tests/mod-resolver/skip-files-issue-5065/foo/bar/baz.rs new file mode 100644 index 000000000000..3519b0ee59c8 --- /dev/null +++ b/tests/mod-resolver/skip-files-issue-5065/foo/bar/baz.rs @@ -0,0 +1 @@ +fn baz() { } \ No newline at end of file diff --git a/tests/mod-resolver/skip-files-issue-5065/main.rs b/tests/mod-resolver/skip-files-issue-5065/main.rs new file mode 100644 index 000000000000..3122e4f220f6 --- /dev/null +++ b/tests/mod-resolver/skip-files-issue-5065/main.rs @@ -0,0 +1,9 @@ +#![rustfmt::skip] + +mod foo; +mod one; + +fn main() {println!("Hello, world!"); +} + +// trailing commet diff --git a/tests/mod-resolver/skip-files-issue-5065/one.rs b/tests/mod-resolver/skip-files-issue-5065/one.rs new file mode 100644 index 000000000000..e7eb2c2d64dd --- /dev/null +++ b/tests/mod-resolver/skip-files-issue-5065/one.rs @@ -0,0 +1 @@ +struct One { value: String } \ No newline at end of file diff --git a/tests/target/skip/preserve_trailing_comment.rs b/tests/target/skip/preserve_trailing_comment.rs new file mode 100644 index 000000000000..f85de33257cc --- /dev/null +++ b/tests/target/skip/preserve_trailing_comment.rs @@ -0,0 +1,7 @@ +#![rustfmt::skip] + +fn main() { + println!("Hello, world!"); +} + +// Trailing Comment From 740fb57f5ddacddd9bcf074df701bcc50b46e69f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Sun, 12 Dec 2021 20:15:08 +0100 Subject: [PATCH 110/111] clippy fixes --- src/bin/main.rs | 2 +- src/expr.rs | 4 +--- src/formatting.rs | 2 +- src/items.rs | 10 +++++----- src/lists.rs | 4 +--- src/visitor.rs | 12 ++++++------ 6 files changed, 15 insertions(+), 19 deletions(-) diff --git a/src/bin/main.rs b/src/bin/main.rs index 9d2e97c9479f..4d845547cdfe 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -26,7 +26,7 @@ fn main() { let exit_code = match execute(&opts) { Ok(code) => code, Err(e) => { - eprintln!("{}", e.to_string()); + eprintln!("{}", e); 1 } }; diff --git a/src/expr.rs b/src/expr.rs index 5fd86c1a4ead..edd004ac63f0 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -2003,9 +2003,7 @@ fn choose_rhs( has_rhs_comment: bool, ) -> Option { match orig_rhs { - Some(ref new_str) if new_str.is_empty() => { - return Some(String::new()); - } + Some(ref new_str) if new_str.is_empty() => Some(String::new()), Some(ref new_str) if !new_str.contains('\n') && unicode_str_width(new_str) <= shape.width => { diff --git a/src/formatting.rs b/src/formatting.rs index 1972b5a87a5e..b39480a0ef90 100644 --- a/src/formatting.rs +++ b/src/formatting.rs @@ -76,7 +76,7 @@ fn should_skip_module( return true; } - if !input_is_stdin && context.ignore_file(&path) { + if !input_is_stdin && context.ignore_file(path) { return true; } diff --git a/src/items.rs b/src/items.rs index f36bdba26e98..a77b7c108760 100644 --- a/src/items.rs +++ b/src/items.rs @@ -1535,7 +1535,7 @@ pub(crate) fn rewrite_type_alias<'a, 'b>( // https://rustc-dev-guide.rust-lang.org/opaque-types-type-alias-impl-trait.html // https://github.com/rust-dev-tools/fmt-rfcs/blob/master/guide/items.md#type-aliases match (visitor_kind, &op_ty) { - (Item(_) | AssocTraitItem(_) | ForeignItem(_), Some(ref op_bounds)) => { + (Item(_) | AssocTraitItem(_) | ForeignItem(_), Some(op_bounds)) => { let op = OpaqueType { bounds: op_bounds }; rewrite_ty(rw_info, Some(bounds), Some(&op), vis) } @@ -1543,7 +1543,7 @@ pub(crate) fn rewrite_type_alias<'a, 'b>( rewrite_ty(rw_info, Some(bounds), ty_opt, vis) } (AssocImplItem(_), _) => { - let result = if let Some(ref op_bounds) = op_ty { + let result = if let Some(op_bounds) = op_ty { let op = OpaqueType { bounds: op_bounds }; rewrite_ty(rw_info, Some(bounds), Some(&op), &DEFAULT_VISIBILITY) } else { @@ -3124,7 +3124,7 @@ impl Rewrite for ast::ForeignItem { let inner_attrs = inner_attributes(&self.attrs); let fn_ctxt = visit::FnCtxt::Foreign; visitor.visit_fn( - visit::FnKind::Fn(fn_ctxt, self.ident, &sig, &self.vis, Some(body)), + visit::FnKind::Fn(fn_ctxt, self.ident, sig, &self.vis, Some(body)), generics, &sig.decl, self.span, @@ -3137,7 +3137,7 @@ impl Rewrite for ast::ForeignItem { context, shape.indent, self.ident, - &FnSig::from_method_sig(&sig, generics, &self.vis), + &FnSig::from_method_sig(sig, generics, &self.vis), span, FnBraceStyle::None, ) @@ -3166,7 +3166,7 @@ impl Rewrite for ast::ForeignItem { .map(|s| s + ";") } ast::ForeignItemKind::TyAlias(ref ty_alias) => { - let (kind, span) = (&ItemVisitorKind::ForeignItem(&self), self.span); + let (kind, span) = (&ItemVisitorKind::ForeignItem(self), self.span); rewrite_type_alias(ty_alias, context, shape.indent, kind, span) } ast::ForeignItemKind::MacCall(ref mac) => { diff --git a/src/lists.rs b/src/lists.rs index 3515dd172510..7aa0315f18c2 100644 --- a/src/lists.rs +++ b/src/lists.rs @@ -448,10 +448,8 @@ where true } else if starts_with_newline(comment) { false - } else if comment.trim().contains('\n') || comment.trim().len() > width { - true } else { - false + comment.trim().contains('\n') || comment.trim().len() > width }; rewrite_comment( diff --git a/src/visitor.rs b/src/visitor.rs index ba446200232b..1896a4744fe4 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -552,7 +552,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { _ => visit::FnCtxt::Foreign, }; self.visit_fn( - visit::FnKind::Fn(fn_ctxt, item.ident, &sig, &item.vis, Some(body)), + visit::FnKind::Fn(fn_ctxt, item.ident, sig, &item.vis, Some(body)), generics, &sig.decl, item.span, @@ -562,14 +562,14 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { } else { let indent = self.block_indent; let rewrite = self.rewrite_required_fn( - indent, item.ident, &sig, &item.vis, generics, item.span, + indent, item.ident, sig, &item.vis, generics, item.span, ); self.push_rewrite(item.span, rewrite); } } ast::ItemKind::TyAlias(ref ty_alias) => { use ItemVisitorKind::Item; - self.visit_ty_alias_kind(ty_alias, &Item(&item), item.span); + self.visit_ty_alias_kind(ty_alias, &Item(item), item.span); } ast::ItemKind::GlobalAsm(..) => { let snippet = Some(self.snippet(item.span).to_owned()); @@ -619,17 +619,17 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { skip_out_of_file_lines_range_visitor!(self, ai.span); if self.visit_attrs(&ai.attrs, ast::AttrStyle::Outer) { - self.push_skipped_with_span(&ai.attrs.as_slice(), skip_span, skip_span); + self.push_skipped_with_span(ai.attrs.as_slice(), skip_span, skip_span); return; } // TODO(calebcartwright): consider enabling box_patterns feature gate match (&ai.kind, visitor_kind) { (ast::AssocItemKind::Const(..), AssocTraitItem(_)) => { - self.visit_static(&StaticParts::from_trait_item(&ai)) + self.visit_static(&StaticParts::from_trait_item(ai)) } (ast::AssocItemKind::Const(..), AssocImplItem(_)) => { - self.visit_static(&StaticParts::from_impl_item(&ai)) + self.visit_static(&StaticParts::from_impl_item(ai)) } (ast::AssocItemKind::Fn(ref fn_kind), _) => { let ast::Fn { From 57ac92bf1658a576fdc066b82a37aa3a7de2c96b Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Wed, 17 Nov 2021 20:46:48 -0500 Subject: [PATCH 111/111] Prevent duplicate comma when formatting struct pattern with ".." Fixes 5066 When a struct pattern that contained a ".." was formatted, it was assumed that a trailing comma should always be added if the struct fields weren't formatted vertically. Now, a trailing comma is only added if not already included in the reformatted struct fields. --- src/patterns.rs | 7 ++++--- ..._struct_trailing_comma_always_struct_lit_width_0.rs | 10 ++++++++++ ...e_struct_trailing_comma_never_struct_lit_width_0.rs | 10 ++++++++++ .../multi_line_struct_with_trailing_comma_always.rs | 10 ++++++++++ .../multi_line_struct_with_trailing_comma_never.rs | 10 ++++++++++ tests/target/issue-5066/with_trailing_comma_always.rs | 5 +++++ tests/target/issue-5066/with_trailing_comma_never.rs | 5 +++++ 7 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 tests/target/issue-5066/multi_line_struct_trailing_comma_always_struct_lit_width_0.rs create mode 100644 tests/target/issue-5066/multi_line_struct_trailing_comma_never_struct_lit_width_0.rs create mode 100644 tests/target/issue-5066/multi_line_struct_with_trailing_comma_always.rs create mode 100644 tests/target/issue-5066/multi_line_struct_with_trailing_comma_never.rs create mode 100644 tests/target/issue-5066/with_trailing_comma_always.rs create mode 100644 tests/target/issue-5066/with_trailing_comma_never.rs diff --git a/src/patterns.rs b/src/patterns.rs index a80d63201f98..9b74b35f3141 100644 --- a/src/patterns.rs +++ b/src/patterns.rs @@ -318,10 +318,12 @@ fn rewrite_struct_pat( let mut fields_str = write_list(&item_vec, &fmt)?; let one_line_width = h_shape.map_or(0, |shape| shape.width); + let has_trailing_comma = fmt.needs_trailing_separator(); + if ellipsis { if fields_str.contains('\n') || fields_str.len() > one_line_width { // Add a missing trailing comma. - if context.config.trailing_comma() == SeparatorTactic::Never { + if !has_trailing_comma { fields_str.push(','); } fields_str.push('\n'); @@ -329,8 +331,7 @@ fn rewrite_struct_pat( } else { if !fields_str.is_empty() { // there are preceding struct fields being matched on - if tactic == DefinitiveListTactic::Vertical { - // if the tactic is Vertical, write_list already added a trailing , + if has_trailing_comma { fields_str.push(' '); } else { fields_str.push_str(", "); diff --git a/tests/target/issue-5066/multi_line_struct_trailing_comma_always_struct_lit_width_0.rs b/tests/target/issue-5066/multi_line_struct_trailing_comma_always_struct_lit_width_0.rs new file mode 100644 index 000000000000..c7122c676237 --- /dev/null +++ b/tests/target/issue-5066/multi_line_struct_trailing_comma_always_struct_lit_width_0.rs @@ -0,0 +1,10 @@ +// rustfmt-trailing_comma: Always +// rustfmt-struct_lit_single_line: false +// rustfmt-struct_lit_width: 0 + +fn main() { + let Foo { + a, + .. + } = b; +} diff --git a/tests/target/issue-5066/multi_line_struct_trailing_comma_never_struct_lit_width_0.rs b/tests/target/issue-5066/multi_line_struct_trailing_comma_never_struct_lit_width_0.rs new file mode 100644 index 000000000000..68e89c4179f7 --- /dev/null +++ b/tests/target/issue-5066/multi_line_struct_trailing_comma_never_struct_lit_width_0.rs @@ -0,0 +1,10 @@ +// rustfmt-trailing_comma: Never +// rustfmt-struct_lit_single_line: false +// rustfmt-struct_lit_width: 0 + +fn main() { + let Foo { + a, + .. + } = b; +} diff --git a/tests/target/issue-5066/multi_line_struct_with_trailing_comma_always.rs b/tests/target/issue-5066/multi_line_struct_with_trailing_comma_always.rs new file mode 100644 index 000000000000..3368f0703868 --- /dev/null +++ b/tests/target/issue-5066/multi_line_struct_with_trailing_comma_always.rs @@ -0,0 +1,10 @@ +// rustfmt-trailing_comma: Always +// rustfmt-struct_lit_single_line: false + +// There is an issue with how this is formatted. +// formatting should look like ./multi_line_struct_trailing_comma_always_struct_lit_width_0.rs +fn main() { + let Foo { + a, .. + } = b; +} diff --git a/tests/target/issue-5066/multi_line_struct_with_trailing_comma_never.rs b/tests/target/issue-5066/multi_line_struct_with_trailing_comma_never.rs new file mode 100644 index 000000000000..cf63c4c983c4 --- /dev/null +++ b/tests/target/issue-5066/multi_line_struct_with_trailing_comma_never.rs @@ -0,0 +1,10 @@ +// rustfmt-trailing_comma: Never +// rustfmt-struct_lit_single_line: false + +// There is an issue with how this is formatted. +// formatting should look like ./multi_line_struct_trailing_comma_never_struct_lit_width_0.rs +fn main() { + let Foo { + a, .. + } = b; +} diff --git a/tests/target/issue-5066/with_trailing_comma_always.rs b/tests/target/issue-5066/with_trailing_comma_always.rs new file mode 100644 index 000000000000..e20bcec93169 --- /dev/null +++ b/tests/target/issue-5066/with_trailing_comma_always.rs @@ -0,0 +1,5 @@ +// rustfmt-trailing_comma: Always + +fn main() { + let Foo { a, .. } = b; +} diff --git a/tests/target/issue-5066/with_trailing_comma_never.rs b/tests/target/issue-5066/with_trailing_comma_never.rs new file mode 100644 index 000000000000..8b95bb137bca --- /dev/null +++ b/tests/target/issue-5066/with_trailing_comma_never.rs @@ -0,0 +1,5 @@ +// rustfmt-trailing_comma: Never + +fn main() { + let Foo { a, .. } = b; +}