Skip to content

Commit c801367

Browse files
Merge remote-tracking branch 'upstream/master' into subtree-sync-2022-03-16
2 parents a918d8b + 1bb85bd commit c801367

File tree

111 files changed

+1675
-259
lines changed

Some content is hidden

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

111 files changed

+1675
-259
lines changed

.github/workflows/linux.yml

Lines changed: 4 additions & 0 deletions
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'

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
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

Configurations.md

Lines changed: 3 additions & 1 deletion
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`
@@ -2204,7 +2206,7 @@ Don't reformat out of line modules
22042206

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

22092211
## `single_line_if_else_max_width`
22102212

config_proc_macro/src/utils.rs

Lines changed: 2 additions & 2 deletions
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 {

rust-toolchain

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
[toolchain]
2-
channel = "nightly-2021-12-29"
2+
channel = "nightly-2022-01-23"
33
components = ["rustc-dev"]

src/bin/main.rs

Lines changed: 19 additions & 19 deletions
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/cargo-fmt/main.rs

Lines changed: 1 addition & 2 deletions
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/comment.rs

Lines changed: 53 additions & 11 deletions
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/config/file_lines.rs

Lines changed: 1 addition & 1 deletion
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/config/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,9 @@ fn get_toml_path(dir: &Path) -> Result<Option<PathBuf>, Error> {
364364
// find the project file yet, and continue searching.
365365
Err(e) => {
366366
if e.kind() != ErrorKind::NotFound {
367-
return Err(e);
367+
let ctx = format!("Failed to get metadata for config file {:?}", &config_file);
368+
let err = anyhow::Error::new(e).context(ctx);
369+
return Err(Error::new(ErrorKind::Other, err));
368370
}
369371
}
370372
_ => {}

src/emitter/checkstyle.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ use self::xml::XmlEscaped;
22
use super::*;
33
use crate::rustfmt_diff::{make_diff, DiffLine, Mismatch};
44
use std::io::{self, Write};
5-
use std::path::Path;
65

76
mod xml;
87

@@ -30,7 +29,6 @@ impl Emitter for CheckstyleEmitter {
3029
}: FormattedFile<'_>,
3130
) -> Result<EmitterResult, io::Error> {
3231
const CONTEXT_SIZE: usize = 0;
33-
let filename = ensure_real_path(filename);
3432
let diff = make_diff(original_text, formatted_text, CONTEXT_SIZE);
3533
output_checkstyle_file(output, filename, diff)?;
3634
Ok(EmitterResult::default())
@@ -39,13 +37,13 @@ impl Emitter for CheckstyleEmitter {
3937

4038
pub(crate) fn output_checkstyle_file<T>(
4139
mut writer: T,
42-
filename: &Path,
40+
filename: &FileName,
4341
diff: Vec<Mismatch>,
4442
) -> Result<(), io::Error>
4543
where
4644
T: Write,
4745
{
48-
write!(writer, r#"<file name="{}">"#, filename.display())?;
46+
write!(writer, r#"<file name="{}">"#, filename)?;
4947
for mismatch in diff {
5048
let begin_line = mismatch.line_number;
5149
let mut current_line;
@@ -77,7 +75,11 @@ mod tests {
7775
fn emits_empty_record_on_file_with_no_mismatches() {
7876
let file_name = "src/well_formatted.rs";
7977
let mut writer = Vec::new();
80-
let _ = output_checkstyle_file(&mut writer, &PathBuf::from(file_name), vec![]);
78+
let _ = output_checkstyle_file(
79+
&mut writer,
80+
&FileName::Real(PathBuf::from(file_name)),
81+
vec![],
82+
);
8183
assert_eq!(
8284
&writer[..],
8385
format!(r#"<file name="{}"></file>"#, file_name).as_bytes()

src/emitter/diff.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ impl Emitter for DiffEmitter {
2828

2929
if has_diff {
3030
if self.config.print_misformatted_file_names() {
31-
writeln!(output, "{}", ensure_real_path(filename).display())?;
31+
writeln!(output, "{}", filename)?;
3232
} else {
3333
print_diff(
3434
mismatch,
@@ -40,8 +40,7 @@ impl Emitter for DiffEmitter {
4040
// This occurs when the only difference between the original and formatted values
4141
// is the newline style. This happens because The make_diff function compares the
4242
// original and formatted values line by line, independent of line endings.
43-
let file_path = ensure_real_path(filename);
44-
writeln!(output, "Incorrect newline style in {}", file_path.display())?;
43+
writeln!(output, "Incorrect newline style in {}", filename)?;
4544
return Ok(EmitterResult { has_diff: true });
4645
}
4746

0 commit comments

Comments
 (0)