Skip to content

Commit 419df99

Browse files
Merge commit '5ff7b632a95bac6955611d85040859128902c580' into sync-rustfmt-subtree
2 parents 9c06e1b + 5ff7b63 commit 419df99

File tree

125 files changed

+2013
-235
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

125 files changed

+2013
-235
lines changed

src/tools/rustfmt/.github/workflows/linux.yml

+4
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ jobs:
4040
rustc -Vv
4141
cargo -V
4242
cargo build
43+
env:
44+
RUSTFLAGS: '-D warnings'
4345

4446
- name: test
4547
run: cargo test
48+
env:
49+
RUSTFLAGS: '-D warnings'

src/tools/rustfmt/CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## [Unreleased]
44

5+
### Fixed
6+
7+
- 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)
8+
59
## [1.4.38] 2021-10-20
610

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

5862
- 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)
5963
- 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)
64+
if `format_generated_files` option is set to `false` (by default `@generated` files are formatted)
6065
- 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)
6166

6267
See the section on the configuration site for more information

src/tools/rustfmt/Cargo.lock

+2-2
Original file line numberDiff line numberDiff line change
@@ -275,9 +275,9 @@ dependencies = [
275275

276276
[[package]]
277277
name = "itertools"
278-
version = "0.9.0"
278+
version = "0.10.3"
279279
source = "registry+https://github.com/rust-lang/crates.io-index"
280-
checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b"
280+
checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3"
281281
dependencies = [
282282
"either",
283283
]

src/tools/rustfmt/Configurations.md

+37-1
Original file line numberDiff line numberDiff line change
@@ -930,6 +930,8 @@ fn add_one(x: i32) -> i32 {
930930

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

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

2203+
## `short_array_element_width_threshold`
2204+
2205+
The width threshold for an array element to be considered "short".
2206+
2207+
The layout of an array is dependent on the length of each of its elements.
2208+
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.
2209+
2210+
- **Default value**: `10`
2211+
- **Possible values**: any positive integer that is less than or equal to the value specified for [`max_width`](#max_width)
2212+
- **Stable**: Yes
2213+
2214+
#### `10` (default):
2215+
```rust
2216+
fn main() {
2217+
pub const FORMAT_TEST: [u64; 5] = [
2218+
0x0000000000000000,
2219+
0xaaaaaaaaaaaaaaaa,
2220+
0xbbbbbbbbbbbbbbbb,
2221+
0xcccccccccccccccc,
2222+
0xdddddddddddddddd,
2223+
];
2224+
}
2225+
```
2226+
#### `20`:
2227+
```rust
2228+
fn main() {
2229+
pub const FORMAT_TEST: [u64; 5] = [
2230+
0x0000000000000000, 0xaaaaaaaaaaaaaaaa, 0xbbbbbbbbbbbbbbbb, 0xcccccccccccccccc,
2231+
0xdddddddddddddddd,
2232+
];
2233+
}
2234+
```
2235+
See also [`max_width`](#max_width).
2236+
22012237
## `skip_children`
22022238

22032239
Don't reformat out of line modules
22042240

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

22092245
## `single_line_if_else_max_width`
22102246

src/tools/rustfmt/config_proc_macro/src/utils.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ pub fn is_unit(v: &syn::Variant) -> bool {
2222
#[cfg(feature = "debug-with-rustfmt")]
2323
/// Pretty-print the output of proc macro using rustfmt.
2424
pub fn debug_with_rustfmt(input: &TokenStream) {
25-
use std::io::Write;
26-
use std::process::{Command, Stdio};
2725
use std::env;
2826
use std::ffi::OsStr;
27+
use std::io::Write;
28+
use std::process::{Command, Stdio};
2929

3030
let rustfmt_var = env::var_os("RUSTFMT");
3131
let rustfmt = match &rustfmt_var {

src/tools/rustfmt/rust-toolchain

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
[toolchain]
2-
channel = "nightly-2021-12-29"
2+
channel = "nightly-2022-03-27"
33
components = ["rustc-dev"]

src/tools/rustfmt/src/attr.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,10 @@ impl Rewrite for [ast::Attribute] {
389389
let mut attrs = self;
390390
let mut result = String::new();
391391

392+
// Determine if the source text is annotated with `#[rustfmt::skip::attributes(derive)]`
393+
// or `#![rustfmt::skip::attributes(derive)]`
394+
let skip_derives = context.skip_context.skip_attribute("derive");
395+
392396
// This is not just a simple map because we need to handle doc comments
393397
// (where we take as many doc comment attributes as possible) and possibly
394398
// merging derives into a single attribute.
@@ -431,7 +435,7 @@ impl Rewrite for [ast::Attribute] {
431435
}
432436

433437
// Handle derives if we will merge them.
434-
if context.config.merge_derives() && is_derive(&attrs[0]) {
438+
if !skip_derives && context.config.merge_derives() && is_derive(&attrs[0]) {
435439
let derives = take_while_with_pred(context, attrs, is_derive);
436440
let derive_str = format_derive(derives, shape, context)?;
437441
result.push_str(&derive_str);

src/tools/rustfmt/src/bin/main.rs

+19-19
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ fn main() {
2626
let exit_code = match execute(&opts) {
2727
Ok(code) => code,
2828
Err(e) => {
29-
eprintln!("{}", e);
29+
eprintln!("{:#}", e);
3030
1
3131
}
3232
};
@@ -74,14 +74,10 @@ pub enum OperationError {
7474
/// An io error during reading or writing.
7575
#[error("{0}")]
7676
IoError(IoError),
77-
/// Attempt to use --check with stdin, which isn't currently
78-
/// supported.
79-
#[error("The `--check` option is not supported with standard input.")]
80-
CheckWithStdin,
81-
/// Attempt to use --emit=json with stdin, which isn't currently
82-
/// supported.
83-
#[error("Using `--emit` other than stdout is not supported with standard input.")]
84-
EmitWithStdin,
77+
/// Attempt to use --emit with a mode which is not currently
78+
/// supported with stdandard input.
79+
#[error("Emit mode {0} not supported with standard output.")]
80+
StdinBadEmit(EmitMode),
8581
}
8682

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

257253
if options.check {
258-
return Err(OperationError::CheckWithStdin.into());
259-
}
260-
if let Some(emit_mode) = options.emit_mode {
261-
if emit_mode != EmitMode::Stdout {
262-
return Err(OperationError::EmitWithStdin.into());
254+
config.set().emit_mode(EmitMode::Diff);
255+
} else {
256+
match options.emit_mode {
257+
// Emit modes which work with standard input
258+
// None means default, which is Stdout.
259+
None | Some(EmitMode::Stdout) | Some(EmitMode::Checkstyle) | Some(EmitMode::Json) => {}
260+
Some(emit_mode) => {
261+
return Err(OperationError::StdinBadEmit(emit_mode).into());
262+
}
263263
}
264+
config
265+
.set()
266+
.emit_mode(options.emit_mode.unwrap_or(EmitMode::Stdout));
264267
}
265-
// emit mode is always Stdout for Stdin.
266-
config.set().emit_mode(EmitMode::Stdout);
267268
config.set().verbose(Verbosity::Quiet);
268269

269270
// parse file_lines
@@ -393,9 +394,8 @@ fn print_usage_to_stdout(opts: &Options, reason: &str) {
393394
format!("{}\n\n", reason)
394395
};
395396
let msg = format!(
396-
"{}Format Rust code\n\nusage: {} [options] <file>...",
397-
sep,
398-
env::args_os().next().unwrap().to_string_lossy()
397+
"{}Format Rust code\n\nusage: rustfmt [options] <file>...",
398+
sep
399399
);
400400
println!("{}", opts.usage(&msg));
401401
}

src/tools/rustfmt/src/cargo-fmt/main.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -387,8 +387,7 @@ fn get_targets_root_only(
387387
.unwrap_or_default()
388388
== current_dir_manifest
389389
})
390-
.map(|p| p.targets)
391-
.flatten()
390+
.flat_map(|p| p.targets)
392391
.collect(),
393392
};
394393

src/tools/rustfmt/src/comment.rs

+53-11
Original file line numberDiff line numberDiff line change
@@ -432,36 +432,49 @@ impl CodeBlockAttribute {
432432

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

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

455455
/// Creates a new ItemizedBlock described with the given line.
456456
/// The `is_itemized_line` needs to be called first.
457457
fn new(line: &str) -> ItemizedBlock {
458458
let space_to_sigil = line.chars().take_while(|c| c.is_whitespace()).count();
459-
let indent = space_to_sigil + 2;
459+
// +2 = '* ', which will add the appropriate amount of whitespace to keep itemized
460+
// content formatted correctly.
461+
let mut indent = space_to_sigil + 2;
462+
let mut line_start = " ".repeat(indent);
463+
464+
// Markdown blockquote start with a "> "
465+
if line.trim_start().starts_with(">") {
466+
// remove the original +2 indent because there might be multiple nested block quotes
467+
// and it's easier to reason about the final indent by just taking the length
468+
// of th new line_start. We update the indent because it effects the max width
469+
// of each formatted line.
470+
line_start = itemized_block_quote_start(line, line_start, 2);
471+
indent = line_start.len();
472+
}
460473
ItemizedBlock {
461474
lines: vec![line[indent..].to_string()],
462475
indent,
463476
opener: line[..indent].to_string(),
464-
line_start: " ".repeat(indent),
477+
line_start,
465478
}
466479
}
467480

@@ -504,6 +517,25 @@ impl ItemizedBlock {
504517
}
505518
}
506519

520+
/// Determine the line_start when formatting markdown block quotes.
521+
/// The original line_start likely contains indentation (whitespaces), which we'd like to
522+
/// replace with '> ' characters.
523+
fn itemized_block_quote_start(line: &str, mut line_start: String, remove_indent: usize) -> String {
524+
let quote_level = line
525+
.chars()
526+
.take_while(|c| !c.is_alphanumeric())
527+
.fold(0, |acc, c| if c == '>' { acc + 1 } else { acc });
528+
529+
for _ in 0..remove_indent {
530+
line_start.pop();
531+
}
532+
533+
for _ in 0..quote_level {
534+
line_start.push_str("> ")
535+
}
536+
line_start
537+
}
538+
507539
struct CommentRewrite<'a> {
508540
result: String,
509541
code_block_buffer: String,
@@ -651,6 +683,7 @@ impl<'a> CommentRewrite<'a> {
651683
i: usize,
652684
line: &'a str,
653685
has_leading_whitespace: bool,
686+
is_doc_comment: bool,
654687
) -> bool {
655688
let num_newlines = count_newlines(orig);
656689
let is_last = i == num_newlines;
@@ -757,10 +790,19 @@ impl<'a> CommentRewrite<'a> {
757790
}
758791
}
759792

760-
if self.fmt.config.wrap_comments()
793+
let is_markdown_header_doc_comment = is_doc_comment && line.starts_with("#");
794+
795+
// We only want to wrap the comment if:
796+
// 1) wrap_comments = true is configured
797+
// 2) The comment is not the start of a markdown header doc comment
798+
// 3) The comment width exceeds the shape's width
799+
// 4) No URLS were found in the commnet
800+
let should_wrap_comment = self.fmt.config.wrap_comments()
801+
&& !is_markdown_header_doc_comment
761802
&& unicode_str_width(line) > self.fmt.shape.width
762-
&& !has_url(line)
763-
{
803+
&& !has_url(line);
804+
805+
if should_wrap_comment {
764806
match rewrite_string(line, &self.fmt, self.max_width) {
765807
Some(ref s) => {
766808
self.is_prev_line_multi_line = s.contains('\n');
@@ -850,7 +892,7 @@ fn rewrite_comment_inner(
850892
});
851893

852894
for (i, (line, has_leading_whitespace)) in lines.enumerate() {
853-
if rewriter.handle_line(orig, i, line, has_leading_whitespace) {
895+
if rewriter.handle_line(orig, i, line, has_leading_whitespace, is_doc_comment) {
854896
break;
855897
}
856898
}

src/tools/rustfmt/src/config/file_lines.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ impl fmt::Display for FileName {
3939
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4040
match self {
4141
FileName::Real(p) => write!(f, "{}", p.to_str().unwrap()),
42-
FileName::Stdin => write!(f, "stdin"),
42+
FileName::Stdin => write!(f, "<stdin>"),
4343
}
4444
}
4545
}

src/tools/rustfmt/src/config/mod.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ create_config! {
106106
// Misc.
107107
remove_nested_parens: bool, true, true, "Remove nested parens";
108108
combine_control_expr: bool, true, false, "Combine control expressions with function calls";
109+
short_array_element_width_threshold: usize, 10, true,
110+
"Width threshold for an array element to be considered short";
109111
overflow_delimited_expr: bool, false, false,
110112
"Allow trailing bracket/brace delimited expressions to overflow";
111113
struct_field_align_threshold: usize, 0, false,
@@ -364,7 +366,9 @@ fn get_toml_path(dir: &Path) -> Result<Option<PathBuf>, Error> {
364366
// find the project file yet, and continue searching.
365367
Err(e) => {
366368
if e.kind() != ErrorKind::NotFound {
367-
return Err(e);
369+
let ctx = format!("Failed to get metadata for config file {:?}", &config_file);
370+
let err = anyhow::Error::new(e).context(ctx);
371+
return Err(Error::new(ErrorKind::Other, err));
368372
}
369373
}
370374
_ => {}
@@ -589,6 +593,7 @@ spaces_around_ranges = false
589593
binop_separator = "Front"
590594
remove_nested_parens = true
591595
combine_control_expr = true
596+
short_array_element_width_threshold = 10
592597
overflow_delimited_expr = false
593598
struct_field_align_threshold = 0
594599
enum_discrim_align_threshold = 0

0 commit comments

Comments
 (0)