Skip to content

Commit

Permalink
Auto merge of #95458 - calebcartwright:sync-rustfmt-subtree, r=calebc…
Browse files Browse the repository at this point in the history
…artwright

Sync rustfmt subtree

r? `@calebcartwright`
  • Loading branch information
bors committed Mar 30, 2022
2 parents 3e75146 + 419df99 commit bb5c437
Show file tree
Hide file tree
Showing 125 changed files with 2,013 additions and 235 deletions.
4 changes: 4 additions & 0 deletions src/tools/rustfmt/.github/workflows/linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ jobs:
rustc -Vv
cargo -V
cargo build
env:
RUSTFLAGS: '-D warnings'

- name: test
run: cargo test
env:
RUSTFLAGS: '-D warnings'
5 changes: 5 additions & 0 deletions src/tools/rustfmt/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## [Unreleased]

### Fixed

- Fixes issue where wrapped strings would be incorrectly indented in macro defs when `format_strings` was enabled [#4036](https://github.com/rust-lang/rustfmt/issues/4036)

## [1.4.38] 2021-10-20

### Changed
Expand Down Expand Up @@ -57,6 +61,7 @@ Note this hit the rustup distributions prior to the v1.4.38 release as part of a

- 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)
if `format_generated_files` option is set to `false` (by default `@generated` files are formatted)
- 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
Expand Down
4 changes: 2 additions & 2 deletions src/tools/rustfmt/Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -275,9 +275,9 @@ dependencies = [

[[package]]
name = "itertools"
version = "0.9.0"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b"
checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3"
dependencies = [
"either",
]
Expand Down
38 changes: 37 additions & 1 deletion src/tools/rustfmt/Configurations.md
Original file line number Diff line number Diff line change
Expand Up @@ -930,6 +930,8 @@ fn add_one(x: i32) -> i32 {

Format generated files. A file is considered generated
if any of the first five lines contain a `@generated` comment marker.
By default, generated files are reformatted, i. e. `@generated` marker is ignored.
This option is currently ignored for stdin (`@generated` in stdin is ignored.)

- **Default value**: `true`
- **Possible values**: `true`, `false`
Expand Down Expand Up @@ -2198,13 +2200,47 @@ specific version of rustfmt is used in your CI, use this option.
- **Possible values**: any published version (e.g. `"0.3.8"`)
- **Stable**: No (tracking issue: [#3386](https://github.com/rust-lang/rustfmt/issues/3386))

## `short_array_element_width_threshold`

The width threshold for an array element to be considered "short".

The layout of an array is dependent on the length of each of its elements.
If the length of every element in an array is below this threshold (all elements are "short") then the array can be formatted in the mixed/compressed style, but if any one element has a length that exceeds this threshold then the array elements will have to be formatted vertically.

- **Default value**: `10`
- **Possible values**: any positive integer that is less than or equal to the value specified for [`max_width`](#max_width)
- **Stable**: Yes

#### `10` (default):
```rust
fn main() {
pub const FORMAT_TEST: [u64; 5] = [
0x0000000000000000,
0xaaaaaaaaaaaaaaaa,
0xbbbbbbbbbbbbbbbb,
0xcccccccccccccccc,
0xdddddddddddddddd,
];
}
```
#### `20`:
```rust
fn main() {
pub const FORMAT_TEST: [u64; 5] = [
0x0000000000000000, 0xaaaaaaaaaaaaaaaa, 0xbbbbbbbbbbbbbbbb, 0xcccccccccccccccc,
0xdddddddddddddddd,
];
}
```
See also [`max_width`](#max_width).

## `skip_children`

Don't reformat out of line modules

- **Default value**: `false`
- **Possible values**: `true`, `false`
- **Stable**: No (tracking issue: [#3389](https://github.com/rust-lang/rustfmt/issues/3386))
- **Stable**: No (tracking issue: [#3389](https://github.com/rust-lang/rustfmt/issues/3389))

## `single_line_if_else_max_width`

Expand Down
4 changes: 2 additions & 2 deletions src/tools/rustfmt/config_proc_macro/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ pub fn is_unit(v: &syn::Variant) -> bool {
#[cfg(feature = "debug-with-rustfmt")]
/// Pretty-print the output of proc macro using rustfmt.
pub fn debug_with_rustfmt(input: &TokenStream) {
use std::io::Write;
use std::process::{Command, Stdio};
use std::env;
use std::ffi::OsStr;
use std::io::Write;
use std::process::{Command, Stdio};

let rustfmt_var = env::var_os("RUSTFMT");
let rustfmt = match &rustfmt_var {
Expand Down
2 changes: 1 addition & 1 deletion src/tools/rustfmt/rust-toolchain
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[toolchain]
channel = "nightly-2021-12-29"
channel = "nightly-2022-03-27"
components = ["rustc-dev"]
6 changes: 5 additions & 1 deletion src/tools/rustfmt/src/attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,10 @@ impl Rewrite for [ast::Attribute] {
let mut attrs = self;
let mut result = String::new();

// Determine if the source text is annotated with `#[rustfmt::skip::attributes(derive)]`
// or `#![rustfmt::skip::attributes(derive)]`
let skip_derives = context.skip_context.skip_attribute("derive");

// This is not just a simple map because we need to handle doc comments
// (where we take as many doc comment attributes as possible) and possibly
// merging derives into a single attribute.
Expand Down Expand Up @@ -431,7 +435,7 @@ impl Rewrite for [ast::Attribute] {
}

// Handle derives if we will merge them.
if context.config.merge_derives() && is_derive(&attrs[0]) {
if !skip_derives && context.config.merge_derives() && is_derive(&attrs[0]) {
let derives = take_while_with_pred(context, attrs, is_derive);
let derive_str = format_derive(derives, shape, context)?;
result.push_str(&derive_str);
Expand Down
38 changes: 19 additions & 19 deletions src/tools/rustfmt/src/bin/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ fn main() {
let exit_code = match execute(&opts) {
Ok(code) => code,
Err(e) => {
eprintln!("{}", e);
eprintln!("{:#}", e);
1
}
};
Expand Down Expand Up @@ -74,14 +74,10 @@ pub enum OperationError {
/// An io error during reading or writing.
#[error("{0}")]
IoError(IoError),
/// Attempt to use --check with stdin, which isn't currently
/// supported.
#[error("The `--check` option is not supported with standard input.")]
CheckWithStdin,
/// Attempt to use --emit=json with stdin, which isn't currently
/// supported.
#[error("Using `--emit` other than stdout is not supported with standard input.")]
EmitWithStdin,
/// Attempt to use --emit with a mode which is not currently
/// supported with stdandard input.
#[error("Emit mode {0} not supported with standard output.")]
StdinBadEmit(EmitMode),
}

impl From<IoError> for OperationError {
Expand Down Expand Up @@ -255,15 +251,20 @@ fn format_string(input: String, options: GetOptsOptions) -> Result<i32> {
let (mut config, _) = load_config(Some(Path::new(".")), Some(options.clone()))?;

if options.check {
return Err(OperationError::CheckWithStdin.into());
}
if let Some(emit_mode) = options.emit_mode {
if emit_mode != EmitMode::Stdout {
return Err(OperationError::EmitWithStdin.into());
config.set().emit_mode(EmitMode::Diff);
} else {
match options.emit_mode {
// Emit modes which work with standard input
// None means default, which is Stdout.
None | Some(EmitMode::Stdout) | Some(EmitMode::Checkstyle) | Some(EmitMode::Json) => {}
Some(emit_mode) => {
return Err(OperationError::StdinBadEmit(emit_mode).into());
}
}
config
.set()
.emit_mode(options.emit_mode.unwrap_or(EmitMode::Stdout));
}
// emit mode is always Stdout for Stdin.
config.set().emit_mode(EmitMode::Stdout);
config.set().verbose(Verbosity::Quiet);

// parse file_lines
Expand Down Expand Up @@ -393,9 +394,8 @@ fn print_usage_to_stdout(opts: &Options, reason: &str) {
format!("{}\n\n", reason)
};
let msg = format!(
"{}Format Rust code\n\nusage: {} [options] <file>...",
sep,
env::args_os().next().unwrap().to_string_lossy()
"{}Format Rust code\n\nusage: rustfmt [options] <file>...",
sep
);
println!("{}", opts.usage(&msg));
}
Expand Down
3 changes: 1 addition & 2 deletions src/tools/rustfmt/src/cargo-fmt/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -387,8 +387,7 @@ fn get_targets_root_only(
.unwrap_or_default()
== current_dir_manifest
})
.map(|p| p.targets)
.flatten()
.flat_map(|p| p.targets)
.collect(),
};

Expand Down
64 changes: 53 additions & 11 deletions src/tools/rustfmt/src/comment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -432,36 +432,49 @@ impl CodeBlockAttribute {

/// Block that is formatted as an item.
///
/// An item starts with either a star `*` or a dash `-`. Different level of indentation are
/// handled by shrinking the shape accordingly.
/// An item starts with either a star `*` a dash `-` or a greater-than `>`.
/// Different level of indentation are handled by shrinking the shape accordingly.
struct ItemizedBlock {
/// the lines that are identified as part of an itemized block
lines: Vec<String>,
/// the number of whitespaces up to the item sigil
/// the number of characters (typically whitespaces) up to the item sigil
indent: usize,
/// the string that marks the start of an item
opener: String,
/// sequence of whitespaces to prefix new lines that are part of the item
/// sequence of characters (typically whitespaces) to prefix new lines that are part of the item
line_start: String,
}

impl ItemizedBlock {
/// Returns `true` if the line is formatted as an item
fn is_itemized_line(line: &str) -> bool {
let trimmed = line.trim_start();
trimmed.starts_with("* ") || trimmed.starts_with("- ")
trimmed.starts_with("* ") || trimmed.starts_with("- ") || trimmed.starts_with("> ")
}

/// Creates a new ItemizedBlock described with the given line.
/// The `is_itemized_line` needs to be called first.
fn new(line: &str) -> ItemizedBlock {
let space_to_sigil = line.chars().take_while(|c| c.is_whitespace()).count();
let indent = space_to_sigil + 2;
// +2 = '* ', which will add the appropriate amount of whitespace to keep itemized
// content formatted correctly.
let mut indent = space_to_sigil + 2;
let mut line_start = " ".repeat(indent);

// Markdown blockquote start with a "> "
if line.trim_start().starts_with(">") {
// remove the original +2 indent because there might be multiple nested block quotes
// and it's easier to reason about the final indent by just taking the length
// of th new line_start. We update the indent because it effects the max width
// of each formatted line.
line_start = itemized_block_quote_start(line, line_start, 2);
indent = line_start.len();
}
ItemizedBlock {
lines: vec![line[indent..].to_string()],
indent,
opener: line[..indent].to_string(),
line_start: " ".repeat(indent),
line_start,
}
}

Expand Down Expand Up @@ -504,6 +517,25 @@ impl ItemizedBlock {
}
}

/// Determine the line_start when formatting markdown block quotes.
/// The original line_start likely contains indentation (whitespaces), which we'd like to
/// replace with '> ' characters.
fn itemized_block_quote_start(line: &str, mut line_start: String, remove_indent: usize) -> String {
let quote_level = line
.chars()
.take_while(|c| !c.is_alphanumeric())
.fold(0, |acc, c| if c == '>' { acc + 1 } else { acc });

for _ in 0..remove_indent {
line_start.pop();
}

for _ in 0..quote_level {
line_start.push_str("> ")
}
line_start
}

struct CommentRewrite<'a> {
result: String,
code_block_buffer: String,
Expand Down Expand Up @@ -651,6 +683,7 @@ impl<'a> CommentRewrite<'a> {
i: usize,
line: &'a str,
has_leading_whitespace: bool,
is_doc_comment: bool,
) -> bool {
let num_newlines = count_newlines(orig);
let is_last = i == num_newlines;
Expand Down Expand Up @@ -757,10 +790,19 @@ impl<'a> CommentRewrite<'a> {
}
}

if self.fmt.config.wrap_comments()
let is_markdown_header_doc_comment = is_doc_comment && line.starts_with("#");

// We only want to wrap the comment if:
// 1) wrap_comments = true is configured
// 2) The comment is not the start of a markdown header doc comment
// 3) The comment width exceeds the shape's width
// 4) No URLS were found in the commnet
let should_wrap_comment = self.fmt.config.wrap_comments()
&& !is_markdown_header_doc_comment
&& unicode_str_width(line) > self.fmt.shape.width
&& !has_url(line)
{
&& !has_url(line);

if should_wrap_comment {
match rewrite_string(line, &self.fmt, self.max_width) {
Some(ref s) => {
self.is_prev_line_multi_line = s.contains('\n');
Expand Down Expand Up @@ -850,7 +892,7 @@ fn rewrite_comment_inner(
});

for (i, (line, has_leading_whitespace)) in lines.enumerate() {
if rewriter.handle_line(orig, i, line, has_leading_whitespace) {
if rewriter.handle_line(orig, i, line, has_leading_whitespace, is_doc_comment) {
break;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/tools/rustfmt/src/config/file_lines.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ impl fmt::Display for FileName {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
FileName::Real(p) => write!(f, "{}", p.to_str().unwrap()),
FileName::Stdin => write!(f, "stdin"),
FileName::Stdin => write!(f, "<stdin>"),
}
}
}
Expand Down
7 changes: 6 additions & 1 deletion src/tools/rustfmt/src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ create_config! {
// Misc.
remove_nested_parens: bool, true, true, "Remove nested parens";
combine_control_expr: bool, true, false, "Combine control expressions with function calls";
short_array_element_width_threshold: usize, 10, true,
"Width threshold for an array element to be considered short";
overflow_delimited_expr: bool, false, false,
"Allow trailing bracket/brace delimited expressions to overflow";
struct_field_align_threshold: usize, 0, false,
Expand Down Expand Up @@ -364,7 +366,9 @@ fn get_toml_path(dir: &Path) -> Result<Option<PathBuf>, Error> {
// find the project file yet, and continue searching.
Err(e) => {
if e.kind() != ErrorKind::NotFound {
return Err(e);
let ctx = format!("Failed to get metadata for config file {:?}", &config_file);
let err = anyhow::Error::new(e).context(ctx);
return Err(Error::new(ErrorKind::Other, err));
}
}
_ => {}
Expand Down Expand Up @@ -589,6 +593,7 @@ spaces_around_ranges = false
binop_separator = "Front"
remove_nested_parens = true
combine_control_expr = true
short_array_element_width_threshold = 10
overflow_delimited_expr = false
struct_field_align_threshold = 0
enum_discrim_align_threshold = 0
Expand Down
Loading

0 comments on commit bb5c437

Please sign in to comment.