From 8211d64c71bd3ab050ef5840c825fd762f33abb3 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Tue, 29 Mar 2022 23:17:30 -0500 Subject: [PATCH 01/53] Merge commit '5ff7b632a95bac6955611d85040859128902c580' into sync-rustfmt-subtree --- .github/workflows/linux.yml | 4 + CHANGELOG.md | 5 + Cargo.lock | 4 +- Configurations.md | 38 +++- config_proc_macro/src/utils.rs | 4 +- rust-toolchain | 2 +- src/attr.rs | 6 +- src/bin/main.rs | 38 ++-- src/cargo-fmt/main.rs | 3 +- src/comment.rs | 64 ++++-- src/config/file_lines.rs | 2 +- src/config/mod.rs | 7 +- src/emitter/checkstyle.rs | 12 +- src/emitter/diff.rs | 5 +- src/emitter/json.rs | 187 +++++++++--------- src/format_report_formatter.rs | 1 + src/ignore_path.rs | 9 +- src/imports.rs | 56 ++++-- src/items.rs | 26 ++- src/lists.rs | 27 ++- src/macros.rs | 16 +- src/modules.rs | 47 ++++- src/overflow.rs | 13 +- src/parse/session.rs | 34 +++- src/spanned.rs | 15 +- src/string.rs | 5 +- src/test/configuration_snippet.rs | 30 +++ src/test/mod.rs | 128 +++++++++++- src/test/mod_resolver.rs | 30 +++ src/types.rs | 11 +- src/utils.rs | 19 +- src/vertical.rs | 23 ++- tests/cargo-fmt/main.rs | 25 +++ tests/mod-resolver/issue-5167/src/a.rs | 0 tests/mod-resolver/issue-5167/src/a/mod.rs | 0 tests/mod-resolver/issue-5167/src/lib.rs | 1 + tests/mod-resolver/issue-5198/a.rs | 1 + tests/mod-resolver/issue-5198/lib.rs | 3 + tests/mod-resolver/issue-5198/lib/b.rs | 1 + tests/mod-resolver/issue-5198/lib/c/d.rs | 3 + .../issue-5198/lib/c/d/explanation.txt | 16 ++ tests/mod-resolver/issue-5198/lib/c/d/f.rs | 1 + .../mod-resolver/issue-5198/lib/c/d/g/mod.rs | 1 + tests/mod-resolver/issue-5198/lib/c/e.rs | 1 + tests/mod-resolver/issue-5198/lib/c/mod.rs | 3 + .../issue-5198/lib/explanation.txt | 16 ++ .../bad_path_attribute/lib.rs | 3 + .../module-not-found/relative_module/a.rs | 2 + .../module-not-found/relative_module/lib.rs | 1 + .../module-not-found/sibling_module/lib.rs | 2 + .../test-submodule-issue-5119/Cargo.toml | 8 + .../test-submodule-issue-5119/src/lib.rs | 7 + .../test-submodule-issue-5119/tests/test1.rs | 8 + .../tests/test1/sub1.rs | 6 + .../tests/test1/sub2.rs | 6 + .../tests/test1/sub3/mod.rs | 1 + .../tests/test1/sub3/sub4.rs | 0 tests/rustfmt/main.rs | 51 +++++ tests/source/5131_crate.rs | 14 ++ tests/source/5131_module.rs | 33 ++++ tests/source/5131_one.rs | 15 ++ .../short_array_element_width_threshold/10.rs | 11 ++ .../short_array_element_width_threshold/20.rs | 11 ++ .../greater_than_max_width.rs | 12 ++ tests/source/extern.rs | 13 ++ tests/source/imports_granularity_module.rs | 1 + tests/source/issue-4036/one.rs | 11 ++ tests/source/issue-4036/three.rs | 12 ++ tests/source/issue-4036/two.rs | 11 ++ tests/source/issue-4791/buggy.rs | 14 ++ tests/source/issue-4791/trailing_comma.rs | 14 ++ tests/source/issue-5023.rs | 22 +++ .../multi-line_comment_with_trailing_comma.rs | 24 +++ ...lti-line_comment_without_trailing_comma.rs | 24 +++ ...single-line_comment_with_trailing_comma.rs | 9 + ...gle-line_comment_without_trailing_comma.rs | 10 + .../indented_itemized_markdown_blockquote.rs | 4 + .../nested_itemized_markdown_blockquote.rs | 10 + .../support_itemized_markdown_blockquote.rs | 4 + .../markdown_header_wrap_comments_false.rs | 11 ++ .../markdown_header_wrap_comments_true.rs | 11 ++ tests/source/issue-5270/merge_derives_true.rs | 62 ++++++ tests/source/issue_4854.rs | 113 +++++++++++ tests/target/5131_crate.rs | 9 + tests/target/5131_module.rs | 32 +++ tests/target/5131_one.rs | 12 ++ .../comments-in-lists/format-doc-comments.rs | 10 +- .../comments-in-lists/wrap-comments-false.rs | 10 +- .../wrap-comments-not-normalized.rs | 8 +- .../comments-in-lists/wrap-comments-true.rs | 8 +- .../short_array_element_width_threshold/10.rs | 11 ++ .../short_array_element_width_threshold/20.rs | 8 + .../greater_than_max_width.rs | 12 ++ tests/target/doc-of-generic-item.rs | 14 ++ tests/target/extern.rs | 13 ++ tests/target/imports_granularity_module.rs | 2 + tests/target/issue-4036/one.rs | 12 ++ tests/target/issue-4036/three.rs | 17 ++ tests/target/issue-4036/two.rs | 16 ++ tests/target/issue-4791/buggy.rs | 14 ++ tests/target/issue-4791/issue_4928.rs | 70 +++++++ tests/target/issue-4791/no_trailing_comma.rs | 8 + tests/target/issue-4791/trailing_comma.rs | 14 ++ tests/target/issue-5023.rs | 23 +++ .../multi-line_comment_with_trailing_comma.rs | 24 +++ ...lti-line_comment_without_trailing_comma.rs | 24 +++ ...single-line_comment_with_trailing_comma.rs | 7 + ...gle-line_comment_without_trailing_comma.rs | 7 + .../attributes_in_formal_fuction_parameter.rs | 6 + .../long_parameter_in_different_positions.rs | 24 +++ tests/target/issue-5125/minimum_example.rs | 6 + .../with_leading_and_inline_comments.rs | 7 + .../indented_itemized_markdown_blockquote.rs | 6 + .../nested_itemized_markdown_blockquote.rs | 18 ++ .../support_itemized_markdown_blockquote.rs | 6 + .../markdown_header_wrap_comments_false.rs | 11 ++ .../markdown_header_wrap_comments_true.rs | 14 ++ .../target/issue-5270/merge_derives_false.rs | 62 ++++++ tests/target/issue-5270/merge_derives_true.rs | 60 ++++++ tests/target/issue_4854.rs | 115 +++++++++++ tests/target/issue_5273.rs | 3 + tests/writemode/source/stdin.rs | 6 + tests/writemode/target/output.json | 2 +- tests/writemode/target/stdin.json | 1 + tests/writemode/target/stdin.xml | 2 + 125 files changed, 2013 insertions(+), 235 deletions(-) create mode 100644 tests/mod-resolver/issue-5167/src/a.rs create mode 100644 tests/mod-resolver/issue-5167/src/a/mod.rs create mode 100644 tests/mod-resolver/issue-5167/src/lib.rs create mode 100644 tests/mod-resolver/issue-5198/a.rs create mode 100644 tests/mod-resolver/issue-5198/lib.rs create mode 100644 tests/mod-resolver/issue-5198/lib/b.rs create mode 100644 tests/mod-resolver/issue-5198/lib/c/d.rs create mode 100644 tests/mod-resolver/issue-5198/lib/c/d/explanation.txt create mode 100644 tests/mod-resolver/issue-5198/lib/c/d/f.rs create mode 100644 tests/mod-resolver/issue-5198/lib/c/d/g/mod.rs create mode 100644 tests/mod-resolver/issue-5198/lib/c/e.rs create mode 100644 tests/mod-resolver/issue-5198/lib/c/mod.rs create mode 100644 tests/mod-resolver/issue-5198/lib/explanation.txt create mode 100644 tests/mod-resolver/module-not-found/bad_path_attribute/lib.rs create mode 100644 tests/mod-resolver/module-not-found/relative_module/a.rs create mode 100644 tests/mod-resolver/module-not-found/relative_module/lib.rs create mode 100644 tests/mod-resolver/module-not-found/sibling_module/lib.rs create mode 100644 tests/mod-resolver/test-submodule-issue-5119/Cargo.toml create mode 100644 tests/mod-resolver/test-submodule-issue-5119/src/lib.rs create mode 100644 tests/mod-resolver/test-submodule-issue-5119/tests/test1.rs create mode 100644 tests/mod-resolver/test-submodule-issue-5119/tests/test1/sub1.rs create mode 100644 tests/mod-resolver/test-submodule-issue-5119/tests/test1/sub2.rs create mode 100644 tests/mod-resolver/test-submodule-issue-5119/tests/test1/sub3/mod.rs create mode 100644 tests/mod-resolver/test-submodule-issue-5119/tests/test1/sub3/sub4.rs create mode 100644 tests/source/5131_crate.rs create mode 100644 tests/source/5131_module.rs create mode 100644 tests/source/5131_one.rs create mode 100644 tests/source/configs/short_array_element_width_threshold/10.rs create mode 100644 tests/source/configs/short_array_element_width_threshold/20.rs create mode 100644 tests/source/configs/short_array_element_width_threshold/greater_than_max_width.rs create mode 100644 tests/source/issue-4036/one.rs create mode 100644 tests/source/issue-4036/three.rs create mode 100644 tests/source/issue-4036/two.rs create mode 100644 tests/source/issue-4791/buggy.rs create mode 100644 tests/source/issue-4791/trailing_comma.rs create mode 100644 tests/source/issue-5023.rs create mode 100644 tests/source/issue-5042/multi-line_comment_with_trailing_comma.rs create mode 100644 tests/source/issue-5042/multi-line_comment_without_trailing_comma.rs create mode 100644 tests/source/issue-5042/single-line_comment_with_trailing_comma.rs create mode 100644 tests/source/issue-5042/single-line_comment_without_trailing_comma.rs create mode 100644 tests/source/issue-5157/indented_itemized_markdown_blockquote.rs create mode 100644 tests/source/issue-5157/nested_itemized_markdown_blockquote.rs create mode 100644 tests/source/issue-5157/support_itemized_markdown_blockquote.rs create mode 100644 tests/source/issue-5238/markdown_header_wrap_comments_false.rs create mode 100644 tests/source/issue-5238/markdown_header_wrap_comments_true.rs create mode 100644 tests/source/issue-5270/merge_derives_true.rs create mode 100644 tests/source/issue_4854.rs create mode 100644 tests/target/5131_crate.rs create mode 100644 tests/target/5131_module.rs create mode 100644 tests/target/5131_one.rs create mode 100644 tests/target/configs/short_array_element_width_threshold/10.rs create mode 100644 tests/target/configs/short_array_element_width_threshold/20.rs create mode 100644 tests/target/configs/short_array_element_width_threshold/greater_than_max_width.rs create mode 100644 tests/target/doc-of-generic-item.rs create mode 100644 tests/target/issue-4036/one.rs create mode 100644 tests/target/issue-4036/three.rs create mode 100644 tests/target/issue-4036/two.rs create mode 100644 tests/target/issue-4791/buggy.rs create mode 100644 tests/target/issue-4791/issue_4928.rs create mode 100644 tests/target/issue-4791/no_trailing_comma.rs create mode 100644 tests/target/issue-4791/trailing_comma.rs create mode 100644 tests/target/issue-5023.rs create mode 100644 tests/target/issue-5042/multi-line_comment_with_trailing_comma.rs create mode 100644 tests/target/issue-5042/multi-line_comment_without_trailing_comma.rs create mode 100644 tests/target/issue-5042/single-line_comment_with_trailing_comma.rs create mode 100644 tests/target/issue-5042/single-line_comment_without_trailing_comma.rs create mode 100644 tests/target/issue-5125/attributes_in_formal_fuction_parameter.rs create mode 100644 tests/target/issue-5125/long_parameter_in_different_positions.rs create mode 100644 tests/target/issue-5125/minimum_example.rs create mode 100644 tests/target/issue-5125/with_leading_and_inline_comments.rs create mode 100644 tests/target/issue-5157/indented_itemized_markdown_blockquote.rs create mode 100644 tests/target/issue-5157/nested_itemized_markdown_blockquote.rs create mode 100644 tests/target/issue-5157/support_itemized_markdown_blockquote.rs create mode 100644 tests/target/issue-5238/markdown_header_wrap_comments_false.rs create mode 100644 tests/target/issue-5238/markdown_header_wrap_comments_true.rs create mode 100644 tests/target/issue-5270/merge_derives_false.rs create mode 100644 tests/target/issue-5270/merge_derives_true.rs create mode 100644 tests/target/issue_4854.rs create mode 100644 tests/target/issue_5273.rs create mode 100644 tests/writemode/source/stdin.rs create mode 100644 tests/writemode/target/stdin.json create mode 100644 tests/writemode/target/stdin.xml diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index db49794164212..45f63b83c0562 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -40,6 +40,10 @@ jobs: rustc -Vv cargo -V cargo build + env: + RUSTFLAGS: '-D warnings' - name: test run: cargo test + env: + RUSTFLAGS: '-D warnings' diff --git a/CHANGELOG.md b/CHANGELOG.md index b59438dc4fe78..5b23360858356 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 @@ -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 diff --git a/Cargo.lock b/Cargo.lock index 2ef83ddd1ae6c..b932e15ef7461 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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", ] diff --git a/Configurations.md b/Configurations.md index 4476f2a449b1f..a47439b9ba96c 100644 --- a/Configurations.md +++ b/Configurations.md @@ -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` @@ -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` diff --git a/config_proc_macro/src/utils.rs b/config_proc_macro/src/utils.rs index 5b68d2748490f..f5cba87b07b67 100644 --- a/config_proc_macro/src/utils.rs +++ b/config_proc_macro/src/utils.rs @@ -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 { diff --git a/rust-toolchain b/rust-toolchain index d4cdcec2018aa..94b57d506c20b 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2021-12-29" +channel = "nightly-2022-03-27" components = ["rustc-dev"] diff --git a/src/attr.rs b/src/attr.rs index 3887a8051f209..befe12ae2c4cd 100644 --- a/src/attr.rs +++ b/src/attr.rs @@ -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. @@ -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); diff --git a/src/bin/main.rs b/src/bin/main.rs index 4d845547cdfed..ad10b9ede608f 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -26,7 +26,7 @@ fn main() { let exit_code = match execute(&opts) { Ok(code) => code, Err(e) => { - eprintln!("{}", e); + eprintln!("{:#}", e); 1 } }; @@ -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 for OperationError { @@ -255,15 +251,20 @@ fn format_string(input: String, options: GetOptsOptions) -> Result { 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 @@ -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] ...", - sep, - env::args_os().next().unwrap().to_string_lossy() + "{}Format Rust code\n\nusage: rustfmt [options] ...", + sep ); println!("{}", opts.usage(&msg)); } diff --git a/src/cargo-fmt/main.rs b/src/cargo-fmt/main.rs index 759b21218c353..8cb7b4585ecb2 100644 --- a/src/cargo-fmt/main.rs +++ b/src/cargo-fmt/main.rs @@ -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(), }; diff --git a/src/comment.rs b/src/comment.rs index 0f850b9b2f2fb..f9d8a0fa70c00 100644 --- a/src/comment.rs +++ b/src/comment.rs @@ -432,16 +432,16 @@ 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, - /// 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, } @@ -449,19 +449,32 @@ 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, } } @@ -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, @@ -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; @@ -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'); @@ -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; } } diff --git a/src/config/file_lines.rs b/src/config/file_lines.rs index 7b498dc46b320..e4e51a3f3b409 100644 --- a/src/config/file_lines.rs +++ b/src/config/file_lines.rs @@ -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, ""), } } } diff --git a/src/config/mod.rs b/src/config/mod.rs index cd90e0904b6cd..18e1854612bf7 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -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, @@ -364,7 +366,9 @@ fn get_toml_path(dir: &Path) -> Result, 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)); } } _ => {} @@ -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 diff --git a/src/emitter/checkstyle.rs b/src/emitter/checkstyle.rs index 76f2527db3dad..545b259979d91 100644 --- a/src/emitter/checkstyle.rs +++ b/src/emitter/checkstyle.rs @@ -2,7 +2,6 @@ use self::xml::XmlEscaped; use super::*; use crate::rustfmt_diff::{make_diff, DiffLine, Mismatch}; use std::io::{self, Write}; -use std::path::Path; mod xml; @@ -30,7 +29,6 @@ impl Emitter for CheckstyleEmitter { }: FormattedFile<'_>, ) -> Result { const CONTEXT_SIZE: usize = 0; - let filename = ensure_real_path(filename); let diff = make_diff(original_text, formatted_text, CONTEXT_SIZE); output_checkstyle_file(output, filename, diff)?; Ok(EmitterResult::default()) @@ -39,13 +37,13 @@ impl Emitter for CheckstyleEmitter { pub(crate) fn output_checkstyle_file( mut writer: T, - filename: &Path, + filename: &FileName, diff: Vec, ) -> Result<(), io::Error> where T: Write, { - write!(writer, r#""#, filename.display())?; + write!(writer, r#""#, filename)?; for mismatch in diff { let begin_line = mismatch.line_number; let mut current_line; @@ -77,7 +75,11 @@ mod tests { fn emits_empty_record_on_file_with_no_mismatches() { let file_name = "src/well_formatted.rs"; let mut writer = Vec::new(); - let _ = output_checkstyle_file(&mut writer, &PathBuf::from(file_name), vec![]); + let _ = output_checkstyle_file( + &mut writer, + &FileName::Real(PathBuf::from(file_name)), + vec![], + ); assert_eq!( &writer[..], format!(r#""#, file_name).as_bytes() diff --git a/src/emitter/diff.rs b/src/emitter/diff.rs index 7264ad8bbf365..5e1f134465605 100644 --- a/src/emitter/diff.rs +++ b/src/emitter/diff.rs @@ -28,7 +28,7 @@ impl Emitter for DiffEmitter { if has_diff { if self.config.print_misformatted_file_names() { - writeln!(output, "{}", ensure_real_path(filename).display())?; + writeln!(output, "{}", filename)?; } else { print_diff( mismatch, @@ -40,8 +40,7 @@ impl Emitter for DiffEmitter { // This occurs when the only difference between the original and formatted values // is the newline style. This happens because The make_diff function compares the // original and formatted values line by line, independent of line endings. - let file_path = ensure_real_path(filename); - writeln!(output, "Incorrect newline style in {}", file_path.display())?; + writeln!(output, "Incorrect newline style in {}", filename)?; return Ok(EmitterResult { has_diff: true }); } diff --git a/src/emitter/json.rs b/src/emitter/json.rs index 269dd2d4daf57..c7f68d4675a67 100644 --- a/src/emitter/json.rs +++ b/src/emitter/json.rs @@ -3,14 +3,13 @@ use crate::rustfmt_diff::{make_diff, DiffLine, Mismatch}; use serde::Serialize; use serde_json::to_string as to_json_string; use std::io::{self, Write}; -use std::path::Path; #[derive(Debug, Default)] pub(crate) struct JsonEmitter { - num_files: u32, + mismatched_files: Vec, } -#[derive(Debug, Default, Serialize)] +#[derive(Debug, Default, PartialEq, Serialize)] struct MismatchedBlock { original_begin_line: u32, original_end_line: u32, @@ -20,26 +19,20 @@ struct MismatchedBlock { expected: String, } -#[derive(Debug, Default, Serialize)] +#[derive(Debug, Default, PartialEq, Serialize)] struct MismatchedFile { name: String, mismatches: Vec, } impl Emitter for JsonEmitter { - fn emit_header(&self, output: &mut dyn Write) -> Result<(), io::Error> { - write!(output, "[")?; - Ok(()) - } - fn emit_footer(&self, output: &mut dyn Write) -> Result<(), io::Error> { - write!(output, "]")?; - Ok(()) + writeln!(output, "{}", &to_json_string(&self.mismatched_files)?) } fn emit_formatted_file( &mut self, - output: &mut dyn Write, + _output: &mut dyn Write, FormattedFile { filename, original_text, @@ -47,71 +40,67 @@ impl Emitter for JsonEmitter { }: FormattedFile<'_>, ) -> Result { const CONTEXT_SIZE: usize = 0; - let filename = ensure_real_path(filename); let diff = make_diff(original_text, formatted_text, CONTEXT_SIZE); let has_diff = !diff.is_empty(); if has_diff { - output_json_file(output, filename, diff, self.num_files)?; - self.num_files += 1; + self.add_misformatted_file(filename, diff)?; } Ok(EmitterResult { has_diff }) } } -fn output_json_file( - mut writer: T, - filename: &Path, - diff: Vec, - num_emitted_files: u32, -) -> Result<(), io::Error> -where - T: Write, -{ - let mut mismatches = vec![]; - for mismatch in diff { - let original_begin_line = mismatch.line_number_orig; - let expected_begin_line = mismatch.line_number; - let mut original_end_line = original_begin_line; - let mut expected_end_line = expected_begin_line; - let mut original_line_counter = 0; - let mut expected_line_counter = 0; - let mut original_lines = vec![]; - let mut expected_lines = vec![]; +impl JsonEmitter { + fn add_misformatted_file( + &mut self, + filename: &FileName, + diff: Vec, + ) -> Result<(), io::Error> { + let mut mismatches = vec![]; + for mismatch in diff { + let original_begin_line = mismatch.line_number_orig; + let expected_begin_line = mismatch.line_number; + let mut original_end_line = original_begin_line; + let mut expected_end_line = expected_begin_line; + let mut original_line_counter = 0; + let mut expected_line_counter = 0; + let mut original = String::new(); + let mut expected = String::new(); - for line in mismatch.lines { - match line { - DiffLine::Expected(msg) => { - expected_end_line = expected_begin_line + expected_line_counter; - expected_line_counter += 1; - expected_lines.push(msg) - } - DiffLine::Resulting(msg) => { - original_end_line = original_begin_line + original_line_counter; - original_line_counter += 1; - original_lines.push(msg) + for line in mismatch.lines { + match line { + DiffLine::Expected(msg) => { + expected_end_line = expected_begin_line + expected_line_counter; + expected_line_counter += 1; + expected.push_str(&msg); + expected.push('\n'); + } + DiffLine::Resulting(msg) => { + original_end_line = original_begin_line + original_line_counter; + original_line_counter += 1; + original.push_str(&msg); + original.push('\n'); + } + DiffLine::Context(_) => continue, } - DiffLine::Context(_) => continue, } - } - mismatches.push(MismatchedBlock { - original_begin_line, - original_end_line, - expected_begin_line, - expected_end_line, - original: original_lines.join("\n"), - expected: expected_lines.join("\n"), + mismatches.push(MismatchedBlock { + original_begin_line, + original_end_line, + expected_begin_line, + expected_end_line, + original, + expected, + }); + } + self.mismatched_files.push(MismatchedFile { + name: format!("{}", filename), + mismatches, }); + Ok(()) } - let json = to_json_string(&MismatchedFile { - name: String::from(filename.to_str().unwrap()), - mismatches, - })?; - let prefix = if num_emitted_files > 0 { "," } else { "" }; - write!(writer, "{}{}", prefix, &json)?; - Ok(()) } #[cfg(test)] @@ -122,6 +111,9 @@ mod tests { #[test] fn expected_line_range_correct_when_single_line_split() { + let mut emitter = JsonEmitter { + mismatched_files: vec![], + }; let file = "foo/bar.rs"; let mismatched_file = MismatchedFile { name: String::from(file), @@ -130,8 +122,8 @@ mod tests { original_end_line: 79, expected_begin_line: 79, expected_end_line: 82, - original: String::from("fn Foo() where T: Bar {"), - expected: String::from("fn Foo()\nwhere\n T: Bar,\n{"), + original: String::from("fn Foo() where T: Bar {\n"), + expected: String::from("fn Foo()\nwhere\n T: Bar,\n{\n"), }], }; let mismatch = Mismatch { @@ -146,14 +138,19 @@ mod tests { ], }; - let mut writer = Vec::new(); - let exp_json = to_json_string(&mismatched_file).unwrap(); - let _ = output_json_file(&mut writer, &PathBuf::from(file), vec![mismatch], 0); - assert_eq!(&writer[..], format!("{}", exp_json).as_bytes()); + let _ = emitter + .add_misformatted_file(&FileName::Real(PathBuf::from(file)), vec![mismatch]) + .unwrap(); + + assert_eq!(emitter.mismatched_files.len(), 1); + assert_eq!(emitter.mismatched_files[0], mismatched_file); } #[test] fn context_lines_ignored() { + let mut emitter = JsonEmitter { + mismatched_files: vec![], + }; let file = "src/lib.rs"; let mismatched_file = MismatchedFile { name: String::from(file), @@ -163,10 +160,10 @@ mod tests { expected_begin_line: 5, expected_end_line: 5, original: String::from( - "fn foo(_x: &u64) -> Option<&(dyn::std::error::Error + 'static)> {", + "fn foo(_x: &u64) -> Option<&(dyn::std::error::Error + 'static)> {\n", ), expected: String::from( - "fn foo(_x: &u64) -> Option<&(dyn ::std::error::Error + 'static)> {", + "fn foo(_x: &u64) -> Option<&(dyn ::std::error::Error + 'static)> {\n", ), }], }; @@ -186,10 +183,12 @@ mod tests { ], }; - let mut writer = Vec::new(); - let exp_json = to_json_string(&mismatched_file).unwrap(); - let _ = output_json_file(&mut writer, &PathBuf::from(file), vec![mismatch], 0); - assert_eq!(&writer[..], format!("{}", exp_json).as_bytes()); + let _ = emitter + .add_misformatted_file(&FileName::Real(PathBuf::from(file)), vec![mismatch]) + .unwrap(); + + assert_eq!(emitter.mismatched_files.len(), 1); + assert_eq!(emitter.mismatched_files[0], mismatched_file); } #[test] @@ -209,7 +208,7 @@ mod tests { .unwrap(); let _ = emitter.emit_footer(&mut writer); assert_eq!(result.has_diff, false); - assert_eq!(&writer[..], "[]".as_bytes()); + assert_eq!(&writer[..], "[]\n".as_bytes()); } #[test] @@ -255,7 +254,7 @@ mod tests { ) .unwrap(); let _ = emitter.emit_footer(&mut writer); - let exp_json = to_json_string(&MismatchedFile { + let exp_json = to_json_string(&vec![MismatchedFile { name: String::from(file_name), mismatches: vec![ MismatchedBlock { @@ -263,8 +262,8 @@ mod tests { original_end_line: 2, expected_begin_line: 2, expected_end_line: 2, - original: String::from("println!(\"Hello, world!\");"), - expected: String::from(" println!(\"Hello, world!\");"), + original: String::from("println!(\"Hello, world!\");\n"), + expected: String::from(" println!(\"Hello, world!\");\n"), }, MismatchedBlock { original_begin_line: 7, @@ -272,17 +271,17 @@ mod tests { expected_begin_line: 7, expected_end_line: 10, original: String::from( - "#[test]\nfn it_works() {\n assert_eq!(2 + 2, 4);\n}", + "#[test]\nfn it_works() {\n assert_eq!(2 + 2, 4);\n}\n", ), expected: String::from( - " #[test]\n fn it_works() {\n assert_eq!(2 + 2, 4);\n }", + " #[test]\n fn it_works() {\n assert_eq!(2 + 2, 4);\n }\n", ), }, ], - }) + }]) .unwrap(); assert_eq!(result.has_diff, true); - assert_eq!(&writer[..], format!("[{}]", exp_json).as_bytes()); + assert_eq!(&writer[..], format!("{}\n", exp_json).as_bytes()); } #[test] @@ -317,33 +316,31 @@ mod tests { ) .unwrap(); let _ = emitter.emit_footer(&mut writer); - let exp_bin_json = to_json_string(&MismatchedFile { + let exp_bin = MismatchedFile { name: String::from(bin_file), mismatches: vec![MismatchedBlock { original_begin_line: 2, original_end_line: 2, expected_begin_line: 2, expected_end_line: 2, - original: String::from("println!(\"Hello, world!\");"), - expected: String::from(" println!(\"Hello, world!\");"), + original: String::from("println!(\"Hello, world!\");\n"), + expected: String::from(" println!(\"Hello, world!\");\n"), }], - }) - .unwrap(); - let exp_lib_json = to_json_string(&MismatchedFile { + }; + + let exp_lib = MismatchedFile { name: String::from(lib_file), mismatches: vec![MismatchedBlock { original_begin_line: 2, original_end_line: 2, expected_begin_line: 2, expected_end_line: 2, - original: String::from("println!(\"Greetings!\");"), - expected: String::from(" println!(\"Greetings!\");"), + original: String::from("println!(\"Greetings!\");\n"), + expected: String::from(" println!(\"Greetings!\");\n"), }], - }) - .unwrap(); - assert_eq!( - &writer[..], - format!("[{},{}]", exp_bin_json, exp_lib_json).as_bytes() - ); + }; + + let exp_json = to_json_string(&vec![exp_bin, exp_lib]).unwrap(); + assert_eq!(&writer[..], format!("{}\n", exp_json).as_bytes()); } } diff --git a/src/format_report_formatter.rs b/src/format_report_formatter.rs index c820259256c47..90406cdb95e2b 100644 --- a/src/format_report_formatter.rs +++ b/src/format_report_formatter.rs @@ -20,6 +20,7 @@ impl<'a> FormatReportFormatterBuilder<'a> { } /// Enables colors and formatting in the output. + #[must_use] pub fn enable_colors(self, enable_colors: bool) -> Self { Self { enable_colors, diff --git a/src/ignore_path.rs b/src/ignore_path.rs index 7738eee0a7604..d955949496a67 100644 --- a/src/ignore_path.rs +++ b/src/ignore_path.rs @@ -32,16 +32,15 @@ impl IgnorePathSet { #[cfg(test)] mod test { - use std::path::{Path, PathBuf}; - - use crate::config::{Config, FileName}; - use crate::ignore_path::IgnorePathSet; - use rustfmt_config_proc_macro::nightly_only_test; #[nightly_only_test] #[test] fn test_ignore_path_set() { + use crate::config::{Config, FileName}; + use crate::ignore_path::IgnorePathSet; + use std::path::{Path, PathBuf}; + let config = Config::from_toml(r#"ignore = ["foo.rs", "bar_dir/*"]"#, Path::new("")).unwrap(); let ignore_path_set = IgnorePathSet::from_ignore_list(&config.ignore()).unwrap(); diff --git a/src/imports.rs b/src/imports.rs index 40e0d06f99df8..0231980948686 100644 --- a/src/imports.rs +++ b/src/imports.rs @@ -190,13 +190,17 @@ pub(crate) fn merge_use_trees(use_trees: Vec, merge_by: SharedPrefix) - continue; } - for flattened in use_tree.flatten() { + for mut flattened in use_tree.flatten() { if let Some(tree) = result .iter_mut() .find(|tree| tree.share_prefix(&flattened, merge_by)) { tree.merge(&flattened, merge_by); } else { + // If this is the first tree with this prefix, handle potential trailing ::self + if merge_by == SharedPrefix::Module { + flattened = flattened.nest_trailing_self(); + } result.push(flattened); } } @@ -208,17 +212,7 @@ pub(crate) fn flatten_use_trees(use_trees: Vec) -> Vec { use_trees .into_iter() .flat_map(UseTree::flatten) - .map(|mut tree| { - // If a path ends in `::self`, rewrite it to `::{self}`. - if let Some(UseSegment::Slf(..)) = tree.path.last() { - let self_segment = tree.path.pop().unwrap(); - tree.path.push(UseSegment::List(vec![UseTree::from_path( - vec![self_segment], - DUMMY_SP, - )])); - } - tree - }) + .map(UseTree::nest_trailing_self) .collect() } @@ -238,7 +232,8 @@ impl fmt::Display for UseSegment { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { UseSegment::Glob => write!(f, "*"), - UseSegment::Ident(ref s, _) => write!(f, "{}", s), + UseSegment::Ident(ref s, Some(ref alias)) => write!(f, "{} as {}", s, alias), + UseSegment::Ident(ref s, None) => write!(f, "{}", s), UseSegment::Slf(..) => write!(f, "self"), UseSegment::Super(..) => write!(f, "super"), UseSegment::Crate(..) => write!(f, "crate"), @@ -622,7 +617,8 @@ impl UseTree { fn merge(&mut self, other: &UseTree, merge_by: SharedPrefix) { let mut prefix = 0; for (a, b) in self.path.iter().zip(other.path.iter()) { - if a.equal_except_alias(b) { + // only discard the alias at the root of the tree + if (prefix == 0 && a.equal_except_alias(b)) || a == b { prefix += 1; } else { break; @@ -633,6 +629,18 @@ impl UseTree { self.span = self.span.to(other.span); } } + + /// If this tree ends in `::self`, rewrite it to `::{self}`. + fn nest_trailing_self(mut self) -> UseTree { + if let Some(UseSegment::Slf(..)) = self.path.last() { + let self_segment = self.path.pop().unwrap(); + self.path.push(UseSegment::List(vec![UseTree::from_path( + vec![self_segment], + DUMMY_SP, + )])); + } + self + } } fn merge_rest( @@ -1309,4 +1317,24 @@ mod test { < parse_use_tree("std::cmp::{b, e, g, f}").normalize() ); } + + #[test] + fn test_use_tree_nest_trailing_self() { + assert_eq!( + parse_use_tree("a::b::self").nest_trailing_self(), + parse_use_tree("a::b::{self}") + ); + assert_eq!( + parse_use_tree("a::b::c").nest_trailing_self(), + parse_use_tree("a::b::c") + ); + assert_eq!( + parse_use_tree("a::b::{c, d}").nest_trailing_self(), + parse_use_tree("a::b::{c, d}") + ); + assert_eq!( + parse_use_tree("a::b::{self, c}").nest_trailing_self(), + parse_use_tree("a::b::{self, c}") + ); + } } diff --git a/src/items.rs b/src/items.rs index 8498cb6addaa1..92f423bbb6275 100644 --- a/src/items.rs +++ b/src/items.rs @@ -1273,7 +1273,13 @@ pub(crate) fn format_struct_struct( result.push_str(&header_str); let header_hi = struct_parts.ident.span.hi(); - let body_lo = context.snippet_provider.span_after(span, "{"); + let body_lo = if let Some(generics) = struct_parts.generics { + // Adjust the span to start at the end of the generic arguments before searching for the '{' + let span = span.with_lo(generics.span.hi()); + context.snippet_provider.span_after(span, "{") + } else { + context.snippet_provider.span_after(span, "{") + }; let generics_str = match struct_parts.generics { Some(g) => format_generics( @@ -1377,17 +1383,21 @@ fn format_empty_struct_or_tuple( result.push_str(&offset.to_string_with_newline(context.config)) } result.push_str(opener); - match rewrite_missing_comment(span, Shape::indented(offset, context.config), context) { + + // indented shape for proper indenting of multi-line comments + let shape = Shape::indented(offset.block_indent(context.config), context.config); + match rewrite_missing_comment(span, shape, context) { Some(ref s) if s.is_empty() => (), Some(ref s) => { - if !is_single_line(s) || first_line_contains_single_line_comment(s) { + let is_multi_line = !is_single_line(s); + if is_multi_line || first_line_contains_single_line_comment(s) { let nested_indent_str = offset .block_indent(context.config) .to_string_with_newline(context.config); result.push_str(&nested_indent_str); } result.push_str(s); - if last_line_contains_single_line_comment(s) { + if is_multi_line || last_line_contains_single_line_comment(s) { result.push_str(&offset.to_string_with_newline(context.config)); } } @@ -2046,9 +2056,15 @@ impl Rewrite for ast::Param { { result.push_str(&ty_str); } else { + let prev_str = if param_attrs_result.is_empty() { + param_attrs_result + } else { + param_attrs_result + &shape.to_string_with_newline(context.config) + }; + result = combine_strs_with_missing_comments( context, - &(param_attrs_result + &shape.to_string_with_newline(context.config)), + &prev_str, param_name, span, shape, diff --git a/src/lists.rs b/src/lists.rs index 29d75585eb725..e87850507824f 100644 --- a/src/lists.rs +++ b/src/lists.rs @@ -611,15 +611,30 @@ pub(crate) fn extract_post_comment( post_snippet: &str, comment_end: usize, separator: &str, + is_last: bool, ) -> Option { let white_space: &[_] = &[' ', '\t']; // Cleanup post-comment: strip separators and whitespace. let post_snippet = post_snippet[..comment_end].trim(); + + let last_inline_comment_ends_with_separator = if is_last { + if let Some(line) = post_snippet.lines().last() { + line.ends_with(separator) && line.trim().starts_with("//") + } else { + false + } + } else { + false + }; + let post_snippet_trimmed = if post_snippet.starts_with(|c| c == ',' || c == ':') { post_snippet[1..].trim_matches(white_space) } else if let Some(stripped) = post_snippet.strip_prefix(separator) { stripped.trim_matches(white_space) + } else if last_inline_comment_ends_with_separator { + // since we're on the last item it's fine to keep any trailing separators in comments + post_snippet.trim_matches(white_space) } // not comment or over two lines else if post_snippet.ends_with(',') @@ -748,14 +763,12 @@ where .snippet_provider .span_to_snippet(mk_sp((self.get_hi)(&item), next_start)) .unwrap_or(""); - let comment_end = get_comment_end( - post_snippet, - self.separator, - self.terminator, - self.inner.peek().is_none(), - ); + let is_last = self.inner.peek().is_none(); + let comment_end = + get_comment_end(post_snippet, self.separator, self.terminator, is_last); let new_lines = has_extra_newline(post_snippet, comment_end); - let post_comment = extract_post_comment(post_snippet, comment_end, self.separator); + let post_comment = + extract_post_comment(post_snippet, comment_end, self.separator, is_last); self.prev_span_end = (self.get_hi)(&item) + BytePos(comment_end as u32); diff --git a/src/macros.rs b/src/macros.rs index f29552caf8d87..664f152e8be1d 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -112,6 +112,7 @@ fn rewrite_macro_name( fn return_macro_parse_failure_fallback( context: &RewriteContext<'_>, indent: Indent, + position: MacroPosition, span: Span, ) -> Option { // Mark this as a failure however we format it @@ -140,7 +141,11 @@ fn return_macro_parse_failure_fallback( )); // Return the snippet unmodified if the macro is not block-like - Some(context.snippet(span).to_owned()) + let mut snippet = context.snippet(span).to_owned(); + if position == MacroPosition::Item { + snippet.push(';'); + } + Some(snippet) } pub(crate) fn rewrite_macro( @@ -152,7 +157,7 @@ pub(crate) fn rewrite_macro( ) -> Option { let should_skip = context .skip_context - .skip_macro(&context.snippet(mac.path.span).to_owned()); + .skip_macro(context.snippet(mac.path.span)); if should_skip { None } else { @@ -233,7 +238,12 @@ fn rewrite_macro_inner( } = match parse_macro_args(context, ts, style, is_forced_bracket) { Some(args) => args, None => { - return return_macro_parse_failure_fallback(context, shape.indent, mac.span()); + return return_macro_parse_failure_fallback( + context, + shape.indent, + position, + mac.span(), + ); } }; diff --git a/src/modules.rs b/src/modules.rs index 64d96a5c6a6e4..a65dc66f7972e 100644 --- a/src/modules.rs +++ b/src/modules.rs @@ -81,6 +81,7 @@ pub struct ModuleResolutionError { pub(crate) kind: ModuleResolutionErrorKind, } +/// Defines variants similar to those of [rustc_expand::module::ModError] #[derive(Debug, Error)] pub(crate) enum ModuleResolutionErrorKind { /// Find a file that cannot be parsed. @@ -89,6 +90,12 @@ pub(crate) enum ModuleResolutionErrorKind { /// File cannot be found. #[error("{file} does not exist")] NotFound { file: PathBuf }, + /// File a.rs and a/mod.rs both exist + #[error("file for module found at both {default_path:?} and {secondary_path:?}")] + MultipleCandidates { + default_path: PathBuf, + secondary_path: PathBuf, + }, } #[derive(Clone)] @@ -444,12 +451,31 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> { } Ok(Some(SubModKind::MultiExternal(mods_outside_ast))) } - Err(_) => Err(ModuleResolutionError { - module: mod_name.to_string(), - kind: ModuleResolutionErrorKind::NotFound { - file: self.directory.path.clone(), - }, - }), + Err(e) => match e { + ModError::FileNotFound(_, default_path, _secondary_path) => { + Err(ModuleResolutionError { + module: mod_name.to_string(), + kind: ModuleResolutionErrorKind::NotFound { file: default_path }, + }) + } + ModError::MultipleCandidates(_, default_path, secondary_path) => { + Err(ModuleResolutionError { + module: mod_name.to_string(), + kind: ModuleResolutionErrorKind::MultipleCandidates { + default_path, + secondary_path, + }, + }) + } + ModError::ParserError(_) + | ModError::CircularInclusion(_) + | ModError::ModInBlock(_) => Err(ModuleResolutionError { + module: mod_name.to_string(), + kind: ModuleResolutionErrorKind::ParseError { + file: self.directory.path.clone(), + }, + }), + }, } } @@ -458,6 +484,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> { self.directory.path.push(path.as_str()); self.directory.ownership = DirectoryOwnership::Owned { relative: None }; } else { + let id = id.as_str(); // We have to push on the current module name in the case of relative // paths in order to ensure that any additional module paths from inline // `mod x { ... }` come after the relative extension. @@ -468,9 +495,15 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> { if let Some(ident) = relative.take() { // remove the relative offset self.directory.path.push(ident.as_str()); + + // In the case where there is an x.rs and an ./x directory we want + // to prevent adding x twice. For example, ./x/x + if self.directory.path.exists() && !self.directory.path.join(id).exists() { + return; + } } } - self.directory.path.push(id.as_str()); + self.directory.path.push(id); } } diff --git a/src/overflow.rs b/src/overflow.rs index 3475f5c378cd2..80aed998d7377 100644 --- a/src/overflow.rs +++ b/src/overflow.rs @@ -26,8 +26,6 @@ use crate::spanned::Spanned; use crate::types::{can_be_overflowed_type, SegmentParam}; use crate::utils::{count_newlines, extra_offset, first_line_width, last_line_width, mk_sp}; -const SHORT_ITEM_THRESHOLD: usize = 10; - /// A list of `format!`-like macros, that take a long format string and a list of arguments to /// format. /// @@ -572,7 +570,12 @@ impl<'a> Context<'a> { if one_line { tactic = DefinitiveListTactic::SpecialMacro(num_args_before); }; - } else if is_every_expr_simple(&self.items) && no_long_items(list_items) { + } else if is_every_expr_simple(&self.items) + && no_long_items( + list_items, + self.context.config.short_array_element_width_threshold(), + ) + { tactic = DefinitiveListTactic::Mixed; } } @@ -755,9 +758,9 @@ fn shape_from_indent_style( } } -fn no_long_items(list: &[ListItem]) -> bool { +fn no_long_items(list: &[ListItem], short_array_element_width_threshold: usize) -> bool { list.iter() - .all(|item| item.inner_as_ref().len() <= SHORT_ITEM_THRESHOLD) + .all(|item| item.inner_as_ref().len() <= short_array_element_width_threshold) } /// In case special-case style is required, returns an offset from which we start horizontal layout. diff --git a/src/parse/session.rs b/src/parse/session.rs index 412f4434b9ead..7571e6d078a7b 100644 --- a/src/parse/session.rs +++ b/src/parse/session.rs @@ -12,6 +12,7 @@ use rustc_span::{ use crate::config::file_lines::LineRange; use crate::ignore_path::IgnorePathSet; +use crate::parse::parser::{ModError, ModulePathSuccess}; use crate::source_map::LineRangeUtils; use crate::utils::starts_with_newline; use crate::visitor::SnippetProvider; @@ -145,13 +146,33 @@ impl ParseSess { }) } + /// Determine the submodule path for the given module identifier. + /// + /// * `id` - The name of the module + /// * `relative` - If Some(symbol), the symbol name is a directory relative to the dir_path. + /// If relative is Some, resolve the submodle at {dir_path}/{symbol}/{id}.rs + /// or {dir_path}/{symbol}/{id}/mod.rs. if None, resolve the module at {dir_path}/{id}.rs. + /// * `dir_path` - Module resolution will occur relative to this direcotry. pub(crate) fn default_submod_path( &self, id: symbol::Ident, relative: Option, dir_path: &Path, - ) -> Result> { - rustc_expand::module::default_submod_path(&self.parse_sess, id, relative, dir_path) + ) -> Result> { + rustc_expand::module::default_submod_path(&self.parse_sess, id, relative, dir_path).or_else( + |e| { + // If resloving a module relative to {dir_path}/{symbol} fails because a file + // could not be found, then try to resolve the module relative to {dir_path}. + // If we still can't find the module after searching for it in {dir_path}, + // surface the original error. + if matches!(e, ModError::FileNotFound(..)) && relative.is_some() { + rustc_expand::module::default_submod_path(&self.parse_sess, id, None, dir_path) + .map_err(|_| e) + } else { + Err(e) + } + }, + ) } pub(crate) fn is_file_parsed(&self, path: &Path) -> bool { @@ -197,6 +218,15 @@ impl ParseSess { self.parse_sess.source_map().lookup_char_pos(pos).line } + // TODO(calebcartwright): Preemptive, currently unused addition + // that will be used to support formatting scenarios that take original + // positions into account + /// Determines whether two byte positions are in the same source line. + #[allow(dead_code)] + pub(crate) fn byte_pos_same_line(&self, a: BytePos, b: BytePos) -> bool { + self.line_of_byte_pos(a) == self.line_of_byte_pos(b) + } + pub(crate) fn span_to_debug_info(&self, span: Span) -> String { self.parse_sess.source_map().span_to_diagnostic_string(span) } diff --git a/src/spanned.rs b/src/spanned.rs index 8e6c75a3744ac..2136cfeae1af1 100644 --- a/src/spanned.rs +++ b/src/spanned.rs @@ -113,17 +113,10 @@ impl Spanned for ast::Param { impl Spanned for ast::GenericParam { fn span(&self) -> Span { - let lo = if let ast::GenericParamKind::Const { - ty: _, - kw_span, - default: _, - } = self.kind - { - kw_span.lo() - } else if self.attrs.is_empty() { - self.ident.span.lo() - } else { - self.attrs[0].span.lo() + let lo = match self.kind { + _ if !self.attrs.is_empty() => self.attrs[0].span.lo(), + ast::GenericParamKind::Const { kw_span, .. } => kw_span.lo(), + _ => self.ident.span.lo(), }; let hi = if self.bounds.is_empty() { self.ident.span.hi() diff --git a/src/string.rs b/src/string.rs index 64ae15672df8f..b65aa5b33b241 100644 --- a/src/string.rs +++ b/src/string.rs @@ -278,6 +278,9 @@ fn break_string(max_width: usize, trim_end: bool, line_end: &str, input: &[&str] } cur_index }; + if max_width_index_in_input == 0 { + return SnippetState::EndOfInput(input.concat()); + } // Find the position in input for breaking the string if line_end.is_empty() @@ -301,7 +304,7 @@ fn break_string(max_width: usize, trim_end: bool, line_end: &str, input: &[&str] return if trim_end { SnippetState::LineEnd(input[..=url_index_end].concat(), index_plus_ws + 1) } else { - return SnippetState::LineEnd(input[..=index_plus_ws].concat(), index_plus_ws + 1); + SnippetState::LineEnd(input[..=index_plus_ws].concat(), index_plus_ws + 1) }; } diff --git a/src/test/configuration_snippet.rs b/src/test/configuration_snippet.rs index 92949ab576a6b..c8fda7c8556db 100644 --- a/src/test/configuration_snippet.rs +++ b/src/test/configuration_snippet.rs @@ -290,3 +290,33 @@ fn get_code_blocks() -> Vec { code_blocks } + +#[test] +fn check_unstable_option_tracking_issue_numbers() { + // Ensure that tracking issue links point to the correct issue number + let tracking_issue = + regex::Regex::new(r"\(tracking issue: \[#(?P\d+)\]\((?P\S+)\)\)") + .expect("failed creating configuration pattern"); + + let lines = BufReader::new( + fs::File::open(Path::new(CONFIGURATIONS_FILE_NAME)) + .unwrap_or_else(|_| panic!("couldn't read file {}", CONFIGURATIONS_FILE_NAME)), + ) + .lines() + .map(Result::unwrap) + .enumerate(); + + for (idx, line) in lines { + if let Some(capture) = tracking_issue.captures(&line) { + let number = capture.name("number").unwrap().as_str(); + let link = capture.name("link").unwrap().as_str(); + assert!( + link.ends_with(number), + "{} on line {} does not point to issue #{}", + link, + idx + 1, + number, + ); + } + } +} diff --git a/src/test/mod.rs b/src/test/mod.rs index c50d18644b091..ab966d4a36075 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -307,6 +307,52 @@ fn assert_output(source: &Path, expected_filename: &Path) { } } +// Helper function for comparing the results of rustfmt +// to a known output generated by one of the write modes. +fn assert_stdin_output( + source: &Path, + expected_filename: &Path, + emit_mode: EmitMode, + has_diff: bool, +) { + let mut config = Config::default(); + config.set().newline_style(NewlineStyle::Unix); + config.set().emit_mode(emit_mode); + + let mut source_file = fs::File::open(&source).expect("couldn't open source"); + let mut source_text = String::new(); + source_file + .read_to_string(&mut source_text) + .expect("Failed reading target"); + let input = Input::Text(source_text); + + // Populate output by writing to a vec. + let mut buf: Vec = vec![]; + { + let mut session = Session::new(config, Some(&mut buf)); + session.format(input).unwrap(); + let errors = ReportedErrors { + has_diff: has_diff, + ..Default::default() + }; + assert_eq!(session.errors, errors); + } + + let mut expected_file = fs::File::open(&expected_filename).expect("couldn't open target"); + let mut expected_text = String::new(); + expected_file + .read_to_string(&mut expected_text) + .expect("Failed reading target"); + + let output = String::from_utf8(buf).unwrap(); + let compare = make_diff(&expected_text, &output, DIFF_CONTEXT_SIZE); + if !compare.is_empty() { + let mut failures = HashMap::new(); + failures.insert(source.to_owned(), compare); + print_mismatches_default_message(failures); + panic!("Text does not match expected output"); + } +} // Idempotence tests. Files in tests/target are checked to be unaltered by // rustfmt. #[nightly_only_test] @@ -420,9 +466,9 @@ fn stdin_formatting_smoke_test() { } #[cfg(not(windows))] - assert_eq!(buf, "stdin:\n\nfn main() {}\n".as_bytes()); + assert_eq!(buf, ":\n\nfn main() {}\n".as_bytes()); #[cfg(windows)] - assert_eq!(buf, "stdin:\n\nfn main() {}\r\n".as_bytes()); + assert_eq!(buf, ":\n\nfn main() {}\r\n".as_bytes()); } #[test] @@ -463,6 +509,30 @@ fn stdin_works_with_modified_lines() { assert_eq!(buf, output.as_bytes()); } +/// Ensures that `EmitMode::Json` works with input from `stdin`. +#[test] +fn stdin_works_with_json() { + init_log(); + assert_stdin_output( + Path::new("tests/writemode/source/stdin.rs"), + Path::new("tests/writemode/target/stdin.json"), + EmitMode::Json, + true, + ); +} + +/// Ensures that `EmitMode::Checkstyle` works with input from `stdin`. +#[test] +fn stdin_works_with_checkstyle() { + init_log(); + assert_stdin_output( + Path::new("tests/writemode/source/stdin.rs"), + Path::new("tests/writemode/target/stdin.xml"), + EmitMode::Checkstyle, + false, + ); +} + #[test] fn stdin_disable_all_formatting_test() { init_log(); @@ -502,7 +572,10 @@ fn stdin_generated_files_issue_5172() { assert!(session.has_no_errors()); } // N.B. this should be changed once `format_generated_files` is supported with stdin - assert_eq!(buf, "stdin:\n\n//@generated\nfn main() {}\n".as_bytes()); + assert_eq!( + String::from_utf8(buf).unwrap(), + ":\n\n//@generated\nfn main() {}\n", + ); } #[test] @@ -914,3 +987,52 @@ fn verify_check_works() { .status() .expect("run with check option failed"); } + +#[test] +fn verify_check_works_with_stdin() { + init_log(); + + let mut child = Command::new(rustfmt().to_str().unwrap()) + .arg("--check") + .stdin(Stdio::piped()) + .stderr(Stdio::piped()) + .spawn() + .expect("run with check option failed"); + + { + let stdin = child.stdin.as_mut().expect("Failed to open stdin"); + stdin + .write_all("fn main() {}\n".as_bytes()) + .expect("Failed to write to rustfmt --check"); + } + let output = child + .wait_with_output() + .expect("Failed to wait on rustfmt child"); + assert!(output.status.success()); +} + +#[test] +fn verify_check_l_works_with_stdin() { + init_log(); + + let mut child = Command::new(rustfmt().to_str().unwrap()) + .arg("--check") + .arg("-l") + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .spawn() + .expect("run with check option failed"); + + { + let stdin = child.stdin.as_mut().expect("Failed to open stdin"); + stdin + .write_all("fn main()\n{}\n".as_bytes()) + .expect("Failed to write to rustfmt --check"); + } + let output = child + .wait_with_output() + .expect("Failed to wait on rustfmt child"); + assert!(output.status.success()); + assert_eq!(std::str::from_utf8(&output.stdout).unwrap(), "\n"); +} diff --git a/src/test/mod_resolver.rs b/src/test/mod_resolver.rs index ec9ed0f0b8d62..aacb2acc68498 100644 --- a/src/test/mod_resolver.rs +++ b/src/test/mod_resolver.rs @@ -50,3 +50,33 @@ fn skip_out_of_line_nested_inline_within_out_of_line() { &["tests/mod-resolver/skip-files-issue-5065/one.rs"], ); } + +#[test] +fn fmt_out_of_line_test_modules() { + // See also https://github.com/rust-lang/rustfmt/issues/5119 + verify_mod_resolution( + "tests/mod-resolver/test-submodule-issue-5119/tests/test1.rs", + &[ + "tests/mod-resolver/test-submodule-issue-5119/tests/test1.rs", + "tests/mod-resolver/test-submodule-issue-5119/tests/test1/sub1.rs", + "tests/mod-resolver/test-submodule-issue-5119/tests/test1/sub2.rs", + "tests/mod-resolver/test-submodule-issue-5119/tests/test1/sub3/sub4.rs", + ], + ) +} + +#[test] +fn fallback_and_try_to_resolve_external_submod_relative_to_current_dir_path() { + // See also https://github.com/rust-lang/rustfmt/issues/5198 + verify_mod_resolution( + "tests/mod-resolver/issue-5198/lib.rs", + &[ + "tests/mod-resolver/issue-5198/a.rs", + "tests/mod-resolver/issue-5198/lib/b.rs", + "tests/mod-resolver/issue-5198/lib/c/mod.rs", + "tests/mod-resolver/issue-5198/lib/c/e.rs", + "tests/mod-resolver/issue-5198/lib/c/d/f.rs", + "tests/mod-resolver/issue-5198/lib/c/d/g/mod.rs", + ], + ) +} diff --git a/src/types.rs b/src/types.rs index a49d473a13f3f..64a201e45ddd4 100644 --- a/src/types.rs +++ b/src/types.rs @@ -575,7 +575,16 @@ impl Rewrite for ast::GenericParam { let mut result = String::with_capacity(128); // FIXME: If there are more than one attributes, this will force multiline. match self.attrs.rewrite(context, shape) { - Some(ref rw) if !rw.is_empty() => result.push_str(&format!("{} ", rw)), + Some(ref rw) if !rw.is_empty() => { + result.push_str(rw); + // When rewriting generic params, an extra newline should be put + // if the attributes end with a doc comment + if let Some(true) = self.attrs.last().map(|a| a.is_doc_comment()) { + result.push_str(&shape.indent.to_string_with_newline(context.config)); + } else { + result.push(' '); + } + } _ => (), } diff --git a/src/utils.rs b/src/utils.rs index 2428d8cb0fd89..35512e78fa6e2 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -646,9 +646,22 @@ pub(crate) fn trim_left_preserve_layout( } /// Based on the given line, determine if the next line can be indented or not. -/// This allows to preserve the indentation of multi-line literals. -pub(crate) fn indent_next_line(kind: FullCodeCharKind, _line: &str, config: &Config) -> bool { - !(kind.is_string() || (config.version() == Version::Two && kind.is_commented_string())) +/// This allows to preserve the indentation of multi-line literals when +/// re-inserted a code block that has been formatted separately from the rest +/// of the code, such as code in macro defs or code blocks doc comments. +pub(crate) fn indent_next_line(kind: FullCodeCharKind, line: &str, config: &Config) -> bool { + if kind.is_string() { + // If the string ends with '\', the string has been wrapped over + // multiple lines. If `format_strings = true`, then the indentation of + // strings wrapped over multiple lines will have been adjusted while + // formatting the code block, therefore the string's indentation needs + // to be adjusted for the code surrounding the code block. + config.format_strings() && line.ends_with('\\') + } else if config.version() == Version::Two { + !kind.is_commented_string() + } else { + true + } } pub(crate) fn is_empty_line(s: &str) -> bool { diff --git a/src/vertical.rs b/src/vertical.rs index c4208848c6c2a..a06bc995aa55e 100644 --- a/src/vertical.rs +++ b/src/vertical.rs @@ -160,8 +160,18 @@ pub(crate) fn rewrite_with_alignment( }; let init_span = mk_sp(span.lo(), init_last_pos); let one_line_width = if rest.is_empty() { one_line_width } else { 0 }; - let result = - rewrite_aligned_items_inner(context, init, init_span, shape.indent, one_line_width)?; + + // if another group follows, we must force a separator + let force_separator = !rest.is_empty(); + + let result = rewrite_aligned_items_inner( + context, + init, + init_span, + shape.indent, + one_line_width, + force_separator, + )?; if rest.is_empty() { Some(result + spaces) } else { @@ -201,6 +211,7 @@ fn rewrite_aligned_items_inner( span: Span, offset: Indent, one_line_width: usize, + force_trailing_separator: bool, ) -> Option { // 1 = "," let item_shape = Shape::indented(offset, context.config).sub_width(1)?; @@ -246,9 +257,15 @@ fn rewrite_aligned_items_inner( }); } + let separator_tactic = if force_trailing_separator { + SeparatorTactic::Always + } else { + context.config.trailing_comma() + }; + let fmt = ListFormatting::new(item_shape, context.config) .tactic(tactic) - .trailing_separator(context.config.trailing_comma()) + .trailing_separator(separator_tactic) .preserve_newline(true); write_list(&items, &fmt) } diff --git a/tests/cargo-fmt/main.rs b/tests/cargo-fmt/main.rs index 5493b09e4aa63..348876cd264fa 100644 --- a/tests/cargo-fmt/main.rs +++ b/tests/cargo-fmt/main.rs @@ -1,6 +1,7 @@ // Integration tests for cargo-fmt. use std::env; +use std::path::Path; use std::process::Command; /// Run the cargo-fmt executable and return its output. @@ -71,3 +72,27 @@ fn rustfmt_help() { assert_that!(&["--", "-h"], contains("Format Rust code")); assert_that!(&["--", "--help=config"], contains("Configuration Options:")); } + +#[ignore] +#[test] +fn cargo_fmt_out_of_line_test_modules() { + // See also https://github.com/rust-lang/rustfmt/issues/5119 + let expected_modified_files = [ + "tests/mod-resolver/test-submodule-issue-5119/src/lib.rs", + "tests/mod-resolver/test-submodule-issue-5119/tests/test1.rs", + "tests/mod-resolver/test-submodule-issue-5119/tests/test1/sub1.rs", + "tests/mod-resolver/test-submodule-issue-5119/tests/test1/sub2.rs", + "tests/mod-resolver/test-submodule-issue-5119/tests/test1/sub3/sub4.rs", + ]; + let args = [ + "-v", + "--check", + "--manifest-path", + "tests/mod-resolver/test-submodule-issue-5119/Cargo.toml", + ]; + let (stdout, _) = cargo_fmt(&args); + for file in expected_modified_files { + let path = Path::new(file).canonicalize().unwrap(); + assert!(stdout.contains(&format!("Diff in {}", path.display()))) + } +} diff --git a/tests/mod-resolver/issue-5167/src/a.rs b/tests/mod-resolver/issue-5167/src/a.rs new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/tests/mod-resolver/issue-5167/src/a/mod.rs b/tests/mod-resolver/issue-5167/src/a/mod.rs new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/tests/mod-resolver/issue-5167/src/lib.rs b/tests/mod-resolver/issue-5167/src/lib.rs new file mode 100644 index 0000000000000..f21af614da057 --- /dev/null +++ b/tests/mod-resolver/issue-5167/src/lib.rs @@ -0,0 +1 @@ +mod a; diff --git a/tests/mod-resolver/issue-5198/a.rs b/tests/mod-resolver/issue-5198/a.rs new file mode 100644 index 0000000000000..cd686f5611690 --- /dev/null +++ b/tests/mod-resolver/issue-5198/a.rs @@ -0,0 +1 @@ +fn main( ) { println!("Hello World!") } diff --git a/tests/mod-resolver/issue-5198/lib.rs b/tests/mod-resolver/issue-5198/lib.rs new file mode 100644 index 0000000000000..696832913c879 --- /dev/null +++ b/tests/mod-resolver/issue-5198/lib.rs @@ -0,0 +1,3 @@ +mod a; +mod b; +mod c; diff --git a/tests/mod-resolver/issue-5198/lib/b.rs b/tests/mod-resolver/issue-5198/lib/b.rs new file mode 100644 index 0000000000000..cd686f5611690 --- /dev/null +++ b/tests/mod-resolver/issue-5198/lib/b.rs @@ -0,0 +1 @@ +fn main( ) { println!("Hello World!") } diff --git a/tests/mod-resolver/issue-5198/lib/c/d.rs b/tests/mod-resolver/issue-5198/lib/c/d.rs new file mode 100644 index 0000000000000..d1604aa23a3cb --- /dev/null +++ b/tests/mod-resolver/issue-5198/lib/c/d.rs @@ -0,0 +1,3 @@ +mod e; +mod f; +mod g; diff --git a/tests/mod-resolver/issue-5198/lib/c/d/explanation.txt b/tests/mod-resolver/issue-5198/lib/c/d/explanation.txt new file mode 100644 index 0000000000000..92c9e3021431f --- /dev/null +++ b/tests/mod-resolver/issue-5198/lib/c/d/explanation.txt @@ -0,0 +1,16 @@ +This file is contained in the './lib/c/d/' directory. + +The directory name './lib/c/d/' conflicts with the './lib/c/d.rs' file name. + +'./lib/c/d.rs' defines 3 external modules: + + * mod e; + * mod f; + * mod g; + +Module resolution will fail if we look for './lib/c/d/e.rs' or './lib/c/d/e/mod.rs', +so we should fall back to looking for './lib/c/e.rs', which correctly finds the modlue, that +rustfmt should format. + +'./lib/c/d/f.rs' and './lib/c/d/g/mod.rs' exist at the default submodule paths so we should be able +to resolve these modules with no problems. \ No newline at end of file diff --git a/tests/mod-resolver/issue-5198/lib/c/d/f.rs b/tests/mod-resolver/issue-5198/lib/c/d/f.rs new file mode 100644 index 0000000000000..cd686f5611690 --- /dev/null +++ b/tests/mod-resolver/issue-5198/lib/c/d/f.rs @@ -0,0 +1 @@ +fn main( ) { println!("Hello World!") } diff --git a/tests/mod-resolver/issue-5198/lib/c/d/g/mod.rs b/tests/mod-resolver/issue-5198/lib/c/d/g/mod.rs new file mode 100644 index 0000000000000..cd686f5611690 --- /dev/null +++ b/tests/mod-resolver/issue-5198/lib/c/d/g/mod.rs @@ -0,0 +1 @@ +fn main( ) { println!("Hello World!") } diff --git a/tests/mod-resolver/issue-5198/lib/c/e.rs b/tests/mod-resolver/issue-5198/lib/c/e.rs new file mode 100644 index 0000000000000..cd686f5611690 --- /dev/null +++ b/tests/mod-resolver/issue-5198/lib/c/e.rs @@ -0,0 +1 @@ +fn main( ) { println!("Hello World!") } diff --git a/tests/mod-resolver/issue-5198/lib/c/mod.rs b/tests/mod-resolver/issue-5198/lib/c/mod.rs new file mode 100644 index 0000000000000..81904619650f9 --- /dev/null +++ b/tests/mod-resolver/issue-5198/lib/c/mod.rs @@ -0,0 +1,3 @@ +mod d; + +fn main( ) { println!("Hello World!") } diff --git a/tests/mod-resolver/issue-5198/lib/explanation.txt b/tests/mod-resolver/issue-5198/lib/explanation.txt new file mode 100644 index 0000000000000..d436a8076cd71 --- /dev/null +++ b/tests/mod-resolver/issue-5198/lib/explanation.txt @@ -0,0 +1,16 @@ +This file is contained in the './lib' directory. + +The directory name './lib' conflicts with the './lib.rs' file name. + +'lib.rs' defines 3 external modules: + + * mod a; + * mod b; + * mod c; + +Module resolution will fail if we look for './lib/a.rs' or './lib/a/mod.rs', +so we should fall back to looking for './a.rs', which correctly finds the modlue that +rustfmt should format. + +'./lib/b.rs' and './lib/c/mod.rs' exist at the default submodule paths so we should be able +to resolve these modules with no problems. diff --git a/tests/mod-resolver/module-not-found/bad_path_attribute/lib.rs b/tests/mod-resolver/module-not-found/bad_path_attribute/lib.rs new file mode 100644 index 0000000000000..2a63c961be8fc --- /dev/null +++ b/tests/mod-resolver/module-not-found/bad_path_attribute/lib.rs @@ -0,0 +1,3 @@ +// module resolution fails because the path does not exist. +#[path = "path/to/does_not_exist.rs"] +mod a; diff --git a/tests/mod-resolver/module-not-found/relative_module/a.rs b/tests/mod-resolver/module-not-found/relative_module/a.rs new file mode 100644 index 0000000000000..4a1eac8965ded --- /dev/null +++ b/tests/mod-resolver/module-not-found/relative_module/a.rs @@ -0,0 +1,2 @@ +// module resolution fails because `./a/b.rs` does not exist +mod b; diff --git a/tests/mod-resolver/module-not-found/relative_module/lib.rs b/tests/mod-resolver/module-not-found/relative_module/lib.rs new file mode 100644 index 0000000000000..f21af614da057 --- /dev/null +++ b/tests/mod-resolver/module-not-found/relative_module/lib.rs @@ -0,0 +1 @@ +mod a; diff --git a/tests/mod-resolver/module-not-found/sibling_module/lib.rs b/tests/mod-resolver/module-not-found/sibling_module/lib.rs new file mode 100644 index 0000000000000..d9d9e1e3c9087 --- /dev/null +++ b/tests/mod-resolver/module-not-found/sibling_module/lib.rs @@ -0,0 +1,2 @@ +// module resolution fails because `./a.rs` does not exist +mod a; diff --git a/tests/mod-resolver/test-submodule-issue-5119/Cargo.toml b/tests/mod-resolver/test-submodule-issue-5119/Cargo.toml new file mode 100644 index 0000000000000..0993f12795991 --- /dev/null +++ b/tests/mod-resolver/test-submodule-issue-5119/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "rustfmt-test-submodule-issue" +version = "0.1.0" +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/tests/mod-resolver/test-submodule-issue-5119/src/lib.rs b/tests/mod-resolver/test-submodule-issue-5119/src/lib.rs new file mode 100644 index 0000000000000..3f7ddba8a288c --- /dev/null +++ b/tests/mod-resolver/test-submodule-issue-5119/src/lib.rs @@ -0,0 +1,7 @@ +pub fn foo() -> i32 { +3 +} + +pub fn bar() -> i32 { +4 +} diff --git a/tests/mod-resolver/test-submodule-issue-5119/tests/test1.rs b/tests/mod-resolver/test-submodule-issue-5119/tests/test1.rs new file mode 100644 index 0000000000000..da4e86169ad92 --- /dev/null +++ b/tests/mod-resolver/test-submodule-issue-5119/tests/test1.rs @@ -0,0 +1,8 @@ +mod test1 { +#[cfg(unix)] +mod sub1; +#[cfg(not(unix))] +mod sub2; + +mod sub3; +} diff --git a/tests/mod-resolver/test-submodule-issue-5119/tests/test1/sub1.rs b/tests/mod-resolver/test-submodule-issue-5119/tests/test1/sub1.rs new file mode 100644 index 0000000000000..b760ba23cd277 --- /dev/null +++ b/tests/mod-resolver/test-submodule-issue-5119/tests/test1/sub1.rs @@ -0,0 +1,6 @@ +use rustfmt_test_submodule_issue::foo; + +#[test] +fn test_foo() { +assert_eq!(3, foo()); +} diff --git a/tests/mod-resolver/test-submodule-issue-5119/tests/test1/sub2.rs b/tests/mod-resolver/test-submodule-issue-5119/tests/test1/sub2.rs new file mode 100644 index 0000000000000..4fd8286eac400 --- /dev/null +++ b/tests/mod-resolver/test-submodule-issue-5119/tests/test1/sub2.rs @@ -0,0 +1,6 @@ +use rustfmt_test_submodule_issue::bar; + +#[test] +fn test_bar() { +assert_eq!(4, bar()); +} diff --git a/tests/mod-resolver/test-submodule-issue-5119/tests/test1/sub3/mod.rs b/tests/mod-resolver/test-submodule-issue-5119/tests/test1/sub3/mod.rs new file mode 100644 index 0000000000000..e029785bc2457 --- /dev/null +++ b/tests/mod-resolver/test-submodule-issue-5119/tests/test1/sub3/mod.rs @@ -0,0 +1 @@ +mod sub4; diff --git a/tests/mod-resolver/test-submodule-issue-5119/tests/test1/sub3/sub4.rs b/tests/mod-resolver/test-submodule-issue-5119/tests/test1/sub3/sub4.rs new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/tests/rustfmt/main.rs b/tests/rustfmt/main.rs index 8effb1c6fcab6..450051d2fec61 100644 --- a/tests/rustfmt/main.rs +++ b/tests/rustfmt/main.rs @@ -106,3 +106,54 @@ fn inline_config() { && contains("format_strings = true") ); } + +#[test] +fn rustfmt_usage_text() { + let args = ["--help"]; + let (stdout, _) = rustfmt(&args); + assert!(stdout.contains("Format Rust code\n\nusage: rustfmt [options] ...")); +} + +#[test] +fn mod_resolution_error_multiple_candidate_files() { + // See also https://github.com/rust-lang/rustfmt/issues/5167 + let default_path = Path::new("tests/mod-resolver/issue-5167/src/a.rs"); + let secondary_path = Path::new("tests/mod-resolver/issue-5167/src/a/mod.rs"); + let error_message = format!( + "file for module found at both {:?} and {:?}", + default_path.canonicalize().unwrap(), + secondary_path.canonicalize().unwrap(), + ); + + let args = ["tests/mod-resolver/issue-5167/src/lib.rs"]; + let (_stdout, stderr) = rustfmt(&args); + assert!(stderr.contains(&error_message)) +} + +#[test] +fn mod_resolution_error_sibling_module_not_found() { + let args = ["tests/mod-resolver/module-not-found/sibling_module/lib.rs"]; + let (_stdout, stderr) = rustfmt(&args); + // Module resolution fails because we're unable to find `a.rs` in the same directory as lib.rs + assert!(stderr.contains("a.rs does not exist")) +} + +#[test] +fn mod_resolution_error_relative_module_not_found() { + let args = ["tests/mod-resolver/module-not-found/relative_module/lib.rs"]; + let (_stdout, stderr) = rustfmt(&args); + // The file `./a.rs` and directory `./a` both exist. + // Module resolution fails becuase we're unable to find `./a/b.rs` + #[cfg(not(windows))] + assert!(stderr.contains("a/b.rs does not exist")); + #[cfg(windows)] + assert!(stderr.contains("a\\b.rs does not exist")); +} + +#[test] +fn mod_resolution_error_path_attribute_does_not_exist() { + let args = ["tests/mod-resolver/module-not-found/bad_path_attribute/lib.rs"]; + let (_stdout, stderr) = rustfmt(&args); + // The path attribute points to a file that does not exist + assert!(stderr.contains("does_not_exist.rs does not exist")); +} diff --git a/tests/source/5131_crate.rs b/tests/source/5131_crate.rs new file mode 100644 index 0000000000000..96a31659022aa --- /dev/null +++ b/tests/source/5131_crate.rs @@ -0,0 +1,14 @@ +// rustfmt-imports_granularity: Crate + +use foo::a; +use foo::a; +use foo::b; +use foo::b as b2; +use foo::b::f; +use foo::b::g; +use foo::b::g as g2; +use foo::c; +use foo::d::e; +use qux::h; +use qux::h as h2; +use qux::i; diff --git a/tests/source/5131_module.rs b/tests/source/5131_module.rs new file mode 100644 index 0000000000000..3e9139177c56e --- /dev/null +++ b/tests/source/5131_module.rs @@ -0,0 +1,33 @@ +// rustfmt-imports_granularity: Module + +#![allow(dead_code)] + +mod a { + pub mod b { + pub struct Data { + pub a: i32, + } + } + + use crate::a::b::Data; + use crate::a::b::Data as Data2; + + pub fn data(a: i32) -> Data { + Data { a } + } + + pub fn data2(a: i32) -> Data2 { + Data2 { a } + } + + #[cfg(test)] + mod tests { + use super::*; + + #[test] + pub fn test() { + data(1); + data2(1); + } + } +} diff --git a/tests/source/5131_one.rs b/tests/source/5131_one.rs new file mode 100644 index 0000000000000..61ddf13410d4b --- /dev/null +++ b/tests/source/5131_one.rs @@ -0,0 +1,15 @@ +// rustfmt-imports_granularity: One + +pub use foo::x; +pub use foo::x as x2; +pub use foo::y; +use bar::a; +use bar::b; +use bar::b::f; +use bar::b::f as f2; +use bar::b::g; +use bar::c; +use bar::d::e; +use bar::d::e as e2; +use qux::h; +use qux::i; diff --git a/tests/source/configs/short_array_element_width_threshold/10.rs b/tests/source/configs/short_array_element_width_threshold/10.rs new file mode 100644 index 0000000000000..7d0d70919a607 --- /dev/null +++ b/tests/source/configs/short_array_element_width_threshold/10.rs @@ -0,0 +1,11 @@ +// rustfmt-short_array_element_width_threshold: 10 + +fn main() { + pub const FORMAT_TEST: [u64; 5] = [ + 0x0000000000000000, + 0xaaaaaaaaaaaaaaaa, + 0xbbbbbbbbbbbbbbbb, + 0xcccccccccccccccc, + 0xdddddddddddddddd, + ]; +} \ No newline at end of file diff --git a/tests/source/configs/short_array_element_width_threshold/20.rs b/tests/source/configs/short_array_element_width_threshold/20.rs new file mode 100644 index 0000000000000..8a93a51d6a281 --- /dev/null +++ b/tests/source/configs/short_array_element_width_threshold/20.rs @@ -0,0 +1,11 @@ +// rustfmt-short_array_element_width_threshold: 20 + +fn main() { + pub const FORMAT_TEST: [u64; 5] = [ + 0x0000000000000000, + 0xaaaaaaaaaaaaaaaa, + 0xbbbbbbbbbbbbbbbb, + 0xcccccccccccccccc, + 0xdddddddddddddddd, + ]; +} \ No newline at end of file diff --git a/tests/source/configs/short_array_element_width_threshold/greater_than_max_width.rs b/tests/source/configs/short_array_element_width_threshold/greater_than_max_width.rs new file mode 100644 index 0000000000000..710b6fe7c4ba0 --- /dev/null +++ b/tests/source/configs/short_array_element_width_threshold/greater_than_max_width.rs @@ -0,0 +1,12 @@ +// rustfmt-max_width: 20 +// rustfmt-short_array_element_width_threshold: 30 + +fn main() { + pub const FORMAT_TEST: [u64; 5] = [ + 0x0000000000000000, + 0xaaaaaaaaaaaaaaaa, + 0xbbbbbbbbbbbbbbbb, + 0xcccccccccccccccc, + 0xdddddddddddddddd, + ]; +} diff --git a/tests/source/extern.rs b/tests/source/extern.rs index d0a033b12432a..f51ba6e98c9f5 100644 --- a/tests/source/extern.rs +++ b/tests/source/extern.rs @@ -77,3 +77,16 @@ libc::c_long; extern { } + +macro_rules! x { + ($tt:tt) => {}; +} + +extern "macros" { + x!(ident); + x!(#); + x![ident]; + x![#]; + x! {ident} + x! {#} +} diff --git a/tests/source/imports_granularity_module.rs b/tests/source/imports_granularity_module.rs index 5a4fad5872bdd..2d7bb299aaace 100644 --- a/tests/source/imports_granularity_module.rs +++ b/tests/source/imports_granularity_module.rs @@ -4,6 +4,7 @@ use a::{b::c, d::e}; use a::{f, g::{h, i}}; use a::{j::{self, k::{self, l}, m}, n::{o::p, q}}; pub use a::{r::s, t}; +use b::{c::d, self}; #[cfg(test)] use foo::{a::b, c::d}; diff --git a/tests/source/issue-4036/one.rs b/tests/source/issue-4036/one.rs new file mode 100644 index 0000000000000..9f9675f51631a --- /dev/null +++ b/tests/source/issue-4036/one.rs @@ -0,0 +1,11 @@ +// rustfmt-format_strings: true + +macro_rules! test { + () => { + fn from() { + None.expect( + "We asserted that `buffer.len()` is exactly `$n` so we can expect `ApInt::from_iter` to be successful.", + ) + } + }; +} diff --git a/tests/source/issue-4036/three.rs b/tests/source/issue-4036/three.rs new file mode 100644 index 0000000000000..e1865dd0868b6 --- /dev/null +++ b/tests/source/issue-4036/three.rs @@ -0,0 +1,12 @@ +// rustfmt-format_strings: true +// rustfmt-hard_tabs: true + +macro_rules! test { + () => { + fn from() { + None.expect( + "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + ) + } + }; +} diff --git a/tests/source/issue-4036/two.rs b/tests/source/issue-4036/two.rs new file mode 100644 index 0000000000000..fa54d2e3e09cb --- /dev/null +++ b/tests/source/issue-4036/two.rs @@ -0,0 +1,11 @@ +// rustfmt-format_strings: true + +macro_rules! test { + () => { + fn from() { + None.expect( + "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + ) + } + }; +} diff --git a/tests/source/issue-4791/buggy.rs b/tests/source/issue-4791/buggy.rs new file mode 100644 index 0000000000000..4760022eeaf0d --- /dev/null +++ b/tests/source/issue-4791/buggy.rs @@ -0,0 +1,14 @@ +// rustfmt-struct_field_align_threshold: 30 +// rustfmt-trailing_comma: Never + +struct Foo { + group_a: u8, + + group_b: u8, +} + +struct Bar { + group_a: u8, + + group_b: u8 +} diff --git a/tests/source/issue-4791/trailing_comma.rs b/tests/source/issue-4791/trailing_comma.rs new file mode 100644 index 0000000000000..c56c70faeae40 --- /dev/null +++ b/tests/source/issue-4791/trailing_comma.rs @@ -0,0 +1,14 @@ +// rustfmt-struct_field_align_threshold: 30 +// rustfmt-trailing_comma: Always + +struct Foo { + group_a: u8, + + group_b: u8 +} + +struct Bar { + group_a: u8, + + group_b: u8, +} diff --git a/tests/source/issue-5023.rs b/tests/source/issue-5023.rs new file mode 100644 index 0000000000000..ae1c723eff76a --- /dev/null +++ b/tests/source/issue-5023.rs @@ -0,0 +1,22 @@ +// rustfmt-wrap_comments: true + +/// A comment to test special unicode characters on boundaries +/// 是,是,是,是,是,是,是,是,是,是,是,是 it should break right here this goes to the next line +fn main() { + if xxx { + let xxx = xxx + .into_iter() + .filter(|(xxx, xxx)| { + if let Some(x) = Some(1) { + // xxxxxxxxxxxxxxxxxx, xxxxxxxxxxxx, xxxxxxxxxxxxxxxxxxxx xxx xxxxxxx, xxxxx xxx + // xxxxxxxxxx. xxxxxxxxxxxxxxxx,xxxxxxxxxxxxxxxxx xxx xxxxxxx + // 是sdfadsdfxxxxxxxxx,sdfaxxxxxx_xxxxx_masdfaonxxx, + if false { + return true; + } + } + false + }) + .collect(); + } +} diff --git a/tests/source/issue-5042/multi-line_comment_with_trailing_comma.rs b/tests/source/issue-5042/multi-line_comment_with_trailing_comma.rs new file mode 100644 index 0000000000000..5d171f32a1aea --- /dev/null +++ b/tests/source/issue-5042/multi-line_comment_with_trailing_comma.rs @@ -0,0 +1,24 @@ +fn main() { + // 5042 deals with trailing commas, not the indentation issue of these comments + // When a future PR fixes the inentation issues these test can be updated + let _ = std::ops::Add::add(10, 20 + // ... + // ..., + ); + + let _ = std::ops::Add::add(10, 20 + /* ... */ + // ..., + ); + + let _ = std::ops::Add::add(10, 20 + // ..., + // ..., + ); + + let _ = std::ops::Add::add(10, 20 + // ..., + /* ... + */, + ); +} diff --git a/tests/source/issue-5042/multi-line_comment_without_trailing_comma.rs b/tests/source/issue-5042/multi-line_comment_without_trailing_comma.rs new file mode 100644 index 0000000000000..b8a824b34b796 --- /dev/null +++ b/tests/source/issue-5042/multi-line_comment_without_trailing_comma.rs @@ -0,0 +1,24 @@ +fn main() { + // 5042 deals with trailing commas, not the indentation issue of these comments + // When a future PR fixes the inentation issues these test can be updated + let _ = std::ops::Add::add(10, 20 + // ... + // ... + ); + + let _ = std::ops::Add::add(10, 20 + /* ... */ + // ... + ); + + let _ = std::ops::Add::add(10, 20 + // ... + // ... + ); + + let _ = std::ops::Add::add(10, 20 + // ... + /* ... + */ + ); +} diff --git a/tests/source/issue-5042/single-line_comment_with_trailing_comma.rs b/tests/source/issue-5042/single-line_comment_with_trailing_comma.rs new file mode 100644 index 0000000000000..bd765b7b41f49 --- /dev/null +++ b/tests/source/issue-5042/single-line_comment_with_trailing_comma.rs @@ -0,0 +1,9 @@ +fn main() { + let _ = std::ops::Add::add(10, 20 + // ..., + ); + + let _ = std::ops::Add::add(10, 20 + /* ... */, + ); +} diff --git a/tests/source/issue-5042/single-line_comment_without_trailing_comma.rs b/tests/source/issue-5042/single-line_comment_without_trailing_comma.rs new file mode 100644 index 0000000000000..2ed8de875add8 --- /dev/null +++ b/tests/source/issue-5042/single-line_comment_without_trailing_comma.rs @@ -0,0 +1,10 @@ +fn main() { + let _ = std::ops::Add::add(10, 20 + // ... + ); + + let _ = std::ops::Add::add(10, 20 + /* ... */ + ); +} + diff --git a/tests/source/issue-5157/indented_itemized_markdown_blockquote.rs b/tests/source/issue-5157/indented_itemized_markdown_blockquote.rs new file mode 100644 index 0000000000000..5c1d79a743098 --- /dev/null +++ b/tests/source/issue-5157/indented_itemized_markdown_blockquote.rs @@ -0,0 +1,4 @@ +// rustfmt-wrap_comments: true + +/// > For each sample received, the middleware internally maintains a sample_state relative to each DataReader. The sample_state can either be READ or NOT_READ. +fn block_quote() {} diff --git a/tests/source/issue-5157/nested_itemized_markdown_blockquote.rs b/tests/source/issue-5157/nested_itemized_markdown_blockquote.rs new file mode 100644 index 0000000000000..cf200d04e08ef --- /dev/null +++ b/tests/source/issue-5157/nested_itemized_markdown_blockquote.rs @@ -0,0 +1,10 @@ +// rustfmt-wrap_comments: true + +/// > For each sample received, the middleware internally maintains a sample_state relative to each DataReader. The sample_state can either be READ or NOT_READ. +/// +/// > > For each sample received, the middleware internally maintains a sample_state relative to each DataReader. The sample_state can either be READ or NOT_READ. +/// +/// > > > For each sample received, the middleware internally maintains a sample_state relative to each DataReader. The sample_state can either be READ or NOT_READ. +/// +/// > > > > > > > > For each sample received, the middleware internally maintains a sample_state relative to each DataReader. The sample_state can either be READ or NOT_READ. +fn block_quote() {} diff --git a/tests/source/issue-5157/support_itemized_markdown_blockquote.rs b/tests/source/issue-5157/support_itemized_markdown_blockquote.rs new file mode 100644 index 0000000000000..eb436402e4e00 --- /dev/null +++ b/tests/source/issue-5157/support_itemized_markdown_blockquote.rs @@ -0,0 +1,4 @@ +// rustfmt-wrap_comments: true + +/// > For each sample received, the middleware internally maintains a sample_state relative to each DataReader. The sample_state can either be READ or NOT_READ. +fn block_quote() {} diff --git a/tests/source/issue-5238/markdown_header_wrap_comments_false.rs b/tests/source/issue-5238/markdown_header_wrap_comments_false.rs new file mode 100644 index 0000000000000..229c6e5753d2e --- /dev/null +++ b/tests/source/issue-5238/markdown_header_wrap_comments_false.rs @@ -0,0 +1,11 @@ +// rustfmt-wrap_comments: false + +/// no markdown header so rustfmt should wrap this comment when `format_code_in_doc_comments = true` and `wrap_comments = true` +fn not_documented_with_markdown_header() { + // This is just a normal inline comment so rustfmt should wrap this comment when `wrap_comments = true` +} + +/// # We're using a markdown header here so rustfmt should refuse to wrap this comment in all circumstances +fn documented_with_markdown_header() { + // # We're using a markdown header in an inline comment. rustfmt should be able to wrap this comment when `wrap_comments = true` +} diff --git a/tests/source/issue-5238/markdown_header_wrap_comments_true.rs b/tests/source/issue-5238/markdown_header_wrap_comments_true.rs new file mode 100644 index 0000000000000..c547ff35c691b --- /dev/null +++ b/tests/source/issue-5238/markdown_header_wrap_comments_true.rs @@ -0,0 +1,11 @@ +// rustfmt-wrap_comments: true + +/// no markdown header so rustfmt should wrap this comment when `format_code_in_doc_comments = true` and `wrap_comments = true` +fn not_documented_with_markdown_header() { + // This is just a normal inline comment so rustfmt should wrap this comment when `wrap_comments = true` +} + +/// # We're using a markdown header here so rustfmt should refuse to wrap this comment in all circumstances +fn documented_with_markdown_header() { + // # We're using a markdown header in an inline comment. rustfmt should be able to wrap this comment when `wrap_comments = true` +} diff --git a/tests/source/issue-5270/merge_derives_true.rs b/tests/source/issue-5270/merge_derives_true.rs new file mode 100644 index 0000000000000..b31bbf095e730 --- /dev/null +++ b/tests/source/issue-5270/merge_derives_true.rs @@ -0,0 +1,62 @@ +// rustfmt-merge_derives:true + +#[rustfmt::skip::attributes(derive)] +#[allow(dead_code)] +#[derive(StructField)] +#[derive(Clone)] +struct DoNotMergeDerives { + field: String, +} + +#[allow(dead_code)] +#[derive(StructField)] +#[rustfmt::skip::attributes(derive)] +#[derive(Clone)] +struct DoNotMergeDerivesSkipInMiddle { + field: String, +} + +#[allow(dead_code)] +#[derive(StructField)] +#[derive(Clone)] +#[rustfmt::skip::attributes(derive)] +struct DoNotMergeDerivesSkipAtEnd { + field: String, +} + +#[allow(dead_code)] +#[derive(StructField)] +#[derive(Clone)] +struct MergeDerives { + field: String, +} + +mod inner_attribute_derive_skip { + #![rustfmt::skip::attributes(derive)] + + #[allow(dead_code)] + #[derive(StructField)] + #[derive(Clone)] + struct DoNotMergeDerives { + field: String, + } +} + +#[rustfmt::skip::attributes(derive)] +mod outer_attribute_derive_skip { + #[allow(dead_code)] + #[derive(StructField)] + #[derive(Clone)] + struct DoNotMergeDerives { + field: String, + } +} + +mod no_derive_skip { + #[allow(dead_code)] + #[derive(StructField)] + #[derive(Clone)] + struct MergeDerives { + field: String, + } +} diff --git a/tests/source/issue_4854.rs b/tests/source/issue_4854.rs new file mode 100644 index 0000000000000..35d6e21affeeb --- /dev/null +++ b/tests/source/issue_4854.rs @@ -0,0 +1,113 @@ +struct Struct { + // Multiline comment + // should be formatted + // properly. +} + +struct Struct2 { + // This formatting +// Should be changed +} + +struct Struct3( + // This + // is + // correct +); + +struct Struct4( + // This +// is +// not +// correct +); + +struct Struct5 { + /* + Comment block + with many lines. + */ +} + +struct Struct6( + /* + Comment block + with many lines. + */ +); + +struct Struct7 { + /* +Invalid +format +*/ +} + +struct Struct8( + /* +Invalid +format +*/ +); + +struct Struct9 { /* bar */ } + +struct Struct10 { /* bar +baz +*/ } + +mod module { + struct Struct { + // Multiline comment + // should be formatted + // properly. + } + + struct Struct2 { + // This formatting +// Should be changed + } + + struct Struct3( + // This + // is + // correct + ); + + struct Struct4( + // This + // is + // not +// correct + ); + + struct Struct5 { + /* + Comment block + with many lines. + */ + } + + struct Struct6( + /* + Comment block + with many lines. + */ + ); + + struct Struct7 { + /* +Invalid +format +*/ + } + + struct Struct8( + /* +Invalid +format +*/ + ); + + struct Struct9 { /* bar */ } +} diff --git a/tests/target/5131_crate.rs b/tests/target/5131_crate.rs new file mode 100644 index 0000000000000..557d667035546 --- /dev/null +++ b/tests/target/5131_crate.rs @@ -0,0 +1,9 @@ +// rustfmt-imports_granularity: Crate + +use foo::{ + a, b, b as b2, + b::{f, g, g as g2}, + c, + d::e, +}; +use qux::{h, h as h2, i}; diff --git a/tests/target/5131_module.rs b/tests/target/5131_module.rs new file mode 100644 index 0000000000000..763024d6fa495 --- /dev/null +++ b/tests/target/5131_module.rs @@ -0,0 +1,32 @@ +// rustfmt-imports_granularity: Module + +#![allow(dead_code)] + +mod a { + pub mod b { + pub struct Data { + pub a: i32, + } + } + + use crate::a::b::{Data, Data as Data2}; + + pub fn data(a: i32) -> Data { + Data { a } + } + + pub fn data2(a: i32) -> Data2 { + Data2 { a } + } + + #[cfg(test)] + mod tests { + use super::*; + + #[test] + pub fn test() { + data(1); + data2(1); + } + } +} diff --git a/tests/target/5131_one.rs b/tests/target/5131_one.rs new file mode 100644 index 0000000000000..a086dae5a4221 --- /dev/null +++ b/tests/target/5131_one.rs @@ -0,0 +1,12 @@ +// rustfmt-imports_granularity: One + +pub use foo::{x, x as x2, y}; +use { + bar::{ + a, + b::{self, f, g}, + c, + d::{e, e as e2}, + }, + qux::{h, i}, +}; diff --git a/tests/target/comments-in-lists/format-doc-comments.rs b/tests/target/comments-in-lists/format-doc-comments.rs index be31bf0a33198..be4b7a8c42e3e 100644 --- a/tests/target/comments-in-lists/format-doc-comments.rs +++ b/tests/target/comments-in-lists/format-doc-comments.rs @@ -25,9 +25,8 @@ pub enum E { } pub enum E2 { - // This can be changed once https://github.com/rust-lang/rustfmt/issues/4854 is fixed -// Expand as needed, numbers should be ascending according to the stage -// through the inclusion pipeline, or according to the descriptions + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions } pub struct S { @@ -42,9 +41,8 @@ pub struct S { } pub struct S2 { - // This can be changed once https://github.com/rust-lang/rustfmt/issues/4854 is fixed -// Expand as needed, numbers should be ascending according to the stage -// through the inclusion pipeline, or according to the descriptions + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions } fn foo( diff --git a/tests/target/comments-in-lists/wrap-comments-false.rs b/tests/target/comments-in-lists/wrap-comments-false.rs index 80aea59d1b520..db4da6223721c 100644 --- a/tests/target/comments-in-lists/wrap-comments-false.rs +++ b/tests/target/comments-in-lists/wrap-comments-false.rs @@ -13,9 +13,8 @@ pub enum E { } pub enum E2 { - // This can be changed once https://github.com/rust-lang/rustfmt/issues/4854 is fixed -// Expand as needed, numbers should be ascending according to the stage -// through the inclusion pipeline, or according to the descriptions + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions } pub struct S { @@ -30,9 +29,8 @@ pub struct S { } pub struct S2 { - // This can be changed once https://github.com/rust-lang/rustfmt/issues/4854 is fixed -// Expand as needed, numbers should be ascending according to the stage -// through the inclusion pipeline, or according to the descriptions + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions } fn foo( diff --git a/tests/target/comments-in-lists/wrap-comments-not-normalized.rs b/tests/target/comments-in-lists/wrap-comments-not-normalized.rs index 52315f470e4b9..9b9147eb1247a 100644 --- a/tests/target/comments-in-lists/wrap-comments-not-normalized.rs +++ b/tests/target/comments-in-lists/wrap-comments-not-normalized.rs @@ -14,8 +14,8 @@ pub enum E { pub enum E2 { // This can be changed once https://github.com/rust-lang/rustfmt/issues/4854 is fixed -// Expand as needed, numbers should be ascending according to the stage -// through the inclusion pipeline, or according to the descriptions + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions } pub enum E3 { @@ -42,8 +42,8 @@ pub struct S { pub struct S2 { // This can be changed once https://github.com/rust-lang/rustfmt/issues/4854 is fixed -// Expand as needed, numbers should be ascending according to the stage -// through the inclusion pipeline, or according to the descriptions + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions } pub struct S3 { diff --git a/tests/target/comments-in-lists/wrap-comments-true.rs b/tests/target/comments-in-lists/wrap-comments-true.rs index e0bfcf0b5007d..c1531d22a4a70 100644 --- a/tests/target/comments-in-lists/wrap-comments-true.rs +++ b/tests/target/comments-in-lists/wrap-comments-true.rs @@ -15,8 +15,8 @@ pub enum E { pub enum E2 { // This can be changed once https://github.com/rust-lang/rustfmt/issues/4854 is fixed -// Expand as needed, numbers should be ascending according to the stage -// through the inclusion pipeline, or according to the descriptions + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions } pub enum E3 { @@ -43,8 +43,8 @@ pub struct S { pub struct S2 { // This can be changed once https://github.com/rust-lang/rustfmt/issues/4854 is fixed -// Expand as needed, numbers should be ascending according to the stage -// through the inclusion pipeline, or according to the descriptions + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions } pub struct S3 { diff --git a/tests/target/configs/short_array_element_width_threshold/10.rs b/tests/target/configs/short_array_element_width_threshold/10.rs new file mode 100644 index 0000000000000..78c4adba1c1f1 --- /dev/null +++ b/tests/target/configs/short_array_element_width_threshold/10.rs @@ -0,0 +1,11 @@ +// rustfmt-short_array_element_width_threshold: 10 + +fn main() { + pub const FORMAT_TEST: [u64; 5] = [ + 0x0000000000000000, + 0xaaaaaaaaaaaaaaaa, + 0xbbbbbbbbbbbbbbbb, + 0xcccccccccccccccc, + 0xdddddddddddddddd, + ]; +} diff --git a/tests/target/configs/short_array_element_width_threshold/20.rs b/tests/target/configs/short_array_element_width_threshold/20.rs new file mode 100644 index 0000000000000..6084690652f06 --- /dev/null +++ b/tests/target/configs/short_array_element_width_threshold/20.rs @@ -0,0 +1,8 @@ +// rustfmt-short_array_element_width_threshold: 20 + +fn main() { + pub const FORMAT_TEST: [u64; 5] = [ + 0x0000000000000000, 0xaaaaaaaaaaaaaaaa, 0xbbbbbbbbbbbbbbbb, 0xcccccccccccccccc, + 0xdddddddddddddddd, + ]; +} diff --git a/tests/target/configs/short_array_element_width_threshold/greater_than_max_width.rs b/tests/target/configs/short_array_element_width_threshold/greater_than_max_width.rs new file mode 100644 index 0000000000000..710b6fe7c4ba0 --- /dev/null +++ b/tests/target/configs/short_array_element_width_threshold/greater_than_max_width.rs @@ -0,0 +1,12 @@ +// rustfmt-max_width: 20 +// rustfmt-short_array_element_width_threshold: 30 + +fn main() { + pub const FORMAT_TEST: [u64; 5] = [ + 0x0000000000000000, + 0xaaaaaaaaaaaaaaaa, + 0xbbbbbbbbbbbbbbbb, + 0xcccccccccccccccc, + 0xdddddddddddddddd, + ]; +} diff --git a/tests/target/doc-of-generic-item.rs b/tests/target/doc-of-generic-item.rs new file mode 100644 index 0000000000000..2efc5e09a3d34 --- /dev/null +++ b/tests/target/doc-of-generic-item.rs @@ -0,0 +1,14 @@ +// Non-doc pre-comment of Foo +/// doc of Foo +// Non-doc post-comment of Foo +struct Foo< + // Non-doc pre-comment of 'a + /// doc of 'a + 'a, + // Non-doc pre-comment of T + /// doc of T + T, + // Non-doc pre-comment of N + /// doc of N + const N: item, +>; diff --git a/tests/target/extern.rs b/tests/target/extern.rs index 44ed6d4b4756d..d1741360cfd64 100644 --- a/tests/target/extern.rs +++ b/tests/target/extern.rs @@ -82,3 +82,16 @@ extern "C" { } extern "C" {} + +macro_rules! x { + ($tt:tt) => {}; +} + +extern "macros" { + x!(ident); + x!(#); + x![ident]; + x![#]; + x! {ident} + x! {#} +} diff --git a/tests/target/imports_granularity_module.rs b/tests/target/imports_granularity_module.rs index 9c1387c466afa..e4e1a299e5866 100644 --- a/tests/target/imports_granularity_module.rs +++ b/tests/target/imports_granularity_module.rs @@ -10,6 +10,8 @@ use a::n::o::p; use a::n::q; pub use a::r::s; pub use a::t; +use b::c::d; +use b::{self}; use foo::e; #[cfg(test)] diff --git a/tests/target/issue-4036/one.rs b/tests/target/issue-4036/one.rs new file mode 100644 index 0000000000000..54e490b7fbeae --- /dev/null +++ b/tests/target/issue-4036/one.rs @@ -0,0 +1,12 @@ +// rustfmt-format_strings: true + +macro_rules! test { + () => { + fn from() { + None.expect( + "We asserted that `buffer.len()` is exactly `$n` so we can expect \ + `ApInt::from_iter` to be successful.", + ) + } + }; +} diff --git a/tests/target/issue-4036/three.rs b/tests/target/issue-4036/three.rs new file mode 100644 index 0000000000000..394dc8633f534 --- /dev/null +++ b/tests/target/issue-4036/three.rs @@ -0,0 +1,17 @@ +// rustfmt-format_strings: true +// rustfmt-hard_tabs: true + +macro_rules! test { + () => { + fn from() { + None.expect( + "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor \ + incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis \ + nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. \ + Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu \ + fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in \ + culpa qui officia deserunt mollit anim id est laborum.", + ) + } + }; +} diff --git a/tests/target/issue-4036/two.rs b/tests/target/issue-4036/two.rs new file mode 100644 index 0000000000000..01cafa76b6842 --- /dev/null +++ b/tests/target/issue-4036/two.rs @@ -0,0 +1,16 @@ +// rustfmt-format_strings: true + +macro_rules! test { + () => { + fn from() { + None.expect( + "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor \ + incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis \ + nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. \ + Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu \ + fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in \ + culpa qui officia deserunt mollit anim id est laborum.", + ) + } + }; +} diff --git a/tests/target/issue-4791/buggy.rs b/tests/target/issue-4791/buggy.rs new file mode 100644 index 0000000000000..fff58be99a509 --- /dev/null +++ b/tests/target/issue-4791/buggy.rs @@ -0,0 +1,14 @@ +// rustfmt-struct_field_align_threshold: 30 +// rustfmt-trailing_comma: Never + +struct Foo { + group_a: u8, + + group_b: u8 +} + +struct Bar { + group_a: u8, + + group_b: u8 +} diff --git a/tests/target/issue-4791/issue_4928.rs b/tests/target/issue-4791/issue_4928.rs new file mode 100644 index 0000000000000..588656b535fa1 --- /dev/null +++ b/tests/target/issue-4791/issue_4928.rs @@ -0,0 +1,70 @@ +// rustfmt-brace_style: SameLineWhere +// rustfmt-comment_width: 100 +// rustfmt-edition: 2018 +// rustfmt-fn_args_layout: Compressed +// rustfmt-hard_tabs: false +// rustfmt-match_block_trailing_comma: true +// rustfmt-max_width: 100 +// rustfmt-merge_derives: false +// rustfmt-newline_style: Unix +// rustfmt-normalize_doc_attributes: true +// rustfmt-overflow_delimited_expr: true +// rustfmt-reorder_imports: false +// rustfmt-reorder_modules: true +// rustfmt-struct_field_align_threshold: 20 +// rustfmt-tab_spaces: 4 +// rustfmt-trailing_comma: Never +// rustfmt-use_small_heuristics: Max +// rustfmt-use_try_shorthand: true +// rustfmt-wrap_comments: true + +/// Lorem ipsum dolor sit amet. +#[repr(C)] +#[derive(Debug, Default, Copy, Clone, PartialEq, Eq)] +pub struct BufferAttr { + /* NOTE: Blah blah blah blah blah. */ + /// Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt + /// ut labore et dolore magna aliqua. Morbi quis commodo odio aenean sed adipiscing. Nunc + /// congue nisi vitae suscipit tellus mauris a. Consectetur adipiscing elit pellentesque + /// habitant morbi tristique senectus. + pub foo: u32, + + /// Elit eget gravida cum sociis natoque penatibus et magnis dis. Consequat semper viverra nam + /// libero. Accumsan in nisl nisi scelerisque eu. Pellentesque id nibh tortor id aliquet. Sed + /// velit dignissim sodales ut. Facilisis sed odio morbi quis commodo odio aenean sed. Et + /// ultrices neque ornare aenean euismod elementum. Condimentum lacinia quis vel eros donec ac + /// odio tempor. + /// + /// Lacinia at quis risus sed vulputate odio ut enim. Etiam erat velit scelerisque in dictum. + /// Nibh tellus molestie nunc non blandit massa enim nec. Nascetur ridiculus mus mauris vitae. + pub bar: u32, + + /// Mi proin sed libero enim sed faucibus turpis. Amet consectetur adipiscing elit duis + /// tristique sollicitudin nibh sit amet. Congue quisque egestas diam in arcu cursus euismod + /// quis viverra. Cum sociis natoque penatibus et magnis dis parturient montes. Enim sit amet + /// venenatis urna cursus eget nunc scelerisque viverra. Cras semper auctor neque vitae tempus + /// quam pellentesque. Tortor posuere ac ut consequat semper viverra nam libero justo. Vitae + /// auctor eu augue ut lectus arcu bibendum at. Faucibus vitae aliquet nec ullamcorper sit amet + /// risus nullam. Maecenas accumsan lacus vel facilisis volutpat. Arcu non odio euismod + /// lacinia. + /// + /// [`FooBar::beep()`]: crate::foobar::FooBar::beep + /// [`FooBar::boop()`]: crate::foobar::FooBar::boop + /// [`foobar::BazBaq::BEEP_BOOP`]: crate::foobar::BazBaq::BEEP_BOOP + pub baz: u32, + + /// Eu consequat ac felis donec et odio pellentesque diam. Ut eu sem integer vitae justo eget. + /// Consequat ac felis donec et odio pellentesque diam volutpat. + pub baq: u32, + + /// Amet consectetur adipiscing elit pellentesque habitant. Ut morbi tincidunt augue interdum + /// velit euismod in pellentesque. Imperdiet sed euismod nisi porta lorem. Nec tincidunt + /// praesent semper feugiat. Facilisis leo vel fringilla est. Egestas diam in arcu cursus + /// euismod quis viverra. Sagittis eu volutpat odio facilisis mauris sit amet. Posuere morbi + /// leo urna molestie at. + /// + /// Pretium aenean pharetra magna ac. Nisl condimentum id venenatis a condimentum vitae. Semper + /// quis lectus nulla at volutpat diam ut venenatis tellus. Egestas tellus rutrum tellus + /// pellentesque eu tincidunt tortor aliquam. + pub foobar: u32 +} diff --git a/tests/target/issue-4791/no_trailing_comma.rs b/tests/target/issue-4791/no_trailing_comma.rs new file mode 100644 index 0000000000000..4a37163969ae9 --- /dev/null +++ b/tests/target/issue-4791/no_trailing_comma.rs @@ -0,0 +1,8 @@ +// rustfmt-struct_field_align_threshold: 0 +// rustfmt-trailing_comma: Never + +pub struct Baz { + group_a: u8, + + group_b: u8 +} diff --git a/tests/target/issue-4791/trailing_comma.rs b/tests/target/issue-4791/trailing_comma.rs new file mode 100644 index 0000000000000..29a224b3f6d96 --- /dev/null +++ b/tests/target/issue-4791/trailing_comma.rs @@ -0,0 +1,14 @@ +// rustfmt-struct_field_align_threshold: 30 +// rustfmt-trailing_comma: Always + +struct Foo { + group_a: u8, + + group_b: u8, +} + +struct Bar { + group_a: u8, + + group_b: u8, +} diff --git a/tests/target/issue-5023.rs b/tests/target/issue-5023.rs new file mode 100644 index 0000000000000..4e84c7d98427a --- /dev/null +++ b/tests/target/issue-5023.rs @@ -0,0 +1,23 @@ +// rustfmt-wrap_comments: true + +/// A comment to test special unicode characters on boundaries +/// 是,是,是,是,是,是,是,是,是,是,是,是 it should break right here +/// this goes to the next line +fn main() { + if xxx { + let xxx = xxx + .into_iter() + .filter(|(xxx, xxx)| { + if let Some(x) = Some(1) { + // xxxxxxxxxxxxxxxxxx, xxxxxxxxxxxx, xxxxxxxxxxxxxxxxxxxx xxx xxxxxxx, xxxxx xxx + // xxxxxxxxxx. xxxxxxxxxxxxxxxx,xxxxxxxxxxxxxxxxx xxx xxxxxxx + // 是sdfadsdfxxxxxxxxx,sdfaxxxxxx_xxxxx_masdfaonxxx, + if false { + return true; + } + } + false + }) + .collect(); + } +} diff --git a/tests/target/issue-5042/multi-line_comment_with_trailing_comma.rs b/tests/target/issue-5042/multi-line_comment_with_trailing_comma.rs new file mode 100644 index 0000000000000..1ae1212b488d9 --- /dev/null +++ b/tests/target/issue-5042/multi-line_comment_with_trailing_comma.rs @@ -0,0 +1,24 @@ +fn main() { + // 5042 deals with trailing commas, not the indentation issue of these comments + // When a future PR fixes the inentation issues these test can be updated + let _ = std::ops::Add::add( + 10, 20, // ... + // ..., + ); + + let _ = std::ops::Add::add( + 10, 20, /* ... */ + // ..., + ); + + let _ = std::ops::Add::add( + 10, 20, // ..., + // ..., + ); + + let _ = std::ops::Add::add( + 10, 20, // ..., + /* ... + */ + ); +} diff --git a/tests/target/issue-5042/multi-line_comment_without_trailing_comma.rs b/tests/target/issue-5042/multi-line_comment_without_trailing_comma.rs new file mode 100644 index 0000000000000..30d174664c9cf --- /dev/null +++ b/tests/target/issue-5042/multi-line_comment_without_trailing_comma.rs @@ -0,0 +1,24 @@ +fn main() { + // 5042 deals with trailing commas, not the indentation issue of these comments + // When a future PR fixes the inentation issues these test can be updated + let _ = std::ops::Add::add( + 10, 20, // ... + // ... + ); + + let _ = std::ops::Add::add( + 10, 20, /* ... */ + // ... + ); + + let _ = std::ops::Add::add( + 10, 20, // ... + // ... + ); + + let _ = std::ops::Add::add( + 10, 20, // ... + /* ... + */ + ); +} diff --git a/tests/target/issue-5042/single-line_comment_with_trailing_comma.rs b/tests/target/issue-5042/single-line_comment_with_trailing_comma.rs new file mode 100644 index 0000000000000..87b651dd285ef --- /dev/null +++ b/tests/target/issue-5042/single-line_comment_with_trailing_comma.rs @@ -0,0 +1,7 @@ +fn main() { + let _ = std::ops::Add::add( + 10, 20, // ..., + ); + + let _ = std::ops::Add::add(10, 20 /* ... */); +} diff --git a/tests/target/issue-5042/single-line_comment_without_trailing_comma.rs b/tests/target/issue-5042/single-line_comment_without_trailing_comma.rs new file mode 100644 index 0000000000000..116df86a4b554 --- /dev/null +++ b/tests/target/issue-5042/single-line_comment_without_trailing_comma.rs @@ -0,0 +1,7 @@ +fn main() { + let _ = std::ops::Add::add( + 10, 20, // ... + ); + + let _ = std::ops::Add::add(10, 20 /* ... */); +} diff --git a/tests/target/issue-5125/attributes_in_formal_fuction_parameter.rs b/tests/target/issue-5125/attributes_in_formal_fuction_parameter.rs new file mode 100644 index 0000000000000..5d167932828f3 --- /dev/null +++ b/tests/target/issue-5125/attributes_in_formal_fuction_parameter.rs @@ -0,0 +1,6 @@ +fn foo( + #[unused] a: >::ForeignType, +) { +} diff --git a/tests/target/issue-5125/long_parameter_in_different_positions.rs b/tests/target/issue-5125/long_parameter_in_different_positions.rs new file mode 100644 index 0000000000000..cab20381ce8f7 --- /dev/null +++ b/tests/target/issue-5125/long_parameter_in_different_positions.rs @@ -0,0 +1,24 @@ +fn middle( + a: usize, + b: >::ForeignType, + c: bool, +) { +} + +fn last( + a: usize, + b: >::ForeignType, +) { +} + +fn first( + a: >::ForeignType, + b: usize, +) { +} diff --git a/tests/target/issue-5125/minimum_example.rs b/tests/target/issue-5125/minimum_example.rs new file mode 100644 index 0000000000000..8003e66968c78 --- /dev/null +++ b/tests/target/issue-5125/minimum_example.rs @@ -0,0 +1,6 @@ +fn foo( + a: >::ForeignType, +) { +} diff --git a/tests/target/issue-5125/with_leading_and_inline_comments.rs b/tests/target/issue-5125/with_leading_and_inline_comments.rs new file mode 100644 index 0000000000000..2340b2f3472e9 --- /dev/null +++ b/tests/target/issue-5125/with_leading_and_inline_comments.rs @@ -0,0 +1,7 @@ +fn foo( + // Pre Comment + a: >::ForeignType, // Inline comment +) { +} diff --git a/tests/target/issue-5157/indented_itemized_markdown_blockquote.rs b/tests/target/issue-5157/indented_itemized_markdown_blockquote.rs new file mode 100644 index 0000000000000..e47677f203903 --- /dev/null +++ b/tests/target/issue-5157/indented_itemized_markdown_blockquote.rs @@ -0,0 +1,6 @@ +// rustfmt-wrap_comments: true + +/// > For each sample received, the middleware internally maintains a +/// > sample_state relative to each DataReader. The sample_state can +/// > either be READ or NOT_READ. +fn block_quote() {} diff --git a/tests/target/issue-5157/nested_itemized_markdown_blockquote.rs b/tests/target/issue-5157/nested_itemized_markdown_blockquote.rs new file mode 100644 index 0000000000000..079510442b799 --- /dev/null +++ b/tests/target/issue-5157/nested_itemized_markdown_blockquote.rs @@ -0,0 +1,18 @@ +// rustfmt-wrap_comments: true + +/// > For each sample received, the middleware internally maintains a +/// > sample_state relative to each DataReader. The sample_state can either be +/// > READ or NOT_READ. +/// +/// > > For each sample received, the middleware internally maintains a +/// > > sample_state relative to each DataReader. The sample_state can either be +/// > > READ or NOT_READ. +/// +/// > > > For each sample received, the middleware internally maintains a +/// > > > sample_state relative to each DataReader. The sample_state can either +/// > > > be READ or NOT_READ. +/// +/// > > > > > > > > For each sample received, the middleware internally +/// > > > > > > > > maintains a sample_state relative to each DataReader. The +/// > > > > > > > > sample_state can either be READ or NOT_READ. +fn block_quote() {} diff --git a/tests/target/issue-5157/support_itemized_markdown_blockquote.rs b/tests/target/issue-5157/support_itemized_markdown_blockquote.rs new file mode 100644 index 0000000000000..029ee37d22a8b --- /dev/null +++ b/tests/target/issue-5157/support_itemized_markdown_blockquote.rs @@ -0,0 +1,6 @@ +// rustfmt-wrap_comments: true + +/// > For each sample received, the middleware internally maintains a +/// > sample_state relative to each DataReader. The sample_state can either be +/// > READ or NOT_READ. +fn block_quote() {} diff --git a/tests/target/issue-5238/markdown_header_wrap_comments_false.rs b/tests/target/issue-5238/markdown_header_wrap_comments_false.rs new file mode 100644 index 0000000000000..229c6e5753d2e --- /dev/null +++ b/tests/target/issue-5238/markdown_header_wrap_comments_false.rs @@ -0,0 +1,11 @@ +// rustfmt-wrap_comments: false + +/// no markdown header so rustfmt should wrap this comment when `format_code_in_doc_comments = true` and `wrap_comments = true` +fn not_documented_with_markdown_header() { + // This is just a normal inline comment so rustfmt should wrap this comment when `wrap_comments = true` +} + +/// # We're using a markdown header here so rustfmt should refuse to wrap this comment in all circumstances +fn documented_with_markdown_header() { + // # We're using a markdown header in an inline comment. rustfmt should be able to wrap this comment when `wrap_comments = true` +} diff --git a/tests/target/issue-5238/markdown_header_wrap_comments_true.rs b/tests/target/issue-5238/markdown_header_wrap_comments_true.rs new file mode 100644 index 0000000000000..87dae58eccd73 --- /dev/null +++ b/tests/target/issue-5238/markdown_header_wrap_comments_true.rs @@ -0,0 +1,14 @@ +// rustfmt-wrap_comments: true + +/// no markdown header so rustfmt should wrap this comment when +/// `format_code_in_doc_comments = true` and `wrap_comments = true` +fn not_documented_with_markdown_header() { + // This is just a normal inline comment so rustfmt should wrap this comment + // when `wrap_comments = true` +} + +/// # We're using a markdown header here so rustfmt should refuse to wrap this comment in all circumstances +fn documented_with_markdown_header() { + // # We're using a markdown header in an inline comment. rustfmt should be + // able to wrap this comment when `wrap_comments = true` +} diff --git a/tests/target/issue-5270/merge_derives_false.rs b/tests/target/issue-5270/merge_derives_false.rs new file mode 100644 index 0000000000000..3b6f7e66993c0 --- /dev/null +++ b/tests/target/issue-5270/merge_derives_false.rs @@ -0,0 +1,62 @@ +// rustfmt-merge_derives:false + +#[rustfmt::skip::attributes(derive)] +#[allow(dead_code)] +#[derive(StructField)] +#[derive(Clone)] +struct DoNotMergeDerives { + field: String, +} + +#[allow(dead_code)] +#[derive(StructField)] +#[rustfmt::skip::attributes(derive)] +#[derive(Clone)] +struct DoNotMergeDerivesSkipInMiddle { + field: String, +} + +#[allow(dead_code)] +#[derive(StructField)] +#[derive(Clone)] +#[rustfmt::skip::attributes(derive)] +struct DoNotMergeDerivesSkipAtEnd { + field: String, +} + +#[allow(dead_code)] +#[derive(StructField)] +#[derive(Clone)] +struct MergeDerives { + field: String, +} + +mod inner_attribute_derive_skip { + #![rustfmt::skip::attributes(derive)] + + #[allow(dead_code)] + #[derive(StructField)] + #[derive(Clone)] + struct DoNotMergeDerives { + field: String, + } +} + +#[rustfmt::skip::attributes(derive)] +mod outer_attribute_derive_skip { + #[allow(dead_code)] + #[derive(StructField)] + #[derive(Clone)] + struct DoNotMergeDerives { + field: String, + } +} + +mod no_derive_skip { + #[allow(dead_code)] + #[derive(StructField)] + #[derive(Clone)] + struct MergeDerives { + field: String, + } +} diff --git a/tests/target/issue-5270/merge_derives_true.rs b/tests/target/issue-5270/merge_derives_true.rs new file mode 100644 index 0000000000000..5f488b4542d0b --- /dev/null +++ b/tests/target/issue-5270/merge_derives_true.rs @@ -0,0 +1,60 @@ +// rustfmt-merge_derives:true + +#[rustfmt::skip::attributes(derive)] +#[allow(dead_code)] +#[derive(StructField)] +#[derive(Clone)] +struct DoNotMergeDerives { + field: String, +} + +#[allow(dead_code)] +#[derive(StructField)] +#[rustfmt::skip::attributes(derive)] +#[derive(Clone)] +struct DoNotMergeDerivesSkipInMiddle { + field: String, +} + +#[allow(dead_code)] +#[derive(StructField)] +#[derive(Clone)] +#[rustfmt::skip::attributes(derive)] +struct DoNotMergeDerivesSkipAtEnd { + field: String, +} + +#[allow(dead_code)] +#[derive(StructField, Clone)] +struct MergeDerives { + field: String, +} + +mod inner_attribute_derive_skip { + #![rustfmt::skip::attributes(derive)] + + #[allow(dead_code)] + #[derive(StructField)] + #[derive(Clone)] + struct DoNotMergeDerives { + field: String, + } +} + +#[rustfmt::skip::attributes(derive)] +mod outer_attribute_derive_skip { + #[allow(dead_code)] + #[derive(StructField)] + #[derive(Clone)] + struct DoNotMergeDerives { + field: String, + } +} + +mod no_derive_skip { + #[allow(dead_code)] + #[derive(StructField, Clone)] + struct MergeDerives { + field: String, + } +} diff --git a/tests/target/issue_4854.rs b/tests/target/issue_4854.rs new file mode 100644 index 0000000000000..a81c5a5171fb5 --- /dev/null +++ b/tests/target/issue_4854.rs @@ -0,0 +1,115 @@ +struct Struct { + // Multiline comment + // should be formatted + // properly. +} + +struct Struct2 { + // This formatting + // Should be changed +} + +struct Struct3( + // This + // is + // correct +); + +struct Struct4( + // This + // is + // not + // correct +); + +struct Struct5 { + /* + Comment block + with many lines. + */ +} + +struct Struct6( + /* + Comment block + with many lines. + */ +); + +struct Struct7 { + /* + Invalid + format + */ +} + +struct Struct8( + /* + Invalid + format + */ +); + +struct Struct9 {/* bar */} + +struct Struct10 { + /* bar + baz + */ +} + +mod module { + struct Struct { + // Multiline comment + // should be formatted + // properly. + } + + struct Struct2 { + // This formatting + // Should be changed + } + + struct Struct3( + // This + // is + // correct + ); + + struct Struct4( + // This + // is + // not + // correct + ); + + struct Struct5 { + /* + Comment block + with many lines. + */ + } + + struct Struct6( + /* + Comment block + with many lines. + */ + ); + + struct Struct7 { + /* + Invalid + format + */ + } + + struct Struct8( + /* + Invalid + format + */ + ); + + struct Struct9 {/* bar */} +} diff --git a/tests/target/issue_5273.rs b/tests/target/issue_5273.rs new file mode 100644 index 0000000000000..3bb9048a5fd3d --- /dev/null +++ b/tests/target/issue_5273.rs @@ -0,0 +1,3 @@ +struct Example { + // +} diff --git a/tests/writemode/source/stdin.rs b/tests/writemode/source/stdin.rs new file mode 100644 index 0000000000000..06f8a0c288d7f --- /dev/null +++ b/tests/writemode/source/stdin.rs @@ -0,0 +1,6 @@ + +fn + some( ) +{ +} +fn main () {} diff --git a/tests/writemode/target/output.json b/tests/writemode/target/output.json index b5f327b0a1ca6..d8b5467ee91ca 100644 --- a/tests/writemode/target/output.json +++ b/tests/writemode/target/output.json @@ -1 +1 @@ -[{"name":"tests/writemode/source/json.rs","mismatches":[{"original_begin_line":5,"original_end_line":7,"expected_begin_line":5,"expected_end_line":5,"original":"fn foo_expr() {\n 1\n}","expected":"fn foo_expr() { 1 }"},{"original_begin_line":9,"original_end_line":11,"expected_begin_line":7,"expected_end_line":7,"original":"fn foo_stmt() {\n foo();\n}","expected":"fn foo_stmt() { foo(); }"},{"original_begin_line":13,"original_end_line":15,"expected_begin_line":9,"expected_end_line":9,"original":"fn foo_decl_local() {\n let z = 5;\n }","expected":"fn foo_decl_local() { let z = 5; }"},{"original_begin_line":17,"original_end_line":19,"expected_begin_line":11,"expected_end_line":11,"original":"fn foo_decl_item(x: &mut i32) {\n x = 3;\n}","expected":"fn foo_decl_item(x: &mut i32) { x = 3; }"},{"original_begin_line":21,"original_end_line":21,"expected_begin_line":13,"expected_end_line":13,"original":" fn empty() {","expected":"fn empty() {}"},{"original_begin_line":23,"original_end_line":23,"expected_begin_line":15,"expected_end_line":15,"original":"}","expected":"fn foo_return() -> String { \"yay\" }"},{"original_begin_line":25,"original_end_line":29,"expected_begin_line":17,"expected_end_line":20,"original":"fn foo_return() -> String {\n \"yay\"\n}\n\nfn foo_where() -> T where T: Sync {","expected":"fn foo_where() -> T\nwhere\n T: Sync,\n{"},{"original_begin_line":64,"original_end_line":66,"expected_begin_line":55,"expected_end_line":55,"original":"fn lots_of_space () {\n 1 \n}","expected":"fn lots_of_space() { 1 }"},{"original_begin_line":71,"original_end_line":72,"expected_begin_line":60,"expected_end_line":60,"original":" fn dummy(&self) {\n }","expected":" fn dummy(&self) {}"},{"original_begin_line":75,"original_end_line":75,"expected_begin_line":63,"expected_end_line":64,"original":"trait CoolerTypes { fn dummy(&self) { ","expected":"trait CoolerTypes {\n fn dummy(&self) {}"},{"original_begin_line":77,"original_end_line":77,"expected_begin_line":66,"expected_end_line":66,"original":"}","expected":""},{"original_begin_line":79,"original_end_line":79,"expected_begin_line":67,"expected_end_line":70,"original":"fn Foo() where T: Bar {","expected":"fn Foo()\nwhere\n T: Bar,\n{"}]}] \ No newline at end of file +[{"name":"tests/writemode/source/json.rs","mismatches":[{"original_begin_line":5,"original_end_line":7,"expected_begin_line":5,"expected_end_line":5,"original":"fn foo_expr() {\n 1\n}\n","expected":"fn foo_expr() { 1 }\n"},{"original_begin_line":9,"original_end_line":11,"expected_begin_line":7,"expected_end_line":7,"original":"fn foo_stmt() {\n foo();\n}\n","expected":"fn foo_stmt() { foo(); }\n"},{"original_begin_line":13,"original_end_line":15,"expected_begin_line":9,"expected_end_line":9,"original":"fn foo_decl_local() {\n let z = 5;\n }\n","expected":"fn foo_decl_local() { let z = 5; }\n"},{"original_begin_line":17,"original_end_line":19,"expected_begin_line":11,"expected_end_line":11,"original":"fn foo_decl_item(x: &mut i32) {\n x = 3;\n}\n","expected":"fn foo_decl_item(x: &mut i32) { x = 3; }\n"},{"original_begin_line":21,"original_end_line":21,"expected_begin_line":13,"expected_end_line":13,"original":" fn empty() {\n","expected":"fn empty() {}\n"},{"original_begin_line":23,"original_end_line":23,"expected_begin_line":15,"expected_end_line":15,"original":"}\n","expected":"fn foo_return() -> String { \"yay\" }\n"},{"original_begin_line":25,"original_end_line":29,"expected_begin_line":17,"expected_end_line":20,"original":"fn foo_return() -> String {\n \"yay\"\n}\n\nfn foo_where() -> T where T: Sync {\n","expected":"fn foo_where() -> T\nwhere\n T: Sync,\n{\n"},{"original_begin_line":64,"original_end_line":66,"expected_begin_line":55,"expected_end_line":55,"original":"fn lots_of_space () {\n 1 \n}\n","expected":"fn lots_of_space() { 1 }\n"},{"original_begin_line":71,"original_end_line":72,"expected_begin_line":60,"expected_end_line":60,"original":" fn dummy(&self) {\n }\n","expected":" fn dummy(&self) {}\n"},{"original_begin_line":75,"original_end_line":75,"expected_begin_line":63,"expected_end_line":64,"original":"trait CoolerTypes { fn dummy(&self) { \n","expected":"trait CoolerTypes {\n fn dummy(&self) {}\n"},{"original_begin_line":77,"original_end_line":77,"expected_begin_line":66,"expected_end_line":66,"original":"}\n","expected":""},{"original_begin_line":79,"original_end_line":79,"expected_begin_line":67,"expected_end_line":70,"original":"fn Foo() where T: Bar {\n","expected":"fn Foo()\nwhere\n T: Bar,\n{\n"}]}] diff --git a/tests/writemode/target/stdin.json b/tests/writemode/target/stdin.json new file mode 100644 index 0000000000000..dbf2c48632295 --- /dev/null +++ b/tests/writemode/target/stdin.json @@ -0,0 +1 @@ +[{"name":"","mismatches":[{"original_begin_line":1,"original_end_line":6,"expected_begin_line":1,"expected_end_line":2,"original":"\nfn\n some( )\n{\n}\nfn main () {}\n","expected":"fn some() {}\nfn main() {}\n"}]}] diff --git a/tests/writemode/target/stdin.xml b/tests/writemode/target/stdin.xml new file mode 100644 index 0000000000000..a7301bbc553c3 --- /dev/null +++ b/tests/writemode/target/stdin.xml @@ -0,0 +1,2 @@ + + From 1dcdfb276d8a10470ce1c6a6fd20a6104c313d82 Mon Sep 17 00:00:00 2001 From: Tharun Rajendran Date: Sat, 2 Apr 2022 05:30:53 +0530 Subject: [PATCH 02/53] fix(rustfmt): fix struct field formatting with doc comments present (#5217) * fix(rustfmt): fix struct field formatting with doc comments present Fixes #5215 * fix review feedbacks * add unit test without doc comment * move tests to a seperate file * add additional test cases * reintroduce a newline at the of test/souce/structs.rs --- src/items.rs | 2 +- tests/source/struct_field_doc_comment.rs | 72 ++++++++++++++++++++++++ tests/target/struct_field_doc_comment.rs | 69 +++++++++++++++++++++++ 3 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 tests/source/struct_field_doc_comment.rs create mode 100644 tests/target/struct_field_doc_comment.rs diff --git a/src/items.rs b/src/items.rs index 92f423bbb6275..79f6ff69aa921 100644 --- a/src/items.rs +++ b/src/items.rs @@ -1771,7 +1771,7 @@ pub(crate) fn rewrite_struct_field( .offset_left(overhead + spacing.len()) .and_then(|ty_shape| field.ty.rewrite(context, ty_shape)); if let Some(ref ty) = orig_ty { - if !ty.contains('\n') { + if !ty.contains('\n') && !contains_comment(context.snippet(missing_span)) { return Some(attr_prefix + &spacing + ty); } } diff --git a/tests/source/struct_field_doc_comment.rs b/tests/source/struct_field_doc_comment.rs new file mode 100644 index 0000000000000..191a621004593 --- /dev/null +++ b/tests/source/struct_field_doc_comment.rs @@ -0,0 +1,72 @@ +// #5215 +struct MyTuple( + /// Doc Comments + /* TODO note to add more to Doc Comments */ u32, + /// Doc Comments + // TODO note + u64, +); + +struct MyTuple( + #[cfg(unix)] // some comment + u64, + #[cfg(not(unix))] /*block comment */ + u32, +); + +struct MyTuple( + #[cfg(unix)] + // some comment + u64, + #[cfg(not(unix))] + /*block comment */ + u32, +); + +struct MyTuple( + #[cfg(unix)] // some comment + pub u64, + #[cfg(not(unix))] /*block comment */ + pub(crate) u32, +); + +struct MyTuple( + /// Doc Comments + /* TODO note to add more to Doc Comments */ + pub u32, + /// Doc Comments + // TODO note + pub(crate) u64, +); + +struct MyStruct { + #[cfg(unix)] // some comment + a: u64, + #[cfg(not(unix))] /*block comment */ + b: u32, +} + +struct MyStruct { + #[cfg(unix)] // some comment + pub a: u64, + #[cfg(not(unix))] /*block comment */ + pub(crate) b: u32, +} + +struct MyStruct { + /// Doc Comments + /* TODO note to add more to Doc Comments */ + a: u32, + /// Doc Comments + // TODO note + b: u64, +} + +struct MyStruct { + /// Doc Comments + /* TODO note to add more to Doc Comments */ + pub a: u32, + /// Doc Comments + // TODO note + pub(crate) b: u64, +} diff --git a/tests/target/struct_field_doc_comment.rs b/tests/target/struct_field_doc_comment.rs new file mode 100644 index 0000000000000..ebb01a668f4c9 --- /dev/null +++ b/tests/target/struct_field_doc_comment.rs @@ -0,0 +1,69 @@ +// #5215 +struct MyTuple( + /// Doc Comments + /* TODO note to add more to Doc Comments */ + u32, + /// Doc Comments + // TODO note + u64, +); + +struct MyTuple( + #[cfg(unix)] // some comment + u64, + #[cfg(not(unix))] /*block comment */ u32, +); + +struct MyTuple( + #[cfg(unix)] + // some comment + u64, + #[cfg(not(unix))] + /*block comment */ + u32, +); + +struct MyTuple( + #[cfg(unix)] // some comment + pub u64, + #[cfg(not(unix))] /*block comment */ pub(crate) u32, +); + +struct MyTuple( + /// Doc Comments + /* TODO note to add more to Doc Comments */ + pub u32, + /// Doc Comments + // TODO note + pub(crate) u64, +); + +struct MyStruct { + #[cfg(unix)] // some comment + a: u64, + #[cfg(not(unix))] /*block comment */ b: u32, +} + +struct MyStruct { + #[cfg(unix)] // some comment + pub a: u64, + #[cfg(not(unix))] /*block comment */ pub(crate) b: u32, +} + +struct MyStruct { + /// Doc Comments + /* TODO note to add more to Doc Comments */ + a: u32, + /// Doc Comments + // TODO note + b: u64, +} + +struct MyStruct { + /// Doc Comments + /* TODO note to add more to Doc Comments */ + pub a: u32, + /// Doc Comments + // TODO note + pub(crate) b: u64, +} From 6c6ebec5165c0131d6041881752220ece1da6127 Mon Sep 17 00:00:00 2001 From: Jacob Pratt Date: Mon, 28 Feb 2022 18:13:24 -0500 Subject: [PATCH 03/53] Create 2024 edition --- src/bin/main.rs | 1 + src/config/options.rs | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/src/bin/main.rs b/src/bin/main.rs index ad10b9ede608f..8e871e61f2683 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -693,6 +693,7 @@ fn edition_from_edition_str(edition_str: &str) -> Result { "2015" => Ok(Edition::Edition2015), "2018" => Ok(Edition::Edition2018), "2021" => Ok(Edition::Edition2021), + "2024" => Ok(Edition::Edition2024), _ => Err(format_err!("Invalid value for `--edition`")), } } diff --git a/src/config/options.rs b/src/config/options.rs index d857c29be29c6..257a17b2703a9 100644 --- a/src/config/options.rs +++ b/src/config/options.rs @@ -423,6 +423,10 @@ pub enum Edition { #[doc_hint = "2021"] /// Edition 2021. Edition2021, + #[value = "2024"] + #[doc_hint = "2024"] + /// Edition 2024. + Edition2024, } impl Default for Edition { @@ -437,6 +441,7 @@ impl From for rustc_span::edition::Edition { Edition::Edition2015 => Self::Edition2015, Edition::Edition2018 => Self::Edition2018, Edition::Edition2021 => Self::Edition2021, + Edition::Edition2024 => Self::Edition2024, } } } From 7d6ca7c35c275ab7a6a50d290babe874cb8e3fc7 Mon Sep 17 00:00:00 2001 From: Light Ning Date: Sat, 2 Apr 2022 23:45:38 +0800 Subject: [PATCH 04/53] Bump deps (#5237) * bump deps * sort the deps --- Cargo.lock | 334 +++++++++++++++++++++++++++-------------------------- Cargo.toml | 41 +++---- 2 files changed, 192 insertions(+), 183 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b932e15ef7461..1b444136585d0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,64 +4,60 @@ version = 3 [[package]] name = "aho-corasick" -version = "0.7.6" +version = "0.7.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" dependencies = [ "memchr", ] [[package]] name = "annotate-snippets" -version = "0.8.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d78ea013094e5ea606b1c05fe35f1dd7ea1eb1ea259908d040b25bd5ec677ee5" +checksum = "c3b9d411ecbaf79885c6df4d75fff75858d5995ff25385657a28af47e82f9c36" dependencies = [ + "unicode-width", "yansi-term", ] [[package]] name = "ansi_term" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" dependencies = [ "winapi", ] [[package]] name = "anyhow" -version = "1.0.25" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9267dff192e68f3399525901e709a48c1d3982c9c072fa32f2127a0cb0babf14" +checksum = "4361135be9122e0870de935d7c439aef945b9f9ddd4199a553b5270b49c82a27" [[package]] name = "atty" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ + "hermit-abi", "libc", "winapi", ] -[[package]] -name = "autocfg" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" - [[package]] name = "bitflags" -version = "1.2.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bstr" -version = "0.2.8" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d6c2c5b58ab920a4f5aeaaca34b4488074e8cc7596af94e6f8c6ff247c60245" +checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" dependencies = [ "memchr", ] @@ -77,27 +73,27 @@ dependencies = [ [[package]] name = "camino" -version = "1.0.5" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52d74260d9bf6944e2208aa46841b4b8f0d7ffc0849a06837b2f510337f86b2b" +checksum = "6f3132262930b0522068049f5870a856ab8affc80c70d08b6ecb785771a6fc23" dependencies = [ "serde", ] [[package]] name = "cargo-platform" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0226944a63d1bf35a3b5f948dd7c59e263db83695c9e8bffc4037de02e30f1d7" +checksum = "cbdb825da8a5df079a43676dbe042702f1707b1109f713a01420fbb4cc71fa27" dependencies = [ "serde", ] [[package]] name = "cargo_metadata" -version = "0.14.0" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c297bd3135f558552f99a0daa180876984ea2c4ffa7470314540dff8c654109a" +checksum = "4acbb09d9ee8e23699b9634375c72795d095bf268439da88562cf9b501f181fa" dependencies = [ "camino", "cargo-platform", @@ -106,12 +102,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - [[package]] name = "cfg-if" version = "1.0.0" @@ -120,9 +110,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "2.33.0" +version = "2.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" dependencies = [ "ansi_term", "atty", @@ -135,20 +125,19 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.3" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7e9d99fa91428effe99c5c6d4634cdeba32b8cf784fc428a2a687f61a952c49" +checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38" dependencies = [ - "autocfg", - "cfg-if 1.0.0", + "cfg-if", "lazy_static", ] [[package]] name = "derive-new" -version = "0.5.8" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71f31892cd5c62e414316f2963c5689242c43d8e7bbcaaeca97e5e28c95d91d9" +checksum = "3418329ca0ad70234b9735dc4ceed10af4df60eff9c8e7b06cb5e520d92c3535" dependencies = [ "proc-macro2", "quote", @@ -157,25 +146,45 @@ dependencies = [ [[package]] name = "diff" -version = "0.1.11" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c2b69f912779fbb121ceb775d74d51e915af17aaebc38d28a592843a2dd0a3a" +checksum = "0e25ea47919b1560c4e3b7fe0aaab9becf5b84a10325ddf7db0f0ba5e1026499" [[package]] name = "dirs" -version = "2.0.2" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" dependencies = [ - "cfg-if 0.1.10", "dirs-sys", ] +[[package]] +name = "dirs-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +dependencies = [ + "cfg-if", + "dirs-sys-next", +] + [[package]] name = "dirs-sys" -version = "0.3.6" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "dirs-sys-next" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03d86534ed367a67548dc68113a0f5db55432fdfbb6e6f9d77704397d95d5780" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" dependencies = [ "libc", "redox_users", @@ -184,15 +193,15 @@ dependencies = [ [[package]] name = "either" -version = "1.5.3" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" [[package]] name = "env_logger" -version = "0.8.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54532e3223c5af90a6a757c90b5c5521564b07e5e7a958681bcd2afad421cdcd" +checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" dependencies = [ "atty", "humantime", @@ -203,9 +212,9 @@ dependencies = [ [[package]] name = "fnv" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "getopts" @@ -218,20 +227,20 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.3" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", "wasi", ] [[package]] name = "globset" -version = "0.4.6" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c152169ef1e421390738366d2f796655fec62621dabbd0fd476f905934061e4a" +checksum = "10463d9ff00a2a068db14231982f5132edebad0d7660cd956a1c30292dbcbfbd" dependencies = [ "aho-corasick", "bstr", @@ -242,13 +251,22 @@ dependencies = [ [[package]] name = "heck" -version = "0.3.1" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" dependencies = [ "unicode-segmentation", ] +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + [[package]] name = "humantime" version = "2.1.0" @@ -257,9 +275,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "ignore" -version = "0.4.17" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b287fb45c60bb826a0dc68ff08742b9d88a2fea13d6e0c286b3172065aaf878c" +checksum = "713f1b139373f96a2e0ce3ac931cd01ee973c3c5dd7c40c0c2efe96ad2b6751d" dependencies = [ "crossbeam-utils", "globset", @@ -284,9 +302,9 @@ dependencies = [ [[package]] name = "itoa" -version = "0.4.4" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" +checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" [[package]] name = "lazy_static" @@ -296,9 +314,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.77" +version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f96b10ec2560088a8e76961b00d47107b3a625fecb76dedb29ee7ccbf98235" +checksum = "efaa7b300f3b5fe8eb6bf21ce3895e1751d9665086af2d64b42f19701015ff4f" [[package]] name = "libm" @@ -308,34 +326,40 @@ checksum = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a" [[package]] name = "log" -version = "0.4.14" +version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] [[package]] name = "memchr" -version = "2.2.1" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" + +[[package]] +name = "once_cell" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" +checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" [[package]] name = "packed_simd_2" -version = "0.3.4" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3278e0492f961fd4ae70909f56b2723a7e8d01a228427294e19cdfdebda89a17" +checksum = "defdcfef86dcc44ad208f71d9ff4ce28df6537a4e0d6b0e8e845cb8ca10059a6" dependencies = [ - "cfg-if 0.1.10", + "cfg-if", "libm", ] [[package]] name = "proc-macro-error" -version = "0.4.11" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7959c6467d962050d639361f7703b2051c43036d03493c36f01d440fdd3138a" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" dependencies = [ "proc-macro-error-attr", "proc-macro2", @@ -346,71 +370,69 @@ dependencies = [ [[package]] name = "proc-macro-error-attr" -version = "0.4.11" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4002d9f55991d5e019fb940a90e1a95eb80c24e77cb2462dd4dc869604d543a" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" dependencies = [ "proc-macro2", "quote", - "syn", - "syn-mid", "version_check", ] [[package]] name = "proc-macro2" -version = "1.0.26" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec" +checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" dependencies = [ "unicode-xid", ] [[package]] name = "quote" -version = "1.0.6" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54a21852a652ad6f610c9510194f398ff6f8692e334fd1145fed931f7fbe44ea" +checksum = "632d02bff7f874a36f33ea8bb416cd484b90cc66c1194b1a1110d067a7013f58" dependencies = [ "proc-macro2", ] [[package]] name = "redox_syscall" -version = "0.2.4" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05ec8ca9416c5ea37062b502703cd7fcb207736bc294f6e0cf367ac6fc234570" +checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" dependencies = [ "bitflags", ] [[package]] name = "redox_users" -version = "0.4.0" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ "getrandom", "redox_syscall", + "thiserror", ] [[package]] name = "regex" -version = "1.4.3" +version = "1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9251239e129e16308e70d853559389de218ac275b515068abc96829d05b948a" +checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286" dependencies = [ "aho-corasick", "memchr", "regex-syntax", - "thread_local", ] [[package]] name = "regex-syntax" -version = "0.6.22" +version = "0.6.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" [[package]] name = "rustc-workspace-hack" @@ -458,44 +480,50 @@ dependencies = [ "unicode_categories", ] +[[package]] +name = "rustversion" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f" + [[package]] name = "ryu" -version = "1.0.2" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8" +checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" [[package]] name = "same-file" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "585e8ddcedc187886a30fa705c47985c3fa88d06624095856b36ca0b82ff4421" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" dependencies = [ "winapi-util", ] [[package]] name = "semver" -version = "1.0.4" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012" +checksum = "d65bd28f48be7196d222d95b9243287f48d27aca604e08497513019ff0502cc4" dependencies = [ "serde", ] [[package]] name = "serde" -version = "1.0.126" +version = "1.0.136" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03" +checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.126" +version = "1.0.136" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43" +checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" dependencies = [ "proc-macro2", "quote", @@ -504,9 +532,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.59" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcac07dbffa1c65e7f816ab9eba78eb142c6d44410f4eeba1e26e4f5dfa56b95" +checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" dependencies = [ "itoa", "ryu", @@ -521,9 +549,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "structopt" -version = "0.3.11" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fe43617218c0805c6eb37160119dc3c548110a67786da7218d1c6555212f073" +checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10" dependencies = [ "clap", "lazy_static", @@ -532,9 +560,9 @@ dependencies = [ [[package]] name = "structopt-derive" -version = "0.4.4" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6e79c80e0f4efd86ca960218d4e056249be189ff1c42824dcd9a7f51a56f0bd" +checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" dependencies = [ "heck", "proc-macro-error", @@ -545,43 +573,33 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.65" +version = "1.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3a1d708c221c5a612956ef9f75b37e454e88d1f7b899fbd3a18d4252012d663" +checksum = "704df27628939572cd88d33f171cd6f896f4eaca85252c6e0a72d8d8287ee86f" dependencies = [ "proc-macro2", "quote", "unicode-xid", ] -[[package]] -name = "syn-mid" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "term" -version = "0.6.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0863a3345e70f61d613eab32ee046ccd1bcc5f9105fe402c61fcd0c13eeb8b5" +checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f" dependencies = [ - "dirs", + "dirs-next", + "rustversion", "winapi", ] [[package]] name = "termcolor" -version = "1.0.5" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d6098003bde162e4277c70665bd87c326f5a0c3f3fbfb285787fa482d54e6e" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" dependencies = [ - "wincolor", + "winapi-util", ] [[package]] @@ -595,18 +613,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.6" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc6b305ec0e323c7b6cfff6098a22516e0063d0bb7c3d88660a890217dca099a" +checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.6" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45ba8d810d9c48fc456b7ad54574e8bfb7c7918a57ad7a6e6a0985d7959e8597" +checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" dependencies = [ "proc-macro2", "quote", @@ -615,39 +633,39 @@ dependencies = [ [[package]] name = "thread_local" -version = "1.0.1" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" +checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" dependencies = [ - "lazy_static", + "once_cell", ] [[package]] name = "toml" -version = "0.5.3" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7aabe75941d914b72bf3e5d3932ed92ce0664d49d8432305a8b547c37227724" +checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" dependencies = [ "serde", ] [[package]] name = "unicode-segmentation" -version = "1.3.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1967f4cdfc355b37fd76d2a954fb2ed3871034eb4f26d60537d88795cfc332a9" +checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" [[package]] name = "unicode-width" -version = "0.1.6" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7007dbd421b92cc6e28410fe7362e2e0a2503394908f417b68ec8d1c364c4e20" +checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" [[package]] name = "unicode-xid" -version = "0.2.0" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" [[package]] name = "unicode_categories" @@ -657,21 +675,21 @@ checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" [[package]] name = "vec_map" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" [[package]] name = "version_check" -version = "0.9.1" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "walkdir" -version = "2.2.9" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9658c94fa8b940eab2250bd5a457f9c48b748420d71293b165c8cdbe2f55f71e" +checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" dependencies = [ "same-file", "winapi", @@ -686,9 +704,9 @@ checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[package]] name = "winapi" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" dependencies = [ "winapi-i686-pc-windows-gnu", "winapi-x86_64-pc-windows-gnu", @@ -702,9 +720,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.2" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" dependencies = [ "winapi", ] @@ -715,16 +733,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "wincolor" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96f5016b18804d24db43cebf3c77269e7569b8954a8464501c216cc5e070eaa9" -dependencies = [ - "winapi", - "winapi-util", -] - [[package]] name = "yansi-term" version = "0.1.2" diff --git a/Cargo.toml b/Cargo.toml index 764714638a978..4325f46db9fe4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,30 +33,31 @@ rustfmt-format-diff = [] generic-simd = ["bytecount/generic-simd"] [dependencies] -itertools = "0.10.1" -toml = "0.5" -serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0" -unicode-segmentation = "1.0.0" -regex = "1.0" -term = "0.6" +annotate-snippets = { version = "0.9", features = ["color"] } +anyhow = "1.0" +bytecount = "0.6" +cargo_metadata = "0.14" +derive-new = "0.5" diff = "0.1" -log = "0.4.14" -env_logger = "0.8" +dirs = "4.0" +env_logger = "0.9" getopts = "0.2" -derive-new = "0.5" -cargo_metadata = "0.14" -bytecount = "0.6" -unicode-width = "0.1.5" -unicode_categories = "0.1.1" -dirs = "2.0.1" -ignore = "0.4.17" -annotate-snippets = { version = "0.8", features = ["color"] } +ignore = "0.4" +itertools = "0.10" +lazy_static = "1.4" +log = "0.4" +regex = "1.5" +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" structopt = "0.3" -rustfmt-config_proc_macro = { version = "0.2", path = "config_proc_macro" } -lazy_static = "1.0.0" -anyhow = "1.0" +term = "0.7" thiserror = "1.0" +toml = "0.5" +unicode-segmentation = "1.9" +unicode-width = "0.1" +unicode_categories = "0.1" + +rustfmt-config_proc_macro = { version = "0.2", path = "config_proc_macro" } # A noop dependency that changes in the Rust repository, it's a bit of a hack. # See the `src/tools/rustc-workspace-hack/README.md` file in `rust-lang/rust` From 11d0bae9f1682c215693e71d2d738b58639ebdff Mon Sep 17 00:00:00 2001 From: David Wood Date: Thu, 24 Mar 2022 02:03:04 +0000 Subject: [PATCH 05/53] span: move `MultiSpan` `MultiSpan` contains labels, which are more complicated with the introduction of diagnostic translation and will use types from `rustc_errors` - however, `rustc_errors` depends on `rustc_span` so `rustc_span` cannot use types like `DiagnosticMessage` without dependency cycles. Introduce a new `rustc_error_messages` crate that can contain `DiagnosticMessage` and `MultiSpan`. Signed-off-by: David Wood --- src/parse/session.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/parse/session.rs b/src/parse/session.rs index 7571e6d078a7b..7f11cddd882c7 100644 --- a/src/parse/session.rs +++ b/src/parse/session.rs @@ -313,7 +313,8 @@ mod tests { use super::*; use crate::config::IgnoreList; use crate::utils::mk_sp; - use rustc_span::{FileName as SourceMapFileName, MultiSpan, RealFileName}; + use rustc_errors::MultiSpan; + use rustc_span::{FileName as SourceMapFileName, RealFileName}; use std::path::PathBuf; use std::sync::atomic::AtomicU32; From 6eea2a88c16d44dd6d81cdabcbf2c15ffa424fdc Mon Sep 17 00:00:00 2001 From: David Wood Date: Sat, 26 Mar 2022 07:27:43 +0000 Subject: [PATCH 06/53] errors: implement fallback diagnostic translation This commit updates the signatures of all diagnostic functions to accept types that can be converted into a `DiagnosticMessage`. This enables existing diagnostic calls to continue to work as before and Fluent identifiers to be provided. The `SessionDiagnostic` derive just generates normal diagnostic calls, so these APIs had to be modified to accept Fluent identifiers. In addition, loading of the "fallback" Fluent bundle, which contains the built-in English messages, has been implemented. Each diagnostic now has "arguments" which correspond to variables in the Fluent messages (necessary to render a Fluent message) but no API for adding arguments has been added yet. Therefore, diagnostics (that do not require interpolation) can be converted to use Fluent identifiers and will be output as before. --- src/parse/session.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/parse/session.rs b/src/parse/session.rs index 7f11cddd882c7..4563dbf6c16b0 100644 --- a/src/parse/session.rs +++ b/src/parse/session.rs @@ -33,6 +33,12 @@ impl Emitter for SilentEmitter { None } fn emit_diagnostic(&mut self, _db: &Diagnostic) {} + fn fluent_bundle(&self) -> Option<&Lrc> { + None + } + fn fallback_fluent_bundle(&self) -> &Lrc { + panic!("silent emitter attempted to translate a diagnostic"); + } } fn silent_emitter() -> Box { @@ -82,6 +88,14 @@ impl Emitter for SilentOnIgnoredFilesEmitter { } self.handle_non_ignoreable_error(db); } + + fn fluent_bundle(&self) -> Option<&Lrc> { + self.emitter.fluent_bundle() + } + + fn fallback_fluent_bundle(&self) -> &Lrc { + self.emitter.fallback_fluent_bundle() + } } fn default_handler( @@ -100,9 +114,11 @@ fn default_handler( let emitter = if hide_parse_errors { silent_emitter() } else { + let fallback_bundle = rustc_errors::fallback_fluent_bundle(); Box::new(EmitterWriter::stderr( color_cfg, Some(source_map.clone()), + fallback_bundle, false, false, None, @@ -329,6 +345,12 @@ mod tests { fn emit_diagnostic(&mut self, _db: &Diagnostic) { self.num_emitted_errors.fetch_add(1, Ordering::Release); } + fn fluent_bundle(&self) -> Option<&Lrc> { + None + } + fn fallback_fluent_bundle(&self) -> &Lrc { + panic!("test emitter attempted to translate a diagnostic"); + } } fn build_diagnostic(level: DiagnosticLevel, span: Option) -> Diagnostic { From f8ad4b5cf853b85bc4d8794bdf6ee3244935c123 Mon Sep 17 00:00:00 2001 From: David Wood Date: Mon, 28 Mar 2022 09:36:20 +0100 Subject: [PATCH 07/53] errors: implement sysroot/testing bundle loading Extend loading of Fluent bundles so that bundles can be loaded from the sysroot based on the language requested by the user, or using a nightly flag. Sysroot bundles are loaded from `$sysroot/share/locale/$locale/*.ftl`. Signed-off-by: David Wood --- src/parse/session.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/parse/session.rs b/src/parse/session.rs index 4563dbf6c16b0..6967028d55f56 100644 --- a/src/parse/session.rs +++ b/src/parse/session.rs @@ -114,10 +114,12 @@ fn default_handler( let emitter = if hide_parse_errors { silent_emitter() } else { - let fallback_bundle = rustc_errors::fallback_fluent_bundle(); + let fallback_bundle = rustc_errors::fallback_fluent_bundle() + .expect("failed to load fallback fluent bundle"); Box::new(EmitterWriter::stderr( color_cfg, Some(source_map.clone()), + None, fallback_bundle, false, false, From b482bee00cc35017da249e2f6e26ea7e68ab8d92 Mon Sep 17 00:00:00 2001 From: David Wood Date: Sun, 3 Apr 2022 04:53:01 +0100 Subject: [PATCH 08/53] session: opt for enabling directionality markers Add an option for enabling and disabling Fluent's directionality isolation markers in output. Disabled by default as these can render in some terminals and applications. Signed-off-by: David Wood --- src/parse/session.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/parse/session.rs b/src/parse/session.rs index 6967028d55f56..7125b2ee6859b 100644 --- a/src/parse/session.rs +++ b/src/parse/session.rs @@ -114,7 +114,7 @@ fn default_handler( let emitter = if hide_parse_errors { silent_emitter() } else { - let fallback_bundle = rustc_errors::fallback_fluent_bundle() + let fallback_bundle = rustc_errors::fallback_fluent_bundle(false) .expect("failed to load fallback fluent bundle"); Box::new(EmitterWriter::stderr( color_cfg, From 91995b6142faf1a5e56e1b7b1cb922504726197c Mon Sep 17 00:00:00 2001 From: Expyron <5100376+Expyron@users.noreply.github.com> Date: Thu, 7 Apr 2022 09:57:58 +0200 Subject: [PATCH 09/53] Replace `structopt` dependency by `clap` --- Cargo.lock | 127 +++++++++++++++++++------------------- Cargo.toml | 2 +- src/cargo-fmt/main.rs | 33 +++++----- src/cargo-fmt/test/mod.rs | 42 +++++++------ src/format-diff/main.rs | 45 +++++++------- 5 files changed, 130 insertions(+), 119 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1b444136585d0..4eaaee74cf96a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21,15 +21,6 @@ dependencies = [ "yansi-term", ] -[[package]] -name = "ansi_term" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" -dependencies = [ - "winapi", -] - [[package]] name = "anyhow" version = "1.0.56" @@ -47,6 +38,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + [[package]] name = "bitflags" version = "1.3.2" @@ -110,17 +107,32 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "2.34.0" +version = "3.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +checksum = "71c47df61d9e16dc010b55dba1952a57d8c215dbb533fd13cdd13369aac73b1c" dependencies = [ - "ansi_term", "atty", "bitflags", + "clap_derive", + "indexmap", + "lazy_static", + "os_str_bytes", "strsim", + "termcolor", "textwrap", - "unicode-width", - "vec_map", +] + +[[package]] +name = "clap_derive" +version = "3.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3aab4734e083b809aaf5794e14e756d1c798d2c69c7f7de7a09a2f5214993c1" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -249,14 +261,17 @@ dependencies = [ "regex", ] +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" + [[package]] name = "heck" -version = "0.3.3" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" -dependencies = [ - "unicode-segmentation", -] +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" [[package]] name = "hermit-abi" @@ -291,6 +306,16 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "indexmap" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee" +dependencies = [ + "autocfg", + "hashbrown", +] + [[package]] name = "itertools" version = "0.10.3" @@ -314,9 +339,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.121" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efaa7b300f3b5fe8eb6bf21ce3895e1751d9665086af2d64b42f19701015ff4f" +checksum = "ec647867e2bf0772e28c8bcde4f0d19a9216916e890543b5a03ed8ef27b8f259" [[package]] name = "libm" @@ -345,6 +370,15 @@ version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" +[[package]] +name = "os_str_bytes" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64" +dependencies = [ + "memchr", +] + [[package]] name = "packed_simd_2" version = "0.3.7" @@ -381,9 +415,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" +checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1" dependencies = [ "unicode-xid", ] @@ -457,6 +491,7 @@ dependencies = [ "anyhow", "bytecount", "cargo_metadata", + "clap", "derive-new", "diff", "dirs", @@ -471,7 +506,6 @@ dependencies = [ "rustfmt-config_proc_macro", "serde", "serde_json", - "structopt", "term", "thiserror", "toml", @@ -543,39 +577,15 @@ dependencies = [ [[package]] name = "strsim" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" - -[[package]] -name = "structopt" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10" -dependencies = [ - "clap", - "lazy_static", - "structopt-derive", -] - -[[package]] -name = "structopt-derive" -version = "0.4.18" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" -dependencies = [ - "heck", - "proc-macro-error", - "proc-macro2", - "quote", - "syn", -] +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "1.0.90" +version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "704df27628939572cd88d33f171cd6f896f4eaca85252c6e0a72d8d8287ee86f" +checksum = "b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d" dependencies = [ "proc-macro2", "quote", @@ -604,12 +614,9 @@ dependencies = [ [[package]] name = "textwrap" -version = "0.11.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -dependencies = [ - "unicode-width", -] +checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" [[package]] name = "thiserror" @@ -673,12 +680,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" -[[package]] -name = "vec_map" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" - [[package]] name = "version_check" version = "0.9.4" diff --git a/Cargo.toml b/Cargo.toml index 4325f46db9fe4..0be9723bc4dcf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,6 +37,7 @@ annotate-snippets = { version = "0.9", features = ["color"] } anyhow = "1.0" bytecount = "0.6" cargo_metadata = "0.14" +clap = { version = "3.1", features = ["derive"] } derive-new = "0.5" diff = "0.1" dirs = "4.0" @@ -49,7 +50,6 @@ log = "0.4" regex = "1.5" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -structopt = "0.3" term = "0.7" thiserror = "1.0" toml = "0.5" diff --git a/src/cargo-fmt/main.rs b/src/cargo-fmt/main.rs index 8cb7b4585ecb2..3542536f29b61 100644 --- a/src/cargo-fmt/main.rs +++ b/src/cargo-fmt/main.rs @@ -15,54 +15,59 @@ use std::path::{Path, PathBuf}; use std::process::Command; use std::str; -use structopt::StructOpt; +use clap::{CommandFactory, Parser}; #[path = "test/mod.rs"] #[cfg(test)] mod cargo_fmt_tests; -#[derive(StructOpt, Debug)] -#[structopt( +#[derive(Parser)] +#[clap( bin_name = "cargo fmt", about = "This utility formats all bin and lib files of \ the current crate using rustfmt." )] pub struct Opts { /// No output printed to stdout - #[structopt(short = "q", long = "quiet")] + #[clap(short = 'q', long = "quiet")] quiet: bool, /// Use verbose output - #[structopt(short = "v", long = "verbose")] + #[clap(short = 'v', long = "verbose")] verbose: bool, /// Print rustfmt version and exit - #[structopt(long = "version")] + #[clap(long = "version")] version: bool, /// Specify package to format - #[structopt(short = "p", long = "package", value_name = "package")] + #[clap( + short = 'p', + long = "package", + value_name = "package", + multiple_values = true + )] packages: Vec, /// Specify path to Cargo.toml - #[structopt(long = "manifest-path", value_name = "manifest-path")] + #[clap(long = "manifest-path", value_name = "manifest-path")] manifest_path: Option, /// Specify message-format: short|json|human - #[structopt(long = "message-format", value_name = "message-format")] + #[clap(long = "message-format", value_name = "message-format")] message_format: Option, /// Options passed to rustfmt // 'raw = true' to make `--` explicit. - #[structopt(name = "rustfmt_options", raw(true))] + #[clap(name = "rustfmt_options", raw(true))] rustfmt_options: Vec, /// Format all packages, and also their local path-based dependencies - #[structopt(long = "all")] + #[clap(long = "all")] format_all: bool, /// Run rustfmt in check mode - #[structopt(long = "check")] + #[clap(long = "check")] check: bool, } @@ -87,7 +92,7 @@ fn execute() -> i32 { } }); - let opts = Opts::from_iter(args); + let opts = Opts::parse_from(args); let verbosity = match (opts.verbose, opts.quiet) { (false, false) => Verbosity::Normal, @@ -204,7 +209,7 @@ fn convert_message_format_to_rustfmt_args( fn print_usage_to_stderr(reason: &str) { eprintln!("{}", reason); - let app = Opts::clap(); + let app = Opts::command(); app.after_help("") .write_help(&mut io::stderr()) .expect("failed to write to stderr"); diff --git a/src/cargo-fmt/test/mod.rs b/src/cargo-fmt/test/mod.rs index 360503632c7ed..56e52fbabb68b 100644 --- a/src/cargo-fmt/test/mod.rs +++ b/src/cargo-fmt/test/mod.rs @@ -6,7 +6,7 @@ mod targets; #[test] fn default_options() { let empty: Vec = vec![]; - let o = Opts::from_iter(&empty); + let o = Opts::parse_from(&empty); assert_eq!(false, o.quiet); assert_eq!(false, o.verbose); assert_eq!(false, o.version); @@ -20,7 +20,7 @@ fn default_options() { #[test] fn good_options() { - let o = Opts::from_iter(&[ + let o = Opts::parse_from(&[ "test", "-q", "-p", @@ -47,8 +47,8 @@ fn good_options() { #[test] fn unexpected_option() { assert!( - Opts::clap() - .get_matches_from_safe(&["test", "unexpected"]) + Opts::command() + .try_get_matches_from(&["test", "unexpected"]) .is_err() ); } @@ -56,8 +56,8 @@ fn unexpected_option() { #[test] fn unexpected_flag() { assert!( - Opts::clap() - .get_matches_from_safe(&["test", "--flag"]) + Opts::command() + .try_get_matches_from(&["test", "--flag"]) .is_err() ); } @@ -65,20 +65,20 @@ fn unexpected_flag() { #[test] fn mandatory_separator() { assert!( - Opts::clap() - .get_matches_from_safe(&["test", "--emit"]) + Opts::command() + .try_get_matches_from(&["test", "--emit"]) .is_err() ); assert!( - !Opts::clap() - .get_matches_from_safe(&["test", "--", "--emit"]) + !Opts::command() + .try_get_matches_from(&["test", "--", "--emit"]) .is_err() ); } #[test] fn multiple_packages_one_by_one() { - let o = Opts::from_iter(&[ + let o = Opts::parse_from(&[ "test", "-p", "package1", @@ -92,7 +92,7 @@ fn multiple_packages_one_by_one() { #[test] fn multiple_packages_grouped() { - let o = Opts::from_iter(&[ + let o = Opts::parse_from(&[ "test", "--package", "package1", @@ -106,14 +106,18 @@ fn multiple_packages_grouped() { #[test] fn empty_packages_1() { - assert!(Opts::clap().get_matches_from_safe(&["test", "-p"]).is_err()); + assert!( + Opts::command() + .try_get_matches_from(&["test", "-p"]) + .is_err() + ); } #[test] fn empty_packages_2() { assert!( - Opts::clap() - .get_matches_from_safe(&["test", "-p", "--", "--check"]) + Opts::command() + .try_get_matches_from(&["test", "-p", "--", "--check"]) .is_err() ); } @@ -121,8 +125,8 @@ fn empty_packages_2() { #[test] fn empty_packages_3() { assert!( - Opts::clap() - .get_matches_from_safe(&["test", "-p", "--verbose"]) + Opts::command() + .try_get_matches_from(&["test", "-p", "--verbose"]) .is_err() ); } @@ -130,8 +134,8 @@ fn empty_packages_3() { #[test] fn empty_packages_4() { assert!( - Opts::clap() - .get_matches_from_safe(&["test", "-p", "--check"]) + Opts::command() + .try_get_matches_from(&["test", "-p", "--check"]) .is_err() ); } diff --git a/src/format-diff/main.rs b/src/format-diff/main.rs index 655aeda42bf28..f6b739e1c2a37 100644 --- a/src/format-diff/main.rs +++ b/src/format-diff/main.rs @@ -19,8 +19,7 @@ use std::process; use regex::Regex; -use structopt::clap::AppSettings; -use structopt::StructOpt; +use clap::{CommandFactory, Parser}; /// The default pattern of files to format. /// @@ -37,16 +36,16 @@ enum FormatDiffError { IoError(#[from] io::Error), } -#[derive(StructOpt, Debug)] -#[structopt( +#[derive(Parser, Debug)] +#[clap( name = "rustfmt-format-diff", - setting = AppSettings::DisableVersion, - setting = AppSettings::NextLineHelp + disable_version_flag = true, + next_line_help = true )] pub struct Opts { /// Skip the smallest prefix containing NUMBER slashes - #[structopt( - short = "p", + #[clap( + short = 'p', long = "skip-prefix", value_name = "NUMBER", default_value = "0" @@ -54,8 +53,8 @@ pub struct Opts { skip_prefix: u32, /// Custom pattern selecting file paths to reformat - #[structopt( - short = "f", + #[clap( + short = 'f', long = "filter", value_name = "PATTERN", default_value = DEFAULT_PATTERN @@ -65,10 +64,12 @@ pub struct Opts { fn main() { env_logger::Builder::from_env("RUSTFMT_LOG").init(); - let opts = Opts::from_args(); + let opts = Opts::parse(); if let Err(e) = run(opts) { println!("{}", e); - Opts::clap().print_help().expect("cannot write to stdout"); + Opts::command() + .print_help() + .expect("cannot write to stdout"); process::exit(1); } } @@ -230,14 +231,14 @@ mod cmd_line_tests { #[test] fn default_options() { let empty: Vec = vec![]; - let o = Opts::from_iter(&empty); + let o = Opts::parse_from(&empty); assert_eq!(DEFAULT_PATTERN, o.filter); assert_eq!(0, o.skip_prefix); } #[test] fn good_options() { - let o = Opts::from_iter(&["test", "-p", "10", "-f", r".*\.hs"]); + let o = Opts::parse_from(&["test", "-p", "10", "-f", r".*\.hs"]); assert_eq!(r".*\.hs", o.filter); assert_eq!(10, o.skip_prefix); } @@ -245,8 +246,8 @@ mod cmd_line_tests { #[test] fn unexpected_option() { assert!( - Opts::clap() - .get_matches_from_safe(&["test", "unexpected"]) + Opts::command() + .try_get_matches_from(&["test", "unexpected"]) .is_err() ); } @@ -254,8 +255,8 @@ mod cmd_line_tests { #[test] fn unexpected_flag() { assert!( - Opts::clap() - .get_matches_from_safe(&["test", "--flag"]) + Opts::command() + .try_get_matches_from(&["test", "--flag"]) .is_err() ); } @@ -263,8 +264,8 @@ mod cmd_line_tests { #[test] fn overridden_option() { assert!( - Opts::clap() - .get_matches_from_safe(&["test", "-p", "10", "-p", "20"]) + Opts::command() + .try_get_matches_from(&["test", "-p", "10", "-p", "20"]) .is_err() ); } @@ -272,8 +273,8 @@ mod cmd_line_tests { #[test] fn negative_filter() { assert!( - Opts::clap() - .get_matches_from_safe(&["test", "-p", "-1"]) + Opts::command() + .try_get_matches_from(&["test", "-p", "-1"]) .is_err() ); } From 2d9bc460108df4e3587be82e36a58f2fb3f4813f Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Tue, 14 Jul 2020 00:03:13 -0500 Subject: [PATCH 10/53] Backport 4326 refactor: rename some private whitelist names --- src/overflow.rs | 12 ++++++------ src/test/mod.rs | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/overflow.rs b/src/overflow.rs index 80aed998d7377..c296961d1f0ce 100644 --- a/src/overflow.rs +++ b/src/overflow.rs @@ -32,7 +32,7 @@ use crate::utils::{count_newlines, extra_offset, first_line_width, last_line_wid /// Organized as a list of `(&str, usize)` tuples, giving the name of the macro and the number of /// arguments before the format string (none for `format!("format", ...)`, one for `assert!(result, /// "format", ...)`, two for `assert_eq!(left, right, "format", ...)`). -const SPECIAL_MACRO_WHITELIST: &[(&str, usize)] = &[ +const SPECIAL_CASE_MACROS: &[(&str, usize)] = &[ // format! like macros // From the Rust Standard Library. ("eprint!", 0), @@ -60,7 +60,7 @@ const SPECIAL_MACRO_WHITELIST: &[(&str, usize)] = &[ ("debug_assert_ne!", 2), ]; -const SPECIAL_ATTR_WHITELIST: &[(&str, usize)] = &[ +const SPECIAL_CASE_ATTR: &[(&str, usize)] = &[ // From the `failure` crate. ("fail", 0), ]; @@ -182,10 +182,10 @@ impl<'a> OverflowableItem<'a> { } } - fn whitelist(&self) -> &'static [(&'static str, usize)] { + fn special_cases(&self) -> &'static [(&'static str, usize)] { match self { - OverflowableItem::MacroArg(..) => SPECIAL_MACRO_WHITELIST, - OverflowableItem::NestedMetaItem(..) => SPECIAL_ATTR_WHITELIST, + OverflowableItem::MacroArg(..) => SPECIAL_CASE_MACROS, + OverflowableItem::NestedMetaItem(..) => SPECIAL_CASE_ATTR, _ => &[], } } @@ -770,7 +770,7 @@ pub(crate) fn maybe_get_args_offset( ) -> Option<(bool, usize)> { if let Some(&(_, num_args_before)) = args .get(0)? - .whitelist() + .special_cases() .iter() .find(|&&(s, _)| s == callee_str) { diff --git a/src/test/mod.rs b/src/test/mod.rs index ab966d4a36075..4bad8e71481e8 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -24,7 +24,7 @@ mod parser; const DIFF_CONTEXT_SIZE: usize = 3; // A list of files on which we want to skip testing. -const SKIP_FILE_WHITE_LIST: &[&str] = &[ +const FILE_SKIP_LIST: &[&str] = &[ // We want to make sure that the `skip_children` is correctly working, // so we do not want to test this file directly. "configs/skip_children/foo/mod.rs", @@ -90,7 +90,7 @@ where } fn is_file_skip(path: &Path) -> bool { - SKIP_FILE_WHITE_LIST + FILE_SKIP_LIST .iter() .any(|file_path| is_subpath(path, file_path)) } From 4f3f87fb9a629db8bf0c6e04604320cd028f79e8 Mon Sep 17 00:00:00 2001 From: Tom Milligan Date: Sat, 5 Mar 2022 23:01:43 +0000 Subject: [PATCH 11/53] group_imports: test and document non-consecutive imports --- Configurations.md | 6 ++++- .../StdExternalCrate-non_consecutive.rs | 27 +++++++++++++++++++ .../StdExternalCrate-non_consecutive.rs | 18 +++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 tests/source/configs/group_imports/StdExternalCrate-non_consecutive.rs create mode 100644 tests/target/configs/group_imports/StdExternalCrate-non_consecutive.rs diff --git a/Configurations.md b/Configurations.md index a47439b9ba96c..dc8d38267a83d 100644 --- a/Configurations.md +++ b/Configurations.md @@ -2061,12 +2061,16 @@ use sit; ## `group_imports` -Controls the strategy for how imports are grouped together. +Controls the strategy for how consecutive imports are grouped together. + +Controls the strategy for grouping sets of consecutive imports. Imports may contain newlines between imports and still be grouped together as a single set, but other statements between imports will result in different grouping sets. - **Default value**: `Preserve` - **Possible values**: `Preserve`, `StdExternalCrate`, `One` - **Stable**: No (tracking issue: [#5083](https://github.com/rust-lang/rustfmt/issues/5083)) +Each set of imports (one or more `use` statements, optionally separated by newlines) will be formatted independently. Other statements such as `mod ...` or `extern crate ...` will cause imports to not be grouped together. + #### `Preserve` (default): Preserve the source file's import groups. diff --git a/tests/source/configs/group_imports/StdExternalCrate-non_consecutive.rs b/tests/source/configs/group_imports/StdExternalCrate-non_consecutive.rs new file mode 100644 index 0000000000000..f239a0efa0855 --- /dev/null +++ b/tests/source/configs/group_imports/StdExternalCrate-non_consecutive.rs @@ -0,0 +1,27 @@ +// rustfmt-group_imports: StdExternalCrate +use chrono::Utc; +use super::update::convert_publish_payload; + + + + + +use juniper::{FieldError, FieldResult}; + +use uuid::Uuid; +use alloc::alloc::Layout; + +extern crate uuid; + + + + + +use std::sync::Arc; + + +use broker::database::PooledConnection; + +use super::schema::{Context, Payload}; +use core::f32; +use crate::models::Event; diff --git a/tests/target/configs/group_imports/StdExternalCrate-non_consecutive.rs b/tests/target/configs/group_imports/StdExternalCrate-non_consecutive.rs new file mode 100644 index 0000000000000..ecc8ede02cc61 --- /dev/null +++ b/tests/target/configs/group_imports/StdExternalCrate-non_consecutive.rs @@ -0,0 +1,18 @@ +// rustfmt-group_imports: StdExternalCrate +use alloc::alloc::Layout; + +use chrono::Utc; +use juniper::{FieldError, FieldResult}; +use uuid::Uuid; + +use super::update::convert_publish_payload; + +extern crate uuid; + +use core::f32; +use std::sync::Arc; + +use broker::database::PooledConnection; + +use super::schema::{Context, Payload}; +use crate::models::Event; From 0cf62ae103422c96000c10ebcc3ec76028647b1e Mon Sep 17 00:00:00 2001 From: David Wood Date: Tue, 12 Apr 2022 09:34:40 +0100 Subject: [PATCH 12/53] errors: lazily load fallback fluent bundle Loading the fallback bundle in compilation sessions that won't go on to emit any errors unnecessarily degrades compile time performance, so lazily create the Fluent bundle when it is first required. Signed-off-by: David Wood --- src/parse/session.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/parse/session.rs b/src/parse/session.rs index 7125b2ee6859b..4408e20747a6a 100644 --- a/src/parse/session.rs +++ b/src/parse/session.rs @@ -36,7 +36,7 @@ impl Emitter for SilentEmitter { fn fluent_bundle(&self) -> Option<&Lrc> { None } - fn fallback_fluent_bundle(&self) -> &Lrc { + fn fallback_fluent_bundle(&self) -> &rustc_errors::FluentBundle { panic!("silent emitter attempted to translate a diagnostic"); } } @@ -93,7 +93,7 @@ impl Emitter for SilentOnIgnoredFilesEmitter { self.emitter.fluent_bundle() } - fn fallback_fluent_bundle(&self) -> &Lrc { + fn fallback_fluent_bundle(&self) -> &rustc_errors::FluentBundle { self.emitter.fallback_fluent_bundle() } } @@ -114,8 +114,8 @@ fn default_handler( let emitter = if hide_parse_errors { silent_emitter() } else { - let fallback_bundle = rustc_errors::fallback_fluent_bundle(false) - .expect("failed to load fallback fluent bundle"); + let fallback_bundle = + rustc_errors::fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false); Box::new(EmitterWriter::stderr( color_cfg, Some(source_map.clone()), @@ -350,7 +350,7 @@ mod tests { fn fluent_bundle(&self) -> Option<&Lrc> { None } - fn fallback_fluent_bundle(&self) -> &Lrc { + fn fallback_fluent_bundle(&self) -> &rustc_errors::FluentBundle { panic!("test emitter attempted to translate a diagnostic"); } } From 10954cfd4c2a6a847d522540c81f654219bb9ce5 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 19 Nov 2021 22:03:43 +0100 Subject: [PATCH 13/53] Visit generics inside visit_fn. --- src/items.rs | 13 +++++++++---- src/visitor.rs | 18 +++++++++++------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/items.rs b/src/items.rs index 92f423bbb6275..ad2502b041840 100644 --- a/src/items.rs +++ b/src/items.rs @@ -204,12 +204,11 @@ impl<'a> FnSig<'a> { pub(crate) fn from_fn_kind( fn_kind: &'a visit::FnKind<'_>, - generics: &'a ast::Generics, decl: &'a ast::FnDecl, defaultness: ast::Defaultness, ) -> FnSig<'a> { match *fn_kind { - visit::FnKind::Fn(fn_ctxt, _, fn_sig, vis, _) => match fn_ctxt { + visit::FnKind::Fn(fn_ctxt, _, fn_sig, vis, generics, _) => match fn_ctxt { visit::FnCtxt::Assoc(..) => { let mut fn_sig = FnSig::from_method_sig(fn_sig, generics, vis); fn_sig.defaultness = defaultness; @@ -3180,8 +3179,14 @@ impl Rewrite for ast::ForeignItem { let inner_attrs = inner_attributes(&self.attrs); let fn_ctxt = visit::FnCtxt::Foreign; visitor.visit_fn( - visit::FnKind::Fn(fn_ctxt, self.ident, sig, &self.vis, Some(body)), - generics, + visit::FnKind::Fn( + fn_ctxt, + self.ident, + sig, + &self.vis, + generics, + Some(body), + ), &sig.decl, self.span, defaultness, diff --git a/src/visitor.rs b/src/visitor.rs index 3ebfa551d1cbc..1621eb406b10f 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -382,7 +382,6 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { pub(crate) fn visit_fn( &mut self, fk: visit::FnKind<'_>, - generics: &ast::Generics, fd: &ast::FnDecl, s: Span, defaultness: ast::Defaultness, @@ -391,12 +390,12 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { let indent = self.block_indent; let block; let rewrite = match fk { - visit::FnKind::Fn(_, ident, _, _, Some(ref b)) => { + visit::FnKind::Fn(_, ident, _, _, _, Some(ref b)) => { block = b; self.rewrite_fn_before_block( indent, ident, - &FnSig::from_fn_kind(&fk, generics, fd, defaultness), + &FnSig::from_fn_kind(&fk, fd, defaultness), mk_sp(s.lo(), b.span.lo()), ) } @@ -552,8 +551,14 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { _ => visit::FnCtxt::Foreign, }; self.visit_fn( - visit::FnKind::Fn(fn_ctxt, item.ident, sig, &item.vis, Some(body)), - generics, + visit::FnKind::Fn( + fn_ctxt, + item.ident, + sig, + &item.vis, + generics, + Some(body), + ), &sig.decl, item.span, defaultness, @@ -642,8 +647,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { let inner_attrs = inner_attributes(&ai.attrs); let fn_ctxt = visit::FnCtxt::Assoc(assoc_ctxt); self.visit_fn( - visit::FnKind::Fn(fn_ctxt, ai.ident, sig, &ai.vis, Some(body)), - generics, + visit::FnKind::Fn(fn_ctxt, ai.ident, sig, &ai.vis, generics, Some(body)), &sig.decl, ai.span, defaultness, From ba0351a1460e1e415293aa5e2b347b83e933703f Mon Sep 17 00:00:00 2001 From: Paul Gey Date: Sun, 17 Oct 2021 16:21:53 +0200 Subject: [PATCH 14/53] Preserve attributes for `imports_granularity=Item` Fixes #5030 --- src/imports.rs | 52 ++++++++++++++++++++++++++++---------- src/reorder.rs | 15 +++-------- tests/source/issue-5030.rs | 7 +++++ tests/target/issue-5030.rs | 6 +++++ 4 files changed, 56 insertions(+), 24 deletions(-) create mode 100644 tests/source/issue-5030.rs create mode 100644 tests/target/issue-5030.rs diff --git a/src/imports.rs b/src/imports.rs index 0231980948686..485a72b85da44 100644 --- a/src/imports.rs +++ b/src/imports.rs @@ -10,6 +10,7 @@ use rustc_span::{ use crate::comment::combine_strs_with_missing_comments; use crate::config::lists::*; +use crate::config::ImportGranularity; use crate::config::{Edition, IndentStyle}; use crate::lists::{ definitive_tactic, itemize_list, write_list, ListFormatting, ListItem, Separator, @@ -182,7 +183,18 @@ impl UseSegment { } } -pub(crate) fn merge_use_trees(use_trees: Vec, merge_by: SharedPrefix) -> Vec { +pub(crate) fn regroup_use_trees( + use_trees: Vec, + import_granularity: ImportGranularity, +) -> Vec { + let merge_by = match import_granularity { + ImportGranularity::Item => return flatten_use_trees(use_trees, ImportGranularity::Item), + ImportGranularity::Preserve => return use_trees, + ImportGranularity::Crate => SharedPrefix::Crate, + ImportGranularity::Module => SharedPrefix::Module, + ImportGranularity::One => SharedPrefix::One, + }; + let mut result = Vec::with_capacity(use_trees.len()); for use_tree in use_trees { if use_tree.has_comment() || use_tree.attrs.is_some() { @@ -190,7 +202,7 @@ pub(crate) fn merge_use_trees(use_trees: Vec, merge_by: SharedPrefix) - continue; } - for mut flattened in use_tree.flatten() { + for mut flattened in use_tree.flatten(import_granularity) { if let Some(tree) = result .iter_mut() .find(|tree| tree.share_prefix(&flattened, merge_by)) @@ -208,10 +220,13 @@ pub(crate) fn merge_use_trees(use_trees: Vec, merge_by: SharedPrefix) - result } -pub(crate) fn flatten_use_trees(use_trees: Vec) -> Vec { +fn flatten_use_trees( + use_trees: Vec, + import_granularity: ImportGranularity, +) -> Vec { use_trees .into_iter() - .flat_map(UseTree::flatten) + .flat_map(|tree| tree.flatten(import_granularity)) .map(UseTree::nest_trailing_self) .collect() } @@ -581,7 +596,7 @@ impl UseTree { } } - fn flatten(self) -> Vec { + fn flatten(self, import_granularity: ImportGranularity) -> Vec { if self.path.is_empty() { return vec![self]; } @@ -595,7 +610,7 @@ impl UseTree { let prefix = &self.path[..self.path.len() - 1]; let mut result = vec![]; for nested_use_tree in list { - for flattend in &mut nested_use_tree.clone().flatten() { + for flattend in &mut nested_use_tree.clone().flatten(import_granularity) { let mut new_path = prefix.to_vec(); new_path.append(&mut flattend.path); result.push(UseTree { @@ -603,7 +618,11 @@ impl UseTree { span: self.span, list_item: None, visibility: self.visibility.clone(), - attrs: None, + // only retain attributes for `ImportGranularity::Item` + attrs: match import_granularity { + ImportGranularity::Item => self.attrs.clone(), + _ => None, + }, }); } } @@ -951,7 +970,7 @@ impl Rewrite for UseTree { } #[derive(Copy, Clone, Debug, PartialEq, Eq)] -pub(crate) enum SharedPrefix { +enum SharedPrefix { Crate, Module, One, @@ -1106,7 +1125,7 @@ mod test { macro_rules! test_merge { ($by:ident, [$($input:expr),* $(,)*], [$($output:expr),* $(,)*]) => { assert_eq!( - merge_use_trees(parse_use_trees!($($input,)*), SharedPrefix::$by), + regroup_use_trees(parse_use_trees!($($input,)*), ImportGranularity::$by), parse_use_trees!($($output,)*), ); } @@ -1215,12 +1234,18 @@ mod test { #[test] fn test_flatten_use_trees() { assert_eq!( - flatten_use_trees(parse_use_trees!["foo::{a::{b, c}, d::e}"]), + flatten_use_trees( + parse_use_trees!["foo::{a::{b, c}, d::e}"], + ImportGranularity::Item + ), parse_use_trees!["foo::a::b", "foo::a::c", "foo::d::e"] ); assert_eq!( - flatten_use_trees(parse_use_trees!["foo::{self, a, b::{c, d}, e::*}"]), + flatten_use_trees( + parse_use_trees!["foo::{self, a, b::{c, d}, e::*}"], + ImportGranularity::Item + ), parse_use_trees![ "foo::{self}", "foo::a", @@ -1234,12 +1259,13 @@ mod test { #[test] fn test_use_tree_flatten() { assert_eq!( - parse_use_tree("a::b::{c, d, e, f}").flatten(), + parse_use_tree("a::b::{c, d, e, f}").flatten(ImportGranularity::Item), parse_use_trees!("a::b::c", "a::b::d", "a::b::e", "a::b::f",) ); assert_eq!( - parse_use_tree("a::b::{c::{d, e, f}, g, h::{i, j, k}}").flatten(), + parse_use_tree("a::b::{c::{d, e, f}, g, h::{i, j, k}}") + .flatten(ImportGranularity::Item), parse_use_trees![ "a::b::c::d", "a::b::c::e", diff --git a/src/reorder.rs b/src/reorder.rs index 13bfc92507d0a..f565612ded184 100644 --- a/src/reorder.rs +++ b/src/reorder.rs @@ -11,8 +11,8 @@ use std::cmp::{Ord, Ordering}; use rustc_ast::ast; use rustc_span::{symbol::sym, Span}; -use crate::config::{Config, GroupImportsTactic, ImportGranularity}; -use crate::imports::{flatten_use_trees, merge_use_trees, SharedPrefix, UseSegment, UseTree}; +use crate::config::{Config, GroupImportsTactic}; +use crate::imports::{regroup_use_trees, UseSegment, UseTree}; use crate::items::{is_mod_decl, rewrite_extern_crate, rewrite_mod}; use crate::lists::{itemize_list, write_list, ListFormatting, ListItem}; use crate::rewrite::RewriteContext; @@ -107,15 +107,8 @@ fn rewrite_reorderable_or_regroupable_items( for (item, list_item) in normalized_items.iter_mut().zip(list_items) { item.list_item = Some(list_item.clone()); } - normalized_items = match context.config.imports_granularity() { - ImportGranularity::Crate => merge_use_trees(normalized_items, SharedPrefix::Crate), - ImportGranularity::Module => { - merge_use_trees(normalized_items, SharedPrefix::Module) - } - ImportGranularity::Item => flatten_use_trees(normalized_items), - ImportGranularity::One => merge_use_trees(normalized_items, SharedPrefix::One), - ImportGranularity::Preserve => normalized_items, - }; + normalized_items = + regroup_use_trees(normalized_items, context.config.imports_granularity()); let mut regrouped_items = match context.config.group_imports() { GroupImportsTactic::Preserve | GroupImportsTactic::One => { diff --git a/tests/source/issue-5030.rs b/tests/source/issue-5030.rs new file mode 100644 index 0000000000000..f367e79f01f64 --- /dev/null +++ b/tests/source/issue-5030.rs @@ -0,0 +1,7 @@ +// rustfmt-imports_granularity: Item + +#[cfg(feature = "foo")] +use std::collections::{ + HashMap, + HashSet, +}; diff --git a/tests/target/issue-5030.rs b/tests/target/issue-5030.rs new file mode 100644 index 0000000000000..b371331ed0096 --- /dev/null +++ b/tests/target/issue-5030.rs @@ -0,0 +1,6 @@ +// rustfmt-imports_granularity: Item + +#[cfg(feature = "foo")] +use std::collections::HashMap; +#[cfg(feature = "foo")] +use std::collections::HashSet; From 9b1b3d69559750cf459638076dc32202110ec40e Mon Sep 17 00:00:00 2001 From: Tom Milligan Date: Sat, 16 Apr 2022 11:50:24 +0100 Subject: [PATCH 15/53] [review] rename internal function --- src/imports.rs | 7 +++++-- src/reorder.rs | 8 +++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/imports.rs b/src/imports.rs index 485a72b85da44..efe4e9498c909 100644 --- a/src/imports.rs +++ b/src/imports.rs @@ -183,7 +183,7 @@ impl UseSegment { } } -pub(crate) fn regroup_use_trees( +pub(crate) fn normalize_use_trees_with_granularity( use_trees: Vec, import_granularity: ImportGranularity, ) -> Vec { @@ -1125,7 +1125,10 @@ mod test { macro_rules! test_merge { ($by:ident, [$($input:expr),* $(,)*], [$($output:expr),* $(,)*]) => { assert_eq!( - regroup_use_trees(parse_use_trees!($($input,)*), ImportGranularity::$by), + normalize_use_trees_with_granularity( + parse_use_trees!($($input,)*), + ImportGranularity::$by, + ), parse_use_trees!($($output,)*), ); } diff --git a/src/reorder.rs b/src/reorder.rs index f565612ded184..8ae297de25bc2 100644 --- a/src/reorder.rs +++ b/src/reorder.rs @@ -12,7 +12,7 @@ use rustc_ast::ast; use rustc_span::{symbol::sym, Span}; use crate::config::{Config, GroupImportsTactic}; -use crate::imports::{regroup_use_trees, UseSegment, UseTree}; +use crate::imports::{normalize_use_trees_with_granularity, UseSegment, UseTree}; use crate::items::{is_mod_decl, rewrite_extern_crate, rewrite_mod}; use crate::lists::{itemize_list, write_list, ListFormatting, ListItem}; use crate::rewrite::RewriteContext; @@ -107,8 +107,10 @@ fn rewrite_reorderable_or_regroupable_items( for (item, list_item) in normalized_items.iter_mut().zip(list_items) { item.list_item = Some(list_item.clone()); } - normalized_items = - regroup_use_trees(normalized_items, context.config.imports_granularity()); + normalized_items = normalize_use_trees_with_granularity( + normalized_items, + context.config.imports_granularity(), + ); let mut regrouped_items = match context.config.group_imports() { GroupImportsTactic::Preserve | GroupImportsTactic::One => { From acdab00ecc4c5064b6a42f87a523961304678c06 Mon Sep 17 00:00:00 2001 From: Tom Milligan Date: Sat, 16 Apr 2022 12:12:27 +0100 Subject: [PATCH 16/53] [review] check interaction with import grouping --- tests/source/issue-5030.rs | 15 +++++++++++++++ tests/target/issue-5030.rs | 15 +++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/tests/source/issue-5030.rs b/tests/source/issue-5030.rs index f367e79f01f64..08ffaac7d1dc2 100644 --- a/tests/source/issue-5030.rs +++ b/tests/source/issue-5030.rs @@ -1,7 +1,22 @@ // rustfmt-imports_granularity: Item +// rustfmt-group_imports: One +// Confirm that attributes are duplicated to all items in the use statement #[cfg(feature = "foo")] use std::collections::{ HashMap, HashSet, }; + +// Separate the imports below from the ones above +const A: usize = 0; + +// Copying attrs works with import grouping as well +#[cfg(feature = "foo")] +use std::collections::{ + HashMap, + HashSet, +}; + +#[cfg(feature = "spam")] +use qux::{bar, baz}; diff --git a/tests/target/issue-5030.rs b/tests/target/issue-5030.rs index b371331ed0096..8ac3888bdbee0 100644 --- a/tests/target/issue-5030.rs +++ b/tests/target/issue-5030.rs @@ -1,5 +1,20 @@ // rustfmt-imports_granularity: Item +// rustfmt-group_imports: One +// Confirm that attributes are duplicated to all items in the use statement +#[cfg(feature = "foo")] +use std::collections::HashMap; +#[cfg(feature = "foo")] +use std::collections::HashSet; + +// Separate the imports below from the ones above +const A: usize = 0; + +// Copying attrs works with import grouping as well +#[cfg(feature = "spam")] +use qux::bar; +#[cfg(feature = "spam")] +use qux::baz; #[cfg(feature = "foo")] use std::collections::HashMap; #[cfg(feature = "foo")] From a37d3ab0e1c7c05f1a6410fb7ddf5539f0d030f8 Mon Sep 17 00:00:00 2001 From: hkalbasi Date: Wed, 15 Dec 2021 19:38:31 +0330 Subject: [PATCH 17/53] Memoize format_expr --- src/expr.rs | 51 +- src/formatting.rs | 2 + src/rewrite.rs | 13 + src/shape.rs | 4 +- src/visitor.rs | 7 +- tests/source/performance/issue-4476.rs | 638 +++ tests/source/performance/issue-5128.rs | 5127 ++++++++++++++++++++++++ tests/target/performance/issue-4476.rs | 705 ++++ tests/target/performance/issue-4867.rs | 13 + tests/target/performance/issue-5128.rs | 4898 ++++++++++++++++++++++ 10 files changed, 11454 insertions(+), 4 deletions(-) create mode 100644 tests/source/performance/issue-4476.rs create mode 100644 tests/source/performance/issue-5128.rs create mode 100644 tests/target/performance/issue-4476.rs create mode 100644 tests/target/performance/issue-4867.rs create mode 100644 tests/target/performance/issue-5128.rs diff --git a/src/expr.rs b/src/expr.rs index 4f333cd27cefe..cfecc9b9d89ae 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -1,5 +1,6 @@ use std::borrow::Cow; use std::cmp::min; +use std::collections::HashMap; use itertools::Itertools; use rustc_ast::token::{DelimToken, LitKind}; @@ -22,7 +23,7 @@ use crate::macros::{rewrite_macro, MacroPosition}; use crate::matches::rewrite_match; use crate::overflow::{self, IntoOverflowableItem, OverflowableItem}; use crate::pairs::{rewrite_all_pairs, rewrite_pair, PairParts}; -use crate::rewrite::{Rewrite, RewriteContext}; +use crate::rewrite::{QueryId, Rewrite, RewriteContext}; use crate::shape::{Indent, Shape}; use crate::source_map::{LineRangeUtils, SpanUtils}; use crate::spanned::Spanned; @@ -53,6 +54,54 @@ pub(crate) fn format_expr( expr_type: ExprType, context: &RewriteContext<'_>, shape: Shape, +) -> Option { + // when max_width is tight, we should check all possible formattings, in order to find + // if we can fit expression in the limit. Doing it recursively takes exponential time + // relative to input size, and people hit it with rustfmt takes minutes in #4476 #4867 #5128 + // By memoization of format_expr function, we format each pair of expression and shape + // only once, so worst case execution time becomes O(n*max_width^3). + if context.inside_macro() || context.is_macro_def { + // span ids are not unique in macros, so we don't memoize result of them. + return format_expr_inner(expr, expr_type, context, shape); + } + let clean; + let query_id = QueryId { + shape, + span: expr.span, + }; + if let Some(map) = context.memoize.take() { + if let Some(r) = map.get(&query_id) { + let r = r.clone(); + context.memoize.set(Some(map)); // restore map in the memoize cell for other users + return r; + } + context.memoize.set(Some(map)); + clean = false; + } else { + context.memoize.set(Some(HashMap::default())); + clean = true; // We got None, so we are the top level called function. When + // this function finishes, no one is interested in what is in the map, because + // all of them are sub expressions of this top level expression, and this is + // done. So we should clean up memoize map to save some memory. + } + + let r = format_expr_inner(expr, expr_type, context, shape); + if clean { + context.memoize.set(None); + } else { + if let Some(mut map) = context.memoize.take() { + map.insert(query_id, r.clone()); // insert the result in the memoize map + context.memoize.set(Some(map)); // so it won't be computed again + } + } + r +} + +fn format_expr_inner( + expr: &ast::Expr, + expr_type: ExprType, + context: &RewriteContext<'_>, + shape: Shape, ) -> Option { skip_out_of_file_lines_range!(context, expr.span); diff --git a/src/formatting.rs b/src/formatting.rs index ca93955a549dd..281d3e4e808a5 100644 --- a/src/formatting.rs +++ b/src/formatting.rs @@ -2,6 +2,7 @@ use std::collections::HashMap; use std::io::{self, Write}; +use std::rc::Rc; use std::time::{Duration, Instant}; use rustc_ast::ast; @@ -190,6 +191,7 @@ impl<'a, T: FormatHandler + 'a> FormatContext<'a, T> { self.config, &snippet_provider, self.report.clone(), + Rc::default(), ); visitor.skip_context.update_with_attrs(&self.krate.attrs); visitor.is_macro_def = is_macro_def; diff --git a/src/rewrite.rs b/src/rewrite.rs index 4a3bd129d16f5..f97df70cc6a7b 100644 --- a/src/rewrite.rs +++ b/src/rewrite.rs @@ -12,6 +12,7 @@ use crate::shape::Shape; use crate::skip::SkipContext; use crate::visitor::SnippetProvider; use crate::FormatReport; +use rustc_data_structures::stable_map::FxHashMap; pub(crate) trait Rewrite { /// Rewrite self into shape. @@ -24,10 +25,22 @@ impl Rewrite for ptr::P { } } +#[derive(Clone, PartialEq, Eq, Hash)] +pub(crate) struct QueryId { + pub(crate) shape: Shape, + pub(crate) span: Span, +} + +// We use Option instead of HashMap, because in case of `None` +// the function clean the memoize map, but it doesn't clean when +// there is `Some(empty)`, so they are different. +pub(crate) type Memoize = Rc>>>>; + #[derive(Clone)] pub(crate) struct RewriteContext<'a> { pub(crate) parse_sess: &'a ParseSess, pub(crate) config: &'a Config, + pub(crate) memoize: Memoize, pub(crate) inside_macro: Rc>, // Force block indent style even if we are using visual indent style. pub(crate) use_block: Cell, diff --git a/src/shape.rs b/src/shape.rs index 4376fd12b5260..b3f785a9470ee 100644 --- a/src/shape.rs +++ b/src/shape.rs @@ -4,7 +4,7 @@ use std::ops::{Add, Sub}; use crate::Config; -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] pub(crate) struct Indent { // Width of the block indent, in characters. Must be a multiple of // Config::tab_spaces. @@ -139,7 +139,7 @@ impl Sub for Indent { // 8096 is close enough to infinite for rustfmt. const INFINITE_SHAPE_WIDTH: usize = 8096; -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] pub(crate) struct Shape { pub(crate) width: usize, // The current indentation of code. diff --git a/src/visitor.rs b/src/visitor.rs index 3ebfa551d1cbc..06736e3079a5c 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -17,7 +17,7 @@ use crate::items::{ use crate::macros::{macro_style, rewrite_macro, rewrite_macro_def, MacroPosition}; use crate::modules::Module; use crate::parse::session::ParseSess; -use crate::rewrite::{Rewrite, RewriteContext}; +use crate::rewrite::{Memoize, Rewrite, RewriteContext}; use crate::shape::{Indent, Shape}; use crate::skip::{is_skip_attr, SkipContext}; use crate::source_map::{LineRangeUtils, SpanUtils}; @@ -71,6 +71,7 @@ impl SnippetProvider { pub(crate) struct FmtVisitor<'a> { parent_context: Option<&'a RewriteContext<'a>>, + pub(crate) memoize: Memoize, pub(crate) parse_sess: &'a ParseSess, pub(crate) buffer: String, pub(crate) last_pos: BytePos, @@ -754,6 +755,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { ctx.config, ctx.snippet_provider, ctx.report.clone(), + ctx.memoize.clone(), ); visitor.skip_context.update(ctx.skip_context.clone()); visitor.set_parent_context(ctx); @@ -765,10 +767,12 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { config: &'a Config, snippet_provider: &'a SnippetProvider, report: FormatReport, + memoize: Memoize, ) -> FmtVisitor<'a> { FmtVisitor { parent_context: None, parse_sess: parse_session, + memoize, buffer: String::with_capacity(snippet_provider.big_snippet.len() * 2), last_pos: BytePos(0), block_indent: Indent::empty(), @@ -991,6 +995,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { RewriteContext { parse_sess: self.parse_sess, config: self.config, + memoize: self.memoize.clone(), inside_macro: Rc::new(Cell::new(false)), use_block: Cell::new(false), is_if_else_block: Cell::new(false), diff --git a/tests/source/performance/issue-4476.rs b/tests/source/performance/issue-4476.rs new file mode 100644 index 0000000000000..8da3f19b62d60 --- /dev/null +++ b/tests/source/performance/issue-4476.rs @@ -0,0 +1,638 @@ +use super::SemverParser; + +#[allow(dead_code, non_camel_case_types)] +#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub enum Rule { + EOI, + range_set, + logical_or, + range, + empty, + hyphen, + simple, + primitive, + primitive_op, + partial, + xr, + xr_op, + nr, + tilde, + caret, + qualifier, + parts, + part, + space, +} +#[allow(clippy::all)] +impl ::pest::Parser for SemverParser { + fn parse<'i>( + rule: Rule, + input: &'i str, + ) -> ::std::result::Result<::pest::iterators::Pairs<'i, Rule>, ::pest::error::Error> { + mod rules { + pub mod hidden { + use super::super::Rule; + #[inline] + #[allow(dead_code, non_snake_case, unused_variables)] + pub fn skip( + state: Box<::pest::ParserState>, + ) -> ::pest::ParseResult>> { + Ok(state) + } + } + pub mod visible { + use super::super::Rule; + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn range_set( + state: Box<::pest::ParserState>, + ) -> ::pest::ParseResult>> { + state.rule(Rule::range_set, |state| { + state.sequence(|state| { + self::SOI(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + self::space(state).and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state).and_then(|state| self::space(state)) + }) + }) + }) + }) + }) + }) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::range(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + state + .sequence(|state| { + self::logical_or(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::range(state)) + }) + .and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state).and_then(|state| { + state.sequence(|state| { + self::logical_or(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::range(state)) + }) + }) + }) + }) + }) + }) + }) + }) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + self::space(state).and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state).and_then(|state| self::space(state)) + }) + }) + }) + }) + }) + }) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::EOI(state)) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn logical_or( + state: Box<::pest::ParserState>, + ) -> ::pest::ParseResult>> { + state.rule(Rule::logical_or, |state| { + state.sequence(|state| { + state + .sequence(|state| { + state.optional(|state| { + self::space(state).and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state).and_then(|state| self::space(state)) + }) + }) + }) + }) + }) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.match_string("||")) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + self::space(state).and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state).and_then(|state| self::space(state)) + }) + }) + }) + }) + }) + }) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn range( + state: Box<::pest::ParserState>, + ) -> ::pest::ParseResult>> { + state.rule(Rule::range, |state| { + self::hyphen(state) + .or_else(|state| { + state.sequence(|state| { + self::simple(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + state + .sequence(|state| { + state + .optional(|state| state.match_string(",")) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + self::space(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + self::space(state).and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state) + .and_then(|state| self::space(state)) + }) + }) + }) + }) + }) + }) + }) + }) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::simple(state)) + }) + .and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state).and_then(|state| { + state.sequence(|state| { + state + .optional(|state| state.match_string(",")) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + self::space(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + self::space(state).and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state) + .and_then(|state| self::space(state)) + }) + }) + }) + }) + }) + }) + }) + }) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::simple(state)) + }) + }) + }) + }) + }) + }) + }) + }) + }) + }) + .or_else(|state| self::empty(state)) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn empty( + state: Box<::pest::ParserState>, + ) -> ::pest::ParseResult>> { + state.rule(Rule::empty, |state| state.match_string("")) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn hyphen( + state: Box<::pest::ParserState>, + ) -> ::pest::ParseResult>> { + state.rule(Rule::hyphen, |state| { + state.sequence(|state| { + self::partial(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + self::space(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + self::space(state).and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state).and_then(|state| self::space(state)) + }) + }) + }) + }) + }) + }) + }) + }) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.match_string("-")) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + self::space(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + self::space(state).and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state).and_then(|state| self::space(state)) + }) + }) + }) + }) + }) + }) + }) + }) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::partial(state)) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn simple( + state: Box<::pest::ParserState>, + ) -> ::pest::ParseResult>> { + state.rule(Rule::simple, |state| { + self::primitive(state) + .or_else(|state| self::partial(state)) + .or_else(|state| self::tilde(state)) + .or_else(|state| self::caret(state)) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn primitive( + state: Box<::pest::ParserState>, + ) -> ::pest::ParseResult>> { + state.rule(Rule::primitive, |state| { + state.sequence(|state| { + self::primitive_op(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + self::space(state).and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state).and_then(|state| self::space(state)) + }) + }) + }) + }) + }) + }) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::partial(state)) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn primitive_op( + state: Box<::pest::ParserState>, + ) -> ::pest::ParseResult>> { + state.rule(Rule::primitive_op, |state| { + state + .match_string("<=") + .or_else(|state| state.match_string(">=")) + .or_else(|state| state.match_string(">")) + .or_else(|state| state.match_string("<")) + .or_else(|state| state.match_string("=")) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn partial( + state: Box<::pest::ParserState>, + ) -> ::pest::ParseResult>> { + state.rule(Rule::partial, |state| { + state.sequence(|state| { + self::xr(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.optional(|state| { + state.sequence(|state| { + state + .match_string(".") + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::xr(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.optional(|state| { + state.sequence(|state| { + state + .match_string(".") + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::xr(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.optional(|state| self::qualifier(state))) + }) + }) + }) + }) + }) + }) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn xr( + state: Box<::pest::ParserState>, + ) -> ::pest::ParseResult>> { + state.rule(Rule::xr, |state| { + self::xr_op(state).or_else(|state| self::nr(state)) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn xr_op( + state: Box<::pest::ParserState>, + ) -> ::pest::ParseResult>> { + state.rule(Rule::xr_op, |state| { + state + .match_string("x") + .or_else(|state| state.match_string("X")) + .or_else(|state| state.match_string("*")) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn nr( + state: Box<::pest::ParserState>, + ) -> ::pest::ParseResult>> { + state.rule(Rule::nr, |state| { + state.match_string("0").or_else(|state| { + state.sequence(|state| { + state + .match_range('1'..'9') + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + state.match_range('0'..'9').and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state) + .and_then(|state| state.match_range('0'..'9')) + }) + }) + }) + }) + }) + }) + }) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn tilde( + state: Box<::pest::ParserState>, + ) -> ::pest::ParseResult>> { + state.rule(Rule::tilde, |state| { + state.sequence(|state| { + state + .match_string("~>") + .or_else(|state| state.match_string("~")) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + self::space(state).and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state).and_then(|state| self::space(state)) + }) + }) + }) + }) + }) + }) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::partial(state)) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn caret( + state: Box<::pest::ParserState>, + ) -> ::pest::ParseResult>> { + state.rule(Rule::caret, |state| { + state.sequence(|state| { + state + .match_string("^") + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + self::space(state).and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state).and_then(|state| self::space(state)) + }) + }) + }) + }) + }) + }) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::partial(state)) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn qualifier( + state: Box<::pest::ParserState>, + ) -> ::pest::ParseResult>> { + state.rule(Rule::qualifier, |state| { + state.sequence(|state| { + state + .match_string("-") + .or_else(|state| state.match_string("+")) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::parts(state)) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn parts( + state: Box<::pest::ParserState>, + ) -> ::pest::ParseResult>> { + state.rule(Rule::parts, |state| { + state.sequence(|state| { + self::part(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + state + .sequence(|state| { + state + .match_string(".") + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::part(state)) + }) + .and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state).and_then(|state| { + state.sequence(|state| { + state + .match_string(".") + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::part(state)) + }) + }) + }) + }) + }) + }) + }) + }) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn part( + state: Box<::pest::ParserState>, + ) -> ::pest::ParseResult>> { + state.rule(Rule::part, |state| { + self::nr(state).or_else(|state| { + state.sequence(|state| { + state + .match_string("-") + .or_else(|state| state.match_range('0'..'9')) + .or_else(|state| state.match_range('A'..'Z')) + .or_else(|state| state.match_range('a'..'z')) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + state + .match_string("-") + .or_else(|state| state.match_range('0'..'9')) + .or_else(|state| state.match_range('A'..'Z')) + .or_else(|state| state.match_range('a'..'z')) + .and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state).and_then(|state| { + state + .match_string("-") + .or_else(|state| state.match_range('0'..'9')) + .or_else(|state| state.match_range('A'..'Z')) + .or_else(|state| state.match_range('a'..'z')) + }) + }) + }) + }) + }) + }) + }) + }) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn space( + state: Box<::pest::ParserState>, + ) -> ::pest::ParseResult>> { + state + .match_string(" ") + .or_else(|state| state.match_string("\t")) + } + #[inline] + #[allow(dead_code, non_snake_case, unused_variables)] + pub fn EOI( + state: Box<::pest::ParserState>, + ) -> ::pest::ParseResult>> { + state.rule(Rule::EOI, |state| state.end_of_input()) + } + #[inline] + #[allow(dead_code, non_snake_case, unused_variables)] + pub fn SOI( + state: Box<::pest::ParserState>, + ) -> ::pest::ParseResult>> { + state.start_of_input() + } + } + pub use self::visible::*; + } + ::pest::state(input, |state| match rule { + Rule::range_set => rules::range_set(state), + Rule::logical_or => rules::logical_or(state), + Rule::range => rules::range(state), + Rule::empty => rules::empty(state), + Rule::hyphen => rules::hyphen(state), + Rule::simple => rules::simple(state), + Rule::primitive => rules::primitive(state), + Rule::primitive_op => rules::primitive_op(state), + Rule::partial => rules::partial(state), + Rule::xr => rules::xr(state), + Rule::xr_op => rules::xr_op(state), + Rule::nr => rules::nr(state), + Rule::tilde => rules::tilde(state), + Rule::caret => rules::caret(state), + Rule::qualifier => rules::qualifier(state), + Rule::parts => rules::parts(state), + Rule::part => rules::part(state), + Rule::space => rules::space(state), + Rule::EOI => rules::EOI(state), + }) + } +} \ No newline at end of file diff --git a/tests/source/performance/issue-5128.rs b/tests/source/performance/issue-5128.rs new file mode 100644 index 0000000000000..3adce49601c0c --- /dev/null +++ b/tests/source/performance/issue-5128.rs @@ -0,0 +1,5127 @@ + +fn takes_a_long_time_to_rustfmt() { + let inner_cte = vec![Node { + node: Some(node::Node::CommonTableExpr(Box::new(CommonTableExpr { + ctename: String::from("ranked_by_age_within_key"), + aliascolnames: vec![], + ctematerialized: CteMaterialize::Default as i32, + ctequery: Some(Box::new(Node { + node: Some(node::Node::SelectStmt(Box::new(SelectStmt { + distinct_clause: vec![], + into_clause: None, + target_list: vec![ + Node { + node: Some(node::Node::ResTarget(Box::new(ResTarget { + name: String::from(""), + indirection: vec![], + val: Some(Box::new(Node { + node: Some(node::Node::ColumnRef(ColumnRef { + fields: vec![Node { + node: Some(node::Node::AStar(AStar{})) + }], + location: 80 + })) + })), + location: 80 + }))) + }, + Node { + node: Some(node::Node::ResTarget(Box::new(ResTarget { + name: String::from("rank_in_key"), + indirection: vec![], + val: Some(Box::new(Node { + node: Some(node::Node::FuncCall(Box::new(FuncCall { + funcname: vec![Node { + node: Some(node::Node::String(String2 { + str: String::from("row_number") + })) + }], + args: vec![], + agg_order: vec![], + agg_filter: None, + agg_within_group: false, + agg_star: false, + agg_distinct: false, + func_variadic: false, + over: Some(Box::new(WindowDef { + name: String::from(""), + refname: String::from(""), + partition_clause: vec![ + Node { + node: Some(node::Node::ColumnRef(ColumnRef { + fields: vec![Node { + node: Some(node::Node::String(String2 { + str: String::from("synthetic_key") + })) + }], location: 123 + })) + }], order_clause: vec![Node { + node: Some(node::Node::SortBy(Box::new(SortBy { + node: Some(Box::new(Node { + node: Some(node::Node::ColumnRef(ColumnRef { + fields: vec![Node { + node: Some(node::Node::String(String2 { + str: String::from("logical_timestamp") + })) + }], location: 156 + })) + })), + sortby_dir: SortByDir::SortbyDesc as i32, + sortby_nulls: SortByNulls::SortbyNullsDefault as i32, + use_op: vec![], + location: -1 + }))) + }], frame_options: 1058, start_offset: None, end_offset: None, location: 109 + })), + location: 91 + }))) + })), + location: 91 + }))) + }], + from_clause: vec![Node { + node: Some(node::Node::RangeVar(RangeVar { + catalogname: String::from(""), schemaname: String::from("_supertables"), relname: String::from("9999-9999-9999"), inh: true, relpersistence: String::from("p"), alias: None, location: 206 + })) + }], + where_clause: Some(Box::new(Node { + node: Some(node::Node::AExpr(Box::new(AExpr { + kind: AExprKind::AexprOp as i32, + name: vec![Node { + node: Some(node::Node::String(String2 { + str: String::from("<=") + })) + }], + lexpr: Some(Box::new(Node { + node: Some(node::Node::ColumnRef(ColumnRef { + fields: vec![Node { + node: Some(node::Node::String(String2 { + str: String::from("logical_timestamp") + })) + }], + location: 250 + })) + })), + rexpr: Some(Box::new(Node { + node: Some(node::Node::AConst(Box::new(AConst { + val: Some(Box::new(Node { + node: Some(node::Node::Integer(Integer { + ival: 9000 + })) + })), + location: 271 + }))) + })), + location: 268 + }))) + })), + group_clause: vec![], + having_clause: None, + window_clause: vec![], + values_lists: vec![], + sort_clause: vec![], + limit_offset: None, + limit_count: None, + limit_option: LimitOption::Default as i32, + locking_clause: vec![], + with_clause: None, + op: SetOperation::SetopNone as i32, + all: false, + larg: None, + rarg: None + }))), + })), + location: 29, + cterecursive: false, + cterefcount: 0, + ctecolnames: vec![], + ctecoltypes: vec![], + ctecoltypmods: vec![], + ctecolcollations: vec![], + }))), + }]; + let outer_cte = vec![Node { + node: Some(node::Node::CommonTableExpr(Box::new(CommonTableExpr { + ctename: String::from("table_name"), + aliascolnames: vec![], + ctematerialized: CteMaterialize::Default as i32, + ctequery: Some(Box::new(Node { + node: Some(node::Node::SelectStmt(Box::new(SelectStmt { + distinct_clause: vec![], + into_clause: None, + target_list: vec![ + Node { + node: Some(node::Node::ResTarget(Box::new(ResTarget { + name: String::from("column1"), + indirection: vec![], + val: Some(Box::new(Node { + node: Some(node::Node::ColumnRef(ColumnRef { + fields: vec![Node { + node: Some(node::Node::String(String2 { + str: String::from("c1"), + })), + }], + location: 301, + })), + })), + location: 301, + }))), + }, + Node { + node: Some(node::Node::ResTarget(Box::new(ResTarget { + name: String::from("column2"), + indirection: vec![], + val: Some(Box::new(Node { + node: Some(node::Node::ColumnRef(ColumnRef { + fields: vec![Node { + node: Some(node::Node::String(String2 { + str: String::from("c2"), + })), + }], + location: 324, + })), + })), + location: 324, + }))), + }, + ], + from_clause: vec![Node { + node: Some(node::Node::RangeVar(RangeVar { + catalogname: String::from(""), + schemaname: String::from(""), + relname: String::from("ranked_by_age_within_key"), + inh: true, + relpersistence: String::from("p"), + alias: None, + location: 347, + })), + }], + where_clause: Some(Box::new(Node { + node: Some(node::Node::BoolExpr(Box::new(BoolExpr { + xpr: None, + boolop: BoolExprType::AndExpr as i32, + args: vec![ + Node { + node: Some(node::Node::AExpr(Box::new(AExpr { + kind: AExprKind::AexprOp as i32, + name: vec![Node { + node: Some(node::Node::String(String2 { + str: String::from("="), + })), + }], + lexpr: Some(Box::new(Node { + node: Some(node::Node::ColumnRef(ColumnRef { + fields: vec![Node { + node: Some(node::Node::String( + String2 { + str: String::from("rank_in_key"), + }, + )), + }], + location: 382, + })), + })), + rexpr: Some(Box::new(Node { + node: Some(node::Node::AConst(Box::new(AConst { + val: Some(Box::new(Node { + node: Some(node::Node::Integer( + Integer { ival: 1 }, + )), + })), + location: 396, + }))), + })), + location: 394, + }))), + }, + Node { + node: Some(node::Node::AExpr(Box::new(AExpr { + kind: AExprKind::AexprOp as i32, + name: vec![Node { + node: Some(node::Node::String(String2 { + str: String::from("="), + })), + }], + lexpr: Some(Box::new(Node { + node: Some(node::Node::ColumnRef(ColumnRef { + fields: vec![Node { + node: Some(node::Node::String( + String2 { + str: String::from("is_deleted"), + }, + )), + }], + location: 402, + })), + })), + rexpr: Some(Box::new(Node { + node: Some(node::Node::TypeCast(Box::new( + TypeCast { + arg: Some(Box::new(Node { + node: Some(node::Node::AConst( + Box::new(AConst { + val: Some(Box::new(Node { + node: Some( + node::Node::String( + String2 { + str: + String::from( + "f", + ), + }, + ), + ), + })), + location: 415, + }), + )), + })), + type_name: Some(TypeName { + names: vec![ + Node { + node: Some(node::Node::String( + String2 { + str: String::from( + "pg_catalog", + ), + }, + )), + }, + Node { + node: Some(node::Node::String( + String2 { + str: String::from( + "bool", + ), + }, + )), + }, + ], + type_oid: 0, + setof: false, + pct_type: false, + typmods: vec![], + typemod: -1, + array_bounds: vec![], + location: -1, + }), + location: -1, + }, + ))), + })), + location: 413, + }))), + }, + ], + location: 398, + }))), + })), + group_clause: vec![], + having_clause: None, + window_clause: vec![], + values_lists: vec![], + sort_clause: vec![], + limit_offset: None, + limit_count: None, + limit_option: LimitOption::Default as i32, + locking_clause: vec![], + with_clause: Some(WithClause { + ctes: inner_cte, + recursive: false, + location: 24, + }), + op: SetOperation::SetopNone as i32, + all: false, + larg: None, + rarg: None, + }))), + })), + location: 5, + cterecursive: false, + cterefcount: 0, + ctecolnames: vec![], + ctecoltypes: vec![], + ctecoltypmods: vec![], + ctecolcollations: vec![], + }))), + }]; + let expected_result = ParseResult { + version: 130003, + stmts: vec![RawStmt { + stmt: Some(Box::new(Node { + node: Some(node::Node::SelectStmt(Box::new(SelectStmt { + distinct_clause: vec![], + into_clause: None, + + target_list: vec![Node { + node: Some(node::Node::ResTarget(Box::new(ResTarget { + name: String::from(""), + indirection: vec![], + val: Some(Box::new(Node { + node: Some(node::Node::ColumnRef(ColumnRef { + fields: vec![Node { + node: Some(node::Node::String(String2 { + str: String::from("column1"), + })), + }], + location: 430, + })), + })), + location: 430, + }))), + }], + from_clause: vec![Node { + node: Some(node::Node::RangeVar(RangeVar { + catalogname: String::from(""), + schemaname: String::from(""), + relname: String::from("table_name"), + inh: true, + relpersistence: String::from("p"), + alias: None, + location: 443, + })), + }], + where_clause: Some(Box::new(Node { + node: Some(node::Node::AExpr(Box::new(AExpr { + kind: AExprKind::AexprOp as i32, + name: vec![Node { + node: Some(node::Node::String(String2 { + str: String::from(">"), + })), + }], + lexpr: Some(Box::new(Node { + node: Some(node::Node::ColumnRef(ColumnRef { + fields: vec![Node { + node: Some(node::Node::String(String2 { + str: String::from("column2"), + })), + }], + location: 460, + })), + })), + rexpr: Some(Box::new(Node { + node: Some(node::Node::AConst(Box::new(AConst { + val: Some(Box::new(Node { + node: Some(node::Node::Integer(Integer { + ival: 9000, + })), + })), + location: 470, + }))), + })), + location: 468, + }))), + })), + group_clause: vec![], + having_clause: None, + window_clause: vec![], + values_lists: vec![], + sort_clause: vec![], + limit_offset: None, + limit_count: None, + limit_option: LimitOption::Default as i32, + locking_clause: vec![], + with_clause: Some(WithClause { + ctes: outer_cte, + recursive: false, + location: 0, + }), + op: SetOperation::SetopNone as i32, + all: false, + larg: None, + rarg: None, + }))), + })), + stmt_location: 0, + stmt_len: 0, + }], + }; + +} +#[derive(Clone, PartialEq)] +pub struct ParseResult { + + pub version: i32, + + pub stmts: Vec, +} +#[derive(Clone, PartialEq)] +pub struct ScanResult { + + pub version: i32, + + pub tokens: Vec, +} +#[derive(Clone, PartialEq)] +pub struct Node { + pub node: ::core::option::Option, +} +/// Nested message and enum types in `Node`. +pub mod node { + #[derive(Clone, PartialEq)] + pub enum Node { + + Alias(super::Alias), + + RangeVar(super::RangeVar), + + TableFunc(Box), + + Expr(super::Expr), + + Var(Box), + + Param(Box), + + Aggref(Box), + + GroupingFunc(Box), + + WindowFunc(Box), + + SubscriptingRef(Box), + + FuncExpr(Box), + + NamedArgExpr(Box), + + OpExpr(Box), + + DistinctExpr(Box), + + NullIfExpr(Box), + + ScalarArrayOpExpr(Box), + + BoolExpr(Box), + + SubLink(Box), + + SubPlan(Box), + + AlternativeSubPlan(Box), + + FieldSelect(Box), + + FieldStore(Box), + + RelabelType(Box), + + CoerceViaIo(Box), + + ArrayCoerceExpr(Box), + + ConvertRowtypeExpr(Box), + + CollateExpr(Box), + + CaseExpr(Box), + + CaseWhen(Box), + + CaseTestExpr(Box), + + ArrayExpr(Box), + + RowExpr(Box), + + RowCompareExpr(Box), + + CoalesceExpr(Box), + + MinMaxExpr(Box), + + SqlvalueFunction(Box), + + XmlExpr(Box), + + NullTest(Box), + + BooleanTest(Box), + + CoerceToDomain(Box), + + CoerceToDomainValue(Box), + + SetToDefault(Box), + + CurrentOfExpr(Box), + + NextValueExpr(Box), + + InferenceElem(Box), + + TargetEntry(Box), + + RangeTblRef(super::RangeTblRef), + + JoinExpr(Box), + + FromExpr(Box), + + OnConflictExpr(Box), + + IntoClause(Box), + + RawStmt(Box), + + Query(Box), + + InsertStmt(Box), + + DeleteStmt(Box), + + UpdateStmt(Box), + + SelectStmt(Box), + + AlterTableStmt(super::AlterTableStmt), + + AlterTableCmd(Box), + + AlterDomainStmt(Box), + + SetOperationStmt(Box), + + GrantStmt(super::GrantStmt), + + GrantRoleStmt(super::GrantRoleStmt), + + AlterDefaultPrivilegesStmt(super::AlterDefaultPrivilegesStmt), + + ClosePortalStmt(super::ClosePortalStmt), + + ClusterStmt(super::ClusterStmt), + + CopyStmt(Box), + + CreateStmt(super::CreateStmt), + + DefineStmt(super::DefineStmt), + + DropStmt(super::DropStmt), + + TruncateStmt(super::TruncateStmt), + + CommentStmt(Box), + + FetchStmt(super::FetchStmt), + + IndexStmt(Box), + + CreateFunctionStmt(super::CreateFunctionStmt), + + AlterFunctionStmt(super::AlterFunctionStmt), + + DoStmt(super::DoStmt), + + RenameStmt(Box), + + RuleStmt(Box), + + NotifyStmt(super::NotifyStmt), + + ListenStmt(super::ListenStmt), + + UnlistenStmt(super::UnlistenStmt), + + TransactionStmt(super::TransactionStmt), + + ViewStmt(Box), + + LoadStmt(super::LoadStmt), + + CreateDomainStmt(Box), + + CreatedbStmt(super::CreatedbStmt), + + DropdbStmt(super::DropdbStmt), + + VacuumStmt(super::VacuumStmt), + + ExplainStmt(Box), + + CreateTableAsStmt(Box), + + CreateSeqStmt(super::CreateSeqStmt), + + AlterSeqStmt(super::AlterSeqStmt), + + VariableSetStmt(super::VariableSetStmt), + + VariableShowStmt(super::VariableShowStmt), + + DiscardStmt(super::DiscardStmt), + + CreateTrigStmt(Box), + + CreatePlangStmt(super::CreatePLangStmt), + + CreateRoleStmt(super::CreateRoleStmt), + + AlterRoleStmt(super::AlterRoleStmt), + + DropRoleStmt(super::DropRoleStmt), + + LockStmt(super::LockStmt), + + ConstraintsSetStmt(super::ConstraintsSetStmt), + + ReindexStmt(super::ReindexStmt), + + CheckPointStmt(super::CheckPointStmt), + + CreateSchemaStmt(super::CreateSchemaStmt), + + AlterDatabaseStmt(super::AlterDatabaseStmt), + + AlterDatabaseSetStmt(super::AlterDatabaseSetStmt), + + AlterRoleSetStmt(super::AlterRoleSetStmt), + + CreateConversionStmt(super::CreateConversionStmt), + + CreateCastStmt(super::CreateCastStmt), + + CreateOpClassStmt(super::CreateOpClassStmt), + + CreateOpFamilyStmt(super::CreateOpFamilyStmt), + + AlterOpFamilyStmt(super::AlterOpFamilyStmt), + + PrepareStmt(Box), + + ExecuteStmt(super::ExecuteStmt), + + DeallocateStmt(super::DeallocateStmt), + + DeclareCursorStmt(Box), + + CreateTableSpaceStmt(super::CreateTableSpaceStmt), + + DropTableSpaceStmt(super::DropTableSpaceStmt), + + AlterObjectDependsStmt(Box), + + AlterObjectSchemaStmt(Box), + + AlterOwnerStmt(Box), + + AlterOperatorStmt(super::AlterOperatorStmt), + + AlterTypeStmt(super::AlterTypeStmt), + + DropOwnedStmt(super::DropOwnedStmt), + + ReassignOwnedStmt(super::ReassignOwnedStmt), + + CompositeTypeStmt(super::CompositeTypeStmt), + + CreateEnumStmt(super::CreateEnumStmt), + + CreateRangeStmt(super::CreateRangeStmt), + + AlterEnumStmt(super::AlterEnumStmt), + + AlterTsdictionaryStmt(super::AlterTsDictionaryStmt), + + AlterTsconfigurationStmt(super::AlterTsConfigurationStmt), + + CreateFdwStmt(super::CreateFdwStmt), + + AlterFdwStmt(super::AlterFdwStmt), + + CreateForeignServerStmt(super::CreateForeignServerStmt), + + AlterForeignServerStmt(super::AlterForeignServerStmt), + + CreateUserMappingStmt(super::CreateUserMappingStmt), + + AlterUserMappingStmt(super::AlterUserMappingStmt), + + DropUserMappingStmt(super::DropUserMappingStmt), + + AlterTableSpaceOptionsStmt(super::AlterTableSpaceOptionsStmt), + + AlterTableMoveAllStmt(super::AlterTableMoveAllStmt), + + SecLabelStmt(Box), + + CreateForeignTableStmt(super::CreateForeignTableStmt), + + ImportForeignSchemaStmt(super::ImportForeignSchemaStmt), + + CreateExtensionStmt(super::CreateExtensionStmt), + + AlterExtensionStmt(super::AlterExtensionStmt), + + AlterExtensionContentsStmt(Box), + + CreateEventTrigStmt(super::CreateEventTrigStmt), + + AlterEventTrigStmt(super::AlterEventTrigStmt), + + RefreshMatViewStmt(super::RefreshMatViewStmt), + + ReplicaIdentityStmt(super::ReplicaIdentityStmt), + + AlterSystemStmt(super::AlterSystemStmt), + + CreatePolicyStmt(Box), + + AlterPolicyStmt(Box), + + CreateTransformStmt(super::CreateTransformStmt), + + CreateAmStmt(super::CreateAmStmt), + + CreatePublicationStmt(super::CreatePublicationStmt), + + AlterPublicationStmt(super::AlterPublicationStmt), + + CreateSubscriptionStmt(super::CreateSubscriptionStmt), + + AlterSubscriptionStmt(super::AlterSubscriptionStmt), + + DropSubscriptionStmt(super::DropSubscriptionStmt), + + CreateStatsStmt(super::CreateStatsStmt), + + AlterCollationStmt(super::AlterCollationStmt), + + CallStmt(Box), + + AlterStatsStmt(super::AlterStatsStmt), + + AExpr(Box), + + ColumnRef(super::ColumnRef), + + ParamRef(super::ParamRef), + + AConst(Box), + + FuncCall(Box), + + AStar(super::AStar), + + AIndices(Box), + + AIndirection(Box), + + AArrayExpr(super::AArrayExpr), + + ResTarget(Box), + + MultiAssignRef(Box), + + TypeCast(Box), + + CollateClause(Box), + + SortBy(Box), + + WindowDef(Box), + + RangeSubselect(Box), + + RangeFunction(super::RangeFunction), + + RangeTableSample(Box), + + RangeTableFunc(Box), + + RangeTableFuncCol(Box), + + TypeName(super::TypeName), + + ColumnDef(Box), + + IndexElem(Box), + + Constraint(Box), + + DefElem(Box), + + RangeTblEntry(Box), + + RangeTblFunction(Box), + + TableSampleClause(Box), + + WithCheckOption(Box), + + SortGroupClause(super::SortGroupClause), + + GroupingSet(super::GroupingSet), + + WindowClause(Box), + + ObjectWithArgs(super::ObjectWithArgs), + + AccessPriv(super::AccessPriv), + + CreateOpClassItem(super::CreateOpClassItem), + + TableLikeClause(super::TableLikeClause), + + FunctionParameter(Box), + + LockingClause(super::LockingClause), + + RowMarkClause(super::RowMarkClause), + + XmlSerialize(Box), + + WithClause(super::WithClause), + + InferClause(Box), + + OnConflictClause(Box), + + CommonTableExpr(Box), + + RoleSpec(super::RoleSpec), + + TriggerTransition(super::TriggerTransition), + + PartitionElem(Box), + + PartitionSpec(super::PartitionSpec), + + PartitionBoundSpec(super::PartitionBoundSpec), + + PartitionRangeDatum(Box), + + PartitionCmd(super::PartitionCmd), + + VacuumRelation(super::VacuumRelation), + + InlineCodeBlock(super::InlineCodeBlock), + + CallContext(super::CallContext), + + Integer(super::Integer), + + Float(super::Float), + + String(super::String2), + + BitString(super::BitString), + + Null(super::Null), + + List(super::List), + + IntList(super::IntList), + + OidList(super::OidList), + } +} +#[derive(Clone, PartialEq)] +pub struct Integer { + /// machine integer + + pub ival: i32, +} +#[derive(Clone, PartialEq)] +pub struct Float { + /// string + + pub str: String, +} +#[derive(Clone, PartialEq)] +pub struct String2 { + /// string + + pub str: String, +} +#[derive(Clone, PartialEq)] +pub struct BitString { + /// string + + pub str: String, +} +/// intentionally empty +#[derive(Clone, PartialEq)] +pub struct Null {} +#[derive(Clone, PartialEq)] +pub struct List { + + pub items: Vec, +} +#[derive(Clone, PartialEq)] +pub struct OidList { + + pub items: Vec, +} +#[derive(Clone, PartialEq)] +pub struct IntList { + + pub items: Vec, +} +#[derive(Clone, PartialEq)] +pub struct Alias { + + pub aliasname: String, + + pub colnames: Vec, +} +#[derive(Clone, PartialEq)] +pub struct RangeVar { + + pub catalogname: String, + + pub schemaname: String, + + pub relname: String, + + pub inh: bool, + + pub relpersistence: String, + + pub alias: ::core::option::Option, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct TableFunc { + + pub ns_uris: Vec, + + pub ns_names: Vec, + + pub docexpr: ::core::option::Option>, + + pub rowexpr: ::core::option::Option>, + + pub colnames: Vec, + + pub coltypes: Vec, + + pub coltypmods: Vec, + + pub colcollations: Vec, + + pub colexprs: Vec, + + pub coldefexprs: Vec, + + pub notnulls: Vec, + + pub ordinalitycol: i32, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct Expr {} +#[derive(Clone, PartialEq)] +pub struct Var { + + pub xpr: ::core::option::Option>, + + pub varno: u32, + + pub varattno: i32, + + pub vartype: u32, + + pub vartypmod: i32, + + pub varcollid: u32, + + pub varlevelsup: u32, + + pub varnosyn: u32, + + pub varattnosyn: i32, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct Param { + + pub xpr: ::core::option::Option>, + + pub paramkind: i32, + + pub paramid: i32, + + pub paramtype: u32, + + pub paramtypmod: i32, + + pub paramcollid: u32, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct Aggref { + + pub xpr: ::core::option::Option>, + + pub aggfnoid: u32, + + pub aggtype: u32, + + pub aggcollid: u32, + + pub inputcollid: u32, + + pub aggtranstype: u32, + + pub aggargtypes: Vec, + + pub aggdirectargs: Vec, + + pub args: Vec, + + pub aggorder: Vec, + + pub aggdistinct: Vec, + + pub aggfilter: ::core::option::Option>, + + pub aggstar: bool, + + pub aggvariadic: bool, + + pub aggkind: String, + + pub agglevelsup: u32, + + pub aggsplit: i32, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct GroupingFunc { + + pub xpr: ::core::option::Option>, + + pub args: Vec, + + pub refs: Vec, + + pub cols: Vec, + + pub agglevelsup: u32, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct WindowFunc { + + pub xpr: ::core::option::Option>, + + pub winfnoid: u32, + + pub wintype: u32, + + pub wincollid: u32, + + pub inputcollid: u32, + + pub args: Vec, + + pub aggfilter: ::core::option::Option>, + + pub winref: u32, + + pub winstar: bool, + + pub winagg: bool, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct SubscriptingRef { + + pub xpr: ::core::option::Option>, + + pub refcontainertype: u32, + + pub refelemtype: u32, + + pub reftypmod: i32, + + pub refcollid: u32, + + pub refupperindexpr: Vec, + + pub reflowerindexpr: Vec, + + pub refexpr: ::core::option::Option>, + + pub refassgnexpr: ::core::option::Option>, +} +#[derive(Clone, PartialEq)] +pub struct FuncExpr { + + pub xpr: ::core::option::Option>, + + pub funcid: u32, + + pub funcresulttype: u32, + + pub funcretset: bool, + + pub funcvariadic: bool, + + pub funcformat: i32, + + pub funccollid: u32, + + pub inputcollid: u32, + + pub args: Vec, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct NamedArgExpr { + + pub xpr: ::core::option::Option>, + + pub arg: ::core::option::Option>, + + pub name: String, + + pub argnumber: i32, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct OpExpr { + + pub xpr: ::core::option::Option>, + + pub opno: u32, + + pub opfuncid: u32, + + pub opresulttype: u32, + + pub opretset: bool, + + pub opcollid: u32, + + pub inputcollid: u32, + + pub args: Vec, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct DistinctExpr { + + pub xpr: ::core::option::Option>, + + pub opno: u32, + + pub opfuncid: u32, + + pub opresulttype: u32, + + pub opretset: bool, + + pub opcollid: u32, + + pub inputcollid: u32, + + pub args: Vec, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct NullIfExpr { + + pub xpr: ::core::option::Option>, + + pub opno: u32, + + pub opfuncid: u32, + + pub opresulttype: u32, + + pub opretset: bool, + + pub opcollid: u32, + + pub inputcollid: u32, + + pub args: Vec, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct ScalarArrayOpExpr { + + pub xpr: ::core::option::Option>, + + pub opno: u32, + + pub opfuncid: u32, + + pub use_or: bool, + + pub inputcollid: u32, + + pub args: Vec, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct BoolExpr { + + pub xpr: ::core::option::Option>, + + pub boolop: i32, + + pub args: Vec, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct SubLink { + + pub xpr: ::core::option::Option>, + + pub sub_link_type: i32, + + pub sub_link_id: i32, + + pub testexpr: ::core::option::Option>, + + pub oper_name: Vec, + + pub subselect: ::core::option::Option>, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct SubPlan { + + pub xpr: ::core::option::Option>, + + pub sub_link_type: i32, + + pub testexpr: ::core::option::Option>, + + pub param_ids: Vec, + + pub plan_id: i32, + + pub plan_name: String, + + pub first_col_type: u32, + + pub first_col_typmod: i32, + + pub first_col_collation: u32, + + pub use_hash_table: bool, + + pub unknown_eq_false: bool, + + pub parallel_safe: bool, + + pub set_param: Vec, + + pub par_param: Vec, + + pub args: Vec, + + pub startup_cost: f64, + + pub per_call_cost: f64, +} +#[derive(Clone, PartialEq)] +pub struct AlternativeSubPlan { + + pub xpr: ::core::option::Option>, + + pub subplans: Vec, +} +#[derive(Clone, PartialEq)] +pub struct FieldSelect { + + pub xpr: ::core::option::Option>, + + pub arg: ::core::option::Option>, + + pub fieldnum: i32, + + pub resulttype: u32, + + pub resulttypmod: i32, + + pub resultcollid: u32, +} +#[derive(Clone, PartialEq)] +pub struct FieldStore { + + pub xpr: ::core::option::Option>, + + pub arg: ::core::option::Option>, + + pub newvals: Vec, + + pub fieldnums: Vec, + + pub resulttype: u32, +} +#[derive(Clone, PartialEq)] +pub struct RelabelType { + + pub xpr: ::core::option::Option>, + + pub arg: ::core::option::Option>, + + pub resulttype: u32, + + pub resulttypmod: i32, + + pub resultcollid: u32, + + pub relabelformat: i32, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct CoerceViaIo { + + pub xpr: ::core::option::Option>, + + pub arg: ::core::option::Option>, + + pub resulttype: u32, + + pub resultcollid: u32, + + pub coerceformat: i32, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct ArrayCoerceExpr { + + pub xpr: ::core::option::Option>, + + pub arg: ::core::option::Option>, + + pub elemexpr: ::core::option::Option>, + + pub resulttype: u32, + + pub resulttypmod: i32, + + pub resultcollid: u32, + + pub coerceformat: i32, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct ConvertRowtypeExpr { + + pub xpr: ::core::option::Option>, + + pub arg: ::core::option::Option>, + + pub resulttype: u32, + + pub convertformat: i32, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct CollateExpr { + + pub xpr: ::core::option::Option>, + + pub arg: ::core::option::Option>, + + pub coll_oid: u32, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct CaseExpr { + + pub xpr: ::core::option::Option>, + + pub casetype: u32, + + pub casecollid: u32, + + pub arg: ::core::option::Option>, + + pub args: Vec, + + pub defresult: ::core::option::Option>, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct CaseWhen { + + pub xpr: ::core::option::Option>, + + pub expr: ::core::option::Option>, + + pub result: ::core::option::Option>, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct CaseTestExpr { + + pub xpr: ::core::option::Option>, + + pub type_id: u32, + + pub type_mod: i32, + + pub collation: u32, +} +#[derive(Clone, PartialEq)] +pub struct ArrayExpr { + + pub xpr: ::core::option::Option>, + + pub array_typeid: u32, + + pub array_collid: u32, + + pub element_typeid: u32, + + pub elements: Vec, + + pub multidims: bool, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct RowExpr { + + pub xpr: ::core::option::Option>, + + pub args: Vec, + + pub row_typeid: u32, + + pub row_format: i32, + + pub colnames: Vec, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct RowCompareExpr { + + pub xpr: ::core::option::Option>, + + pub rctype: i32, + + pub opnos: Vec, + + pub opfamilies: Vec, + + pub inputcollids: Vec, + + pub largs: Vec, + + pub rargs: Vec, +} +#[derive(Clone, PartialEq)] +pub struct CoalesceExpr { + + pub xpr: ::core::option::Option>, + + pub coalescetype: u32, + + pub coalescecollid: u32, + + pub args: Vec, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct MinMaxExpr { + + pub xpr: ::core::option::Option>, + + pub minmaxtype: u32, + + pub minmaxcollid: u32, + + pub inputcollid: u32, + + pub op: i32, + + pub args: Vec, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct SqlValueFunction { + + pub xpr: ::core::option::Option>, + + pub op: i32, + + pub r#type: u32, + + pub typmod: i32, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct XmlExpr { + + pub xpr: ::core::option::Option>, + + pub op: i32, + + pub name: String, + + pub named_args: Vec, + + pub arg_names: Vec, + + pub args: Vec, + + pub xmloption: i32, + + pub r#type: u32, + + pub typmod: i32, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct NullTest { + + pub xpr: ::core::option::Option>, + + pub arg: ::core::option::Option>, + + pub nulltesttype: i32, + + pub argisrow: bool, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct BooleanTest { + + pub xpr: ::core::option::Option>, + + pub arg: ::core::option::Option>, + + pub booltesttype: i32, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct CoerceToDomain { + + pub xpr: ::core::option::Option>, + + pub arg: ::core::option::Option>, + + pub resulttype: u32, + + pub resulttypmod: i32, + + pub resultcollid: u32, + + pub coercionformat: i32, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct CoerceToDomainValue { + + pub xpr: ::core::option::Option>, + + pub type_id: u32, + + pub type_mod: i32, + + pub collation: u32, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct SetToDefault { + + pub xpr: ::core::option::Option>, + + pub type_id: u32, + + pub type_mod: i32, + + pub collation: u32, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct CurrentOfExpr { + + pub xpr: ::core::option::Option>, + + pub cvarno: u32, + + pub cursor_name: String, + + pub cursor_param: i32, +} +#[derive(Clone, PartialEq)] +pub struct NextValueExpr { + + pub xpr: ::core::option::Option>, + + pub seqid: u32, + + pub type_id: u32, +} +#[derive(Clone, PartialEq)] +pub struct InferenceElem { + + pub xpr: ::core::option::Option>, + + pub expr: ::core::option::Option>, + + pub infercollid: u32, + + pub inferopclass: u32, +} +#[derive(Clone, PartialEq)] +pub struct TargetEntry { + + pub xpr: ::core::option::Option>, + + pub expr: ::core::option::Option>, + + pub resno: i32, + + pub resname: String, + + pub ressortgroupref: u32, + + pub resorigtbl: u32, + + pub resorigcol: i32, + + pub resjunk: bool, +} +#[derive(Clone, PartialEq)] +pub struct RangeTblRef { + + pub rtindex: i32, +} +#[derive(Clone, PartialEq)] +pub struct JoinExpr { + + pub jointype: i32, + + pub is_natural: bool, + + pub larg: ::core::option::Option>, + + pub rarg: ::core::option::Option>, + + pub using_clause: Vec, + + pub quals: ::core::option::Option>, + + pub alias: ::core::option::Option, + + pub rtindex: i32, +} +#[derive(Clone, PartialEq)] +pub struct FromExpr { + + pub fromlist: Vec, + + pub quals: ::core::option::Option>, +} +#[derive(Clone, PartialEq)] +pub struct OnConflictExpr { + + pub action: i32, + + pub arbiter_elems: Vec, + + pub arbiter_where: ::core::option::Option>, + + pub constraint: u32, + + pub on_conflict_set: Vec, + + pub on_conflict_where: ::core::option::Option>, + + pub excl_rel_index: i32, + + pub excl_rel_tlist: Vec, +} +#[derive(Clone, PartialEq)] +pub struct IntoClause { + + pub rel: ::core::option::Option, + + pub col_names: Vec, + + pub access_method: String, + + pub options: Vec, + + pub on_commit: i32, + + pub table_space_name: String, + + pub view_query: ::core::option::Option>, + + pub skip_data: bool, +} +#[derive(Clone, PartialEq)] +pub struct RawStmt { + + pub stmt: ::core::option::Option>, + + pub stmt_location: i32, + + pub stmt_len: i32, +} +#[derive(Clone, PartialEq)] +pub struct Query { + + pub command_type: i32, + + pub query_source: i32, + + pub can_set_tag: bool, + + pub utility_stmt: ::core::option::Option>, + + pub result_relation: i32, + + pub has_aggs: bool, + + pub has_window_funcs: bool, + + pub has_target_srfs: bool, + + pub has_sub_links: bool, + + pub has_distinct_on: bool, + + pub has_recursive: bool, + + pub has_modifying_cte: bool, + + pub has_for_update: bool, + + pub has_row_security: bool, + + pub cte_list: Vec, + + pub rtable: Vec, + + pub jointree: ::core::option::Option>, + + pub target_list: Vec, + + pub r#override: i32, + + pub on_conflict: ::core::option::Option>, + + pub returning_list: Vec, + + pub group_clause: Vec, + + pub grouping_sets: Vec, + + pub having_qual: ::core::option::Option>, + + pub window_clause: Vec, + + pub distinct_clause: Vec, + + pub sort_clause: Vec, + + pub limit_offset: ::core::option::Option>, + + pub limit_count: ::core::option::Option>, + + pub limit_option: i32, + + pub row_marks: Vec, + + pub set_operations: ::core::option::Option>, + + pub constraint_deps: Vec, + + pub with_check_options: Vec, + + pub stmt_location: i32, + + pub stmt_len: i32, +} +#[derive(Clone, PartialEq)] +pub struct InsertStmt { + + pub relation: ::core::option::Option, + + pub cols: Vec, + + pub select_stmt: ::core::option::Option>, + + pub on_conflict_clause: ::core::option::Option>, + + pub returning_list: Vec, + + pub with_clause: ::core::option::Option, + + pub r#override: i32, +} +#[derive(Clone, PartialEq)] +pub struct DeleteStmt { + + pub relation: ::core::option::Option, + + pub using_clause: Vec, + + pub where_clause: ::core::option::Option>, + + pub returning_list: Vec, + + pub with_clause: ::core::option::Option, +} +#[derive(Clone, PartialEq)] +pub struct UpdateStmt { + + pub relation: ::core::option::Option, + + pub target_list: Vec, + + pub where_clause: ::core::option::Option>, + + pub from_clause: Vec, + + pub returning_list: Vec, + + pub with_clause: ::core::option::Option, +} +#[derive(Clone, PartialEq)] +pub struct SelectStmt { + + pub distinct_clause: Vec, + + pub into_clause: ::core::option::Option>, + + pub target_list: Vec, + + pub from_clause: Vec, + + pub where_clause: ::core::option::Option>, + + pub group_clause: Vec, + + pub having_clause: ::core::option::Option>, + + pub window_clause: Vec, + + pub values_lists: Vec, + + pub sort_clause: Vec, + + pub limit_offset: ::core::option::Option>, + + pub limit_count: ::core::option::Option>, + + pub limit_option: i32, + + pub locking_clause: Vec, + + pub with_clause: ::core::option::Option, + + pub op: i32, + + pub all: bool, + + pub larg: ::core::option::Option>, + + pub rarg: ::core::option::Option>, +} +#[derive(Clone, PartialEq)] +pub struct AlterTableStmt { + + pub relation: ::core::option::Option, + + pub cmds: Vec, + + pub relkind: i32, + + pub missing_ok: bool, +} +#[derive(Clone, PartialEq)] +pub struct AlterTableCmd { + + pub subtype: i32, + + pub name: String, + + pub num: i32, + + pub newowner: ::core::option::Option, + + pub def: ::core::option::Option>, + + pub behavior: i32, + + pub missing_ok: bool, +} +#[derive(Clone, PartialEq)] +pub struct AlterDomainStmt { + + pub subtype: String, + + pub type_name: Vec, + + pub name: String, + + pub def: ::core::option::Option>, + + pub behavior: i32, + + pub missing_ok: bool, +} +#[derive(Clone, PartialEq)] +pub struct SetOperationStmt { + + pub op: i32, + + pub all: bool, + + pub larg: ::core::option::Option>, + + pub rarg: ::core::option::Option>, + + pub col_types: Vec, + + pub col_typmods: Vec, + + pub col_collations: Vec, + + pub group_clauses: Vec, +} +#[derive(Clone, PartialEq)] +pub struct GrantStmt { + + pub is_grant: bool, + + pub targtype: i32, + + pub objtype: i32, + + pub objects: Vec, + + pub privileges: Vec, + + pub grantees: Vec, + + pub grant_option: bool, + + pub behavior: i32, +} +#[derive(Clone, PartialEq)] +pub struct GrantRoleStmt { + + pub granted_roles: Vec, + + pub grantee_roles: Vec, + + pub is_grant: bool, + + pub admin_opt: bool, + + pub grantor: ::core::option::Option, + + pub behavior: i32, +} +#[derive(Clone, PartialEq)] +pub struct AlterDefaultPrivilegesStmt { + + pub options: Vec, + + pub action: ::core::option::Option, +} +#[derive(Clone, PartialEq)] +pub struct ClosePortalStmt { + + pub portalname: String, +} +#[derive(Clone, PartialEq)] +pub struct ClusterStmt { + + pub relation: ::core::option::Option, + + pub indexname: String, + + pub options: i32, +} +#[derive(Clone, PartialEq)] +pub struct CopyStmt { + + pub relation: ::core::option::Option, + + pub query: ::core::option::Option>, + + pub attlist: Vec, + + pub is_from: bool, + + pub is_program: bool, + + pub filename: String, + + pub options: Vec, + + pub where_clause: ::core::option::Option>, +} +#[derive(Clone, PartialEq)] +pub struct CreateStmt { + + pub relation: ::core::option::Option, + + pub table_elts: Vec, + + pub inh_relations: Vec, + + pub partbound: ::core::option::Option, + + pub partspec: ::core::option::Option, + + pub of_typename: ::core::option::Option, + + pub constraints: Vec, + + pub options: Vec, + + pub oncommit: i32, + + pub tablespacename: String, + + pub access_method: String, + + pub if_not_exists: bool, +} +#[derive(Clone, PartialEq)] +pub struct DefineStmt { + + pub kind: i32, + + pub oldstyle: bool, + + pub defnames: Vec, + + pub args: Vec, + + pub definition: Vec, + + pub if_not_exists: bool, + + pub replace: bool, +} +#[derive(Clone, PartialEq)] +pub struct DropStmt { + + pub objects: Vec, + + pub remove_type: i32, + + pub behavior: i32, + + pub missing_ok: bool, + + pub concurrent: bool, +} +#[derive(Clone, PartialEq)] +pub struct TruncateStmt { + + pub relations: Vec, + + pub restart_seqs: bool, + + pub behavior: i32, +} +#[derive(Clone, PartialEq)] +pub struct CommentStmt { + + pub objtype: i32, + + pub object: ::core::option::Option>, + + pub comment: String, +} +#[derive(Clone, PartialEq)] +pub struct FetchStmt { + + pub direction: i32, + + pub how_many: i64, + + pub portalname: String, + + pub ismove: bool, +} +#[derive(Clone, PartialEq)] +pub struct IndexStmt { + + pub idxname: String, + + pub relation: ::core::option::Option, + + pub access_method: String, + + pub table_space: String, + + pub index_params: Vec, + + pub index_including_params: Vec, + + pub options: Vec, + + pub where_clause: ::core::option::Option>, + + pub exclude_op_names: Vec, + + pub idxcomment: String, + + pub index_oid: u32, + + pub old_node: u32, + + pub old_create_subid: u32, + + pub old_first_relfilenode_subid: u32, + + pub unique: bool, + + pub primary: bool, + + pub isconstraint: bool, + + pub deferrable: bool, + + pub initdeferred: bool, + + pub transformed: bool, + + pub concurrent: bool, + + pub if_not_exists: bool, + + pub reset_default_tblspc: bool, +} +#[derive(Clone, PartialEq)] +pub struct CreateFunctionStmt { + + pub is_procedure: bool, + + pub replace: bool, + + pub funcname: Vec, + + pub parameters: Vec, + + pub return_type: ::core::option::Option, + + pub options: Vec, +} +#[derive(Clone, PartialEq)] +pub struct AlterFunctionStmt { + + pub objtype: i32, + + pub func: ::core::option::Option, + + pub actions: Vec, +} +#[derive(Clone, PartialEq)] +pub struct DoStmt { + + pub args: Vec, +} +#[derive(Clone, PartialEq)] +pub struct RenameStmt { + + pub rename_type: i32, + + pub relation_type: i32, + + pub relation: ::core::option::Option, + + pub object: ::core::option::Option>, + + pub subname: String, + + pub newname: String, + + pub behavior: i32, + + pub missing_ok: bool, +} +#[derive(Clone, PartialEq)] +pub struct RuleStmt { + + pub relation: ::core::option::Option, + + pub rulename: String, + + pub where_clause: ::core::option::Option>, + + pub event: i32, + + pub instead: bool, + + pub actions: Vec, + + pub replace: bool, +} +#[derive(Clone, PartialEq)] +pub struct NotifyStmt { + + pub conditionname: String, + + pub payload: String, +} +#[derive(Clone, PartialEq)] +pub struct ListenStmt { + + pub conditionname: String, +} +#[derive(Clone, PartialEq)] +pub struct UnlistenStmt { + + pub conditionname: String, +} +#[derive(Clone, PartialEq)] +pub struct TransactionStmt { + + pub kind: i32, + + pub options: Vec, + + pub savepoint_name: String, + + pub gid: String, + + pub chain: bool, +} +#[derive(Clone, PartialEq)] +pub struct ViewStmt { + + pub view: ::core::option::Option, + + pub aliases: Vec, + + pub query: ::core::option::Option>, + + pub replace: bool, + + pub options: Vec, + + pub with_check_option: i32, +} +#[derive(Clone, PartialEq)] +pub struct LoadStmt { + + pub filename: String, +} +#[derive(Clone, PartialEq)] +pub struct CreateDomainStmt { + + pub domainname: Vec, + + pub type_name: ::core::option::Option, + + pub coll_clause: ::core::option::Option>, + + pub constraints: Vec, +} +#[derive(Clone, PartialEq)] +pub struct CreatedbStmt { + + pub dbname: String, + + pub options: Vec, +} +#[derive(Clone, PartialEq)] +pub struct DropdbStmt { + + pub dbname: String, + + pub missing_ok: bool, + + pub options: Vec, +} +#[derive(Clone, PartialEq)] +pub struct VacuumStmt { + + pub options: Vec, + + pub rels: Vec, + + pub is_vacuumcmd: bool, +} +#[derive(Clone, PartialEq)] +pub struct ExplainStmt { + + pub query: ::core::option::Option>, + + pub options: Vec, +} +#[derive(Clone, PartialEq)] +pub struct CreateTableAsStmt { + + pub query: ::core::option::Option>, + + pub into: ::core::option::Option>, + + pub relkind: i32, + + pub is_select_into: bool, + + pub if_not_exists: bool, +} +#[derive(Clone, PartialEq)] +pub struct CreateSeqStmt { + + pub sequence: ::core::option::Option, + + pub options: Vec, + + pub owner_id: u32, + + pub for_identity: bool, + + pub if_not_exists: bool, +} +#[derive(Clone, PartialEq)] +pub struct AlterSeqStmt { + + pub sequence: ::core::option::Option, + + pub options: Vec, + + pub for_identity: bool, + + pub missing_ok: bool, +} +#[derive(Clone, PartialEq)] +pub struct VariableSetStmt { + + pub kind: i32, + + pub name: String, + + pub args: Vec, + + pub is_local: bool, +} +#[derive(Clone, PartialEq)] +pub struct VariableShowStmt { + + pub name: String, +} +#[derive(Clone, PartialEq)] +pub struct DiscardStmt { + + pub target: i32, +} +#[derive(Clone, PartialEq)] +pub struct CreateTrigStmt { + + pub trigname: String, + + pub relation: ::core::option::Option, + + pub funcname: Vec, + + pub args: Vec, + + pub row: bool, + + pub timing: i32, + + pub events: i32, + + pub columns: Vec, + + pub when_clause: ::core::option::Option>, + + pub isconstraint: bool, + + pub transition_rels: Vec, + + pub deferrable: bool, + + pub initdeferred: bool, + + pub constrrel: ::core::option::Option, +} +#[derive(Clone, PartialEq)] +pub struct CreatePLangStmt { + + pub replace: bool, + + pub plname: String, + + pub plhandler: Vec, + + pub plinline: Vec, + + pub plvalidator: Vec, + + pub pltrusted: bool, +} +#[derive(Clone, PartialEq)] +pub struct CreateRoleStmt { + + pub stmt_type: i32, + + pub role: String, + + pub options: Vec, +} +#[derive(Clone, PartialEq)] +pub struct AlterRoleStmt { + + pub role: ::core::option::Option, + + pub options: Vec, + + pub action: i32, +} +#[derive(Clone, PartialEq)] +pub struct DropRoleStmt { + + pub roles: Vec, + + pub missing_ok: bool, +} +#[derive(Clone, PartialEq)] +pub struct LockStmt { + + pub relations: Vec, + + pub mode: i32, + + pub nowait: bool, +} +#[derive(Clone, PartialEq)] +pub struct ConstraintsSetStmt { + + pub constraints: Vec, + + pub deferred: bool, +} +#[derive(Clone, PartialEq)] +pub struct ReindexStmt { + + pub kind: i32, + + pub relation: ::core::option::Option, + + pub name: String, + + pub options: i32, + + pub concurrent: bool, +} +#[derive(Clone, PartialEq)] +pub struct CheckPointStmt {} +#[derive(Clone, PartialEq)] +pub struct CreateSchemaStmt { + + pub schemaname: String, + + pub authrole: ::core::option::Option, + + pub schema_elts: Vec, + + pub if_not_exists: bool, +} +#[derive(Clone, PartialEq)] +pub struct AlterDatabaseStmt { + + pub dbname: String, + + pub options: Vec, +} +#[derive(Clone, PartialEq)] +pub struct AlterDatabaseSetStmt { + + pub dbname: String, + + pub setstmt: ::core::option::Option, +} +#[derive(Clone, PartialEq)] +pub struct AlterRoleSetStmt { + + pub role: ::core::option::Option, + + pub database: String, + + pub setstmt: ::core::option::Option, +} +#[derive(Clone, PartialEq)] +pub struct CreateConversionStmt { + + pub conversion_name: Vec, + + pub for_encoding_name: String, + + pub to_encoding_name: String, + + pub func_name: Vec, + + pub def: bool, +} +#[derive(Clone, PartialEq)] +pub struct CreateCastStmt { + + pub sourcetype: ::core::option::Option, + + pub targettype: ::core::option::Option, + + pub func: ::core::option::Option, + + pub context: i32, + + pub inout: bool, +} +#[derive(Clone, PartialEq)] +pub struct CreateOpClassStmt { + + pub opclassname: Vec, + + pub opfamilyname: Vec, + + pub amname: String, + + pub datatype: ::core::option::Option, + + pub items: Vec, + + pub is_default: bool, +} +#[derive(Clone, PartialEq)] +pub struct CreateOpFamilyStmt { + + pub opfamilyname: Vec, + + pub amname: String, +} +#[derive(Clone, PartialEq)] +pub struct AlterOpFamilyStmt { + + pub opfamilyname: Vec, + + pub amname: String, + + pub is_drop: bool, + + pub items: Vec, +} +#[derive(Clone, PartialEq)] +pub struct PrepareStmt { + + pub name: String, + + pub argtypes: Vec, + + pub query: ::core::option::Option>, +} +#[derive(Clone, PartialEq)] +pub struct ExecuteStmt { + + pub name: String, + + pub params: Vec, +} +#[derive(Clone, PartialEq)] +pub struct DeallocateStmt { + + pub name: String, +} +#[derive(Clone, PartialEq)] +pub struct DeclareCursorStmt { + + pub portalname: String, + + pub options: i32, + + pub query: ::core::option::Option>, +} +#[derive(Clone, PartialEq)] +pub struct CreateTableSpaceStmt { + + pub tablespacename: String, + + pub owner: ::core::option::Option, + + pub location: String, + + pub options: Vec, +} +#[derive(Clone, PartialEq)] +pub struct DropTableSpaceStmt { + + pub tablespacename: String, + + pub missing_ok: bool, +} +#[derive(Clone, PartialEq)] +pub struct AlterObjectDependsStmt { + + pub object_type: i32, + + pub relation: ::core::option::Option, + + pub object: ::core::option::Option>, + + pub extname: ::core::option::Option>, + + pub remove: bool, +} +#[derive(Clone, PartialEq)] +pub struct AlterObjectSchemaStmt { + + pub object_type: i32, + + pub relation: ::core::option::Option, + + pub object: ::core::option::Option>, + + pub newschema: String, + + pub missing_ok: bool, +} +#[derive(Clone, PartialEq)] +pub struct AlterOwnerStmt { + + pub object_type: i32, + + pub relation: ::core::option::Option, + + pub object: ::core::option::Option>, + + pub newowner: ::core::option::Option, +} +#[derive(Clone, PartialEq)] +pub struct AlterOperatorStmt { + + pub opername: ::core::option::Option, + + pub options: Vec, +} +#[derive(Clone, PartialEq)] +pub struct AlterTypeStmt { + + pub type_name: Vec, + + pub options: Vec, +} +#[derive(Clone, PartialEq)] +pub struct DropOwnedStmt { + + pub roles: Vec, + + pub behavior: i32, +} +#[derive(Clone, PartialEq)] +pub struct ReassignOwnedStmt { + + pub roles: Vec, + + pub newrole: ::core::option::Option, +} +#[derive(Clone, PartialEq)] +pub struct CompositeTypeStmt { + + pub typevar: ::core::option::Option, + + pub coldeflist: Vec, +} +#[derive(Clone, PartialEq)] +pub struct CreateEnumStmt { + + pub type_name: Vec, + + pub vals: Vec, +} +#[derive(Clone, PartialEq)] +pub struct CreateRangeStmt { + + pub type_name: Vec, + + pub params: Vec, +} +#[derive(Clone, PartialEq)] +pub struct AlterEnumStmt { + + pub type_name: Vec, + + pub old_val: String, + + pub new_val: String, + + pub new_val_neighbor: String, + + pub new_val_is_after: bool, + + pub skip_if_new_val_exists: bool, +} +#[derive(Clone, PartialEq)] +pub struct AlterTsDictionaryStmt { + + pub dictname: Vec, + + pub options: Vec, +} +#[derive(Clone, PartialEq)] +pub struct AlterTsConfigurationStmt { + + pub kind: i32, + + pub cfgname: Vec, + + pub tokentype: Vec, + + pub dicts: Vec, + + pub r#override: bool, + + pub replace: bool, + + pub missing_ok: bool, +} +#[derive(Clone, PartialEq)] +pub struct CreateFdwStmt { + + pub fdwname: String, + + pub func_options: Vec, + + pub options: Vec, +} +#[derive(Clone, PartialEq)] +pub struct AlterFdwStmt { + + pub fdwname: String, + + pub func_options: Vec, + + pub options: Vec, +} +#[derive(Clone, PartialEq)] +pub struct CreateForeignServerStmt { + + pub servername: String, + + pub servertype: String, + + pub version: String, + + pub fdwname: String, + + pub if_not_exists: bool, + + pub options: Vec, +} +#[derive(Clone, PartialEq)] +pub struct AlterForeignServerStmt { + + pub servername: String, + + pub version: String, + + pub options: Vec, + + pub has_version: bool, +} +#[derive(Clone, PartialEq)] +pub struct CreateUserMappingStmt { + + pub user: ::core::option::Option, + + pub servername: String, + + pub if_not_exists: bool, + + pub options: Vec, +} +#[derive(Clone, PartialEq)] +pub struct AlterUserMappingStmt { + + pub user: ::core::option::Option, + + pub servername: String, + + pub options: Vec, +} +#[derive(Clone, PartialEq)] +pub struct DropUserMappingStmt { + + pub user: ::core::option::Option, + + pub servername: String, + + pub missing_ok: bool, +} +#[derive(Clone, PartialEq)] +pub struct AlterTableSpaceOptionsStmt { + + pub tablespacename: String, + + pub options: Vec, + + pub is_reset: bool, +} +#[derive(Clone, PartialEq)] +pub struct AlterTableMoveAllStmt { + + pub orig_tablespacename: String, + + pub objtype: i32, + + pub roles: Vec, + + pub new_tablespacename: String, + + pub nowait: bool, +} +#[derive(Clone, PartialEq)] +pub struct SecLabelStmt { + + pub objtype: i32, + + pub object: ::core::option::Option>, + + pub provider: String, + + pub label: String, +} +#[derive(Clone, PartialEq)] +pub struct CreateForeignTableStmt { + + pub base_stmt: ::core::option::Option, + + pub servername: String, + + pub options: Vec, +} +#[derive(Clone, PartialEq)] +pub struct ImportForeignSchemaStmt { + + pub server_name: String, + + pub remote_schema: String, + + pub local_schema: String, + + pub list_type: i32, + + pub table_list: Vec, + + pub options: Vec, +} +#[derive(Clone, PartialEq)] +pub struct CreateExtensionStmt { + + pub extname: String, + + pub if_not_exists: bool, + + pub options: Vec, +} +#[derive(Clone, PartialEq)] +pub struct AlterExtensionStmt { + + pub extname: String, + + pub options: Vec, +} +#[derive(Clone, PartialEq)] +pub struct AlterExtensionContentsStmt { + + pub extname: String, + + pub action: i32, + + pub objtype: i32, + + pub object: ::core::option::Option>, +} +#[derive(Clone, PartialEq)] +pub struct CreateEventTrigStmt { + + pub trigname: String, + + pub eventname: String, + + pub whenclause: Vec, + + pub funcname: Vec, +} +#[derive(Clone, PartialEq)] +pub struct AlterEventTrigStmt { + + pub trigname: String, + + pub tgenabled: String, +} +#[derive(Clone, PartialEq)] +pub struct RefreshMatViewStmt { + + pub concurrent: bool, + + pub skip_data: bool, + + pub relation: ::core::option::Option, +} +#[derive(Clone, PartialEq)] +pub struct ReplicaIdentityStmt { + + pub identity_type: String, + + pub name: String, +} +#[derive(Clone, PartialEq)] +pub struct AlterSystemStmt { + + pub setstmt: ::core::option::Option, +} +#[derive(Clone, PartialEq)] +pub struct CreatePolicyStmt { + + pub policy_name: String, + + pub table: ::core::option::Option, + + pub cmd_name: String, + + pub permissive: bool, + + pub roles: Vec, + + pub qual: ::core::option::Option>, + + pub with_check: ::core::option::Option>, +} +#[derive(Clone, PartialEq)] +pub struct AlterPolicyStmt { + + pub policy_name: String, + + pub table: ::core::option::Option, + + pub roles: Vec, + + pub qual: ::core::option::Option>, + + pub with_check: ::core::option::Option>, +} +#[derive(Clone, PartialEq)] +pub struct CreateTransformStmt { + + pub replace: bool, + + pub type_name: ::core::option::Option, + + pub lang: String, + + pub fromsql: ::core::option::Option, + + pub tosql: ::core::option::Option, +} +#[derive(Clone, PartialEq)] +pub struct CreateAmStmt { + + pub amname: String, + + pub handler_name: Vec, + + pub amtype: String, +} +#[derive(Clone, PartialEq)] +pub struct CreatePublicationStmt { + + pub pubname: String, + + pub options: Vec, + + pub tables: Vec, + + pub for_all_tables: bool, +} +#[derive(Clone, PartialEq)] +pub struct AlterPublicationStmt { + + pub pubname: String, + + pub options: Vec, + + pub tables: Vec, + + pub for_all_tables: bool, + + pub table_action: i32, +} +#[derive(Clone, PartialEq)] +pub struct CreateSubscriptionStmt { + + pub subname: String, + + pub conninfo: String, + + pub publication: Vec, + + pub options: Vec, +} +#[derive(Clone, PartialEq)] +pub struct AlterSubscriptionStmt { + + pub kind: i32, + + pub subname: String, + + pub conninfo: String, + + pub publication: Vec, + + pub options: Vec, +} +#[derive(Clone, PartialEq)] +pub struct DropSubscriptionStmt { + + pub subname: String, + + pub missing_ok: bool, + + pub behavior: i32, +} +#[derive(Clone, PartialEq)] +pub struct CreateStatsStmt { + + pub defnames: Vec, + + pub stat_types: Vec, + + pub exprs: Vec, + + pub relations: Vec, + + pub stxcomment: String, + + pub if_not_exists: bool, +} +#[derive(Clone, PartialEq)] +pub struct AlterCollationStmt { + + pub collname: Vec, +} +#[derive(Clone, PartialEq)] +pub struct CallStmt { + + pub funccall: ::core::option::Option>, + + pub funcexpr: ::core::option::Option>, +} +#[derive(Clone, PartialEq)] +pub struct AlterStatsStmt { + + pub defnames: Vec, + + pub stxstattarget: i32, + + pub missing_ok: bool, +} +#[derive(Clone, PartialEq)] +pub struct AExpr { + + pub kind: i32, + + pub name: Vec, + + pub lexpr: ::core::option::Option>, + + pub rexpr: ::core::option::Option>, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct ColumnRef { + + pub fields: Vec, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct ParamRef { + + pub number: i32, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct AConst { + + pub val: ::core::option::Option>, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct FuncCall { + + pub funcname: Vec, + + pub args: Vec, + + pub agg_order: Vec, + + pub agg_filter: ::core::option::Option>, + + pub agg_within_group: bool, + + pub agg_star: bool, + + pub agg_distinct: bool, + + pub func_variadic: bool, + + pub over: ::core::option::Option>, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct AStar {} +#[derive(Clone, PartialEq)] +pub struct AIndices { + + pub is_slice: bool, + + pub lidx: ::core::option::Option>, + + pub uidx: ::core::option::Option>, +} +#[derive(Clone, PartialEq)] +pub struct AIndirection { + + pub arg: ::core::option::Option>, + + pub indirection: Vec, +} +#[derive(Clone, PartialEq)] +pub struct AArrayExpr { + + pub elements: Vec, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct ResTarget { + + pub name: String, + + pub indirection: Vec, + + pub val: ::core::option::Option>, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct MultiAssignRef { + + pub source: ::core::option::Option>, + + pub colno: i32, + + pub ncolumns: i32, +} +#[derive(Clone, PartialEq)] +pub struct TypeCast { + + pub arg: ::core::option::Option>, + + pub type_name: ::core::option::Option, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct CollateClause { + + pub arg: ::core::option::Option>, + + pub collname: Vec, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct SortBy { + + pub node: ::core::option::Option>, + + pub sortby_dir: i32, + + pub sortby_nulls: i32, + + pub use_op: Vec, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct WindowDef { + + pub name: String, + + pub refname: String, + + pub partition_clause: Vec, + + pub order_clause: Vec, + + pub frame_options: i32, + + pub start_offset: ::core::option::Option>, + + pub end_offset: ::core::option::Option>, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct RangeSubselect { + + pub lateral: bool, + + pub subquery: ::core::option::Option>, + + pub alias: ::core::option::Option, +} +#[derive(Clone, PartialEq)] +pub struct RangeFunction { + + pub lateral: bool, + + pub ordinality: bool, + + pub is_rowsfrom: bool, + + pub functions: Vec, + + pub alias: ::core::option::Option, + + pub coldeflist: Vec, +} +#[derive(Clone, PartialEq)] +pub struct RangeTableSample { + + pub relation: ::core::option::Option>, + + pub method: Vec, + + pub args: Vec, + + pub repeatable: ::core::option::Option>, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct RangeTableFunc { + + pub lateral: bool, + + pub docexpr: ::core::option::Option>, + + pub rowexpr: ::core::option::Option>, + + pub namespaces: Vec, + + pub columns: Vec, + + pub alias: ::core::option::Option, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct RangeTableFuncCol { + + pub colname: String, + + pub type_name: ::core::option::Option, + + pub for_ordinality: bool, + + pub is_not_null: bool, + + pub colexpr: ::core::option::Option>, + + pub coldefexpr: ::core::option::Option>, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct TypeName { + + pub names: Vec, + + pub type_oid: u32, + + pub setof: bool, + + pub pct_type: bool, + + pub typmods: Vec, + + pub typemod: i32, + + pub array_bounds: Vec, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct ColumnDef { + + pub colname: String, + + pub type_name: ::core::option::Option, + + pub inhcount: i32, + + pub is_local: bool, + + pub is_not_null: bool, + + pub is_from_type: bool, + + pub storage: String, + + pub raw_default: ::core::option::Option>, + + pub cooked_default: ::core::option::Option>, + + pub identity: String, + + pub identity_sequence: ::core::option::Option, + + pub generated: String, + + pub coll_clause: ::core::option::Option>, + + pub coll_oid: u32, + + pub constraints: Vec, + + pub fdwoptions: Vec, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct IndexElem { + + pub name: String, + + pub expr: ::core::option::Option>, + + pub indexcolname: String, + + pub collation: Vec, + + pub opclass: Vec, + + pub opclassopts: Vec, + + pub ordering: i32, + + pub nulls_ordering: i32, +} +#[derive(Clone, PartialEq)] +pub struct Constraint { + + pub contype: i32, + + pub conname: String, + + pub deferrable: bool, + + pub initdeferred: bool, + + pub location: i32, + + pub is_no_inherit: bool, + + pub raw_expr: ::core::option::Option>, + + pub cooked_expr: String, + + pub generated_when: String, + + pub keys: Vec, + + pub including: Vec, + + pub exclusions: Vec, + + pub options: Vec, + + pub indexname: String, + + pub indexspace: String, + + pub reset_default_tblspc: bool, + + pub access_method: String, + + pub where_clause: ::core::option::Option>, + + pub pktable: ::core::option::Option, + + pub fk_attrs: Vec, + + pub pk_attrs: Vec, + + pub fk_matchtype: String, + + pub fk_upd_action: String, + + pub fk_del_action: String, + + pub old_conpfeqop: Vec, + + pub old_pktable_oid: u32, + + pub skip_validation: bool, + + pub initially_valid: bool, +} +#[derive(Clone, PartialEq)] +pub struct DefElem { + + pub defnamespace: String, + + pub defname: String, + + pub arg: ::core::option::Option>, + + pub defaction: i32, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct RangeTblEntry { + + pub rtekind: i32, + + pub relid: u32, + + pub relkind: String, + + pub rellockmode: i32, + + pub tablesample: ::core::option::Option>, + + pub subquery: ::core::option::Option>, + + pub security_barrier: bool, + + pub jointype: i32, + + pub joinmergedcols: i32, + + pub joinaliasvars: Vec, + + pub joinleftcols: Vec, + + pub joinrightcols: Vec, + + pub functions: Vec, + + pub funcordinality: bool, + + pub tablefunc: ::core::option::Option>, + + pub values_lists: Vec, + + pub ctename: String, + + pub ctelevelsup: u32, + + pub self_reference: bool, + + pub coltypes: Vec, + + pub coltypmods: Vec, + + pub colcollations: Vec, + + pub enrname: String, + + pub enrtuples: f64, + + pub alias: ::core::option::Option, + + pub eref: ::core::option::Option, + + pub lateral: bool, + + pub inh: bool, + + pub in_from_cl: bool, + + pub required_perms: u32, + + pub check_as_user: u32, + + pub selected_cols: Vec, + + pub inserted_cols: Vec, + + pub updated_cols: Vec, + + pub extra_updated_cols: Vec, + + pub security_quals: Vec, +} +#[derive(Clone, PartialEq)] +pub struct RangeTblFunction { + + pub funcexpr: ::core::option::Option>, + + pub funccolcount: i32, + + pub funccolnames: Vec, + + pub funccoltypes: Vec, + + pub funccoltypmods: Vec, + + pub funccolcollations: Vec, + + pub funcparams: Vec, +} +#[derive(Clone, PartialEq)] +pub struct TableSampleClause { + + pub tsmhandler: u32, + + pub args: Vec, + + pub repeatable: ::core::option::Option>, +} +#[derive(Clone, PartialEq)] +pub struct WithCheckOption { + + pub kind: i32, + + pub relname: String, + + pub polname: String, + + pub qual: ::core::option::Option>, + + pub cascaded: bool, +} +#[derive(Clone, PartialEq)] +pub struct SortGroupClause { + + pub tle_sort_group_ref: u32, + + pub eqop: u32, + + pub sortop: u32, + + pub nulls_first: bool, + + pub hashable: bool, +} +#[derive(Clone, PartialEq)] +pub struct GroupingSet { + + pub kind: i32, + + pub content: Vec, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct WindowClause { + + pub name: String, + + pub refname: String, + + pub partition_clause: Vec, + + pub order_clause: Vec, + + pub frame_options: i32, + + pub start_offset: ::core::option::Option>, + + pub end_offset: ::core::option::Option>, + + pub start_in_range_func: u32, + + pub end_in_range_func: u32, + + pub in_range_coll: u32, + + pub in_range_asc: bool, + + pub in_range_nulls_first: bool, + + pub winref: u32, + + pub copied_order: bool, +} +#[derive(Clone, PartialEq)] +pub struct ObjectWithArgs { + + pub objname: Vec, + + pub objargs: Vec, + + pub args_unspecified: bool, +} +#[derive(Clone, PartialEq)] +pub struct AccessPriv { + + pub priv_name: String, + + pub cols: Vec, +} +#[derive(Clone, PartialEq)] +pub struct CreateOpClassItem { + + pub itemtype: i32, + + pub name: ::core::option::Option, + + pub number: i32, + + pub order_family: Vec, + + pub class_args: Vec, + + pub storedtype: ::core::option::Option, +} +#[derive(Clone, PartialEq)] +pub struct TableLikeClause { + + pub relation: ::core::option::Option, + + pub options: u32, + + pub relation_oid: u32, +} +#[derive(Clone, PartialEq)] +pub struct FunctionParameter { + + pub name: String, + + pub arg_type: ::core::option::Option, + + pub mode: i32, + + pub defexpr: ::core::option::Option>, +} +#[derive(Clone, PartialEq)] +pub struct LockingClause { + + pub locked_rels: Vec, + + pub strength: i32, + + pub wait_policy: i32, +} +#[derive(Clone, PartialEq)] +pub struct RowMarkClause { + + pub rti: u32, + + pub strength: i32, + + pub wait_policy: i32, + + pub pushed_down: bool, +} +#[derive(Clone, PartialEq)] +pub struct XmlSerialize { + + pub xmloption: i32, + + pub expr: ::core::option::Option>, + + pub type_name: ::core::option::Option, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct WithClause { + + pub ctes: Vec, + + pub recursive: bool, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct InferClause { + + pub index_elems: Vec, + + pub where_clause: ::core::option::Option>, + + pub conname: String, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct OnConflictClause { + + pub action: i32, + + pub infer: ::core::option::Option>, + + pub target_list: Vec, + + pub where_clause: ::core::option::Option>, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct CommonTableExpr { + + pub ctename: String, + + pub aliascolnames: Vec, + + pub ctematerialized: i32, + + pub ctequery: ::core::option::Option>, + + pub location: i32, + + pub cterecursive: bool, + + pub cterefcount: i32, + + pub ctecolnames: Vec, + + pub ctecoltypes: Vec, + + pub ctecoltypmods: Vec, + + pub ctecolcollations: Vec, +} +#[derive(Clone, PartialEq)] +pub struct RoleSpec { + + pub roletype: i32, + + pub rolename: String, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct TriggerTransition { + + pub name: String, + + pub is_new: bool, + + pub is_table: bool, +} +#[derive(Clone, PartialEq)] +pub struct PartitionElem { + + pub name: String, + + pub expr: ::core::option::Option>, + + pub collation: Vec, + + pub opclass: Vec, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct PartitionSpec { + + pub strategy: String, + + pub part_params: Vec, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct PartitionBoundSpec { + + pub strategy: String, + + pub is_default: bool, + + pub modulus: i32, + + pub remainder: i32, + + pub listdatums: Vec, + + pub lowerdatums: Vec, + + pub upperdatums: Vec, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct PartitionRangeDatum { + + pub kind: i32, + + pub value: ::core::option::Option>, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct PartitionCmd { + + pub name: ::core::option::Option, + + pub bound: ::core::option::Option, +} +#[derive(Clone, PartialEq)] +pub struct VacuumRelation { + + pub relation: ::core::option::Option, + + pub oid: u32, + + pub va_cols: Vec, +} +#[derive(Clone, PartialEq)] +pub struct InlineCodeBlock { + + pub source_text: String, + + pub lang_oid: u32, + + pub lang_is_trusted: bool, + + pub atomic: bool, +} +#[derive(Clone, PartialEq)] +pub struct CallContext { + + pub atomic: bool, +} +#[derive(Clone, PartialEq)] +pub struct ScanToken { + + pub start: i32, + + pub end: i32, + + pub token: i32, + + pub keyword_kind: i32, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum OverridingKind { + Undefined = 0, + OverridingNotSet = 1, + OverridingUserValue = 2, + OverridingSystemValue = 3, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum QuerySource { + Undefined = 0, + QsrcOriginal = 1, + QsrcParser = 2, + QsrcInsteadRule = 3, + QsrcQualInsteadRule = 4, + QsrcNonInsteadRule = 5, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum SortByDir { + Undefined = 0, + SortbyDefault = 1, + SortbyAsc = 2, + SortbyDesc = 3, + SortbyUsing = 4, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum SortByNulls { + Undefined = 0, + SortbyNullsDefault = 1, + SortbyNullsFirst = 2, + SortbyNullsLast = 3, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum AExprKind { + Undefined = 0, + AexprOp = 1, + AexprOpAny = 2, + AexprOpAll = 3, + AexprDistinct = 4, + AexprNotDistinct = 5, + AexprNullif = 6, + AexprOf = 7, + AexprIn = 8, + AexprLike = 9, + AexprIlike = 10, + AexprSimilar = 11, + AexprBetween = 12, + AexprNotBetween = 13, + AexprBetweenSym = 14, + AexprNotBetweenSym = 15, + AexprParen = 16, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum RoleSpecType { + Undefined = 0, + RolespecCstring = 1, + RolespecCurrentUser = 2, + RolespecSessionUser = 3, + RolespecPublic = 4, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum TableLikeOption { + Undefined = 0, + CreateTableLikeComments = 1, + CreateTableLikeConstraints = 2, + CreateTableLikeDefaults = 3, + CreateTableLikeGenerated = 4, + CreateTableLikeIdentity = 5, + CreateTableLikeIndexes = 6, + CreateTableLikeStatistics = 7, + CreateTableLikeStorage = 8, + CreateTableLikeAll = 9, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum DefElemAction { + Undefined = 0, + DefelemUnspec = 1, + DefelemSet = 2, + DefelemAdd = 3, + DefelemDrop = 4, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum PartitionRangeDatumKind { + Undefined = 0, + PartitionRangeDatumMinvalue = 1, + PartitionRangeDatumValue = 2, + PartitionRangeDatumMaxvalue = 3, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum RteKind { + RtekindUndefined = 0, + RteRelation = 1, + RteSubquery = 2, + RteJoin = 3, + RteFunction = 4, + RteTablefunc = 5, + RteValues = 6, + RteCte = 7, + RteNamedtuplestore = 8, + RteResult = 9, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum WcoKind { + WcokindUndefined = 0, + WcoViewCheck = 1, + WcoRlsInsertCheck = 2, + WcoRlsUpdateCheck = 3, + WcoRlsConflictCheck = 4, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum GroupingSetKind { + Undefined = 0, + GroupingSetEmpty = 1, + GroupingSetSimple = 2, + GroupingSetRollup = 3, + GroupingSetCube = 4, + GroupingSetSets = 5, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum CteMaterialize { + CtematerializeUndefined = 0, + Default = 1, + Always = 2, + Never = 3, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum SetOperation { + Undefined = 0, + SetopNone = 1, + SetopUnion = 2, + SetopIntersect = 3, + SetopExcept = 4, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum ObjectType { + Undefined = 0, + ObjectAccessMethod = 1, + ObjectAggregate = 2, + ObjectAmop = 3, + ObjectAmproc = 4, + ObjectAttribute = 5, + ObjectCast = 6, + ObjectColumn = 7, + ObjectCollation = 8, + ObjectConversion = 9, + ObjectDatabase = 10, + ObjectDefault = 11, + ObjectDefacl = 12, + ObjectDomain = 13, + ObjectDomconstraint = 14, + ObjectEventTrigger = 15, + ObjectExtension = 16, + ObjectFdw = 17, + ObjectForeignServer = 18, + ObjectForeignTable = 19, + ObjectFunction = 20, + ObjectIndex = 21, + ObjectLanguage = 22, + ObjectLargeobject = 23, + ObjectMatview = 24, + ObjectOpclass = 25, + ObjectOperator = 26, + ObjectOpfamily = 27, + ObjectPolicy = 28, + ObjectProcedure = 29, + ObjectPublication = 30, + ObjectPublicationRel = 31, + ObjectRole = 32, + ObjectRoutine = 33, + ObjectRule = 34, + ObjectSchema = 35, + ObjectSequence = 36, + ObjectSubscription = 37, + ObjectStatisticExt = 38, + ObjectTabconstraint = 39, + ObjectTable = 40, + ObjectTablespace = 41, + ObjectTransform = 42, + ObjectTrigger = 43, + ObjectTsconfiguration = 44, + ObjectTsdictionary = 45, + ObjectTsparser = 46, + ObjectTstemplate = 47, + ObjectType = 48, + ObjectUserMapping = 49, + ObjectView = 50, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum DropBehavior { + Undefined = 0, + DropRestrict = 1, + DropCascade = 2, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum AlterTableType { + Undefined = 0, + AtAddColumn = 1, + AtAddColumnRecurse = 2, + AtAddColumnToView = 3, + AtColumnDefault = 4, + AtCookedColumnDefault = 5, + AtDropNotNull = 6, + AtSetNotNull = 7, + AtDropExpression = 8, + AtCheckNotNull = 9, + AtSetStatistics = 10, + AtSetOptions = 11, + AtResetOptions = 12, + AtSetStorage = 13, + AtDropColumn = 14, + AtDropColumnRecurse = 15, + AtAddIndex = 16, + AtReAddIndex = 17, + AtAddConstraint = 18, + AtAddConstraintRecurse = 19, + AtReAddConstraint = 20, + AtReAddDomainConstraint = 21, + AtAlterConstraint = 22, + AtValidateConstraint = 23, + AtValidateConstraintRecurse = 24, + AtAddIndexConstraint = 25, + AtDropConstraint = 26, + AtDropConstraintRecurse = 27, + AtReAddComment = 28, + AtAlterColumnType = 29, + AtAlterColumnGenericOptions = 30, + AtChangeOwner = 31, + AtClusterOn = 32, + AtDropCluster = 33, + AtSetLogged = 34, + AtSetUnLogged = 35, + AtDropOids = 36, + AtSetTableSpace = 37, + AtSetRelOptions = 38, + AtResetRelOptions = 39, + AtReplaceRelOptions = 40, + AtEnableTrig = 41, + AtEnableAlwaysTrig = 42, + AtEnableReplicaTrig = 43, + AtDisableTrig = 44, + AtEnableTrigAll = 45, + AtDisableTrigAll = 46, + AtEnableTrigUser = 47, + AtDisableTrigUser = 48, + AtEnableRule = 49, + AtEnableAlwaysRule = 50, + AtEnableReplicaRule = 51, + AtDisableRule = 52, + AtAddInherit = 53, + AtDropInherit = 54, + AtAddOf = 55, + AtDropOf = 56, + AtReplicaIdentity = 57, + AtEnableRowSecurity = 58, + AtDisableRowSecurity = 59, + AtForceRowSecurity = 60, + AtNoForceRowSecurity = 61, + AtGenericOptions = 62, + AtAttachPartition = 63, + AtDetachPartition = 64, + AtAddIdentity = 65, + AtSetIdentity = 66, + AtDropIdentity = 67, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum GrantTargetType { + Undefined = 0, + AclTargetObject = 1, + AclTargetAllInSchema = 2, + AclTargetDefaults = 3, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum VariableSetKind { + Undefined = 0, + VarSetValue = 1, + VarSetDefault = 2, + VarSetCurrent = 3, + VarSetMulti = 4, + VarReset = 5, + VarResetAll = 6, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum ConstrType { + Undefined = 0, + ConstrNull = 1, + ConstrNotnull = 2, + ConstrDefault = 3, + ConstrIdentity = 4, + ConstrGenerated = 5, + ConstrCheck = 6, + ConstrPrimary = 7, + ConstrUnique = 8, + ConstrExclusion = 9, + ConstrForeign = 10, + ConstrAttrDeferrable = 11, + ConstrAttrNotDeferrable = 12, + ConstrAttrDeferred = 13, + ConstrAttrImmediate = 14, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum ImportForeignSchemaType { + Undefined = 0, + FdwImportSchemaAll = 1, + FdwImportSchemaLimitTo = 2, + FdwImportSchemaExcept = 3, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum RoleStmtType { + Undefined = 0, + RolestmtRole = 1, + RolestmtUser = 2, + RolestmtGroup = 3, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum FetchDirection { + Undefined = 0, + FetchForward = 1, + FetchBackward = 2, + FetchAbsolute = 3, + FetchRelative = 4, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum FunctionParameterMode { + Undefined = 0, + FuncParamIn = 1, + FuncParamOut = 2, + FuncParamInout = 3, + FuncParamVariadic = 4, + FuncParamTable = 5, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum TransactionStmtKind { + Undefined = 0, + TransStmtBegin = 1, + TransStmtStart = 2, + TransStmtCommit = 3, + TransStmtRollback = 4, + TransStmtSavepoint = 5, + TransStmtRelease = 6, + TransStmtRollbackTo = 7, + TransStmtPrepare = 8, + TransStmtCommitPrepared = 9, + TransStmtRollbackPrepared = 10, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum ViewCheckOption { + Undefined = 0, + NoCheckOption = 1, + LocalCheckOption = 2, + CascadedCheckOption = 3, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum ClusterOption { + Undefined = 0, + CluoptRecheck = 1, + CluoptVerbose = 2, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum DiscardMode { + Undefined = 0, + DiscardAll = 1, + DiscardPlans = 2, + DiscardSequences = 3, + DiscardTemp = 4, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum ReindexObjectType { + Undefined = 0, + ReindexObjectIndex = 1, + ReindexObjectTable = 2, + ReindexObjectSchema = 3, + ReindexObjectSystem = 4, + ReindexObjectDatabase = 5, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum AlterTsConfigType { + AlterTsconfigTypeUndefined = 0, + AlterTsconfigAddMapping = 1, + AlterTsconfigAlterMappingForToken = 2, + AlterTsconfigReplaceDict = 3, + AlterTsconfigReplaceDictForToken = 4, + AlterTsconfigDropMapping = 5, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum AlterSubscriptionType { + Undefined = 0, + AlterSubscriptionOptions = 1, + AlterSubscriptionConnection = 2, + AlterSubscriptionPublication = 3, + AlterSubscriptionRefresh = 4, + AlterSubscriptionEnabled = 5, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum OnCommitAction { + Undefined = 0, + OncommitNoop = 1, + OncommitPreserveRows = 2, + OncommitDeleteRows = 3, + OncommitDrop = 4, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum ParamKind { + Undefined = 0, + ParamExtern = 1, + ParamExec = 2, + ParamSublink = 3, + ParamMultiexpr = 4, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum CoercionContext { + Undefined = 0, + CoercionImplicit = 1, + CoercionAssignment = 2, + CoercionExplicit = 3, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum CoercionForm { + Undefined = 0, + CoerceExplicitCall = 1, + CoerceExplicitCast = 2, + CoerceImplicitCast = 3, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum BoolExprType { + Undefined = 0, + AndExpr = 1, + OrExpr = 2, + NotExpr = 3, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum SubLinkType { + Undefined = 0, + ExistsSublink = 1, + AllSublink = 2, + AnySublink = 3, + RowcompareSublink = 4, + ExprSublink = 5, + MultiexprSublink = 6, + ArraySublink = 7, + CteSublink = 8, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum RowCompareType { + Undefined = 0, + RowcompareLt = 1, + RowcompareLe = 2, + RowcompareEq = 3, + RowcompareGe = 4, + RowcompareGt = 5, + RowcompareNe = 6, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum MinMaxOp { + Undefined = 0, + IsGreatest = 1, + IsLeast = 2, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum SqlValueFunctionOp { + SqlvalueFunctionOpUndefined = 0, + SvfopCurrentDate = 1, + SvfopCurrentTime = 2, + SvfopCurrentTimeN = 3, + SvfopCurrentTimestamp = 4, + SvfopCurrentTimestampN = 5, + SvfopLocaltime = 6, + SvfopLocaltimeN = 7, + SvfopLocaltimestamp = 8, + SvfopLocaltimestampN = 9, + SvfopCurrentRole = 10, + SvfopCurrentUser = 11, + SvfopUser = 12, + SvfopSessionUser = 13, + SvfopCurrentCatalog = 14, + SvfopCurrentSchema = 15, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum XmlExprOp { + Undefined = 0, + IsXmlconcat = 1, + IsXmlelement = 2, + IsXmlforest = 3, + IsXmlparse = 4, + IsXmlpi = 5, + IsXmlroot = 6, + IsXmlserialize = 7, + IsDocument = 8, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum XmlOptionType { + Undefined = 0, + XmloptionDocument = 1, + XmloptionContent = 2, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum NullTestType { + Undefined = 0, + IsNull = 1, + IsNotNull = 2, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum BoolTestType { + Undefined = 0, + IsTrue = 1, + IsNotTrue = 2, + IsFalse = 3, + IsNotFalse = 4, + IsUnknown = 5, + IsNotUnknown = 6, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum CmdType { + Undefined = 0, + CmdUnknown = 1, + CmdSelect = 2, + CmdUpdate = 3, + CmdInsert = 4, + CmdDelete = 5, + CmdUtility = 6, + CmdNothing = 7, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum JoinType { + Undefined = 0, + JoinInner = 1, + JoinLeft = 2, + JoinFull = 3, + JoinRight = 4, + JoinSemi = 5, + JoinAnti = 6, + JoinUniqueOuter = 7, + JoinUniqueInner = 8, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum AggStrategy { + Undefined = 0, + AggPlain = 1, + AggSorted = 2, + AggHashed = 3, + AggMixed = 4, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum AggSplit { + Undefined = 0, + AggsplitSimple = 1, + AggsplitInitialSerial = 2, + AggsplitFinalDeserial = 3, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum SetOpCmd { + Undefined = 0, + SetopcmdIntersect = 1, + SetopcmdIntersectAll = 2, + SetopcmdExcept = 3, + SetopcmdExceptAll = 4, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum SetOpStrategy { + Undefined = 0, + SetopSorted = 1, + SetopHashed = 2, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum OnConflictAction { + Undefined = 0, + OnconflictNone = 1, + OnconflictNothing = 2, + OnconflictUpdate = 3, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum LimitOption { + Undefined = 0, + Default = 1, + Count = 2, + WithTies = 3, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum LockClauseStrength { + Undefined = 0, + LcsNone = 1, + LcsForkeyshare = 2, + LcsForshare = 3, + LcsFornokeyupdate = 4, + LcsForupdate = 5, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum LockWaitPolicy { + Undefined = 0, + LockWaitBlock = 1, + LockWaitSkip = 2, + LockWaitError = 3, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum LockTupleMode { + Undefined = 0, + LockTupleKeyShare = 1, + LockTupleShare = 2, + LockTupleNoKeyExclusive = 3, + LockTupleExclusive = 4, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum KeywordKind { + NoKeyword = 0, + UnreservedKeyword = 1, + ColNameKeyword = 2, + TypeFuncNameKeyword = 3, + ReservedKeyword = 4, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum Token { + Nul = 0, + /// Single-character tokens that are returned 1:1 (identical with "self" list in scan.l) + /// Either supporting syntax, or single-character operators (some can be both) + /// Also see + /// + /// "%" + Ascii37 = 37, + /// "(" + Ascii40 = 40, + /// ")" + Ascii41 = 41, + /// "*" + Ascii42 = 42, + /// "+" + Ascii43 = 43, + /// "," + Ascii44 = 44, + /// "-" + Ascii45 = 45, + /// "." + Ascii46 = 46, + /// "/" + Ascii47 = 47, + /// ":" + Ascii58 = 58, + /// ";" + Ascii59 = 59, + /// "<" + Ascii60 = 60, + /// "=" + Ascii61 = 61, + /// ">" + Ascii62 = 62, + /// "?" + Ascii63 = 63, + /// "[" + Ascii91 = 91, + /// "\" + Ascii92 = 92, + /// "]" + Ascii93 = 93, + /// "^" + Ascii94 = 94, + /// Named tokens in scan.l + Ident = 258, + Uident = 259, + Fconst = 260, + Sconst = 261, + Usconst = 262, + Bconst = 263, + Xconst = 264, + Op = 265, + Iconst = 266, + Param = 267, + Typecast = 268, + DotDot = 269, + ColonEquals = 270, + EqualsGreater = 271, + LessEquals = 272, + GreaterEquals = 273, + NotEquals = 274, + SqlComment = 275, + CComment = 276, + AbortP = 277, + AbsoluteP = 278, + Access = 279, + Action = 280, + AddP = 281, + Admin = 282, + After = 283, + Aggregate = 284, + All = 285, + Also = 286, + Alter = 287, + Always = 288, + Analyse = 289, + Analyze = 290, + And = 291, + Any = 292, + Array = 293, + As = 294, + Asc = 295, + Assertion = 296, + Assignment = 297, + Asymmetric = 298, + At = 299, + Attach = 300, + Attribute = 301, + Authorization = 302, + Backward = 303, + Before = 304, + BeginP = 305, + Between = 306, + Bigint = 307, + Binary = 308, + Bit = 309, + BooleanP = 310, + Both = 311, + By = 312, + Cache = 313, + Call = 314, + Called = 315, + Cascade = 316, + Cascaded = 317, + Case = 318, + Cast = 319, + CatalogP = 320, + Chain = 321, + CharP = 322, + Character = 323, + Characteristics = 324, + Check = 325, + Checkpoint = 326, + Class = 327, + Close = 328, + Cluster = 329, + Coalesce = 330, + Collate = 331, + Collation = 332, + Column = 333, + Columns = 334, + Comment = 335, + Comments = 336, + Commit = 337, + Committed = 338, + Concurrently = 339, + Configuration = 340, + Conflict = 341, + Connection = 342, + Constraint = 343, + Constraints = 344, + ContentP = 345, + ContinueP = 346, + ConversionP = 347, + Copy = 348, + Cost = 349, + Create = 350, + Cross = 351, + Csv = 352, + Cube = 353, + CurrentP = 354, + CurrentCatalog = 355, + CurrentDate = 356, + CurrentRole = 357, + CurrentSchema = 358, + CurrentTime = 359, + CurrentTimestamp = 360, + CurrentUser = 361, + Cursor = 362, + Cycle = 363, + DataP = 364, + Database = 365, + DayP = 366, + Deallocate = 367, + Dec = 368, + DecimalP = 369, + Declare = 370, + Default = 371, + Defaults = 372, + Deferrable = 373, + Deferred = 374, + Definer = 375, + DeleteP = 376, + Delimiter = 377, + Delimiters = 378, + Depends = 379, + Desc = 380, + Detach = 381, + Dictionary = 382, + DisableP = 383, + Discard = 384, + Distinct = 385, + Do = 386, + DocumentP = 387, + DomainP = 388, + DoubleP = 389, + Drop = 390, + Each = 391, + Else = 392, + EnableP = 393, + Encoding = 394, + Encrypted = 395, + EndP = 396, + EnumP = 397, + Escape = 398, + Event = 399, + Except = 400, + Exclude = 401, + Excluding = 402, + Exclusive = 403, + Execute = 404, + Exists = 405, + Explain = 406, + Expression = 407, + Extension = 408, + External = 409, + Extract = 410, + FalseP = 411, + Family = 412, + Fetch = 413, + Filter = 414, + FirstP = 415, + FloatP = 416, + Following = 417, + For = 418, + Force = 419, + Foreign = 420, + Forward = 421, + Freeze = 422, + From = 423, + Full = 424, + Function = 425, + Functions = 426, + Generated = 427, + Global = 428, + Grant = 429, + Granted = 430, + Greatest = 431, + GroupP = 432, + Grouping = 433, + Groups = 434, + Handler = 435, + Having = 436, + HeaderP = 437, + Hold = 438, + HourP = 439, + IdentityP = 440, + IfP = 441, + Ilike = 442, + Immediate = 443, + Immutable = 444, + ImplicitP = 445, + ImportP = 446, + InP = 447, + Include = 448, + Including = 449, + Increment = 450, + Index = 451, + Indexes = 452, + Inherit = 453, + Inherits = 454, + Initially = 455, + InlineP = 456, + InnerP = 457, + Inout = 458, + InputP = 459, + Insensitive = 460, + Insert = 461, + Instead = 462, + IntP = 463, + Integer = 464, + Intersect = 465, + Interval = 466, + Into = 467, + Invoker = 468, + Is = 469, + Isnull = 470, + Isolation = 471, + Join = 472, + Key = 473, + Label = 474, + Language = 475, + LargeP = 476, + LastP = 477, + LateralP = 478, + Leading = 479, + Leakproof = 480, + Least = 481, + Left = 482, + Level = 483, + Like = 484, + Limit = 485, + Listen = 486, + Load = 487, + Local = 488, + Localtime = 489, + Localtimestamp = 490, + Location = 491, + LockP = 492, + Locked = 493, + Logged = 494, + Mapping = 495, + Match = 496, + Materialized = 497, + Maxvalue = 498, + Method = 499, + MinuteP = 500, + Minvalue = 501, + Mode = 502, + MonthP = 503, + Move = 504, + NameP = 505, + Names = 506, + National = 507, + Natural = 508, + Nchar = 509, + New = 510, + Next = 511, + Nfc = 512, + Nfd = 513, + Nfkc = 514, + Nfkd = 515, + No = 516, + None = 517, + Normalize = 518, + Normalized = 519, + Not = 520, + Nothing = 521, + Notify = 522, + Notnull = 523, + Nowait = 524, + NullP = 525, + Nullif = 526, + NullsP = 527, + Numeric = 528, + ObjectP = 529, + Of = 530, + Off = 531, + Offset = 532, + Oids = 533, + Old = 534, + On = 535, + Only = 536, + Operator = 537, + Option = 538, + Options = 539, + Or = 540, + Order = 541, + Ordinality = 542, + Others = 543, + OutP = 544, + OuterP = 545, + Over = 546, + Overlaps = 547, + Overlay = 548, + Overriding = 549, + Owned = 550, + Owner = 551, + Parallel = 552, + Parser = 553, + Partial = 554, + Partition = 555, + Passing = 556, + Password = 557, + Placing = 558, + Plans = 559, + Policy = 560, + Position = 561, + Preceding = 562, + Precision = 563, + Preserve = 564, + Prepare = 565, + Prepared = 566, + Primary = 567, + Prior = 568, + Privileges = 569, + Procedural = 570, + Procedure = 571, + Procedures = 572, + Program = 573, + Publication = 574, + Quote = 575, + Range = 576, + Read = 577, + Real = 578, + Reassign = 579, + Recheck = 580, + Recursive = 581, + Ref = 582, + References = 583, + Referencing = 584, + Refresh = 585, + Reindex = 586, + RelativeP = 587, + Release = 588, + Rename = 589, + Repeatable = 590, + Replace = 591, + Replica = 592, + Reset = 593, + Restart = 594, + Restrict = 595, + Returning = 596, + Returns = 597, + Revoke = 598, + Right = 599, + Role = 600, + Rollback = 601, + Rollup = 602, + Routine = 603, + Routines = 604, + Row = 605, + Rows = 606, + Rule = 607, + Savepoint = 608, + Schema = 609, + Schemas = 610, + Scroll = 611, + Search = 612, + SecondP = 613, + Security = 614, + Select = 615, + Sequence = 616, + Sequences = 617, + Serializable = 618, + Server = 619, + Session = 620, + SessionUser = 621, + Set = 622, + Sets = 623, + Setof = 624, + Share = 625, + Show = 626, + Similar = 627, + Simple = 628, + Skip = 629, + Smallint = 630, + Snapshot = 631, + Some = 632, + SqlP = 633, + Stable = 634, + StandaloneP = 635, + Start = 636, + Statement = 637, + Statistics = 638, + Stdin = 639, + Stdout = 640, + Storage = 641, + Stored = 642, + StrictP = 643, + StripP = 644, + Subscription = 645, + Substring = 646, + Support = 647, + Symmetric = 648, + Sysid = 649, + SystemP = 650, + Table = 651, + Tables = 652, + Tablesample = 653, + Tablespace = 654, + Temp = 655, + Template = 656, + Temporary = 657, + TextP = 658, + Then = 659, + Ties = 660, + Time = 661, + Timestamp = 662, + To = 663, + Trailing = 664, + Transaction = 665, + Transform = 666, + Treat = 667, + Trigger = 668, + Trim = 669, + TrueP = 670, + Truncate = 671, + Trusted = 672, + TypeP = 673, + TypesP = 674, + Uescape = 675, + Unbounded = 676, + Uncommitted = 677, + Unencrypted = 678, + Union = 679, + Unique = 680, + Unknown = 681, + Unlisten = 682, + Unlogged = 683, + Until = 684, + Update = 685, + User = 686, + Using = 687, + Vacuum = 688, + Valid = 689, + Validate = 690, + Validator = 691, + ValueP = 692, + Values = 693, + Varchar = 694, + Variadic = 695, + Varying = 696, + Verbose = 697, + VersionP = 698, + View = 699, + Views = 700, + Volatile = 701, + When = 702, + Where = 703, + WhitespaceP = 704, + Window = 705, + With = 706, + Within = 707, + Without = 708, + Work = 709, + Wrapper = 710, + Write = 711, + XmlP = 712, + Xmlattributes = 713, + Xmlconcat = 714, + Xmlelement = 715, + Xmlexists = 716, + Xmlforest = 717, + Xmlnamespaces = 718, + Xmlparse = 719, + Xmlpi = 720, + Xmlroot = 721, + Xmlserialize = 722, + Xmltable = 723, + YearP = 724, + YesP = 725, + Zone = 726, + NotLa = 727, + NullsLa = 728, + WithLa = 729, + Postfixop = 730, + Uminus = 731, +} diff --git a/tests/target/performance/issue-4476.rs b/tests/target/performance/issue-4476.rs new file mode 100644 index 0000000000000..30567f2644b74 --- /dev/null +++ b/tests/target/performance/issue-4476.rs @@ -0,0 +1,705 @@ +use super::SemverParser; + +#[allow(dead_code, non_camel_case_types)] +#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub enum Rule { + EOI, + range_set, + logical_or, + range, + empty, + hyphen, + simple, + primitive, + primitive_op, + partial, + xr, + xr_op, + nr, + tilde, + caret, + qualifier, + parts, + part, + space, +} +#[allow(clippy::all)] +impl ::pest::Parser for SemverParser { + fn parse<'i>( + rule: Rule, + input: &'i str, + ) -> ::std::result::Result<::pest::iterators::Pairs<'i, Rule>, ::pest::error::Error> { + mod rules { + pub mod hidden { + use super::super::Rule; + #[inline] + #[allow(dead_code, non_snake_case, unused_variables)] + pub fn skip( + state: Box<::pest::ParserState>, + ) -> ::pest::ParseResult>> { + Ok(state) + } + } + pub mod visible { + use super::super::Rule; + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn range_set( + state: Box<::pest::ParserState>, + ) -> ::pest::ParseResult>> { + state.rule(Rule::range_set, |state| { + state.sequence(|state| { + self::SOI(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + self::space(state).and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state) + .and_then(|state| self::space(state)) + }) + }) + }) + }) + }) + }) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::range(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + state + .sequence(|state| { + self::logical_or(state) + .and_then(|state| { + super::hidden::skip(state) + }) + .and_then(|state| self::range(state)) + }) + .and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state).and_then( + |state| { + state.sequence(|state| { + self::logical_or(state) + .and_then(|state| { + super::hidden::skip( + state, + ) + }) + .and_then(|state| { + self::range(state) + }) + }) + }, + ) + }) + }) + }) + }) + }) + }) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + self::space(state).and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state) + .and_then(|state| self::space(state)) + }) + }) + }) + }) + }) + }) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::EOI(state)) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn logical_or( + state: Box<::pest::ParserState>, + ) -> ::pest::ParseResult>> { + state.rule(Rule::logical_or, |state| { + state.sequence(|state| { + state + .sequence(|state| { + state.optional(|state| { + self::space(state).and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state) + .and_then(|state| self::space(state)) + }) + }) + }) + }) + }) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.match_string("||")) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + self::space(state).and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state) + .and_then(|state| self::space(state)) + }) + }) + }) + }) + }) + }) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn range( + state: Box<::pest::ParserState>, + ) -> ::pest::ParseResult>> { + state.rule(Rule::range, |state| { + self::hyphen(state) + .or_else(|state| { + state.sequence(|state| { + self::simple(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + state + .sequence(|state| { + state + .optional(|state| { + state.match_string(",") + }) + .and_then(|state| { + super::hidden::skip(state) + }) + .and_then(|state| { + state.sequence(|state| { + self::space(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + self::space(state).and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state) + .and_then(|state| self::space(state)) + }) + }) + }) + }) + }) + }) + }) + }) + .and_then(|state| { + super::hidden::skip(state) + }) + .and_then(|state| { + self::simple(state) + }) + }) + .and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state) + .and_then(|state| { + state.sequence( + |state| { + state + .optional(|state| state.match_string(",")) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + self::space(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + self::space(state).and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state) + .and_then(|state| self::space(state)) + }) + }) + }) + }) + }) + }) + }) + }) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::simple(state)) + }, + ) + }) + }) + }) + }) + }) + }) + }) + }) + }) + .or_else(|state| self::empty(state)) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn empty( + state: Box<::pest::ParserState>, + ) -> ::pest::ParseResult>> { + state.rule(Rule::empty, |state| state.match_string("")) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn hyphen( + state: Box<::pest::ParserState>, + ) -> ::pest::ParseResult>> { + state.rule(Rule::hyphen, |state| { + state.sequence(|state| { + self::partial(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + self::space(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + self::space(state).and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state) + .and_then(|state| { + self::space(state) + }) + }) + }) + }) + }) + }) + }) + }) + }) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| state.match_string("-")) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + self::space(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + self::space(state).and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state) + .and_then(|state| { + self::space(state) + }) + }) + }) + }) + }) + }) + }) + }) + }) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::partial(state)) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn simple( + state: Box<::pest::ParserState>, + ) -> ::pest::ParseResult>> { + state.rule(Rule::simple, |state| { + self::primitive(state) + .or_else(|state| self::partial(state)) + .or_else(|state| self::tilde(state)) + .or_else(|state| self::caret(state)) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn primitive( + state: Box<::pest::ParserState>, + ) -> ::pest::ParseResult>> { + state.rule(Rule::primitive, |state| { + state.sequence(|state| { + self::primitive_op(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + self::space(state).and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state) + .and_then(|state| self::space(state)) + }) + }) + }) + }) + }) + }) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::partial(state)) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn primitive_op( + state: Box<::pest::ParserState>, + ) -> ::pest::ParseResult>> { + state.rule(Rule::primitive_op, |state| { + state + .match_string("<=") + .or_else(|state| state.match_string(">=")) + .or_else(|state| state.match_string(">")) + .or_else(|state| state.match_string("<")) + .or_else(|state| state.match_string("=")) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn partial( + state: Box<::pest::ParserState>, + ) -> ::pest::ParseResult>> { + state.rule(Rule::partial, |state| { + state.sequence(|state| { + self::xr(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.optional(|state| { + state.sequence(|state| { + state + .match_string(".") + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::xr(state)) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.optional(|state| { + state.sequence(|state| { + state + .match_string(".") + .and_then(|state| { + super::hidden::skip(state) + }) + .and_then(|state| self::xr(state)) + .and_then(|state| { + super::hidden::skip(state) + }) + .and_then(|state| { + state.optional(|state| { + self::qualifier(state) + }) + }) + }) + }) + }) + }) + }) + }) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn xr( + state: Box<::pest::ParserState>, + ) -> ::pest::ParseResult>> { + state.rule(Rule::xr, |state| { + self::xr_op(state).or_else(|state| self::nr(state)) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn xr_op( + state: Box<::pest::ParserState>, + ) -> ::pest::ParseResult>> { + state.rule(Rule::xr_op, |state| { + state + .match_string("x") + .or_else(|state| state.match_string("X")) + .or_else(|state| state.match_string("*")) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn nr( + state: Box<::pest::ParserState>, + ) -> ::pest::ParseResult>> { + state.rule(Rule::nr, |state| { + state.match_string("0").or_else(|state| { + state.sequence(|state| { + state + .match_range('1'..'9') + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + state.match_range('0'..'9').and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state).and_then( + |state| state.match_range('0'..'9'), + ) + }) + }) + }) + }) + }) + }) + }) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn tilde( + state: Box<::pest::ParserState>, + ) -> ::pest::ParseResult>> { + state.rule(Rule::tilde, |state| { + state.sequence(|state| { + state + .match_string("~>") + .or_else(|state| state.match_string("~")) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + self::space(state).and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state) + .and_then(|state| self::space(state)) + }) + }) + }) + }) + }) + }) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::partial(state)) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn caret( + state: Box<::pest::ParserState>, + ) -> ::pest::ParseResult>> { + state.rule(Rule::caret, |state| { + state.sequence(|state| { + state + .match_string("^") + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + self::space(state).and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state) + .and_then(|state| self::space(state)) + }) + }) + }) + }) + }) + }) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::partial(state)) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn qualifier( + state: Box<::pest::ParserState>, + ) -> ::pest::ParseResult>> { + state.rule(Rule::qualifier, |state| { + state.sequence(|state| { + state + .match_string("-") + .or_else(|state| state.match_string("+")) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| self::parts(state)) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn parts( + state: Box<::pest::ParserState>, + ) -> ::pest::ParseResult>> { + state.rule(Rule::parts, |state| { + state.sequence(|state| { + self::part(state) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + state + .sequence(|state| { + state + .match_string(".") + .and_then(|state| { + super::hidden::skip(state) + }) + .and_then(|state| self::part(state)) + }) + .and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state).and_then( + |state| { + state.sequence(|state| { + state + .match_string(".") + .and_then(|state| { + super::hidden::skip( + state, + ) + }) + .and_then(|state| { + self::part(state) + }) + }) + }, + ) + }) + }) + }) + }) + }) + }) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn part( + state: Box<::pest::ParserState>, + ) -> ::pest::ParseResult>> { + state.rule(Rule::part, |state| { + self::nr(state).or_else(|state| { + state.sequence(|state| { + state + .match_string("-") + .or_else(|state| state.match_range('0'..'9')) + .or_else(|state| state.match_range('A'..'Z')) + .or_else(|state| state.match_range('a'..'z')) + .and_then(|state| super::hidden::skip(state)) + .and_then(|state| { + state.sequence(|state| { + state.optional(|state| { + state + .match_string("-") + .or_else(|state| state.match_range('0'..'9')) + .or_else(|state| state.match_range('A'..'Z')) + .or_else(|state| state.match_range('a'..'z')) + .and_then(|state| { + state.repeat(|state| { + state.sequence(|state| { + super::hidden::skip(state).and_then( + |state| { + state + .match_string("-") + .or_else(|state| { + state.match_range( + '0'..'9', + ) + }) + .or_else(|state| { + state.match_range( + 'A'..'Z', + ) + }) + .or_else(|state| { + state.match_range( + 'a'..'z', + ) + }) + }, + ) + }) + }) + }) + }) + }) + }) + }) + }) + }) + } + #[inline] + #[allow(non_snake_case, unused_variables)] + pub fn space( + state: Box<::pest::ParserState>, + ) -> ::pest::ParseResult>> { + state + .match_string(" ") + .or_else(|state| state.match_string("\t")) + } + #[inline] + #[allow(dead_code, non_snake_case, unused_variables)] + pub fn EOI( + state: Box<::pest::ParserState>, + ) -> ::pest::ParseResult>> { + state.rule(Rule::EOI, |state| state.end_of_input()) + } + #[inline] + #[allow(dead_code, non_snake_case, unused_variables)] + pub fn SOI( + state: Box<::pest::ParserState>, + ) -> ::pest::ParseResult>> { + state.start_of_input() + } + } + pub use self::visible::*; + } + ::pest::state(input, |state| match rule { + Rule::range_set => rules::range_set(state), + Rule::logical_or => rules::logical_or(state), + Rule::range => rules::range(state), + Rule::empty => rules::empty(state), + Rule::hyphen => rules::hyphen(state), + Rule::simple => rules::simple(state), + Rule::primitive => rules::primitive(state), + Rule::primitive_op => rules::primitive_op(state), + Rule::partial => rules::partial(state), + Rule::xr => rules::xr(state), + Rule::xr_op => rules::xr_op(state), + Rule::nr => rules::nr(state), + Rule::tilde => rules::tilde(state), + Rule::caret => rules::caret(state), + Rule::qualifier => rules::qualifier(state), + Rule::parts => rules::parts(state), + Rule::part => rules::part(state), + Rule::space => rules::space(state), + Rule::EOI => rules::EOI(state), + }) + } +} diff --git a/tests/target/performance/issue-4867.rs b/tests/target/performance/issue-4867.rs new file mode 100644 index 0000000000000..336dae1b64ab8 --- /dev/null +++ b/tests/target/performance/issue-4867.rs @@ -0,0 +1,13 @@ +mod modA { + mod modB { + mod modC { + mod modD { + mod modE { + fn func() { + state . rule (Rule :: myrule , | state | { state . sequence (| state | { state . sequence (| state | { state . match_string ("abc") . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_string ("def") }) }) . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . sequence (| state | { state . optional (| state | { state . sequence (| state | { state . match_string ("abc") . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_string ("def") }) }) . and_then (| state | { state . repeat (| state | { state . sequence (| state | { super :: hidden :: skip (state) . and_then (| state | { state . sequence (| state | { state . match_string ("abc") . and_then (| state | { super :: hidden :: skip (state) }) . and_then (| state | { state . match_string ("def") }) }) }) }) }) }) }) }) }) }) }); + } + } + } + } + } +} diff --git a/tests/target/performance/issue-5128.rs b/tests/target/performance/issue-5128.rs new file mode 100644 index 0000000000000..ba9ebfc6243f2 --- /dev/null +++ b/tests/target/performance/issue-5128.rs @@ -0,0 +1,4898 @@ +fn takes_a_long_time_to_rustfmt() { + let inner_cte = vec![Node { + node: Some(node::Node::CommonTableExpr(Box::new(CommonTableExpr { + ctename: String::from("ranked_by_age_within_key"), + aliascolnames: vec![], + ctematerialized: CteMaterialize::Default as i32, + ctequery: Some(Box::new(Node { + node: Some(node::Node::SelectStmt(Box::new(SelectStmt { + distinct_clause: vec![], + into_clause: None, + target_list: vec![ + Node { + node: Some(node::Node::ResTarget(Box::new(ResTarget { + name: String::from(""), + indirection: vec![], + val: Some(Box::new(Node { + node: Some(node::Node::ColumnRef(ColumnRef { + fields: vec![Node { + node: Some(node::Node::AStar(AStar {})), + }], + location: 80, + })), + })), + location: 80, + }))), + }, + Node { + node: Some(node::Node::ResTarget(Box::new(ResTarget { + name: String::from("rank_in_key"), + indirection: vec![], + val: Some(Box::new(Node { + node: Some(node::Node::FuncCall(Box::new(FuncCall { + funcname: vec![Node { + node: Some(node::Node::String(String2 { + str: String::from("row_number"), + })), + }], + args: vec![], + agg_order: vec![], + agg_filter: None, + agg_within_group: false, + agg_star: false, + agg_distinct: false, + func_variadic: false, + over: Some(Box::new(WindowDef { + name: String::from(""), + refname: String::from(""), + partition_clause: vec![Node { + node: Some(node::Node::ColumnRef(ColumnRef { + fields: vec![Node { + node: Some(node::Node::String(String2 { + str: String::from("synthetic_key"), + })), + }], + location: 123, + })), + }], + order_clause: vec![Node { + node: Some(node::Node::SortBy(Box::new(SortBy { + node: Some(Box::new(Node { + node: Some(node::Node::ColumnRef( + ColumnRef { + fields: vec![Node { + node: Some(node::Node::String( + String2 { + str: String::from( + "logical_timestamp", + ), + }, + )), + }], + location: 156, + }, + )), + })), + sortby_dir: SortByDir::SortbyDesc as i32, + sortby_nulls: SortByNulls::SortbyNullsDefault + as i32, + use_op: vec![], + location: -1, + }))), + }], + frame_options: 1058, + start_offset: None, + end_offset: None, + location: 109, + })), + location: 91, + }))), + })), + location: 91, + }))), + }, + ], + from_clause: vec![Node { + node: Some(node::Node::RangeVar(RangeVar { + catalogname: String::from(""), + schemaname: String::from("_supertables"), + relname: String::from("9999-9999-9999"), + inh: true, + relpersistence: String::from("p"), + alias: None, + location: 206, + })), + }], + where_clause: Some(Box::new(Node { + node: Some(node::Node::AExpr(Box::new(AExpr { + kind: AExprKind::AexprOp as i32, + name: vec![Node { + node: Some(node::Node::String(String2 { + str: String::from("<="), + })), + }], + lexpr: Some(Box::new(Node { + node: Some(node::Node::ColumnRef(ColumnRef { + fields: vec![Node { + node: Some(node::Node::String(String2 { + str: String::from("logical_timestamp"), + })), + }], + location: 250, + })), + })), + rexpr: Some(Box::new(Node { + node: Some(node::Node::AConst(Box::new(AConst { + val: Some(Box::new(Node { + node: Some(node::Node::Integer(Integer { ival: 9000 })), + })), + location: 271, + }))), + })), + location: 268, + }))), + })), + group_clause: vec![], + having_clause: None, + window_clause: vec![], + values_lists: vec![], + sort_clause: vec![], + limit_offset: None, + limit_count: None, + limit_option: LimitOption::Default as i32, + locking_clause: vec![], + with_clause: None, + op: SetOperation::SetopNone as i32, + all: false, + larg: None, + rarg: None, + }))), + })), + location: 29, + cterecursive: false, + cterefcount: 0, + ctecolnames: vec![], + ctecoltypes: vec![], + ctecoltypmods: vec![], + ctecolcollations: vec![], + }))), + }]; + let outer_cte = vec![Node { + node: Some(node::Node::CommonTableExpr(Box::new(CommonTableExpr { + ctename: String::from("table_name"), + aliascolnames: vec![], + ctematerialized: CteMaterialize::Default as i32, + ctequery: Some(Box::new(Node { + node: Some(node::Node::SelectStmt(Box::new(SelectStmt { + distinct_clause: vec![], + into_clause: None, + target_list: vec![ + Node { + node: Some(node::Node::ResTarget(Box::new(ResTarget { + name: String::from("column1"), + indirection: vec![], + val: Some(Box::new(Node { + node: Some(node::Node::ColumnRef(ColumnRef { + fields: vec![Node { + node: Some(node::Node::String(String2 { + str: String::from("c1"), + })), + }], + location: 301, + })), + })), + location: 301, + }))), + }, + Node { + node: Some(node::Node::ResTarget(Box::new(ResTarget { + name: String::from("column2"), + indirection: vec![], + val: Some(Box::new(Node { + node: Some(node::Node::ColumnRef(ColumnRef { + fields: vec![Node { + node: Some(node::Node::String(String2 { + str: String::from("c2"), + })), + }], + location: 324, + })), + })), + location: 324, + }))), + }, + ], + from_clause: vec![Node { + node: Some(node::Node::RangeVar(RangeVar { + catalogname: String::from(""), + schemaname: String::from(""), + relname: String::from("ranked_by_age_within_key"), + inh: true, + relpersistence: String::from("p"), + alias: None, + location: 347, + })), + }], + where_clause: Some(Box::new(Node { + node: Some(node::Node::BoolExpr(Box::new(BoolExpr { + xpr: None, + boolop: BoolExprType::AndExpr as i32, + args: vec![ + Node { + node: Some(node::Node::AExpr(Box::new(AExpr { + kind: AExprKind::AexprOp as i32, + name: vec![Node { + node: Some(node::Node::String(String2 { + str: String::from("="), + })), + }], + lexpr: Some(Box::new(Node { + node: Some(node::Node::ColumnRef(ColumnRef { + fields: vec![Node { + node: Some(node::Node::String(String2 { + str: String::from("rank_in_key"), + })), + }], + location: 382, + })), + })), + rexpr: Some(Box::new(Node { + node: Some(node::Node::AConst(Box::new(AConst { + val: Some(Box::new(Node { + node: Some(node::Node::Integer(Integer { + ival: 1, + })), + })), + location: 396, + }))), + })), + location: 394, + }))), + }, + Node { + node: Some(node::Node::AExpr(Box::new(AExpr { + kind: AExprKind::AexprOp as i32, + name: vec![Node { + node: Some(node::Node::String(String2 { + str: String::from("="), + })), + }], + lexpr: Some(Box::new(Node { + node: Some(node::Node::ColumnRef(ColumnRef { + fields: vec![Node { + node: Some(node::Node::String(String2 { + str: String::from("is_deleted"), + })), + }], + location: 402, + })), + })), + rexpr: Some(Box::new(Node { + node: Some(node::Node::TypeCast(Box::new(TypeCast { + arg: Some(Box::new(Node { + node: Some(node::Node::AConst(Box::new( + AConst { + val: Some(Box::new(Node { + node: Some(node::Node::String( + String2 { + str: String::from("f"), + }, + )), + })), + location: 415, + }, + ))), + })), + type_name: Some(TypeName { + names: vec![ + Node { + node: Some(node::Node::String( + String2 { + str: String::from("pg_catalog"), + }, + )), + }, + Node { + node: Some(node::Node::String( + String2 { + str: String::from("bool"), + }, + )), + }, + ], + type_oid: 0, + setof: false, + pct_type: false, + typmods: vec![], + typemod: -1, + array_bounds: vec![], + location: -1, + }), + location: -1, + }))), + })), + location: 413, + }))), + }, + ], + location: 398, + }))), + })), + group_clause: vec![], + having_clause: None, + window_clause: vec![], + values_lists: vec![], + sort_clause: vec![], + limit_offset: None, + limit_count: None, + limit_option: LimitOption::Default as i32, + locking_clause: vec![], + with_clause: Some(WithClause { + ctes: inner_cte, + recursive: false, + location: 24, + }), + op: SetOperation::SetopNone as i32, + all: false, + larg: None, + rarg: None, + }))), + })), + location: 5, + cterecursive: false, + cterefcount: 0, + ctecolnames: vec![], + ctecoltypes: vec![], + ctecoltypmods: vec![], + ctecolcollations: vec![], + }))), + }]; + let expected_result = ParseResult { + version: 130003, + stmts: vec![RawStmt { + stmt: Some(Box::new(Node { + node: Some(node::Node::SelectStmt(Box::new(SelectStmt { + distinct_clause: vec![], + into_clause: None, + + target_list: vec![Node { + node: Some(node::Node::ResTarget(Box::new(ResTarget { + name: String::from(""), + indirection: vec![], + val: Some(Box::new(Node { + node: Some(node::Node::ColumnRef(ColumnRef { + fields: vec![Node { + node: Some(node::Node::String(String2 { + str: String::from("column1"), + })), + }], + location: 430, + })), + })), + location: 430, + }))), + }], + from_clause: vec![Node { + node: Some(node::Node::RangeVar(RangeVar { + catalogname: String::from(""), + schemaname: String::from(""), + relname: String::from("table_name"), + inh: true, + relpersistence: String::from("p"), + alias: None, + location: 443, + })), + }], + where_clause: Some(Box::new(Node { + node: Some(node::Node::AExpr(Box::new(AExpr { + kind: AExprKind::AexprOp as i32, + name: vec![Node { + node: Some(node::Node::String(String2 { + str: String::from(">"), + })), + }], + lexpr: Some(Box::new(Node { + node: Some(node::Node::ColumnRef(ColumnRef { + fields: vec![Node { + node: Some(node::Node::String(String2 { + str: String::from("column2"), + })), + }], + location: 460, + })), + })), + rexpr: Some(Box::new(Node { + node: Some(node::Node::AConst(Box::new(AConst { + val: Some(Box::new(Node { + node: Some(node::Node::Integer(Integer { ival: 9000 })), + })), + location: 470, + }))), + })), + location: 468, + }))), + })), + group_clause: vec![], + having_clause: None, + window_clause: vec![], + values_lists: vec![], + sort_clause: vec![], + limit_offset: None, + limit_count: None, + limit_option: LimitOption::Default as i32, + locking_clause: vec![], + with_clause: Some(WithClause { + ctes: outer_cte, + recursive: false, + location: 0, + }), + op: SetOperation::SetopNone as i32, + all: false, + larg: None, + rarg: None, + }))), + })), + stmt_location: 0, + stmt_len: 0, + }], + }; +} +#[derive(Clone, PartialEq)] +pub struct ParseResult { + pub version: i32, + + pub stmts: Vec, +} +#[derive(Clone, PartialEq)] +pub struct ScanResult { + pub version: i32, + + pub tokens: Vec, +} +#[derive(Clone, PartialEq)] +pub struct Node { + pub node: ::core::option::Option, +} +/// Nested message and enum types in `Node`. +pub mod node { + #[derive(Clone, PartialEq)] + pub enum Node { + Alias(super::Alias), + + RangeVar(super::RangeVar), + + TableFunc(Box), + + Expr(super::Expr), + + Var(Box), + + Param(Box), + + Aggref(Box), + + GroupingFunc(Box), + + WindowFunc(Box), + + SubscriptingRef(Box), + + FuncExpr(Box), + + NamedArgExpr(Box), + + OpExpr(Box), + + DistinctExpr(Box), + + NullIfExpr(Box), + + ScalarArrayOpExpr(Box), + + BoolExpr(Box), + + SubLink(Box), + + SubPlan(Box), + + AlternativeSubPlan(Box), + + FieldSelect(Box), + + FieldStore(Box), + + RelabelType(Box), + + CoerceViaIo(Box), + + ArrayCoerceExpr(Box), + + ConvertRowtypeExpr(Box), + + CollateExpr(Box), + + CaseExpr(Box), + + CaseWhen(Box), + + CaseTestExpr(Box), + + ArrayExpr(Box), + + RowExpr(Box), + + RowCompareExpr(Box), + + CoalesceExpr(Box), + + MinMaxExpr(Box), + + SqlvalueFunction(Box), + + XmlExpr(Box), + + NullTest(Box), + + BooleanTest(Box), + + CoerceToDomain(Box), + + CoerceToDomainValue(Box), + + SetToDefault(Box), + + CurrentOfExpr(Box), + + NextValueExpr(Box), + + InferenceElem(Box), + + TargetEntry(Box), + + RangeTblRef(super::RangeTblRef), + + JoinExpr(Box), + + FromExpr(Box), + + OnConflictExpr(Box), + + IntoClause(Box), + + RawStmt(Box), + + Query(Box), + + InsertStmt(Box), + + DeleteStmt(Box), + + UpdateStmt(Box), + + SelectStmt(Box), + + AlterTableStmt(super::AlterTableStmt), + + AlterTableCmd(Box), + + AlterDomainStmt(Box), + + SetOperationStmt(Box), + + GrantStmt(super::GrantStmt), + + GrantRoleStmt(super::GrantRoleStmt), + + AlterDefaultPrivilegesStmt(super::AlterDefaultPrivilegesStmt), + + ClosePortalStmt(super::ClosePortalStmt), + + ClusterStmt(super::ClusterStmt), + + CopyStmt(Box), + + CreateStmt(super::CreateStmt), + + DefineStmt(super::DefineStmt), + + DropStmt(super::DropStmt), + + TruncateStmt(super::TruncateStmt), + + CommentStmt(Box), + + FetchStmt(super::FetchStmt), + + IndexStmt(Box), + + CreateFunctionStmt(super::CreateFunctionStmt), + + AlterFunctionStmt(super::AlterFunctionStmt), + + DoStmt(super::DoStmt), + + RenameStmt(Box), + + RuleStmt(Box), + + NotifyStmt(super::NotifyStmt), + + ListenStmt(super::ListenStmt), + + UnlistenStmt(super::UnlistenStmt), + + TransactionStmt(super::TransactionStmt), + + ViewStmt(Box), + + LoadStmt(super::LoadStmt), + + CreateDomainStmt(Box), + + CreatedbStmt(super::CreatedbStmt), + + DropdbStmt(super::DropdbStmt), + + VacuumStmt(super::VacuumStmt), + + ExplainStmt(Box), + + CreateTableAsStmt(Box), + + CreateSeqStmt(super::CreateSeqStmt), + + AlterSeqStmt(super::AlterSeqStmt), + + VariableSetStmt(super::VariableSetStmt), + + VariableShowStmt(super::VariableShowStmt), + + DiscardStmt(super::DiscardStmt), + + CreateTrigStmt(Box), + + CreatePlangStmt(super::CreatePLangStmt), + + CreateRoleStmt(super::CreateRoleStmt), + + AlterRoleStmt(super::AlterRoleStmt), + + DropRoleStmt(super::DropRoleStmt), + + LockStmt(super::LockStmt), + + ConstraintsSetStmt(super::ConstraintsSetStmt), + + ReindexStmt(super::ReindexStmt), + + CheckPointStmt(super::CheckPointStmt), + + CreateSchemaStmt(super::CreateSchemaStmt), + + AlterDatabaseStmt(super::AlterDatabaseStmt), + + AlterDatabaseSetStmt(super::AlterDatabaseSetStmt), + + AlterRoleSetStmt(super::AlterRoleSetStmt), + + CreateConversionStmt(super::CreateConversionStmt), + + CreateCastStmt(super::CreateCastStmt), + + CreateOpClassStmt(super::CreateOpClassStmt), + + CreateOpFamilyStmt(super::CreateOpFamilyStmt), + + AlterOpFamilyStmt(super::AlterOpFamilyStmt), + + PrepareStmt(Box), + + ExecuteStmt(super::ExecuteStmt), + + DeallocateStmt(super::DeallocateStmt), + + DeclareCursorStmt(Box), + + CreateTableSpaceStmt(super::CreateTableSpaceStmt), + + DropTableSpaceStmt(super::DropTableSpaceStmt), + + AlterObjectDependsStmt(Box), + + AlterObjectSchemaStmt(Box), + + AlterOwnerStmt(Box), + + AlterOperatorStmt(super::AlterOperatorStmt), + + AlterTypeStmt(super::AlterTypeStmt), + + DropOwnedStmt(super::DropOwnedStmt), + + ReassignOwnedStmt(super::ReassignOwnedStmt), + + CompositeTypeStmt(super::CompositeTypeStmt), + + CreateEnumStmt(super::CreateEnumStmt), + + CreateRangeStmt(super::CreateRangeStmt), + + AlterEnumStmt(super::AlterEnumStmt), + + AlterTsdictionaryStmt(super::AlterTsDictionaryStmt), + + AlterTsconfigurationStmt(super::AlterTsConfigurationStmt), + + CreateFdwStmt(super::CreateFdwStmt), + + AlterFdwStmt(super::AlterFdwStmt), + + CreateForeignServerStmt(super::CreateForeignServerStmt), + + AlterForeignServerStmt(super::AlterForeignServerStmt), + + CreateUserMappingStmt(super::CreateUserMappingStmt), + + AlterUserMappingStmt(super::AlterUserMappingStmt), + + DropUserMappingStmt(super::DropUserMappingStmt), + + AlterTableSpaceOptionsStmt(super::AlterTableSpaceOptionsStmt), + + AlterTableMoveAllStmt(super::AlterTableMoveAllStmt), + + SecLabelStmt(Box), + + CreateForeignTableStmt(super::CreateForeignTableStmt), + + ImportForeignSchemaStmt(super::ImportForeignSchemaStmt), + + CreateExtensionStmt(super::CreateExtensionStmt), + + AlterExtensionStmt(super::AlterExtensionStmt), + + AlterExtensionContentsStmt(Box), + + CreateEventTrigStmt(super::CreateEventTrigStmt), + + AlterEventTrigStmt(super::AlterEventTrigStmt), + + RefreshMatViewStmt(super::RefreshMatViewStmt), + + ReplicaIdentityStmt(super::ReplicaIdentityStmt), + + AlterSystemStmt(super::AlterSystemStmt), + + CreatePolicyStmt(Box), + + AlterPolicyStmt(Box), + + CreateTransformStmt(super::CreateTransformStmt), + + CreateAmStmt(super::CreateAmStmt), + + CreatePublicationStmt(super::CreatePublicationStmt), + + AlterPublicationStmt(super::AlterPublicationStmt), + + CreateSubscriptionStmt(super::CreateSubscriptionStmt), + + AlterSubscriptionStmt(super::AlterSubscriptionStmt), + + DropSubscriptionStmt(super::DropSubscriptionStmt), + + CreateStatsStmt(super::CreateStatsStmt), + + AlterCollationStmt(super::AlterCollationStmt), + + CallStmt(Box), + + AlterStatsStmt(super::AlterStatsStmt), + + AExpr(Box), + + ColumnRef(super::ColumnRef), + + ParamRef(super::ParamRef), + + AConst(Box), + + FuncCall(Box), + + AStar(super::AStar), + + AIndices(Box), + + AIndirection(Box), + + AArrayExpr(super::AArrayExpr), + + ResTarget(Box), + + MultiAssignRef(Box), + + TypeCast(Box), + + CollateClause(Box), + + SortBy(Box), + + WindowDef(Box), + + RangeSubselect(Box), + + RangeFunction(super::RangeFunction), + + RangeTableSample(Box), + + RangeTableFunc(Box), + + RangeTableFuncCol(Box), + + TypeName(super::TypeName), + + ColumnDef(Box), + + IndexElem(Box), + + Constraint(Box), + + DefElem(Box), + + RangeTblEntry(Box), + + RangeTblFunction(Box), + + TableSampleClause(Box), + + WithCheckOption(Box), + + SortGroupClause(super::SortGroupClause), + + GroupingSet(super::GroupingSet), + + WindowClause(Box), + + ObjectWithArgs(super::ObjectWithArgs), + + AccessPriv(super::AccessPriv), + + CreateOpClassItem(super::CreateOpClassItem), + + TableLikeClause(super::TableLikeClause), + + FunctionParameter(Box), + + LockingClause(super::LockingClause), + + RowMarkClause(super::RowMarkClause), + + XmlSerialize(Box), + + WithClause(super::WithClause), + + InferClause(Box), + + OnConflictClause(Box), + + CommonTableExpr(Box), + + RoleSpec(super::RoleSpec), + + TriggerTransition(super::TriggerTransition), + + PartitionElem(Box), + + PartitionSpec(super::PartitionSpec), + + PartitionBoundSpec(super::PartitionBoundSpec), + + PartitionRangeDatum(Box), + + PartitionCmd(super::PartitionCmd), + + VacuumRelation(super::VacuumRelation), + + InlineCodeBlock(super::InlineCodeBlock), + + CallContext(super::CallContext), + + Integer(super::Integer), + + Float(super::Float), + + String(super::String2), + + BitString(super::BitString), + + Null(super::Null), + + List(super::List), + + IntList(super::IntList), + + OidList(super::OidList), + } +} +#[derive(Clone, PartialEq)] +pub struct Integer { + /// machine integer + pub ival: i32, +} +#[derive(Clone, PartialEq)] +pub struct Float { + /// string + pub str: String, +} +#[derive(Clone, PartialEq)] +pub struct String2 { + /// string + pub str: String, +} +#[derive(Clone, PartialEq)] +pub struct BitString { + /// string + pub str: String, +} +/// intentionally empty +#[derive(Clone, PartialEq)] +pub struct Null {} +#[derive(Clone, PartialEq)] +pub struct List { + pub items: Vec, +} +#[derive(Clone, PartialEq)] +pub struct OidList { + pub items: Vec, +} +#[derive(Clone, PartialEq)] +pub struct IntList { + pub items: Vec, +} +#[derive(Clone, PartialEq)] +pub struct Alias { + pub aliasname: String, + + pub colnames: Vec, +} +#[derive(Clone, PartialEq)] +pub struct RangeVar { + pub catalogname: String, + + pub schemaname: String, + + pub relname: String, + + pub inh: bool, + + pub relpersistence: String, + + pub alias: ::core::option::Option, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct TableFunc { + pub ns_uris: Vec, + + pub ns_names: Vec, + + pub docexpr: ::core::option::Option>, + + pub rowexpr: ::core::option::Option>, + + pub colnames: Vec, + + pub coltypes: Vec, + + pub coltypmods: Vec, + + pub colcollations: Vec, + + pub colexprs: Vec, + + pub coldefexprs: Vec, + + pub notnulls: Vec, + + pub ordinalitycol: i32, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct Expr {} +#[derive(Clone, PartialEq)] +pub struct Var { + pub xpr: ::core::option::Option>, + + pub varno: u32, + + pub varattno: i32, + + pub vartype: u32, + + pub vartypmod: i32, + + pub varcollid: u32, + + pub varlevelsup: u32, + + pub varnosyn: u32, + + pub varattnosyn: i32, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct Param { + pub xpr: ::core::option::Option>, + + pub paramkind: i32, + + pub paramid: i32, + + pub paramtype: u32, + + pub paramtypmod: i32, + + pub paramcollid: u32, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct Aggref { + pub xpr: ::core::option::Option>, + + pub aggfnoid: u32, + + pub aggtype: u32, + + pub aggcollid: u32, + + pub inputcollid: u32, + + pub aggtranstype: u32, + + pub aggargtypes: Vec, + + pub aggdirectargs: Vec, + + pub args: Vec, + + pub aggorder: Vec, + + pub aggdistinct: Vec, + + pub aggfilter: ::core::option::Option>, + + pub aggstar: bool, + + pub aggvariadic: bool, + + pub aggkind: String, + + pub agglevelsup: u32, + + pub aggsplit: i32, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct GroupingFunc { + pub xpr: ::core::option::Option>, + + pub args: Vec, + + pub refs: Vec, + + pub cols: Vec, + + pub agglevelsup: u32, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct WindowFunc { + pub xpr: ::core::option::Option>, + + pub winfnoid: u32, + + pub wintype: u32, + + pub wincollid: u32, + + pub inputcollid: u32, + + pub args: Vec, + + pub aggfilter: ::core::option::Option>, + + pub winref: u32, + + pub winstar: bool, + + pub winagg: bool, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct SubscriptingRef { + pub xpr: ::core::option::Option>, + + pub refcontainertype: u32, + + pub refelemtype: u32, + + pub reftypmod: i32, + + pub refcollid: u32, + + pub refupperindexpr: Vec, + + pub reflowerindexpr: Vec, + + pub refexpr: ::core::option::Option>, + + pub refassgnexpr: ::core::option::Option>, +} +#[derive(Clone, PartialEq)] +pub struct FuncExpr { + pub xpr: ::core::option::Option>, + + pub funcid: u32, + + pub funcresulttype: u32, + + pub funcretset: bool, + + pub funcvariadic: bool, + + pub funcformat: i32, + + pub funccollid: u32, + + pub inputcollid: u32, + + pub args: Vec, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct NamedArgExpr { + pub xpr: ::core::option::Option>, + + pub arg: ::core::option::Option>, + + pub name: String, + + pub argnumber: i32, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct OpExpr { + pub xpr: ::core::option::Option>, + + pub opno: u32, + + pub opfuncid: u32, + + pub opresulttype: u32, + + pub opretset: bool, + + pub opcollid: u32, + + pub inputcollid: u32, + + pub args: Vec, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct DistinctExpr { + pub xpr: ::core::option::Option>, + + pub opno: u32, + + pub opfuncid: u32, + + pub opresulttype: u32, + + pub opretset: bool, + + pub opcollid: u32, + + pub inputcollid: u32, + + pub args: Vec, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct NullIfExpr { + pub xpr: ::core::option::Option>, + + pub opno: u32, + + pub opfuncid: u32, + + pub opresulttype: u32, + + pub opretset: bool, + + pub opcollid: u32, + + pub inputcollid: u32, + + pub args: Vec, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct ScalarArrayOpExpr { + pub xpr: ::core::option::Option>, + + pub opno: u32, + + pub opfuncid: u32, + + pub use_or: bool, + + pub inputcollid: u32, + + pub args: Vec, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct BoolExpr { + pub xpr: ::core::option::Option>, + + pub boolop: i32, + + pub args: Vec, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct SubLink { + pub xpr: ::core::option::Option>, + + pub sub_link_type: i32, + + pub sub_link_id: i32, + + pub testexpr: ::core::option::Option>, + + pub oper_name: Vec, + + pub subselect: ::core::option::Option>, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct SubPlan { + pub xpr: ::core::option::Option>, + + pub sub_link_type: i32, + + pub testexpr: ::core::option::Option>, + + pub param_ids: Vec, + + pub plan_id: i32, + + pub plan_name: String, + + pub first_col_type: u32, + + pub first_col_typmod: i32, + + pub first_col_collation: u32, + + pub use_hash_table: bool, + + pub unknown_eq_false: bool, + + pub parallel_safe: bool, + + pub set_param: Vec, + + pub par_param: Vec, + + pub args: Vec, + + pub startup_cost: f64, + + pub per_call_cost: f64, +} +#[derive(Clone, PartialEq)] +pub struct AlternativeSubPlan { + pub xpr: ::core::option::Option>, + + pub subplans: Vec, +} +#[derive(Clone, PartialEq)] +pub struct FieldSelect { + pub xpr: ::core::option::Option>, + + pub arg: ::core::option::Option>, + + pub fieldnum: i32, + + pub resulttype: u32, + + pub resulttypmod: i32, + + pub resultcollid: u32, +} +#[derive(Clone, PartialEq)] +pub struct FieldStore { + pub xpr: ::core::option::Option>, + + pub arg: ::core::option::Option>, + + pub newvals: Vec, + + pub fieldnums: Vec, + + pub resulttype: u32, +} +#[derive(Clone, PartialEq)] +pub struct RelabelType { + pub xpr: ::core::option::Option>, + + pub arg: ::core::option::Option>, + + pub resulttype: u32, + + pub resulttypmod: i32, + + pub resultcollid: u32, + + pub relabelformat: i32, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct CoerceViaIo { + pub xpr: ::core::option::Option>, + + pub arg: ::core::option::Option>, + + pub resulttype: u32, + + pub resultcollid: u32, + + pub coerceformat: i32, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct ArrayCoerceExpr { + pub xpr: ::core::option::Option>, + + pub arg: ::core::option::Option>, + + pub elemexpr: ::core::option::Option>, + + pub resulttype: u32, + + pub resulttypmod: i32, + + pub resultcollid: u32, + + pub coerceformat: i32, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct ConvertRowtypeExpr { + pub xpr: ::core::option::Option>, + + pub arg: ::core::option::Option>, + + pub resulttype: u32, + + pub convertformat: i32, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct CollateExpr { + pub xpr: ::core::option::Option>, + + pub arg: ::core::option::Option>, + + pub coll_oid: u32, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct CaseExpr { + pub xpr: ::core::option::Option>, + + pub casetype: u32, + + pub casecollid: u32, + + pub arg: ::core::option::Option>, + + pub args: Vec, + + pub defresult: ::core::option::Option>, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct CaseWhen { + pub xpr: ::core::option::Option>, + + pub expr: ::core::option::Option>, + + pub result: ::core::option::Option>, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct CaseTestExpr { + pub xpr: ::core::option::Option>, + + pub type_id: u32, + + pub type_mod: i32, + + pub collation: u32, +} +#[derive(Clone, PartialEq)] +pub struct ArrayExpr { + pub xpr: ::core::option::Option>, + + pub array_typeid: u32, + + pub array_collid: u32, + + pub element_typeid: u32, + + pub elements: Vec, + + pub multidims: bool, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct RowExpr { + pub xpr: ::core::option::Option>, + + pub args: Vec, + + pub row_typeid: u32, + + pub row_format: i32, + + pub colnames: Vec, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct RowCompareExpr { + pub xpr: ::core::option::Option>, + + pub rctype: i32, + + pub opnos: Vec, + + pub opfamilies: Vec, + + pub inputcollids: Vec, + + pub largs: Vec, + + pub rargs: Vec, +} +#[derive(Clone, PartialEq)] +pub struct CoalesceExpr { + pub xpr: ::core::option::Option>, + + pub coalescetype: u32, + + pub coalescecollid: u32, + + pub args: Vec, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct MinMaxExpr { + pub xpr: ::core::option::Option>, + + pub minmaxtype: u32, + + pub minmaxcollid: u32, + + pub inputcollid: u32, + + pub op: i32, + + pub args: Vec, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct SqlValueFunction { + pub xpr: ::core::option::Option>, + + pub op: i32, + + pub r#type: u32, + + pub typmod: i32, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct XmlExpr { + pub xpr: ::core::option::Option>, + + pub op: i32, + + pub name: String, + + pub named_args: Vec, + + pub arg_names: Vec, + + pub args: Vec, + + pub xmloption: i32, + + pub r#type: u32, + + pub typmod: i32, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct NullTest { + pub xpr: ::core::option::Option>, + + pub arg: ::core::option::Option>, + + pub nulltesttype: i32, + + pub argisrow: bool, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct BooleanTest { + pub xpr: ::core::option::Option>, + + pub arg: ::core::option::Option>, + + pub booltesttype: i32, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct CoerceToDomain { + pub xpr: ::core::option::Option>, + + pub arg: ::core::option::Option>, + + pub resulttype: u32, + + pub resulttypmod: i32, + + pub resultcollid: u32, + + pub coercionformat: i32, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct CoerceToDomainValue { + pub xpr: ::core::option::Option>, + + pub type_id: u32, + + pub type_mod: i32, + + pub collation: u32, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct SetToDefault { + pub xpr: ::core::option::Option>, + + pub type_id: u32, + + pub type_mod: i32, + + pub collation: u32, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct CurrentOfExpr { + pub xpr: ::core::option::Option>, + + pub cvarno: u32, + + pub cursor_name: String, + + pub cursor_param: i32, +} +#[derive(Clone, PartialEq)] +pub struct NextValueExpr { + pub xpr: ::core::option::Option>, + + pub seqid: u32, + + pub type_id: u32, +} +#[derive(Clone, PartialEq)] +pub struct InferenceElem { + pub xpr: ::core::option::Option>, + + pub expr: ::core::option::Option>, + + pub infercollid: u32, + + pub inferopclass: u32, +} +#[derive(Clone, PartialEq)] +pub struct TargetEntry { + pub xpr: ::core::option::Option>, + + pub expr: ::core::option::Option>, + + pub resno: i32, + + pub resname: String, + + pub ressortgroupref: u32, + + pub resorigtbl: u32, + + pub resorigcol: i32, + + pub resjunk: bool, +} +#[derive(Clone, PartialEq)] +pub struct RangeTblRef { + pub rtindex: i32, +} +#[derive(Clone, PartialEq)] +pub struct JoinExpr { + pub jointype: i32, + + pub is_natural: bool, + + pub larg: ::core::option::Option>, + + pub rarg: ::core::option::Option>, + + pub using_clause: Vec, + + pub quals: ::core::option::Option>, + + pub alias: ::core::option::Option, + + pub rtindex: i32, +} +#[derive(Clone, PartialEq)] +pub struct FromExpr { + pub fromlist: Vec, + + pub quals: ::core::option::Option>, +} +#[derive(Clone, PartialEq)] +pub struct OnConflictExpr { + pub action: i32, + + pub arbiter_elems: Vec, + + pub arbiter_where: ::core::option::Option>, + + pub constraint: u32, + + pub on_conflict_set: Vec, + + pub on_conflict_where: ::core::option::Option>, + + pub excl_rel_index: i32, + + pub excl_rel_tlist: Vec, +} +#[derive(Clone, PartialEq)] +pub struct IntoClause { + pub rel: ::core::option::Option, + + pub col_names: Vec, + + pub access_method: String, + + pub options: Vec, + + pub on_commit: i32, + + pub table_space_name: String, + + pub view_query: ::core::option::Option>, + + pub skip_data: bool, +} +#[derive(Clone, PartialEq)] +pub struct RawStmt { + pub stmt: ::core::option::Option>, + + pub stmt_location: i32, + + pub stmt_len: i32, +} +#[derive(Clone, PartialEq)] +pub struct Query { + pub command_type: i32, + + pub query_source: i32, + + pub can_set_tag: bool, + + pub utility_stmt: ::core::option::Option>, + + pub result_relation: i32, + + pub has_aggs: bool, + + pub has_window_funcs: bool, + + pub has_target_srfs: bool, + + pub has_sub_links: bool, + + pub has_distinct_on: bool, + + pub has_recursive: bool, + + pub has_modifying_cte: bool, + + pub has_for_update: bool, + + pub has_row_security: bool, + + pub cte_list: Vec, + + pub rtable: Vec, + + pub jointree: ::core::option::Option>, + + pub target_list: Vec, + + pub r#override: i32, + + pub on_conflict: ::core::option::Option>, + + pub returning_list: Vec, + + pub group_clause: Vec, + + pub grouping_sets: Vec, + + pub having_qual: ::core::option::Option>, + + pub window_clause: Vec, + + pub distinct_clause: Vec, + + pub sort_clause: Vec, + + pub limit_offset: ::core::option::Option>, + + pub limit_count: ::core::option::Option>, + + pub limit_option: i32, + + pub row_marks: Vec, + + pub set_operations: ::core::option::Option>, + + pub constraint_deps: Vec, + + pub with_check_options: Vec, + + pub stmt_location: i32, + + pub stmt_len: i32, +} +#[derive(Clone, PartialEq)] +pub struct InsertStmt { + pub relation: ::core::option::Option, + + pub cols: Vec, + + pub select_stmt: ::core::option::Option>, + + pub on_conflict_clause: ::core::option::Option>, + + pub returning_list: Vec, + + pub with_clause: ::core::option::Option, + + pub r#override: i32, +} +#[derive(Clone, PartialEq)] +pub struct DeleteStmt { + pub relation: ::core::option::Option, + + pub using_clause: Vec, + + pub where_clause: ::core::option::Option>, + + pub returning_list: Vec, + + pub with_clause: ::core::option::Option, +} +#[derive(Clone, PartialEq)] +pub struct UpdateStmt { + pub relation: ::core::option::Option, + + pub target_list: Vec, + + pub where_clause: ::core::option::Option>, + + pub from_clause: Vec, + + pub returning_list: Vec, + + pub with_clause: ::core::option::Option, +} +#[derive(Clone, PartialEq)] +pub struct SelectStmt { + pub distinct_clause: Vec, + + pub into_clause: ::core::option::Option>, + + pub target_list: Vec, + + pub from_clause: Vec, + + pub where_clause: ::core::option::Option>, + + pub group_clause: Vec, + + pub having_clause: ::core::option::Option>, + + pub window_clause: Vec, + + pub values_lists: Vec, + + pub sort_clause: Vec, + + pub limit_offset: ::core::option::Option>, + + pub limit_count: ::core::option::Option>, + + pub limit_option: i32, + + pub locking_clause: Vec, + + pub with_clause: ::core::option::Option, + + pub op: i32, + + pub all: bool, + + pub larg: ::core::option::Option>, + + pub rarg: ::core::option::Option>, +} +#[derive(Clone, PartialEq)] +pub struct AlterTableStmt { + pub relation: ::core::option::Option, + + pub cmds: Vec, + + pub relkind: i32, + + pub missing_ok: bool, +} +#[derive(Clone, PartialEq)] +pub struct AlterTableCmd { + pub subtype: i32, + + pub name: String, + + pub num: i32, + + pub newowner: ::core::option::Option, + + pub def: ::core::option::Option>, + + pub behavior: i32, + + pub missing_ok: bool, +} +#[derive(Clone, PartialEq)] +pub struct AlterDomainStmt { + pub subtype: String, + + pub type_name: Vec, + + pub name: String, + + pub def: ::core::option::Option>, + + pub behavior: i32, + + pub missing_ok: bool, +} +#[derive(Clone, PartialEq)] +pub struct SetOperationStmt { + pub op: i32, + + pub all: bool, + + pub larg: ::core::option::Option>, + + pub rarg: ::core::option::Option>, + + pub col_types: Vec, + + pub col_typmods: Vec, + + pub col_collations: Vec, + + pub group_clauses: Vec, +} +#[derive(Clone, PartialEq)] +pub struct GrantStmt { + pub is_grant: bool, + + pub targtype: i32, + + pub objtype: i32, + + pub objects: Vec, + + pub privileges: Vec, + + pub grantees: Vec, + + pub grant_option: bool, + + pub behavior: i32, +} +#[derive(Clone, PartialEq)] +pub struct GrantRoleStmt { + pub granted_roles: Vec, + + pub grantee_roles: Vec, + + pub is_grant: bool, + + pub admin_opt: bool, + + pub grantor: ::core::option::Option, + + pub behavior: i32, +} +#[derive(Clone, PartialEq)] +pub struct AlterDefaultPrivilegesStmt { + pub options: Vec, + + pub action: ::core::option::Option, +} +#[derive(Clone, PartialEq)] +pub struct ClosePortalStmt { + pub portalname: String, +} +#[derive(Clone, PartialEq)] +pub struct ClusterStmt { + pub relation: ::core::option::Option, + + pub indexname: String, + + pub options: i32, +} +#[derive(Clone, PartialEq)] +pub struct CopyStmt { + pub relation: ::core::option::Option, + + pub query: ::core::option::Option>, + + pub attlist: Vec, + + pub is_from: bool, + + pub is_program: bool, + + pub filename: String, + + pub options: Vec, + + pub where_clause: ::core::option::Option>, +} +#[derive(Clone, PartialEq)] +pub struct CreateStmt { + pub relation: ::core::option::Option, + + pub table_elts: Vec, + + pub inh_relations: Vec, + + pub partbound: ::core::option::Option, + + pub partspec: ::core::option::Option, + + pub of_typename: ::core::option::Option, + + pub constraints: Vec, + + pub options: Vec, + + pub oncommit: i32, + + pub tablespacename: String, + + pub access_method: String, + + pub if_not_exists: bool, +} +#[derive(Clone, PartialEq)] +pub struct DefineStmt { + pub kind: i32, + + pub oldstyle: bool, + + pub defnames: Vec, + + pub args: Vec, + + pub definition: Vec, + + pub if_not_exists: bool, + + pub replace: bool, +} +#[derive(Clone, PartialEq)] +pub struct DropStmt { + pub objects: Vec, + + pub remove_type: i32, + + pub behavior: i32, + + pub missing_ok: bool, + + pub concurrent: bool, +} +#[derive(Clone, PartialEq)] +pub struct TruncateStmt { + pub relations: Vec, + + pub restart_seqs: bool, + + pub behavior: i32, +} +#[derive(Clone, PartialEq)] +pub struct CommentStmt { + pub objtype: i32, + + pub object: ::core::option::Option>, + + pub comment: String, +} +#[derive(Clone, PartialEq)] +pub struct FetchStmt { + pub direction: i32, + + pub how_many: i64, + + pub portalname: String, + + pub ismove: bool, +} +#[derive(Clone, PartialEq)] +pub struct IndexStmt { + pub idxname: String, + + pub relation: ::core::option::Option, + + pub access_method: String, + + pub table_space: String, + + pub index_params: Vec, + + pub index_including_params: Vec, + + pub options: Vec, + + pub where_clause: ::core::option::Option>, + + pub exclude_op_names: Vec, + + pub idxcomment: String, + + pub index_oid: u32, + + pub old_node: u32, + + pub old_create_subid: u32, + + pub old_first_relfilenode_subid: u32, + + pub unique: bool, + + pub primary: bool, + + pub isconstraint: bool, + + pub deferrable: bool, + + pub initdeferred: bool, + + pub transformed: bool, + + pub concurrent: bool, + + pub if_not_exists: bool, + + pub reset_default_tblspc: bool, +} +#[derive(Clone, PartialEq)] +pub struct CreateFunctionStmt { + pub is_procedure: bool, + + pub replace: bool, + + pub funcname: Vec, + + pub parameters: Vec, + + pub return_type: ::core::option::Option, + + pub options: Vec, +} +#[derive(Clone, PartialEq)] +pub struct AlterFunctionStmt { + pub objtype: i32, + + pub func: ::core::option::Option, + + pub actions: Vec, +} +#[derive(Clone, PartialEq)] +pub struct DoStmt { + pub args: Vec, +} +#[derive(Clone, PartialEq)] +pub struct RenameStmt { + pub rename_type: i32, + + pub relation_type: i32, + + pub relation: ::core::option::Option, + + pub object: ::core::option::Option>, + + pub subname: String, + + pub newname: String, + + pub behavior: i32, + + pub missing_ok: bool, +} +#[derive(Clone, PartialEq)] +pub struct RuleStmt { + pub relation: ::core::option::Option, + + pub rulename: String, + + pub where_clause: ::core::option::Option>, + + pub event: i32, + + pub instead: bool, + + pub actions: Vec, + + pub replace: bool, +} +#[derive(Clone, PartialEq)] +pub struct NotifyStmt { + pub conditionname: String, + + pub payload: String, +} +#[derive(Clone, PartialEq)] +pub struct ListenStmt { + pub conditionname: String, +} +#[derive(Clone, PartialEq)] +pub struct UnlistenStmt { + pub conditionname: String, +} +#[derive(Clone, PartialEq)] +pub struct TransactionStmt { + pub kind: i32, + + pub options: Vec, + + pub savepoint_name: String, + + pub gid: String, + + pub chain: bool, +} +#[derive(Clone, PartialEq)] +pub struct ViewStmt { + pub view: ::core::option::Option, + + pub aliases: Vec, + + pub query: ::core::option::Option>, + + pub replace: bool, + + pub options: Vec, + + pub with_check_option: i32, +} +#[derive(Clone, PartialEq)] +pub struct LoadStmt { + pub filename: String, +} +#[derive(Clone, PartialEq)] +pub struct CreateDomainStmt { + pub domainname: Vec, + + pub type_name: ::core::option::Option, + + pub coll_clause: ::core::option::Option>, + + pub constraints: Vec, +} +#[derive(Clone, PartialEq)] +pub struct CreatedbStmt { + pub dbname: String, + + pub options: Vec, +} +#[derive(Clone, PartialEq)] +pub struct DropdbStmt { + pub dbname: String, + + pub missing_ok: bool, + + pub options: Vec, +} +#[derive(Clone, PartialEq)] +pub struct VacuumStmt { + pub options: Vec, + + pub rels: Vec, + + pub is_vacuumcmd: bool, +} +#[derive(Clone, PartialEq)] +pub struct ExplainStmt { + pub query: ::core::option::Option>, + + pub options: Vec, +} +#[derive(Clone, PartialEq)] +pub struct CreateTableAsStmt { + pub query: ::core::option::Option>, + + pub into: ::core::option::Option>, + + pub relkind: i32, + + pub is_select_into: bool, + + pub if_not_exists: bool, +} +#[derive(Clone, PartialEq)] +pub struct CreateSeqStmt { + pub sequence: ::core::option::Option, + + pub options: Vec, + + pub owner_id: u32, + + pub for_identity: bool, + + pub if_not_exists: bool, +} +#[derive(Clone, PartialEq)] +pub struct AlterSeqStmt { + pub sequence: ::core::option::Option, + + pub options: Vec, + + pub for_identity: bool, + + pub missing_ok: bool, +} +#[derive(Clone, PartialEq)] +pub struct VariableSetStmt { + pub kind: i32, + + pub name: String, + + pub args: Vec, + + pub is_local: bool, +} +#[derive(Clone, PartialEq)] +pub struct VariableShowStmt { + pub name: String, +} +#[derive(Clone, PartialEq)] +pub struct DiscardStmt { + pub target: i32, +} +#[derive(Clone, PartialEq)] +pub struct CreateTrigStmt { + pub trigname: String, + + pub relation: ::core::option::Option, + + pub funcname: Vec, + + pub args: Vec, + + pub row: bool, + + pub timing: i32, + + pub events: i32, + + pub columns: Vec, + + pub when_clause: ::core::option::Option>, + + pub isconstraint: bool, + + pub transition_rels: Vec, + + pub deferrable: bool, + + pub initdeferred: bool, + + pub constrrel: ::core::option::Option, +} +#[derive(Clone, PartialEq)] +pub struct CreatePLangStmt { + pub replace: bool, + + pub plname: String, + + pub plhandler: Vec, + + pub plinline: Vec, + + pub plvalidator: Vec, + + pub pltrusted: bool, +} +#[derive(Clone, PartialEq)] +pub struct CreateRoleStmt { + pub stmt_type: i32, + + pub role: String, + + pub options: Vec, +} +#[derive(Clone, PartialEq)] +pub struct AlterRoleStmt { + pub role: ::core::option::Option, + + pub options: Vec, + + pub action: i32, +} +#[derive(Clone, PartialEq)] +pub struct DropRoleStmt { + pub roles: Vec, + + pub missing_ok: bool, +} +#[derive(Clone, PartialEq)] +pub struct LockStmt { + pub relations: Vec, + + pub mode: i32, + + pub nowait: bool, +} +#[derive(Clone, PartialEq)] +pub struct ConstraintsSetStmt { + pub constraints: Vec, + + pub deferred: bool, +} +#[derive(Clone, PartialEq)] +pub struct ReindexStmt { + pub kind: i32, + + pub relation: ::core::option::Option, + + pub name: String, + + pub options: i32, + + pub concurrent: bool, +} +#[derive(Clone, PartialEq)] +pub struct CheckPointStmt {} +#[derive(Clone, PartialEq)] +pub struct CreateSchemaStmt { + pub schemaname: String, + + pub authrole: ::core::option::Option, + + pub schema_elts: Vec, + + pub if_not_exists: bool, +} +#[derive(Clone, PartialEq)] +pub struct AlterDatabaseStmt { + pub dbname: String, + + pub options: Vec, +} +#[derive(Clone, PartialEq)] +pub struct AlterDatabaseSetStmt { + pub dbname: String, + + pub setstmt: ::core::option::Option, +} +#[derive(Clone, PartialEq)] +pub struct AlterRoleSetStmt { + pub role: ::core::option::Option, + + pub database: String, + + pub setstmt: ::core::option::Option, +} +#[derive(Clone, PartialEq)] +pub struct CreateConversionStmt { + pub conversion_name: Vec, + + pub for_encoding_name: String, + + pub to_encoding_name: String, + + pub func_name: Vec, + + pub def: bool, +} +#[derive(Clone, PartialEq)] +pub struct CreateCastStmt { + pub sourcetype: ::core::option::Option, + + pub targettype: ::core::option::Option, + + pub func: ::core::option::Option, + + pub context: i32, + + pub inout: bool, +} +#[derive(Clone, PartialEq)] +pub struct CreateOpClassStmt { + pub opclassname: Vec, + + pub opfamilyname: Vec, + + pub amname: String, + + pub datatype: ::core::option::Option, + + pub items: Vec, + + pub is_default: bool, +} +#[derive(Clone, PartialEq)] +pub struct CreateOpFamilyStmt { + pub opfamilyname: Vec, + + pub amname: String, +} +#[derive(Clone, PartialEq)] +pub struct AlterOpFamilyStmt { + pub opfamilyname: Vec, + + pub amname: String, + + pub is_drop: bool, + + pub items: Vec, +} +#[derive(Clone, PartialEq)] +pub struct PrepareStmt { + pub name: String, + + pub argtypes: Vec, + + pub query: ::core::option::Option>, +} +#[derive(Clone, PartialEq)] +pub struct ExecuteStmt { + pub name: String, + + pub params: Vec, +} +#[derive(Clone, PartialEq)] +pub struct DeallocateStmt { + pub name: String, +} +#[derive(Clone, PartialEq)] +pub struct DeclareCursorStmt { + pub portalname: String, + + pub options: i32, + + pub query: ::core::option::Option>, +} +#[derive(Clone, PartialEq)] +pub struct CreateTableSpaceStmt { + pub tablespacename: String, + + pub owner: ::core::option::Option, + + pub location: String, + + pub options: Vec, +} +#[derive(Clone, PartialEq)] +pub struct DropTableSpaceStmt { + pub tablespacename: String, + + pub missing_ok: bool, +} +#[derive(Clone, PartialEq)] +pub struct AlterObjectDependsStmt { + pub object_type: i32, + + pub relation: ::core::option::Option, + + pub object: ::core::option::Option>, + + pub extname: ::core::option::Option>, + + pub remove: bool, +} +#[derive(Clone, PartialEq)] +pub struct AlterObjectSchemaStmt { + pub object_type: i32, + + pub relation: ::core::option::Option, + + pub object: ::core::option::Option>, + + pub newschema: String, + + pub missing_ok: bool, +} +#[derive(Clone, PartialEq)] +pub struct AlterOwnerStmt { + pub object_type: i32, + + pub relation: ::core::option::Option, + + pub object: ::core::option::Option>, + + pub newowner: ::core::option::Option, +} +#[derive(Clone, PartialEq)] +pub struct AlterOperatorStmt { + pub opername: ::core::option::Option, + + pub options: Vec, +} +#[derive(Clone, PartialEq)] +pub struct AlterTypeStmt { + pub type_name: Vec, + + pub options: Vec, +} +#[derive(Clone, PartialEq)] +pub struct DropOwnedStmt { + pub roles: Vec, + + pub behavior: i32, +} +#[derive(Clone, PartialEq)] +pub struct ReassignOwnedStmt { + pub roles: Vec, + + pub newrole: ::core::option::Option, +} +#[derive(Clone, PartialEq)] +pub struct CompositeTypeStmt { + pub typevar: ::core::option::Option, + + pub coldeflist: Vec, +} +#[derive(Clone, PartialEq)] +pub struct CreateEnumStmt { + pub type_name: Vec, + + pub vals: Vec, +} +#[derive(Clone, PartialEq)] +pub struct CreateRangeStmt { + pub type_name: Vec, + + pub params: Vec, +} +#[derive(Clone, PartialEq)] +pub struct AlterEnumStmt { + pub type_name: Vec, + + pub old_val: String, + + pub new_val: String, + + pub new_val_neighbor: String, + + pub new_val_is_after: bool, + + pub skip_if_new_val_exists: bool, +} +#[derive(Clone, PartialEq)] +pub struct AlterTsDictionaryStmt { + pub dictname: Vec, + + pub options: Vec, +} +#[derive(Clone, PartialEq)] +pub struct AlterTsConfigurationStmt { + pub kind: i32, + + pub cfgname: Vec, + + pub tokentype: Vec, + + pub dicts: Vec, + + pub r#override: bool, + + pub replace: bool, + + pub missing_ok: bool, +} +#[derive(Clone, PartialEq)] +pub struct CreateFdwStmt { + pub fdwname: String, + + pub func_options: Vec, + + pub options: Vec, +} +#[derive(Clone, PartialEq)] +pub struct AlterFdwStmt { + pub fdwname: String, + + pub func_options: Vec, + + pub options: Vec, +} +#[derive(Clone, PartialEq)] +pub struct CreateForeignServerStmt { + pub servername: String, + + pub servertype: String, + + pub version: String, + + pub fdwname: String, + + pub if_not_exists: bool, + + pub options: Vec, +} +#[derive(Clone, PartialEq)] +pub struct AlterForeignServerStmt { + pub servername: String, + + pub version: String, + + pub options: Vec, + + pub has_version: bool, +} +#[derive(Clone, PartialEq)] +pub struct CreateUserMappingStmt { + pub user: ::core::option::Option, + + pub servername: String, + + pub if_not_exists: bool, + + pub options: Vec, +} +#[derive(Clone, PartialEq)] +pub struct AlterUserMappingStmt { + pub user: ::core::option::Option, + + pub servername: String, + + pub options: Vec, +} +#[derive(Clone, PartialEq)] +pub struct DropUserMappingStmt { + pub user: ::core::option::Option, + + pub servername: String, + + pub missing_ok: bool, +} +#[derive(Clone, PartialEq)] +pub struct AlterTableSpaceOptionsStmt { + pub tablespacename: String, + + pub options: Vec, + + pub is_reset: bool, +} +#[derive(Clone, PartialEq)] +pub struct AlterTableMoveAllStmt { + pub orig_tablespacename: String, + + pub objtype: i32, + + pub roles: Vec, + + pub new_tablespacename: String, + + pub nowait: bool, +} +#[derive(Clone, PartialEq)] +pub struct SecLabelStmt { + pub objtype: i32, + + pub object: ::core::option::Option>, + + pub provider: String, + + pub label: String, +} +#[derive(Clone, PartialEq)] +pub struct CreateForeignTableStmt { + pub base_stmt: ::core::option::Option, + + pub servername: String, + + pub options: Vec, +} +#[derive(Clone, PartialEq)] +pub struct ImportForeignSchemaStmt { + pub server_name: String, + + pub remote_schema: String, + + pub local_schema: String, + + pub list_type: i32, + + pub table_list: Vec, + + pub options: Vec, +} +#[derive(Clone, PartialEq)] +pub struct CreateExtensionStmt { + pub extname: String, + + pub if_not_exists: bool, + + pub options: Vec, +} +#[derive(Clone, PartialEq)] +pub struct AlterExtensionStmt { + pub extname: String, + + pub options: Vec, +} +#[derive(Clone, PartialEq)] +pub struct AlterExtensionContentsStmt { + pub extname: String, + + pub action: i32, + + pub objtype: i32, + + pub object: ::core::option::Option>, +} +#[derive(Clone, PartialEq)] +pub struct CreateEventTrigStmt { + pub trigname: String, + + pub eventname: String, + + pub whenclause: Vec, + + pub funcname: Vec, +} +#[derive(Clone, PartialEq)] +pub struct AlterEventTrigStmt { + pub trigname: String, + + pub tgenabled: String, +} +#[derive(Clone, PartialEq)] +pub struct RefreshMatViewStmt { + pub concurrent: bool, + + pub skip_data: bool, + + pub relation: ::core::option::Option, +} +#[derive(Clone, PartialEq)] +pub struct ReplicaIdentityStmt { + pub identity_type: String, + + pub name: String, +} +#[derive(Clone, PartialEq)] +pub struct AlterSystemStmt { + pub setstmt: ::core::option::Option, +} +#[derive(Clone, PartialEq)] +pub struct CreatePolicyStmt { + pub policy_name: String, + + pub table: ::core::option::Option, + + pub cmd_name: String, + + pub permissive: bool, + + pub roles: Vec, + + pub qual: ::core::option::Option>, + + pub with_check: ::core::option::Option>, +} +#[derive(Clone, PartialEq)] +pub struct AlterPolicyStmt { + pub policy_name: String, + + pub table: ::core::option::Option, + + pub roles: Vec, + + pub qual: ::core::option::Option>, + + pub with_check: ::core::option::Option>, +} +#[derive(Clone, PartialEq)] +pub struct CreateTransformStmt { + pub replace: bool, + + pub type_name: ::core::option::Option, + + pub lang: String, + + pub fromsql: ::core::option::Option, + + pub tosql: ::core::option::Option, +} +#[derive(Clone, PartialEq)] +pub struct CreateAmStmt { + pub amname: String, + + pub handler_name: Vec, + + pub amtype: String, +} +#[derive(Clone, PartialEq)] +pub struct CreatePublicationStmt { + pub pubname: String, + + pub options: Vec, + + pub tables: Vec, + + pub for_all_tables: bool, +} +#[derive(Clone, PartialEq)] +pub struct AlterPublicationStmt { + pub pubname: String, + + pub options: Vec, + + pub tables: Vec, + + pub for_all_tables: bool, + + pub table_action: i32, +} +#[derive(Clone, PartialEq)] +pub struct CreateSubscriptionStmt { + pub subname: String, + + pub conninfo: String, + + pub publication: Vec, + + pub options: Vec, +} +#[derive(Clone, PartialEq)] +pub struct AlterSubscriptionStmt { + pub kind: i32, + + pub subname: String, + + pub conninfo: String, + + pub publication: Vec, + + pub options: Vec, +} +#[derive(Clone, PartialEq)] +pub struct DropSubscriptionStmt { + pub subname: String, + + pub missing_ok: bool, + + pub behavior: i32, +} +#[derive(Clone, PartialEq)] +pub struct CreateStatsStmt { + pub defnames: Vec, + + pub stat_types: Vec, + + pub exprs: Vec, + + pub relations: Vec, + + pub stxcomment: String, + + pub if_not_exists: bool, +} +#[derive(Clone, PartialEq)] +pub struct AlterCollationStmt { + pub collname: Vec, +} +#[derive(Clone, PartialEq)] +pub struct CallStmt { + pub funccall: ::core::option::Option>, + + pub funcexpr: ::core::option::Option>, +} +#[derive(Clone, PartialEq)] +pub struct AlterStatsStmt { + pub defnames: Vec, + + pub stxstattarget: i32, + + pub missing_ok: bool, +} +#[derive(Clone, PartialEq)] +pub struct AExpr { + pub kind: i32, + + pub name: Vec, + + pub lexpr: ::core::option::Option>, + + pub rexpr: ::core::option::Option>, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct ColumnRef { + pub fields: Vec, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct ParamRef { + pub number: i32, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct AConst { + pub val: ::core::option::Option>, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct FuncCall { + pub funcname: Vec, + + pub args: Vec, + + pub agg_order: Vec, + + pub agg_filter: ::core::option::Option>, + + pub agg_within_group: bool, + + pub agg_star: bool, + + pub agg_distinct: bool, + + pub func_variadic: bool, + + pub over: ::core::option::Option>, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct AStar {} +#[derive(Clone, PartialEq)] +pub struct AIndices { + pub is_slice: bool, + + pub lidx: ::core::option::Option>, + + pub uidx: ::core::option::Option>, +} +#[derive(Clone, PartialEq)] +pub struct AIndirection { + pub arg: ::core::option::Option>, + + pub indirection: Vec, +} +#[derive(Clone, PartialEq)] +pub struct AArrayExpr { + pub elements: Vec, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct ResTarget { + pub name: String, + + pub indirection: Vec, + + pub val: ::core::option::Option>, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct MultiAssignRef { + pub source: ::core::option::Option>, + + pub colno: i32, + + pub ncolumns: i32, +} +#[derive(Clone, PartialEq)] +pub struct TypeCast { + pub arg: ::core::option::Option>, + + pub type_name: ::core::option::Option, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct CollateClause { + pub arg: ::core::option::Option>, + + pub collname: Vec, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct SortBy { + pub node: ::core::option::Option>, + + pub sortby_dir: i32, + + pub sortby_nulls: i32, + + pub use_op: Vec, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct WindowDef { + pub name: String, + + pub refname: String, + + pub partition_clause: Vec, + + pub order_clause: Vec, + + pub frame_options: i32, + + pub start_offset: ::core::option::Option>, + + pub end_offset: ::core::option::Option>, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct RangeSubselect { + pub lateral: bool, + + pub subquery: ::core::option::Option>, + + pub alias: ::core::option::Option, +} +#[derive(Clone, PartialEq)] +pub struct RangeFunction { + pub lateral: bool, + + pub ordinality: bool, + + pub is_rowsfrom: bool, + + pub functions: Vec, + + pub alias: ::core::option::Option, + + pub coldeflist: Vec, +} +#[derive(Clone, PartialEq)] +pub struct RangeTableSample { + pub relation: ::core::option::Option>, + + pub method: Vec, + + pub args: Vec, + + pub repeatable: ::core::option::Option>, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct RangeTableFunc { + pub lateral: bool, + + pub docexpr: ::core::option::Option>, + + pub rowexpr: ::core::option::Option>, + + pub namespaces: Vec, + + pub columns: Vec, + + pub alias: ::core::option::Option, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct RangeTableFuncCol { + pub colname: String, + + pub type_name: ::core::option::Option, + + pub for_ordinality: bool, + + pub is_not_null: bool, + + pub colexpr: ::core::option::Option>, + + pub coldefexpr: ::core::option::Option>, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct TypeName { + pub names: Vec, + + pub type_oid: u32, + + pub setof: bool, + + pub pct_type: bool, + + pub typmods: Vec, + + pub typemod: i32, + + pub array_bounds: Vec, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct ColumnDef { + pub colname: String, + + pub type_name: ::core::option::Option, + + pub inhcount: i32, + + pub is_local: bool, + + pub is_not_null: bool, + + pub is_from_type: bool, + + pub storage: String, + + pub raw_default: ::core::option::Option>, + + pub cooked_default: ::core::option::Option>, + + pub identity: String, + + pub identity_sequence: ::core::option::Option, + + pub generated: String, + + pub coll_clause: ::core::option::Option>, + + pub coll_oid: u32, + + pub constraints: Vec, + + pub fdwoptions: Vec, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct IndexElem { + pub name: String, + + pub expr: ::core::option::Option>, + + pub indexcolname: String, + + pub collation: Vec, + + pub opclass: Vec, + + pub opclassopts: Vec, + + pub ordering: i32, + + pub nulls_ordering: i32, +} +#[derive(Clone, PartialEq)] +pub struct Constraint { + pub contype: i32, + + pub conname: String, + + pub deferrable: bool, + + pub initdeferred: bool, + + pub location: i32, + + pub is_no_inherit: bool, + + pub raw_expr: ::core::option::Option>, + + pub cooked_expr: String, + + pub generated_when: String, + + pub keys: Vec, + + pub including: Vec, + + pub exclusions: Vec, + + pub options: Vec, + + pub indexname: String, + + pub indexspace: String, + + pub reset_default_tblspc: bool, + + pub access_method: String, + + pub where_clause: ::core::option::Option>, + + pub pktable: ::core::option::Option, + + pub fk_attrs: Vec, + + pub pk_attrs: Vec, + + pub fk_matchtype: String, + + pub fk_upd_action: String, + + pub fk_del_action: String, + + pub old_conpfeqop: Vec, + + pub old_pktable_oid: u32, + + pub skip_validation: bool, + + pub initially_valid: bool, +} +#[derive(Clone, PartialEq)] +pub struct DefElem { + pub defnamespace: String, + + pub defname: String, + + pub arg: ::core::option::Option>, + + pub defaction: i32, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct RangeTblEntry { + pub rtekind: i32, + + pub relid: u32, + + pub relkind: String, + + pub rellockmode: i32, + + pub tablesample: ::core::option::Option>, + + pub subquery: ::core::option::Option>, + + pub security_barrier: bool, + + pub jointype: i32, + + pub joinmergedcols: i32, + + pub joinaliasvars: Vec, + + pub joinleftcols: Vec, + + pub joinrightcols: Vec, + + pub functions: Vec, + + pub funcordinality: bool, + + pub tablefunc: ::core::option::Option>, + + pub values_lists: Vec, + + pub ctename: String, + + pub ctelevelsup: u32, + + pub self_reference: bool, + + pub coltypes: Vec, + + pub coltypmods: Vec, + + pub colcollations: Vec, + + pub enrname: String, + + pub enrtuples: f64, + + pub alias: ::core::option::Option, + + pub eref: ::core::option::Option, + + pub lateral: bool, + + pub inh: bool, + + pub in_from_cl: bool, + + pub required_perms: u32, + + pub check_as_user: u32, + + pub selected_cols: Vec, + + pub inserted_cols: Vec, + + pub updated_cols: Vec, + + pub extra_updated_cols: Vec, + + pub security_quals: Vec, +} +#[derive(Clone, PartialEq)] +pub struct RangeTblFunction { + pub funcexpr: ::core::option::Option>, + + pub funccolcount: i32, + + pub funccolnames: Vec, + + pub funccoltypes: Vec, + + pub funccoltypmods: Vec, + + pub funccolcollations: Vec, + + pub funcparams: Vec, +} +#[derive(Clone, PartialEq)] +pub struct TableSampleClause { + pub tsmhandler: u32, + + pub args: Vec, + + pub repeatable: ::core::option::Option>, +} +#[derive(Clone, PartialEq)] +pub struct WithCheckOption { + pub kind: i32, + + pub relname: String, + + pub polname: String, + + pub qual: ::core::option::Option>, + + pub cascaded: bool, +} +#[derive(Clone, PartialEq)] +pub struct SortGroupClause { + pub tle_sort_group_ref: u32, + + pub eqop: u32, + + pub sortop: u32, + + pub nulls_first: bool, + + pub hashable: bool, +} +#[derive(Clone, PartialEq)] +pub struct GroupingSet { + pub kind: i32, + + pub content: Vec, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct WindowClause { + pub name: String, + + pub refname: String, + + pub partition_clause: Vec, + + pub order_clause: Vec, + + pub frame_options: i32, + + pub start_offset: ::core::option::Option>, + + pub end_offset: ::core::option::Option>, + + pub start_in_range_func: u32, + + pub end_in_range_func: u32, + + pub in_range_coll: u32, + + pub in_range_asc: bool, + + pub in_range_nulls_first: bool, + + pub winref: u32, + + pub copied_order: bool, +} +#[derive(Clone, PartialEq)] +pub struct ObjectWithArgs { + pub objname: Vec, + + pub objargs: Vec, + + pub args_unspecified: bool, +} +#[derive(Clone, PartialEq)] +pub struct AccessPriv { + pub priv_name: String, + + pub cols: Vec, +} +#[derive(Clone, PartialEq)] +pub struct CreateOpClassItem { + pub itemtype: i32, + + pub name: ::core::option::Option, + + pub number: i32, + + pub order_family: Vec, + + pub class_args: Vec, + + pub storedtype: ::core::option::Option, +} +#[derive(Clone, PartialEq)] +pub struct TableLikeClause { + pub relation: ::core::option::Option, + + pub options: u32, + + pub relation_oid: u32, +} +#[derive(Clone, PartialEq)] +pub struct FunctionParameter { + pub name: String, + + pub arg_type: ::core::option::Option, + + pub mode: i32, + + pub defexpr: ::core::option::Option>, +} +#[derive(Clone, PartialEq)] +pub struct LockingClause { + pub locked_rels: Vec, + + pub strength: i32, + + pub wait_policy: i32, +} +#[derive(Clone, PartialEq)] +pub struct RowMarkClause { + pub rti: u32, + + pub strength: i32, + + pub wait_policy: i32, + + pub pushed_down: bool, +} +#[derive(Clone, PartialEq)] +pub struct XmlSerialize { + pub xmloption: i32, + + pub expr: ::core::option::Option>, + + pub type_name: ::core::option::Option, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct WithClause { + pub ctes: Vec, + + pub recursive: bool, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct InferClause { + pub index_elems: Vec, + + pub where_clause: ::core::option::Option>, + + pub conname: String, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct OnConflictClause { + pub action: i32, + + pub infer: ::core::option::Option>, + + pub target_list: Vec, + + pub where_clause: ::core::option::Option>, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct CommonTableExpr { + pub ctename: String, + + pub aliascolnames: Vec, + + pub ctematerialized: i32, + + pub ctequery: ::core::option::Option>, + + pub location: i32, + + pub cterecursive: bool, + + pub cterefcount: i32, + + pub ctecolnames: Vec, + + pub ctecoltypes: Vec, + + pub ctecoltypmods: Vec, + + pub ctecolcollations: Vec, +} +#[derive(Clone, PartialEq)] +pub struct RoleSpec { + pub roletype: i32, + + pub rolename: String, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct TriggerTransition { + pub name: String, + + pub is_new: bool, + + pub is_table: bool, +} +#[derive(Clone, PartialEq)] +pub struct PartitionElem { + pub name: String, + + pub expr: ::core::option::Option>, + + pub collation: Vec, + + pub opclass: Vec, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct PartitionSpec { + pub strategy: String, + + pub part_params: Vec, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct PartitionBoundSpec { + pub strategy: String, + + pub is_default: bool, + + pub modulus: i32, + + pub remainder: i32, + + pub listdatums: Vec, + + pub lowerdatums: Vec, + + pub upperdatums: Vec, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct PartitionRangeDatum { + pub kind: i32, + + pub value: ::core::option::Option>, + + pub location: i32, +} +#[derive(Clone, PartialEq)] +pub struct PartitionCmd { + pub name: ::core::option::Option, + + pub bound: ::core::option::Option, +} +#[derive(Clone, PartialEq)] +pub struct VacuumRelation { + pub relation: ::core::option::Option, + + pub oid: u32, + + pub va_cols: Vec, +} +#[derive(Clone, PartialEq)] +pub struct InlineCodeBlock { + pub source_text: String, + + pub lang_oid: u32, + + pub lang_is_trusted: bool, + + pub atomic: bool, +} +#[derive(Clone, PartialEq)] +pub struct CallContext { + pub atomic: bool, +} +#[derive(Clone, PartialEq)] +pub struct ScanToken { + pub start: i32, + + pub end: i32, + + pub token: i32, + + pub keyword_kind: i32, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum OverridingKind { + Undefined = 0, + OverridingNotSet = 1, + OverridingUserValue = 2, + OverridingSystemValue = 3, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum QuerySource { + Undefined = 0, + QsrcOriginal = 1, + QsrcParser = 2, + QsrcInsteadRule = 3, + QsrcQualInsteadRule = 4, + QsrcNonInsteadRule = 5, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum SortByDir { + Undefined = 0, + SortbyDefault = 1, + SortbyAsc = 2, + SortbyDesc = 3, + SortbyUsing = 4, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum SortByNulls { + Undefined = 0, + SortbyNullsDefault = 1, + SortbyNullsFirst = 2, + SortbyNullsLast = 3, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum AExprKind { + Undefined = 0, + AexprOp = 1, + AexprOpAny = 2, + AexprOpAll = 3, + AexprDistinct = 4, + AexprNotDistinct = 5, + AexprNullif = 6, + AexprOf = 7, + AexprIn = 8, + AexprLike = 9, + AexprIlike = 10, + AexprSimilar = 11, + AexprBetween = 12, + AexprNotBetween = 13, + AexprBetweenSym = 14, + AexprNotBetweenSym = 15, + AexprParen = 16, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum RoleSpecType { + Undefined = 0, + RolespecCstring = 1, + RolespecCurrentUser = 2, + RolespecSessionUser = 3, + RolespecPublic = 4, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum TableLikeOption { + Undefined = 0, + CreateTableLikeComments = 1, + CreateTableLikeConstraints = 2, + CreateTableLikeDefaults = 3, + CreateTableLikeGenerated = 4, + CreateTableLikeIdentity = 5, + CreateTableLikeIndexes = 6, + CreateTableLikeStatistics = 7, + CreateTableLikeStorage = 8, + CreateTableLikeAll = 9, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum DefElemAction { + Undefined = 0, + DefelemUnspec = 1, + DefelemSet = 2, + DefelemAdd = 3, + DefelemDrop = 4, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum PartitionRangeDatumKind { + Undefined = 0, + PartitionRangeDatumMinvalue = 1, + PartitionRangeDatumValue = 2, + PartitionRangeDatumMaxvalue = 3, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum RteKind { + RtekindUndefined = 0, + RteRelation = 1, + RteSubquery = 2, + RteJoin = 3, + RteFunction = 4, + RteTablefunc = 5, + RteValues = 6, + RteCte = 7, + RteNamedtuplestore = 8, + RteResult = 9, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum WcoKind { + WcokindUndefined = 0, + WcoViewCheck = 1, + WcoRlsInsertCheck = 2, + WcoRlsUpdateCheck = 3, + WcoRlsConflictCheck = 4, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum GroupingSetKind { + Undefined = 0, + GroupingSetEmpty = 1, + GroupingSetSimple = 2, + GroupingSetRollup = 3, + GroupingSetCube = 4, + GroupingSetSets = 5, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum CteMaterialize { + CtematerializeUndefined = 0, + Default = 1, + Always = 2, + Never = 3, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum SetOperation { + Undefined = 0, + SetopNone = 1, + SetopUnion = 2, + SetopIntersect = 3, + SetopExcept = 4, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum ObjectType { + Undefined = 0, + ObjectAccessMethod = 1, + ObjectAggregate = 2, + ObjectAmop = 3, + ObjectAmproc = 4, + ObjectAttribute = 5, + ObjectCast = 6, + ObjectColumn = 7, + ObjectCollation = 8, + ObjectConversion = 9, + ObjectDatabase = 10, + ObjectDefault = 11, + ObjectDefacl = 12, + ObjectDomain = 13, + ObjectDomconstraint = 14, + ObjectEventTrigger = 15, + ObjectExtension = 16, + ObjectFdw = 17, + ObjectForeignServer = 18, + ObjectForeignTable = 19, + ObjectFunction = 20, + ObjectIndex = 21, + ObjectLanguage = 22, + ObjectLargeobject = 23, + ObjectMatview = 24, + ObjectOpclass = 25, + ObjectOperator = 26, + ObjectOpfamily = 27, + ObjectPolicy = 28, + ObjectProcedure = 29, + ObjectPublication = 30, + ObjectPublicationRel = 31, + ObjectRole = 32, + ObjectRoutine = 33, + ObjectRule = 34, + ObjectSchema = 35, + ObjectSequence = 36, + ObjectSubscription = 37, + ObjectStatisticExt = 38, + ObjectTabconstraint = 39, + ObjectTable = 40, + ObjectTablespace = 41, + ObjectTransform = 42, + ObjectTrigger = 43, + ObjectTsconfiguration = 44, + ObjectTsdictionary = 45, + ObjectTsparser = 46, + ObjectTstemplate = 47, + ObjectType = 48, + ObjectUserMapping = 49, + ObjectView = 50, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum DropBehavior { + Undefined = 0, + DropRestrict = 1, + DropCascade = 2, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum AlterTableType { + Undefined = 0, + AtAddColumn = 1, + AtAddColumnRecurse = 2, + AtAddColumnToView = 3, + AtColumnDefault = 4, + AtCookedColumnDefault = 5, + AtDropNotNull = 6, + AtSetNotNull = 7, + AtDropExpression = 8, + AtCheckNotNull = 9, + AtSetStatistics = 10, + AtSetOptions = 11, + AtResetOptions = 12, + AtSetStorage = 13, + AtDropColumn = 14, + AtDropColumnRecurse = 15, + AtAddIndex = 16, + AtReAddIndex = 17, + AtAddConstraint = 18, + AtAddConstraintRecurse = 19, + AtReAddConstraint = 20, + AtReAddDomainConstraint = 21, + AtAlterConstraint = 22, + AtValidateConstraint = 23, + AtValidateConstraintRecurse = 24, + AtAddIndexConstraint = 25, + AtDropConstraint = 26, + AtDropConstraintRecurse = 27, + AtReAddComment = 28, + AtAlterColumnType = 29, + AtAlterColumnGenericOptions = 30, + AtChangeOwner = 31, + AtClusterOn = 32, + AtDropCluster = 33, + AtSetLogged = 34, + AtSetUnLogged = 35, + AtDropOids = 36, + AtSetTableSpace = 37, + AtSetRelOptions = 38, + AtResetRelOptions = 39, + AtReplaceRelOptions = 40, + AtEnableTrig = 41, + AtEnableAlwaysTrig = 42, + AtEnableReplicaTrig = 43, + AtDisableTrig = 44, + AtEnableTrigAll = 45, + AtDisableTrigAll = 46, + AtEnableTrigUser = 47, + AtDisableTrigUser = 48, + AtEnableRule = 49, + AtEnableAlwaysRule = 50, + AtEnableReplicaRule = 51, + AtDisableRule = 52, + AtAddInherit = 53, + AtDropInherit = 54, + AtAddOf = 55, + AtDropOf = 56, + AtReplicaIdentity = 57, + AtEnableRowSecurity = 58, + AtDisableRowSecurity = 59, + AtForceRowSecurity = 60, + AtNoForceRowSecurity = 61, + AtGenericOptions = 62, + AtAttachPartition = 63, + AtDetachPartition = 64, + AtAddIdentity = 65, + AtSetIdentity = 66, + AtDropIdentity = 67, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum GrantTargetType { + Undefined = 0, + AclTargetObject = 1, + AclTargetAllInSchema = 2, + AclTargetDefaults = 3, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum VariableSetKind { + Undefined = 0, + VarSetValue = 1, + VarSetDefault = 2, + VarSetCurrent = 3, + VarSetMulti = 4, + VarReset = 5, + VarResetAll = 6, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum ConstrType { + Undefined = 0, + ConstrNull = 1, + ConstrNotnull = 2, + ConstrDefault = 3, + ConstrIdentity = 4, + ConstrGenerated = 5, + ConstrCheck = 6, + ConstrPrimary = 7, + ConstrUnique = 8, + ConstrExclusion = 9, + ConstrForeign = 10, + ConstrAttrDeferrable = 11, + ConstrAttrNotDeferrable = 12, + ConstrAttrDeferred = 13, + ConstrAttrImmediate = 14, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum ImportForeignSchemaType { + Undefined = 0, + FdwImportSchemaAll = 1, + FdwImportSchemaLimitTo = 2, + FdwImportSchemaExcept = 3, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum RoleStmtType { + Undefined = 0, + RolestmtRole = 1, + RolestmtUser = 2, + RolestmtGroup = 3, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum FetchDirection { + Undefined = 0, + FetchForward = 1, + FetchBackward = 2, + FetchAbsolute = 3, + FetchRelative = 4, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum FunctionParameterMode { + Undefined = 0, + FuncParamIn = 1, + FuncParamOut = 2, + FuncParamInout = 3, + FuncParamVariadic = 4, + FuncParamTable = 5, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum TransactionStmtKind { + Undefined = 0, + TransStmtBegin = 1, + TransStmtStart = 2, + TransStmtCommit = 3, + TransStmtRollback = 4, + TransStmtSavepoint = 5, + TransStmtRelease = 6, + TransStmtRollbackTo = 7, + TransStmtPrepare = 8, + TransStmtCommitPrepared = 9, + TransStmtRollbackPrepared = 10, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum ViewCheckOption { + Undefined = 0, + NoCheckOption = 1, + LocalCheckOption = 2, + CascadedCheckOption = 3, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum ClusterOption { + Undefined = 0, + CluoptRecheck = 1, + CluoptVerbose = 2, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum DiscardMode { + Undefined = 0, + DiscardAll = 1, + DiscardPlans = 2, + DiscardSequences = 3, + DiscardTemp = 4, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum ReindexObjectType { + Undefined = 0, + ReindexObjectIndex = 1, + ReindexObjectTable = 2, + ReindexObjectSchema = 3, + ReindexObjectSystem = 4, + ReindexObjectDatabase = 5, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum AlterTsConfigType { + AlterTsconfigTypeUndefined = 0, + AlterTsconfigAddMapping = 1, + AlterTsconfigAlterMappingForToken = 2, + AlterTsconfigReplaceDict = 3, + AlterTsconfigReplaceDictForToken = 4, + AlterTsconfigDropMapping = 5, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum AlterSubscriptionType { + Undefined = 0, + AlterSubscriptionOptions = 1, + AlterSubscriptionConnection = 2, + AlterSubscriptionPublication = 3, + AlterSubscriptionRefresh = 4, + AlterSubscriptionEnabled = 5, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum OnCommitAction { + Undefined = 0, + OncommitNoop = 1, + OncommitPreserveRows = 2, + OncommitDeleteRows = 3, + OncommitDrop = 4, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum ParamKind { + Undefined = 0, + ParamExtern = 1, + ParamExec = 2, + ParamSublink = 3, + ParamMultiexpr = 4, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum CoercionContext { + Undefined = 0, + CoercionImplicit = 1, + CoercionAssignment = 2, + CoercionExplicit = 3, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum CoercionForm { + Undefined = 0, + CoerceExplicitCall = 1, + CoerceExplicitCast = 2, + CoerceImplicitCast = 3, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum BoolExprType { + Undefined = 0, + AndExpr = 1, + OrExpr = 2, + NotExpr = 3, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum SubLinkType { + Undefined = 0, + ExistsSublink = 1, + AllSublink = 2, + AnySublink = 3, + RowcompareSublink = 4, + ExprSublink = 5, + MultiexprSublink = 6, + ArraySublink = 7, + CteSublink = 8, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum RowCompareType { + Undefined = 0, + RowcompareLt = 1, + RowcompareLe = 2, + RowcompareEq = 3, + RowcompareGe = 4, + RowcompareGt = 5, + RowcompareNe = 6, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum MinMaxOp { + Undefined = 0, + IsGreatest = 1, + IsLeast = 2, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum SqlValueFunctionOp { + SqlvalueFunctionOpUndefined = 0, + SvfopCurrentDate = 1, + SvfopCurrentTime = 2, + SvfopCurrentTimeN = 3, + SvfopCurrentTimestamp = 4, + SvfopCurrentTimestampN = 5, + SvfopLocaltime = 6, + SvfopLocaltimeN = 7, + SvfopLocaltimestamp = 8, + SvfopLocaltimestampN = 9, + SvfopCurrentRole = 10, + SvfopCurrentUser = 11, + SvfopUser = 12, + SvfopSessionUser = 13, + SvfopCurrentCatalog = 14, + SvfopCurrentSchema = 15, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum XmlExprOp { + Undefined = 0, + IsXmlconcat = 1, + IsXmlelement = 2, + IsXmlforest = 3, + IsXmlparse = 4, + IsXmlpi = 5, + IsXmlroot = 6, + IsXmlserialize = 7, + IsDocument = 8, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum XmlOptionType { + Undefined = 0, + XmloptionDocument = 1, + XmloptionContent = 2, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum NullTestType { + Undefined = 0, + IsNull = 1, + IsNotNull = 2, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum BoolTestType { + Undefined = 0, + IsTrue = 1, + IsNotTrue = 2, + IsFalse = 3, + IsNotFalse = 4, + IsUnknown = 5, + IsNotUnknown = 6, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum CmdType { + Undefined = 0, + CmdUnknown = 1, + CmdSelect = 2, + CmdUpdate = 3, + CmdInsert = 4, + CmdDelete = 5, + CmdUtility = 6, + CmdNothing = 7, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum JoinType { + Undefined = 0, + JoinInner = 1, + JoinLeft = 2, + JoinFull = 3, + JoinRight = 4, + JoinSemi = 5, + JoinAnti = 6, + JoinUniqueOuter = 7, + JoinUniqueInner = 8, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum AggStrategy { + Undefined = 0, + AggPlain = 1, + AggSorted = 2, + AggHashed = 3, + AggMixed = 4, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum AggSplit { + Undefined = 0, + AggsplitSimple = 1, + AggsplitInitialSerial = 2, + AggsplitFinalDeserial = 3, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum SetOpCmd { + Undefined = 0, + SetopcmdIntersect = 1, + SetopcmdIntersectAll = 2, + SetopcmdExcept = 3, + SetopcmdExceptAll = 4, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum SetOpStrategy { + Undefined = 0, + SetopSorted = 1, + SetopHashed = 2, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum OnConflictAction { + Undefined = 0, + OnconflictNone = 1, + OnconflictNothing = 2, + OnconflictUpdate = 3, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum LimitOption { + Undefined = 0, + Default = 1, + Count = 2, + WithTies = 3, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum LockClauseStrength { + Undefined = 0, + LcsNone = 1, + LcsForkeyshare = 2, + LcsForshare = 3, + LcsFornokeyupdate = 4, + LcsForupdate = 5, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum LockWaitPolicy { + Undefined = 0, + LockWaitBlock = 1, + LockWaitSkip = 2, + LockWaitError = 3, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum LockTupleMode { + Undefined = 0, + LockTupleKeyShare = 1, + LockTupleShare = 2, + LockTupleNoKeyExclusive = 3, + LockTupleExclusive = 4, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum KeywordKind { + NoKeyword = 0, + UnreservedKeyword = 1, + ColNameKeyword = 2, + TypeFuncNameKeyword = 3, + ReservedKeyword = 4, +} +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(i32)] +pub enum Token { + Nul = 0, + /// Single-character tokens that are returned 1:1 (identical with "self" list in scan.l) + /// Either supporting syntax, or single-character operators (some can be both) + /// Also see + /// + /// "%" + Ascii37 = 37, + /// "(" + Ascii40 = 40, + /// ")" + Ascii41 = 41, + /// "*" + Ascii42 = 42, + /// "+" + Ascii43 = 43, + /// "," + Ascii44 = 44, + /// "-" + Ascii45 = 45, + /// "." + Ascii46 = 46, + /// "/" + Ascii47 = 47, + /// ":" + Ascii58 = 58, + /// ";" + Ascii59 = 59, + /// "<" + Ascii60 = 60, + /// "=" + Ascii61 = 61, + /// ">" + Ascii62 = 62, + /// "?" + Ascii63 = 63, + /// "[" + Ascii91 = 91, + /// "\" + Ascii92 = 92, + /// "]" + Ascii93 = 93, + /// "^" + Ascii94 = 94, + /// Named tokens in scan.l + Ident = 258, + Uident = 259, + Fconst = 260, + Sconst = 261, + Usconst = 262, + Bconst = 263, + Xconst = 264, + Op = 265, + Iconst = 266, + Param = 267, + Typecast = 268, + DotDot = 269, + ColonEquals = 270, + EqualsGreater = 271, + LessEquals = 272, + GreaterEquals = 273, + NotEquals = 274, + SqlComment = 275, + CComment = 276, + AbortP = 277, + AbsoluteP = 278, + Access = 279, + Action = 280, + AddP = 281, + Admin = 282, + After = 283, + Aggregate = 284, + All = 285, + Also = 286, + Alter = 287, + Always = 288, + Analyse = 289, + Analyze = 290, + And = 291, + Any = 292, + Array = 293, + As = 294, + Asc = 295, + Assertion = 296, + Assignment = 297, + Asymmetric = 298, + At = 299, + Attach = 300, + Attribute = 301, + Authorization = 302, + Backward = 303, + Before = 304, + BeginP = 305, + Between = 306, + Bigint = 307, + Binary = 308, + Bit = 309, + BooleanP = 310, + Both = 311, + By = 312, + Cache = 313, + Call = 314, + Called = 315, + Cascade = 316, + Cascaded = 317, + Case = 318, + Cast = 319, + CatalogP = 320, + Chain = 321, + CharP = 322, + Character = 323, + Characteristics = 324, + Check = 325, + Checkpoint = 326, + Class = 327, + Close = 328, + Cluster = 329, + Coalesce = 330, + Collate = 331, + Collation = 332, + Column = 333, + Columns = 334, + Comment = 335, + Comments = 336, + Commit = 337, + Committed = 338, + Concurrently = 339, + Configuration = 340, + Conflict = 341, + Connection = 342, + Constraint = 343, + Constraints = 344, + ContentP = 345, + ContinueP = 346, + ConversionP = 347, + Copy = 348, + Cost = 349, + Create = 350, + Cross = 351, + Csv = 352, + Cube = 353, + CurrentP = 354, + CurrentCatalog = 355, + CurrentDate = 356, + CurrentRole = 357, + CurrentSchema = 358, + CurrentTime = 359, + CurrentTimestamp = 360, + CurrentUser = 361, + Cursor = 362, + Cycle = 363, + DataP = 364, + Database = 365, + DayP = 366, + Deallocate = 367, + Dec = 368, + DecimalP = 369, + Declare = 370, + Default = 371, + Defaults = 372, + Deferrable = 373, + Deferred = 374, + Definer = 375, + DeleteP = 376, + Delimiter = 377, + Delimiters = 378, + Depends = 379, + Desc = 380, + Detach = 381, + Dictionary = 382, + DisableP = 383, + Discard = 384, + Distinct = 385, + Do = 386, + DocumentP = 387, + DomainP = 388, + DoubleP = 389, + Drop = 390, + Each = 391, + Else = 392, + EnableP = 393, + Encoding = 394, + Encrypted = 395, + EndP = 396, + EnumP = 397, + Escape = 398, + Event = 399, + Except = 400, + Exclude = 401, + Excluding = 402, + Exclusive = 403, + Execute = 404, + Exists = 405, + Explain = 406, + Expression = 407, + Extension = 408, + External = 409, + Extract = 410, + FalseP = 411, + Family = 412, + Fetch = 413, + Filter = 414, + FirstP = 415, + FloatP = 416, + Following = 417, + For = 418, + Force = 419, + Foreign = 420, + Forward = 421, + Freeze = 422, + From = 423, + Full = 424, + Function = 425, + Functions = 426, + Generated = 427, + Global = 428, + Grant = 429, + Granted = 430, + Greatest = 431, + GroupP = 432, + Grouping = 433, + Groups = 434, + Handler = 435, + Having = 436, + HeaderP = 437, + Hold = 438, + HourP = 439, + IdentityP = 440, + IfP = 441, + Ilike = 442, + Immediate = 443, + Immutable = 444, + ImplicitP = 445, + ImportP = 446, + InP = 447, + Include = 448, + Including = 449, + Increment = 450, + Index = 451, + Indexes = 452, + Inherit = 453, + Inherits = 454, + Initially = 455, + InlineP = 456, + InnerP = 457, + Inout = 458, + InputP = 459, + Insensitive = 460, + Insert = 461, + Instead = 462, + IntP = 463, + Integer = 464, + Intersect = 465, + Interval = 466, + Into = 467, + Invoker = 468, + Is = 469, + Isnull = 470, + Isolation = 471, + Join = 472, + Key = 473, + Label = 474, + Language = 475, + LargeP = 476, + LastP = 477, + LateralP = 478, + Leading = 479, + Leakproof = 480, + Least = 481, + Left = 482, + Level = 483, + Like = 484, + Limit = 485, + Listen = 486, + Load = 487, + Local = 488, + Localtime = 489, + Localtimestamp = 490, + Location = 491, + LockP = 492, + Locked = 493, + Logged = 494, + Mapping = 495, + Match = 496, + Materialized = 497, + Maxvalue = 498, + Method = 499, + MinuteP = 500, + Minvalue = 501, + Mode = 502, + MonthP = 503, + Move = 504, + NameP = 505, + Names = 506, + National = 507, + Natural = 508, + Nchar = 509, + New = 510, + Next = 511, + Nfc = 512, + Nfd = 513, + Nfkc = 514, + Nfkd = 515, + No = 516, + None = 517, + Normalize = 518, + Normalized = 519, + Not = 520, + Nothing = 521, + Notify = 522, + Notnull = 523, + Nowait = 524, + NullP = 525, + Nullif = 526, + NullsP = 527, + Numeric = 528, + ObjectP = 529, + Of = 530, + Off = 531, + Offset = 532, + Oids = 533, + Old = 534, + On = 535, + Only = 536, + Operator = 537, + Option = 538, + Options = 539, + Or = 540, + Order = 541, + Ordinality = 542, + Others = 543, + OutP = 544, + OuterP = 545, + Over = 546, + Overlaps = 547, + Overlay = 548, + Overriding = 549, + Owned = 550, + Owner = 551, + Parallel = 552, + Parser = 553, + Partial = 554, + Partition = 555, + Passing = 556, + Password = 557, + Placing = 558, + Plans = 559, + Policy = 560, + Position = 561, + Preceding = 562, + Precision = 563, + Preserve = 564, + Prepare = 565, + Prepared = 566, + Primary = 567, + Prior = 568, + Privileges = 569, + Procedural = 570, + Procedure = 571, + Procedures = 572, + Program = 573, + Publication = 574, + Quote = 575, + Range = 576, + Read = 577, + Real = 578, + Reassign = 579, + Recheck = 580, + Recursive = 581, + Ref = 582, + References = 583, + Referencing = 584, + Refresh = 585, + Reindex = 586, + RelativeP = 587, + Release = 588, + Rename = 589, + Repeatable = 590, + Replace = 591, + Replica = 592, + Reset = 593, + Restart = 594, + Restrict = 595, + Returning = 596, + Returns = 597, + Revoke = 598, + Right = 599, + Role = 600, + Rollback = 601, + Rollup = 602, + Routine = 603, + Routines = 604, + Row = 605, + Rows = 606, + Rule = 607, + Savepoint = 608, + Schema = 609, + Schemas = 610, + Scroll = 611, + Search = 612, + SecondP = 613, + Security = 614, + Select = 615, + Sequence = 616, + Sequences = 617, + Serializable = 618, + Server = 619, + Session = 620, + SessionUser = 621, + Set = 622, + Sets = 623, + Setof = 624, + Share = 625, + Show = 626, + Similar = 627, + Simple = 628, + Skip = 629, + Smallint = 630, + Snapshot = 631, + Some = 632, + SqlP = 633, + Stable = 634, + StandaloneP = 635, + Start = 636, + Statement = 637, + Statistics = 638, + Stdin = 639, + Stdout = 640, + Storage = 641, + Stored = 642, + StrictP = 643, + StripP = 644, + Subscription = 645, + Substring = 646, + Support = 647, + Symmetric = 648, + Sysid = 649, + SystemP = 650, + Table = 651, + Tables = 652, + Tablesample = 653, + Tablespace = 654, + Temp = 655, + Template = 656, + Temporary = 657, + TextP = 658, + Then = 659, + Ties = 660, + Time = 661, + Timestamp = 662, + To = 663, + Trailing = 664, + Transaction = 665, + Transform = 666, + Treat = 667, + Trigger = 668, + Trim = 669, + TrueP = 670, + Truncate = 671, + Trusted = 672, + TypeP = 673, + TypesP = 674, + Uescape = 675, + Unbounded = 676, + Uncommitted = 677, + Unencrypted = 678, + Union = 679, + Unique = 680, + Unknown = 681, + Unlisten = 682, + Unlogged = 683, + Until = 684, + Update = 685, + User = 686, + Using = 687, + Vacuum = 688, + Valid = 689, + Validate = 690, + Validator = 691, + ValueP = 692, + Values = 693, + Varchar = 694, + Variadic = 695, + Varying = 696, + Verbose = 697, + VersionP = 698, + View = 699, + Views = 700, + Volatile = 701, + When = 702, + Where = 703, + WhitespaceP = 704, + Window = 705, + With = 706, + Within = 707, + Without = 708, + Work = 709, + Wrapper = 710, + Write = 711, + XmlP = 712, + Xmlattributes = 713, + Xmlconcat = 714, + Xmlelement = 715, + Xmlexists = 716, + Xmlforest = 717, + Xmlnamespaces = 718, + Xmlparse = 719, + Xmlpi = 720, + Xmlroot = 721, + Xmlserialize = 722, + Xmltable = 723, + YearP = 724, + YesP = 725, + Zone = 726, + NotLa = 727, + NullsLa = 728, + WithLa = 729, + Postfixop = 730, + Uminus = 731, +} From e08df2dd6b7c0470796ef8801635e60b8a21d34e Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 26 Apr 2022 15:21:15 +1000 Subject: [PATCH 18/53] Avoid producing `NoDelim` values in `MacArgs::delim()`. --- src/expr.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/expr.rs b/src/expr.rs index 4f333cd27cefe..cd724373f4d16 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -1325,7 +1325,7 @@ pub(crate) fn can_be_overflowed_expr( } ast::ExprKind::MacCall(ref mac) => { match ( - rustc_ast::ast::MacDelimiter::from_token(mac.args.delim()), + rustc_ast::ast::MacDelimiter::from_token(mac.args.delim().unwrap()), context.config.overflow_delimited_expr(), ) { (Some(ast::MacDelimiter::Bracket), true) From f300792f9a9a318e524b933a08097564a36b9628 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 26 Apr 2022 15:09:11 +1000 Subject: [PATCH 19/53] Make explicit an unreachable `NoDelim` case in `rustfmt`. --- src/macros.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/macros.rs b/src/macros.rs index 664f152e8be1d..92606902c5789 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -562,7 +562,7 @@ fn delim_token_to_str( ("{ ", " }") } } - DelimToken::NoDelim => ("", ""), + DelimToken::NoDelim => unreachable!(), }; if use_multiple_lines { let indent_str = shape.indent.to_string_with_newline(context.config); From 70067e31ed8da831c4b564d3ce803099a7696eaf Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 26 Apr 2022 15:40:14 +0300 Subject: [PATCH 20/53] rustc_ast: Harmonize delimiter naming with `proc_macro::Delimiter` --- src/expr.rs | 4 +-- src/macros.rs | 70 +++++++++++++++++++------------------- src/overflow.rs | 8 ++--- src/parse/macros/cfg_if.rs | 8 ++--- src/parse/macros/mod.rs | 8 ++--- src/visitor.rs | 4 +-- 6 files changed, 51 insertions(+), 51 deletions(-) diff --git a/src/expr.rs b/src/expr.rs index cd724373f4d16..741f3350801db 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -2,7 +2,7 @@ use std::borrow::Cow; use std::cmp::min; use itertools::Itertools; -use rustc_ast::token::{DelimToken, LitKind}; +use rustc_ast::token::{Delimiter, LitKind}; use rustc_ast::{ast, ptr}; use rustc_span::{BytePos, Span}; @@ -412,7 +412,7 @@ pub(crate) fn rewrite_array<'a, T: 'a + IntoOverflowableItem<'a>>( context: &'a RewriteContext<'_>, shape: Shape, force_separator_tactic: Option, - delim_token: Option, + delim_token: Option, ) -> Option { overflow::rewrite_with_square_brackets( context, diff --git a/src/macros.rs b/src/macros.rs index 92606902c5789..26c429eb94ff3 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -12,7 +12,7 @@ use std::collections::HashMap; use std::panic::{catch_unwind, AssertUnwindSafe}; -use rustc_ast::token::{BinOpToken, DelimToken, Token, TokenKind}; +use rustc_ast::token::{BinOpToken, Delimiter, Token, TokenKind}; use rustc_ast::tokenstream::{Cursor, Spacing, TokenStream, TokenTree}; use rustc_ast::{ast, ptr}; use rustc_ast_pretty::pprust; @@ -203,7 +203,7 @@ fn rewrite_macro_inner( let is_forced_bracket = FORCED_BRACKET_MACROS.contains(&¯o_name[..]); let style = if is_forced_bracket && !is_nested_macro { - DelimToken::Bracket + Delimiter::Bracket } else { original_style }; @@ -212,15 +212,15 @@ fn rewrite_macro_inner( let has_comment = contains_comment(context.snippet(mac.span())); if ts.is_empty() && !has_comment { return match style { - DelimToken::Paren if position == MacroPosition::Item => { + Delimiter::Parenthesis if position == MacroPosition::Item => { Some(format!("{}();", macro_name)) } - DelimToken::Bracket if position == MacroPosition::Item => { + Delimiter::Bracket if position == MacroPosition::Item => { Some(format!("{}[];", macro_name)) } - DelimToken::Paren => Some(format!("{}()", macro_name)), - DelimToken::Bracket => Some(format!("{}[]", macro_name)), - DelimToken::Brace => Some(format!("{} {{}}", macro_name)), + Delimiter::Parenthesis => Some(format!("{}()", macro_name)), + Delimiter::Bracket => Some(format!("{}[]", macro_name)), + Delimiter::Brace => Some(format!("{} {{}}", macro_name)), _ => unreachable!(), }; } @@ -260,7 +260,7 @@ fn rewrite_macro_inner( } match style { - DelimToken::Paren => { + Delimiter::Parenthesis => { // Handle special case: `vec!(expr; expr)` if vec_with_semi { handle_vec_semi(context, shape, arg_vec, macro_name, style) @@ -286,7 +286,7 @@ fn rewrite_macro_inner( }) } } - DelimToken::Bracket => { + Delimiter::Bracket => { // Handle special case: `vec![expr; expr]` if vec_with_semi { handle_vec_semi(context, shape, arg_vec, macro_name, style) @@ -323,7 +323,7 @@ fn rewrite_macro_inner( Some(format!("{}{}", rewrite, comma)) } } - DelimToken::Brace => { + Delimiter::Brace => { // For macro invocations with braces, always put a space between // the `macro_name!` and `{ /* macro_body */ }` but skip modifying // anything in between the braces (for now). @@ -342,11 +342,11 @@ fn handle_vec_semi( shape: Shape, arg_vec: Vec, macro_name: String, - delim_token: DelimToken, + delim_token: Delimiter, ) -> Option { let (left, right) = match delim_token { - DelimToken::Paren => ("(", ")"), - DelimToken::Bracket => ("[", "]"), + Delimiter::Parenthesis => ("(", ")"), + Delimiter::Bracket => ("[", "]"), _ => unreachable!(), }; @@ -528,7 +528,7 @@ enum MacroArgKind { /// e.g., `$($foo: expr),*` Repeat( /// `()`, `[]` or `{}`. - DelimToken, + Delimiter, /// Inner arguments inside delimiters. Vec, /// Something after the closing delimiter and the repeat token, if available. @@ -537,7 +537,7 @@ enum MacroArgKind { Token, ), /// e.g., `[derive(Debug)]` - Delimited(DelimToken, Vec), + Delimited(Delimiter, Vec), /// A possible separator. e.g., `,` or `;`. Separator(String, String), /// Other random stuff that does not fit to other kinds. @@ -547,22 +547,22 @@ enum MacroArgKind { fn delim_token_to_str( context: &RewriteContext<'_>, - delim_token: DelimToken, + delim_token: Delimiter, shape: Shape, use_multiple_lines: bool, inner_is_empty: bool, ) -> (String, String) { let (lhs, rhs) = match delim_token { - DelimToken::Paren => ("(", ")"), - DelimToken::Bracket => ("[", "]"), - DelimToken::Brace => { + Delimiter::Parenthesis => ("(", ")"), + Delimiter::Bracket => ("[", "]"), + Delimiter::Brace => { if inner_is_empty || use_multiple_lines { ("{", "}") } else { ("{ ", " }") } } - DelimToken::NoDelim => unreachable!(), + Delimiter::Invisible => unreachable!(), }; if use_multiple_lines { let indent_str = shape.indent.to_string_with_newline(context.config); @@ -583,8 +583,8 @@ impl MacroArgKind { fn starts_with_brace(&self) -> bool { matches!( *self, - MacroArgKind::Repeat(DelimToken::Brace, _, _, _) - | MacroArgKind::Delimited(DelimToken::Brace, _) + MacroArgKind::Repeat(Delimiter::Brace, _, _, _) + | MacroArgKind::Delimited(Delimiter::Brace, _) ) } @@ -753,7 +753,7 @@ impl MacroArgParser { } } - fn add_delimited(&mut self, inner: Vec, delim: DelimToken) { + fn add_delimited(&mut self, inner: Vec, delim: Delimiter) { self.result.push(ParsedMacroArg { kind: MacroArgKind::Delimited(delim, inner), }); @@ -763,7 +763,7 @@ impl MacroArgParser { fn add_repeat( &mut self, inner: Vec, - delim: DelimToken, + delim: Delimiter, iter: &mut Cursor, ) -> Option<()> { let mut buffer = String::new(); @@ -1083,18 +1083,18 @@ pub(crate) fn convert_try_mac( } } -pub(crate) fn macro_style(mac: &ast::MacCall, context: &RewriteContext<'_>) -> DelimToken { +pub(crate) fn macro_style(mac: &ast::MacCall, context: &RewriteContext<'_>) -> Delimiter { let snippet = context.snippet(mac.span()); let paren_pos = snippet.find_uncommented("(").unwrap_or(usize::max_value()); let bracket_pos = snippet.find_uncommented("[").unwrap_or(usize::max_value()); let brace_pos = snippet.find_uncommented("{").unwrap_or(usize::max_value()); if paren_pos < bracket_pos && paren_pos < brace_pos { - DelimToken::Paren + Delimiter::Parenthesis } else if bracket_pos < brace_pos { - DelimToken::Bracket + Delimiter::Bracket } else { - DelimToken::Brace + Delimiter::Brace } } @@ -1174,7 +1174,7 @@ struct Macro { // rather than clone them, if we can make the borrowing work out. struct MacroBranch { span: Span, - args_paren_kind: DelimToken, + args_paren_kind: Delimiter, args: TokenStream, body: Span, whole_body: Span, @@ -1188,7 +1188,7 @@ impl MacroBranch { multi_branch_style: bool, ) -> Option { // Only attempt to format function-like macros. - if self.args_paren_kind != DelimToken::Paren { + if self.args_paren_kind != Delimiter::Parenthesis { // FIXME(#1539): implement for non-sugared macros. return None; } @@ -1350,18 +1350,18 @@ fn rewrite_macro_with_items( items: &[MacroArg], macro_name: &str, shape: Shape, - style: DelimToken, + style: Delimiter, position: MacroPosition, span: Span, ) -> Option { let (opener, closer) = match style { - DelimToken::Paren => ("(", ")"), - DelimToken::Bracket => ("[", "]"), - DelimToken::Brace => (" {", "}"), + Delimiter::Parenthesis => ("(", ")"), + Delimiter::Bracket => ("[", "]"), + Delimiter::Brace => (" {", "}"), _ => return None, }; let trailing_semicolon = match style { - DelimToken::Paren | DelimToken::Bracket if position == MacroPosition::Item => ";", + Delimiter::Parenthesis | Delimiter::Bracket if position == MacroPosition::Item => ";", _ => "", }; diff --git a/src/overflow.rs b/src/overflow.rs index 80aed998d7377..f115e7d026182 100644 --- a/src/overflow.rs +++ b/src/overflow.rs @@ -3,7 +3,7 @@ use std::cmp::min; use itertools::Itertools; -use rustc_ast::token::DelimToken; +use rustc_ast::token::Delimiter; use rustc_ast::{ast, ptr}; use rustc_span::Span; @@ -297,11 +297,11 @@ pub(crate) fn rewrite_with_square_brackets<'a, T: 'a + IntoOverflowableItem<'a>> shape: Shape, span: Span, force_separator_tactic: Option, - delim_token: Option, + delim_token: Option, ) -> Option { let (lhs, rhs) = match delim_token { - Some(DelimToken::Paren) => ("(", ")"), - Some(DelimToken::Brace) => ("{", "}"), + Some(Delimiter::Parenthesis) => ("(", ")"), + Some(Delimiter::Brace) => ("{", "}"), _ => ("[", "]"), }; Context::new( diff --git a/src/parse/macros/cfg_if.rs b/src/parse/macros/cfg_if.rs index 306b6bb745ee6..09b3e32df312d 100644 --- a/src/parse/macros/cfg_if.rs +++ b/src/parse/macros/cfg_if.rs @@ -1,7 +1,7 @@ use std::panic::{catch_unwind, AssertUnwindSafe}; use rustc_ast::ast; -use rustc_ast::token::{DelimToken, TokenKind}; +use rustc_ast::token::{Delimiter, TokenKind}; use rustc_parse::parser::ForceCollect; use rustc_span::symbol::kw; @@ -47,11 +47,11 @@ fn parse_cfg_if_inner<'a>( .map_err(|_| "Failed to parse attributes")?; } - if !parser.eat(&TokenKind::OpenDelim(DelimToken::Brace)) { + if !parser.eat(&TokenKind::OpenDelim(Delimiter::Brace)) { return Err("Expected an opening brace"); } - while parser.token != TokenKind::CloseDelim(DelimToken::Brace) + while parser.token != TokenKind::CloseDelim(Delimiter::Brace) && parser.token.kind != TokenKind::Eof { let item = match parser.parse_item(ForceCollect::No) { @@ -70,7 +70,7 @@ fn parse_cfg_if_inner<'a>( } } - if !parser.eat(&TokenKind::CloseDelim(DelimToken::Brace)) { + if !parser.eat(&TokenKind::CloseDelim(Delimiter::Brace)) { return Err("Expected a closing brace"); } diff --git a/src/parse/macros/mod.rs b/src/parse/macros/mod.rs index 3728f3a19b44f..d4dbf21f8cab7 100644 --- a/src/parse/macros/mod.rs +++ b/src/parse/macros/mod.rs @@ -1,4 +1,4 @@ -use rustc_ast::token::{DelimToken, TokenKind}; +use rustc_ast::token::{Delimiter, TokenKind}; use rustc_ast::tokenstream::TokenStream; use rustc_ast::{ast, ptr}; use rustc_parse::parser::{ForceCollect, Parser}; @@ -81,7 +81,7 @@ fn check_keyword<'a, 'b: 'a>(parser: &'a mut Parser<'b>) -> Option { && parser.look_ahead(1, |t| { t.kind == TokenKind::Eof || t.kind == TokenKind::Comma - || t.kind == TokenKind::CloseDelim(DelimToken::NoDelim) + || t.kind == TokenKind::CloseDelim(Delimiter::Invisible) }) { parser.bump(); @@ -97,7 +97,7 @@ fn check_keyword<'a, 'b: 'a>(parser: &'a mut Parser<'b>) -> Option { pub(crate) fn parse_macro_args( context: &RewriteContext<'_>, tokens: TokenStream, - style: DelimToken, + style: Delimiter, forced_bracket: bool, ) -> Option { let mut parser = build_parser(context, tokens); @@ -105,7 +105,7 @@ pub(crate) fn parse_macro_args( let mut vec_with_semi = false; let mut trailing_comma = false; - if DelimToken::Brace != style { + if Delimiter::Brace != style { loop { if let Some(arg) = check_keyword(&mut parser) { args.push(arg); diff --git a/src/visitor.rs b/src/visitor.rs index 1621eb406b10f..f04fb2e0446c2 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -1,7 +1,7 @@ use std::cell::{Cell, RefCell}; use std::rc::Rc; -use rustc_ast::{ast, token::DelimToken, visit, AstLike}; +use rustc_ast::{ast, token::Delimiter, visit, AstLike}; use rustc_data_structures::sync::Lrc; use rustc_span::{symbol, BytePos, Pos, Span}; @@ -689,7 +689,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { // with whitespace between the delimiters and trailing semi (i.e. `foo!(abc) ;`) // are formatted correctly. let (span, rewrite) = match macro_style(mac, &self.get_context()) { - DelimToken::Bracket | DelimToken::Paren if MacroPosition::Item == pos => { + Delimiter::Bracket | Delimiter::Parenthesis if MacroPosition::Item == pos => { let search_span = mk_sp(mac.span().hi(), self.snippet_provider.end_pos()); let hi = self.snippet_provider.span_before(search_span, ";"); let target_span = mk_sp(mac.span().lo(), hi + BytePos(1)); From b26c86b51afa013815fc54404ef033f14541c707 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 30 Apr 2022 14:07:43 -0700 Subject: [PATCH 21/53] Update GitHub Actions actions/checkout@v2 to v3 The v2 implementation uses Node 12, which is end-of-life on April 30, 2022. See https://nodejs.org/en/about/releases/. Update to v3, which is based on Node 16 whose support lasts until April 30, 2024. --- .github/workflows/integration.yml | 2 +- .github/workflows/linux.yml | 2 +- .github/workflows/mac.yml | 2 +- .github/workflows/rustdoc_check.yml | 2 +- .github/workflows/upload-assets.yml | 2 +- .github/workflows/windows.yml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index b79221d054369..4d8899b434bbe 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -69,7 +69,7 @@ jobs: steps: - name: checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 # Run build - name: install rustup diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 45f63b83c0562..6a3f9d89d98fc 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -26,7 +26,7 @@ jobs: steps: - name: checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 # Run build - name: install rustup diff --git a/.github/workflows/mac.yml b/.github/workflows/mac.yml index 55e1cc9539b85..7dfda3142ca9d 100644 --- a/.github/workflows/mac.yml +++ b/.github/workflows/mac.yml @@ -23,7 +23,7 @@ jobs: steps: - name: checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 # Run build - name: install rustup diff --git a/.github/workflows/rustdoc_check.yml b/.github/workflows/rustdoc_check.yml index ca96d30f58639..cd0c3218971e2 100644 --- a/.github/workflows/rustdoc_check.yml +++ b/.github/workflows/rustdoc_check.yml @@ -11,7 +11,7 @@ jobs: name: rustdoc check steps: - name: checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: install rustup run: | diff --git a/.github/workflows/upload-assets.yml b/.github/workflows/upload-assets.yml index f4dd394445301..25699234a1ec3 100644 --- a/.github/workflows/upload-assets.yml +++ b/.github/workflows/upload-assets.yml @@ -31,7 +31,7 @@ jobs: target: x86_64-pc-windows-msvc runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 # Run build - name: install rustup diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index dcb08b5412ea6..4ebc296384905 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -33,7 +33,7 @@ jobs: - name: disable git eol translation run: git config --global core.autocrlf false - name: checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 # Run build - name: Install Rustup using win.rustup.rs From 050978ba436674db0dc28d5946ef9c93231165f9 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sun, 24 Apr 2022 19:25:30 -0700 Subject: [PATCH 22/53] Fix the rustfmt build --- src/expr.rs | 4 ++++ src/utils.rs | 1 + 2 files changed, 5 insertions(+) diff --git a/src/expr.rs b/src/expr.rs index 741f3350801db..e4cc93026f10b 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -225,6 +225,10 @@ pub(crate) fn format_expr( ast::ExprKind::Ret(Some(ref expr)) => { rewrite_unary_prefix(context, "return ", &**expr, shape) } + ast::ExprKind::Yeet(None) => Some("do yeet".to_owned()), + ast::ExprKind::Yeet(Some(ref expr)) => { + rewrite_unary_prefix(context, "do yeet ", &**expr, shape) + } ast::ExprKind::Box(ref expr) => rewrite_unary_prefix(context, "box ", &**expr, shape), ast::ExprKind::AddrOf(borrow_kind, mutability, ref expr) => { rewrite_expr_addrof(context, borrow_kind, mutability, expr, shape) diff --git a/src/utils.rs b/src/utils.rs index 35512e78fa6e2..ed418fb1fece6 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -512,6 +512,7 @@ pub(crate) fn is_block_expr(context: &RewriteContext<'_>, expr: &ast::Expr, repr | ast::ExprKind::Range(..) | ast::ExprKind::Repeat(..) | ast::ExprKind::Ret(..) + | ast::ExprKind::Yeet(..) | ast::ExprKind::Tup(..) | ast::ExprKind::Type(..) | ast::ExprKind::Yield(None) From c03e1842f637e34b23297fa3a0aeeb0fcdca1c47 Mon Sep 17 00:00:00 2001 From: cuishuang Date: Sat, 7 May 2022 23:56:21 +0800 Subject: [PATCH 23/53] fix some typos Signed-off-by: cuishuang --- src/parse/session.rs | 2 +- tests/rustfmt/main.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/parse/session.rs b/src/parse/session.rs index 7571e6d078a7b..55050571db793 100644 --- a/src/parse/session.rs +++ b/src/parse/session.rs @@ -152,7 +152,7 @@ impl ParseSess { /// * `relative` - If Some(symbol), the symbol name is a directory relative to the dir_path. /// If relative is Some, resolve the submodle at {dir_path}/{symbol}/{id}.rs /// or {dir_path}/{symbol}/{id}/mod.rs. if None, resolve the module at {dir_path}/{id}.rs. - /// * `dir_path` - Module resolution will occur relative to this direcotry. + /// * `dir_path` - Module resolution will occur relative to this directory. pub(crate) fn default_submod_path( &self, id: symbol::Ident, diff --git a/tests/rustfmt/main.rs b/tests/rustfmt/main.rs index 450051d2fec61..4c6d52726f3fe 100644 --- a/tests/rustfmt/main.rs +++ b/tests/rustfmt/main.rs @@ -143,7 +143,7 @@ fn mod_resolution_error_relative_module_not_found() { let args = ["tests/mod-resolver/module-not-found/relative_module/lib.rs"]; let (_stdout, stderr) = rustfmt(&args); // The file `./a.rs` and directory `./a` both exist. - // Module resolution fails becuase we're unable to find `./a/b.rs` + // Module resolution fails because we're unable to find `./a/b.rs` #[cfg(not(windows))] assert!(stderr.contains("a/b.rs does not exist")); #[cfg(windows)] From 3cc1f5ed5b04ea6512b710e231c147b4546f8e52 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Thu, 28 Apr 2022 23:08:22 -0400 Subject: [PATCH 24/53] Add tests for issue 4573 It's unclear which PR resolved this issue, however the behavior of adding inline comments to the next line can't be reproduced. These test cases should serve to prevent a regression. --- tests/target/issue_4573.rs | 245 +++++++++++++++++++++++++++++++++++++ 1 file changed, 245 insertions(+) create mode 100644 tests/target/issue_4573.rs diff --git a/tests/target/issue_4573.rs b/tests/target/issue_4573.rs new file mode 100644 index 0000000000000..82cfe4f535981 --- /dev/null +++ b/tests/target/issue_4573.rs @@ -0,0 +1,245 @@ +// rustmft-version:Two +// rustmft-use_small_heuristics:Max +// rustmft-merge_derives:false +// These are the same rustfmt configuration options that are used +// in the comiler as of ce39461ca75a and 8eb7c58dbb7b +// These are commits in https://github.com/rust-lang/rust + +#![no_std] // inner attribute comment +// inner attribute comment +#![no_implicit_prelude] +// post inner attribute comment + +#[cfg(not(miri))] // inline comment +#[no_link] +extern crate foo; + +// before attributes +#[no_link] +// between attributes +#[cfg(not(miri))] // inline comment +extern crate foo as bar; + +#[cfg(not(miri))] // inline comment +// between attribute and use +use foo; + +#[cfg(not(miri))] // inline comment +use foo; + +/* pre attributre */ +#[cfg(not(miri))] +use foo::bar; + +#[cfg(not(miri))] // inline comment +use foo::bar as FooBar; + +#[cfg(not(miri))] // inline comment +#[allow(unused)] +#[deprecated( + since = "5.2", // inline inner comment + note = "FOO was rarely used. Users should instead use BAR" +)] +#[allow(unused)] +static FOO: i32 = 42; + +#[used] +#[export_name = "FOO"] +#[cfg(not(miri))] // inline comment +#[deprecated( + since = "5.2", + note = "FOO was rarely used. Users should instead use BAR" +)] +static FOO: i32 = 42; + +#[cfg(not(miri))] // inline comment +#[export_name = "FOO"] +static BAR: &'static str = "bar"; + +#[cfg(not(miri))] // inline comment +const BAR: i32 = 42; + +#[cfg(not(miri))] // inline comment +#[no_mangle] +#[link_section = ".example_section"] +fn foo(bar: usize) { + #[cfg(not(miri))] // inline comment + println!("hello world!"); +} + +#[cfg(not(miri))] // inline comment +mod foo {} + +#[cfg(not(miri))] // inline comment +extern "C" { + fn my_c_function(x: i32) -> bool; +} + +#[cfg(not(miri))] // inline comment +#[link(name = "CoreFoundation", kind = "framework")] +extern "C" { + + #[link_name = "actual_symbol_name"] // inline comment + // between attribute and function + fn my_c_function(x: i32) -> bool; +} + +#[cfg(not(miri))] // inline comment +pub extern "C" fn callable_from_c(x: i32) -> bool { + x % 3 == 0 +} + +#[cfg(not(miri))] // inline comment +/* between attribute block comment */ +#[no_mangle] +/* between attribute and type */ +type Foo = Bar; + +#[no_mangle] +#[cfg(not(miri))] // inline comment +#[non_exhaustive] // inline comment +enum Foo { + Bar, + Baz, +} + +#[no_mangle] +#[cfg(not(miri))] /* inline comment */ +struct Foo { + x: A, +} + +#[cfg(not(miri))] // inline comment +union Foo { + x: A, + y: B, +} + +#[cfg(not(miri))] // inline comment +trait Foo {} + +#[cfg(not(miri))] // inline comment +trait Foo = Bar + Quux; + +#[cfg(not(miri))] // inline comment +impl Foo {} + +#[cfg(not(miri))] // inline comment +macro_rules! bar { + (3) => {}; +} + +mod nested { + #[cfg(not(miri))] // inline comment + // between attribute and use + use foo; + + #[cfg(not(miri))] // inline comment + use foo; + + #[cfg(not(miri))] // inline comment + use foo::bar; + + #[cfg(not(miri))] // inline comment + use foo::bar as FooBar; + + #[cfg(not(miri))] // inline comment + static FOO: i32 = 42; + + #[cfg(not(miri))] // inline comment + static FOO: i32 = 42; + + #[cfg(not(miri))] // inline comment + static FOO: &'static str = "bar"; + + #[cfg(not(miri))] // inline comment + const FOO: i32 = 42; + + #[cfg(not(miri))] // inline comment + fn foo(bar: usize) { + #[cfg(not(miri))] // inline comment + println!("hello world!"); + } + + #[cfg(not(miri))] // inline comment + mod foo {} + + #[cfg(not(miri))] // inline comment + mod foo {} + + #[cfg(not(miri))] // inline comment + extern "C" { + fn my_c_function(x: i32) -> bool; + } + + #[cfg(not(miri))] // inline comment + #[link(name = "CoreFoundation", kind = "framework")] + extern "C" { + + #[link_name = "actual_symbol_name"] // inline comment + // between attribute and function + fn my_c_function(x: i32) -> bool; + } + + #[cfg(not(miri))] // inline comment + pub extern "C" fn callable_from_c(x: i32) -> bool { + x % 3 == 0 + } + + #[cfg(not(miri))] // inline comment + type Foo = Bar; + + #[cfg(not(miri))] // inline comment + #[non_exhaustive] // inline comment + enum Foo { + // comment + #[attribute_1] + #[attribute_2] // comment + // comment! + Bar, + /* comment */ + #[attribute_1] + #[attribute_2] /* comment */ + #[attribute_3] + #[attribute_4] + /* comment! */ + Baz, + } + + #[cfg(not(miri))] // inline comment + struct Foo { + x: A, + } + + #[cfg(not(miri))] // inline comment + union Foo { + #[attribute_1] + #[attribute_2] /* comment */ + #[attribute_3] + #[attribute_4] // comment + x: A, + y: B, + } + + #[cfg(not(miri))] // inline comment + #[allow(missing_docs)] + trait Foo { + #[must_use] /* comment + * that wrappes to + * the next line */ + fn bar() {} + } + + #[allow(missing_docs)] + #[cfg(not(miri))] // inline comment + trait Foo = Bar + Quux; + + #[allow(missing_docs)] + #[cfg(not(miri))] // inline comment + impl Foo {} + + #[cfg(not(miri))] // inline comment + macro_rules! bar { + (3) => {}; + } +} From c65ba14d692bedab306b0426c36ab8f4fe4cbab2 Mon Sep 17 00:00:00 2001 From: Pascal Seitz Date: Sun, 13 Mar 2022 10:03:50 +0800 Subject: [PATCH 25/53] Fixes #5260 Fixes #5260 by checking if it is part of a type '::' --- src/comment.rs | 2 +- src/string.rs | 45 ++++++++++++++++++++++++++++++++------ tests/source/issue-5260.rs | 14 ++++++++++++ tests/target/issue-5260.rs | 13 +++++++++++ 4 files changed, 66 insertions(+), 8 deletions(-) create mode 100644 tests/source/issue-5260.rs create mode 100644 tests/target/issue-5260.rs diff --git a/src/comment.rs b/src/comment.rs index f9d8a0fa70c00..eb195b1f7628f 100644 --- a/src/comment.rs +++ b/src/comment.rs @@ -796,7 +796,7 @@ impl<'a> CommentRewrite<'a> { // 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 + // 4) No URLS were found in the comment let should_wrap_comment = self.fmt.config.wrap_comments() && !is_markdown_header_doc_comment && unicode_str_width(line) > self.fmt.shape.width diff --git a/src/string.rs b/src/string.rs index b65aa5b33b241..78b72a50cb2f9 100644 --- a/src/string.rs +++ b/src/string.rs @@ -315,20 +315,21 @@ fn break_string(max_width: usize, trim_end: bool, line_end: &str, input: &[&str] // Found a whitespace and what is on its left side is big enough. Some(index) if index >= MIN_STRING => break_at(index), // No whitespace found, try looking for a punctuation instead - _ => match input[0..max_width_index_in_input] - .iter() - .rposition(|grapheme| is_punctuation(grapheme)) + _ => match (0..max_width_index_in_input) + .rev() + .skip_while(|pos| !is_valid_linebreak(input, *pos)) + .next() { // Found a punctuation and what is on its left side is big enough. Some(index) if index >= MIN_STRING => break_at(index), // Either no boundary character was found to the left of `input[max_chars]`, or the line // got too small. We try searching for a boundary character to the right. - _ => match input[max_width_index_in_input..] - .iter() - .position(|grapheme| is_whitespace(grapheme) || is_punctuation(grapheme)) + _ => match (max_width_index_in_input..input.len()) + .skip_while(|pos| !is_valid_linebreak(input, *pos)) + .next() { // A boundary was found after the line limit - Some(index) => break_at(max_width_index_in_input + index), + Some(index) => break_at(index), // No boundary to the right, the input cannot be broken None => SnippetState::EndOfInput(input.concat()), }, @@ -336,6 +337,23 @@ fn break_string(max_width: usize, trim_end: bool, line_end: &str, input: &[&str] } } +fn is_valid_linebreak(input: &[&str], pos: usize) -> bool { + let is_whitespace = is_whitespace(input[pos]); + if is_whitespace { + return true; + } + let is_punctuation = is_punctuation(input[pos]); + if is_punctuation && !is_part_of_type(input, pos) { + return true; + } + false +} + +fn is_part_of_type(input: &[&str], pos: usize) -> bool { + input.get(pos..=pos + 1) == Some(&[":", ":"]) + || input.get(pos.saturating_sub(1)..=pos) == Some(&[":", ":"]) +} + fn is_new_line(grapheme: &str) -> bool { let bytes = grapheme.as_bytes(); bytes.starts_with(b"\n") || bytes.starts_with(b"\r\n") @@ -369,6 +387,19 @@ mod test { rewrite_string("eq_", &fmt, 2); } + #[test] + fn line_break_at_valid_points_test() { + let string = "[TheName](Dont::break::my::type::That::would::be::very::nice) break here"; + let graphemes = UnicodeSegmentation::graphemes(&*string, false).collect::>(); + assert_eq!( + break_string(20, false, "", &graphemes[..]), + SnippetState::LineEnd( + "[TheName](Dont::break::my::type::That::would::be::very::nice) ".to_string(), + 62 + ) + ); + } + #[test] fn should_break_on_whitespace() { let string = "Placerat felis. Mauris porta ante sagittis purus."; diff --git a/tests/source/issue-5260.rs b/tests/source/issue-5260.rs new file mode 100644 index 0000000000000..c0606817290cd --- /dev/null +++ b/tests/source/issue-5260.rs @@ -0,0 +1,14 @@ +// rustfmt-wrap_comments: true + +/// [MyType](VeryLongPathToMyType::NoLineBreak::Here::Okay::ThatWouldBeNice::Thanks) +fn documented_with_longtype() { + // # We're using a long type link, rustfmt should not break line + // on the type when `wrap_comments = true` +} + +/// VeryLongPathToMyType::JustMyType::But::VeryVery::Long::NoLineBreak::Here::Okay::ThatWouldBeNice::Thanks +fn documented_with_verylongtype() { + // # We're using a long type link, rustfmt should not break line + // on the type when `wrap_comments = true` +} + diff --git a/tests/target/issue-5260.rs b/tests/target/issue-5260.rs new file mode 100644 index 0000000000000..171f6fa51b78e --- /dev/null +++ b/tests/target/issue-5260.rs @@ -0,0 +1,13 @@ +// rustfmt-wrap_comments: true + +/// [MyType](VeryLongPathToMyType::NoLineBreak::Here::Okay::ThatWouldBeNice::Thanks) +fn documented_with_longtype() { + // # We're using a long type link, rustfmt should not break line + // on the type when `wrap_comments = true` +} + +/// VeryLongPathToMyType::JustMyType::But::VeryVery::Long::NoLineBreak::Here::Okay::ThatWouldBeNice::Thanks +fn documented_with_verylongtype() { + // # We're using a long type link, rustfmt should not break line + // on the type when `wrap_comments = true` +} From 84fd4cdd022c7a6234006100b7e547eb2b178634 Mon Sep 17 00:00:00 2001 From: PSeitz Date: Mon, 9 May 2022 04:54:15 +0200 Subject: [PATCH 26/53] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b23360858356..0db1dffd6e0a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### 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) +- Fixes an issue where types would be incorrectly wrapped in comments [#5260](https://github.com/rust-lang/rustfmt/issues/5260) ## [1.4.38] 2021-10-20 From 17003ce66b5737a71d0a08832995dc11df497ee2 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Mon, 9 May 2022 17:10:53 -0700 Subject: [PATCH 27/53] In the docs for `hex_literal_case`, show the default as a possible value --- Configurations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Configurations.md b/Configurations.md index dc8d38267a83d..7afd4b5cd6a97 100644 --- a/Configurations.md +++ b/Configurations.md @@ -1065,7 +1065,7 @@ See also: [`tab_spaces`](#tab_spaces). Control the case of the letters in hexadecimal literal values - **Default value**: `Preserve` -- **Possible values**: `Upper`, `Lower` +- **Possible values**: `Preserve`, `Upper`, `Lower` - **Stable**: No (tracking issue: [#5081](https://github.com/rust-lang/rustfmt/issues/5081)) ## `hide_parse_errors` From 77f096453c819224e712bf56b4567558c7ae31e2 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 11 May 2022 10:14:49 +1000 Subject: [PATCH 28/53] Remove some unnecessary invisible delimiter checks. These seem to have no useful effect... they don't seem useful from a code inspection point of view, and they affect anything in the test suite. --- src/parse/macros/mod.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/parse/macros/mod.rs b/src/parse/macros/mod.rs index d4dbf21f8cab7..67f3985926e2f 100644 --- a/src/parse/macros/mod.rs +++ b/src/parse/macros/mod.rs @@ -79,9 +79,7 @@ fn check_keyword<'a, 'b: 'a>(parser: &'a mut Parser<'b>) -> Option { for &keyword in RUST_KW.iter() { if parser.token.is_keyword(keyword) && parser.look_ahead(1, |t| { - t.kind == TokenKind::Eof - || t.kind == TokenKind::Comma - || t.kind == TokenKind::CloseDelim(Delimiter::Invisible) + t.kind == TokenKind::Eof || t.kind == TokenKind::Comma }) { parser.bump(); From f77fd90affcf794354ca8d120e9cc55dc64f4cf1 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 1 May 2022 20:58:24 +0300 Subject: [PATCH 29/53] ast: Introduce some traits to get AST node properties generically And use them to avoid constructing some artificial `Nonterminal` tokens during expansion --- src/attr.rs | 2 +- src/formatting.rs | 1 - src/modules.rs | 12 +----------- src/visitor.rs | 2 +- 4 files changed, 3 insertions(+), 14 deletions(-) diff --git a/src/attr.rs b/src/attr.rs index befe12ae2c4cd..41ba9a847e67a 100644 --- a/src/attr.rs +++ b/src/attr.rs @@ -1,7 +1,7 @@ //! Format attributes and meta items. use rustc_ast::ast; -use rustc_ast::AstLike; +use rustc_ast::HasAttrs; use rustc_span::{symbol::sym, Span, Symbol}; use self::doc_comment::DocCommentFormatter; diff --git a/src/formatting.rs b/src/formatting.rs index ca93955a549dd..ebadf3dd598bd 100644 --- a/src/formatting.rs +++ b/src/formatting.rs @@ -5,7 +5,6 @@ use std::io::{self, Write}; use std::time::{Duration, Instant}; use rustc_ast::ast; -use rustc_ast::AstLike; use rustc_span::Span; use self::newline_style::apply_newline_style; diff --git a/src/modules.rs b/src/modules.rs index a65dc66f7972e..81da724329f02 100644 --- a/src/modules.rs +++ b/src/modules.rs @@ -4,7 +4,6 @@ use std::path::{Path, PathBuf}; use rustc_ast::ast; use rustc_ast::visit::Visitor; -use rustc_ast::AstLike; use rustc_span::symbol::{self, sym, Symbol}; use rustc_span::Span; use thiserror::Error; @@ -50,19 +49,10 @@ impl<'a> Module<'a> { ast_mod_kind, } } -} -impl<'a> AstLike for Module<'a> { - const SUPPORTS_CUSTOM_INNER_ATTRS: bool = true; - fn attrs(&self) -> &[ast::Attribute] { + pub(crate) fn attrs(&self) -> &[ast::Attribute] { &self.inner_attr } - fn visit_attrs(&mut self, f: impl FnOnce(&mut Vec)) { - f(&mut self.inner_attr) - } - fn tokens_mut(&mut self) -> Option<&mut Option> { - unimplemented!() - } } /// Maps each module to the corresponding file. diff --git a/src/visitor.rs b/src/visitor.rs index f04fb2e0446c2..9a0e0752c12f5 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -1,7 +1,7 @@ use std::cell::{Cell, RefCell}; use std::rc::Rc; -use rustc_ast::{ast, token::Delimiter, visit, AstLike}; +use rustc_ast::{ast, token::Delimiter, visit}; use rustc_data_structures::sync::Lrc; use rustc_span::{symbol, BytePos, Pos, Span}; From 8a4c05865be17bac75b8d53eae5be18d749a0f5c Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Thu, 12 May 2022 00:44:25 +0900 Subject: [PATCH 30/53] Use the traits added to the Rust 2021 Edition prelude Follow up https://github.com/rust-lang/rust/pull/96861. This PR uses the traits added to the Rust 2021 Edition prelude. > The `TryInto`, `TryFrom` and `FromIterator` traits are now part of the prelude. https://doc.rust-lang.org/edition-guide/rust-2021/prelude.html --- src/cargo-fmt/main.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/cargo-fmt/main.rs b/src/cargo-fmt/main.rs index 3542536f29b61..55fd75f6de9b8 100644 --- a/src/cargo-fmt/main.rs +++ b/src/cargo-fmt/main.rs @@ -10,7 +10,6 @@ use std::ffi::OsStr; use std::fs; use std::hash::{Hash, Hasher}; use std::io::{self, Write}; -use std::iter::FromIterator; use std::path::{Path, PathBuf}; use std::process::Command; use std::str; From b08b2daeb6da2f77be50a53cdca2098fb3bb11b2 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Thu, 31 Mar 2022 18:15:51 -0400 Subject: [PATCH 31/53] Add test for issue 3937 Closes 3937 It's unclear which change fixed the `format_code_in_doc_comments=true` issue brought up in this issue, however I'm unable to reproduce the error on the current master. The added test cases should serve to prevent a regression. --- tests/target/issue_3937.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 tests/target/issue_3937.rs diff --git a/tests/target/issue_3937.rs b/tests/target/issue_3937.rs new file mode 100644 index 0000000000000..8067310850053 --- /dev/null +++ b/tests/target/issue_3937.rs @@ -0,0 +1,13 @@ +// rustfmt-format_code_in_doc_comments:true + +struct Foo { + // a: i32, + // + // b: i32, +} + +struct Foo { + a: i32, + // + // b: i32, +} From b507c60e1c7fae20b643557a4430aba7e7e037df Mon Sep 17 00:00:00 2001 From: klensy Date: Wed, 18 May 2022 19:02:06 +0300 Subject: [PATCH 32/53] fix rustfmt --- src/macros.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/macros.rs b/src/macros.rs index 26c429eb94ff3..f4b2bcf281577 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -226,7 +226,7 @@ fn rewrite_macro_inner( } // Format well-known macros which cannot be parsed as a valid AST. if macro_name == "lazy_static!" && !has_comment { - if let success @ Some(..) = format_lazy_static(context, shape, ts.trees().collect()) { + if let success @ Some(..) = format_lazy_static(context, shape, ts.clone()) { return success; } } @@ -855,7 +855,7 @@ impl MacroArgParser { /// Returns a collection of parsed macro def's arguments. fn parse(mut self, tokens: TokenStream) -> Option> { - let mut iter = tokens.trees(); + let mut iter = tokens.into_trees(); while let Some(tok) = iter.next() { match tok { From 95837832f4bb89a681fd7fae57dad42fca497e23 Mon Sep 17 00:00:00 2001 From: David Lattimore Date: Sat, 30 Apr 2022 15:12:06 +1000 Subject: [PATCH 33/53] import_granularity: Don't normalize imports with comments --- src/imports.rs | 17 +++++++- tests/source/imports_granularity_crate.rs | 28 +++++++++++++ tests/source/imports_granularity_item.rs | 28 +++++++++++++ tests/source/imports_granularity_module.rs | 28 +++++++++++++ tests/source/imports_granularity_one.rs | 28 +++++++++++++ tests/target/imports_granularity_crate.rs | 31 +++++++++++++++ tests/target/imports_granularity_item.rs | 32 +++++++++++++++ tests/target/imports_granularity_module.rs | 39 ++++++++++++++++-- tests/target/imports_granularity_one.rs | 46 ++++++++++++++++++---- 9 files changed, 264 insertions(+), 13 deletions(-) diff --git a/src/imports.rs b/src/imports.rs index efe4e9498c909..962f2126c66c3 100644 --- a/src/imports.rs +++ b/src/imports.rs @@ -181,6 +181,14 @@ impl UseSegment { } }) } + + fn contains_comment(&self) -> bool { + if let UseSegment::List(list) = self { + list.iter().any(|subtree| subtree.contains_comment()) + } else { + false + } + } } pub(crate) fn normalize_use_trees_with_granularity( @@ -197,7 +205,7 @@ pub(crate) fn normalize_use_trees_with_granularity( let mut result = Vec::with_capacity(use_trees.len()); for use_tree in use_trees { - if use_tree.has_comment() || use_tree.attrs.is_some() { + if use_tree.contains_comment() || use_tree.attrs.is_some() { result.push(use_tree); continue; } @@ -556,6 +564,10 @@ impl UseTree { self.list_item.as_ref().map_or(false, ListItem::has_comment) } + fn contains_comment(&self) -> bool { + self.has_comment() || self.path.iter().any(|path| path.contains_comment()) + } + fn same_visibility(&self, other: &UseTree) -> bool { match (&self.visibility, &other.visibility) { ( @@ -582,6 +594,7 @@ impl UseTree { if self.path.is_empty() || other.path.is_empty() || self.attrs.is_some() + || self.contains_comment() || !self.same_visibility(other) { false @@ -597,7 +610,7 @@ impl UseTree { } fn flatten(self, import_granularity: ImportGranularity) -> Vec { - if self.path.is_empty() { + if self.path.is_empty() || self.contains_comment() { return vec![self]; } match self.path.clone().last().unwrap() { diff --git a/tests/source/imports_granularity_crate.rs b/tests/source/imports_granularity_crate.rs index d16681b01b561..f6f7761e82ee7 100644 --- a/tests/source/imports_granularity_crate.rs +++ b/tests/source/imports_granularity_crate.rs @@ -35,3 +35,31 @@ use j::{a::{self}}; use {k::{a, b}, l::{a, b}}; use {k::{c, d}, l::{c, d}}; + +use b::{f::g, h::{i, j} /* After b::h group */}; +use b::e; +use b::{/* Before b::l group */ l::{self, m, n::o, p::*}, q}; +use b::d; +use b::r; // After b::r +use b::q::{self /* After b::q::self */}; +use b::u::{ + a, + b, +}; +use b::t::{ + // Before b::t::a + a, + b, +}; +use b::s::{ + a, + b, // After b::s::b +}; +use b::v::{ + // Before b::v::a + a, + // Before b::v::b + b, +}; +use b::t::{/* Before b::t::self */ self}; +use b::c; diff --git a/tests/source/imports_granularity_item.rs b/tests/source/imports_granularity_item.rs index d0e94df66ae2a..b82c0d33cafde 100644 --- a/tests/source/imports_granularity_item.rs +++ b/tests/source/imports_granularity_item.rs @@ -4,3 +4,31 @@ use a::{b, c, d}; use a::{f::g, h::{i, j}}; use a::{l::{self, m, n::o, p::*}}; use a::q::{self}; + +use b::{f::g, h::{i, j} /* After b::h group */}; +use b::e; +use b::{/* Before b::l group */ l::{self, m, n::o, p::*}, q}; +use b::d; +use b::r; // After b::r +use b::q::{self /* After b::q::self */}; +use b::u::{ + a, + b, +}; +use b::t::{ + // Before b::t::a + a, + b, +}; +use b::s::{ + a, + b, // After b::s::b +}; +use b::v::{ + // Before b::v::a + a, + // Before b::v::b + b, +}; +use b::t::{/* Before b::t::self */ self}; +use b::c; diff --git a/tests/source/imports_granularity_module.rs b/tests/source/imports_granularity_module.rs index 2d7bb299aaace..c7f68cea6d47a 100644 --- a/tests/source/imports_granularity_module.rs +++ b/tests/source/imports_granularity_module.rs @@ -17,3 +17,31 @@ use bar::{ c::d, e::f, }; + +use b::{f::g, h::{i, j} /* After b::h group */}; +use b::e; +use b::{/* Before b::l group */ l::{self, m, n::o, p::*}, q}; +use b::d; +use b::r; // After b::r +use b::q::{self /* After b::q::self */}; +use b::u::{ + a, + b, +}; +use b::t::{ + // Before b::t::a + a, + b, +}; +use b::s::{ + a, + b, // After b::s::b +}; +use b::v::{ + // Before b::v::a + a, + // Before b::v::b + b, +}; +use b::t::{/* Before b::t::self */ self}; +use b::c; diff --git a/tests/source/imports_granularity_one.rs b/tests/source/imports_granularity_one.rs index c21707df39545..4d5a479564132 100644 --- a/tests/source/imports_granularity_one.rs +++ b/tests/source/imports_granularity_one.rs @@ -58,3 +58,31 @@ use a::{ }; use b as x; use a::ad::ada; + +use b::{f::g, h::{i, j} /* After b::h group */}; +use b::e; +use b::{/* Before b::l group */ l::{self, m, n::o, p::*}, q}; +use b::d; +use b::r; // After b::r +use b::q::{self /* After b::q::self */}; +use b::u::{ + a, + b, +}; +use b::t::{ + // Before b::t::a + a, + b, +}; +use b::s::{ + a, + b, // After b::s::b +}; +use b::v::{ + // Before b::v::a + a, + // Before b::v::b + b, +}; +use b::t::{/* Before b::t::self */ self}; +use b::c; diff --git a/tests/target/imports_granularity_crate.rs b/tests/target/imports_granularity_crate.rs index d75906d30f18b..36e01558ff041 100644 --- a/tests/target/imports_granularity_crate.rs +++ b/tests/target/imports_granularity_crate.rs @@ -26,3 +26,34 @@ use j::a::{self}; use k::{a, b, c, d}; use l::{a, b, c, d}; + +use b::q::{self /* After b::q::self */}; +use b::r; // After b::r +use b::s::{ + a, + b, // After b::s::b +}; +use b::t::{/* Before b::t::self */ self}; +use b::t::{ + // Before b::t::a + a, + b, +}; +use b::v::{ + // Before b::v::a + a, + // Before b::v::b + b, +}; +use b::{ + c, d, e, + u::{a, b}, +}; +use b::{ + f::g, + h::{i, j}, /* After b::h group */ +}; +use b::{ + /* Before b::l group */ l::{self, m, n::o, p::*}, + q, +}; diff --git a/tests/target/imports_granularity_item.rs b/tests/target/imports_granularity_item.rs index eace785e6705e..d2f5496fdacad 100644 --- a/tests/target/imports_granularity_item.rs +++ b/tests/target/imports_granularity_item.rs @@ -11,3 +11,35 @@ use a::l::n::o; use a::l::p::*; use a::l::{self}; use a::q::{self}; + +use b::c; +use b::d; +use b::e; +use b::q::{self /* After b::q::self */}; +use b::r; // After b::r +use b::s::{ + a, + b, // After b::s::b +}; +use b::t::{/* Before b::t::self */ self}; +use b::t::{ + // Before b::t::a + a, + b, +}; +use b::u::a; +use b::u::b; +use b::v::{ + // Before b::v::a + a, + // Before b::v::b + b, +}; +use b::{ + f::g, + h::{i, j}, /* After b::h group */ +}; +use b::{ + /* Before b::l group */ l::{self, m, n::o, p::*}, + q, +}; diff --git a/tests/target/imports_granularity_module.rs b/tests/target/imports_granularity_module.rs index e4e1a299e5866..14f341016ff91 100644 --- a/tests/target/imports_granularity_module.rs +++ b/tests/target/imports_granularity_module.rs @@ -17,6 +17,39 @@ use foo::e; #[cfg(test)] use foo::{a::b, c::d}; -use bar::a::b; -use bar::c::d; -use bar::e::f; +use bar::{ + // comment + a::b, + // more comment + c::d, + e::f, +}; + +use b::q::{self /* After b::q::self */}; +use b::r; // After b::r +use b::s::{ + a, + b, // After b::s::b +}; +use b::t::{/* Before b::t::self */ self}; +use b::t::{ + // Before b::t::a + a, + b, +}; +use b::u::{a, b}; +use b::v::{ + // Before b::v::a + a, + // Before b::v::b + b, +}; +use b::{c, d, e}; +use b::{ + f::g, + h::{i, j}, /* After b::h group */ +}; +use b::{ + /* Before b::l group */ l::{self, m, n::o, p::*}, + q, +}; diff --git a/tests/target/imports_granularity_one.rs b/tests/target/imports_granularity_one.rs index 78ec5e7325c50..da4c6678db149 100644 --- a/tests/target/imports_granularity_one.rs +++ b/tests/target/imports_granularity_one.rs @@ -68,12 +68,42 @@ use { c::{self, ca}, }; -use { - a::{ - aa::{aaa, aab}, - ab, - ac::aca, - ad::ada, - }, - b as x, +use a::{ + // some comment + aa::{aaa, aab}, + ab, + // another comment + ac::aca, +}; +use {a::ad::ada, b as x}; + +use b::q::{self /* After b::q::self */}; +use b::r; // After b::r +use b::s::{ + a, + b, // After b::s::b +}; +use b::t::{/* Before b::t::self */ self}; +use b::t::{ + // Before b::t::a + a, + b, +}; +use b::v::{ + // Before b::v::a + a, + // Before b::v::b + b, +}; +use b::{ + c, d, e, + u::{a, b}, +}; +use b::{ + f::g, + h::{i, j}, /* After b::h group */ +}; +use b::{ + /* Before b::l group */ l::{self, m, n::o, p::*}, + q, }; From 86940d2652acbede150f9fc52111688468c2be62 Mon Sep 17 00:00:00 2001 From: ydah <13041216+ydah@users.noreply.github.com> Date: Fri, 20 May 2022 10:39:10 +0900 Subject: [PATCH 34/53] Fix typo This PR is fixes typo "avaiable" to "available". --- tests/source/cfg_if/detect/arch/x86.rs | 2 +- tests/target/cfg_if/detect/arch/x86.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/source/cfg_if/detect/arch/x86.rs b/tests/source/cfg_if/detect/arch/x86.rs index 4c71a2c6ab90b..d26f4ee894fad 100644 --- a/tests/source/cfg_if/detect/arch/x86.rs +++ b/tests/source/cfg_if/detect/arch/x86.rs @@ -3,7 +3,7 @@ //! The features are detected using the `detect_features` function below. //! This function uses the CPUID instruction to read the feature flags from the //! CPU and encodes them in a `usize` where each bit position represents -//! whether a feature is available (bit is set) or unavaiable (bit is cleared). +//! whether a feature is available (bit is set) or unavailable (bit is cleared). //! //! The enum `Feature` is used to map bit positions to feature names, and the //! the `__crate::detect::check_for!` macro is used to map string literals (e.g., diff --git a/tests/target/cfg_if/detect/arch/x86.rs b/tests/target/cfg_if/detect/arch/x86.rs index b985dd8caa1ff..02d5eed1c2923 100644 --- a/tests/target/cfg_if/detect/arch/x86.rs +++ b/tests/target/cfg_if/detect/arch/x86.rs @@ -3,7 +3,7 @@ //! The features are detected using the `detect_features` function below. //! This function uses the CPUID instruction to read the feature flags from the //! CPU and encodes them in a `usize` where each bit position represents -//! whether a feature is available (bit is set) or unavaiable (bit is cleared). +//! whether a feature is available (bit is set) or unavailable (bit is cleared). //! //! The enum `Feature` is used to map bit positions to feature names, and the //! the `__crate::detect::check_for!` macro is used to map string literals (e.g., From 241a6f69309d177f0cb212851cbddcdf8ffdf10b Mon Sep 17 00:00:00 2001 From: Jacob Pratt Date: Fri, 20 May 2022 21:06:44 -0400 Subject: [PATCH 35/53] Remove `crate` visibility modifier in libs, tests --- tests/source/fn-simple.rs | 2 +- tests/source/pub-restricted.rs | 13 ------------- tests/target/fn-simple.rs | 2 +- tests/target/pub-restricted.rs | 13 ------------- 4 files changed, 2 insertions(+), 28 deletions(-) diff --git a/tests/source/fn-simple.rs b/tests/source/fn-simple.rs index 528b9a0292a9e..12a50c013a91f 100644 --- a/tests/source/fn-simple.rs +++ b/tests/source/fn-simple.rs @@ -63,7 +63,7 @@ mod foo { // #2082 pub(crate) fn init() {} -crate fn init() {} +pub(crate) fn init() {} // #2630 fn make_map String)>(records: &Vec, key_fn: F) -> HashMap {} diff --git a/tests/source/pub-restricted.rs b/tests/source/pub-restricted.rs index 30051fa72ee7d..5683acbf3aa93 100644 --- a/tests/source/pub-restricted.rs +++ b/tests/source/pub-restricted.rs @@ -24,19 +24,6 @@ pub( crate ) enum WriteState { WriteData(Writer), } - crate enum WriteState { - WriteId { - id: U64Writer, - size: U64Writer, - payload: Option>, - }, - WriteSize { - size: U64Writer, - payload: Option>, - }, - WriteData(Writer), -} - pub(in ::global:: path :: to::some_mod ) enum WriteState { WriteId { id: U64Writer, diff --git a/tests/target/fn-simple.rs b/tests/target/fn-simple.rs index 692739fa6a9f8..e725269360d2c 100644 --- a/tests/target/fn-simple.rs +++ b/tests/target/fn-simple.rs @@ -105,7 +105,7 @@ mod foo { // #2082 pub(crate) fn init() {} -crate fn init() {} +pub(crate) fn init() {} // #2630 fn make_map String)>(records: &Vec, key_fn: F) -> HashMap {} diff --git a/tests/target/pub-restricted.rs b/tests/target/pub-restricted.rs index 8cc2ade612afa..0e178ef10136e 100644 --- a/tests/target/pub-restricted.rs +++ b/tests/target/pub-restricted.rs @@ -24,19 +24,6 @@ pub(crate) enum WriteState { WriteData(Writer), } -crate enum WriteState { - WriteId { - id: U64Writer, - size: U64Writer, - payload: Option>, - }, - WriteSize { - size: U64Writer, - payload: Option>, - }, - WriteData(Writer), -} - pub(in global::path::to::some_mod) enum WriteState { WriteId { id: U64Writer, From 0d27f70743e12255804d40ff491108c8962bd7a3 Mon Sep 17 00:00:00 2001 From: Jacob Pratt Date: Sat, 21 May 2022 13:53:26 -0400 Subject: [PATCH 36/53] Remove feature: `crate` visibility modifier --- src/items.rs | 2 +- src/utils.rs | 13 ++++--------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/items.rs b/src/items.rs index ad2502b041840..ecbd44e197624 100644 --- a/src/items.rs +++ b/src/items.rs @@ -1361,7 +1361,7 @@ pub(crate) fn format_struct_struct( fn get_bytepos_after_visibility(vis: &ast::Visibility, default_span: Span) -> BytePos { match vis.kind { - ast::VisibilityKind::Crate(..) | ast::VisibilityKind::Restricted { .. } => vis.span.hi(), + ast::VisibilityKind::Crate | ast::VisibilityKind::Restricted { .. } => vis.span.hi(), _ => default_span.lo(), } } diff --git a/src/utils.rs b/src/utils.rs index ed418fb1fece6..4a66c168bb95d 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,7 +1,7 @@ use std::borrow::Cow; use rustc_ast::ast::{ - self, Attribute, CrateSugar, MetaItem, MetaItemKind, NestedMetaItem, NodeId, Path, Visibility, + self, Attribute, MetaItem, MetaItemKind, NestedMetaItem, NodeId, Path, Visibility, VisibilityKind, }; use rustc_ast::ptr; @@ -46,12 +46,8 @@ pub(crate) fn is_same_visibility(a: &Visibility, b: &Visibility) -> bool { (VisibilityKind::Public, VisibilityKind::Public) | (VisibilityKind::Inherited, VisibilityKind::Inherited) | ( - VisibilityKind::Crate(CrateSugar::PubCrate), - VisibilityKind::Crate(CrateSugar::PubCrate), - ) - | ( - VisibilityKind::Crate(CrateSugar::JustCrate), - VisibilityKind::Crate(CrateSugar::JustCrate), + VisibilityKind::Crate, + VisibilityKind::Crate, ) => true, _ => false, } @@ -65,8 +61,7 @@ pub(crate) fn format_visibility( match vis.kind { VisibilityKind::Public => Cow::from("pub "), VisibilityKind::Inherited => Cow::from(""), - VisibilityKind::Crate(CrateSugar::PubCrate) => Cow::from("pub(crate) "), - VisibilityKind::Crate(CrateSugar::JustCrate) => Cow::from("crate "), + VisibilityKind::Crate => Cow::from("pub(crate) "), VisibilityKind::Restricted { ref path, .. } => { let Path { ref segments, .. } = **path; let mut segments_iter = segments.iter().map(|seg| rewrite_ident(context, seg.ident)); From 9b697d0b90f2e6e021564454c5481e2b1b3c0df4 Mon Sep 17 00:00:00 2001 From: Jacob Pratt Date: Sat, 21 May 2022 14:45:14 -0400 Subject: [PATCH 37/53] Merge crate and restricted visibilities --- src/items.rs | 2 +- src/utils.rs | 9 ++------- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/items.rs b/src/items.rs index ecbd44e197624..8816d7d2f1fe2 100644 --- a/src/items.rs +++ b/src/items.rs @@ -1361,7 +1361,7 @@ pub(crate) fn format_struct_struct( fn get_bytepos_after_visibility(vis: &ast::Visibility, default_span: Span) -> BytePos { match vis.kind { - ast::VisibilityKind::Crate | ast::VisibilityKind::Restricted { .. } => vis.span.hi(), + ast::VisibilityKind::Restricted { .. } => vis.span.hi(), _ => default_span.lo(), } } diff --git a/src/utils.rs b/src/utils.rs index 4a66c168bb95d..58fd95c656e79 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -44,11 +44,7 @@ pub(crate) fn is_same_visibility(a: &Visibility, b: &Visibility) -> bool { VisibilityKind::Restricted { path: q, .. }, ) => pprust::path_to_string(p) == pprust::path_to_string(q), (VisibilityKind::Public, VisibilityKind::Public) - | (VisibilityKind::Inherited, VisibilityKind::Inherited) - | ( - VisibilityKind::Crate, - VisibilityKind::Crate, - ) => true, + | (VisibilityKind::Inherited, VisibilityKind::Inherited) => true, _ => false, } } @@ -61,7 +57,6 @@ pub(crate) fn format_visibility( match vis.kind { VisibilityKind::Public => Cow::from("pub "), VisibilityKind::Inherited => Cow::from(""), - VisibilityKind::Crate => Cow::from("pub(crate) "), VisibilityKind::Restricted { ref path, .. } => { let Path { ref segments, .. } = **path; let mut segments_iter = segments.iter().map(|seg| rewrite_ident(context, seg.ident)); @@ -70,7 +65,7 @@ pub(crate) fn format_visibility( .next() .expect("Non-global path in pub(restricted)?"); } - let is_keyword = |s: &str| s == "self" || s == "super"; + let is_keyword = |s: &str| s == "crate" || s == "self" || s == "super"; let path = segments_iter.collect::>().join("::"); let in_str = if is_keyword(&path) { "" } else { "in " }; From 0b6659cf02fd9bbdec1c0a5a90b48d1aff1ed5f8 Mon Sep 17 00:00:00 2001 From: Alexander Pozdneev Date: Sun, 22 May 2022 21:41:03 +0100 Subject: [PATCH 38/53] Update Configurations.md --- Configurations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Configurations.md b/Configurations.md index 7afd4b5cd6a97..5380275f8f9ad 100644 --- a/Configurations.md +++ b/Configurations.md @@ -10,7 +10,7 @@ reorder_imports = false ``` Each configuration option is either stable or unstable. -Stable options can be used directly, while unstable options are opt-in. +Stable options can always be used, while unstable ones are only available on a nightly toolchain, and opt-in. To enable unstable options, set `unstable_features = true` in `rustfmt.toml` or pass `--unstable-features` to rustfmt. # Configuration Options From 37b48ca4b20fa9873297bcef9f25abf3fcdbd475 Mon Sep 17 00:00:00 2001 From: Alexander Pozdneev Date: Mon, 23 May 2022 10:07:19 +0100 Subject: [PATCH 39/53] Update Configurations.md Co-authored-by: Yacin Tmimi --- Configurations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Configurations.md b/Configurations.md index 5380275f8f9ad..b3463fad19bd8 100644 --- a/Configurations.md +++ b/Configurations.md @@ -10,7 +10,7 @@ reorder_imports = false ``` Each configuration option is either stable or unstable. -Stable options can always be used, while unstable ones are only available on a nightly toolchain, and opt-in. +Stable options can always be used, while unstable options are only available on a nightly toolchain and must be opted into. To enable unstable options, set `unstable_features = true` in `rustfmt.toml` or pass `--unstable-features` to rustfmt. # Configuration Options From a5cfd4d14522ae064c55ac776731b069ae91bb9c Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Sat, 9 Apr 2022 00:31:24 -0400 Subject: [PATCH 40/53] Updated Unreleased CHANGELOG entries from revision v1.4.38..2d9bc460 --- CHANGELOG.md | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0db1dffd6e0a2..729c7516d1fef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,10 +2,62 @@ ## [Unreleased] -### Fixed +### Changed +- Also apply `empty_item_single_line=true` to trait definitions to match the behavior of empty functions, struct, enums, and impls [#5047](https://github.com/rust-lang/rustfmt/issues/5047) + +### Fixed + +- Block indent line breaks for type alias impl traits (TAITs) when `version = "Two"` [#5027](https://github.com/rust-lang/rustfmt/issues/5027) +- Retain trailing comments in module when using `#![rustfmt::skip]` [#5033](https://github.com/rust-lang/rustfmt/issues/5033) +- Remove trailing whitespace when formatting a where clause with an empty right hand side [#5012](https://github.com/rust-lang/rustfmt/issues/5012) [#4850](https://github.com/rust-lang/rustfmt/issues/4850) +- Fix various module resolution issues: + - Handle external mods imported via external->inline load hierarchy [#5063](https://github.com/rust-lang/rustfmt/issues/5063) + - Resolve sub modules of integration tests [#5119](https://github.com/rust-lang/rustfmt/issues/5119) + - Module resolution will fallback to the current search directory if a relative directory search results in a `FileNotFound` error [#5198](https://github.com/rust-lang/rustfmt/issues/5198) + - Give clearer error messsaeg when a module is found in two places (e.g `x.rs` and `x/mod.rs`) [#5167](https://github.com/rust-lang/rustfmt/issues/5167) +- Prevent rustfmt from adding an `impl Trait` definition into types [#5086](https://github.com/rust-lang/rustfmt/issues/5086) +- Correctly format associated type in macro body [#4823](https://github.com/rust-lang/rustfmt/issues/4823) +- Fix cases where `normalize_comments=true` would de-normalizes some comments [#4909](https://github.com/rust-lang/rustfmt/issues/4909) +- Prevent rustfmt from wrapping reference style links [#5095](https://github.com/rust-lang/rustfmt/issues/5095) and [#4933](https://github.com/rust-lang/rustfmt/issues/4933) +- Prevent rustfmt from always adding an empty comment line when formatting itemized blocks [#5088](https://github.com/rust-lang/rustfmt/issues/5088) +- Don't format files annotated with an inner `#![rustfmt::skip]` attribute [PR #5094](https://github.com/rust-lang/rustfmt/pull/5094) +- Remove duplicate comma when struct pattern ends with `..` and `trailing_comma=Always` [#5066](https://github.com/rust-lang/rustfmt/issues/5066) +- Fix static async closure qualifier order [#5149](https://github.com/rust-lang/rustfmt/issues/5149) +- Retain qualified path when rewriting struct literal expressions [#5151](https://github.com/rust-lang/rustfmt/issues/5151) +- Do not flatten match arm block with leading attributes [#4109](https://github.com/rust-lang/rustfmt/issues/4109) +- Backport json emitter and stdin changes [PR #5054](https://github.com/rust-lang/rustfmt/pull/5054) + - Make `--check` work when running rustfmt with input from stdin [PR #3896](https://github.com/rust-lang/rustfmt/pull/3896) + - Fix `--check` with the `--files-with-diff` flag [PR #3910](https://github.com/rust-lang/rustfmt/pull/3910) + - Produce valid JSON when using the JSON emitter [PR #3953](https://github.com/rust-lang/rustfmt/pull/3953) + - Fix newlines in JSON output [PR #4262](https://github.com/rust-lang/rustfmt/pull/4262) + - Use `` when emitting stdin as filename [PR #4298](https://github.com/rust-lang/rustfmt/pull/4298) +- Generate output when formatting `@generated` input via stdin [#5172](https://github.com/rust-lang/rustfmt/issues/5172) +- Fix comment indentation in empty structs [#4854](https://github.com/rust-lang/rustfmt/issues/4854) +- Prevent adding whitespace when rewriting `ast::Param` [#5125](https://github.com/rust-lang/rustfmt/issues/5125) +- Prevent panic when `wrap_comments=true` and non-ascii character at comment wrap boundary [#5023](https://github.com/rust-lang/rustfmt/issues/5023) +- Retain trailing commas in inline post comments [#5042](https://github.com/rust-lang/rustfmt/issues/5042) +- Fix `import_granularity` option when the use tree has an alias [#5131](https://github.com/rust-lang/rustfmt/issues/5131) +- Don't merge gereric items into their doc comments [#5122](https://github.com/rust-lang/rustfmt/issues/5122) - 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) +- Handle markdown block quotes when `wrap_comments=true` [#5157](https://github.com/rust-lang/rustfmt/issues/5157) +- Long markdown headers are no longer wrapped when `wrap_comments=true` [#5238](https://github.com/rust-lang/rustfmt/issues/5238) +- Retain trailing comma when struct fields are followed by an empty line [#4791](https://github.com/rust-lang/rustfmt/issues/4791) [#4928](https://github.com/rust-lang/rustfmt/issues/4928) +- Fix compile error when `imports_granularity=Module` and path contains self [#4681](https://github.com/rust-lang/rustfmt/issues/4681) - Fixes an issue where types would be incorrectly wrapped in comments [#5260](https://github.com/rust-lang/rustfmt/issues/5260) +- Don't duplicate parts of `const` expressions when formatting generic arguments [#5273](https://github.com/rust-lang/rustfmt/issues/5273) +- Prevent merging derives when using `#[rustfmt::skip::attributes(derive)]` [#5270](https://github.com/rust-lang/rustfmt/issues/5270) +- Retain trailing `;` when rewriting macro call in extern block [#5281](https://github.com/rust-lang/rustfmt/issues/5281) +- Add a newline when formatting struct fields preceeded by doc comments and inline comments [#5215](https://github.com/rust-lang/rustfmt/issues/5215) + +### Added + +- Added `One` as a new [group_imports](https://rust-lang.github.io/rustfmt/?version=v1.4.38&search=#group_imports) option to create a single group for all imports [PR #4966](https://github.com/rust-lang/rustfmt/pull/4966) +- Add [short_array_element_width_threshold](https://rust-lang.github.io/rustfmt/?version=v1.4.38&search=#short_array_element_width_threshold) config option [PR #5228](https://github.com/rust-lang/rustfmt/pull/5228) + +### Removed + +- Remove rustfmt executable path from usage string [#5214](https://github.com/rust-lang/rustfmt/issues/5214) ## [1.4.38] 2021-10-20 From 73be264f9f8be070bd2764323911f94f1529db4d Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Thu, 26 May 2022 16:06:46 -0400 Subject: [PATCH 41/53] Rephrase changelog entries to give more context --- CHANGELOG.md | 72 +++++++++++++++++++++++++++------------------------- 1 file changed, 37 insertions(+), 35 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 729c7516d1fef..e729bfb848682 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,60 +4,62 @@ ### Changed -- Also apply `empty_item_single_line=true` to trait definitions to match the behavior of empty functions, struct, enums, and impls [#5047](https://github.com/rust-lang/rustfmt/issues/5047) +- Also apply `empty_item_single_line=true` to trait definitions to match the behavior of empty functions, structs, enums, and impls [#5047](https://github.com/rust-lang/rustfmt/issues/5047) ### Fixed -- Block indent line breaks for type alias impl traits (TAITs) when `version = "Two"` [#5027](https://github.com/rust-lang/rustfmt/issues/5027) -- Retain trailing comments in module when using `#![rustfmt::skip]` [#5033](https://github.com/rust-lang/rustfmt/issues/5033) -- Remove trailing whitespace when formatting a where clause with an empty right hand side [#5012](https://github.com/rust-lang/rustfmt/issues/5012) [#4850](https://github.com/rust-lang/rustfmt/issues/4850) -- Fix various module resolution issues: +- Prevent rustfmt from removing trailing comments at the end of files annotated with inner `#![rustfmt::skip]` attributes [#5033](https://github.com/rust-lang/rustfmt/issues/5033) +- Fixed various `error[internal]: left behind trailing whitespace"` issues: + - Remove trailing whitespace when formatting a where clause who's bounds have an empty right hand side [#5012](https://github.com/rust-lang/rustfmt/issues/5012) [#4850](https://github.com/rust-lang/rustfmt/issues/4850) + - Prevent rustfmt from adding an empty comment line when rewriting markdown lists at the start of doc comments. This issue was triggered when `wrap_comments=true` [#5088](https://github.com/rust-lang/rustfmt/issues/5088) +- Prevent adding a block indented newline before a function parameter with a complex type that was formatted over multiple lines [#5125](https://github.com/rust-lang/rustfmt/issues/5125) +- Fix various module resolution issues preventing rustfmt from finding modules that should be formatted: - Handle external mods imported via external->inline load hierarchy [#5063](https://github.com/rust-lang/rustfmt/issues/5063) - Resolve sub modules of integration tests [#5119](https://github.com/rust-lang/rustfmt/issues/5119) - Module resolution will fallback to the current search directory if a relative directory search results in a `FileNotFound` error [#5198](https://github.com/rust-lang/rustfmt/issues/5198) - - Give clearer error messsaeg when a module is found in two places (e.g `x.rs` and `x/mod.rs`) [#5167](https://github.com/rust-lang/rustfmt/issues/5167) -- Prevent rustfmt from adding an `impl Trait` definition into types [#5086](https://github.com/rust-lang/rustfmt/issues/5086) -- Correctly format associated type in macro body [#4823](https://github.com/rust-lang/rustfmt/issues/4823) -- Fix cases where `normalize_comments=true` would de-normalizes some comments [#4909](https://github.com/rust-lang/rustfmt/issues/4909) -- Prevent rustfmt from wrapping reference style links [#5095](https://github.com/rust-lang/rustfmt/issues/5095) and [#4933](https://github.com/rust-lang/rustfmt/issues/4933) -- Prevent rustfmt from always adding an empty comment line when formatting itemized blocks [#5088](https://github.com/rust-lang/rustfmt/issues/5088) -- Don't format files annotated with an inner `#![rustfmt::skip]` attribute [PR #5094](https://github.com/rust-lang/rustfmt/pull/5094) -- Remove duplicate comma when struct pattern ends with `..` and `trailing_comma=Always` [#5066](https://github.com/rust-lang/rustfmt/issues/5066) -- Fix static async closure qualifier order [#5149](https://github.com/rust-lang/rustfmt/issues/5149) -- Retain qualified path when rewriting struct literal expressions [#5151](https://github.com/rust-lang/rustfmt/issues/5151) -- Do not flatten match arm block with leading attributes [#4109](https://github.com/rust-lang/rustfmt/issues/4109) +- Give users a clearer error message when resolving a module who's file path is ambiguous (e.g `x.rs` and `x/mod.rs`). Before users were given a `File not found` error message which was confusing [#5167](https://github.com/rust-lang/rustfmt/issues/5167) +- Fix various issues related to type aliases: + - Prevent rustfmt from adding `= impl` to associated types defined in macro bodies [#4823](https://github.com/rust-lang/rustfmt/issues/4823) + - Properly block indent type alias impl traits (TAITs) that wrap to the next line when `version=Two` is set. Before any trait bounds that wrapped to the next line would not be indented [#5027](https://github.com/rust-lang/rustfmt/issues/5027) + - Prevent rustfmt from adding an `impl Trait` definition into types [#5086](https://github.com/rust-lang/rustfmt/issues/5086) +- Fix cases where `normalize_comments=true` would de-normalizes some comments by changing inline comments into block comments [#4909](https://github.com/rust-lang/rustfmt/issues/4909) +- Prevent rustfmt from wrapping the content of markdown [reference-style links](https://www.markdownguide.org/basic-syntax/#reference-style-links) in doc comments [#5095](https://github.com/rust-lang/rustfmt/issues/5095) [#4933](https://github.com/rust-lang/rustfmt/issues/4933) +- Don't format files annotated with inner `#![rustfmt::skip]` attribute [PR #5094](https://github.com/rust-lang/rustfmt/pull/5094) +- Prevent duplicate comma when struct pattern ends with `..` and `trailing_comma=Always`. For example, `let Foo { a, .. } = b;` would become `let Foo { a,, .. } = b;` [#5066](https://github.com/rust-lang/rustfmt/issues/5066) +- Fix the order of `static` and `async` keywords when rewriting static async closures. The correct order is `static` and then `async` (e.g `static async || {}`) [#5149](https://github.com/rust-lang/rustfmt/issues/5149) +- Retain the fully qualified path segment when rewriting struct literals in expression position. Now `::Type` is not rewritten as `Trait::Type` [#5151](https://github.com/rust-lang/rustfmt/issues/5151) +- Do not remove match arm braces from a match arm with a single `ast::ExprKind::Block` that has leading attributes. Removing the braces could lead to code that does not compile. Now rustfmt will leave the outer `{}` in place when formatting `=> {#[allow(unsafe_code)]unsafe {}}` [#4109](https://github.com/rust-lang/rustfmt/issues/4109) - Backport json emitter and stdin changes [PR #5054](https://github.com/rust-lang/rustfmt/pull/5054) - Make `--check` work when running rustfmt with input from stdin [PR #3896](https://github.com/rust-lang/rustfmt/pull/3896) - Fix `--check` with the `--files-with-diff` flag [PR #3910](https://github.com/rust-lang/rustfmt/pull/3910) - Produce valid JSON when using the JSON emitter [PR #3953](https://github.com/rust-lang/rustfmt/pull/3953) - Fix newlines in JSON output [PR #4262](https://github.com/rust-lang/rustfmt/pull/4262) - Use `` when emitting stdin as filename [PR #4298](https://github.com/rust-lang/rustfmt/pull/4298) -- Generate output when formatting `@generated` input via stdin [#5172](https://github.com/rust-lang/rustfmt/issues/5172) -- Fix comment indentation in empty structs [#4854](https://github.com/rust-lang/rustfmt/issues/4854) -- Prevent adding whitespace when rewriting `ast::Param` [#5125](https://github.com/rust-lang/rustfmt/issues/5125) -- Prevent panic when `wrap_comments=true` and non-ascii character at comment wrap boundary [#5023](https://github.com/rust-lang/rustfmt/issues/5023) -- Retain trailing commas in inline post comments [#5042](https://github.com/rust-lang/rustfmt/issues/5042) -- Fix `import_granularity` option when the use tree has an alias [#5131](https://github.com/rust-lang/rustfmt/issues/5131) -- Don't merge gereric items into their doc comments [#5122](https://github.com/rust-lang/rustfmt/issues/5122) -- 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) -- Handle markdown block quotes when `wrap_comments=true` [#5157](https://github.com/rust-lang/rustfmt/issues/5157) -- Long markdown headers are no longer wrapped when `wrap_comments=true` [#5238](https://github.com/rust-lang/rustfmt/issues/5238) -- Retain trailing comma when struct fields are followed by an empty line [#4791](https://github.com/rust-lang/rustfmt/issues/4791) [#4928](https://github.com/rust-lang/rustfmt/issues/4928) -- Fix compile error when `imports_granularity=Module` and path contains self [#4681](https://github.com/rust-lang/rustfmt/issues/4681) -- Fixes an issue where types would be incorrectly wrapped in comments [#5260](https://github.com/rust-lang/rustfmt/issues/5260) -- Don't duplicate parts of `const` expressions when formatting generic arguments [#5273](https://github.com/rust-lang/rustfmt/issues/5273) -- Prevent merging derives when using `#[rustfmt::skip::attributes(derive)]` [#5270](https://github.com/rust-lang/rustfmt/issues/5270) -- Retain trailing `;` when rewriting macro call in extern block [#5281](https://github.com/rust-lang/rustfmt/issues/5281) -- Add a newline when formatting struct fields preceeded by doc comments and inline comments [#5215](https://github.com/rust-lang/rustfmt/issues/5215) +- Always generate some output when formatting `@generated` files via stdin even when `format_generated_files=false`. Not producing output caused rust-analyzer to delete the file content [rust-lang/rust-analyzer](https://github.com/rust-lang/rust-analyzer/issues/11285) [#5172](https://github.com/rust-lang/rustfmt/issues/5172) +- Properly block indent multi-line comments in empty struct definitions. Previously, only the first comment line would be block indented. All other comment lines would be aligned with the struct definition [#4854](https://github.com/rust-lang/rustfmt/issues/4854) +- Prevent rustfmt from wrapping a comment at a byte position inside a non-ascii character when `wrap_comments=true`. This prevents rustfmt from panicking when breaking on the invalid position [#5023](https://github.com/rust-lang/rustfmt/issues/5023) +- Prevent rustfmt from removing commented out trailing separators (e.g commas) when rewriting lists. For example, remove the comma from a comment like this `// ...,` would lead to a scenario where the entire list could not be rewritten because the content of the comment changed [#5042](https://github.com/rust-lang/rustfmt/issues/5042) +- Fix panic when `import_granularity` was set to `Module`, `One`, or `Crate` and the import use declaration contained an alias `use crate a::b as b1` [#5131](https://github.com/rust-lang/rustfmt/issues/5131) +- Add a newline between generic parameters and their doc comments to prevent the generic parameters from being merged into their doc comments [#5122](https://github.com/rust-lang/rustfmt/issues/5122) +- Fixes indentation issue where string literals manually broken with line continuation characters (`\`) would be incorrectly indented in macro definitions when setting `format_strings=true`[#4036](https://github.com/rust-lang/rustfmt/issues/4036) +- Properly wrap and format long markdown block quotes when `wrap_comments=true` [#5157](https://github.com/rust-lang/rustfmt/issues/5157) +- Prevent rustfmt from wrapping markdown headers even when `wrap_comments=true`. Wrapping the markdown headers would prevent them from being properly rendered with rustdoc [#5238](https://github.com/rust-lang/rustfmt/issues/5238) +- Prevent rustfmt from removing commas between struct fields when those fields were also separated by an empty line [#4791](https://github.com/rust-lang/rustfmt/issues/4791) [#4928](https://github.com/rust-lang/rustfmt/issues/4928) +- Fix compiler error caused when formatting imports with `imports_granularity=Module` and a path containing `self`. Given the following import `use crate::lexer::{self, tokens::TokenData};`, rustfmt would transform the `self` import into `use crate::lexer::self;`. Now rustfmt produces `use crate::lexer::{self};` [#4681](https://github.com/rust-lang/rustfmt/issues/4681) +- Prevent rustfmt from breaking long type links in doc comments on namespace qualifiers (`::`) when `wrap_comments=true`. Breaking these long type links over multiple lines prevented them from being properly rendered in rustdoc [#5260](https://github.com/rust-lang/rustfmt/issues/5260) +- Correctly find the start of struct bodies after any generic `const` parameters. Naively searching for an opening `{` lead to issues since generic `const` parameters are also defined with `{}` (e.g. `struct Example {}`) [#5273](https://github.com/rust-lang/rustfmt/issues/5273) +- Prevent rustfmt from merging derives when using inner or outer `rustfmt::skip::attributes` attributes. For example, `#[rustfmt::skip::attributes(derive)]` [#5270](https://github.com/rust-lang/rustfmt/issues/5270) +- Retain trailing `;` when rewriting macro calls in extern blocks. For example, `extern "C" { x!(-); }`[#5281](https://github.com/rust-lang/rustfmt/issues/5281) +- Add a newline when formatting struct fields preceded by both doc comments and inline comments to prevent the field from being merged into the inline comment. This was not an issue when a struct was preceded by just a doc comment or just an inline comment [#5215](https://github.com/rust-lang/rustfmt/issues/5215) ### Added - Added `One` as a new [group_imports](https://rust-lang.github.io/rustfmt/?version=v1.4.38&search=#group_imports) option to create a single group for all imports [PR #4966](https://github.com/rust-lang/rustfmt/pull/4966) -- Add [short_array_element_width_threshold](https://rust-lang.github.io/rustfmt/?version=v1.4.38&search=#short_array_element_width_threshold) config option [PR #5228](https://github.com/rust-lang/rustfmt/pull/5228) +- Add [short_array_element_width_threshold](https://rust-lang.github.io/rustfmt/?version=v1.4.38&search=#short_array_element_width_threshold) config option to give users more control over when `Mixed` list formatting is used [PR #5228](https://github.com/rust-lang/rustfmt/pull/5228) ### Removed -- Remove rustfmt executable path from usage string [#5214](https://github.com/rust-lang/rustfmt/issues/5214) +- Remove rustfmt binary path from the usage string when running `rustfmt --help` [#5214](https://github.com/rust-lang/rustfmt/issues/5214) ## [1.4.38] 2021-10-20 From 3e38399ed89da3b7ed68b062ad82bdc0f2068685 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Thu, 26 May 2022 21:56:35 -0500 Subject: [PATCH 42/53] docs: clarify imports_granularity behavior with comments --- CHANGELOG.md | 1 + Configurations.md | 2 ++ 2 files changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e729bfb848682..3664571fe64bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ ### Fixed +- Don't change granularity of imports containing comments with `imports_granularity` if doing so could lose or misplace those comments [#5311](https://github.com/rust-lang/rustfmt/pull/5311) - Prevent rustfmt from removing trailing comments at the end of files annotated with inner `#![rustfmt::skip]` attributes [#5033](https://github.com/rust-lang/rustfmt/issues/5033) - Fixed various `error[internal]: left behind trailing whitespace"` issues: - Remove trailing whitespace when formatting a where clause who's bounds have an empty right hand side [#5012](https://github.com/rust-lang/rustfmt/issues/5012) [#4850](https://github.com/rust-lang/rustfmt/issues/4850) diff --git a/Configurations.md b/Configurations.md index b3463fad19bd8..669da79087c9a 100644 --- a/Configurations.md +++ b/Configurations.md @@ -1705,6 +1705,8 @@ How imports should be grouped into `use` statements. Imports will be merged or s - **Possible values**: `Preserve`, `Crate`, `Module`, `Item`, `One` - **Stable**: No (tracking issue: [#4991](https://github.com/rust-lang/rustfmt/issues/4991)) +Note that rustfmt will not modify the granularity of imports containing comments if doing so could potentially lose or misplace said comments. + #### `Preserve` (default): Do not change the granularity of any imports and preserve the original structure written by the developer. From 4c8db8593905d09a872601c445005a594ac632dc Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Sun, 29 May 2022 21:35:12 -0500 Subject: [PATCH 43/53] feat: remove report_todo option --- Configurations.md | 17 ------ src/config/mod.rs | 3 - src/formatting.rs | 4 +- src/issues.rs | 110 ++++++----------------------------- src/test/mod.rs | 5 +- tests/config/small_tabs.toml | 1 - 6 files changed, 20 insertions(+), 120 deletions(-) diff --git a/Configurations.md b/Configurations.md index 669da79087c9a..72499618755e9 100644 --- a/Configurations.md +++ b/Configurations.md @@ -2180,23 +2180,6 @@ Warns about any comments containing `FIXME` in them when set to `"Always"`. If it contains a `#X` (with `X` being a number) in parentheses following the `FIXME`, `"Unnumbered"` will ignore it. -See also [`report_todo`](#report_todo). - - -## `report_todo` - -Report `TODO` items in comments. - -- **Default value**: `"Never"` -- **Possible values**: `"Always"`, `"Unnumbered"`, `"Never"` -- **Stable**: No (tracking issue: [#3393](https://github.com/rust-lang/rustfmt/issues/3393)) - -Warns about any comments containing `TODO` in them when set to `"Always"`. If -it contains a `#X` (with `X` being a number) in parentheses following the -`TODO`, `"Unnumbered"` will ignore it. - -See also [`report_fixme`](#report_fixme). - ## `required_version` Require a specific version of rustfmt. If you want to make sure that the diff --git a/src/config/mod.rs b/src/config/mod.rs index 18e1854612bf7..4c14d7356891d 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -164,8 +164,6 @@ create_config! { error_on_unformatted: bool, false, false, "Error if unable to get comments or string literals within max_width, \ or they are left with trailing whitespaces"; - report_todo: ReportTactic, ReportTactic::Never, false, - "Report all, none or unnumbered occurrences of TODO in source file comments"; report_fixme: ReportTactic, ReportTactic::Never, false, "Report all, none or unnumbered occurrences of FIXME in source file comments"; ignore: IgnoreList, IgnoreList::default(), false, @@ -625,7 +623,6 @@ skip_children = false hide_parse_errors = false error_on_line_overflow = false error_on_unformatted = false -report_todo = "Never" report_fixme = "Never" ignore = [] emit_mode = "Files" diff --git a/src/formatting.rs b/src/formatting.rs index 281d3e4e808a5..8e6999643b1e5 100644 --- a/src/formatting.rs +++ b/src/formatting.rs @@ -497,7 +497,7 @@ impl<'a> FormatLines<'a> { skipped_range: &'a [(usize, usize)], config: &'a Config, ) -> FormatLines<'a> { - let issue_seeker = BadIssueSeeker::new(config.report_todo(), config.report_fixme()); + let issue_seeker = BadIssueSeeker::new(config.report_fixme()); FormatLines { name, skipped_range, @@ -537,7 +537,7 @@ impl<'a> FormatLines<'a> { } if self.allow_issue_seek && self.format_line { - // Add warnings for bad todos/ fixmes + // Add warnings for bad fixmes if let Some(issue) = self.issue_seeker.inspect(c) { self.push_err(ErrorKind::BadIssue(issue), false, false); } diff --git a/src/issues.rs b/src/issues.rs index 33fb5522aeae5..3c39d813a6f9d 100644 --- a/src/issues.rs +++ b/src/issues.rs @@ -6,7 +6,6 @@ use std::fmt; use crate::config::ReportTactic; -const TO_DO_CHARS: &[char] = &['t', 'o', 'd', 'o']; const FIX_ME_CHARS: &[char] = &['f', 'i', 'x', 'm', 'e']; // Enabled implementation detail is here because it is @@ -17,7 +16,7 @@ fn is_enabled(report_tactic: ReportTactic) -> bool { #[derive(Clone, Copy)] enum Seeking { - Issue { todo_idx: usize, fixme_idx: usize }, + Issue { fixme_idx: usize }, Number { issue: Issue, part: NumberPart }, } @@ -40,7 +39,6 @@ pub struct Issue { impl fmt::Display for Issue { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { let msg = match self.issue_type { - IssueType::Todo => "TODO", IssueType::Fixme => "FIXME", }; let details = if self.missing_number { @@ -55,7 +53,6 @@ impl fmt::Display for Issue { #[derive(PartialEq, Eq, Debug, Clone, Copy)] enum IssueType { - Todo, Fixme, } @@ -67,35 +64,27 @@ enum IssueClassification { pub(crate) struct BadIssueSeeker { state: Seeking, - report_todo: ReportTactic, report_fixme: ReportTactic, } impl BadIssueSeeker { - pub(crate) fn new(report_todo: ReportTactic, report_fixme: ReportTactic) -> BadIssueSeeker { + pub(crate) fn new(report_fixme: ReportTactic) -> BadIssueSeeker { BadIssueSeeker { - state: Seeking::Issue { - todo_idx: 0, - fixme_idx: 0, - }, - report_todo, + state: Seeking::Issue { fixme_idx: 0 }, report_fixme, } } pub(crate) fn is_disabled(&self) -> bool { - !is_enabled(self.report_todo) && !is_enabled(self.report_fixme) + !is_enabled(self.report_fixme) } // Check whether or not the current char is conclusive evidence for an // unnumbered TO-DO or FIX-ME. pub(crate) fn inspect(&mut self, c: char) -> Option { match self.state { - Seeking::Issue { - todo_idx, - fixme_idx, - } => { - self.state = self.inspect_issue(c, todo_idx, fixme_idx); + Seeking::Issue { fixme_idx } => { + self.state = self.inspect_issue(c, fixme_idx); } Seeking::Number { issue, part } => { let result = self.inspect_number(c, issue, part); @@ -104,10 +93,7 @@ impl BadIssueSeeker { return None; } - self.state = Seeking::Issue { - todo_idx: 0, - fixme_idx: 0, - }; + self.state = Seeking::Issue { fixme_idx: 0 }; if let IssueClassification::Bad(issue) = result { return Some(issue); @@ -118,21 +104,9 @@ impl BadIssueSeeker { None } - fn inspect_issue(&mut self, c: char, mut todo_idx: usize, mut fixme_idx: usize) -> Seeking { + fn inspect_issue(&mut self, c: char, mut fixme_idx: usize) -> Seeking { if let Some(lower_case_c) = c.to_lowercase().next() { - if is_enabled(self.report_todo) && lower_case_c == TO_DO_CHARS[todo_idx] { - todo_idx += 1; - if todo_idx == TO_DO_CHARS.len() { - return Seeking::Number { - issue: Issue { - issue_type: IssueType::Todo, - missing_number: matches!(self.report_todo, ReportTactic::Unnumbered), - }, - part: NumberPart::OpenParen, - }; - } - fixme_idx = 0; - } else if is_enabled(self.report_fixme) && lower_case_c == FIX_ME_CHARS[fixme_idx] { + if is_enabled(self.report_fixme) && lower_case_c == FIX_ME_CHARS[fixme_idx] { // Exploit the fact that the character sets of todo and fixme // are disjoint by adding else. fixme_idx += 1; @@ -145,17 +119,12 @@ impl BadIssueSeeker { part: NumberPart::OpenParen, }; } - todo_idx = 0; } else { - todo_idx = 0; fixme_idx = 0; } } - Seeking::Issue { - todo_idx, - fixme_idx, - } + Seeking::Issue { fixme_idx } } fn inspect_number( @@ -206,7 +175,7 @@ impl BadIssueSeeker { #[test] fn find_unnumbered_issue() { fn check_fail(text: &str, failing_pos: usize) { - let mut seeker = BadIssueSeeker::new(ReportTactic::Unnumbered, ReportTactic::Unnumbered); + let mut seeker = BadIssueSeeker::new(ReportTactic::Unnumbered); assert_eq!( Some(failing_pos), text.find(|c| seeker.inspect(c).is_some()) @@ -214,12 +183,10 @@ fn find_unnumbered_issue() { } fn check_pass(text: &str) { - let mut seeker = BadIssueSeeker::new(ReportTactic::Unnumbered, ReportTactic::Unnumbered); + let mut seeker = BadIssueSeeker::new(ReportTactic::Unnumbered); assert_eq!(None, text.find(|c| seeker.inspect(c).is_some())); } - check_fail("TODO\n", 4); - check_pass(" TO FIX DOME\n"); check_fail(" \n FIXME\n", 8); check_fail("FIXME(\n", 6); check_fail("FIXME(#\n", 7); @@ -228,71 +195,28 @@ fn find_unnumbered_issue() { check_pass("FIXME(#1222)\n"); check_fail("FIXME(#12\n22)\n", 9); check_pass("FIXME(@maintainer, #1222, hello)\n"); - check_fail("TODO(#22) FIXME\n", 15); } #[test] fn find_issue() { - fn is_bad_issue(text: &str, report_todo: ReportTactic, report_fixme: ReportTactic) -> bool { - let mut seeker = BadIssueSeeker::new(report_todo, report_fixme); + fn is_bad_issue(text: &str, report_fixme: ReportTactic) -> bool { + let mut seeker = BadIssueSeeker::new(report_fixme); text.chars().any(|c| seeker.inspect(c).is_some()) } - assert!(is_bad_issue( - "TODO(@maintainer, #1222, hello)\n", - ReportTactic::Always, - ReportTactic::Never, - )); - - assert!(!is_bad_issue( - "TODO: no number\n", - ReportTactic::Never, - ReportTactic::Always, - )); - - assert!(!is_bad_issue( - "Todo: mixed case\n", - ReportTactic::Never, - ReportTactic::Always, - )); - - assert!(is_bad_issue( - "This is a FIXME(#1)\n", - ReportTactic::Never, - ReportTactic::Always, - )); + assert!(is_bad_issue("This is a FIXME(#1)\n", ReportTactic::Always)); assert!(is_bad_issue( "This is a FixMe(#1) mixed case\n", - ReportTactic::Never, ReportTactic::Always, )); - assert!(!is_bad_issue( - "bad FIXME\n", - ReportTactic::Always, - ReportTactic::Never, - )); + assert!(!is_bad_issue("bad FIXME\n", ReportTactic::Never)); } #[test] fn issue_type() { - let mut seeker = BadIssueSeeker::new(ReportTactic::Always, ReportTactic::Never); - let expected = Some(Issue { - issue_type: IssueType::Todo, - missing_number: false, - }); - - assert_eq!( - expected, - "TODO(#100): more awesomeness" - .chars() - .map(|c| seeker.inspect(c)) - .find(Option::is_some) - .unwrap() - ); - - let mut seeker = BadIssueSeeker::new(ReportTactic::Never, ReportTactic::Unnumbered); + let mut seeker = BadIssueSeeker::new(ReportTactic::Unnumbered); let expected = Some(Issue { issue_type: IssueType::Fixme, missing_number: true, diff --git a/src/test/mod.rs b/src/test/mod.rs index 4bad8e71481e8..0eda9e4b116a3 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -9,7 +9,7 @@ use std::process::{Command, Stdio}; use std::str::Chars; use std::thread; -use crate::config::{Color, Config, EmitMode, FileName, NewlineStyle, ReportTactic}; +use crate::config::{Color, Config, EmitMode, FileName, NewlineStyle}; use crate::formatting::{ReportedErrors, SourceFile}; use crate::rustfmt_diff::{make_diff, print_diff, DiffLine, Mismatch, ModifiedChunk, OutputWriter}; use crate::source_file; @@ -688,9 +688,6 @@ fn read_config(filename: &Path) -> Config { } } - // Don't generate warnings for to-do items. - config.set().report_todo(ReportTactic::Never); - config } diff --git a/tests/config/small_tabs.toml b/tests/config/small_tabs.toml index 35c8fd8646765..598edda6abee4 100644 --- a/tests/config/small_tabs.toml +++ b/tests/config/small_tabs.toml @@ -6,7 +6,6 @@ brace_style = "SameLineWhere" fn_args_layout = "Tall" trailing_comma = "Vertical" indent_style = "Block" -report_todo = "Always" report_fixme = "Never" reorder_imports = false format_strings = true From 825561deb86524107f1c22b59bddb16703d2c790 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Sun, 29 May 2022 21:48:59 -0500 Subject: [PATCH 44/53] feat: remove report_fixme option --- Configurations.md | 12 ------ src/config/mod.rs | 3 -- src/formatting.rs | 2 +- src/issues.rs | 84 ++++++++---------------------------- tests/config/small_tabs.toml | 1 - 5 files changed, 19 insertions(+), 83 deletions(-) diff --git a/Configurations.md b/Configurations.md index 72499618755e9..edb2d1f757518 100644 --- a/Configurations.md +++ b/Configurations.md @@ -2168,18 +2168,6 @@ mod sit; **Note** `mod` with `#[macro_export]` will not be reordered since that could change the semantics of the original source code. -## `report_fixme` - -Report `FIXME` items in comments. - -- **Default value**: `"Never"` -- **Possible values**: `"Always"`, `"Unnumbered"`, `"Never"` -- **Stable**: No (tracking issue: [#3394](https://github.com/rust-lang/rustfmt/issues/3394)) - -Warns about any comments containing `FIXME` in them when set to `"Always"`. If -it contains a `#X` (with `X` being a number) in parentheses following the -`FIXME`, `"Unnumbered"` will ignore it. - ## `required_version` Require a specific version of rustfmt. If you want to make sure that the diff --git a/src/config/mod.rs b/src/config/mod.rs index 4c14d7356891d..fc724beae60a7 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -164,8 +164,6 @@ create_config! { error_on_unformatted: bool, false, false, "Error if unable to get comments or string literals within max_width, \ or they are left with trailing whitespaces"; - report_fixme: ReportTactic, ReportTactic::Never, false, - "Report all, none or unnumbered occurrences of FIXME in source file comments"; ignore: IgnoreList, IgnoreList::default(), false, "Skip formatting the specified files and directories"; @@ -623,7 +621,6 @@ skip_children = false hide_parse_errors = false error_on_line_overflow = false error_on_unformatted = false -report_fixme = "Never" ignore = [] emit_mode = "Files" make_backup = false diff --git a/src/formatting.rs b/src/formatting.rs index 8e6999643b1e5..72bbe240f7b9c 100644 --- a/src/formatting.rs +++ b/src/formatting.rs @@ -497,7 +497,7 @@ impl<'a> FormatLines<'a> { skipped_range: &'a [(usize, usize)], config: &'a Config, ) -> FormatLines<'a> { - let issue_seeker = BadIssueSeeker::new(config.report_fixme()); + let issue_seeker = BadIssueSeeker::new(); FormatLines { name, skipped_range, diff --git a/src/issues.rs b/src/issues.rs index 3c39d813a6f9d..d95a80fe7fd95 100644 --- a/src/issues.rs +++ b/src/issues.rs @@ -6,8 +6,6 @@ use std::fmt; use crate::config::ReportTactic; -const FIX_ME_CHARS: &[char] = &['f', 'i', 'x', 'm', 'e']; - // Enabled implementation detail is here because it is // irrelevant outside the issues module fn is_enabled(report_tactic: ReportTactic) -> bool { @@ -16,7 +14,7 @@ fn is_enabled(report_tactic: ReportTactic) -> bool { #[derive(Clone, Copy)] enum Seeking { - Issue { fixme_idx: usize }, + Issue {}, Number { issue: Issue, part: NumberPart }, } @@ -30,7 +28,7 @@ enum NumberPart { #[derive(PartialEq, Eq, Debug, Clone, Copy)] pub struct Issue { - issue_type: IssueType, + issue_type: Option, // Indicates whether we're looking for issues with missing numbers, or // all issues of this type. missing_number: bool, @@ -39,7 +37,7 @@ pub struct Issue { impl fmt::Display for Issue { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { let msg = match self.issue_type { - IssueType::Fixme => "FIXME", + _ => "", }; let details = if self.missing_number { " without issue number" @@ -52,9 +50,7 @@ impl fmt::Display for Issue { } #[derive(PartialEq, Eq, Debug, Clone, Copy)] -enum IssueType { - Fixme, -} +enum IssueType {} enum IssueClassification { Good, @@ -64,27 +60,25 @@ enum IssueClassification { pub(crate) struct BadIssueSeeker { state: Seeking, - report_fixme: ReportTactic, } impl BadIssueSeeker { - pub(crate) fn new(report_fixme: ReportTactic) -> BadIssueSeeker { + pub(crate) fn new() -> BadIssueSeeker { BadIssueSeeker { - state: Seeking::Issue { fixme_idx: 0 }, - report_fixme, + state: Seeking::Issue {}, } } pub(crate) fn is_disabled(&self) -> bool { - !is_enabled(self.report_fixme) + true } // Check whether or not the current char is conclusive evidence for an // unnumbered TO-DO or FIX-ME. pub(crate) fn inspect(&mut self, c: char) -> Option { match self.state { - Seeking::Issue { fixme_idx } => { - self.state = self.inspect_issue(c, fixme_idx); + Seeking::Issue {} => { + self.state = self.inspect_issue(c, 0); } Seeking::Number { issue, part } => { let result = self.inspect_number(c, issue, part); @@ -93,7 +87,7 @@ impl BadIssueSeeker { return None; } - self.state = Seeking::Issue { fixme_idx: 0 }; + self.state = Seeking::Issue {}; if let IssueClassification::Bad(issue) = result { return Some(issue); @@ -106,25 +100,10 @@ impl BadIssueSeeker { fn inspect_issue(&mut self, c: char, mut fixme_idx: usize) -> Seeking { if let Some(lower_case_c) = c.to_lowercase().next() { - if is_enabled(self.report_fixme) && lower_case_c == FIX_ME_CHARS[fixme_idx] { - // Exploit the fact that the character sets of todo and fixme - // are disjoint by adding else. - fixme_idx += 1; - if fixme_idx == FIX_ME_CHARS.len() { - return Seeking::Number { - issue: Issue { - issue_type: IssueType::Fixme, - missing_number: matches!(self.report_fixme, ReportTactic::Unnumbered), - }, - part: NumberPart::OpenParen, - }; - } - } else { - fixme_idx = 0; - } + fixme_idx = 0; } - Seeking::Issue { fixme_idx } + Seeking::Issue {} } fn inspect_number( @@ -175,7 +154,7 @@ impl BadIssueSeeker { #[test] fn find_unnumbered_issue() { fn check_fail(text: &str, failing_pos: usize) { - let mut seeker = BadIssueSeeker::new(ReportTactic::Unnumbered); + let mut seeker = BadIssueSeeker::new(); assert_eq!( Some(failing_pos), text.find(|c| seeker.inspect(c).is_some()) @@ -183,51 +162,24 @@ fn find_unnumbered_issue() { } fn check_pass(text: &str) { - let mut seeker = BadIssueSeeker::new(ReportTactic::Unnumbered); + let mut seeker = BadIssueSeeker::new(); assert_eq!(None, text.find(|c| seeker.inspect(c).is_some())); } - - check_fail(" \n FIXME\n", 8); - check_fail("FIXME(\n", 6); - check_fail("FIXME(#\n", 7); - check_fail("FIXME(#1\n", 8); - check_fail("FIXME(#)1\n", 7); - check_pass("FIXME(#1222)\n"); - check_fail("FIXME(#12\n22)\n", 9); - check_pass("FIXME(@maintainer, #1222, hello)\n"); } #[test] fn find_issue() { - fn is_bad_issue(text: &str, report_fixme: ReportTactic) -> bool { - let mut seeker = BadIssueSeeker::new(report_fixme); + fn is_bad_issue(text: &str) -> bool { + let mut seeker = BadIssueSeeker::new(); text.chars().any(|c| seeker.inspect(c).is_some()) } - - assert!(is_bad_issue("This is a FIXME(#1)\n", ReportTactic::Always)); - - assert!(is_bad_issue( - "This is a FixMe(#1) mixed case\n", - ReportTactic::Always, - )); - - assert!(!is_bad_issue("bad FIXME\n", ReportTactic::Never)); } #[test] fn issue_type() { - let mut seeker = BadIssueSeeker::new(ReportTactic::Unnumbered); + let seeker = BadIssueSeeker::new(); let expected = Some(Issue { - issue_type: IssueType::Fixme, + issue_type: None, missing_number: true, }); - - assert_eq!( - expected, - "Test. FIXME: bad, bad, not good" - .chars() - .map(|c| seeker.inspect(c)) - .find(Option::is_some) - .unwrap() - ); } diff --git a/tests/config/small_tabs.toml b/tests/config/small_tabs.toml index 598edda6abee4..c3cfd34317a37 100644 --- a/tests/config/small_tabs.toml +++ b/tests/config/small_tabs.toml @@ -6,6 +6,5 @@ brace_style = "SameLineWhere" fn_args_layout = "Tall" trailing_comma = "Vertical" indent_style = "Block" -report_fixme = "Never" reorder_imports = false format_strings = true From 5e4296767fadf87cea31c22edaef1a924dfbad40 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Sun, 29 May 2022 21:54:00 -0500 Subject: [PATCH 45/53] refactor: remove code for bad issue (e.g. todo/fixme) reporting --- src/format_report_formatter.rs | 2 +- src/formatting.rs | 14 --- src/issues.rs | 185 --------------------------------- src/lib.rs | 8 +- 4 files changed, 2 insertions(+), 207 deletions(-) delete mode 100644 src/issues.rs diff --git a/src/format_report_formatter.rs b/src/format_report_formatter.rs index 90406cdb95e2b..9809f72f5ae6b 100644 --- a/src/format_report_formatter.rs +++ b/src/format_report_formatter.rs @@ -146,6 +146,6 @@ fn error_kind_to_snippet_annotation_type(error_kind: &ErrorKind) -> AnnotationTy | ErrorKind::BadAttr | ErrorKind::InvalidGlobPattern(_) | ErrorKind::VersionMismatch => AnnotationType::Error, - ErrorKind::BadIssue(_) | ErrorKind::DeprecatedAttr => AnnotationType::Warning, + ErrorKind::DeprecatedAttr => AnnotationType::Warning, } } diff --git a/src/formatting.rs b/src/formatting.rs index 72bbe240f7b9c..869c6db647d00 100644 --- a/src/formatting.rs +++ b/src/formatting.rs @@ -13,7 +13,6 @@ use self::newline_style::apply_newline_style; use crate::comment::{CharClasses, FullCodeCharKind}; use crate::config::{Config, FileName, Verbosity}; use crate::formatting::generated::is_generated_file; -use crate::issues::BadIssueSeeker; use crate::modules::Module; use crate::parse::parser::{DirectoryOwnership, Parser, ParserError}; use crate::parse::session::ParseSess; @@ -332,7 +331,6 @@ impl FormattingError { ErrorKind::LineOverflow(found, max) => (max, found - max), ErrorKind::TrailingWhitespace | ErrorKind::DeprecatedAttr - | ErrorKind::BadIssue(_) | ErrorKind::BadAttr | ErrorKind::LostComment | ErrorKind::LicenseCheck => { @@ -483,11 +481,9 @@ struct FormatLines<'a> { cur_line: usize, newline_count: usize, errors: Vec, - issue_seeker: BadIssueSeeker, line_buffer: String, current_line_contains_string_literal: bool, format_line: bool, - allow_issue_seek: bool, config: &'a Config, } @@ -497,7 +493,6 @@ impl<'a> FormatLines<'a> { skipped_range: &'a [(usize, usize)], config: &'a Config, ) -> FormatLines<'a> { - let issue_seeker = BadIssueSeeker::new(); FormatLines { name, skipped_range, @@ -506,8 +501,6 @@ impl<'a> FormatLines<'a> { cur_line: 1, newline_count: 0, errors: vec![], - allow_issue_seek: !issue_seeker.is_disabled(), - issue_seeker, line_buffer: String::with_capacity(config.max_width() * 2), current_line_contains_string_literal: false, format_line: config.file_lines().contains_line(name, 1), @@ -536,13 +529,6 @@ impl<'a> FormatLines<'a> { continue; } - if self.allow_issue_seek && self.format_line { - // Add warnings for bad fixmes - if let Some(issue) = self.issue_seeker.inspect(c) { - self.push_err(ErrorKind::BadIssue(issue), false, false); - } - } - if c == '\n' { self.new_line(kind); } else { diff --git a/src/issues.rs b/src/issues.rs deleted file mode 100644 index d95a80fe7fd95..0000000000000 --- a/src/issues.rs +++ /dev/null @@ -1,185 +0,0 @@ -// Objects for seeking through a char stream for occurrences of TODO and FIXME. -// Depending on the loaded configuration, may also check that these have an -// associated issue number. - -use std::fmt; - -use crate::config::ReportTactic; - -// Enabled implementation detail is here because it is -// irrelevant outside the issues module -fn is_enabled(report_tactic: ReportTactic) -> bool { - report_tactic != ReportTactic::Never -} - -#[derive(Clone, Copy)] -enum Seeking { - Issue {}, - Number { issue: Issue, part: NumberPart }, -} - -#[derive(Clone, Copy)] -enum NumberPart { - OpenParen, - Pound, - Number, - CloseParen, -} - -#[derive(PartialEq, Eq, Debug, Clone, Copy)] -pub struct Issue { - issue_type: Option, - // Indicates whether we're looking for issues with missing numbers, or - // all issues of this type. - missing_number: bool, -} - -impl fmt::Display for Issue { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - let msg = match self.issue_type { - _ => "", - }; - let details = if self.missing_number { - " without issue number" - } else { - "" - }; - - write!(fmt, "{}{}", msg, details) - } -} - -#[derive(PartialEq, Eq, Debug, Clone, Copy)] -enum IssueType {} - -enum IssueClassification { - Good, - Bad(Issue), - None, -} - -pub(crate) struct BadIssueSeeker { - state: Seeking, -} - -impl BadIssueSeeker { - pub(crate) fn new() -> BadIssueSeeker { - BadIssueSeeker { - state: Seeking::Issue {}, - } - } - - pub(crate) fn is_disabled(&self) -> bool { - true - } - - // Check whether or not the current char is conclusive evidence for an - // unnumbered TO-DO or FIX-ME. - pub(crate) fn inspect(&mut self, c: char) -> Option { - match self.state { - Seeking::Issue {} => { - self.state = self.inspect_issue(c, 0); - } - Seeking::Number { issue, part } => { - let result = self.inspect_number(c, issue, part); - - if let IssueClassification::None = result { - return None; - } - - self.state = Seeking::Issue {}; - - if let IssueClassification::Bad(issue) = result { - return Some(issue); - } - } - } - - None - } - - fn inspect_issue(&mut self, c: char, mut fixme_idx: usize) -> Seeking { - if let Some(lower_case_c) = c.to_lowercase().next() { - fixme_idx = 0; - } - - Seeking::Issue {} - } - - fn inspect_number( - &mut self, - c: char, - issue: Issue, - mut part: NumberPart, - ) -> IssueClassification { - if !issue.missing_number || c == '\n' { - return IssueClassification::Bad(issue); - } else if c == ')' { - return if let NumberPart::CloseParen = part { - IssueClassification::Good - } else { - IssueClassification::Bad(issue) - }; - } - - match part { - NumberPart::OpenParen => { - if c != '(' { - return IssueClassification::Bad(issue); - } else { - part = NumberPart::Pound; - } - } - NumberPart::Pound => { - if c == '#' { - part = NumberPart::Number; - } - } - NumberPart::Number => { - if ('0'..='9').contains(&c) { - part = NumberPart::CloseParen; - } else { - return IssueClassification::Bad(issue); - } - } - NumberPart::CloseParen => {} - } - - self.state = Seeking::Number { part, issue }; - - IssueClassification::None - } -} - -#[test] -fn find_unnumbered_issue() { - fn check_fail(text: &str, failing_pos: usize) { - let mut seeker = BadIssueSeeker::new(); - assert_eq!( - Some(failing_pos), - text.find(|c| seeker.inspect(c).is_some()) - ); - } - - fn check_pass(text: &str) { - let mut seeker = BadIssueSeeker::new(); - assert_eq!(None, text.find(|c| seeker.inspect(c).is_some())); - } -} - -#[test] -fn find_issue() { - fn is_bad_issue(text: &str) -> bool { - let mut seeker = BadIssueSeeker::new(); - text.chars().any(|c| seeker.inspect(c).is_some()) - } -} - -#[test] -fn issue_type() { - let seeker = BadIssueSeeker::new(); - let expected = Some(Issue { - issue_type: None, - missing_number: true, - }); -} diff --git a/src/lib.rs b/src/lib.rs index ad23b16e02ec1..f46a6914dd8e2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -39,7 +39,6 @@ use thiserror::Error; use crate::comment::LineClasses; use crate::emitter::Emitter; use crate::formatting::{FormatErrorMap, FormattingError, ReportedErrors, SourceFile}; -use crate::issues::Issue; use crate::modules::ModuleResolutionError; use crate::parse::parser::DirectoryOwnership; use crate::shape::Indent; @@ -69,7 +68,6 @@ mod format_report_formatter; pub(crate) mod formatting; mod ignore_path; mod imports; -mod issues; mod items; mod lists; mod macros; @@ -110,9 +108,6 @@ pub enum ErrorKind { /// Line ends in whitespace. #[error("left behind trailing whitespace")] TrailingWhitespace, - /// TODO or FIXME item without an issue number. - #[error("found {0}")] - BadIssue(Issue), /// License check has failed. #[error("license check failed")] LicenseCheck, @@ -236,8 +231,7 @@ impl FormatReport { ErrorKind::LostComment => { errs.has_unformatted_code_errors = true; } - ErrorKind::BadIssue(_) - | ErrorKind::LicenseCheck + ErrorKind::LicenseCheck | ErrorKind::DeprecatedAttr | ErrorKind::BadAttr | ErrorKind::VersionMismatch => { From 79515f17ed4661da864347c90c76c51f9bf86069 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Sun, 29 May 2022 22:05:57 -0500 Subject: [PATCH 46/53] feat: remove license_template_path config option --- Configurations.md | 20 -- src/config/config_type.rs | 22 -- src/config/license.rs | 265 ------------------ src/config/mod.rs | 32 --- src/format_report_formatter.rs | 1 - src/formatting.rs | 20 +- src/lib.rs | 8 +- tests/config/issue-3802.toml | 2 - tests/license-template/lt.txt | 2 - .../license-templates/empty_license_path.rs | 5 - tests/source/license-templates/license.rs | 6 - .../license-templates/empty_license_path.rs | 5 - tests/target/license-templates/license.rs | 6 - 13 files changed, 3 insertions(+), 391 deletions(-) delete mode 100644 src/config/license.rs delete mode 100644 tests/config/issue-3802.toml delete mode 100644 tests/license-template/lt.txt delete mode 100644 tests/source/license-templates/empty_license_path.rs delete mode 100644 tests/source/license-templates/license.rs delete mode 100644 tests/target/license-templates/empty_license_path.rs delete mode 100644 tests/target/license-templates/license.rs diff --git a/Configurations.md b/Configurations.md index edb2d1f757518..8c84614352ca2 100644 --- a/Configurations.md +++ b/Configurations.md @@ -1473,26 +1473,6 @@ use core::slice; #[cfg(feature = "alloc")] use core::slice; ``` -## `license_template_path` - -Check whether beginnings of files match a license template. - -- **Default value**: `""` -- **Possible values**: path to a license template file -- **Stable**: No (tracking issue: [#3352](https://github.com/rust-lang/rustfmt/issues/3352)) - -A license template is a plain text file which is matched literally against the -beginning of each source file, except for `{}`-delimited blocks, which are -matched as regular expressions. The following license template therefore -matches strings like `// Copyright 2017 The Rust Project Developers.`, `// -Copyright 2018 The Rust Project Developers.`, etc.: - -``` -// Copyright {\d+} The Rust Project Developers. -``` - -`\{`, `\}` and `\\` match literal braces / backslashes. - ## `match_arm_blocks` Controls whether arm bodies are wrapped in cases where the first line of the body cannot fit on the same line as the `=>` operator. diff --git a/src/config/config_type.rs b/src/config/config_type.rs index 7fc4486ddcd3d..e37ed798cb559 100644 --- a/src/config/config_type.rs +++ b/src/config/config_type.rs @@ -61,9 +61,6 @@ macro_rules! create_config { #[derive(Clone)] #[allow(unreachable_pub)] pub struct Config { - // if a license_template_path has been specified, successfully read, parsed and compiled - // into a regex, it will be stored here - pub license_template: Option, // For each config item, we store a bool indicating whether it has // been accessed and the value, and a bool whether the option was // manually initialised, or taken from the default, @@ -104,7 +101,6 @@ macro_rules! create_config { | "struct_variant_width" | "array_width" | "chain_width" => self.0.set_heuristics(), - "license_template_path" => self.0.set_license_template(), "merge_imports" => self.0.set_merge_imports(), &_ => (), } @@ -163,7 +159,6 @@ macro_rules! create_config { } )+ self.set_heuristics(); - self.set_license_template(); self.set_ignore(dir); self.set_merge_imports(); self @@ -247,7 +242,6 @@ macro_rules! create_config { | "struct_variant_width" | "array_width" | "chain_width" => self.set_heuristics(), - "license_template_path" => self.set_license_template(), "merge_imports" => self.set_merge_imports(), &_ => (), } @@ -386,21 +380,6 @@ macro_rules! create_config { }; } - fn set_license_template(&mut self) { - if self.was_set().license_template_path() { - let lt_path = self.license_template_path(); - if lt_path.len() > 0 { - match license::load_and_compile_template(<_path) { - Ok(re) => self.license_template = Some(re), - Err(msg) => eprintln!("Warning for license template file {:?}: {}", - lt_path, msg), - } - } else { - self.license_template = None; - } - } - } - fn set_ignore(&mut self, dir: &Path) { self.ignore.2.add_prefix(dir); } @@ -437,7 +416,6 @@ macro_rules! create_config { impl Default for Config { fn default() -> Config { Config { - license_template: None, $( $i: (Cell::new(false), false, $def, $stb), )+ diff --git a/src/config/license.rs b/src/config/license.rs deleted file mode 100644 index c7feb502ea91e..0000000000000 --- a/src/config/license.rs +++ /dev/null @@ -1,265 +0,0 @@ -use std::fmt; -use std::fs::File; -use std::io; -use std::io::Read; - -use regex::Regex; - -#[derive(Debug)] -pub(crate) enum LicenseError { - IO(io::Error), - Regex(regex::Error), - Parse(String), -} - -impl fmt::Display for LicenseError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match *self { - LicenseError::IO(ref err) => err.fmt(f), - LicenseError::Regex(ref err) => err.fmt(f), - LicenseError::Parse(ref err) => write!(f, "parsing failed, {}", err), - } - } -} - -impl From for LicenseError { - fn from(err: io::Error) -> LicenseError { - LicenseError::IO(err) - } -} - -impl From for LicenseError { - fn from(err: regex::Error) -> LicenseError { - LicenseError::Regex(err) - } -} - -// the template is parsed using a state machine -enum ParsingState { - Lit, - LitEsc, - // the u32 keeps track of brace nesting - Re(u32), - ReEsc(u32), - Abort(String), -} - -use self::ParsingState::*; - -pub(crate) struct TemplateParser { - parsed: String, - buffer: String, - state: ParsingState, - linum: u32, - open_brace_line: u32, -} - -impl TemplateParser { - fn new() -> Self { - Self { - parsed: "^".to_owned(), - buffer: String::new(), - state: Lit, - linum: 1, - // keeps track of last line on which a regex placeholder was started - open_brace_line: 0, - } - } - - /// Converts a license template into a string which can be turned into a regex. - /// - /// The license template could use regex syntax directly, but that would require a lot of manual - /// escaping, which is inconvenient. It is therefore literal by default, with optional regex - /// subparts delimited by `{` and `}`. Additionally: - /// - /// - to insert literal `{`, `}` or `\`, escape it with `\` - /// - an empty regex placeholder (`{}`) is shorthand for `{.*?}` - /// - /// This function parses this input format and builds a properly escaped *string* representation - /// of the equivalent regular expression. It **does not** however guarantee that the returned - /// string is a syntactically valid regular expression. - /// - /// # Examples - /// - /// ```text - /// assert_eq!( - /// TemplateParser::parse( - /// r" - /// // Copyright {\d+} The \} Rust \\ Project \{ Developers. See the {([A-Z]+)} - /// // file at the top-level directory of this distribution and at - /// // {}. - /// // - /// // Licensed under the Apache License, Version 2.0 or the MIT license - /// // , at your - /// // option. This file may not be copied, modified, or distributed - /// // except according to those terms. - /// " - /// ).unwrap(), - /// r"^ - /// // Copyright \d+ The \} Rust \\ Project \{ Developers\. See the ([A-Z]+) - /// // file at the top\-level directory of this distribution and at - /// // .*?\. - /// // - /// // Licensed under the Apache License, Version 2\.0 or the MIT license - /// // , at your - /// // option\. This file may not be copied, modified, or distributed - /// // except according to those terms\. - /// " - /// ); - /// ``` - pub(crate) fn parse(template: &str) -> Result { - let mut parser = Self::new(); - for chr in template.chars() { - if chr == '\n' { - parser.linum += 1; - } - parser.state = match parser.state { - Lit => parser.trans_from_lit(chr), - LitEsc => parser.trans_from_litesc(chr), - Re(brace_nesting) => parser.trans_from_re(chr, brace_nesting), - ReEsc(brace_nesting) => parser.trans_from_reesc(chr, brace_nesting), - Abort(msg) => return Err(LicenseError::Parse(msg)), - }; - } - // check if we've ended parsing in a valid state - match parser.state { - Abort(msg) => return Err(LicenseError::Parse(msg)), - Re(_) | ReEsc(_) => { - return Err(LicenseError::Parse(format!( - "escape or balance opening brace on l. {}", - parser.open_brace_line - ))); - } - LitEsc => { - return Err(LicenseError::Parse(format!( - "incomplete escape sequence on l. {}", - parser.linum - ))); - } - _ => (), - } - parser.parsed.push_str(®ex::escape(&parser.buffer)); - - Ok(parser.parsed) - } - - fn trans_from_lit(&mut self, chr: char) -> ParsingState { - match chr { - '{' => { - self.parsed.push_str(®ex::escape(&self.buffer)); - self.buffer.clear(); - self.open_brace_line = self.linum; - Re(1) - } - '}' => Abort(format!( - "escape or balance closing brace on l. {}", - self.linum - )), - '\\' => LitEsc, - _ => { - self.buffer.push(chr); - Lit - } - } - } - - fn trans_from_litesc(&mut self, chr: char) -> ParsingState { - self.buffer.push(chr); - Lit - } - - fn trans_from_re(&mut self, chr: char, brace_nesting: u32) -> ParsingState { - match chr { - '{' => { - self.buffer.push(chr); - Re(brace_nesting + 1) - } - '}' => { - match brace_nesting { - 1 => { - // default regex for empty placeholder {} - if self.buffer.is_empty() { - self.parsed.push_str(".*?"); - } else { - self.parsed.push_str(&self.buffer); - } - self.buffer.clear(); - Lit - } - _ => { - self.buffer.push(chr); - Re(brace_nesting - 1) - } - } - } - '\\' => { - self.buffer.push(chr); - ReEsc(brace_nesting) - } - _ => { - self.buffer.push(chr); - Re(brace_nesting) - } - } - } - - fn trans_from_reesc(&mut self, chr: char, brace_nesting: u32) -> ParsingState { - self.buffer.push(chr); - Re(brace_nesting) - } -} - -pub(crate) fn load_and_compile_template(path: &str) -> Result { - let mut lt_file = File::open(&path)?; - let mut lt_str = String::new(); - lt_file.read_to_string(&mut lt_str)?; - let lt_parsed = TemplateParser::parse(<_str)?; - Ok(Regex::new(<_parsed)?) -} - -#[cfg(test)] -mod test { - use super::TemplateParser; - - #[test] - fn test_parse_license_template() { - assert_eq!( - TemplateParser::parse("literal (.*)").unwrap(), - r"^literal \(\.\*\)" - ); - assert_eq!( - TemplateParser::parse(r"escaping \}").unwrap(), - r"^escaping \}" - ); - assert!(TemplateParser::parse("unbalanced } without escape").is_err()); - assert_eq!( - TemplateParser::parse(r"{\d+} place{-?}holder{s?}").unwrap(), - r"^\d+ place-?holders?" - ); - assert_eq!(TemplateParser::parse("default {}").unwrap(), "^default .*?"); - assert_eq!( - TemplateParser::parse(r"unbalanced nested braces {\{{3}}").unwrap(), - r"^unbalanced nested braces \{{3}" - ); - assert_eq!( - &TemplateParser::parse("parsing error }") - .unwrap_err() - .to_string(), - "parsing failed, escape or balance closing brace on l. 1" - ); - assert_eq!( - &TemplateParser::parse("parsing error {\nsecond line") - .unwrap_err() - .to_string(), - "parsing failed, escape or balance opening brace on l. 1" - ); - assert_eq!( - &TemplateParser::parse(r"parsing error \") - .unwrap_err() - .to_string(), - "parsing failed, incomplete escape sequence on l. 1" - ); - } -} diff --git a/src/config/mod.rs b/src/config/mod.rs index fc724beae60a7..a516952818783 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -5,7 +5,6 @@ use std::io::{Error, ErrorKind, Read}; use std::path::{Path, PathBuf}; use std::{env, fs}; -use regex::Regex; use thiserror::Error; use crate::config::config_type::ConfigType; @@ -22,7 +21,6 @@ pub(crate) mod config_type; pub(crate) mod options; pub(crate) mod file_lines; -pub(crate) mod license; pub(crate) mod lists; // This macro defines configuration options used in rustfmt. Each option @@ -63,8 +61,6 @@ create_config! { "Maximum length of comments. No effect unless wrap_comments = true"; normalize_comments: bool, false, false, "Convert /* */ comments to // comments where possible"; normalize_doc_attributes: bool, false, false, "Normalize doc attributes as doc comments"; - license_template_path: String, String::default(), false, - "Beginning of file must match license template"; format_strings: bool, false, false, "Format string literals where necessary"; format_macro_matchers: bool, false, false, "Format the metavariable matching patterns in macros"; @@ -414,8 +410,6 @@ mod test { create_config! { // Options that are used by the generated functions max_width: usize, 100, true, "Maximum width of each line"; - license_template_path: String, String::default(), false, - "Beginning of file must match license template"; required_version: String, env!("CARGO_PKG_VERSION").to_owned(), false, "Require a specific version of rustfmt."; ignore: IgnoreList, IgnoreList::default(), false, @@ -520,31 +514,6 @@ mod test { assert_eq!(s.contains("(unstable)"), true); } - #[test] - fn test_empty_string_license_template_path() { - let toml = r#"license_template_path = """#; - let config = Config::from_toml(toml, Path::new("")).unwrap(); - assert!(config.license_template.is_none()); - } - - #[nightly_only_test] - #[test] - fn test_valid_license_template_path() { - let toml = r#"license_template_path = "tests/license-template/lt.txt""#; - let config = Config::from_toml(toml, Path::new("")).unwrap(); - assert!(config.license_template.is_some()); - } - - #[nightly_only_test] - #[test] - fn test_override_existing_license_with_no_license() { - let toml = r#"license_template_path = "tests/license-template/lt.txt""#; - let mut config = Config::from_toml(toml, Path::new("")).unwrap(); - assert!(config.license_template.is_some()); - config.override_value("license_template_path", ""); - assert!(config.license_template.is_none()); - } - #[test] fn test_dump_default_config() { let default_config = format!( @@ -566,7 +535,6 @@ format_code_in_doc_comments = false comment_width = 80 normalize_comments = false normalize_doc_attributes = false -license_template_path = "" format_strings = false format_macro_matchers = false format_macro_bodies = true diff --git a/src/format_report_formatter.rs b/src/format_report_formatter.rs index 9809f72f5ae6b..fd536d4df41a2 100644 --- a/src/format_report_formatter.rs +++ b/src/format_report_formatter.rs @@ -142,7 +142,6 @@ fn error_kind_to_snippet_annotation_type(error_kind: &ErrorKind) -> AnnotationTy | ErrorKind::ModuleResolutionError(_) | ErrorKind::ParseError | ErrorKind::LostComment - | ErrorKind::LicenseCheck | ErrorKind::BadAttr | ErrorKind::InvalidGlobPattern(_) | ErrorKind::VersionMismatch => AnnotationType::Error, diff --git a/src/formatting.rs b/src/formatting.rs index 869c6db647d00..e6995210a943a 100644 --- a/src/formatting.rs +++ b/src/formatting.rs @@ -332,8 +332,7 @@ impl FormattingError { ErrorKind::TrailingWhitespace | ErrorKind::DeprecatedAttr | ErrorKind::BadAttr - | ErrorKind::LostComment - | ErrorKind::LicenseCheck => { + | ErrorKind::LostComment => { let trailing_ws_start = self .line_buffer .rfind(|c: char| !c.is_whitespace()) @@ -365,7 +364,7 @@ pub(crate) struct ReportedErrors { // Code contains macro call that was unable to format. pub(crate) has_macro_format_failure: bool, - // Failed a check, such as the license check or other opt-in checking. + // Failed an opt-in checking. pub(crate) has_check_errors: bool, /// Formatted code differs from existing code (--check only). @@ -461,7 +460,6 @@ fn format_lines( report: &FormatReport, ) { let mut formatter = FormatLines::new(name, skipped_range, config); - formatter.check_license(text); formatter.iterate(text); if formatter.newline_count > 1 { @@ -508,20 +506,6 @@ impl<'a> FormatLines<'a> { } } - fn check_license(&mut self, text: &mut String) { - if let Some(ref license_template) = self.config.license_template { - if !license_template.is_match(text) { - self.errors.push(FormattingError { - line: self.cur_line, - kind: ErrorKind::LicenseCheck, - is_comment: false, - is_string: false, - line_buffer: String::new(), - }); - } - } - } - // Iterate over the chars in the file map. fn iterate(&mut self, text: &mut String) { for (kind, c) in CharClasses::new(text.chars()) { diff --git a/src/lib.rs b/src/lib.rs index f46a6914dd8e2..495010a297df0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -108,9 +108,6 @@ pub enum ErrorKind { /// Line ends in whitespace. #[error("left behind trailing whitespace")] TrailingWhitespace, - /// License check has failed. - #[error("license check failed")] - LicenseCheck, /// Used deprecated skip attribute. #[error("`rustfmt_skip` is deprecated; use `rustfmt::skip`")] DeprecatedAttr, @@ -231,10 +228,7 @@ impl FormatReport { ErrorKind::LostComment => { errs.has_unformatted_code_errors = true; } - ErrorKind::LicenseCheck - | ErrorKind::DeprecatedAttr - | ErrorKind::BadAttr - | ErrorKind::VersionMismatch => { + ErrorKind::DeprecatedAttr | ErrorKind::BadAttr | ErrorKind::VersionMismatch => { errs.has_check_errors = true; } _ => {} diff --git a/tests/config/issue-3802.toml b/tests/config/issue-3802.toml deleted file mode 100644 index 74ee8b010dd05..0000000000000 --- a/tests/config/issue-3802.toml +++ /dev/null @@ -1,2 +0,0 @@ -unstable_features = true -license_template_path = "" diff --git a/tests/license-template/lt.txt b/tests/license-template/lt.txt deleted file mode 100644 index ea4390371a09a..0000000000000 --- a/tests/license-template/lt.txt +++ /dev/null @@ -1,2 +0,0 @@ -// rustfmt-license_template_path: tests/license-template/lt.txt -// Copyright {\d+} The rustfmt developers. diff --git a/tests/source/license-templates/empty_license_path.rs b/tests/source/license-templates/empty_license_path.rs deleted file mode 100644 index d3a91e4231d19..0000000000000 --- a/tests/source/license-templates/empty_license_path.rs +++ /dev/null @@ -1,5 +0,0 @@ -// rustfmt-config: issue-3802.toml - -fn main() { -println!("Hello world!"); -} diff --git a/tests/source/license-templates/license.rs b/tests/source/license-templates/license.rs deleted file mode 100644 index 6816011c60dc5..0000000000000 --- a/tests/source/license-templates/license.rs +++ /dev/null @@ -1,6 +0,0 @@ -// rustfmt-license_template_path: tests/license-template/lt.txt -// Copyright 2019 The rustfmt developers. - -fn main() { -println!("Hello world!"); -} diff --git a/tests/target/license-templates/empty_license_path.rs b/tests/target/license-templates/empty_license_path.rs deleted file mode 100644 index 950f103ed3922..0000000000000 --- a/tests/target/license-templates/empty_license_path.rs +++ /dev/null @@ -1,5 +0,0 @@ -// rustfmt-config: issue-3802.toml - -fn main() { - println!("Hello world!"); -} diff --git a/tests/target/license-templates/license.rs b/tests/target/license-templates/license.rs deleted file mode 100644 index 7169c7b257615..0000000000000 --- a/tests/target/license-templates/license.rs +++ /dev/null @@ -1,6 +0,0 @@ -// rustfmt-license_template_path: tests/license-template/lt.txt -// Copyright 2019 The rustfmt developers. - -fn main() { - println!("Hello world!"); -} From 64f1f57a4837694cb2449d6bc1f614e60c6ff42c Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Sat, 4 Jun 2022 10:08:33 -0500 Subject: [PATCH 47/53] fix: handle inner ignore attribute on stdin --- src/formatting.rs | 28 +++++++++++++++++++++------- src/test/mod.rs | 24 ++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/src/formatting.rs b/src/formatting.rs index e6995210a943a..23d90d9e2e069 100644 --- a/src/formatting.rs +++ b/src/formatting.rs @@ -40,12 +40,10 @@ impl<'b, T: Write + 'b> Session<'b, T> { rustc_span::create_session_if_not_set_then(self.config.edition().into(), |_| { if self.config.disable_all_formatting() { // When the input is from stdin, echo back the input. - if let Input::Text(ref buf) = input { - if let Err(e) = io::stdout().write_all(buf.as_bytes()) { - return Err(From::from(e)); - } - } - return Ok(FormatReport::new()); + return match input { + Input::Text(ref buf) => echo_back_stdin(buf), + _ => Ok(FormatReport::new()), + }; } let config = &self.config.clone(); @@ -94,6 +92,13 @@ fn should_skip_module( false } +fn echo_back_stdin(input: &str) -> Result { + if let Err(e) = io::stdout().write_all(input.as_bytes()) { + return Err(From::from(e)); + } + Ok(FormatReport::new()) +} + // Format an entire crate (or subset of the module tree). fn format_project( input: Input, @@ -136,7 +141,8 @@ fn format_project( .visit_crate(&krate)? .into_iter() .filter(|(path, module)| { - !should_skip_module(config, &context, input_is_stdin, &main_file, path, module) + input_is_stdin + || !should_skip_module(config, &context, input_is_stdin, &main_file, path, module) }) .collect::>(); @@ -146,6 +152,14 @@ fn format_project( context.parse_session.set_silent_emitter(); for (path, module) in files { + if input_is_stdin && contains_skip(module.attrs()) { + return echo_back_stdin( + context + .parse_session + .snippet_provider(module.span) + .entire_snippet(), + ); + } should_emit_verbose(input_is_stdin, config, || println!("Formatting {}", path)); context.format_file(path, &module, is_macro_def)?; } diff --git a/src/test/mod.rs b/src/test/mod.rs index 0eda9e4b116a3..18ec8620facdf 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -578,6 +578,30 @@ fn stdin_generated_files_issue_5172() { ); } +#[test] +fn stdin_handles_mod_inner_ignore_attr() { + // see https://github.com/rust-lang/rustfmt/issues/5368 + init_log(); + let input = String::from("#![rustfmt::skip]\n\nfn main() { }"); + let mut child = Command::new(rustfmt().to_str().unwrap()) + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .spawn() + .expect("failed to execute child"); + + { + let stdin = child.stdin.as_mut().expect("failed to get stdin"); + stdin + .write_all(input.as_bytes()) + .expect("failed to write stdin"); + } + + let output = child.wait_with_output().expect("failed to wait on child"); + assert!(output.status.success()); + assert!(output.stderr.is_empty()); + assert_eq!(input, String::from_utf8(output.stdout).unwrap()); +} + #[test] fn format_lines_errors_are_reported() { init_log(); From aedb396063e2cd166e3cc0bfd762bf382996cd03 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Tue, 7 Jun 2022 22:14:08 -0500 Subject: [PATCH 48/53] chore: bump toolchain --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 94b57d506c20b..813e5e2c10fea 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2022-03-27" +channel = "nightly-2022-06-06" components = ["rustc-dev"] From 5fa2727ddeef534a7cd437f9e288c221a2cf0b6a Mon Sep 17 00:00:00 2001 From: Urgau Date: Wed, 8 Jun 2022 18:15:22 +0200 Subject: [PATCH 49/53] Remove useless conditional compilation --- src/test/mod.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/test/mod.rs b/src/test/mod.rs index 18ec8620facdf..6b5bc2b30dd5a 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -978,12 +978,6 @@ fn rustfmt() -> PathBuf { // Chop off `deps`. me.pop(); - // If we run `cargo test --release`, we might only have a release build. - if cfg!(release) { - // `../release/` - me.pop(); - me.push("release"); - } me.push("rustfmt"); assert!( me.is_file() || me.with_extension("exe").is_file(), From 7d34cfaf2c31dc90f6dc8fc1cdc001fcbd7ebbfa Mon Sep 17 00:00:00 2001 From: David Bar-On <61089727+davidBar-On@users.noreply.github.com> Date: Tue, 16 Mar 2021 03:57:04 +0200 Subject: [PATCH 50/53] Dedup `imports_granularity = "Item"` (#4737) * Fix for issue 4725 - dedup Item imports_granularity (2nd version) * Use unique() instead of unique_by() --- src/imports.rs | 15 ++++++++++++++- .../source/{ => imports}/imports-impl-only-use.rs | 0 .../imports-reorder-lines-and-items.rs | 0 .../source/{ => imports}/imports-reorder-lines.rs | 0 tests/source/{ => imports}/imports-reorder.rs | 0 tests/source/{ => imports}/imports.rs | 0 .../source/{ => imports}/imports_block_indent.rs | 0 .../{ => imports}/imports_granularity_crate.rs | 0 .../imports_granularity_default-with-dups.rs | 6 ++++++ ..._item-with-dups-StdExternalCrate-no-reorder.rs | 13 +++++++++++++ .../imports/imports_granularity_item-with-dups.rs | 11 +++++++++++ .../{ => imports}/imports_granularity_item.rs | 0 .../{ => imports}/imports_granularity_module.rs | 0 .../{ => imports}/import-fencepost-length.rs | 0 .../target/{ => imports}/imports-impl-only-use.rs | 0 .../imports-reorder-lines-and-items.rs | 0 .../target/{ => imports}/imports-reorder-lines.rs | 0 tests/target/{ => imports}/imports-reorder.rs | 0 tests/target/{ => imports}/imports.rs | 0 .../target/{ => imports}/imports_2021_edition.rs | 0 .../target/{ => imports}/imports_block_indent.rs | 0 .../{ => imports}/imports_granularity_crate.rs | 0 .../imports_granularity_default-with-dups.rs | 6 ++++++ ..._item-with-dups-StdExternalCrate-no-reorder.rs | 7 +++++++ .../imports/imports_granularity_item-with-dups.rs | 5 +++++ .../{ => imports}/imports_granularity_item.rs | 0 .../{ => imports}/imports_granularity_module.rs | 0 27 files changed, 62 insertions(+), 1 deletion(-) rename tests/source/{ => imports}/imports-impl-only-use.rs (100%) rename tests/source/{ => imports}/imports-reorder-lines-and-items.rs (100%) rename tests/source/{ => imports}/imports-reorder-lines.rs (100%) rename tests/source/{ => imports}/imports-reorder.rs (100%) rename tests/source/{ => imports}/imports.rs (100%) rename tests/source/{ => imports}/imports_block_indent.rs (100%) rename tests/source/{ => imports}/imports_granularity_crate.rs (100%) create mode 100644 tests/source/imports/imports_granularity_default-with-dups.rs create mode 100644 tests/source/imports/imports_granularity_item-with-dups-StdExternalCrate-no-reorder.rs create mode 100644 tests/source/imports/imports_granularity_item-with-dups.rs rename tests/source/{ => imports}/imports_granularity_item.rs (100%) rename tests/source/{ => imports}/imports_granularity_module.rs (100%) rename tests/target/{ => imports}/import-fencepost-length.rs (100%) rename tests/target/{ => imports}/imports-impl-only-use.rs (100%) rename tests/target/{ => imports}/imports-reorder-lines-and-items.rs (100%) rename tests/target/{ => imports}/imports-reorder-lines.rs (100%) rename tests/target/{ => imports}/imports-reorder.rs (100%) rename tests/target/{ => imports}/imports.rs (100%) rename tests/target/{ => imports}/imports_2021_edition.rs (100%) rename tests/target/{ => imports}/imports_block_indent.rs (100%) rename tests/target/{ => imports}/imports_granularity_crate.rs (100%) create mode 100644 tests/target/imports/imports_granularity_default-with-dups.rs create mode 100644 tests/target/imports/imports_granularity_item-with-dups-StdExternalCrate-no-reorder.rs create mode 100644 tests/target/imports/imports_granularity_item-with-dups.rs rename tests/target/{ => imports}/imports_granularity_item.rs (100%) rename tests/target/{ => imports}/imports_granularity_module.rs (100%) diff --git a/src/imports.rs b/src/imports.rs index 962f2126c66c3..559ed3917dba7 100644 --- a/src/imports.rs +++ b/src/imports.rs @@ -2,6 +2,10 @@ use std::borrow::Cow; use std::cmp::Ordering; use std::fmt; +use core::hash::{Hash, Hasher}; + +use itertools::Itertools; + use rustc_ast::ast::{self, UseTreeKind}; use rustc_span::{ symbol::{self, sym}, @@ -87,7 +91,7 @@ impl<'a> FmtVisitor<'a> { // sorting. // FIXME we do a lot of allocation to make our own representation. -#[derive(Clone, Eq, PartialEq)] +#[derive(Clone, Eq, Hash, PartialEq)] pub(crate) enum UseSegment { Ident(String, Option), Slf(Option), @@ -232,10 +236,13 @@ fn flatten_use_trees( use_trees: Vec, import_granularity: ImportGranularity, ) -> Vec { + // Return non-sorted single occurance of the use-trees text string; + // order is by first occurance of the use-tree. use_trees .into_iter() .flat_map(|tree| tree.flatten(import_granularity)) .map(UseTree::nest_trailing_self) + .unique() .collect() } @@ -780,6 +787,12 @@ fn merge_use_trees_inner(trees: &mut Vec, use_tree: UseTree, merge_by: trees.sort(); } +impl Hash for UseTree { + fn hash(&self, state: &mut H) { + self.path.hash(state); + } +} + impl PartialOrd for UseSegment { fn partial_cmp(&self, other: &UseSegment) -> Option { Some(self.cmp(other)) diff --git a/tests/source/imports-impl-only-use.rs b/tests/source/imports/imports-impl-only-use.rs similarity index 100% rename from tests/source/imports-impl-only-use.rs rename to tests/source/imports/imports-impl-only-use.rs diff --git a/tests/source/imports-reorder-lines-and-items.rs b/tests/source/imports/imports-reorder-lines-and-items.rs similarity index 100% rename from tests/source/imports-reorder-lines-and-items.rs rename to tests/source/imports/imports-reorder-lines-and-items.rs diff --git a/tests/source/imports-reorder-lines.rs b/tests/source/imports/imports-reorder-lines.rs similarity index 100% rename from tests/source/imports-reorder-lines.rs rename to tests/source/imports/imports-reorder-lines.rs diff --git a/tests/source/imports-reorder.rs b/tests/source/imports/imports-reorder.rs similarity index 100% rename from tests/source/imports-reorder.rs rename to tests/source/imports/imports-reorder.rs diff --git a/tests/source/imports.rs b/tests/source/imports/imports.rs similarity index 100% rename from tests/source/imports.rs rename to tests/source/imports/imports.rs diff --git a/tests/source/imports_block_indent.rs b/tests/source/imports/imports_block_indent.rs similarity index 100% rename from tests/source/imports_block_indent.rs rename to tests/source/imports/imports_block_indent.rs diff --git a/tests/source/imports_granularity_crate.rs b/tests/source/imports/imports_granularity_crate.rs similarity index 100% rename from tests/source/imports_granularity_crate.rs rename to tests/source/imports/imports_granularity_crate.rs diff --git a/tests/source/imports/imports_granularity_default-with-dups.rs b/tests/source/imports/imports_granularity_default-with-dups.rs new file mode 100644 index 0000000000000..cbb21a9f1b38c --- /dev/null +++ b/tests/source/imports/imports_granularity_default-with-dups.rs @@ -0,0 +1,6 @@ +use crate::lexer; +use crate::lexer::tokens::TokenData; +use crate::lexer::{tokens::TokenData}; +use crate::lexer::self; +use crate::lexer::{self}; +use crate::lexer::{self, tokens::TokenData}; diff --git a/tests/source/imports/imports_granularity_item-with-dups-StdExternalCrate-no-reorder.rs b/tests/source/imports/imports_granularity_item-with-dups-StdExternalCrate-no-reorder.rs new file mode 100644 index 0000000000000..e23705a884fef --- /dev/null +++ b/tests/source/imports/imports_granularity_item-with-dups-StdExternalCrate-no-reorder.rs @@ -0,0 +1,13 @@ +// rustfmt-imports_granularity: Item +// rustfmt-reorder_imports: false +// rustfmt-group_imports: StdExternalCrate + +use crate::lexer; +use crate::lexer; +use crate::lexer::tokens::TokenData; +use crate::lexer::{tokens::TokenData}; +use crate::lexer::self; +use crate::lexer; +use crate::lexer; +use crate::lexer::{self}; +use crate::lexer::{self, tokens::TokenData}; diff --git a/tests/source/imports/imports_granularity_item-with-dups.rs b/tests/source/imports/imports_granularity_item-with-dups.rs new file mode 100644 index 0000000000000..3e9589c299f68 --- /dev/null +++ b/tests/source/imports/imports_granularity_item-with-dups.rs @@ -0,0 +1,11 @@ +// rustfmt-imports_granularity: Item + +use crate::lexer; +use crate::lexer; +use crate::lexer::tokens::TokenData; +use crate::lexer::{tokens::TokenData}; +use crate::lexer::self; +use crate::lexer; +use crate::lexer; +use crate::lexer::{self}; +use crate::lexer::{self, tokens::TokenData}; diff --git a/tests/source/imports_granularity_item.rs b/tests/source/imports/imports_granularity_item.rs similarity index 100% rename from tests/source/imports_granularity_item.rs rename to tests/source/imports/imports_granularity_item.rs diff --git a/tests/source/imports_granularity_module.rs b/tests/source/imports/imports_granularity_module.rs similarity index 100% rename from tests/source/imports_granularity_module.rs rename to tests/source/imports/imports_granularity_module.rs diff --git a/tests/target/import-fencepost-length.rs b/tests/target/imports/import-fencepost-length.rs similarity index 100% rename from tests/target/import-fencepost-length.rs rename to tests/target/imports/import-fencepost-length.rs diff --git a/tests/target/imports-impl-only-use.rs b/tests/target/imports/imports-impl-only-use.rs similarity index 100% rename from tests/target/imports-impl-only-use.rs rename to tests/target/imports/imports-impl-only-use.rs diff --git a/tests/target/imports-reorder-lines-and-items.rs b/tests/target/imports/imports-reorder-lines-and-items.rs similarity index 100% rename from tests/target/imports-reorder-lines-and-items.rs rename to tests/target/imports/imports-reorder-lines-and-items.rs diff --git a/tests/target/imports-reorder-lines.rs b/tests/target/imports/imports-reorder-lines.rs similarity index 100% rename from tests/target/imports-reorder-lines.rs rename to tests/target/imports/imports-reorder-lines.rs diff --git a/tests/target/imports-reorder.rs b/tests/target/imports/imports-reorder.rs similarity index 100% rename from tests/target/imports-reorder.rs rename to tests/target/imports/imports-reorder.rs diff --git a/tests/target/imports.rs b/tests/target/imports/imports.rs similarity index 100% rename from tests/target/imports.rs rename to tests/target/imports/imports.rs diff --git a/tests/target/imports_2021_edition.rs b/tests/target/imports/imports_2021_edition.rs similarity index 100% rename from tests/target/imports_2021_edition.rs rename to tests/target/imports/imports_2021_edition.rs diff --git a/tests/target/imports_block_indent.rs b/tests/target/imports/imports_block_indent.rs similarity index 100% rename from tests/target/imports_block_indent.rs rename to tests/target/imports/imports_block_indent.rs diff --git a/tests/target/imports_granularity_crate.rs b/tests/target/imports/imports_granularity_crate.rs similarity index 100% rename from tests/target/imports_granularity_crate.rs rename to tests/target/imports/imports_granularity_crate.rs diff --git a/tests/target/imports/imports_granularity_default-with-dups.rs b/tests/target/imports/imports_granularity_default-with-dups.rs new file mode 100644 index 0000000000000..5da6d588e6dd6 --- /dev/null +++ b/tests/target/imports/imports_granularity_default-with-dups.rs @@ -0,0 +1,6 @@ +use crate::lexer; +use crate::lexer; +use crate::lexer::tokens::TokenData; +use crate::lexer::tokens::TokenData; +use crate::lexer::{self}; +use crate::lexer::{self, tokens::TokenData}; diff --git a/tests/target/imports/imports_granularity_item-with-dups-StdExternalCrate-no-reorder.rs b/tests/target/imports/imports_granularity_item-with-dups-StdExternalCrate-no-reorder.rs new file mode 100644 index 0000000000000..ed4df544d6f9f --- /dev/null +++ b/tests/target/imports/imports_granularity_item-with-dups-StdExternalCrate-no-reorder.rs @@ -0,0 +1,7 @@ +// rustfmt-imports_granularity: Item +// rustfmt-reorder_imports: false +// rustfmt-group_imports: StdExternalCrate + +use crate::lexer; +use crate::lexer::tokens::TokenData; +use crate::lexer::{self}; diff --git a/tests/target/imports/imports_granularity_item-with-dups.rs b/tests/target/imports/imports_granularity_item-with-dups.rs new file mode 100644 index 0000000000000..00df37f933220 --- /dev/null +++ b/tests/target/imports/imports_granularity_item-with-dups.rs @@ -0,0 +1,5 @@ +// rustfmt-imports_granularity: Item + +use crate::lexer; +use crate::lexer::tokens::TokenData; +use crate::lexer::{self}; diff --git a/tests/target/imports_granularity_item.rs b/tests/target/imports/imports_granularity_item.rs similarity index 100% rename from tests/target/imports_granularity_item.rs rename to tests/target/imports/imports_granularity_item.rs diff --git a/tests/target/imports_granularity_module.rs b/tests/target/imports/imports_granularity_module.rs similarity index 100% rename from tests/target/imports_granularity_module.rs rename to tests/target/imports/imports_granularity_module.rs From 7b73b60faca71d01d900e49831fcb84553e93019 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Sun, 12 Jun 2022 21:04:12 -0500 Subject: [PATCH 51/53] chore: prep v1.5.0 release --- CHANGELOG.md | 21 +++++++++++++++++++-- Cargo.lock | 2 +- Cargo.toml | 2 +- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3664571fe64bb..bfc155cd656a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,12 +2,18 @@ ## [Unreleased] +## [1.5.0] 2022-06-13 + ### Changed -- Also apply `empty_item_single_line=true` to trait definitions to match the behavior of empty functions, structs, enums, and impls [#5047](https://github.com/rust-lang/rustfmt/issues/5047) +- Simplify the rustfmt help text by eliding the full path to the rustfmt binary path from the usage string when running `rustfmt --help` [#5214](https://github.com/rust-lang/rustfmt/issues/5214) ### Fixed +- Remove duplicate imports when `imports_granularity` is set to `Item` [#4725](https://github.com/rust-lang/rustfmt/issues/4725) +- Properly handle stdin input containing an inner skip attribute [#5368](https://github.com/rust-lang/rustfmt/issues/5368) +- Maintain attributes on imports when `imports_granularity` is set to `Item` [#5030](https://github.com/rust-lang/rustfmt/issues/5030) +- Format empty trait definitions as a single line when both `empty_item_single_line` is enabled and `brace_style` is set to `AlwaysNextLine` [#5047](https://github.com/rust-lang/rustfmt/issues/5047) - Don't change granularity of imports containing comments with `imports_granularity` if doing so could lose or misplace those comments [#5311](https://github.com/rust-lang/rustfmt/pull/5311) - Prevent rustfmt from removing trailing comments at the end of files annotated with inner `#![rustfmt::skip]` attributes [#5033](https://github.com/rust-lang/rustfmt/issues/5033) - Fixed various `error[internal]: left behind trailing whitespace"` issues: @@ -60,7 +66,18 @@ ### Removed -- Remove rustfmt binary path from the usage string when running `rustfmt --help` [#5214](https://github.com/rust-lang/rustfmt/issues/5214) +- Removed unstable, nightly-only config option `report_todo` [#5101](https://github.com/rust-lang/rustfmt/issues/5101) +- Removed unstable, nightly-only config option `report_fixme` [#5102](https://github.com/rust-lang/rustfmt/issues/5102) +- Removed unstable, nightly-only config option `license_template_path` [#5103](https://github.com/rust-lang/rustfmt/issues/5103) + +### Misc + +- Improved performance when formatting large and deeply nested expression trees, often found in generated code, which have many expressions that exceed `max_width` [#5128](https://github.com/rust-lang/rustfmt/issues/5128), [#4867](https://github.com/rust-lang/rustfmt/issues/4867), [#4476](https://github.com/rust-lang/rustfmt/issues/4476), [#5139](https://github.com/rust-lang/rustfmt/pull/5139) + +### Install/Download Options +- **rustup (nightly)** - *pending* +- **GitHub Release Binaries** - [Release v1.5.0](https://github.com/rust-lang/rustfmt/releases/tag/v1.5.0) +- **Build from source** - [Tag v1.5.0](https://github.com/rust-lang/rustfmt/tree/v1.5.0), see instructions for how to [install rustfmt from source][install-from-source] ## [1.4.38] 2021-10-20 diff --git a/Cargo.lock b/Cargo.lock index 4eaaee74cf96a..639d35886dcda 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -485,7 +485,7 @@ dependencies = [ [[package]] name = "rustfmt-nightly" -version = "1.4.38" +version = "1.5.0" dependencies = [ "annotate-snippets", "anyhow", diff --git a/Cargo.toml b/Cargo.toml index 0be9723bc4dcf..f26e982406234 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rustfmt-nightly" -version = "1.4.38" +version = "1.5.0" description = "Tool to find and fix Rust formatting issues" repository = "https://github.com/rust-lang/rustfmt" readme = "README.md" From f367f4dee0b11ef41cb60d95c163c28d965d0946 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Sun, 12 Jun 2022 22:04:54 -0500 Subject: [PATCH 52/53] update rustfmt version --- Cargo.lock | 103 +++++++++++++++++++++-------------------------------- 1 file changed, 41 insertions(+), 62 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 51b0da65b3145..014eb7eb0fdf9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -72,7 +72,14 @@ name = "annotate-snippets" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d78ea013094e5ea606b1c05fe35f1dd7ea1eb1ea259908d040b25bd5ec677ee5" + +[[package]] +name = "annotate-snippets" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3b9d411ecbaf79885c6df4d75fff75858d5995ff25385657a28af47e82f9c36" dependencies = [ + "unicode-width", "yansi-term", ] @@ -614,6 +621,7 @@ checksum = "6d76c22c9b9b215eeb8d016ad3a90417bd13cb24cf8142756e6472445876cab7" dependencies = [ "atty", "bitflags", + "clap_derive", "indexmap", "lazy_static", "os_str_bytes", @@ -631,6 +639,19 @@ dependencies = [ "clap 3.1.1", ] +[[package]] +name = "clap_derive" +version = "3.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25320346e922cffe59c0bbc5410c8d8784509efb321488971081313cb1e1a33c" +dependencies = [ + "heck 0.4.0", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "clippy" version = "0.1.63" @@ -1099,11 +1120,10 @@ dependencies = [ [[package]] name = "dirs" -version = "2.0.2" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" dependencies = [ - "cfg-if 0.1.10", "dirs-sys", ] @@ -1219,19 +1239,6 @@ dependencies = [ "termcolor", ] -[[package]] -name = "env_logger" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3" -dependencies = [ - "atty", - "humantime 2.0.1", - "log", - "regex", - "termcolor", -] - [[package]] name = "env_logger" version = "0.9.0" @@ -1708,6 +1715,12 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "heck" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" + [[package]] name = "hermit-abi" version = "0.1.19" @@ -3290,7 +3303,7 @@ dependencies = [ "difference", "env_logger 0.9.0", "futures 0.3.19", - "heck", + "heck 0.3.1", "home", "itertools", "jsonrpc-core", @@ -3833,7 +3846,7 @@ dependencies = [ name = "rustc_errors" version = "0.0.0" dependencies = [ - "annotate-snippets", + "annotate-snippets 0.8.0", "atty", "rustc_data_structures", "rustc_error_messages", @@ -4084,7 +4097,7 @@ dependencies = [ name = "rustc_macros" version = "0.1.0" dependencies = [ - "annotate-snippets", + "annotate-snippets 0.8.0", "fluent-bundle", "fluent-syntax", "proc-macro2", @@ -4671,16 +4684,17 @@ dependencies = [ [[package]] name = "rustfmt-nightly" -version = "1.4.38" +version = "1.5.0" dependencies = [ - "annotate-snippets", + "annotate-snippets 0.9.1", "anyhow", "bytecount", "cargo_metadata", + "clap 3.1.1", "derive-new", "diff", "dirs", - "env_logger 0.8.4", + "env_logger 0.9.0", "getopts", "ignore", "itertools", @@ -4691,8 +4705,7 @@ dependencies = [ "rustfmt-config_proc_macro", "serde", "serde_json", - "structopt", - "term 0.6.1", + "term", "thiserror", "toml", "unicode-segmentation", @@ -5080,30 +5093,6 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" -[[package]] -name = "structopt" -version = "0.3.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40b9788f4202aa75c240ecc9c15c65185e6a39ccdeb0fd5d008b98825464c87c" -dependencies = [ - "clap 2.34.0", - "lazy_static", - "structopt-derive", -] - -[[package]] -name = "structopt-derive" -version = "0.4.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" -dependencies = [ - "heck", - "proc-macro-error", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "strum" version = "0.18.0" @@ -5116,7 +5105,7 @@ version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87c85aa3f8ea653bfd3ddf25f7ee357ee4d204731f6aa9ad04002306f6e2774c" dependencies = [ - "heck", + "heck 0.3.1", "proc-macro2", "quote", "syn", @@ -5196,16 +5185,6 @@ dependencies = [ "utf-8", ] -[[package]] -name = "term" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0863a3345e70f61d613eab32ee046ccd1bcc5f9105fe402c61fcd0c13eeb8b5" -dependencies = [ - "dirs", - "winapi", -] - [[package]] name = "term" version = "0.7.0" @@ -5260,7 +5239,7 @@ dependencies = [ "getopts", "libc", "num_cpus", - "term 0.7.0", + "term", ] [[package]] @@ -5689,9 +5668,9 @@ dependencies = [ [[package]] name = "unicode-segmentation" -version = "1.6.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" +checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" [[package]] name = "unicode-width" From 3733e45d97896a3880ac3dba8208a5fdba9fd9c7 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Mon, 13 Jun 2022 17:01:44 -0500 Subject: [PATCH 53/53] deps: add clap to workspace hack --- Cargo.lock | 1 + src/tools/rustc-workspace-hack/Cargo.toml | 1 + 2 files changed, 2 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 014eb7eb0fdf9..4322fc56c445b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3512,6 +3512,7 @@ version = "1.0.0" dependencies = [ "bstr", "byteorder", + "clap 3.1.1", "crossbeam-utils", "libc", "libz-sys", diff --git a/src/tools/rustc-workspace-hack/Cargo.toml b/src/tools/rustc-workspace-hack/Cargo.toml index a79290e7a6bc3..992a2e83f63c4 100644 --- a/src/tools/rustc-workspace-hack/Cargo.toml +++ b/src/tools/rustc-workspace-hack/Cargo.toml @@ -73,6 +73,7 @@ features = [ [dependencies] bstr = { version = "0.2.13", features = ["default"] } byteorder = { version = "1", features = ['default', 'std'] } +clap = { version = "3.1.1", features = ["lazy_static", "derive", "clap_derive"]} curl-sys = { version = "0.4.13", features = ["http2", "libnghttp2-sys"], optional = true } crossbeam-utils = { version = "0.8.0", features = ["nightly"] } libc = { version = "0.2.79", features = ["align"] }