Merge commit 'ea199bacef07213dbe008841b89c450e3bf0c638' into rustfmt-sync

This commit is contained in:
Caleb Cartwright 2021-11-07 20:37:34 -06:00
commit 30fb1246b4
59 changed files with 671 additions and 373 deletions

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -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
@ -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.
@ -129,7 +148,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

View File

@ -1,8 +0,0 @@
environment:
global:
PROJECT_NAME: rustfmt
build: false
test_script:
- echo Why does no one have access to delete me?

View File

@ -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))
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.
- 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)
- 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/1133787/47240803-c0c86780-d3e9-11e8-9265-22f735e4d7ed.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

View File

@ -1,2 +0,0 @@
indent_style = "Visual"
combine_control_expr = false

View File

@ -1,3 +1,3 @@
[toolchain]
channel = "nightly-2021-10-20"
channel = "nightly-2021-11-08"
components = ["rustc-dev"]

View File

@ -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');

View File

@ -77,7 +77,7 @@ mod tests {
) {
assert_eq!(
expected_comment,
format!("{}", DocCommentFormatter::new(&literal, style))
format!("{}", DocCommentFormatter::new(literal, style))
);
}
}

View File

@ -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) {

View File

@ -401,12 +401,12 @@ fn get_targets_root_only(
fn get_targets_recursive(
manifest_path: Option<&Path>,
mut targets: &mut BTreeSet<Target>,
targets: &mut BTreeSet<Target>,
visited: &mut BTreeSet<String>,
) -> 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)?;
}
}
}

View File

@ -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)

View File

@ -405,7 +405,7 @@ impl CodeBlockAttribute {
/// 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(",") {
for attribute in attributes.split(',') {
match attribute.trim() {
"" | "rust" | "should_panic" | "no_run" | "edition2015" | "edition2018"
| "edition2021" => (),
@ -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)
@ -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' {
@ -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("/*!")

View File

@ -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,
}
@ -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]

View File

@ -121,7 +121,7 @@ mod tests {
format!(r#"<file name="{}">"#, bin_file),
format!(
r#"<error line="2" severity="warning" message="Should be `{}`" />"#,
XmlEscaped(&r#" println!("Hello, world!");"#),
XmlEscaped(r#" println!("Hello, world!");"#),
),
String::from("</file>"),
];
@ -129,7 +129,7 @@ mod tests {
format!(r#"<file name="{}">"#, lib_file),
format!(
r#"<error line="2" severity="warning" message="Should be `{}`" />"#,
XmlEscaped(&r#" println!("Greetings!");"#),
XmlEscaped(r#" println!("Greetings!");"#),
),
String::from("</file>"),
];

View File

@ -23,7 +23,7 @@ impl Emitter for DiffEmitter {
}: FormattedFile<'_>,
) -> Result<EmitterResult, io::Error> {
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 {

View File

@ -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<String> {
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())
}
@ -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(
@ -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<R: Rewrite>(
shape: Shape,
rhs_tactics: RhsTactics,
) -> Option<String> {
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<S: Into<String>, 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)
}
@ -1962,6 +1962,9 @@ fn choose_rhs<R: Rewrite>(
has_rhs_comment: bool,
) -> Option<String> {
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 =>
{

View File

@ -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);

View File

@ -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,
);

View File

@ -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

View File

@ -275,7 +275,7 @@ impl UseTree {
shape: Shape,
) -> Option<String> {
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<String> {
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() {

View File

@ -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));
@ -1127,12 +1127,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()
&& 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));
}
@ -1149,9 +1161,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 !items.is_empty() || contains_comment(&snippet[open_pos..]) {
@ -1181,18 +1190,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<String> {
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,
@ -1225,7 +1222,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))
@ -1243,7 +1240,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 = ";"
@ -1391,7 +1388,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))
}
@ -1514,17 +1511,84 @@ fn format_tuple_struct(
Some(result)
}
pub(crate) fn rewrite_type<R: Rewrite>(
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::TyAlias,
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<String> {
use ItemVisitorKind::*;
let ast::TyAlias {
defaultness,
ref generics,
ref 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 { bounds };
rewrite_ty(rw_info, Some(bounds), Some(&op_ty), 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)
} 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(bounds), ty.as_ref(), vis)
}
}
}
fn rewrite_ty<R: Rewrite>(
rw_info: &TyAliasRewriteInfo<'_, '_>,
generic_bounds_opt: Option<&ast::GenericBounds>,
rhs: Option<&R>,
vis: &ast::Visibility,
) -> Option<String> {
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);
@ -1612,28 +1676,6 @@ pub(crate) fn rewrite_type<R: Rewrite>(
}
}
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<String> {
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 { "" },
@ -1871,42 +1913,6 @@ impl<'a> Rewrite for OpaqueType<'a> {
}
}
pub(crate) fn rewrite_impl_type(
ident: symbol::Ident,
vis: &ast::Visibility,
defaultness: ast::Defaultness,
ty_opt: Option<&ptr::P<ast::Ty>>,
generics: &ast::Generics,
context: &RewriteContext<'_>,
indent: Indent,
span: Span,
) -> Option<String> {
// 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<String> {
match *self {
@ -2071,7 +2077,7 @@ fn rewrite_explicit_self(
)?;
Some(combine_strs_with_missing_comments(
context,
&param_attrs,
param_attrs,
&format!("&{} {}self", lifetime_str, mut_str),
span,
shape,
@ -2080,7 +2086,7 @@ fn rewrite_explicit_self(
}
None => Some(combine_strs_with_missing_comments(
context,
&param_attrs,
param_attrs,
&format!("&{}self", mut_str),
span,
shape,
@ -2096,7 +2102,7 @@ fn rewrite_explicit_self(
Some(combine_strs_with_missing_comments(
context,
&param_attrs,
param_attrs,
&format!("{}self: {}", format_mutability(mutability), type_str),
span,
shape,
@ -2105,7 +2111,7 @@ fn rewrite_explicit_self(
}
ast::SelfKind::Value(mutability) => Some(combine_strs_with_missing_comments(
context,
&param_attrs,
param_attrs,
&format!("{}self", format_mutability(mutability)),
span,
shape,
@ -2231,7 +2237,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
@ -2989,7 +2995,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();
@ -3010,7 +3016,7 @@ fn format_header(
}
}
result.push_str(&rewrite_ident(context, ident));
result.push_str(rewrite_ident(context, ident));
result
}
@ -3177,23 +3183,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::TyAlias {
ref generics,
ref bounds,
ref ty,
..
} = **ty_alias_kind;
rewrite_type(
&context,
shape.indent,
self.ident,
&self.vis,
generics,
Some(bounds),
ty.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)
@ -3243,7 +3235,7 @@ fn rewrite_attrs(
combine_strs_with_missing_comments(
context,
&attrs_str,
&item_str,
item_str,
missed_span,
shape,
allow_extend,

View File

@ -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(())
}
}

View File

@ -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 {

View File

@ -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(&macro_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());

View File

@ -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()
@ -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)
};

View File

@ -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),
@ -197,7 +199,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
/// Visit modules from AST.
fn visit_mod_from_ast(
&mut self,
items: &'ast Vec<rustc_ast::ptr::P<ast::Item>>,
items: &'ast [rustc_ast::ptr::P<ast::Item>],
) -> Result<(), ModuleResolutionError> {
for item in items {
if is_cfg_if(item) {
@ -290,7 +292,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,9 +319,11 @@ 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(ast::ModKind::Loaded(items, _, _))), _) | (_, Cow::Owned(items)) => {
self.visit_mod_outside_ast(items)
}
(Some(Cow::Owned(..)), Cow::Owned(items)) => self.visit_mod_outside_ast(items),
(_, _) => Ok(()),
}
}

View File

@ -394,7 +394,7 @@ impl<'a> Context<'a> {
) -> Option<String> {
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.

View File

@ -55,11 +55,11 @@ fn rewrite_pairs_one_line<T: Rewrite>(
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<T: Rewrite>(
shape: Shape,
context: &RewriteContext<'_>,
) -> Option<String> {
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<T: Rewrite>(
}
}
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)?,

View File

@ -456,11 +456,11 @@ fn rewrite_tuple_pat(
context: &RewriteContext<'_>,
shape: Shape,
) -> Option<String> {
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
{
@ -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,

View File

@ -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),
};

View File

@ -112,7 +112,7 @@ impl<'a> Parser<'a> {
span: Span,
) -> Result<(Vec<ast::Attribute>, Vec<ptr::P<ast::Item>>, 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) => {
@ -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),
}

View File

@ -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) {

View File

@ -535,9 +535,9 @@ fn check_files(files: Vec<PathBuf>, opt_config: &Option<PathBuf>) -> (Vec<Format
debug!("Testing '{}'...", file_name.display());
match idempotent_check(&file_name, &opt_config) {
match idempotent_check(&file_name, opt_config) {
Ok(ref report) if report.has_warnings() => {
print!("{}", FormatReportFormatterBuilder::new(&report).build());
print!("{}", FormatReportFormatterBuilder::new(report).build());
fails += 1;
}
Ok(report) => reports.push(report),

View File

@ -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::<io::Stdout>::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",
],
);
}

View File

@ -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);
}

View File

@ -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())
);
}

View File

@ -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;
@ -164,7 +163,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 +272,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 +438,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 +487,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) => {
@ -568,40 +567,9 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
self.push_rewrite(item.span, rewrite);
}
}
ast::ItemKind::TyAlias(ref alias_kind) => {
let ast::TyAlias {
ref generics,
ref 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(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,
bounds,
generics,
&item.vis,
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);
}
ast::ItemKind::GlobalAsm(..) => {
let snippet = Some(self.snippet(item.span).to_owned());
@ -624,18 +592,46 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
self.skip_context = skip_context_saved;
}
pub(crate) fn visit_trait_item(&mut self, ti: &ast::AssocItem) {
skip_out_of_file_lines_range_visitor!(self, ti.span);
fn visit_ty_alias_kind(
&mut self,
ty_kind: &ast::TyAlias,
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);
}
if self.visit_attrs(&ti.attrs, ast::AttrStyle::Outer) {
self.push_skipped_with_span(ti.attrs.as_slice(), ti.span(), 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(&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::Fn {
defaultness,
ref sig,
@ -643,108 +639,39 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
ref body,
} = **fn_kind;
if let Some(ref body) = body {
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) => {
let ast::TyAlias {
ref generics,
ref bounds,
ref ty,
..
} = **ty_alias_kind;
let rewrite = rewrite_type(
&self.get_context(),
self.block_indent,
ti.ident,
&ti.vis,
generics,
Some(bounds),
ty.as_ref(),
ti.span,
);
self.push_rewrite(ti.span, rewrite);
(ast::AssocItemKind::TyAlias(ref ty_alias), _) => {
self.visit_ty_alias_kind(ty_alias, 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::Fn {
defaultness,
ref sig,
ref generics,
ref body,
} = **fn_kind;
if let Some(ref body) = body {
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) => {
let ast::TyAlias {
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,
),
);
}
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<symbol::Ident>, pos: MacroPosition) {
@ -921,7 +848,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
}
fn walk_mod_items(&mut self, items: &[rustc_ast::ptr::P<ast::Item>]) {
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) {

View File

@ -0,0 +1,2 @@
mod bar {
mod baz;}

View File

@ -0,0 +1 @@
fn baz() { }

View File

@ -0,0 +1,5 @@
fn main() {
println!("Hello, world!");
}
mod foo;

View File

@ -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;

View File

@ -0,0 +1,7 @@
// rustfmt-group_imports: One
mod test {
use crate::foo::bar;
use std::path;
use crate::foo::bar2;
}

View File

@ -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;

View File

@ -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;

View File

@ -0,0 +1,46 @@
// rustfmt-brace_style: AlwaysNextLine
// rustfmt-empty_item_single_line: false
fn function()
{
}
struct Struct
{
}
enum Enum
{
}
trait Trait
{
}
impl<T> Trait for T
{
}
trait Trait2<T>
where
T: Copy + Display + Write + Read + FromStr, {}
trait Trait3<T>
where
T: Something
+ SomethingElse
+ Sync
+ Send
+ Display
+ Debug
+ Copy
+ Hash
+ Debug
+ Display
+ Write
+ Read, {}

View File

@ -27,3 +27,38 @@ mod M {
struct D<T> where T: Copy {}
}
fn function()
{
}
trait Trait
{
}
impl<T> Trait for T
{
}
trait Trait2<T>
where
T: Copy + Display + Write + Read + FromStr, {}
trait Trait3<T>
where
T: Something
+ SomethingElse
+ Sync
+ Send
+ Display
+ Debug
+ Copy
+ Hash
+ Debug
+ Display
+ Write
+ Read, {}

View File

@ -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;

View File

@ -0,0 +1,6 @@
// rustfmt-group_imports: One
mod test {
use crate::foo::bar;
use crate::foo::bar2;
use std::path;
}

View File

@ -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;

View File

@ -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;

View File

@ -0,0 +1,41 @@
// rustfmt-brace_style: AlwaysNextLine
// rustfmt-empty_item_single_line: false
fn function()
{
}
struct Struct {}
enum Enum {}
trait Trait
{
}
impl<T> Trait for T
{
}
trait Trait2<T>
where
T: Copy + Display + Write + Read + FromStr,
{
}
trait Trait3<T>
where
T: Something
+ SomethingElse
+ Sync
+ Send
+ Display
+ Debug
+ Copy
+ Hash
+ Debug
+ Display
+ Write
+ Read,
{
}

View File

@ -0,0 +1,8 @@
// rustfmt-trailing_comma: Always
pub struct Matrix<T, const R: usize, const C: usize,>
where
[T; R * C]:,
{
contents: [T; R * C],
}

View File

@ -0,0 +1,8 @@
// rustfmt-trailing_comma: Never
pub struct Matrix<T, const R: usize, const C: usize>
where
[T; R * C]:
{
contents: [T; R * C]
}

View File

@ -0,0 +1,8 @@
// leading comment
#![rustfmt::skip]
fn main() {
println!("main"); // commented
}
// post comment

View File

@ -0,0 +1,11 @@
#![rustfmt::skip]
mod a {
mod b {
}
// trailing comment b
}
// trailing comment a

View File

@ -0,0 +1,4 @@
impl ThisIsALongStructNameToPushTheWhereToWrapLolololol where
[(); this_is_a_long_const_function_name()]:
{
}

View File

@ -40,3 +40,32 @@ mod M
where
T: Copy, {}
}
fn function() {}
trait Trait {}
impl<T> Trait for T {}
trait Trait2<T>
where
T: Copy + Display + Write + Read + FromStr,
{
}
trait Trait3<T>
where
T: Something
+ SomethingElse
+ Sync
+ Send
+ Display
+ Debug
+ Copy
+ Hash
+ Debug
+ Display
+ Write
+ Read,
{
}