From 75765f656ebae28dbbc6f93d36a1e851473aeec9 Mon Sep 17 00:00:00 2001 From: Ruby Lazuli Date: Sat, 22 May 2021 08:22:42 -0500 Subject: Allow `--edition 2021` to be passed to rustfmt This was added to Configurations.md in #4618, but the option wasn't actually made available. This should let people who are using Rust 2021 on nightly rustc run `cargo fmt` again. --- src/bin/main.rs | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/bin/main.rs b/src/bin/main.rs index 56b07222212..92fe8b9c514 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -689,6 +689,7 @@ fn edition_from_edition_str(edition_str: &str) -> Result { match edition_str { "2015" => Ok(Edition::Edition2015), "2018" => Ok(Edition::Edition2018), + "2021" => Ok(Edition::Edition2021), _ => Err(format_err!("Invalid value for `--edition`")), } } -- cgit 1.4.1-3-g733a5 From 1ca3798d2c961c43b02e312e8aa0e4bfa3f1b37e Mon Sep 17 00:00:00 2001 From: Casey Rodarmor Date: Sun, 9 May 2021 20:01:24 -0700 Subject: Improve pasta copyability of `merge_imports` deprecation message Add double quotes around `Crate` so that it can be copied directly into a `Cargo.toml` file --- src/config/config_type.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/config/config_type.rs b/src/config/config_type.rs index 2f567b25521..7fc4486ddcd 100644 --- a/src/config/config_type.rs +++ b/src/config/config_type.rs @@ -409,7 +409,7 @@ macro_rules! create_config { if self.was_set().merge_imports() { eprintln!( "Warning: the `merge_imports` option is deprecated. \ - Use `imports_granularity=Crate` instead" + Use `imports_granularity=\"Crate\"` instead" ); if !self.was_set().imports_granularity() { self.imports_granularity.2 = if self.merge_imports() { -- cgit 1.4.1-3-g733a5 From 486e774fbfbbe2be98cdd2ebdbfc3e8b92fc2a95 Mon Sep 17 00:00:00 2001 From: Michael Murphy Date: Fri, 11 Jun 2021 02:39:28 +0100 Subject: Adjusting help message (#4865) On stable, running with `--help|-h` shows information about `file-lines` which is a nightly-only option. This commit removes all mention of `file-lines` from the help message on stable. There is room for improvement here; perhaps a new struct called, e.g., `StableOptions` could be added to complement the existing `GetOptsOptions` struct. `StableOptions` could have a field for each field in `GetOptsOptions`, with each field's value being a `bool` that specifies whether or not the option exists on stable. Or is this adding too much complexity? --- src/bin/main.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/bin/main.rs b/src/bin/main.rs index 92fe8b9c514..4b4aa42d935 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -178,12 +178,15 @@ fn make_opts() -> Options { opts.optflag("v", "verbose", "Print verbose output"); opts.optflag("q", "quiet", "Print less output"); opts.optflag("V", "version", "Show version information"); - opts.optflagopt( - "h", - "help", - "Show this message or help about a specific topic: `config` or `file-lines`", - "=TOPIC", - ); + let help_topics = if is_nightly { + "`config` or `file-lines`" + } else { + "`config`" + }; + let mut help_topic_msg = "Show this message or help about a specific topic: ".to_owned(); + help_topic_msg.push_str(help_topics); + + opts.optflagopt("h", "help", &help_topic_msg, "=TOPIC"); opts } @@ -437,7 +440,7 @@ fn determine_operation(matches: &Matches) -> Result { return Ok(Operation::Help(HelpOp::None)); } else if topic == Some("config".to_owned()) { return Ok(Operation::Help(HelpOp::Config)); - } else if topic == Some("file-lines".to_owned()) { + } else if topic == Some("file-lines".to_owned()) && is_nightly() { return Ok(Operation::Help(HelpOp::FileLines)); } else { return Err(OperationError::UnknownHelpTopic(topic.unwrap())); -- cgit 1.4.1-3-g733a5 From b305d62e5b9e08c6f4540de0a349fbf6da3dc0e4 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Thu, 24 Jun 2021 18:22:28 -0500 Subject: fix: correct arm leading pipe check (#4880) In the event a pattern starts with a leading pipe the pattern span will contain, and begin with, the pipe. This updates the process to see if a match arm contains a leading pipe by leveraging this recent(ish) change to the patterns in the AST, and avoids an indexing bug that occurs when a pattern starts with a non-ascii char in the old implementation. --- src/matches.rs | 7 ++++--- .../source/configs/match_arm_leading_pipes/preserve.rs | 8 ++++++++ .../target/configs/match_arm_leading_pipes/preserve.rs | 8 ++++++++ tests/target/issue_4868.rs | 17 +++++++++++++++++ 4 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 tests/target/issue_4868.rs (limited to 'src') diff --git a/src/matches.rs b/src/matches.rs index f33fedce92d..140ec226c02 100644 --- a/src/matches.rs +++ b/src/matches.rs @@ -19,7 +19,7 @@ use crate::source_map::SpanUtils; use crate::spanned::Spanned; use crate::utils::{ contains_skip, extra_offset, first_line_width, inner_attributes, last_line_extendable, mk_sp, - mk_sp_lo_plus_one, semicolon_for_expr, trimmed_last_line_width, unicode_str_width, + semicolon_for_expr, trimmed_last_line_width, unicode_str_width, }; /// A simple wrapper type against `ast::Arm`. Used inside `write_list()`. @@ -167,8 +167,9 @@ fn collect_beginning_verts( arms.iter() .map(|a| { context - .snippet_provider - .opt_span_before(mk_sp_lo_plus_one(a.pat.span.lo()), "|") + .snippet(a.pat.span) + .starts_with("|") + .then(|| a.pat.span().lo()) }) .collect() } diff --git a/tests/source/configs/match_arm_leading_pipes/preserve.rs b/tests/source/configs/match_arm_leading_pipes/preserve.rs index ea303e857de..5486877bde1 100644 --- a/tests/source/configs/match_arm_leading_pipes/preserve.rs +++ b/tests/source/configs/match_arm_leading_pipes/preserve.rs @@ -26,3 +26,11 @@ fn bar() { _ => {} } } + +fn f(x: NonAscii) -> bool { + match x { + // foo + | Éfgh => true, + _ => false, + } +} \ No newline at end of file diff --git a/tests/target/configs/match_arm_leading_pipes/preserve.rs b/tests/target/configs/match_arm_leading_pipes/preserve.rs index 2beb1f5d813..4775575842a 100644 --- a/tests/target/configs/match_arm_leading_pipes/preserve.rs +++ b/tests/target/configs/match_arm_leading_pipes/preserve.rs @@ -25,3 +25,11 @@ fn bar() { _ => {} } } + +fn f(x: NonAscii) -> bool { + match x { + // foo + | Éfgh => true, + _ => false, + } +} diff --git a/tests/target/issue_4868.rs b/tests/target/issue_4868.rs new file mode 100644 index 00000000000..763a82c3231 --- /dev/null +++ b/tests/target/issue_4868.rs @@ -0,0 +1,17 @@ +enum NonAscii { + Abcd, + Éfgh, +} + +use NonAscii::*; + +fn f(x: NonAscii) -> bool { + match x { + Éfgh => true, + _ => false, + } +} + +fn main() { + dbg!(f(Abcd)); +} -- cgit 1.4.1-3-g733a5 From 4c2959fb12a6bd083003ec4371126211402e265d Mon Sep 17 00:00:00 2001 From: Matthias Krüger Date: Sun, 18 Jul 2021 10:44:39 +0200 Subject: fix a bunch of clippy warnings clippy::bind_instead_of_map clippy::branches_sharing_code clippy::collapsible_match clippy::inconsistent_struct_constructor clippy::int_plus_one clippy::iter_count clippy::iter_nth_zero clippy::manual_range_contains clippy::match_like_matches_macro clippy::needless::collect clippy::needless_question_mark clippy::needless_return clippy::op_ref clippy::option_as_ref_deref clippy::ptr_arg clippy::redundant_clone clippy::redundant_closure clippy::redundant_static_lifetimes clippy::search_is_some clippy::#single_char_add_str clippy::single_char_pattern clippy::single_component_path_imports clippy::single_match clippy::skip_while_next clippy::unnecessary_lazy_evaluations clippy::unnecessary_unwrap clippy::useless_conversion clippy::useless_format --- src/attr.rs | 2 +- src/cargo-fmt/main.rs | 4 ++-- src/chains.rs | 5 +---- src/closures.rs | 15 ++++++--------- src/comment.rs | 21 +++++++++------------ src/config/file_lines.rs | 4 ++-- src/config/license.rs | 1 - src/emitter/diff.rs | 2 +- src/expr.rs | 30 ++++++++++-------------------- src/formatting/newline_style.rs | 2 +- src/imports.rs | 30 +++++++++++------------------- src/issues.rs | 14 +++----------- src/items.rs | 26 ++++++++++---------------- src/lib.rs | 6 +----- src/lists.rs | 11 ++++------- src/macros.rs | 39 ++++++++++++++++++--------------------- src/missed_spans.rs | 8 +++----- src/overflow.rs | 28 +++++++++++----------------- src/patterns.rs | 25 +++++++++++-------------- src/rustfmt_diff.rs | 7 ++----- src/skip.rs | 6 +++--- src/source_file.rs | 2 +- src/string.rs | 4 ++-- src/syntux/parser.rs | 5 ++--- src/types.rs | 15 ++++----------- src/utils.rs | 5 ++--- src/visitor.rs | 18 +++++++++--------- 27 files changed, 130 insertions(+), 205 deletions(-) (limited to 'src') diff --git a/src/attr.rs b/src/attr.rs index c5ffb074ba5..315eb10a9db 100644 --- a/src/attr.rs +++ b/src/attr.rs @@ -183,7 +183,7 @@ fn format_derive( } else if let SeparatorTactic::Always = context.config.trailing_comma() { // Retain the trailing comma. result.push_str(&item_str); - } else if item_str.ends_with(",") { + } else if item_str.ends_with(',') { // Remove the trailing comma. result.push_str(&item_str[..item_str.len() - 1]); } else { diff --git a/src/cargo-fmt/main.rs b/src/cargo-fmt/main.rs index 9062a2952ec..ba693e852ff 100644 --- a/src/cargo-fmt/main.rs +++ b/src/cargo-fmt/main.rs @@ -405,8 +405,8 @@ fn get_targets_recursive( .packages .iter() .find(|p| p.name == dependency.name && p.source.is_none()); - let manifest_path = if dependency_package.is_some() { - PathBuf::from(&dependency_package.unwrap().manifest_path) + let manifest_path = if let Some(dep_pkg) = dependency_package { + PathBuf::from(&dep_pkg.manifest_path) } else { let mut package_manifest_path = PathBuf::from(&package.manifest_path); package_manifest_path.pop(); diff --git a/src/chains.rs b/src/chains.rs index 8053f0e8fec..614638ea2ab 100644 --- a/src/chains.rs +++ b/src/chains.rs @@ -231,10 +231,7 @@ impl ChainItem { } fn is_comment(&self) -> bool { - match self.kind { - ChainItemKind::Comment(..) => true, - _ => false, - } + matches!(self.kind, ChainItemKind::Comment(..)) } fn rewrite_method_call( diff --git a/src/closures.rs b/src/closures.rs index 3d65077ddc2..c9d46aef294 100644 --- a/src/closures.rs +++ b/src/closures.rs @@ -336,7 +336,7 @@ pub(crate) fn rewrite_last_closure( // We force to use block for the body of the closure for certain kinds of expressions. if is_block_closure_forced(context, body) { - return rewrite_closure_with_block(body, &prefix, context, body_shape).and_then( + return rewrite_closure_with_block(body, &prefix, context, body_shape).map( |body_str| { match fn_decl.output { ast::FnRetTy::Default(..) if body_str.lines().count() <= 7 => { @@ -344,15 +344,15 @@ pub(crate) fn rewrite_last_closure( // closure. However, if the closure has a return type, then we must // keep the blocks. match rewrite_closure_expr(body, &prefix, context, shape) { - Some(ref single_line_body_str) + Some(single_line_body_str) if !single_line_body_str.contains('\n') => { - Some(single_line_body_str.clone()) + single_line_body_str } - _ => Some(body_str), + _ => body_str, } } - _ => Some(body_str), + _ => body_str, } }, ); @@ -377,10 +377,7 @@ pub(crate) fn rewrite_last_closure( pub(crate) fn args_have_many_closure(args: &[OverflowableItem<'_>]) -> bool { args.iter() .filter_map(OverflowableItem::to_expr) - .filter(|expr| match expr.kind { - ast::ExprKind::Closure(..) => true, - _ => false, - }) + .filter(|expr| matches!(expr.kind, ast::ExprKind::Closure(..))) .count() > 1 } diff --git a/src/comment.rs b/src/comment.rs index c71302fdd18..0f8118a408e 100644 --- a/src/comment.rs +++ b/src/comment.rs @@ -67,10 +67,7 @@ impl<'a> CommentStyle<'a> { /// Returns `true` if the commenting style is for documentation. pub(crate) fn is_doc_comment(&self) -> bool { - match *self { - CommentStyle::TripleSlash | CommentStyle::Doc => true, - _ => false, - } + matches!(*self, CommentStyle::TripleSlash | CommentStyle::Doc) } pub(crate) fn opener(&self) -> &'a str { @@ -689,8 +686,8 @@ impl<'a> CommentRewrite<'a> { self.code_block_attr = None; self.item_block = None; - if line.starts_with("```") { - self.code_block_attr = Some(CodeBlockAttribute::new(&line[3..])) + if let Some(stripped) = line.strip_prefix("```") { + self.code_block_attr = Some(CodeBlockAttribute::new(stripped)) } else if self.fmt.config.wrap_comments() && ItemizedBlock::is_itemized_line(&line) { let ib = ItemizedBlock::new(&line); self.item_block = Some(ib); @@ -948,8 +945,8 @@ fn left_trim_comment_line<'a>(line: &'a str, style: &CommentStyle<'_>) -> (&'a s { (&line[4..], true) } else if let CommentStyle::Custom(opener) = *style { - if line.starts_with(opener) { - (&line[opener.len()..], true) + if let Some(ref stripped) = line.strip_prefix(opener) { + (stripped, true) } else { (&line[opener.trim_end().len()..], false) } @@ -968,8 +965,8 @@ fn left_trim_comment_line<'a>(line: &'a str, style: &CommentStyle<'_>) -> (&'a s || line.starts_with("**") { (&line[2..], line.chars().nth(1).unwrap() == ' ') - } else if line.starts_with('*') { - (&line[1..], false) + } else if let Some(stripped) = line.strip_prefix('*') { + (stripped, false) } else { (line, line.starts_with(' ')) } @@ -1682,8 +1679,8 @@ impl<'a> Iterator for CommentReducer<'a> { fn remove_comment_header(comment: &str) -> &str { if comment.starts_with("///") || comment.starts_with("//!") { &comment[3..] - } else if comment.starts_with("//") { - &comment[2..] + } else if let Some(ref stripped) = comment.strip_prefix("//") { + stripped } else if (comment.starts_with("/**") && !comment.starts_with("/**/")) || comment.starts_with("/*!") { diff --git a/src/config/file_lines.rs b/src/config/file_lines.rs index 22dd091cb51..4b799780d85 100644 --- a/src/config/file_lines.rs +++ b/src/config/file_lines.rs @@ -305,7 +305,7 @@ impl str::FromStr for FileLines { let mut m = HashMap::new(); for js in v { let (s, r) = JsonSpan::into_tuple(js)?; - m.entry(s).or_insert_with(|| vec![]).push(r); + m.entry(s).or_insert_with(Vec::new).push(r); } Ok(FileLines::from_ranges(m)) } @@ -322,7 +322,7 @@ impl JsonSpan { fn into_tuple(self) -> Result<(FileName, Range), FileLinesError> { let (lo, hi) = self.range; let canonical = canonicalize_path_string(&self.file) - .ok_or_else(|| FileLinesError::CannotCanonicalize(self.file))?; + .ok_or(FileLinesError::CannotCanonicalize(self.file))?; Ok((canonical, Range::new(lo, hi))) } } diff --git a/src/config/license.rs b/src/config/license.rs index 121a1b1c151..c7feb502ea9 100644 --- a/src/config/license.rs +++ b/src/config/license.rs @@ -3,7 +3,6 @@ use std::fs::File; use std::io; use std::io::Read; -use regex; use regex::Regex; #[derive(Debug)] diff --git a/src/emitter/diff.rs b/src/emitter/diff.rs index 9be4fb28f99..2fbbfedb566 100644 --- a/src/emitter/diff.rs +++ b/src/emitter/diff.rs @@ -45,7 +45,7 @@ impl Emitter for DiffEmitter { return Ok(EmitterResult { has_diff: true }); } - return Ok(EmitterResult { has_diff }); + Ok(EmitterResult { has_diff }) } } diff --git a/src/expr.rs b/src/expr.rs index bca9f77f959..6cfeb9977a9 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -263,15 +263,12 @@ pub(crate) fn format_expr( } fn needs_space_after_range(rhs: &ast::Expr) -> bool { - match rhs.kind { - // Don't format `.. ..` into `....`, which is invalid. - // - // This check is unnecessary for `lhs`, because a range - // starting from another range needs parentheses as `(x ..) ..` - // (`x .. ..` is a range from `x` to `..`). - ast::ExprKind::Range(None, _, _) => true, - _ => false, - } + // Don't format `.. ..` into `....`, which is invalid. + // + // This check is unnecessary for `lhs`, because a range + // starting from another range needs parentheses as `(x ..) ..` + // (`x .. ..` is a range from `x` to `..`). + matches!(rhs.kind, ast::ExprKind::Range(None, _, _)) } let default_sp_delim = |lhs: Option<&ast::Expr>, rhs: Option<&ast::Expr>| { @@ -531,7 +528,7 @@ pub(crate) fn rewrite_block_with_visitor( let inner_attrs = attrs.map(inner_attributes); let label_str = rewrite_label(label); - visitor.visit_block(block, inner_attrs.as_ref().map(|a| &**a), has_braces); + visitor.visit_block(block, inner_attrs.as_deref(), has_braces); let visitor_context = visitor.get_context(); context .skipped_range @@ -595,7 +592,7 @@ pub(crate) fn rewrite_cond( String::from("\n") + &shape.indent.block_only().to_string(context.config); control_flow .rewrite_cond(context, shape, &alt_block_sep) - .and_then(|rw| Some(rw.0)) + .map(|rw| rw.0) }), } } @@ -1157,18 +1154,11 @@ pub(crate) fn is_empty_block( } pub(crate) fn stmt_is_expr(stmt: &ast::Stmt) -> bool { - match stmt.kind { - ast::StmtKind::Expr(..) => true, - _ => false, - } + matches!(stmt.kind, ast::StmtKind::Expr(..)) } pub(crate) fn is_unsafe_block(block: &ast::Block) -> bool { - if let ast::BlockCheckMode::Unsafe(..) = block.rules { - true - } else { - false - } + matches!(block.rules, ast::BlockCheckMode::Unsafe(..)) } pub(crate) fn rewrite_literal( diff --git a/src/formatting/newline_style.rs b/src/formatting/newline_style.rs index ac620094900..97c4fc16d6f 100644 --- a/src/formatting/newline_style.rs +++ b/src/formatting/newline_style.rs @@ -77,7 +77,7 @@ fn convert_to_windows_newlines(formatted_text: &String) -> String { transformed } -fn convert_to_unix_newlines(formatted_text: &String) -> String { +fn convert_to_unix_newlines(formatted_text: &str) -> String { formatted_text.replace(WINDOWS_NEWLINE, UNIX_NEWLINE) } diff --git a/src/imports.rs b/src/imports.rs index 0f635fe1ccb..64d78605f0c 100644 --- a/src/imports.rs +++ b/src/imports.rs @@ -374,7 +374,7 @@ impl UseTree { UseTreeKind::Nested(ref list) => { // Extract comments between nested use items. // This needs to be done before sorting use items. - let items: Vec<_> = itemize_list( + let items = itemize_list( context.snippet_provider, list.iter().map(|(tree, _)| tree), "}", @@ -385,8 +385,8 @@ impl UseTree { context.snippet_provider.span_after(a.span, "{"), a.span.hi(), false, - ) - .collect(); + ); + // in case of a global path and the nested list starts at the root, // e.g., "::{foo, bar}" if a.prefix.segments.len() == 1 && leading_modsep { @@ -394,7 +394,7 @@ impl UseTree { } result.path.push(UseSegment::List( list.iter() - .zip(items.into_iter()) + .zip(items) .map(|(t, list_item)| { Self::from_ast(context, &t.0, Some(list_item), None, None, None) }) @@ -466,11 +466,8 @@ impl UseTree { // Normalise foo::self as bar -> foo as bar. if let UseSegment::Slf(_) = last { - match self.path.last() { - Some(UseSegment::Ident(_, None)) => { - aliased_self = true; - } - _ => {} + if let Some(UseSegment::Ident(_, None)) = self.path.last() { + aliased_self = true; } } @@ -572,9 +569,8 @@ impl UseTree { match self.path.clone().last().unwrap() { UseSegment::List(list) => { if list.len() == 1 && list[0].path.len() == 1 { - match list[0].path[0] { - UseSegment::Slf(..) => return vec![self], - _ => (), + if let UseSegment::Slf(..) = list[0].path[0] { + return vec![self]; }; } let prefix = &self.path[..self.path.len() - 1]; @@ -790,13 +786,9 @@ fn rewrite_nested_use_tree( } } let has_nested_list = use_tree_list.iter().any(|use_segment| { - use_segment - .path - .last() - .map_or(false, |last_segment| match last_segment { - UseSegment::List(..) => true, - _ => false, - }) + use_segment.path.last().map_or(false, |last_segment| { + matches!(last_segment, UseSegment::List(..)) + }) }); let remaining_width = if has_nested_list { diff --git a/src/issues.rs b/src/issues.rs index d369b75541e..33fb5522aea 100644 --- a/src/issues.rs +++ b/src/issues.rs @@ -126,11 +126,7 @@ impl BadIssueSeeker { return Seeking::Number { issue: Issue { issue_type: IssueType::Todo, - missing_number: if let ReportTactic::Unnumbered = self.report_todo { - true - } else { - false - }, + missing_number: matches!(self.report_todo, ReportTactic::Unnumbered), }, part: NumberPart::OpenParen, }; @@ -144,11 +140,7 @@ impl BadIssueSeeker { return Seeking::Number { issue: Issue { issue_type: IssueType::Fixme, - missing_number: if let ReportTactic::Unnumbered = self.report_fixme { - true - } else { - false - }, + missing_number: matches!(self.report_fixme, ReportTactic::Unnumbered), }, part: NumberPart::OpenParen, }; @@ -196,7 +188,7 @@ impl BadIssueSeeker { } } NumberPart::Number => { - if c >= '0' && c <= '9' { + if ('0'..='9').contains(&c) { part = NumberPart::CloseParen; } else { return IssueClassification::Bad(issue); diff --git a/src/items.rs b/src/items.rs index 420484c0ba1..0542358c6e7 100644 --- a/src/items.rs +++ b/src/items.rs @@ -741,7 +741,7 @@ pub(crate) fn format_impl( // there is only one where-clause predicate // recover the suppressed comma in single line where_clause formatting if generics.where_clause.predicates.len() == 1 { - result.push_str(","); + result.push(','); } result.push_str(&format!("{}{{{}}}", sep, sep)); } else { @@ -1207,7 +1207,7 @@ impl<'a> Rewrite for TraitAliasBounds<'a> { let fits_single_line = !generic_bounds_str.contains('\n') && !where_str.contains('\n') - && generic_bounds_str.len() + where_str.len() + 1 <= shape.width; + && generic_bounds_str.len() + where_str.len() < shape.width; let space = if generic_bounds_str.is_empty() || where_str.is_empty() { Cow::from("") } else if fits_single_line { @@ -1236,8 +1236,8 @@ pub(crate) fn format_trait_alias( let lhs = format!("{}trait {} =", vis_str, generics_str); // 1 = ";" let trait_alias_bounds = TraitAliasBounds { - generics, generic_bounds, + generics, }; rewrite_assign_rhs(context, lhs, &trait_alias_bounds, shape.sub_width(1)?).map(|s| s + ";") } @@ -1993,7 +1993,7 @@ impl Rewrite for ast::Param { let num_attrs = self.attrs.len(); ( mk_sp(self.attrs[num_attrs - 1].span.hi(), self.pat.span.lo()), - param_attrs_result.contains("\n"), + param_attrs_result.contains('\n'), ) } else { (mk_sp(self.span.lo(), self.span.lo()), false) @@ -3265,22 +3265,16 @@ pub(crate) fn rewrite_extern_crate( /// Returns `true` for `mod foo;`, false for `mod foo { .. }`. pub(crate) fn is_mod_decl(item: &ast::Item) -> bool { - match item.kind { - ast::ItemKind::Mod(_, ast::ModKind::Loaded(_, ast::Inline::Yes, _)) => false, - _ => true, - } + !matches!( + item.kind, + ast::ItemKind::Mod(_, ast::ModKind::Loaded(_, ast::Inline::Yes, _)) + ) } pub(crate) fn is_use_item(item: &ast::Item) -> bool { - match item.kind { - ast::ItemKind::Use(_) => true, - _ => false, - } + matches!(item.kind, ast::ItemKind::Use(_)) } pub(crate) fn is_extern_crate(item: &ast::Item) -> bool { - match item.kind { - ast::ItemKind::ExternCrate(..) => true, - _ => false, - } + matches!(item.kind, ast::ItemKind::ExternCrate(..)) } diff --git a/src/lib.rs b/src/lib.rs index ce8a45eea65..eb314e63de3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -30,7 +30,6 @@ use std::panic; use std::path::PathBuf; use std::rc::Rc; -use ignore; use rustc_ast::ast; use rustc_span::{symbol, DUMMY_SP}; use thiserror::Error; @@ -149,10 +148,7 @@ pub enum ErrorKind { impl ErrorKind { fn is_comment(&self) -> bool { - match self { - ErrorKind::LostComment => true, - _ => false, - } + matches!(self, ErrorKind::LostComment) } } diff --git a/src/lists.rs b/src/lists.rs index ccf8f784c04..73e886c5563 100644 --- a/src/lists.rs +++ b/src/lists.rs @@ -194,10 +194,7 @@ impl ListItem { // Returns `true` if the item causes something to be written. fn is_substantial(&self) -> bool { fn empty(s: &Option) -> bool { - match *s { - Some(ref s) if !s.is_empty() => false, - _ => true, - } + !matches!(*s, Some(ref s) if !s.is_empty()) } !(empty(&self.pre_comment) && empty(&self.item) && empty(&self.post_comment)) @@ -618,8 +615,8 @@ pub(crate) fn extract_post_comment( let post_snippet = post_snippet[..comment_end].trim(); let post_snippet_trimmed = if post_snippet.starts_with(|c| c == ',' || c == ':') { post_snippet[1..].trim_matches(white_space) - } else if post_snippet.starts_with(separator) { - post_snippet[separator.len()..].trim_matches(white_space) + } else if let Some(stripped) = post_snippet.strip_prefix(separator) { + stripped.trim_matches(white_space) } // not comment or over two lines else if post_snippet.ends_with(',') @@ -823,7 +820,7 @@ where pub(crate) fn total_item_width(item: &ListItem) -> usize { comment_len(item.pre_comment.as_ref().map(|x| &(*x)[..])) + comment_len(item.post_comment.as_ref().map(|x| &(*x)[..])) - + &item.item.as_ref().map_or(0, |s| unicode_str_width(&s)) + + item.item.as_ref().map_or(0, |s| unicode_str_width(&s)) } fn comment_len(comment: Option<&str>) -> usize { diff --git a/src/macros.rs b/src/macros.rs index bf4769b34aa..6c5e32716c0 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -179,10 +179,10 @@ fn return_macro_parse_failure_fallback( .lines() .last() .map(|closing_line| { - closing_line.trim().chars().all(|ch| match ch { - '}' | ')' | ']' => true, - _ => false, - }) + closing_line + .trim() + .chars() + .all(|ch| matches!(ch, '}' | ')' | ']')) }) .unwrap_or(false); if is_like_block_indent_style { @@ -690,25 +690,22 @@ fn delim_token_to_str( impl MacroArgKind { fn starts_with_brace(&self) -> bool { - match *self { + matches!( + *self, MacroArgKind::Repeat(DelimToken::Brace, _, _, _) - | MacroArgKind::Delimited(DelimToken::Brace, _) => true, - _ => false, - } + | MacroArgKind::Delimited(DelimToken::Brace, _) + ) } fn starts_with_dollar(&self) -> bool { - match *self { - MacroArgKind::Repeat(..) | MacroArgKind::MetaVariable(..) => true, - _ => false, - } + matches!( + *self, + MacroArgKind::Repeat(..) | MacroArgKind::MetaVariable(..) + ) } fn ends_with_space(&self) -> bool { - match *self { - MacroArgKind::Separator(..) => true, - _ => false, - } + matches!(*self, MacroArgKind::Separator(..)) } fn has_meta_var(&self) -> bool { @@ -1162,10 +1159,10 @@ fn force_space_before(tok: &TokenKind) -> bool { } fn ident_like(tok: &Token) -> bool { - match tok.kind { - TokenKind::Ident(..) | TokenKind::Literal(..) | TokenKind::Lifetime(_) => true, - _ => false, - } + matches!( + tok.kind, + TokenKind::Ident(..) | TokenKind::Literal(..) | TokenKind::Lifetime(_) + ) } fn next_space(tok: &TokenKind) -> SpaceState { @@ -1399,7 +1396,7 @@ impl MacroBranch { // Undo our replacement of macro variables. // FIXME: this could be *much* more efficient. for (old, new) in &substs { - if old_body.find(new).is_some() { + if old_body.contains(new) { debug!("rewrite_macro_def: bailing matching variable: `{}`", new); return None; } diff --git a/src/missed_spans.rs b/src/missed_spans.rs index 17b11ed6cf4..263d840785a 100644 --- a/src/missed_spans.rs +++ b/src/missed_spans.rs @@ -230,8 +230,7 @@ impl<'a> FmtVisitor<'a> { let last_char = big_snippet .chars() .rev() - .skip_while(|rev_c| [' ', '\t'].contains(rev_c)) - .next(); + .find(|rev_c| ![' ', '\t'].contains(rev_c)); let fix_indent = last_char.map_or(true, |rev_c| ['{', '\n'].contains(&rev_c)); let mut on_same_line = false; @@ -262,7 +261,7 @@ impl<'a> FmtVisitor<'a> { let comment_shape = Shape::legacy(comment_width, comment_indent); if on_same_line { - match subslice.find("\n") { + match subslice.find('\n') { None => { self.push_str(subslice); } @@ -299,8 +298,7 @@ impl<'a> FmtVisitor<'a> { match snippet[status.line_start..] .chars() // skip trailing whitespaces - .skip_while(|c| *c == ' ' || *c == '\t') - .next() + .find(|c| !(*c == ' ' || *c == '\t')) { Some('\n') | Some('\r') => { if !is_last_comment_block(subslice) { diff --git a/src/overflow.rs b/src/overflow.rs index d670b0a41e8..e32213467a5 100644 --- a/src/overflow.rs +++ b/src/overflow.rs @@ -126,21 +126,19 @@ impl<'a> OverflowableItem<'a> { OverflowableItem::MacroArg(MacroArg::Expr(expr)) => is_simple_expr(expr), OverflowableItem::NestedMetaItem(nested_meta_item) => match nested_meta_item { ast::NestedMetaItem::Literal(..) => true, - ast::NestedMetaItem::MetaItem(ref meta_item) => match meta_item.kind { - ast::MetaItemKind::Word => true, - _ => false, - }, + ast::NestedMetaItem::MetaItem(ref meta_item) => { + matches!(meta_item.kind, ast::MetaItemKind::Word) + } }, _ => false, } } pub(crate) fn is_expr(&self) -> bool { - match self { - OverflowableItem::Expr(..) => true, - OverflowableItem::MacroArg(MacroArg::Expr(..)) => true, - _ => false, - } + matches!( + self, + OverflowableItem::Expr(..) | OverflowableItem::MacroArg(MacroArg::Expr(..)) + ) } pub(crate) fn is_nested_call(&self) -> bool { @@ -154,10 +152,7 @@ impl<'a> OverflowableItem<'a> { pub(crate) fn to_expr(&self) -> Option<&'a ast::Expr> { match self { OverflowableItem::Expr(expr) => Some(expr), - OverflowableItem::MacroArg(macro_arg) => match macro_arg { - MacroArg::Expr(ref expr) => Some(expr), - _ => None, - }, + OverflowableItem::MacroArg(MacroArg::Expr(ref expr)) => Some(expr), _ => None, } } @@ -178,10 +173,9 @@ impl<'a> OverflowableItem<'a> { ast::NestedMetaItem::MetaItem(..) => true, } } - OverflowableItem::SegmentParam(seg) => match seg { - SegmentParam::Type(ty) => can_be_overflowed_type(context, ty, len), - _ => false, - }, + OverflowableItem::SegmentParam(SegmentParam::Type(ty)) => { + can_be_overflowed_type(context, ty, len) + } OverflowableItem::TuplePatField(pat) => can_be_overflowed_pat(context, pat, len), OverflowableItem::Ty(ty) => can_be_overflowed_type(context, ty, len), _ => false, diff --git a/src/patterns.rs b/src/patterns.rs index fa0ef260991..062e9cef9bb 100644 --- a/src/patterns.rs +++ b/src/patterns.rs @@ -238,7 +238,7 @@ impl Rewrite for Pat { if let Some(rw) = p.rewrite(context, shape) { rw } else { - format!("{}", context.snippet(p.span)) + context.snippet(p.span).to_string() } }) .collect(); @@ -310,23 +310,22 @@ fn rewrite_struct_pat( if fields_str.contains('\n') || fields_str.len() > one_line_width { // Add a missing trailing comma. if context.config.trailing_comma() == SeparatorTactic::Never { - fields_str.push_str(","); + fields_str.push(','); } - fields_str.push_str("\n"); + fields_str.push('\n'); fields_str.push_str(&nested_shape.indent.to_string(context.config)); - fields_str.push_str(".."); } else { if !fields_str.is_empty() { // there are preceding struct fields being matched on if tactic == DefinitiveListTactic::Vertical { // if the tactic is Vertical, write_list already added a trailing , - fields_str.push_str(" "); + fields_str.push(' '); } else { fields_str.push_str(", "); } } - fields_str.push_str(".."); } + fields_str.push_str(".."); } // ast::Pat doesn't have attrs so use &[] @@ -411,10 +410,7 @@ impl<'a> Spanned for TuplePatField<'a> { impl<'a> TuplePatField<'a> { fn is_dotdot(&self) -> bool { match self { - TuplePatField::Pat(pat) => match pat.kind { - ast::PatKind::Rest => true, - _ => false, - }, + TuplePatField::Pat(pat) => matches!(pat.kind, ast::PatKind::Rest), TuplePatField::Dotdot(_) => true, } } @@ -510,10 +506,11 @@ fn count_wildcard_suffix_len( ) .collect(); - for item in items.iter().rev().take_while(|i| match i.item { - Some(ref internal_string) if internal_string == "_" => true, - _ => false, - }) { + for item in items + .iter() + .rev() + .take_while(|i| matches!(i.item, Some(ref internal_string) if internal_string == "_")) + { suffix_len += 1; if item.has_comment() { diff --git a/src/rustfmt_diff.rs b/src/rustfmt_diff.rs index fc2c7d06e26..a394ce07398 100644 --- a/src/rustfmt_diff.rs +++ b/src/rustfmt_diff.rs @@ -56,10 +56,7 @@ impl From> for ModifiedLines { let chunks = mismatches.into_iter().map(|mismatch| { let lines = mismatch.lines.iter(); let num_removed = lines - .filter(|line| match line { - DiffLine::Resulting(_) => true, - _ => false, - }) + .filter(|line| matches!(line, DiffLine::Resulting(_))) .count(); let new_lines = mismatch.lines.into_iter().filter_map(|line| match line { @@ -94,7 +91,7 @@ impl fmt::Display for ModifiedLines { "{} {} {}", chunk.line_number_orig, chunk.lines_removed, - chunk.lines.iter().count() + chunk.lines.len() )?; for line in &chunk.lines { diff --git a/src/skip.rs b/src/skip.rs index 6c500635a95..0fdc097efc2 100644 --- a/src/skip.rs +++ b/src/skip.rs @@ -32,8 +32,8 @@ impl SkipContext { } } -static RUSTFMT: &'static str = "rustfmt"; -static SKIP: &'static str = "skip"; +static RUSTFMT: &str = "rustfmt"; +static SKIP: &str = "skip"; /// Say if you're playing with `rustfmt`'s skip attribute pub(crate) fn is_skip_attr(segments: &[ast::PathSegment]) -> bool { @@ -46,7 +46,7 @@ pub(crate) fn is_skip_attr(segments: &[ast::PathSegment]) -> bool { segments[1].ident.to_string() == SKIP && ["macros", "attributes"] .iter() - .any(|&n| n == &pprust::path_segment_to_string(&segments[2])) + .any(|&n| n == pprust::path_segment_to_string(&segments[2])) } _ => false, } diff --git a/src/source_file.rs b/src/source_file.rs index 5a9a2cbd80c..853336004d8 100644 --- a/src/source_file.rs +++ b/src/source_file.rs @@ -18,7 +18,7 @@ use rustc_data_structures::sync::Lrc; // Append a newline to the end of each file. pub(crate) fn append_newline(s: &mut String) { - s.push_str("\n"); + s.push('\n'); } #[cfg(test)] diff --git a/src/string.rs b/src/string.rs index 080c4f17788..0cb9d817ca2 100644 --- a/src/string.rs +++ b/src/string.rs @@ -57,7 +57,7 @@ impl<'a> StringFormat<'a> { /// This allows to fit more graphemes from the string on a line when /// SnippetState::EndWithLineFeed. fn max_width_without_indent(&self) -> Option { - Some(self.config.max_width().checked_sub(self.line_end.len())?) + self.config.max_width().checked_sub(self.line_end.len()) } } @@ -99,7 +99,7 @@ pub(crate) fn rewrite_string<'a>( if is_new_line(grapheme) { // take care of blank lines result = trim_end_but_line_feed(fmt.trim_end, result); - result.push_str("\n"); + result.push('\n'); if !is_bareline_ok && cur_start + i + 1 < graphemes.len() { result.push_str(&indent_without_newline); result.push_str(fmt.line_start); diff --git a/src/syntux/parser.rs b/src/syntux/parser.rs index 0b94749f3c6..b5fe4335dd3 100644 --- a/src/syntux/parser.rs +++ b/src/syntux/parser.rs @@ -79,7 +79,7 @@ impl<'a> ParserBuilder<'a> { rustc_span::FileName::Custom("stdin".to_owned()), text, ) - .map_err(|db| Some(db)), + .map_err(Some), } } } @@ -196,8 +196,7 @@ impl<'a> Parser<'a> { mac: &'a ast::MacCall, ) -> Result, &'static str> { let token_stream = mac.args.inner_tokens(); - let mut parser = - rustc_parse::stream_to_parser(sess.inner(), token_stream.clone(), Some("")); + let mut parser = rustc_parse::stream_to_parser(sess.inner(), token_stream, Some("")); let mut items = vec![]; let mut process_if_cfg = true; diff --git a/src/types.rs b/src/types.rs index 974c0c5990c..c6f89c31065 100644 --- a/src/types.rs +++ b/src/types.rs @@ -662,7 +662,7 @@ impl Rewrite for ast::Ty { let mut_str = format_mutability(mt.mutbl); let mut_len = mut_str.len(); let mut result = String::with_capacity(128); - result.push_str("&"); + result.push('&'); let ref_hi = context.snippet_provider.span_after(self.span(), "&"); let mut cmnt_lo = ref_hi; @@ -685,7 +685,7 @@ impl Rewrite for ast::Ty { } else { result.push_str(<_str); } - result.push_str(" "); + result.push(' '); cmnt_lo = lifetime.ident.span.hi(); } @@ -1048,11 +1048,7 @@ fn join_bounds_inner( true, ) .map(|v| (v, trailing_span, extendable)), - _ => Some(( - String::from(strs) + &trailing_str, - trailing_span, - extendable, - )), + _ => Some((strs + &trailing_str, trailing_span, extendable)), } }, )?; @@ -1089,10 +1085,7 @@ fn rewrite_lifetime_param( ) -> Option { let result = generic_params .iter() - .filter(|p| match p.kind { - ast::GenericParamKind::Lifetime => true, - _ => false, - }) + .filter(|p| matches!(p.kind, ast::GenericParamKind::Lifetime)) .map(|lt| lt.rewrite(context, shape)) .collect::>>()? .join(", "); diff --git a/src/utils.rs b/src/utils.rs index 614cda5f911..06159a1b26e 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -191,7 +191,7 @@ pub(crate) fn outer_attributes(attrs: &[ast::Attribute]) -> Vec #[inline] pub(crate) fn is_single_line(s: &str) -> bool { - s.chars().find(|&c| c == '\n').is_none() + !s.chars().any(|c| c == '\n') } #[inline] @@ -260,8 +260,7 @@ fn is_skip(meta_item: &MetaItem) -> bool { match meta_item.kind { MetaItemKind::Word => { let path_str = pprust::path_to_string(&meta_item.path); - path_str == &*skip_annotation().as_str() - || path_str == &*depr_skip_annotation().as_str() + path_str == *skip_annotation().as_str() || path_str == *depr_skip_annotation().as_str() } MetaItemKind::List(ref l) => { meta_item.has_name(sym::cfg_attr) && l.len() == 2 && is_skip_nested(&l[1]) diff --git a/src/visitor.rs b/src/visitor.rs index 079568630cf..3f251bf7c16 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -198,7 +198,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { let missing_span = self.next_span(hi); let snippet = self.snippet(missing_span); let len = CommentCodeSlices::new(snippet) - .nth(0) + .next() .and_then(|(kind, _, s)| { if kind == CodeCharKind::Normal { s.rfind('\n') @@ -293,7 +293,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { } let span_in_between = mk_sp(last_hi, span.lo() + BytePos::from_usize(offset)); let snippet_in_between = self.snippet(span_in_between); - let mut comment_on_same_line = !snippet_in_between.contains("\n"); + let mut comment_on_same_line = !snippet_in_between.contains('\n'); let mut comment_shape = Shape::indented(self.block_indent, config).comment(config); @@ -301,7 +301,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { self.push_str(" "); // put the first line of the comment on the same line as the // block's last line - match sub_slice.find("\n") { + match sub_slice.find('\n') { None => { self.push_str(&sub_slice); } @@ -764,7 +764,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { let hi = self.snippet_provider.span_before(search_span, ";"); let target_span = mk_sp(mac.span().lo(), hi + BytePos(1)); let rewrite = rewrite.map(|rw| { - if !rw.ends_with(";") { + if !rw.ends_with(';') { format!("{};", rw) } else { rw @@ -921,7 +921,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { !is_skip_attr(segments) } - fn walk_mod_items(&mut self, items: &Vec>) { + fn walk_mod_items(&mut self, items: &[rustc_ast::ptr::P]) { self.visit_items_with_reordering(&ptr_vec_to_ref_vec(&items)); } @@ -953,10 +953,10 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { // break the Stability Guarantee // N.B. This could be updated to utilize the version gates. let include_next_empty = if stmts.len() > 1 { - match (&stmts[0].as_ast_node().kind, &stmts[1].as_ast_node().kind) { - (ast::StmtKind::Item(_), ast::StmtKind::Empty) => true, - _ => false, - } + matches!( + (&stmts[0].as_ast_node().kind, &stmts[1].as_ast_node().kind), + (ast::StmtKind::Item(_), ast::StmtKind::Empty) + ) } else { false }; -- cgit 1.4.1-3-g733a5 From d42be80bf772688089b90a7f2c8651adc366a3c4 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Sun, 18 Jul 2021 12:14:23 -0500 Subject: chore: disable clippy::matches_like_macro lint --- Cargo.lock | 24 +++++++++++++++--------- src/cargo-fmt/main.rs | 1 + src/lib.rs | 1 + 3 files changed, 17 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/Cargo.lock b/Cargo.lock index 0e12e81904c..03bb5598007 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -73,7 +73,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "924c76597f0d9ca25d762c25a4d369d51267536465dc5064bdf0eb073ed477ea" dependencies = [ "backtrace-sys", - "cfg-if", + "cfg-if 0.1.10", "libc", "rustc-demangle", ] @@ -162,6 +162,12 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + [[package]] name = "clap" version = "2.33.0" @@ -207,7 +213,7 @@ version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "lazy_static", ] @@ -218,7 +224,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce446db02cdc3165b94ae73111e570793400d0794e46125cc4056c81cbb039f4" dependencies = [ "autocfg", - "cfg-if", + "cfg-if 0.1.10", "lazy_static", ] @@ -245,7 +251,7 @@ version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "dirs-sys", ] @@ -255,7 +261,7 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "afa0b23de8fd801745c471deffa6e12d248f962c9fd4b4c33787b055599bde7b" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", "libc", "redox_users", "winapi", @@ -401,11 +407,11 @@ checksum = "f2f96b10ec2560088a8e76961b00d47107b3a625fecb76dedb29ee7ccbf98235" [[package]] name = "log" -version = "0.4.8" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", ] [[package]] @@ -426,7 +432,7 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a85ea9fc0d4ac0deb6fe7911d38786b32fc11119afd9e9d38b84ff691ce64220" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", ] [[package]] diff --git a/src/cargo-fmt/main.rs b/src/cargo-fmt/main.rs index ba693e852ff..90ffad927e2 100644 --- a/src/cargo-fmt/main.rs +++ b/src/cargo-fmt/main.rs @@ -1,6 +1,7 @@ // Inspired by Paul Woolcock's cargo-fmt (https://github.com/pwoolcoc/cargo-fmt/). #![deny(warnings)] +#![allow(clippy::match_like_matches_macro)] use std::cmp::Ordering; use std::collections::{BTreeMap, BTreeSet}; diff --git a/src/lib.rs b/src/lib.rs index eb314e63de3..206d2f78290 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,6 +2,7 @@ #![deny(rust_2018_idioms)] #![warn(unreachable_pub)] #![recursion_limit = "256"] +#![allow(clippy::match_like_matches_macro)] #[macro_use] extern crate derive_new; -- cgit 1.4.1-3-g733a5 From e7fa07036fa3e87f536fa3bedd3daad51dfeaf16 Mon Sep 17 00:00:00 2001 From: Outvi V <19144373+outloudvi@users.noreply.github.com> Date: Thu, 22 Jul 2021 21:24:07 +0800 Subject: fix: make --edition 2021 visible in --help --- src/bin/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/bin/main.rs b/src/bin/main.rs index 4b4aa42d935..1bcc5c0dada 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -121,7 +121,7 @@ fn make_opts() -> Options { found reverts to the input file path", "[Path for the configuration file]", ); - opts.optopt("", "edition", "Rust edition to use", "[2015|2018]"); + opts.optopt("", "edition", "Rust edition to use", "[2015|2018|2021]"); opts.optopt( "", "color", -- cgit 1.4.1-3-g733a5 From 0b21ea2161923a87f65932b6abb5e7a94003ec3a Mon Sep 17 00:00:00 2001 From: Ellen Date: Wed, 28 Apr 2021 20:44:40 +0100 Subject: Unyeet const param defaults --- src/types.rs | 12 +++++++++++- tests/source/issue-4816/lib.rs | 10 ++++++++++ tests/target/issue-4816/lib.rs | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 tests/source/issue-4816/lib.rs create mode 100644 tests/target/issue-4816/lib.rs (limited to 'src') diff --git a/src/types.rs b/src/types.rs index c6f89c31065..1d3f4669fcd 100644 --- a/src/types.rs +++ b/src/types.rs @@ -571,13 +571,23 @@ impl Rewrite for ast::GenericParam { if let ast::GenericParamKind::Const { ref ty, kw_span: _, - default: _, + default, } = &self.kind { result.push_str("const "); result.push_str(rewrite_ident(context, self.ident)); result.push_str(": "); result.push_str(&ty.rewrite(context, shape)?); + if let Some(default) = default { + let eq_str = match context.config.type_punctuation_density() { + TypeDensity::Compressed => "=", + TypeDensity::Wide => " = ", + }; + result.push_str(eq_str); + let budget = shape.width.checked_sub(result.len())?; + let rewrite = default.rewrite(context, Shape::legacy(budget, shape.indent))?; + result.push_str(&rewrite); + } } else { result.push_str(rewrite_ident(context, self.ident)); } diff --git a/tests/source/issue-4816/lib.rs b/tests/source/issue-4816/lib.rs new file mode 100644 index 00000000000..43d540c4a5d --- /dev/null +++ b/tests/source/issue-4816/lib.rs @@ -0,0 +1,10 @@ +#![feature(const_generics_defaults)] +struct Foo; +struct Bar; +struct Lots; +struct NamesRHard; +struct FooBar< + const LessThan100ButClose: usize = {1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1} +>; +struct FooBarrrrrrrr; diff --git a/tests/target/issue-4816/lib.rs b/tests/target/issue-4816/lib.rs new file mode 100644 index 00000000000..246e775e1fe --- /dev/null +++ b/tests/target/issue-4816/lib.rs @@ -0,0 +1,35 @@ +#![feature(const_generics_defaults)] +struct Foo; +struct Bar; +struct Lots< + const N1BlahFooUwU: usize = { 10 + 28 + 1872 / 10 * 3 }, + const N2SecondParamOhmyyy: usize = { N1BlahFooUwU / 2 + 10 * 2 }, +>; +struct NamesRHard; +struct FooBar< + const LessThan100ButClose: usize = { + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + }, +>; +struct FooBarrrrrrrr< + const N: usize = { + 13478234326456456444323871 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + + 1 + }, +>; -- cgit 1.4.1-3-g733a5 From 8c52aae10a099abf3f481a42bef60bc5db3aba47 Mon Sep 17 00:00:00 2001 From: klensy Date: Thu, 3 Jun 2021 05:28:20 +0300 Subject: Bump deps * dirs-sys v0.3.4 -> v0.3.6 to drop a lot of deps regex v1.3.1 -> v1.4.3 drops thread_local 0.3.6 bytecount v0.6.0 -> v0.6.2 replaces packed_simd with packed_simd_2 ignore v0.4.11 -> v0.4.17 drop crossbeam-channel v0.4.0 * itertools 8.0 -> 9.0 bump `ignore` version in Cargo.toml * cargo_metadata 0.8 -> 0.12 * env_logger 0.6 -> 0.8 --- Cargo.lock | 372 ++++++++++++++------------------------------------ Cargo.toml | 8 +- src/cargo-fmt/main.rs | 2 +- 3 files changed, 106 insertions(+), 276 deletions(-) (limited to 'src') diff --git a/Cargo.lock b/Cargo.lock index 03bb5598007..be134f3e975 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -35,21 +35,6 @@ version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9267dff192e68f3399525901e709a48c1d3982c9c072fa32f2127a0cb0babf14" -[[package]] -name = "arrayref" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee" - -[[package]] -name = "arrayvec" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" -dependencies = [ - "nodrop", -] - [[package]] name = "atty" version = "0.2.13" @@ -62,40 +47,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" - -[[package]] -name = "backtrace" -version = "0.3.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "924c76597f0d9ca25d762c25a4d369d51267536465dc5064bdf0eb073ed477ea" -dependencies = [ - "backtrace-sys", - "cfg-if 0.1.10", - "libc", - "rustc-demangle", -] - -[[package]] -name = "backtrace-sys" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d6575f128516de27e3ce99689419835fce9643a9b215a14d2b5b685be018491" -dependencies = [ - "cc", - "libc", -] - -[[package]] -name = "base64" -version = "0.10.1" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" -dependencies = [ - "byteorder", -] +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" [[package]] name = "bitflags" @@ -103,17 +57,6 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" -[[package]] -name = "blake2b_simd" -version = "0.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5850aeee1552f495dd0250014cf64b82b7c8879a89d83b33bbdace2cc4f63182" -dependencies = [ - "arrayref", - "arrayvec", - "constant_time_eq", -] - [[package]] name = "bstr" version = "0.2.8" @@ -125,37 +68,35 @@ dependencies = [ [[package]] name = "bytecount" -version = "0.6.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0017894339f586ccb943b01b9555de56770c11cda818e7e3d8bd93f4ed7f46e" +checksum = "72feb31ffc86498dacdbd0fcebb56138e7177a8cc5cea4516031d15ae85a742e" dependencies = [ - "packed_simd", + "packed_simd_2", ] [[package]] -name = "byteorder" -version = "1.3.2" +name = "cargo-platform" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" +checksum = "0226944a63d1bf35a3b5f948dd7c59e263db83695c9e8bffc4037de02e30f1d7" +dependencies = [ + "serde", +] [[package]] name = "cargo_metadata" -version = "0.8.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "700b3731fd7d357223d0000f4dbf1808401b694609035c3c411fbc0cd375c426" +checksum = "7714a157da7991e23d90686b9524b9e12e0407a108647f52e9328f4b3d51ac7f" dependencies = [ + "cargo-platform", "semver", + "semver-parser", "serde", - "serde_derive", "serde_json", ] -[[package]] -name = "cc" -version = "1.0.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0213d356d3c4ea2c18c40b037c3be23cd639825c18f25ee670ac7813beeef99c" - [[package]] name = "cfg-if" version = "0.1.10" @@ -183,48 +124,14 @@ dependencies = [ "vec_map", ] -[[package]] -name = "cloudabi" -version = "0.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -dependencies = [ - "bitflags", -] - -[[package]] -name = "constant_time_eq" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "995a44c877f9212528ccc74b21a232f66ad69001e40ede5bcee2ac9ef2657120" - -[[package]] -name = "crossbeam-channel" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acec9a3b0b3559f15aee4f90746c4e5e293b701c0f7d3925d24e01645267b68c" -dependencies = [ - "crossbeam-utils 0.7.0", -] - [[package]] name = "crossbeam-utils" -version = "0.6.6" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6" -dependencies = [ - "cfg-if 0.1.10", - "lazy_static", -] - -[[package]] -name = "crossbeam-utils" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce446db02cdc3165b94ae73111e570793400d0794e46125cc4056c81cbb039f4" +checksum = "e7e9d99fa91428effe99c5c6d4634cdeba32b8cf784fc428a2a687f61a952c49" dependencies = [ "autocfg", - "cfg-if 0.1.10", + "cfg-if 1.0.0", "lazy_static", ] @@ -257,11 +164,10 @@ dependencies = [ [[package]] name = "dirs-sys" -version = "0.3.4" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afa0b23de8fd801745c471deffa6e12d248f962c9fd4b4c33787b055599bde7b" +checksum = "03d86534ed367a67548dc68113a0f5db55432fdfbb6e6f9d77704397d95d5780" dependencies = [ - "cfg-if 0.1.10", "libc", "redox_users", "winapi", @@ -275,9 +181,9 @@ checksum = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" [[package]] name = "env_logger" -version = "0.6.2" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aafcde04e90a5226a6443b7aabdb016ba2f8307c847d524724bd9b346dd1a2d3" +checksum = "54532e3223c5af90a6a757c90b5c5521564b07e5e7a958681bcd2afad421cdcd" dependencies = [ "atty", "humantime", @@ -286,40 +192,12 @@ dependencies = [ "termcolor", ] -[[package]] -name = "failure" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8273f13c977665c5db7eb2b99ae520952fe5ac831ae4cd09d80c4c7042b5ed9" -dependencies = [ - "backtrace", - "failure_derive", -] - -[[package]] -name = "failure_derive" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - [[package]] name = "fnv" version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" -[[package]] -name = "fuchsia-cprng" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" - [[package]] name = "getopts" version = "0.2.21" @@ -329,11 +207,22 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "getrandom" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "wasi", +] + [[package]] name = "globset" -version = "0.4.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "925aa2cac82d8834e2b2a4415b6f6879757fb5c0928fc445ae76461a12eed8f2" +checksum = "c152169ef1e421390738366d2f796655fec62621dabbd0fd476f905934061e4a" dependencies = [ "aho-corasick", "bstr", @@ -353,36 +242,33 @@ dependencies = [ [[package]] name = "humantime" -version = "1.3.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" -dependencies = [ - "quick-error", -] +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "ignore" -version = "0.4.11" +version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "522daefc3b69036f80c7d2990b28ff9e0471c683bad05ca258e0a01dd22c5a1e" +checksum = "b287fb45c60bb826a0dc68ff08742b9d88a2fea13d6e0c286b3172065aaf878c" dependencies = [ - "crossbeam-channel", + "crossbeam-utils", "globset", "lazy_static", "log", "memchr", "regex", "same-file", - "thread_local 1.0.1", + "thread_local", "walkdir", "winapi-util", ] [[package]] name = "itertools" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358" +checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" dependencies = [ "either", ] @@ -405,6 +291,12 @@ version = "0.2.77" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2f96b10ec2560088a8e76961b00d47107b3a625fecb76dedb29ee7ccbf98235" +[[package]] +name = "libm" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a" + [[package]] name = "log" version = "0.4.14" @@ -421,18 +313,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" [[package]] -name = "nodrop" -version = "0.1.14" +name = "packed_simd_2" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" +checksum = "3278e0492f961fd4ae70909f56b2723a7e8d01a228427294e19cdfdebda89a17" +dependencies = [ + "cfg-if 0.1.10", + "libm", +] [[package]] -name = "packed_simd" -version = "0.3.3" +name = "pest" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a85ea9fc0d4ac0deb6fe7911d38786b32fc11119afd9e9d38b84ff691ce64220" +checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" dependencies = [ - "cfg-if 0.1.10", + "ucd-trie", ] [[package]] @@ -463,19 +359,13 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.6" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9e470a8dc4aeae2dee2f335e8f533e2d4b347e1434e5671afc49b054592f27" +checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec" dependencies = [ "unicode-xid", ] -[[package]] -name = "quick-error" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" - [[package]] name = "quote" version = "1.0.6" @@ -486,95 +376,41 @@ dependencies = [ ] [[package]] -name = "rand_core" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" -dependencies = [ - "rand_core 0.4.2", -] - -[[package]] -name = "rand_core" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" - -[[package]] -name = "rand_os" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" -dependencies = [ - "cloudabi", - "fuchsia-cprng", - "libc", - "rand_core 0.4.2", - "rdrand", - "winapi", -] - -[[package]] -name = "rdrand" -version = "0.4.0" +name = "redox_syscall" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +checksum = "05ec8ca9416c5ea37062b502703cd7fcb207736bc294f6e0cf367ac6fc234570" dependencies = [ - "rand_core 0.3.1", + "bitflags", ] -[[package]] -name = "redox_syscall" -version = "0.1.56" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" - [[package]] name = "redox_users" -version = "0.3.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ecedbca3bf205f8d8f5c2b44d83cd0690e39ee84b951ed649e9f1841132b66d" +checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" dependencies = [ - "failure", - "rand_os", + "getrandom", "redox_syscall", - "rust-argon2", ] [[package]] name = "regex" -version = "1.3.1" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc220bd33bdce8f093101afe22a037b8eb0e5af33592e6a9caafff0d4cb81cbd" +checksum = "d9251239e129e16308e70d853559389de218ac275b515068abc96829d05b948a" dependencies = [ "aho-corasick", "memchr", "regex-syntax", - "thread_local 0.3.6", + "thread_local", ] [[package]] name = "regex-syntax" -version = "0.6.12" +version = "0.6.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716" - -[[package]] -name = "rust-argon2" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ca4eaef519b494d1f2848fc602d18816fed808a981aedf4f1f00ceb7c9d32cf" -dependencies = [ - "base64", - "blake2b_simd", - "crossbeam-utils 0.6.6", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" +checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581" [[package]] name = "rustc-workspace-hack" @@ -639,9 +475,9 @@ dependencies = [ [[package]] name = "semver" -version = "0.9.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" dependencies = [ "semver-parser", "serde", @@ -649,24 +485,27 @@ dependencies = [ [[package]] name = "semver-parser" -version = "0.7.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" +checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" +dependencies = [ + "pest", +] [[package]] name = "serde" -version = "1.0.101" +version = "1.0.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9796c9b7ba2ffe7a9ce53c2287dfc48080f4b2b362fcc245a259b3a7201119dd" +checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.101" +version = "1.0.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b133a43a1ecd55d4086bd5b4dc6c1751c68b1bfbeba7a5040442022c7e7c02e" +checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43" dependencies = [ "proc-macro2", "quote", @@ -675,9 +514,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.41" +version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f72eb2a68a7dc3f9a691bfda9305a1c017a6215e5a4545c258500d2099a37c2" +checksum = "dcac07dbffa1c65e7f816ab9eba78eb142c6d44410f4eeba1e26e4f5dfa56b95" dependencies = [ "itoa", "ryu", @@ -716,9 +555,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.11" +version = "1.0.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff0acdb207ae2fe6d5976617f887eb1e35a2ba52c13c7234c790960cdad9238" +checksum = "f3a1d708c221c5a612956ef9f75b37e454e88d1f7b899fbd3a18d4252012d663" dependencies = [ "proc-macro2", "quote", @@ -736,18 +575,6 @@ dependencies = [ "syn", ] -[[package]] -name = "synstructure" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f085a5855930c0441ca1288cf044ea4aecf4f43a91668abdb870b4ba546a203" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "unicode-xid", -] - [[package]] name = "term" version = "0.6.1" @@ -796,15 +623,6 @@ dependencies = [ "syn", ] -[[package]] -name = "thread_local" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" -dependencies = [ - "lazy_static", -] - [[package]] name = "thread_local" version = "1.0.1" @@ -823,6 +641,12 @@ dependencies = [ "serde", ] +[[package]] +name = "ucd-trie" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" + [[package]] name = "unicode-segmentation" version = "1.3.0" @@ -870,6 +694,12 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + [[package]] name = "winapi" version = "0.3.8" diff --git a/Cargo.toml b/Cargo.toml index 3a04fb28f7c..e368f3eb1ec 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,7 +34,7 @@ rustfmt-format-diff = [] generic-simd = ["bytecount/generic-simd"] [dependencies] -itertools = "0.8" +itertools = "0.9" toml = "0.5" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" @@ -43,15 +43,15 @@ regex = "1.0" term = "0.6" diff = "0.1" log = "0.4.14" -env_logger = "0.6" +env_logger = "0.8" getopts = "0.2" derive-new = "0.5" -cargo_metadata = "0.8" +cargo_metadata = "0.12" bytecount = "0.6" unicode-width = "0.1.5" unicode_categories = "0.1.1" dirs = "2.0.1" -ignore = "0.4.11" +ignore = "0.4.17" annotate-snippets = { version = "0.8", features = ["color"] } structopt = "0.3" rustfmt-config_proc_macro = { version = "0.2", path = "config_proc_macro" } diff --git a/src/cargo-fmt/main.rs b/src/cargo-fmt/main.rs index 90ffad927e2..f8cf698525b 100644 --- a/src/cargo-fmt/main.rs +++ b/src/cargo-fmt/main.rs @@ -528,7 +528,7 @@ fn get_cargo_metadata( if let Some(manifest_path) = manifest_path { cmd.manifest_path(manifest_path); } - cmd.other_options(&[String::from("--offline")]); + cmd.other_options(vec![String::from("--offline")]); match cmd.exec() { Ok(metadata) => Ok(metadata), -- cgit 1.4.1-3-g733a5 From fefb5427a2fb28459f91a776948fca0ab0f2d11c Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Fri, 6 Aug 2021 21:26:27 -0500 Subject: fix: handle GAT types in impls with self bounds --- src/items.rs | 82 +++++++++++++++------------------------------- src/visitor.rs | 49 ++++++++++----------------- tests/source/issue_4911.rs | 6 ++++ tests/target/issue_4911.rs | 9 +++++ 4 files changed, 59 insertions(+), 87 deletions(-) create mode 100644 tests/source/issue_4911.rs create mode 100644 tests/target/issue_4911.rs (limited to 'src') diff --git a/src/items.rs b/src/items.rs index 0542358c6e7..1a56acc7de1 100644 --- a/src/items.rs +++ b/src/items.rs @@ -1497,7 +1497,7 @@ fn format_tuple_struct( Some(result) } -fn rewrite_type( +pub(crate) fn rewrite_type( context: &RewriteContext<'_>, indent: Indent, ident: symbol::Ident, @@ -1841,29 +1841,6 @@ fn rewrite_static( Some(format!("{}{};", prefix, ty_str)) } } - -pub(crate) fn rewrite_type_alias( - ident: symbol::Ident, - ty_opt: Option<&ptr::P>, - generics: &ast::Generics, - generic_bounds_opt: Option<&ast::GenericBounds>, - context: &RewriteContext<'_>, - indent: Indent, - vis: &ast::Visibility, - span: Span, -) -> Option { - rewrite_type( - context, - indent, - ident, - vis, - generics, - generic_bounds_opt, - ty_opt, - span, - ) -} - struct OpaqueType<'a> { bounds: &'a ast::GenericBounds, } @@ -1877,32 +1854,7 @@ impl<'a> Rewrite for OpaqueType<'a> { } } -pub(crate) fn rewrite_opaque_impl_type( - context: &RewriteContext<'_>, - ident: symbol::Ident, - generics: &ast::Generics, - generic_bounds: &ast::GenericBounds, - indent: Indent, -) -> Option { - let ident_str = rewrite_ident(context, ident); - // 5 = "type " - let generics_shape = Shape::indented(indent, context.config).offset_left(5)?; - let generics_str = rewrite_generics(context, ident_str, generics, generics_shape)?; - let prefix = format!("type {} =", generics_str); - let rhs = OpaqueType { - bounds: generic_bounds, - }; - - rewrite_assign_rhs( - context, - &prefix, - &rhs, - Shape::indented(indent, context.config).sub_width(1)?, - ) - .map(|s| s + ";") -} - -pub(crate) fn rewrite_associated_impl_type( +pub(crate) fn rewrite_impl_type( ident: symbol::Ident, vis: &ast::Visibility, defaultness: ast::Defaultness, @@ -1912,7 +1864,25 @@ pub(crate) fn rewrite_associated_impl_type( indent: Indent, span: Span, ) -> Option { - let result = rewrite_type_alias(ident, ty_opt, generics, None, context, indent, vis, span)?; + // Opaque type + let result = if let Some(rustc_ast::ast::Ty { + kind: ast::TyKind::ImplTrait(_, ref bounds), + .. + }) = ty_opt.map(|t| &**t) + { + rewrite_type( + context, + indent, + ident, + &DEFAULT_VISIBILITY, + generics, + None, + Some(&OpaqueType { bounds }), + span, + ) + } else { + rewrite_type(context, indent, ident, vis, generics, None, ty_opt, span) + }?; match defaultness { ast::Defaultness::Default(..) => Some(format!("default {}", result)), @@ -3164,14 +3134,14 @@ impl Rewrite for ast::ForeignItem { ast::ForeignItemKind::TyAlias(ref ty_alias_kind) => { let ast::TyAliasKind(_, ref generics, ref generic_bounds, ref type_default) = **ty_alias_kind; - rewrite_type_alias( - self.ident, - type_default.as_ref(), - generics, - Some(generic_bounds), + rewrite_type( &context, shape.indent, + self.ident, &self.vis, + generics, + Some(generic_bounds), + type_default.as_ref(), self.span, ) } diff --git a/src/visitor.rs b/src/visitor.rs index 3f251bf7c16..12a3281eda5 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -11,9 +11,9 @@ use crate::config::Version; use crate::config::{BraceStyle, Config}; use crate::coverage::transform_missing_snippet; use crate::items::{ - format_impl, format_trait, format_trait_alias, is_mod_decl, is_use_item, - rewrite_associated_impl_type, rewrite_extern_crate, rewrite_opaque_impl_type, - rewrite_opaque_type, rewrite_type_alias, FnBraceStyle, FnSig, StaticParts, StructParts, + format_impl, format_trait, format_trait_alias, is_mod_decl, is_use_item, rewrite_extern_crate, + rewrite_impl_type, rewrite_opaque_type, rewrite_type, FnBraceStyle, FnSig, StaticParts, + StructParts, }; use crate::macros::{macro_style, rewrite_macro, rewrite_macro_def, MacroPosition}; use crate::modules::Module; @@ -579,14 +579,14 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { **alias_kind; match ty { Some(ty) => { - let rewrite = rewrite_type_alias( - item.ident, - Some(&*ty), - generics, - Some(generic_bounds), + let rewrite = rewrite_type( &self.get_context(), self.block_indent, + item.ident, &item.vis, + generics, + Some(generic_bounds), + Some(&*ty), item.span, ); self.push_rewrite(item.span, rewrite); @@ -665,14 +665,14 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { ast::AssocItemKind::TyAlias(ref ty_alias_kind) => { let ast::TyAliasKind(_, ref generics, ref generic_bounds, ref type_default) = **ty_alias_kind; - let rewrite = rewrite_type_alias( - ti.ident, - type_default.as_ref(), - generics, - Some(generic_bounds), + let rewrite = rewrite_type( &self.get_context(), self.block_indent, + ti.ident, &ti.vis, + generics, + Some(generic_bounds), + type_default.as_ref(), ti.span, ); self.push_rewrite(ti.span, rewrite); @@ -715,8 +715,9 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { ast::AssocItemKind::Const(..) => self.visit_static(&StaticParts::from_impl_item(ii)), ast::AssocItemKind::TyAlias(ref ty_alias_kind) => { let ast::TyAliasKind(defaultness, ref generics, _, ref ty) = **ty_alias_kind; - let rewrite_associated = || { - rewrite_associated_impl_type( + self.push_rewrite( + ii.span, + rewrite_impl_type( ii.ident, &ii.vis, defaultness, @@ -725,22 +726,8 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { &self.get_context(), self.block_indent, ii.span, - ) - }; - let rewrite = match ty { - None => rewrite_associated(), - Some(ty) => match ty.kind { - ast::TyKind::ImplTrait(_, ref bounds) => rewrite_opaque_impl_type( - &self.get_context(), - ii.ident, - generics, - bounds, - self.block_indent, - ), - _ => rewrite_associated(), - }, - }; - self.push_rewrite(ii.span, rewrite); + ), + ); } ast::AssocItemKind::MacCall(ref mac) => { self.visit_mac(mac, Some(ii.ident), MacroPosition::Item); diff --git a/tests/source/issue_4911.rs b/tests/source/issue_4911.rs new file mode 100644 index 00000000000..21ef6c6c491 --- /dev/null +++ b/tests/source/issue_4911.rs @@ -0,0 +1,6 @@ +#![feature(generic_associated_types)] +#![feature(min_type_alias_impl_trait)] + +impl SomeTrait for SomeType { + type SomeGAT<'a> where Self: 'a = impl SomeOtherTrait; +} \ No newline at end of file diff --git a/tests/target/issue_4911.rs b/tests/target/issue_4911.rs new file mode 100644 index 00000000000..890a62267ce --- /dev/null +++ b/tests/target/issue_4911.rs @@ -0,0 +1,9 @@ +#![feature(generic_associated_types)] +#![feature(min_type_alias_impl_trait)] + +impl SomeTrait for SomeType { + type SomeGAT<'a> + where + Self: 'a, + = impl SomeOtherTrait; +} -- cgit 1.4.1-3-g733a5 From 5d8eb8d79ce01571e468df9a0dfad8b2730bdf58 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Sat, 7 Aug 2021 20:24:14 -0500 Subject: fix: don't drop drop generic args on assoc ty constraints --- src/types.rs | 123 ++++++++++++++++++++++++--------------------- tests/target/issue_4943.rs | 8 +++ 2 files changed, 75 insertions(+), 56 deletions(-) create mode 100644 tests/target/issue_4943.rs (limited to 'src') diff --git a/src/types.rs b/src/types.rs index 1d3f4669fcd..9a0d31e51df 100644 --- a/src/types.rs +++ b/src/types.rs @@ -174,31 +174,38 @@ impl<'a> Rewrite for SegmentParam<'a> { SegmentParam::Const(const_) => const_.rewrite(context, shape), SegmentParam::LifeTime(lt) => lt.rewrite(context, shape), SegmentParam::Type(ty) => ty.rewrite(context, shape), - SegmentParam::Binding(assoc_ty_constraint) => { - let mut result = match assoc_ty_constraint.kind { - ast::AssocTyConstraintKind::Bound { .. } => { - format!("{}: ", rewrite_ident(context, assoc_ty_constraint.ident)) - } - ast::AssocTyConstraintKind::Equality { .. } => { - match context.config.type_punctuation_density() { - TypeDensity::Wide => { - format!("{} = ", rewrite_ident(context, assoc_ty_constraint.ident)) - } - TypeDensity::Compressed => { - format!("{}=", rewrite_ident(context, assoc_ty_constraint.ident)) - } - } - } - }; + SegmentParam::Binding(atc) => atc.rewrite(context, shape), + } + } +} - let budget = shape.width.checked_sub(result.len())?; - let rewrite = assoc_ty_constraint - .kind - .rewrite(context, Shape::legacy(budget, shape.indent + result.len()))?; - result.push_str(&rewrite); - Some(result) - } +impl Rewrite for ast::AssocTyConstraint { + fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option { + use ast::AssocTyConstraintKind::{Bound, Equality}; + + let mut result = String::with_capacity(128); + result.push_str(rewrite_ident(context, self.ident)); + + if let Some(ref gen_args) = self.gen_args { + let budget = shape.width.checked_sub(result.len())?; + let shape = Shape::legacy(budget, shape.indent + result.len()); + let gen_str = rewrite_generic_args(gen_args, context, shape, gen_args.span())?; + result.push_str(&gen_str); } + + let infix = match (&self.kind, context.config.type_punctuation_density()) { + (Bound { .. }, _) => ": ", + (Equality { .. }, TypeDensity::Wide) => " = ", + (Equality { .. }, TypeDensity::Compressed) => "=", + }; + result.push_str(infix); + + let budget = shape.width.checked_sub(result.len())?; + let shape = Shape::legacy(budget, shape.indent + result.len()); + let rewrite = self.kind.rewrite(context, shape)?; + result.push_str(&rewrite); + + Some(result) } } @@ -240,21 +247,9 @@ fn rewrite_segment( }; if let Some(ref args) = segment.args { + let generics_str = rewrite_generic_args(args, context, shape, mk_sp(*span_lo, span_hi))?; match **args { ast::GenericArgs::AngleBracketed(ref data) if !data.args.is_empty() => { - let param_list = data - .args - .iter() - .map(|x| match x { - ast::AngleBracketedArg::Arg(generic_arg) => { - SegmentParam::from_generic_arg(generic_arg) - } - ast::AngleBracketedArg::Constraint(constraint) => { - SegmentParam::Binding(constraint) - } - }) - .collect::>(); - // HACK: squeeze out the span between the identifier and the parameters. // The hack is requried so that we don't remove the separator inside macro calls. // This does not work in the presence of comment, hoping that people are @@ -270,33 +265,14 @@ fn rewrite_segment( }; result.push_str(separator); - let generics_str = overflow::rewrite_with_angle_brackets( - context, - "", - param_list.iter(), - shape, - mk_sp(*span_lo, span_hi), - )?; - // Update position of last bracket. *span_lo = context .snippet_provider .span_after(mk_sp(*span_lo, span_hi), "<"); - - result.push_str(&generics_str) - } - ast::GenericArgs::Parenthesized(ref data) => { - result.push_str(&format_function_type( - data.inputs.iter().map(|x| &**x), - &data.output, - false, - data.span, - context, - shape, - )?); } _ => (), } + result.push_str(&generics_str) } Some(result) @@ -489,6 +465,41 @@ impl Rewrite for ast::GenericArg { } } +fn rewrite_generic_args( + gen_args: &ast::GenericArgs, + context: &RewriteContext<'_>, + shape: Shape, + span: Span, +) -> Option { + match gen_args { + ast::GenericArgs::AngleBracketed(ref data) if !data.args.is_empty() => { + let args = data + .args + .iter() + .map(|x| match x { + ast::AngleBracketedArg::Arg(generic_arg) => { + SegmentParam::from_generic_arg(generic_arg) + } + ast::AngleBracketedArg::Constraint(constraint) => { + SegmentParam::Binding(constraint) + } + }) + .collect::>(); + + overflow::rewrite_with_angle_brackets(context, "", args.iter(), shape, span) + } + ast::GenericArgs::Parenthesized(ref data) => format_function_type( + data.inputs.iter().map(|x| &**x), + &data.output, + false, + data.span, + context, + shape, + ), + _ => Some("".to_owned()), + } +} + fn rewrite_bounded_lifetime( lt: &ast::Lifetime, bounds: &[ast::GenericBound], diff --git a/tests/target/issue_4943.rs b/tests/target/issue_4943.rs new file mode 100644 index 00000000000..bc8f1a366da --- /dev/null +++ b/tests/target/issue_4943.rs @@ -0,0 +1,8 @@ +impl SomeStruct { + fn process(v: T) -> ::R + where + Self: GAT = T>, + { + SomeStruct::do_something(v) + } +} -- cgit 1.4.1-3-g733a5 From fd6b025e8a5ab0bf0356030cab98575dca397f69 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 20 Aug 2021 13:41:27 -0700 Subject: Preserve visibility on trait items inside trait and impl --- src/items.rs | 15 ++++++++------- src/visitor.rs | 14 +++++--------- tests/target/impls.rs | 2 +- tests/target/trait.rs | 6 +++--- 4 files changed, 17 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/items.rs b/src/items.rs index 1a56acc7de1..4fa7190c138 100644 --- a/src/items.rs +++ b/src/items.rs @@ -168,14 +168,14 @@ pub(crate) struct FnSig<'a> { constness: ast::Const, defaultness: ast::Defaultness, unsafety: ast::Unsafe, - visibility: ast::Visibility, + visibility: &'a ast::Visibility, } impl<'a> FnSig<'a> { pub(crate) fn from_method_sig( method_sig: &'a ast::FnSig, generics: &'a ast::Generics, - visibility: ast::Visibility, + visibility: &'a ast::Visibility, ) -> FnSig<'a> { FnSig { unsafety: method_sig.header.unsafety, @@ -198,7 +198,7 @@ impl<'a> FnSig<'a> { match *fn_kind { visit::FnKind::Fn(fn_ctxt, _, fn_sig, vis, _) => match fn_ctxt { visit::FnCtxt::Assoc(..) => { - let mut fn_sig = FnSig::from_method_sig(fn_sig, generics, vis.clone()); + let mut fn_sig = FnSig::from_method_sig(fn_sig, generics, vis); fn_sig.defaultness = defaultness; fn_sig } @@ -210,7 +210,7 @@ impl<'a> FnSig<'a> { is_async: Cow::Borrowed(&fn_sig.header.asyncness), defaultness, unsafety: fn_sig.header.unsafety, - visibility: vis.clone(), + visibility: vis, }, }, _ => unreachable!(), @@ -317,6 +317,7 @@ impl<'a> FmtVisitor<'a> { indent: Indent, ident: symbol::Ident, sig: &ast::FnSig, + vis: &ast::Visibility, generics: &ast::Generics, span: Span, ) -> Option { @@ -328,7 +329,7 @@ impl<'a> FmtVisitor<'a> { &context, indent, ident, - &FnSig::from_method_sig(sig, generics, DEFAULT_VISIBILITY), + &FnSig::from_method_sig(sig, generics, vis), span, FnBraceStyle::None, )?; @@ -1754,7 +1755,7 @@ impl<'a> StaticParts<'a> { }; StaticParts { prefix: "const", - vis: &DEFAULT_VISIBILITY, + vis: &ti.vis, ident: ti.ident, ty, mutability: ast::Mutability::Not, @@ -3110,7 +3111,7 @@ impl Rewrite for ast::ForeignItem { context, shape.indent, self.ident, - &FnSig::from_method_sig(&fn_sig, generics, self.vis.clone()), + &FnSig::from_method_sig(&fn_sig, generics, &self.vis), span, FnBraceStyle::None, ) diff --git a/src/visitor.rs b/src/visitor.rs index 12a3281eda5..c67ebe793fd 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -3,7 +3,7 @@ use std::rc::Rc; use rustc_ast::{ast, token::DelimToken, visit, AstLike}; use rustc_data_structures::sync::Lrc; -use rustc_span::{symbol, BytePos, Pos, Span, DUMMY_SP}; +use rustc_span::{symbol, BytePos, Pos, Span}; use crate::attr::*; use crate::comment::{contains_comment, rewrite_comment, CodeCharKind, CommentCodeSlices}; @@ -568,6 +568,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { indent, item.ident, &fn_signature, + &item.vis, generics, item.span, ); @@ -641,14 +642,9 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { let ast::FnKind(defaultness, ref sig, ref generics, ref block) = **fn_kind; if let Some(ref body) = block { let inner_attrs = inner_attributes(&ti.attrs); - let vis = ast::Visibility { - kind: ast::VisibilityKind::Inherited, - span: DUMMY_SP, - tokens: None, - }; let fn_ctxt = visit::FnCtxt::Assoc(visit::AssocCtxt::Trait); self.visit_fn( - visit::FnKind::Fn(fn_ctxt, ti.ident, sig, &vis, Some(body)), + visit::FnKind::Fn(fn_ctxt, ti.ident, sig, &ti.vis, Some(body)), generics, &sig.decl, ti.span, @@ -658,7 +654,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { } else { let indent = self.block_indent; let rewrite = - self.rewrite_required_fn(indent, ti.ident, sig, generics, ti.span); + self.rewrite_required_fn(indent, ti.ident, sig, &ti.vis, generics, ti.span); self.push_rewrite(ti.span, rewrite); } } @@ -708,7 +704,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { } else { let indent = self.block_indent; let rewrite = - self.rewrite_required_fn(indent, ii.ident, sig, generics, ii.span); + self.rewrite_required_fn(indent, ii.ident, sig, &ii.vis, generics, ii.span); self.push_rewrite(ii.span, rewrite); } } diff --git a/tests/target/impls.rs b/tests/target/impls.rs index f5eebe3b394..99e02990e41 100644 --- a/tests/target/impls.rs +++ b/tests/target/impls.rs @@ -25,7 +25,7 @@ pub impl Foo for Bar { impl Visible for Bar { pub const C: i32; pub type T; - fn f(); + pub fn f(); pub fn g() {} } diff --git a/tests/target/trait.rs b/tests/target/trait.rs index 0313d8d9b84..7f067991b26 100644 --- a/tests/target/trait.rs +++ b/tests/target/trait.rs @@ -213,8 +213,8 @@ where + EEEEEEE; trait Visible { - const C: i32; + pub const C: i32; pub type T; - fn f(); - fn g() {} + pub fn f(); + pub fn g() {} } -- cgit 1.4.1-3-g733a5 From e81c393663daab11238944cddfbd97541630f178 Mon Sep 17 00:00:00 2001 From: Ashvin Arsakularatne Date: Thu, 26 Aug 2021 00:21:29 +0530 Subject: fix: remove wrong reformatting of qualified paths in struct patterns --- src/patterns.rs | 7 ++++--- tests/target/issue-4908-2.rs | 20 ++++++++++++++++++++ tests/target/issue-4908.rs | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 tests/target/issue-4908-2.rs create mode 100644 tests/target/issue-4908.rs (limited to 'src') diff --git a/src/patterns.rs b/src/patterns.rs index 062e9cef9bb..0c6a6f3e814 100644 --- a/src/patterns.rs +++ b/src/patterns.rs @@ -244,8 +244,8 @@ impl Rewrite for Pat { .collect(); Some(format!("[{}]", rw.join(", "))) } - PatKind::Struct(_, ref path, ref fields, ellipsis) => { - rewrite_struct_pat(path, fields, ellipsis, self.span, context, shape) + PatKind::Struct(ref qself, ref path, ref fields, ellipsis) => { + rewrite_struct_pat(qself, path, fields, ellipsis, self.span, context, shape) } PatKind::MacCall(ref mac) => { rewrite_macro(mac, None, context, shape, MacroPosition::Pat) @@ -258,6 +258,7 @@ impl Rewrite for Pat { } fn rewrite_struct_pat( + qself: &Option, path: &ast::Path, fields: &[ast::PatField], ellipsis: bool, @@ -267,7 +268,7 @@ fn rewrite_struct_pat( ) -> Option { // 2 = ` {` let path_shape = shape.sub_width(2)?; - let path_str = rewrite_path(context, PathContext::Expr, None, path, path_shape)?; + let path_str = rewrite_path(context, PathContext::Expr, qself.as_ref(), path, path_shape)?; if fields.is_empty() && !ellipsis { return Some(format!("{} {{}}", path_str)); diff --git a/tests/target/issue-4908-2.rs b/tests/target/issue-4908-2.rs new file mode 100644 index 00000000000..023b323cb27 --- /dev/null +++ b/tests/target/issue-4908-2.rs @@ -0,0 +1,20 @@ +#![feature(more_qualified_paths)] + +fn main() { + // destructure through a qualified path + let ::Assoc { br } = StructStruct { br: 2 }; +} + +struct StructStruct { + br: i8, +} + +struct Foo; + +trait A { + type Assoc; +} + +impl A for Foo { + type Assoc = StructStruct; +} diff --git a/tests/target/issue-4908.rs b/tests/target/issue-4908.rs new file mode 100644 index 00000000000..ac5357abe2a --- /dev/null +++ b/tests/target/issue-4908.rs @@ -0,0 +1,34 @@ +#![feature(more_qualified_paths)] + +mod foo_bar { + pub enum Example { + Example1 {}, + Example2 {}, + } +} + +fn main() { + foo!(crate::foo_bar::Example, Example1); + + let i1 = foo_bar::Example::Example1 {}; + + assert_eq!(i1.foo_example(), 1); + + let i2 = foo_bar::Example::Example2 {}; + + assert_eq!(i2.foo_example(), 2); +} + +#[macro_export] +macro_rules! foo { + ($struct:path, $variant:ident) => { + impl $struct { + pub fn foo_example(&self) -> i32 { + match self { + <$struct>::$variant { .. } => 1, + _ => 2, + } + } + } + }; +} -- cgit 1.4.1-3-g733a5 From ca9b050bbf786fc7f6ef56d82b1751a761efec44 Mon Sep 17 00:00:00 2001 From: Yusuke Tanaka Date: Sat, 30 Jan 2021 14:50:28 +0900 Subject: Implement `One` option for imports_granularity (#4669) This option merges all imports into a single `use` statement as long as they have the same visibility. --- Configurations.md | 19 ++++- src/config/options.rs | 2 + src/imports.rs | 146 ++++++++++++++++++++++++++++---- src/reorder.rs | 1 + tests/source/imports_granularity_one.rs | 60 +++++++++++++ tests/target/imports_granularity_one.rs | 79 +++++++++++++++++ 6 files changed, 288 insertions(+), 19 deletions(-) create mode 100644 tests/source/imports_granularity_one.rs create mode 100644 tests/target/imports_granularity_one.rs (limited to 'src') diff --git a/Configurations.md b/Configurations.md index d2e5613eba9..469deccc56e 100644 --- a/Configurations.md +++ b/Configurations.md @@ -1679,7 +1679,7 @@ pub enum Foo {} How imports should be grouped into `use` statements. Imports will be merged or split to the configured level of granularity. - **Default value**: `Preserve` -- **Possible values**: `Preserve`, `Crate`, `Module`, `Item` +- **Possible values**: `Preserve`, `Crate`, `Module`, `Item`, `One` - **Stable**: No #### `Preserve` (default): @@ -1733,6 +1733,23 @@ use qux::h; use qux::i; ``` +#### `One`: + +Merge all imports into a single `use` statement as long as they have the same visibility. + +```rust +pub use foo::{x, y}; +use { + bar::{ + a, + b::{self, f, g}, + c, + d::e, + }, + qux::{h, i}, +}; +``` + ## `merge_imports` This option is deprecated. Use `imports_granularity = "Crate"` instead. diff --git a/src/config/options.rs b/src/config/options.rs index 3b91021813c..db15ee97a40 100644 --- a/src/config/options.rs +++ b/src/config/options.rs @@ -125,6 +125,8 @@ pub enum ImportGranularity { Module, /// Use one `use` statement per imported item. Item, + /// Use one `use` statement including all items. + One, } #[config_type] diff --git a/src/imports.rs b/src/imports.rs index 64d78605f0c..5ac79936689 100644 --- a/src/imports.rs +++ b/src/imports.rs @@ -138,6 +138,29 @@ impl UseSegment { } } + // Check if self == other with their aliases removed. + fn equal_except_alias(&self, other: &Self) -> bool { + match (self, other) { + (UseSegment::Ident(ref s1, _), UseSegment::Ident(ref s2, _)) => s1 == s2, + (UseSegment::Slf(_), UseSegment::Slf(_)) + | (UseSegment::Super(_), UseSegment::Super(_)) + | (UseSegment::Crate(_), UseSegment::Crate(_)) + | (UseSegment::Glob, UseSegment::Glob) => true, + (UseSegment::List(ref list1), UseSegment::List(ref list2)) => list1 == list2, + _ => false, + } + } + + fn get_alias(&self) -> Option<&str> { + match self { + UseSegment::Ident(_, a) + | UseSegment::Slf(a) + | UseSegment::Super(a) + | UseSegment::Crate(a) => a.as_deref(), + _ => None, + } + } + fn from_path_segment( context: &RewriteContext<'_>, path_seg: &ast::PathSegment, @@ -558,6 +581,7 @@ impl UseTree { SharedPrefix::Module => { self.path[..self.path.len() - 1] == other.path[..other.path.len() - 1] } + SharedPrefix::One => true, } } } @@ -598,7 +622,7 @@ 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 == *b { + if a.equal_except_alias(b) { prefix += 1; } else { break; @@ -633,14 +657,20 @@ fn merge_rest( return Some(new_path); } } else if len == 1 { - let rest = if a.len() == len { &b[1..] } else { &a[1..] }; - return Some(vec![ - b[0].clone(), - UseSegment::List(vec![ - UseTree::from_path(vec![UseSegment::Slf(None)], DUMMY_SP), - UseTree::from_path(rest.to_vec(), DUMMY_SP), - ]), - ]); + let (common, rest) = if a.len() == len { + (&a[0], &b[1..]) + } else { + (&b[0], &a[1..]) + }; + let mut list = vec![UseTree::from_path( + vec![UseSegment::Slf(common.get_alias().map(ToString::to_string))], + DUMMY_SP, + )]; + match rest { + [UseSegment::List(rest_list)] => list.extend(rest_list.clone()), + _ => list.push(UseTree::from_path(rest.to_vec(), DUMMY_SP)), + } + return Some(vec![b[0].clone(), UseSegment::List(list)]); } else { len -= 1; } @@ -655,18 +685,54 @@ fn merge_rest( } fn merge_use_trees_inner(trees: &mut Vec, use_tree: UseTree, merge_by: SharedPrefix) { - let similar_trees = trees - .iter_mut() - .filter(|tree| tree.share_prefix(&use_tree, merge_by)); + struct SimilarTree<'a> { + similarity: usize, + path_len: usize, + tree: &'a mut UseTree, + } + + let similar_trees = trees.iter_mut().filter_map(|tree| { + if tree.share_prefix(&use_tree, merge_by) { + // In the case of `SharedPrefix::One`, `similarity` is used for deciding with which + // tree `use_tree` should be merge. + // In other cases `similarity` won't be used, so set it to `0` as a dummy value. + let similarity = if merge_by == SharedPrefix::One { + tree.path + .iter() + .zip(&use_tree.path) + .take_while(|(a, b)| a.equal_except_alias(b)) + .count() + } else { + 0 + }; + + let path_len = tree.path.len(); + Some(SimilarTree { + similarity, + tree, + path_len, + }) + } else { + None + } + }); + if use_tree.path.len() == 1 && merge_by == SharedPrefix::Crate { - if let Some(tree) = similar_trees.min_by_key(|tree| tree.path.len()) { - if tree.path.len() == 1 { + if let Some(tree) = similar_trees.min_by_key(|tree| tree.path_len) { + if tree.path_len == 1 { + return; + } + } + } else if merge_by == SharedPrefix::One { + if let Some(sim_tree) = similar_trees.max_by_key(|tree| tree.similarity) { + if sim_tree.similarity > 0 { + sim_tree.tree.merge(&use_tree, merge_by); return; } } - } else if let Some(tree) = similar_trees.max_by_key(|tree| tree.path.len()) { - if tree.path.len() > 1 { - tree.merge(&use_tree, merge_by); + } else if let Some(sim_tree) = similar_trees.max_by_key(|tree| tree.path_len) { + if sim_tree.path_len > 1 { + sim_tree.tree.merge(&use_tree, merge_by); return; } } @@ -880,6 +946,7 @@ impl Rewrite for UseTree { pub(crate) enum SharedPrefix { Crate, Module, + One, } #[cfg(test)] @@ -904,7 +971,7 @@ mod test { } fn eat(&mut self, c: char) { - assert!(self.input.next().unwrap() == c); + assert_eq!(self.input.next().unwrap(), c); } fn push_segment( @@ -1094,6 +1161,49 @@ mod test { ); } + #[test] + fn test_use_tree_merge_one() { + test_merge!(One, ["a", "b"], ["{a, b}"]); + + test_merge!(One, ["a::{aa, ab}", "b", "a"], ["{a::{self, aa, ab}, b}"]); + + test_merge!(One, ["a as x", "b as y"], ["{a as x, b as y}"]); + + test_merge!( + One, + ["a::{aa as xa, ab}", "b", "a"], + ["{a::{self, aa as xa, ab}, b}"] + ); + + test_merge!( + One, + ["a", "a::{aa, ab::{aba, abb}}"], + ["a::{self, aa, ab::{aba, abb}}"] + ); + + test_merge!(One, ["a", "b::{ba, *}"], ["{a, b::{ba, *}}"]); + + test_merge!(One, ["a", "b", "a::aa"], ["{a::{self, aa}, b}"]); + + test_merge!( + One, + ["a::aa::aaa", "a::ac::aca", "a::aa::*"], + ["a::{aa::{aaa, *}, ac::aca}"] + ); + + test_merge!( + One, + ["a", "b::{ba, bb}", "a::{aa::*, ab::aba}"], + ["{a::{self, aa::*, ab::aba}, b::{ba, bb}}"] + ); + + test_merge!( + One, + ["b", "a::ac::{aca, acb}", "a::{aa::*, ab}"], + ["{a::{aa::*, ab, ac::{aca, acb}}, b}"] + ); + } + #[test] fn test_flatten_use_trees() { assert_eq!( diff --git a/src/reorder.rs b/src/reorder.rs index ac65ff2c108..2c58350d4fe 100644 --- a/src/reorder.rs +++ b/src/reorder.rs @@ -113,6 +113,7 @@ fn rewrite_reorderable_or_regroupable_items( 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, }; diff --git a/tests/source/imports_granularity_one.rs b/tests/source/imports_granularity_one.rs new file mode 100644 index 00000000000..c21707df395 --- /dev/null +++ b/tests/source/imports_granularity_one.rs @@ -0,0 +1,60 @@ +// rustfmt-imports_granularity: One + +use b; +use a::ac::{aca, acb}; +use a::{aa::*, ab}; + +use a as x; +use b::ba; +use a::{aa, ab}; + +use a::aa::aaa; +use a::ab::aba as x; +use a::aa::*; + +use a::aa; +use a::ad::ada; +#[cfg(test)] +use a::{ab, ac::aca}; +use b; +#[cfg(test)] +use b::{ + ba, bb, + bc::bca::{bcaa, bcab}, +}; + +pub use a::aa; +pub use a::ae; +use a::{ab, ac, ad}; +use b::ba; +pub use b::{bb, bc::bca}; + +use a::aa::aaa; +use a::ac::{aca, acb}; +use a::{aa::*, ab}; +use b::{ + ba, + bb::{self, bba}, +}; + +use crate::a; +use crate::b::ba; +use c::ca; + +use super::a; +use c::ca; +use super::b::ba; + +use crate::a; +use super::b; +use c::{self, ca}; + +use a::{ + // some comment + aa::{aaa, aab}, + ab, + // another comment + ac::aca, +}; +use b as x; +use a::ad::ada; diff --git a/tests/target/imports_granularity_one.rs b/tests/target/imports_granularity_one.rs new file mode 100644 index 00000000000..78ec5e7325c --- /dev/null +++ b/tests/target/imports_granularity_one.rs @@ -0,0 +1,79 @@ +// rustfmt-imports_granularity: One + +use { + a::{ + aa::*, + ab, + ac::{aca, acb}, + }, + b, +}; + +use { + a::{self as x, aa, ab}, + b::ba, +}; + +use a::{ + aa::{aaa, *}, + ab::aba as x, +}; + +#[cfg(test)] +use a::{ab, ac::aca}; +#[cfg(test)] +use b::{ + ba, bb, + bc::bca::{bcaa, bcab}, +}; +use { + a::{aa, ad::ada}, + b, +}; + +pub use { + a::{aa, ae}, + b::{bb, bc::bca}, +}; +use { + a::{ab, ac, ad}, + b::ba, +}; + +use { + a::{ + aa::{aaa, *}, + ab, + ac::{aca, acb}, + }, + b::{ + ba, + bb::{self, bba}, + }, +}; + +use { + crate::{a, b::ba}, + c::ca, +}; + +use { + super::{a, b::ba}, + c::ca, +}; + +use { + super::b, + crate::a, + c::{self, ca}, +}; + +use { + a::{ + aa::{aaa, aab}, + ab, + ac::aca, + ad::ada, + }, + b as x, +}; -- cgit 1.4.1-3-g733a5 From 59063e8b407acf2d187ba12616f9f36d041eff8c Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Thu, 16 Apr 2020 07:52:47 -0500 Subject: fix: newline width calc in combine w/ comments (#4123) --- src/comment.rs | 2 +- tests/target/issue_4031.rs | 21 ++++++++++++++++++ tests/target/issue_4110.rs | 55 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 tests/target/issue_4031.rs create mode 100644 tests/target/issue_4110.rs (limited to 'src') diff --git a/src/comment.rs b/src/comment.rs index 0f8118a408e..62b624acd49 100644 --- a/src/comment.rs +++ b/src/comment.rs @@ -184,7 +184,7 @@ pub(crate) fn combine_strs_with_missing_comments( let missing_comment = rewrite_missing_comment(span, shape, context)?; if missing_comment.is_empty() { - if allow_extend && prev_str.len() + first_sep.len() + next_str.len() <= shape.width { + if allow_extend && one_line_width <= shape.width { result.push_str(first_sep); } else if !prev_str.is_empty() { result.push_str(&indent.to_string_with_newline(config)) diff --git a/tests/target/issue_4031.rs b/tests/target/issue_4031.rs new file mode 100644 index 00000000000..065d5395c7e --- /dev/null +++ b/tests/target/issue_4031.rs @@ -0,0 +1,21 @@ +fn foo() { + with_woff2_glyf_table("tests/fonts/woff2/SFNT-TTF-Composite.woff2", |glyf| { + let actual = glyf + .records + .iter() + .map(|glyph| match glyph { + GlyfRecord::Parsed( + found @ Glyph { + data: GlyphData::Composite { .. }, + .. + }, + ) => Some(found), + _ => None, + }) + .find(|candidate| candidate.is_some()) + .unwrap() + .unwrap(); + + assert_eq!(*actual, expected) + }); +} diff --git a/tests/target/issue_4110.rs b/tests/target/issue_4110.rs new file mode 100644 index 00000000000..4a58c3946e1 --- /dev/null +++ b/tests/target/issue_4110.rs @@ -0,0 +1,55 @@ +fn bindings() { + let err = match (place_desc, explanation) { + ( + Some(ref name), + BorrowExplanation::MustBeValidFor { + category: + category @ (ConstraintCategory::Return + | ConstraintCategory::CallArgument + | ConstraintCategory::OpaqueType), + from_closure: false, + ref region_name, + span, + .. + }, + ) if borrow_spans.for_generator() | borrow_spans.for_closure() => self + .report_escaping_closure_capture( + borrow_spans, + borrow_span, + region_name, + category, + span, + &format!("`{}`", name), + ), + ( + ref name, + BorrowExplanation::MustBeValidFor { + category: ConstraintCategory::Assignment, + from_closure: false, + region_name: + RegionName { + source: RegionNameSource::AnonRegionFromUpvar(upvar_span, ref upvar_name), + .. + }, + span, + .. + }, + ) => self.report_escaping_data(borrow_span, name, upvar_span, upvar_name, span), + (Some(name), explanation) => self.report_local_value_does_not_live_long_enough( + location, + &name, + &borrow, + drop_span, + borrow_spans, + explanation, + ), + (None, explanation) => self.report_temporary_value_does_not_live_long_enough( + location, + &borrow, + drop_span, + borrow_spans, + proper_span, + explanation, + ), + }; +} -- cgit 1.4.1-3-g733a5 From a59cac29f4dcfd6e9aba03db07b33767809fcea0 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Mon, 6 Sep 2021 15:35:25 -0500 Subject: fix: use correct spans for params with attrs --- src/spanned.rs | 2 +- tests/source/issue_4032.rs | 4 ++++ tests/target/issue_4032.rs | 18 ++++++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 tests/source/issue_4032.rs create mode 100644 tests/target/issue_4032.rs (limited to 'src') diff --git a/src/spanned.rs b/src/spanned.rs index 7e3786b7cd9..8e6c75a3744 100644 --- a/src/spanned.rs +++ b/src/spanned.rs @@ -104,7 +104,7 @@ impl Spanned for ast::Arm { impl Spanned for ast::Param { fn span(&self) -> Span { if crate::items::is_named_param(self) { - mk_sp(self.pat.span.lo(), self.ty.span.hi()) + mk_sp(crate::items::span_lo_for_param(self), self.ty.span.hi()) } else { self.ty.span } diff --git a/tests/source/issue_4032.rs b/tests/source/issue_4032.rs new file mode 100644 index 00000000000..11ded074c34 --- /dev/null +++ b/tests/source/issue_4032.rs @@ -0,0 +1,4 @@ +fn a1(#[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa] a: u8) {} +fn b1(#[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa] bb: u8) {} +fn a2(#[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa] a: u8) {} +fn b2(#[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa] bb: u8) {} diff --git a/tests/target/issue_4032.rs b/tests/target/issue_4032.rs new file mode 100644 index 00000000000..2e7e624ca6e --- /dev/null +++ b/tests/target/issue_4032.rs @@ -0,0 +1,18 @@ +fn a1( + #[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa] + a: u8, +) { +} +fn b1( + #[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa] + bb: u8, +) { +} +fn a2( + #[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa] a: u8, +) { +} +fn b2( + #[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa] bb: u8, +) { +} -- cgit 1.4.1-3-g733a5 From c2f0e99d854d399880d05f546953659c2d170d54 Mon Sep 17 00:00:00 2001 From: Stéphane Campinas Date: Tue, 6 Oct 2020 03:44:48 +0200 Subject: try to write the parameter on a new line in case the attribute/parameter together are over max_width --- src/comment.rs | 14 ++++++++------ src/items.rs | 33 +++++++++++++++++++++++++++------ 2 files changed, 35 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/comment.rs b/src/comment.rs index 62b624acd49..42449d1060f 100644 --- a/src/comment.rs +++ b/src/comment.rs @@ -10,7 +10,8 @@ use crate::rewrite::RewriteContext; use crate::shape::{Indent, Shape}; use crate::string::{rewrite_string, StringFormat}; use crate::utils::{ - count_newlines, first_line_width, last_line_width, trim_left_preserve_layout, unicode_str_width, + count_newlines, first_line_width, last_line_width, trim_left_preserve_layout, + trimmed_last_line_width, unicode_str_width, }; use crate::{ErrorKind, FormattingError}; @@ -171,11 +172,12 @@ pub(crate) fn combine_strs_with_missing_comments( String::with_capacity(prev_str.len() + next_str.len() + shape.indent.width() + 128); result.push_str(prev_str); let mut allow_one_line = !prev_str.contains('\n') && !next_str.contains('\n'); - let first_sep = if prev_str.is_empty() || next_str.is_empty() { - "" - } else { - " " - }; + let first_sep = + if prev_str.is_empty() || next_str.is_empty() || trimmed_last_line_width(prev_str) == 0 { + "" + } else { + " " + }; let mut one_line_width = last_line_width(prev_str) + first_line_width(next_str) + first_sep.len(); diff --git a/src/items.rs b/src/items.rs index 4fa7190c138..6ba83b577ae 100644 --- a/src/items.rs +++ b/src/items.rs @@ -1980,12 +1980,13 @@ impl Rewrite for ast::Param { has_multiple_attr_lines, ) } else if is_named_param(self) { + let param_name = &self + .pat + .rewrite(context, Shape::legacy(shape.width, shape.indent))?; let mut result = combine_strs_with_missing_comments( context, ¶m_attrs_result, - &self - .pat - .rewrite(context, Shape::legacy(shape.width, shape.indent))?, + param_name, span, shape, !has_multiple_attr_lines, @@ -1999,10 +2000,30 @@ impl Rewrite for ast::Param { result.push_str(&after_comment); let overhead = last_line_width(&result); let max_width = shape.width.checked_sub(overhead)?; - let ty_str = self + if let Some(ty_str) = self .ty - .rewrite(context, Shape::legacy(max_width, shape.indent))?; - result.push_str(&ty_str); + .rewrite(context, Shape::legacy(max_width, shape.indent)) + { + result.push_str(&ty_str); + } else { + result = combine_strs_with_missing_comments( + context, + &(param_attrs_result + &shape.to_string_with_newline(context.config)), + param_name, + span, + shape, + !has_multiple_attr_lines, + )?; + result.push_str(&before_comment); + result.push_str(colon_spaces(context.config)); + result.push_str(&after_comment); + let overhead = last_line_width(&result); + let max_width = shape.width.checked_sub(overhead)?; + let ty_str = self + .ty + .rewrite(context, Shape::legacy(max_width, shape.indent))?; + result.push_str(&ty_str); + } } Some(result) -- cgit 1.4.1-3-g733a5 From 57548aa096f31d90b9606f882f5815a93b2570b3 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Tue, 7 Sep 2021 19:49:56 -0500 Subject: fix: resolve idempotency issue in extern body elements --- src/missed_spans.rs | 20 ++++++++++++-------- tests/source/issue_4963.rs | 5 +++++ tests/target/issue_4963.rs | 9 +++++++++ 3 files changed, 26 insertions(+), 8 deletions(-) create mode 100644 tests/source/issue_4963.rs create mode 100644 tests/target/issue_4963.rs (limited to 'src') diff --git a/src/missed_spans.rs b/src/missed_spans.rs index 263d840785a..28edcb784b4 100644 --- a/src/missed_spans.rs +++ b/src/missed_spans.rs @@ -51,6 +51,14 @@ impl<'a> FmtVisitor<'a> { } pub(crate) fn format_missing_with_indent(&mut self, end: BytePos) { + self.format_missing_indent(end, true) + } + + pub(crate) fn format_missing_no_indent(&mut self, end: BytePos) { + self.format_missing_indent(end, false) + } + + fn format_missing_indent(&mut self, end: BytePos, should_indent: bool) { let config = self.config; self.format_missing_inner(end, |this, last_snippet, snippet| { this.push_str(last_snippet.trim_end()); @@ -58,14 +66,10 @@ impl<'a> FmtVisitor<'a> { // No new lines in the snippet. this.push_str("\n"); } - let indent = this.block_indent.to_string(config); - this.push_str(&indent); - }) - } - - pub(crate) fn format_missing_no_indent(&mut self, end: BytePos) { - self.format_missing_inner(end, |this, last_snippet, _| { - this.push_str(last_snippet.trim_end()); + if should_indent { + let indent = this.block_indent.to_string(config); + this.push_str(&indent); + } }) } diff --git a/tests/source/issue_4963.rs b/tests/source/issue_4963.rs new file mode 100644 index 00000000000..32e1f6cd41b --- /dev/null +++ b/tests/source/issue_4963.rs @@ -0,0 +1,5 @@ +mod test { + extern "C" {fn test();} +} + +extern "C" {fn test();} \ No newline at end of file diff --git a/tests/target/issue_4963.rs b/tests/target/issue_4963.rs new file mode 100644 index 00000000000..0c3c13579c1 --- /dev/null +++ b/tests/target/issue_4963.rs @@ -0,0 +1,9 @@ +mod test { + extern "C" { + fn test(); + } +} + +extern "C" { + fn test(); +} -- cgit 1.4.1-3-g733a5 From a80688329c7bf696245b5ed6f3eeda6a80ab3721 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Wed, 8 Sep 2021 18:59:49 -0500 Subject: fix: handle param doc comments for macro scenarios --- src/items.rs | 9 ++++++--- tests/target/issue_4936.rs | 10 ++++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) create mode 100644 tests/target/issue_4936.rs (limited to 'src') diff --git a/src/items.rs b/src/items.rs index 6ba83b577ae..e8eb1c5dfbb 100644 --- a/src/items.rs +++ b/src/items.rs @@ -1960,14 +1960,17 @@ impl Rewrite for ast::Param { let param_attrs_result = self .attrs .rewrite(context, Shape::legacy(shape.width, shape.indent))?; - let (span, has_multiple_attr_lines) = if !self.attrs.is_empty() { + // N.B. Doc comments aren't typically valid syntax, but could appear + // in the presence of certain macros - https://github.com/rust-lang/rustfmt/issues/4936 + let (span, has_multiple_attr_lines, has_doc_comments) = if !self.attrs.is_empty() { let num_attrs = self.attrs.len(); ( mk_sp(self.attrs[num_attrs - 1].span.hi(), self.pat.span.lo()), param_attrs_result.contains('\n'), + self.attrs.iter().any(|a| a.is_doc_comment()), ) } else { - (mk_sp(self.span.lo(), self.span.lo()), false) + (mk_sp(self.span.lo(), self.span.lo()), false, false) }; if let Some(ref explicit_self) = self.to_self() { @@ -1989,7 +1992,7 @@ impl Rewrite for ast::Param { param_name, span, shape, - !has_multiple_attr_lines, + !has_multiple_attr_lines && !has_doc_comments, )?; if !is_empty_infer(&*self.ty, self.pat.span) { diff --git a/tests/target/issue_4936.rs b/tests/target/issue_4936.rs new file mode 100644 index 00000000000..c19e505fd03 --- /dev/null +++ b/tests/target/issue_4936.rs @@ -0,0 +1,10 @@ +#[discard_params_doc] +trait Trait { + fn foo( + &self, + /// some docs + bar: String, + /// another docs + baz: i32, + ); +} -- cgit 1.4.1-3-g733a5 From b10ab51fed62f54010a786e3f7d018700464b786 Mon Sep 17 00:00:00 2001 From: Nipunn Koorapati Date: Sat, 7 Aug 2021 18:00:51 -0700 Subject: rustfmt doc code blocks with multiple comma-separated attributes Added test covering this. Chose to treat the code block as rust if and only if all of the comma-separated attributes are rust-valid. Chose to allow/preserve whitespace around commas Fixes #3158 --- src/comment.rs | 52 ++++++++++++++------------------ tests/source/issue-3158.rs | 74 ++++++++++++++++++++++++++++++++++++++++++++++ tests/target/issue-3158.rs | 74 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 171 insertions(+), 29 deletions(-) create mode 100644 tests/source/issue-3158.rs create mode 100644 tests/target/issue-3158.rs (limited to 'src') diff --git a/src/comment.rs b/src/comment.rs index 42449d1060f..60825424858 100644 --- a/src/comment.rs +++ b/src/comment.rs @@ -394,28 +394,26 @@ fn identify_comment( } } -/// Attributes for code blocks in rustdoc. -/// See https://doc.rust-lang.org/rustdoc/print.html#attributes +/// Enum indicating if the code block contains rust based on attributes enum CodeBlockAttribute { Rust, - Ignore, - Text, - ShouldPanic, - NoRun, - CompileFail, + NotRust, } impl CodeBlockAttribute { - fn new(attribute: &str) -> CodeBlockAttribute { - match attribute { - "rust" | "" => CodeBlockAttribute::Rust, - "ignore" => CodeBlockAttribute::Ignore, - "text" => CodeBlockAttribute::Text, - "should_panic" => CodeBlockAttribute::ShouldPanic, - "no_run" => CodeBlockAttribute::NoRun, - "compile_fail" => CodeBlockAttribute::CompileFail, - _ => CodeBlockAttribute::Text, + /// Parse comma separated attributes list. Return rust only if all + /// attributes are valid rust attributes + /// See https://doc.rust-lang.org/rustdoc/print.html#attributes + fn new(attributes: &str) -> CodeBlockAttribute { + for attribute in attributes.split(",") { + match attribute.trim() { + "" | "rust" | "should_panic" | "no_run" | "edition2015" | "edition2018" + | "edition2021" => (), + "ignore" | "compile_fail" | "text" => return CodeBlockAttribute::NotRust, + _ => return CodeBlockAttribute::NotRust, + } } + CodeBlockAttribute::Rust } } @@ -649,25 +647,21 @@ impl<'a> CommentRewrite<'a> { } else if self.code_block_attr.is_some() { if line.starts_with("```") { let code_block = match self.code_block_attr.as_ref().unwrap() { - CodeBlockAttribute::Ignore | CodeBlockAttribute::Text => { - trim_custom_comment_prefix(&self.code_block_buffer) - } - _ if self.code_block_buffer.is_empty() => String::new(), - _ => { + CodeBlockAttribute::Rust + if self.fmt.config.format_code_in_doc_comments() + && !self.code_block_buffer.is_empty() => + { let mut config = self.fmt.config.clone(); config.set().wrap_comments(false); - if config.format_code_in_doc_comments() { - if let Some(s) = - crate::format_code_block(&self.code_block_buffer, &config, false) - { - trim_custom_comment_prefix(&s.snippet) - } else { - trim_custom_comment_prefix(&self.code_block_buffer) - } + if let Some(s) = + crate::format_code_block(&self.code_block_buffer, &config, false) + { + trim_custom_comment_prefix(&s.snippet) } else { trim_custom_comment_prefix(&self.code_block_buffer) } } + _ => trim_custom_comment_prefix(&self.code_block_buffer), }; if !code_block.is_empty() { self.result.push_str(&self.comment_line_separator); diff --git a/tests/source/issue-3158.rs b/tests/source/issue-3158.rs new file mode 100644 index 00000000000..315073db6af --- /dev/null +++ b/tests/source/issue-3158.rs @@ -0,0 +1,74 @@ +// rustfmt-format_code_in_doc_comments: true + +/// Should format +/// ```rust +/// assert!( false ); +/// ``` +/// +/// Should format +/// ```rust,should_panic +/// assert!( false ); +/// ``` +/// +/// Should format +/// ```rust,should_panic,edition2018 +/// assert!( false ); +/// ``` +/// +/// Should format +/// ```rust , should_panic , edition2018 +/// assert!( false ); +/// ``` +/// +/// Should not format +/// ```ignore +/// assert!( false ); +/// ``` +/// +/// Should not format (not all are rust) +/// ```rust,ignore +/// assert!( false ); +/// ``` +/// +/// Should not format (rust compile_fail) +/// ```compile_fail +/// assert!( false ); +/// ``` +/// +/// Should not format (rust compile_fail) +/// ```rust,compile_fail +/// assert!( false ); +/// ``` +/// +/// Various unspecified ones that should format +/// ``` +/// assert!( false ); +/// ``` +/// +/// ```, +/// assert!( false ); +/// ``` +/// +/// ```,,,,, +/// assert!( false ); +/// ``` +/// +/// ```,,, rust ,, +/// assert!( false ); +/// ``` +/// +/// Should not format +/// ```,,, rust , ignore, +/// assert!( false ); +/// ``` +/// +/// Few empty ones +/// ``` +/// ``` +/// +/// ```rust +/// ``` +/// +/// ```ignore +/// ``` +fn foo() {} diff --git a/tests/target/issue-3158.rs b/tests/target/issue-3158.rs new file mode 100644 index 00000000000..4bbbdc1d039 --- /dev/null +++ b/tests/target/issue-3158.rs @@ -0,0 +1,74 @@ +// rustfmt-format_code_in_doc_comments: true + +/// Should format +/// ```rust +/// assert!(false); +/// ``` +/// +/// Should format +/// ```rust,should_panic +/// assert!(false); +/// ``` +/// +/// Should format +/// ```rust,should_panic,edition2018 +/// assert!(false); +/// ``` +/// +/// Should format +/// ```rust , should_panic , edition2018 +/// assert!(false); +/// ``` +/// +/// Should not format +/// ```ignore +/// assert!( false ); +/// ``` +/// +/// Should not format (not all are rust) +/// ```rust,ignore +/// assert!( false ); +/// ``` +/// +/// Should not format (rust compile_fail) +/// ```compile_fail +/// assert!( false ); +/// ``` +/// +/// Should not format (rust compile_fail) +/// ```rust,compile_fail +/// assert!( false ); +/// ``` +/// +/// Various unspecified ones that should format +/// ``` +/// assert!(false); +/// ``` +/// +/// ```, +/// assert!(false); +/// ``` +/// +/// ```,,,,, +/// assert!(false); +/// ``` +/// +/// ```,,, rust ,, +/// assert!(false); +/// ``` +/// +/// Should not format +/// ```,,, rust , ignore, +/// assert!( false ); +/// ``` +/// +/// Few empty ones +/// ``` +/// ``` +/// +/// ```rust +/// ``` +/// +/// ```ignore +/// ``` +fn foo() {} -- cgit 1.4.1-3-g733a5 From 67a59f6ee35c3cfd75e2aab5a8475608e167840b Mon Sep 17 00:00:00 2001 From: Laurențiu Nicola Date: Fri, 8 Nov 2019 23:50:18 +0200 Subject: opts: rephrase wording for --all and -p --- src/cargo-fmt/main.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/cargo-fmt/main.rs b/src/cargo-fmt/main.rs index f8cf698525b..f1125fa0bda 100644 --- a/src/cargo-fmt/main.rs +++ b/src/cargo-fmt/main.rs @@ -36,7 +36,7 @@ pub struct Opts { #[structopt(long = "version")] version: bool, - /// Specify package to format (only usable in workspaces) + /// Specify package to format #[structopt(short = "p", long = "package", value_name = "package")] packages: Vec, @@ -53,7 +53,7 @@ pub struct Opts { #[structopt(name = "rustfmt_options", raw(true))] rustfmt_options: Vec, - /// Format all packages (only usable in workspaces) + /// Format all packages, and also their local path-based dependencies #[structopt(long = "all")] format_all: bool, } -- cgit 1.4.1-3-g733a5 From d4ffd1efa4c83084f05f6e83585ae0a70450bcfd Mon Sep 17 00:00:00 2001 From: Seiichi Uchida Date: Fri, 10 Jul 2020 11:23:12 +0900 Subject: Support @generated marker to skip code formatting This is a copy of #4296 with these changes: * file is not reopened again to find if the file is generated * first five lines are scanned for `@generated` marker instead of one * no attempt is made to only search for marker in comments `@generated` marker is used by certain tools to understand that the file is generated, so it should be treated differently than a file written by a human: * linters should not be invoked on these files, * diffs in these files are less important, * and these files should not be reformatted. This PR proposes builtin support for `@generated` marker. I have not found a standard for a generated file marker, but: * Facebook [uses `@generated` marker](https://tinyurl.com/fb-generated) * Phabricator tool which was spawned from Facebook internal tool [also understands `@generated` marker](https://git.io/JnVHa) * Cargo inserts `@generated` marker into [generated Cargo.lock files](https://git.io/JnVHP) My personal story is that rust-protobuf project which I maintain was broken twice because of incompatibilities/bugs in rustfmt marker handling: [one](https://github.com/stepancheg/rust-protobuf/issues/493), [two](https://github.com/stepancheg/rust-protobuf/issues/551). (Also, rust-protobuf started generating `@generated` marker [6 years ago](https://git.io/JnV5h)). While rustfmt AST markers are useful to apply to a certain AST elements, disable whole-file-at-once all-tools-at-once text level marker might be easier to use and more reliable for generated code. --- Configurations.md | 9 +++++++++ src/config/mod.rs | 2 ++ src/formatting.rs | 9 ++++++++- src/formatting/generated.rs | 7 +++++++ src/syntux/session.rs | 6 ++++++ src/test/mod.rs | 2 +- tests/source/configs/format_generated_files/false.rs | 8 ++++++++ tests/source/configs/format_generated_files/true.rs | 8 ++++++++ tests/target/configs/format_generated_files/false.rs | 8 ++++++++ tests/target/configs/format_generated_files/true.rs | 6 ++++++ 10 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 src/formatting/generated.rs create mode 100644 tests/source/configs/format_generated_files/false.rs create mode 100644 tests/source/configs/format_generated_files/true.rs create mode 100644 tests/target/configs/format_generated_files/false.rs create mode 100644 tests/target/configs/format_generated_files/true.rs (limited to 'src') diff --git a/Configurations.md b/Configurations.md index 469deccc56e..84e8c3f7db6 100644 --- a/Configurations.md +++ b/Configurations.md @@ -924,6 +924,15 @@ fn add_one(x: i32) -> i32 { } ``` +## `format_generated_files` + +Format generated files. A file is considered generated +if any of the first five lines contains `@generated` marker. + +- **Default value**: `false` +- **Possible values**: `true`, `false` +- **Stable**: No + ## `format_macro_matchers` Format the metavariable matching patterns in macros. diff --git a/src/config/mod.rs b/src/config/mod.rs index 8c04363b1fd..3d6e32fdb60 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -136,6 +136,7 @@ create_config! { inline_attribute_width: usize, 0, false, "Write an item and its attribute on the same line \ if their combined width is below a threshold"; + format_generated_files: bool, false, false, "Format generated files"; // Options that can change the source code beyond whitespace/blocks (somewhat linty things) merge_derives: bool, true, true, "Merge multiple `#[derive(...)]` into a single one"; @@ -604,6 +605,7 @@ blank_lines_lower_bound = 0 edition = "2015" version = "One" inline_attribute_width = 0 +format_generated_files = false merge_derives = true use_try_shorthand = false use_field_init_shorthand = false diff --git a/src/formatting.rs b/src/formatting.rs index e0403574eeb..9ef47b887ca 100644 --- a/src/formatting.rs +++ b/src/formatting.rs @@ -10,6 +10,7 @@ use rustc_span::Span; 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::syntux::parser::{DirectoryOwnership, Parser, ParserError}; @@ -18,6 +19,7 @@ use crate::utils::count_newlines; use crate::visitor::FmtVisitor; use crate::{modules, source_file, ErrorKind, FormatReport, Input, Session}; +mod generated; mod newline_style; // A map of the files of a crate, with their new content @@ -103,7 +105,12 @@ fn format_project( context.parse_session.set_silent_emitter(); for (path, module) in files { - let should_ignore = !input_is_stdin && context.ignore_file(&path); + let source_file = context.parse_session.span_to_file_contents(module.span); + let src = source_file.src.as_ref().expect("SourceFile without src"); + + let should_ignore = (!input_is_stdin && context.ignore_file(&path)) + || (!config.format_generated_files() && is_generated_file(src)); + if (config.skip_children() && path != main_file) || should_ignore { continue; } diff --git a/src/formatting/generated.rs b/src/formatting/generated.rs new file mode 100644 index 00000000000..58f43f17ee1 --- /dev/null +++ b/src/formatting/generated.rs @@ -0,0 +1,7 @@ +/// Returns `true` if the given span is a part of generated files. +pub(super) fn is_generated_file(original_snippet: &str) -> bool { + original_snippet + .lines() + .take(5) // looking for marker only in the beginning of the file + .any(|line| line.contains("@generated")) +} diff --git a/src/syntux/session.rs b/src/syntux/session.rs index 870f0acfe39..94257e1ce7f 100644 --- a/src/syntux/session.rs +++ b/src/syntux/session.rs @@ -175,6 +175,12 @@ impl ParseSess { self.parse_sess.source_map().span_to_filename(span).into() } + pub(crate) fn span_to_file_contents(&self, span: Span) -> Lrc { + self.parse_sess + .source_map() + .lookup_source_file(span.data().lo) + } + pub(crate) fn span_to_first_line_string(&self, span: Span) -> String { let file_lines = self.parse_sess.source_map().span_to_lines(span).ok(); diff --git a/src/test/mod.rs b/src/test/mod.rs index cb52346a13a..ece1b91bfd7 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -694,7 +694,7 @@ fn read_significant_comments(file_name: &Path) -> HashMap { reader .lines() .map(|line| line.expect("failed getting line")) - .take_while(|line| line_regex.is_match(line)) + .filter(|line| line_regex.is_match(line)) .filter_map(|line| { regex.captures_iter(&line).next().map(|capture| { ( diff --git a/tests/source/configs/format_generated_files/false.rs b/tests/source/configs/format_generated_files/false.rs new file mode 100644 index 00000000000..dec1e00d117 --- /dev/null +++ b/tests/source/configs/format_generated_files/false.rs @@ -0,0 +1,8 @@ +// @generated +// rustfmt-format_generated_files: false + +fn main() +{ + println!("hello, world") + ; +} diff --git a/tests/source/configs/format_generated_files/true.rs b/tests/source/configs/format_generated_files/true.rs new file mode 100644 index 00000000000..a25ddc25a6a --- /dev/null +++ b/tests/source/configs/format_generated_files/true.rs @@ -0,0 +1,8 @@ +// @generated +// rustfmt-format_generated_files: true + +fn main() +{ + println!("hello, world") + ; +} diff --git a/tests/target/configs/format_generated_files/false.rs b/tests/target/configs/format_generated_files/false.rs new file mode 100644 index 00000000000..dec1e00d117 --- /dev/null +++ b/tests/target/configs/format_generated_files/false.rs @@ -0,0 +1,8 @@ +// @generated +// rustfmt-format_generated_files: false + +fn main() +{ + println!("hello, world") + ; +} diff --git a/tests/target/configs/format_generated_files/true.rs b/tests/target/configs/format_generated_files/true.rs new file mode 100644 index 00000000000..5fea7e8b341 --- /dev/null +++ b/tests/target/configs/format_generated_files/true.rs @@ -0,0 +1,6 @@ +// @generated +// rustfmt-format_generated_files: true + +fn main() { + println!("hello, world"); +} -- cgit 1.4.1-3-g733a5 From 9d65b7dcd19557bca9aa4b175efa14a35db6d713 Mon Sep 17 00:00:00 2001 From: Arjen Laarhoven Date: Thu, 15 Jul 2021 19:55:52 +0200 Subject: feat: upper- or lowercase hexadecimal literals --- Configurations.md | 7 +++++++ src/config/mod.rs | 3 +++ src/config/options.rs | 11 +++++++++++ src/expr.rs | 33 ++++++++++++++++++++++++++++++++- tests/source/hex_literal_lower.rs | 5 +++++ tests/source/hex_literal_upper.rs | 5 +++++ tests/target/hex_literal_lower.rs | 5 +++++ tests/target/hex_literal_preserve.rs | 5 +++++ tests/target/hex_literal_upper.rs | 5 +++++ 9 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 tests/source/hex_literal_lower.rs create mode 100644 tests/source/hex_literal_upper.rs create mode 100644 tests/target/hex_literal_lower.rs create mode 100644 tests/target/hex_literal_preserve.rs create mode 100644 tests/target/hex_literal_upper.rs (limited to 'src') diff --git a/Configurations.md b/Configurations.md index 84e8c3f7db6..b8f8f305396 100644 --- a/Configurations.md +++ b/Configurations.md @@ -1056,6 +1056,13 @@ fn lorem() -> usize { See also: [`tab_spaces`](#tab_spaces). +## `hex_literal_case` + +Control the case of the letters in hexadecimal literal values + +- **Default value**: `Preserve` +- **Possible values**: `Upper`, `Lower` +- **Stable**: No ## `hide_parse_errors` diff --git a/src/config/mod.rs b/src/config/mod.rs index 3d6e32fdb60..c6cee8ed227 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -69,6 +69,8 @@ create_config! { format_macro_matchers: bool, false, false, "Format the metavariable matching patterns in macros"; format_macro_bodies: bool, true, false, "Format the bodies of macros"; + hex_literal_case: HexLiteralCase, HexLiteralCase::Preserve, false, + "Format hexadecimal integer literals"; // Single line expressions and items empty_item_single_line: bool, true, false, @@ -570,6 +572,7 @@ license_template_path = "" format_strings = false format_macro_matchers = false format_macro_bodies = true +hex_literal_case = "Preserve" empty_item_single_line = true struct_lit_single_line = true fn_single_line = false diff --git a/src/config/options.rs b/src/config/options.rs index db15ee97a40..e92f8e8a531 100644 --- a/src/config/options.rs +++ b/src/config/options.rs @@ -129,6 +129,17 @@ pub enum ImportGranularity { One, } +/// Controls how rustfmt should handle case in hexadecimal literals. +#[config_type] +pub enum HexLiteralCase { + /// Leave the literal as-is + Preserve, + /// Ensure all literals use uppercase lettering + Upper, + /// Ensure all literals use lowercase lettering + Lower, +} + #[config_type] pub enum ReportTactic { Always, diff --git a/src/expr.rs b/src/expr.rs index 6cfeb9977a9..01cc388c186 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -13,7 +13,7 @@ use crate::comment::{ rewrite_missing_comment, CharClasses, FindUncommented, }; use crate::config::lists::*; -use crate::config::{Config, ControlBraceStyle, IndentStyle, Version}; +use crate::config::{Config, ControlBraceStyle, HexLiteralCase, IndentStyle, Version}; use crate::lists::{ definitive_tactic, itemize_list, shape_for_tactic, struct_lit_formatting, struct_lit_shape, struct_lit_tactic, write_list, ListFormatting, Separator, @@ -1168,6 +1168,7 @@ pub(crate) fn rewrite_literal( ) -> Option { match l.kind { ast::LitKind::Str(_, ast::StrStyle::Cooked) => rewrite_string_lit(context, l.span, shape), + ast::LitKind::Int(..) => rewrite_int_lit(context, l, shape), _ => wrap_str( context.snippet(l.span).to_owned(), context.config.max_width(), @@ -1202,6 +1203,36 @@ fn rewrite_string_lit(context: &RewriteContext<'_>, span: Span, shape: Shape) -> ) } +fn rewrite_int_lit(context: &RewriteContext<'_>, lit: &ast::Lit, shape: Shape) -> Option { + let span = lit.span; + let symbol = lit.token.symbol.as_str(); + + if symbol.starts_with("0x") { + let hex_lit = match context.config.hex_literal_case() { + HexLiteralCase::Preserve => None, + HexLiteralCase::Upper => Some(symbol[2..].to_ascii_uppercase()), + HexLiteralCase::Lower => Some(symbol[2..].to_ascii_lowercase()), + }; + if let Some(hex_lit) = hex_lit { + return wrap_str( + format!( + "0x{}{}", + hex_lit, + lit.token.suffix.map_or(String::new(), |s| s.to_string()) + ), + context.config.max_width(), + shape, + ); + } + } + + wrap_str( + context.snippet(span).to_owned(), + context.config.max_width(), + shape, + ) +} + fn choose_separator_tactic(context: &RewriteContext<'_>, span: Span) -> Option { if context.inside_macro() { if span_ends_with_comma(context, span) { diff --git a/tests/source/hex_literal_lower.rs b/tests/source/hex_literal_lower.rs new file mode 100644 index 00000000000..ce307b3aa52 --- /dev/null +++ b/tests/source/hex_literal_lower.rs @@ -0,0 +1,5 @@ +// rustfmt-hex_literal_case: Lower +fn main() { + let h1 = 0xCAFE_5EA7; + let h2 = 0xCAFE_F00Du32; +} diff --git a/tests/source/hex_literal_upper.rs b/tests/source/hex_literal_upper.rs new file mode 100644 index 00000000000..b1092ad71ba --- /dev/null +++ b/tests/source/hex_literal_upper.rs @@ -0,0 +1,5 @@ +// rustfmt-hex_literal_case: Upper +fn main() { + let h1 = 0xCaFE_5ea7; + let h2 = 0xCAFE_F00Du32; +} diff --git a/tests/target/hex_literal_lower.rs b/tests/target/hex_literal_lower.rs new file mode 100644 index 00000000000..5c27fded167 --- /dev/null +++ b/tests/target/hex_literal_lower.rs @@ -0,0 +1,5 @@ +// rustfmt-hex_literal_case: Lower +fn main() { + let h1 = 0xcafe_5ea7; + let h2 = 0xcafe_f00du32; +} diff --git a/tests/target/hex_literal_preserve.rs b/tests/target/hex_literal_preserve.rs new file mode 100644 index 00000000000..e8774d0bb24 --- /dev/null +++ b/tests/target/hex_literal_preserve.rs @@ -0,0 +1,5 @@ +// rustfmt-hex_literal_case: Preserve +fn main() { + let h1 = 0xcAfE_5Ea7; + let h2 = 0xCaFe_F00du32; +} diff --git a/tests/target/hex_literal_upper.rs b/tests/target/hex_literal_upper.rs new file mode 100644 index 00000000000..48bb93d2c1c --- /dev/null +++ b/tests/target/hex_literal_upper.rs @@ -0,0 +1,5 @@ +// rustfmt-hex_literal_case: Upper +fn main() { + let h1 = 0xCAFE_5EA7; + let h2 = 0xCAFE_F00Du32; +} -- cgit 1.4.1-3-g733a5 From 17cb2b147e11c9ad274b316026b1001fbd7007d4 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Sat, 26 Oct 2019 21:07:04 -0500 Subject: feat: add --check flag to cargo fmt (#3890) --- src/cargo-fmt/main.rs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/cargo-fmt/main.rs b/src/cargo-fmt/main.rs index f1125fa0bda..89ce454ac4d 100644 --- a/src/cargo-fmt/main.rs +++ b/src/cargo-fmt/main.rs @@ -56,6 +56,10 @@ pub struct Opts { /// Format all packages, and also their local path-based dependencies #[structopt(long = "all")] format_all: bool, + + /// Run rustfmt in check mode + #[structopt(long = "check")] + check: bool, } fn main() { @@ -104,6 +108,12 @@ fn execute() -> i32 { let strategy = CargoFmtStrategy::from_opts(&opts); let mut rustfmt_args = opts.rustfmt_options; + if opts.check { + let check_flag = String::from("--check"); + if !rustfmt_args.contains(&check_flag) { + rustfmt_args.push(check_flag); + } + } if let Some(message_format) = opts.message_format { if let Err(msg) = convert_message_format_to_rustfmt_args(&message_format, &mut rustfmt_args) { @@ -553,6 +563,7 @@ mod cargo_fmt_tests { assert_eq!(false, o.quiet); assert_eq!(false, o.verbose); assert_eq!(false, o.version); + assert_eq!(false, o.check); assert_eq!(empty, o.packages); assert_eq!(empty, o.rustfmt_options); assert_eq!(false, o.format_all); @@ -571,6 +582,7 @@ mod cargo_fmt_tests { "p2", "--message-format", "short", + "--check", "--", "--edition", "2018", @@ -578,6 +590,7 @@ mod cargo_fmt_tests { assert_eq!(true, o.quiet); assert_eq!(false, o.verbose); assert_eq!(false, o.version); + assert_eq!(true, o.check); assert_eq!(vec!["p1", "p2"], o.packages); assert_eq!(vec!["--edition", "2018"], o.rustfmt_options); assert_eq!(false, o.format_all); @@ -606,12 +619,12 @@ mod cargo_fmt_tests { fn mandatory_separator() { assert!( Opts::clap() - .get_matches_from_safe(&["test", "--check"]) + .get_matches_from_safe(&["test", "--emit"]) .is_err() ); assert!( !Opts::clap() - .get_matches_from_safe(&["test", "--", "--check"]) + .get_matches_from_safe(&["test", "--", "--emit"]) .is_err() ); } -- cgit 1.4.1-3-g733a5 From 7aa69e5bc87f32fdcbf037abce2d575335480b9a Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Thu, 16 Sep 2021 21:25:09 -0500 Subject: refactor: use iter workaround for contains() gap --- src/cargo-fmt/main.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/cargo-fmt/main.rs b/src/cargo-fmt/main.rs index 89ce454ac4d..147b19d7a48 100644 --- a/src/cargo-fmt/main.rs +++ b/src/cargo-fmt/main.rs @@ -109,9 +109,9 @@ fn execute() -> i32 { let strategy = CargoFmtStrategy::from_opts(&opts); let mut rustfmt_args = opts.rustfmt_options; if opts.check { - let check_flag = String::from("--check"); - if !rustfmt_args.contains(&check_flag) { - rustfmt_args.push(check_flag); + let check_flag = "--check"; + if !rustfmt_args.iter().any(|o| o == check_flag) { + rustfmt_args.push(check_flag.to_owned()); } } if let Some(message_format) = opts.message_format { -- cgit 1.4.1-3-g733a5 From dd445aba080cd337300644c77137fedcad482623 Mon Sep 17 00:00:00 2001 From: Ulyssa Date: Wed, 15 Sep 2021 08:58:23 -0700 Subject: Trailing comma on match block goes missing when guard is on its own line --- src/matches.rs | 1 + tests/source/match-block-trailing-comma.rs | 8 ++++++++ tests/target/match-block-trailing-comma.rs | 10 ++++++++++ 3 files changed, 19 insertions(+) (limited to 'src') diff --git a/src/matches.rs b/src/matches.rs index 140ec226c02..5a6ed0ec06e 100644 --- a/src/matches.rs +++ b/src/matches.rs @@ -409,6 +409,7 @@ fn rewrite_match_body( } result.push_str(&nested_indent_str); result.push_str(&body_str); + result.push_str(&comma); return Some(result); } diff --git a/tests/source/match-block-trailing-comma.rs b/tests/source/match-block-trailing-comma.rs index e9daac13bf9..baa05b79c16 100644 --- a/tests/source/match-block-trailing-comma.rs +++ b/tests/source/match-block-trailing-comma.rs @@ -8,6 +8,14 @@ fn foo() { "line1"; "line2" } + ThisIsA::Guard if true => { + "line1"; + "line2" + } + ThisIsA::ReallyLongPattern(ThatWillForce::TheGuard, ToWrapOnto::TheFollowingLine) if true => { + "line1"; + "line2" + } b => (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb), } diff --git a/tests/target/match-block-trailing-comma.rs b/tests/target/match-block-trailing-comma.rs index 44d1f289f8e..5ab433a2e6c 100644 --- a/tests/target/match-block-trailing-comma.rs +++ b/tests/target/match-block-trailing-comma.rs @@ -8,6 +8,16 @@ fn foo() { "line1"; "line2" }, + ThisIsA::Guard if true => { + "line1"; + "line2" + }, + ThisIsA::ReallyLongPattern(ThatWillForce::TheGuard, ToWrapOnto::TheFollowingLine) + if true => + { + "line1"; + "line2" + }, b => ( aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, -- cgit 1.4.1-3-g733a5 From 7f6229b9aada69389be4ead0ecbec8aed5892a24 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Mon, 20 Sep 2021 18:58:38 -0500 Subject: tests: restructure and extend cargo-fmt tests --- .gitignore | 1 + src/cargo-fmt/test/message_format.rs | 80 ++++++++++++ src/cargo-fmt/test/mod.rs | 137 +++++++++++++++++++++ src/cargo-fmt/test/targets.rs | 134 ++++++++++++++++++++ .../source/divergent-crate-dir-names/Cargo.toml | 13 ++ .../dependency-dir-name/Cargo.toml | 10 ++ .../dependency-dir-name/src/lib.rs | 7 ++ .../dependency-dir-name/subdep-dir-name/Cargo.toml | 7 ++ .../dependency-dir-name/subdep-dir-name/src/lib.rs | 7 ++ .../source/divergent-crate-dir-names/src/main.rs | 3 + .../source/workspaces/path-dep-above/e/Cargo.toml | 6 + .../source/workspaces/path-dep-above/e/src/main.rs | 1 + .../source/workspaces/path-dep-above/ws/Cargo.toml | 5 + .../workspaces/path-dep-above/ws/a/Cargo.toml | 6 + .../workspaces/path-dep-above/ws/a/d/Cargo.toml | 7 ++ .../workspaces/path-dep-above/ws/a/d/f/Cargo.toml | 4 + .../workspaces/path-dep-above/ws/a/d/f/src/lib.rs | 1 + .../workspaces/path-dep-above/ws/a/d/src/lib.rs | 1 + .../workspaces/path-dep-above/ws/a/src/main.rs | 1 + .../workspaces/path-dep-above/ws/b/Cargo.toml | 6 + .../workspaces/path-dep-above/ws/b/src/main.rs | 1 + .../workspaces/path-dep-above/ws/c/Cargo.toml | 4 + .../workspaces/path-dep-above/ws/c/src/lib.rs | 1 + 23 files changed, 443 insertions(+) create mode 100644 src/cargo-fmt/test/message_format.rs create mode 100644 src/cargo-fmt/test/mod.rs create mode 100644 src/cargo-fmt/test/targets.rs create mode 100644 tests/cargo-fmt/source/divergent-crate-dir-names/Cargo.toml create mode 100644 tests/cargo-fmt/source/divergent-crate-dir-names/dependency-dir-name/Cargo.toml create mode 100644 tests/cargo-fmt/source/divergent-crate-dir-names/dependency-dir-name/src/lib.rs create mode 100644 tests/cargo-fmt/source/divergent-crate-dir-names/dependency-dir-name/subdep-dir-name/Cargo.toml create mode 100644 tests/cargo-fmt/source/divergent-crate-dir-names/dependency-dir-name/subdep-dir-name/src/lib.rs create mode 100644 tests/cargo-fmt/source/divergent-crate-dir-names/src/main.rs create mode 100644 tests/cargo-fmt/source/workspaces/path-dep-above/e/Cargo.toml create mode 100644 tests/cargo-fmt/source/workspaces/path-dep-above/e/src/main.rs create mode 100644 tests/cargo-fmt/source/workspaces/path-dep-above/ws/Cargo.toml create mode 100644 tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/Cargo.toml create mode 100644 tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/d/Cargo.toml create mode 100644 tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/d/f/Cargo.toml create mode 100644 tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/d/f/src/lib.rs create mode 100644 tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/d/src/lib.rs create mode 100644 tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/src/main.rs create mode 100644 tests/cargo-fmt/source/workspaces/path-dep-above/ws/b/Cargo.toml create mode 100644 tests/cargo-fmt/source/workspaces/path-dep-above/ws/b/src/main.rs create mode 100644 tests/cargo-fmt/source/workspaces/path-dep-above/ws/c/Cargo.toml create mode 100644 tests/cargo-fmt/source/workspaces/path-dep-above/ws/c/src/lib.rs (limited to 'src') diff --git a/.gitignore b/.gitignore index 37adf8751ca..71cf88f79e6 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ # Generated by Cargo # will have compiled files and executables /target +tests/cargo-fmt/**/target # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries # More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock diff --git a/src/cargo-fmt/test/message_format.rs b/src/cargo-fmt/test/message_format.rs new file mode 100644 index 00000000000..bf44924f13c --- /dev/null +++ b/src/cargo-fmt/test/message_format.rs @@ -0,0 +1,80 @@ +use super::*; + +#[test] +fn invalid_message_format() { + assert_eq!( + convert_message_format_to_rustfmt_args("awesome", &mut vec![]), + Err(String::from( + "invalid --message-format value: awesome. Allowed values are: short|json|human" + )), + ); +} + +#[test] +fn json_message_format_and_check_arg() { + let mut args = vec![String::from("--check")]; + assert_eq!( + convert_message_format_to_rustfmt_args("json", &mut args), + Err(String::from( + "cannot include --check arg when --message-format is set to json" + )), + ); +} + +#[test] +fn json_message_format_and_emit_arg() { + let mut args = vec![String::from("--emit"), String::from("checkstyle")]; + assert_eq!( + convert_message_format_to_rustfmt_args("json", &mut args), + Err(String::from( + "cannot include --emit arg when --message-format is set to json" + )), + ); +} + +#[test] +fn json_message_format() { + let mut args = vec![String::from("--edition"), String::from("2018")]; + assert!(convert_message_format_to_rustfmt_args("json", &mut args).is_ok()); + assert_eq!( + args, + vec![ + String::from("--edition"), + String::from("2018"), + String::from("--emit"), + String::from("json") + ] + ); +} + +#[test] +fn human_message_format() { + let exp_args = vec![String::from("--emit"), String::from("json")]; + let mut act_args = exp_args.clone(); + assert!(convert_message_format_to_rustfmt_args("human", &mut act_args).is_ok()); + assert_eq!(act_args, exp_args); +} + +#[test] +fn short_message_format() { + let mut args = vec![String::from("--check")]; + assert!(convert_message_format_to_rustfmt_args("short", &mut args).is_ok()); + assert_eq!(args, vec![String::from("--check"), String::from("-l")]); +} + +#[test] +fn short_message_format_included_short_list_files_flag() { + let mut args = vec![String::from("--check"), String::from("-l")]; + assert!(convert_message_format_to_rustfmt_args("short", &mut args).is_ok()); + assert_eq!(args, vec![String::from("--check"), String::from("-l")]); +} + +#[test] +fn short_message_format_included_long_list_files_flag() { + let mut args = vec![String::from("--check"), String::from("--files-with-diff")]; + assert!(convert_message_format_to_rustfmt_args("short", &mut args).is_ok()); + assert_eq!( + args, + vec![String::from("--check"), String::from("--files-with-diff")] + ); +} diff --git a/src/cargo-fmt/test/mod.rs b/src/cargo-fmt/test/mod.rs new file mode 100644 index 00000000000..360503632c7 --- /dev/null +++ b/src/cargo-fmt/test/mod.rs @@ -0,0 +1,137 @@ +use super::*; + +mod message_format; +mod targets; + +#[test] +fn default_options() { + let empty: Vec = vec![]; + let o = Opts::from_iter(&empty); + assert_eq!(false, o.quiet); + assert_eq!(false, o.verbose); + assert_eq!(false, o.version); + assert_eq!(false, o.check); + assert_eq!(empty, o.packages); + assert_eq!(empty, o.rustfmt_options); + assert_eq!(false, o.format_all); + assert_eq!(None, o.manifest_path); + assert_eq!(None, o.message_format); +} + +#[test] +fn good_options() { + let o = Opts::from_iter(&[ + "test", + "-q", + "-p", + "p1", + "-p", + "p2", + "--message-format", + "short", + "--check", + "--", + "--edition", + "2018", + ]); + assert_eq!(true, o.quiet); + assert_eq!(false, o.verbose); + assert_eq!(false, o.version); + assert_eq!(true, o.check); + assert_eq!(vec!["p1", "p2"], o.packages); + assert_eq!(vec!["--edition", "2018"], o.rustfmt_options); + assert_eq!(false, o.format_all); + assert_eq!(Some(String::from("short")), o.message_format); +} + +#[test] +fn unexpected_option() { + assert!( + Opts::clap() + .get_matches_from_safe(&["test", "unexpected"]) + .is_err() + ); +} + +#[test] +fn unexpected_flag() { + assert!( + Opts::clap() + .get_matches_from_safe(&["test", "--flag"]) + .is_err() + ); +} + +#[test] +fn mandatory_separator() { + assert!( + Opts::clap() + .get_matches_from_safe(&["test", "--emit"]) + .is_err() + ); + assert!( + !Opts::clap() + .get_matches_from_safe(&["test", "--", "--emit"]) + .is_err() + ); +} + +#[test] +fn multiple_packages_one_by_one() { + let o = Opts::from_iter(&[ + "test", + "-p", + "package1", + "--package", + "package2", + "-p", + "package3", + ]); + assert_eq!(3, o.packages.len()); +} + +#[test] +fn multiple_packages_grouped() { + let o = Opts::from_iter(&[ + "test", + "--package", + "package1", + "package2", + "-p", + "package3", + "package4", + ]); + assert_eq!(4, o.packages.len()); +} + +#[test] +fn empty_packages_1() { + assert!(Opts::clap().get_matches_from_safe(&["test", "-p"]).is_err()); +} + +#[test] +fn empty_packages_2() { + assert!( + Opts::clap() + .get_matches_from_safe(&["test", "-p", "--", "--check"]) + .is_err() + ); +} + +#[test] +fn empty_packages_3() { + assert!( + Opts::clap() + .get_matches_from_safe(&["test", "-p", "--verbose"]) + .is_err() + ); +} + +#[test] +fn empty_packages_4() { + assert!( + Opts::clap() + .get_matches_from_safe(&["test", "-p", "--check"]) + .is_err() + ); +} diff --git a/src/cargo-fmt/test/targets.rs b/src/cargo-fmt/test/targets.rs new file mode 100644 index 00000000000..b7e7fabdf71 --- /dev/null +++ b/src/cargo-fmt/test/targets.rs @@ -0,0 +1,134 @@ +use super::*; + +struct ExpTarget { + path: &'static str, + edition: &'static str, + kind: &'static str, +} + +mod all_targets { + use super::*; + + fn assert_correct_targets_loaded( + manifest_suffix: &str, + source_root: &str, + exp_targets: &[ExpTarget], + exp_num_targets: usize, + ) { + let root_path = Path::new("tests/cargo-fmt/source").join(source_root); + let get_path = |exp: &str| PathBuf::from(&root_path).join(exp).canonicalize().unwrap(); + let manifest_path = Path::new(&root_path).join(manifest_suffix); + let targets = get_targets(&CargoFmtStrategy::All, Some(manifest_path.as_path())) + .expect("Targets should have been loaded"); + + assert_eq!(targets.len(), exp_num_targets); + + for target in exp_targets { + assert!(targets.contains(&Target { + path: get_path(target.path), + edition: target.edition.to_owned(), + kind: target.kind.to_owned(), + })); + } + } + + mod different_crate_and_dir_names { + use super::*; + + fn assert_correct_targets_loaded(manifest_suffix: &str) { + let exp_targets = vec![ + ExpTarget { + path: "dependency-dir-name/subdep-dir-name/src/lib.rs", + edition: "2018", + kind: "lib", + }, + ExpTarget { + path: "dependency-dir-name/src/lib.rs", + edition: "2018", + kind: "lib", + }, + ExpTarget { + path: "src/main.rs", + edition: "2018", + kind: "main", + }, + ]; + super::assert_correct_targets_loaded( + manifest_suffix, + "divergent-crate-dir-names", + &exp_targets, + 3, + ); + } + + #[test] + fn correct_targets_from_root() { + assert_correct_targets_loaded("Cargo.toml"); + } + + #[test] + fn correct_targets_from_sub_local_dep() { + assert_correct_targets_loaded("dependency-dir-name/Cargo.toml"); + } + } + + mod workspaces { + use super::*; + + fn assert_correct_targets_loaded(manifest_suffix: &str) { + let exp_targets = vec![ + ExpTarget { + path: "ws/a/src/main.rs", + edition: "2018", + kind: "bin", + }, + ExpTarget { + path: "ws/b/src/main.rs", + edition: "2018", + kind: "bin", + }, + ExpTarget { + path: "ws/c/src/lib.rs", + edition: "2018", + kind: "lib", + }, + ExpTarget { + path: "ws/a/d/src/lib.rs", + edition: "2018", + kind: "lib", + }, + ExpTarget { + path: "e/src/main.rs", + edition: "2018", + kind: "main", + }, + ExpTarget { + path: "ws/a/d/f/src/lib.rs", + edition: "2018", + kind: "lib", + }, + ]; + super::assert_correct_targets_loaded( + manifest_suffix, + "workspaces/path-dep-above", + &exp_targets, + 6, + ); + } + + #[test] + fn includes_outside_workspace_deps() { + assert_correct_targets_loaded("ws/Cargo.toml"); + } + + #[test] + fn includes_workspace_from_dep_above() { + assert_correct_targets_loaded("e/Cargo.toml"); + } + + #[test] + fn includes_all_packages_from_workspace_subdir() { + assert_correct_targets_loaded("ws/a/d/f/Cargo.toml"); + } + } +} diff --git a/tests/cargo-fmt/source/divergent-crate-dir-names/Cargo.toml b/tests/cargo-fmt/source/divergent-crate-dir-names/Cargo.toml new file mode 100644 index 00000000000..315364a6457 --- /dev/null +++ b/tests/cargo-fmt/source/divergent-crate-dir-names/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "cargo-fmt-test" +version = "0.1.0" +authors = ["calebcartwright"] +edition = "2018" + +[dependencies] +indexmap = "1.0.2" + +[workspace] +members = [ + "dependency-dir-name", +] \ No newline at end of file diff --git a/tests/cargo-fmt/source/divergent-crate-dir-names/dependency-dir-name/Cargo.toml b/tests/cargo-fmt/source/divergent-crate-dir-names/dependency-dir-name/Cargo.toml new file mode 100644 index 00000000000..4493882bf40 --- /dev/null +++ b/tests/cargo-fmt/source/divergent-crate-dir-names/dependency-dir-name/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "dependency-crate-name" +version = "0.1.0" +authors = ["calebcartwright"] +edition = "2018" + +[dependencies] +subdep-crate-name = { path = "subdep-dir-name" } +indexmap = "1.0.2" +rusty-hook = "0.8.4" \ No newline at end of file diff --git a/tests/cargo-fmt/source/divergent-crate-dir-names/dependency-dir-name/src/lib.rs b/tests/cargo-fmt/source/divergent-crate-dir-names/dependency-dir-name/src/lib.rs new file mode 100644 index 00000000000..e93b18d725b --- /dev/null +++ b/tests/cargo-fmt/source/divergent-crate-dir-names/dependency-dir-name/src/lib.rs @@ -0,0 +1,7 @@ +#[cfg(test)] +mod tests { +#[test] +fn it_works() { + assert_eq!(2 + 2, 4); +} +} diff --git a/tests/cargo-fmt/source/divergent-crate-dir-names/dependency-dir-name/subdep-dir-name/Cargo.toml b/tests/cargo-fmt/source/divergent-crate-dir-names/dependency-dir-name/subdep-dir-name/Cargo.toml new file mode 100644 index 00000000000..7dad09f4077 --- /dev/null +++ b/tests/cargo-fmt/source/divergent-crate-dir-names/dependency-dir-name/subdep-dir-name/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "subdep-crate-name" +version = "0.1.0" +authors = ["calebcartwright"] +edition = "2018" + +[dependencies] diff --git a/tests/cargo-fmt/source/divergent-crate-dir-names/dependency-dir-name/subdep-dir-name/src/lib.rs b/tests/cargo-fmt/source/divergent-crate-dir-names/dependency-dir-name/subdep-dir-name/src/lib.rs new file mode 100644 index 00000000000..1c08c1c4fd3 --- /dev/null +++ b/tests/cargo-fmt/source/divergent-crate-dir-names/dependency-dir-name/subdep-dir-name/src/lib.rs @@ -0,0 +1,7 @@ +#[cfg(test)] +mod tests { +#[test] +fn sub_test_that_works() { + assert_eq!(3 + 3, 6); +} + } diff --git a/tests/cargo-fmt/source/divergent-crate-dir-names/src/main.rs b/tests/cargo-fmt/source/divergent-crate-dir-names/src/main.rs new file mode 100644 index 00000000000..f5c339a8dd1 --- /dev/null +++ b/tests/cargo-fmt/source/divergent-crate-dir-names/src/main.rs @@ -0,0 +1,3 @@ +fn main() { +println!("Hello, world!"); +} diff --git a/tests/cargo-fmt/source/workspaces/path-dep-above/e/Cargo.toml b/tests/cargo-fmt/source/workspaces/path-dep-above/e/Cargo.toml new file mode 100644 index 00000000000..df1886c82be --- /dev/null +++ b/tests/cargo-fmt/source/workspaces/path-dep-above/e/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "e" +version = "0.1.0" +edition = "2018" +[dependencies] +c = { path = "../ws/c" } diff --git a/tests/cargo-fmt/source/workspaces/path-dep-above/e/src/main.rs b/tests/cargo-fmt/source/workspaces/path-dep-above/e/src/main.rs new file mode 100644 index 00000000000..1c26a3895f3 --- /dev/null +++ b/tests/cargo-fmt/source/workspaces/path-dep-above/e/src/main.rs @@ -0,0 +1 @@ +struct E{ } diff --git a/tests/cargo-fmt/source/workspaces/path-dep-above/ws/Cargo.toml b/tests/cargo-fmt/source/workspaces/path-dep-above/ws/Cargo.toml new file mode 100644 index 00000000000..202739b613b --- /dev/null +++ b/tests/cargo-fmt/source/workspaces/path-dep-above/ws/Cargo.toml @@ -0,0 +1,5 @@ +[workspace] +members = [ + "a", + "b" +] \ No newline at end of file diff --git a/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/Cargo.toml b/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/Cargo.toml new file mode 100644 index 00000000000..712a113448f --- /dev/null +++ b/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "a" +version = "0.1.0" +edition = "2018" +[dependencies] +d = { path = "./d" } diff --git a/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/d/Cargo.toml b/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/d/Cargo.toml new file mode 100644 index 00000000000..fb0f06fe5fc --- /dev/null +++ b/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/d/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "d" +version = "0.1.0" +edition = "2018" +[dependencies] +e = { path = "../../../e" } +f = { path = "f" } diff --git a/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/d/f/Cargo.toml b/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/d/f/Cargo.toml new file mode 100644 index 00000000000..5c4fa561788 --- /dev/null +++ b/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/d/f/Cargo.toml @@ -0,0 +1,4 @@ +[package] +name = "f" +version = "0.1.0" +edition = "2018" diff --git a/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/d/f/src/lib.rs b/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/d/f/src/lib.rs new file mode 100644 index 00000000000..c655c4d5e1a --- /dev/null +++ b/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/d/f/src/lib.rs @@ -0,0 +1 @@ +struct F{ } \ No newline at end of file diff --git a/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/d/src/lib.rs b/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/d/src/lib.rs new file mode 100644 index 00000000000..04e6e4cb940 --- /dev/null +++ b/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/d/src/lib.rs @@ -0,0 +1 @@ +struct D{ } \ No newline at end of file diff --git a/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/src/main.rs b/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/src/main.rs new file mode 100644 index 00000000000..04e6e4cb940 --- /dev/null +++ b/tests/cargo-fmt/source/workspaces/path-dep-above/ws/a/src/main.rs @@ -0,0 +1 @@ +struct D{ } \ No newline at end of file diff --git a/tests/cargo-fmt/source/workspaces/path-dep-above/ws/b/Cargo.toml b/tests/cargo-fmt/source/workspaces/path-dep-above/ws/b/Cargo.toml new file mode 100644 index 00000000000..47a24ff4f27 --- /dev/null +++ b/tests/cargo-fmt/source/workspaces/path-dep-above/ws/b/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "b" +version = "0.1.0" +edition = "2018" +[dependencies] +c = { path = "../c" } diff --git a/tests/cargo-fmt/source/workspaces/path-dep-above/ws/b/src/main.rs b/tests/cargo-fmt/source/workspaces/path-dep-above/ws/b/src/main.rs new file mode 100644 index 00000000000..4833bbc69b4 --- /dev/null +++ b/tests/cargo-fmt/source/workspaces/path-dep-above/ws/b/src/main.rs @@ -0,0 +1 @@ +struct B{ } \ No newline at end of file diff --git a/tests/cargo-fmt/source/workspaces/path-dep-above/ws/c/Cargo.toml b/tests/cargo-fmt/source/workspaces/path-dep-above/ws/c/Cargo.toml new file mode 100644 index 00000000000..49fa6c395eb --- /dev/null +++ b/tests/cargo-fmt/source/workspaces/path-dep-above/ws/c/Cargo.toml @@ -0,0 +1,4 @@ +[package] +name = "c" +version = "0.1.0" +edition = "2018" diff --git a/tests/cargo-fmt/source/workspaces/path-dep-above/ws/c/src/lib.rs b/tests/cargo-fmt/source/workspaces/path-dep-above/ws/c/src/lib.rs new file mode 100644 index 00000000000..1245ac91d60 --- /dev/null +++ b/tests/cargo-fmt/source/workspaces/path-dep-above/ws/c/src/lib.rs @@ -0,0 +1 @@ +struct C{ } \ No newline at end of file -- cgit 1.4.1-3-g733a5 From 4b9d637f5846b92f2c17b98985c47dea795064d2 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Mon, 20 Sep 2021 19:09:16 -0500 Subject: refactor: simplify local dep lookups --- src/cargo-fmt/main.rs | 280 +++++--------------------------------------------- 1 file changed, 26 insertions(+), 254 deletions(-) (limited to 'src') diff --git a/src/cargo-fmt/main.rs b/src/cargo-fmt/main.rs index 147b19d7a48..1d423ac3491 100644 --- a/src/cargo-fmt/main.rs +++ b/src/cargo-fmt/main.rs @@ -17,6 +17,10 @@ use std::str; use structopt::StructOpt; +#[path = "test/mod.rs"] +#[cfg(test)] +mod cargo_fmt_tests; + #[derive(StructOpt, Debug)] #[structopt( bin_name = "cargo fmt", @@ -356,7 +360,7 @@ fn get_targets_root_only( manifest_path: Option<&Path>, targets: &mut BTreeSet, ) -> Result<(), io::Error> { - let metadata = get_cargo_metadata(manifest_path, false)?; + let metadata = get_cargo_metadata(manifest_path)?; let workspace_root_path = PathBuf::from(&metadata.workspace_root).canonicalize()?; let (in_workspace_root, current_dir_manifest) = if let Some(target_manifest) = manifest_path { ( @@ -400,34 +404,29 @@ fn get_targets_recursive( mut targets: &mut BTreeSet, visited: &mut BTreeSet, ) -> Result<(), io::Error> { - let metadata = get_cargo_metadata(manifest_path, false)?; - let metadata_with_deps = get_cargo_metadata(manifest_path, true)?; - - for package in metadata.packages { + let metadata = get_cargo_metadata(manifest_path)?; + for package in &metadata.packages { add_targets(&package.targets, &mut targets); - // Look for local dependencies. - for dependency in package.dependencies { - if dependency.source.is_some() || visited.contains(&dependency.name) { + // Look for local dependencies using information available since cargo v1.51 + // It's theoretically possible someone could use a newer version of rustfmt with + // a much older version of `cargo`, but we don't try to explicitly support that scenario. + // If someone reports an issue with path-based deps not being formatted, be sure to + // confirm their version of `cargo` (not `cargo-fmt`) is >= v1.51 + // https://github.com/rust-lang/cargo/pull/8994 + for dependency in &package.dependencies { + if dependency.path.is_none() || visited.contains(&dependency.name) { continue; } - let dependency_package = metadata_with_deps - .packages - .iter() - .find(|p| p.name == dependency.name && p.source.is_none()); - let manifest_path = if let Some(dep_pkg) = dependency_package { - PathBuf::from(&dep_pkg.manifest_path) - } else { - let mut package_manifest_path = PathBuf::from(&package.manifest_path); - package_manifest_path.pop(); - package_manifest_path.push(&dependency.name); - package_manifest_path.push("Cargo.toml"); - package_manifest_path - }; - - if manifest_path.exists() { - visited.insert(dependency.name); + let manifest_path = PathBuf::from(dependency.path.as_ref().unwrap()).join("Cargo.toml"); + if manifest_path.exists() + && !metadata + .packages + .iter() + .any(|p| p.manifest_path.eq(&manifest_path)) + { + visited.insert(dependency.name.to_owned()); get_targets_recursive(Some(&manifest_path), &mut targets, visited)?; } } @@ -441,8 +440,7 @@ fn get_targets_with_hitlist( hitlist: &[String], targets: &mut BTreeSet, ) -> Result<(), io::Error> { - let metadata = get_cargo_metadata(manifest_path, false)?; - + let metadata = get_cargo_metadata(manifest_path)?; let mut workspace_hitlist: BTreeSet<&String> = BTreeSet::from_iter(hitlist); for package in metadata.packages { @@ -527,14 +525,9 @@ fn run_rustfmt( .unwrap_or(SUCCESS)) } -fn get_cargo_metadata( - manifest_path: Option<&Path>, - include_deps: bool, -) -> Result { +fn get_cargo_metadata(manifest_path: Option<&Path>) -> Result { let mut cmd = cargo_metadata::MetadataCommand::new(); - if !include_deps { - cmd.no_deps(); - } + cmd.no_deps(); if let Some(manifest_path) = manifest_path { cmd.manifest_path(manifest_path); } @@ -551,224 +544,3 @@ fn get_cargo_metadata( } } } - -#[cfg(test)] -mod cargo_fmt_tests { - use super::*; - - #[test] - fn default_options() { - let empty: Vec = vec![]; - let o = Opts::from_iter(&empty); - assert_eq!(false, o.quiet); - assert_eq!(false, o.verbose); - assert_eq!(false, o.version); - assert_eq!(false, o.check); - assert_eq!(empty, o.packages); - assert_eq!(empty, o.rustfmt_options); - assert_eq!(false, o.format_all); - assert_eq!(None, o.manifest_path); - assert_eq!(None, o.message_format); - } - - #[test] - fn good_options() { - let o = Opts::from_iter(&[ - "test", - "-q", - "-p", - "p1", - "-p", - "p2", - "--message-format", - "short", - "--check", - "--", - "--edition", - "2018", - ]); - assert_eq!(true, o.quiet); - assert_eq!(false, o.verbose); - assert_eq!(false, o.version); - assert_eq!(true, o.check); - assert_eq!(vec!["p1", "p2"], o.packages); - assert_eq!(vec!["--edition", "2018"], o.rustfmt_options); - assert_eq!(false, o.format_all); - assert_eq!(Some(String::from("short")), o.message_format); - } - - #[test] - fn unexpected_option() { - assert!( - Opts::clap() - .get_matches_from_safe(&["test", "unexpected"]) - .is_err() - ); - } - - #[test] - fn unexpected_flag() { - assert!( - Opts::clap() - .get_matches_from_safe(&["test", "--flag"]) - .is_err() - ); - } - - #[test] - fn mandatory_separator() { - assert!( - Opts::clap() - .get_matches_from_safe(&["test", "--emit"]) - .is_err() - ); - assert!( - !Opts::clap() - .get_matches_from_safe(&["test", "--", "--emit"]) - .is_err() - ); - } - - #[test] - fn multiple_packages_one_by_one() { - let o = Opts::from_iter(&[ - "test", - "-p", - "package1", - "--package", - "package2", - "-p", - "package3", - ]); - assert_eq!(3, o.packages.len()); - } - - #[test] - fn multiple_packages_grouped() { - let o = Opts::from_iter(&[ - "test", - "--package", - "package1", - "package2", - "-p", - "package3", - "package4", - ]); - assert_eq!(4, o.packages.len()); - } - - #[test] - fn empty_packages_1() { - assert!(Opts::clap().get_matches_from_safe(&["test", "-p"]).is_err()); - } - - #[test] - fn empty_packages_2() { - assert!( - Opts::clap() - .get_matches_from_safe(&["test", "-p", "--", "--check"]) - .is_err() - ); - } - - #[test] - fn empty_packages_3() { - assert!( - Opts::clap() - .get_matches_from_safe(&["test", "-p", "--verbose"]) - .is_err() - ); - } - - #[test] - fn empty_packages_4() { - assert!( - Opts::clap() - .get_matches_from_safe(&["test", "-p", "--check"]) - .is_err() - ); - } - - mod convert_message_format_to_rustfmt_args_tests { - use super::*; - - #[test] - fn invalid_message_format() { - assert_eq!( - convert_message_format_to_rustfmt_args("awesome", &mut vec![]), - Err(String::from( - "invalid --message-format value: awesome. Allowed values are: short|json|human" - )), - ); - } - - #[test] - fn json_message_format_and_check_arg() { - let mut args = vec![String::from("--check")]; - assert_eq!( - convert_message_format_to_rustfmt_args("json", &mut args), - Err(String::from( - "cannot include --check arg when --message-format is set to json" - )), - ); - } - - #[test] - fn json_message_format_and_emit_arg() { - let mut args = vec![String::from("--emit"), String::from("checkstyle")]; - assert_eq!( - convert_message_format_to_rustfmt_args("json", &mut args), - Err(String::from( - "cannot include --emit arg when --message-format is set to json" - )), - ); - } - - #[test] - fn json_message_format() { - let mut args = vec![String::from("--edition"), String::from("2018")]; - assert!(convert_message_format_to_rustfmt_args("json", &mut args).is_ok()); - assert_eq!( - args, - vec![ - String::from("--edition"), - String::from("2018"), - String::from("--emit"), - String::from("json") - ] - ); - } - - #[test] - fn human_message_format() { - let exp_args = vec![String::from("--emit"), String::from("json")]; - let mut act_args = exp_args.clone(); - assert!(convert_message_format_to_rustfmt_args("human", &mut act_args).is_ok()); - assert_eq!(act_args, exp_args); - } - - #[test] - fn short_message_format() { - let mut args = vec![String::from("--check")]; - assert!(convert_message_format_to_rustfmt_args("short", &mut args).is_ok()); - assert_eq!(args, vec![String::from("--check"), String::from("-l")]); - } - - #[test] - fn short_message_format_included_short_list_files_flag() { - let mut args = vec![String::from("--check"), String::from("-l")]; - assert!(convert_message_format_to_rustfmt_args("short", &mut args).is_ok()); - assert_eq!(args, vec![String::from("--check"), String::from("-l")]); - } - - #[test] - fn short_message_format_included_long_list_files_flag() { - let mut args = vec![String::from("--check"), String::from("--files-with-diff")]; - assert!(convert_message_format_to_rustfmt_args("short", &mut args).is_ok()); - assert_eq!( - args, - vec![String::from("--check"), String::from("--files-with-diff")] - ); - } - } -} -- cgit 1.4.1-3-g733a5 From a5138b34d5f2644d916e906a3d460856a1b1a42a Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Mon, 27 Sep 2021 16:55:23 -0400 Subject: Prevent removal of qualified path for tuple struct inside macro fixes 5005 This was very similar to 4964 and the fix was to extract and pass along the qself of the ``PatKind::TupleStruct`` --- src/patterns.rs | 5 +++-- tests/target/issue-5005/minimum_example.rs | 9 +++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 tests/target/issue-5005/minimum_example.rs (limited to 'src') diff --git a/src/patterns.rs b/src/patterns.rs index 0c6a6f3e814..4c6a2d5d75b 100644 --- a/src/patterns.rs +++ b/src/patterns.rs @@ -226,8 +226,9 @@ impl Rewrite for Pat { PatKind::Path(ref q_self, ref path) => { rewrite_path(context, PathContext::Expr, q_self.as_ref(), path, shape) } - PatKind::TupleStruct(_, ref path, ref pat_vec) => { - let path_str = rewrite_path(context, PathContext::Expr, None, path, shape)?; + PatKind::TupleStruct(ref q_self, ref path, ref pat_vec) => { + let path_str = + rewrite_path(context, PathContext::Expr, q_self.as_ref(), path, shape)?; rewrite_tuple_pat(pat_vec, Some(path_str), self.span, context, shape) } PatKind::Lit(ref expr) => expr.rewrite(context, shape), diff --git a/tests/target/issue-5005/minimum_example.rs b/tests/target/issue-5005/minimum_example.rs new file mode 100644 index 00000000000..11cc645fa53 --- /dev/null +++ b/tests/target/issue-5005/minimum_example.rs @@ -0,0 +1,9 @@ +#![feature(more_qualified_paths)] +macro_rules! show { + ($ty:ty, $ex:expr) => { + match $ex { + <$ty>::A(_val) => println!("got a"), // formatting should not remove <$ty>:: + <$ty>::B => println!("got b"), + } + }; +} -- cgit 1.4.1-3-g733a5 From f0f449d6edda5a40057fc82ea02cc9abeae4d012 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Fri, 17 Sep 2021 18:56:30 -0700 Subject: Wrap long array and slice patterns. Closes #4530. --- src/overflow.rs | 4 +++- src/patterns.rs | 12 +++++++++++- tests/source/issue-4530.rs | 4 ++++ tests/target/issue-4530.rs | 9 +++++++++ 4 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 tests/source/issue-4530.rs create mode 100644 tests/target/issue-4530.rs (limited to 'src') diff --git a/src/overflow.rs b/src/overflow.rs index e32213467a5..ac24181c780 100644 --- a/src/overflow.rs +++ b/src/overflow.rs @@ -77,6 +77,7 @@ pub(crate) enum OverflowableItem<'a> { FieldDef(&'a ast::FieldDef), TuplePatField(&'a TuplePatField<'a>), Ty(&'a ast::Ty), + Pat(&'a ast::Pat), } impl<'a> Rewrite for OverflowableItem<'a> { @@ -116,6 +117,7 @@ impl<'a> OverflowableItem<'a> { OverflowableItem::FieldDef(sf) => f(*sf), OverflowableItem::TuplePatField(pat) => f(*pat), OverflowableItem::Ty(ty) => f(*ty), + OverflowableItem::Pat(pat) => f(*pat), } } @@ -232,7 +234,7 @@ macro_rules! impl_into_overflowable_item_for_rustfmt_types { } } -impl_into_overflowable_item_for_ast_node!(Expr, GenericParam, NestedMetaItem, FieldDef, Ty); +impl_into_overflowable_item_for_ast_node!(Expr, GenericParam, NestedMetaItem, FieldDef, Ty, Pat); impl_into_overflowable_item_for_rustfmt_types!([MacroArg], [SegmentParam, TuplePatField]); pub(crate) fn into_overflowable_list<'a, T>( diff --git a/src/patterns.rs b/src/patterns.rs index 4c6a2d5d75b..34987b1d59e 100644 --- a/src/patterns.rs +++ b/src/patterns.rs @@ -4,6 +4,7 @@ use rustc_span::{BytePos, Span}; use crate::comment::{combine_strs_with_missing_comments, FindUncommented}; use crate::config::lists::*; +use crate::config::Version; use crate::expr::{can_be_overflowed_expr, rewrite_unary_prefix, wrap_struct_field}; use crate::lists::{ definitive_tactic, itemize_list, shape_for_tactic, struct_lit_formatting, struct_lit_shape, @@ -232,7 +233,7 @@ impl Rewrite for Pat { rewrite_tuple_pat(pat_vec, Some(path_str), self.span, context, shape) } PatKind::Lit(ref expr) => expr.rewrite(context, shape), - PatKind::Slice(ref slice_pat) => { + PatKind::Slice(ref slice_pat) if context.config.version() == Version::One => { let rw: Vec = slice_pat .iter() .map(|p| { @@ -245,6 +246,15 @@ impl Rewrite for Pat { .collect(); Some(format!("[{}]", rw.join(", "))) } + PatKind::Slice(ref slice_pat) => overflow::rewrite_with_square_brackets( + context, + "", + slice_pat.iter(), + shape, + self.span, + None, + None, + ), PatKind::Struct(ref qself, ref path, ref fields, ellipsis) => { rewrite_struct_pat(qself, path, fields, ellipsis, self.span, context, shape) } diff --git a/tests/source/issue-4530.rs b/tests/source/issue-4530.rs new file mode 100644 index 00000000000..9d2882abb3c --- /dev/null +++ b/tests/source/issue-4530.rs @@ -0,0 +1,4 @@ +// rustfmt-version: Two +fn main() { + let [aaaaaaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, cccccccccccccccccccccccccc, ddddddddddddddddddddddddd] = panic!(); +} diff --git a/tests/target/issue-4530.rs b/tests/target/issue-4530.rs new file mode 100644 index 00000000000..296dc559a93 --- /dev/null +++ b/tests/target/issue-4530.rs @@ -0,0 +1,9 @@ +// rustfmt-version: Two +fn main() { + let [ + aaaaaaaaaaaaaaaaaaaaaaaaaa, + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, + cccccccccccccccccccccccccc, + ddddddddddddddddddddddddd, + ] = panic!(); +} -- cgit 1.4.1-3-g733a5 From 40f4993c67ff54e413da17496769407ab85f3924 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Thu, 23 Sep 2021 22:43:03 -0400 Subject: Update derive attibute span to start after opening '(' Fixes 4984 When parsing derive attributes we're only concerned about the traits and comments listed between the opening and closing parentheses. Derive attribute spans currently start at the '#'. Span starts here | v #[derive(...)] After this update the derive spans start after the opening '('. Span starts here | V #[derive(...)] --- src/attr.rs | 5 ++++- tests/source/issue-4984/minimum_example.rs | 2 ++ tests/source/issue-4984/multi_line_derive.rs | 20 ++++++++++++++++++++ tests/target/issue-4984/minimum_example.rs | 2 ++ tests/target/issue-4984/multi_line_derive.rs | 26 ++++++++++++++++++++++++++ 5 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 tests/source/issue-4984/minimum_example.rs create mode 100644 tests/source/issue-4984/multi_line_derive.rs create mode 100644 tests/target/issue-4984/minimum_example.rs create mode 100644 tests/target/issue-4984/multi_line_derive.rs (limited to 'src') diff --git a/src/attr.rs b/src/attr.rs index 315eb10a9db..a5982820e3d 100644 --- a/src/attr.rs +++ b/src/attr.rs @@ -13,6 +13,7 @@ use crate::lists::{definitive_tactic, itemize_list, write_list, ListFormatting, use crate::overflow; use crate::rewrite::{Rewrite, RewriteContext}; use crate::shape::Shape; +use crate::source_map::SpanUtils; use crate::types::{rewrite_path, PathContext}; use crate::utils::{count_newlines, mk_sp}; @@ -116,7 +117,9 @@ fn format_derive( |span| span.lo(), |span| span.hi(), |span| Some(context.snippet(*span).to_owned()), - attr.span.lo(), + // We update derive attribute spans to start after the opening '(' + // This helps us focus parsing to just what's inside #[derive(...)] + context.snippet_provider.span_after(attr.span, "("), attr.span.hi(), false, ); diff --git a/tests/source/issue-4984/minimum_example.rs b/tests/source/issue-4984/minimum_example.rs new file mode 100644 index 00000000000..677f8737716 --- /dev/null +++ b/tests/source/issue-4984/minimum_example.rs @@ -0,0 +1,2 @@ +#[derive(/*Debug, */Clone)] +struct Foo; diff --git a/tests/source/issue-4984/multi_line_derive.rs b/tests/source/issue-4984/multi_line_derive.rs new file mode 100644 index 00000000000..73921dd1735 --- /dev/null +++ b/tests/source/issue-4984/multi_line_derive.rs @@ -0,0 +1,20 @@ +#[derive( +/* ---------- Some really important comment that just had to go inside the derive --------- */ +Debug, Clone, Eq, PartialEq, +)] +struct Foo { + a: i32, + b: T, +} + +#[derive( +/* + Some really important comment that just had to go inside the derive. + Also had to be put over multiple lines +*/ +Debug, Clone, Eq, PartialEq, +)] +struct Bar { + a: i32, + b: T, +} diff --git a/tests/target/issue-4984/minimum_example.rs b/tests/target/issue-4984/minimum_example.rs new file mode 100644 index 00000000000..f0599c5d694 --- /dev/null +++ b/tests/target/issue-4984/minimum_example.rs @@ -0,0 +1,2 @@ +#[derive(/*Debug, */ Clone)] +struct Foo; diff --git a/tests/target/issue-4984/multi_line_derive.rs b/tests/target/issue-4984/multi_line_derive.rs new file mode 100644 index 00000000000..5fbd9784adc --- /dev/null +++ b/tests/target/issue-4984/multi_line_derive.rs @@ -0,0 +1,26 @@ +#[derive( + /* ---------- Some really important comment that just had to go inside the derive --------- */ + Debug, + Clone, + Eq, + PartialEq, +)] +struct Foo { + a: i32, + b: T, +} + +#[derive( + /* + Some really important comment that just had to go inside the derive. + Also had to be put over multiple lines + */ + Debug, + Clone, + Eq, + PartialEq, +)] +struct Bar { + a: i32, + b: T, +} -- cgit 1.4.1-3-g733a5 From 8b58cce673d6ae4fbc1f3a8d28859bc100a72ed8 Mon Sep 17 00:00:00 2001 From: Emilio Cobos Álvarez Date: Sat, 16 May 2020 22:20:51 +0200 Subject: Stabilize match_block_trailing_comma. (#4145) Servo has used this since forever, and it'd be useful to be able to use rustfmt stable there so that we can use the same rustfmt version in both Firefox and Servo. Feel free to close this if there's any reason it shouldn't be done. --- Configurations.md | 2 +- src/config/mod.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/Configurations.md b/Configurations.md index ff83f02f87b..06db897a42e 100644 --- a/Configurations.md +++ b/Configurations.md @@ -1626,7 +1626,7 @@ Put a trailing comma after a block based match arm (non-block arms are not affec - **Default value**: `false` - **Possible values**: `true`, `false` -- **Stable**: No (tracking issue: #3380) +- **Stable**: Yes #### `false` (default): diff --git a/src/config/mod.rs b/src/config/mod.rs index c6cee8ed227..398a1814d8d 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -127,7 +127,7 @@ create_config! { "Add trailing semicolon after break, continue and return"; trailing_comma: SeparatorTactic, SeparatorTactic::Vertical, false, "How to handle trailing commas for lists"; - match_block_trailing_comma: bool, false, false, + match_block_trailing_comma: bool, false, true, "Put a trailing comma after a block based match arm (non-block arms are not affected)"; blank_lines_upper_bound: usize, 1, false, "Maximum number of blank lines which can be put between items"; -- cgit 1.4.1-3-g733a5 From d41805704d4a07ac77e0bc59ea5c91cdb69dea26 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Mon, 11 Oct 2021 18:30:35 -0400 Subject: Prevent structs with ".." from being rewritten with alignment rustfmt should only support rewriting a struct in an expression position with alignment (non-default behavior) when there is no rest (with or without a base) and all of the fields are non-shorthand. --- src/expr.rs | 11 ++--- tests/source/issue-4926/deeply_nested_struct.rs | 35 ++++++++++++++ .../deeply_nested_struct_with_long_field_names.rs | 43 +++++++++++++++++ .../deeply_nested_struct_with_many_fields.rs | 44 ++++++++++++++++++ tests/source/issue-4926/enum_struct_field.rs | 35 ++++++++++++++ tests/source/issue-4926/minimum_example.rs | 10 ++++ .../issue-4926/struct_with_long_field_names.rs | 21 +++++++++ tests/source/issue-4926/struct_with_many_fields.rs | 21 +++++++++ tests/target/issue-4926/deeply_nested_struct.rs | 38 +++++++++++++++ .../deeply_nested_struct_with_long_field_names.rs | 44 ++++++++++++++++++ .../deeply_nested_struct_with_many_fields.rs | 54 ++++++++++++++++++++++ tests/target/issue-4926/enum_struct_field.rs | 41 ++++++++++++++++ tests/target/issue-4926/minimum_example.rs | 10 ++++ .../issue-4926/struct_with_long_field_names.rs | 24 ++++++++++ tests/target/issue-4926/struct_with_many_fields.rs | 34 ++++++++++++++ 15 files changed, 458 insertions(+), 7 deletions(-) create mode 100644 tests/source/issue-4926/deeply_nested_struct.rs create mode 100644 tests/source/issue-4926/deeply_nested_struct_with_long_field_names.rs create mode 100644 tests/source/issue-4926/deeply_nested_struct_with_many_fields.rs create mode 100644 tests/source/issue-4926/enum_struct_field.rs create mode 100644 tests/source/issue-4926/minimum_example.rs create mode 100644 tests/source/issue-4926/struct_with_long_field_names.rs create mode 100644 tests/source/issue-4926/struct_with_many_fields.rs create mode 100644 tests/target/issue-4926/deeply_nested_struct.rs create mode 100644 tests/target/issue-4926/deeply_nested_struct_with_long_field_names.rs create mode 100644 tests/target/issue-4926/deeply_nested_struct_with_many_fields.rs create mode 100644 tests/target/issue-4926/enum_struct_field.rs create mode 100644 tests/target/issue-4926/minimum_example.rs create mode 100644 tests/target/issue-4926/struct_with_long_field_names.rs create mode 100644 tests/target/issue-4926/struct_with_many_fields.rs (limited to 'src') diff --git a/src/expr.rs b/src/expr.rs index 01cc388c186..3a54426b0dd 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -1528,12 +1528,12 @@ fn rewrite_struct_lit<'a>( let path_shape = shape.sub_width(2)?; let path_str = rewrite_path(context, PathContext::Expr, None, path, path_shape)?; - let has_base = match struct_rest { + let has_base_or_rest = match struct_rest { ast::StructRest::None if fields.is_empty() => return Some(format!("{} {{}}", path_str)), ast::StructRest::Rest(_) if fields.is_empty() => { return Some(format!("{} {{ .. }}", path_str)); } - ast::StructRest::Base(_) => true, + ast::StructRest::Rest(_) | ast::StructRest::Base(_) => true, _ => false, }; @@ -1542,7 +1542,7 @@ fn rewrite_struct_lit<'a>( let one_line_width = h_shape.map_or(0, |shape| shape.width); let body_lo = context.snippet_provider.span_after(span, "{"); - let fields_str = if struct_lit_can_be_aligned(fields, has_base) + let fields_str = if struct_lit_can_be_aligned(fields, has_base_or_rest) && context.config.struct_field_align_threshold() > 0 { rewrite_with_alignment( @@ -1614,10 +1614,7 @@ fn rewrite_struct_lit<'a>( nested_shape, tactic, context, - force_no_trailing_comma - || has_base - || !context.use_block_indent() - || matches!(struct_rest, ast::StructRest::Rest(_)), + force_no_trailing_comma || has_base_or_rest || !context.use_block_indent(), ); write_list(&item_vec, &fmt)? diff --git a/tests/source/issue-4926/deeply_nested_struct.rs b/tests/source/issue-4926/deeply_nested_struct.rs new file mode 100644 index 00000000000..e55e41bd1a5 --- /dev/null +++ b/tests/source/issue-4926/deeply_nested_struct.rs @@ -0,0 +1,35 @@ + +// rustfmt-struct_field_align_threshold: 30 + +struct X { + a: i32, + b: i32, + c: i32, +} + +fn test(x: X) { + let d = { + let e = { + let f = { + let g = { + let h = { + let i = { + let j = { + matches!( + x, + X { a: 1_000, b: 1_000, .. } + ) + }; + j + }; + i + }; + h + }; + g + }; + f + }; + e + }; +} \ No newline at end of file diff --git a/tests/source/issue-4926/deeply_nested_struct_with_long_field_names.rs b/tests/source/issue-4926/deeply_nested_struct_with_long_field_names.rs new file mode 100644 index 00000000000..516699fa2b8 --- /dev/null +++ b/tests/source/issue-4926/deeply_nested_struct_with_long_field_names.rs @@ -0,0 +1,43 @@ +// rustfmt-struct_field_align_threshold: 30 + +struct X { + really_really_long_field_a: i32, + really_really_really_long_field_b: i32, + really_really_really_really_long_field_c: i32, + really_really_really_really_really_long_field_d: i32, + really_really_really_really_really_really_long_field_e: i32, + f: i32, +} + +fn test(x: X) { + let d = { + let e = { + let f = { + let g = { + let h = { + let i = { + let j = { + matches!( + x, + X { + really_really_long_field_a: 10, + really_really_really_long_field_b: 10, + really_really_really_really_long_field_c: 10, + really_really_really_really_really_long_field_d: 10, + really_really_really_really_really_really_long_field_e: 10, .. + } + ) + }; + j + }; + i + }; + h + }; + g + }; + f + }; + e + }; +} diff --git a/tests/source/issue-4926/deeply_nested_struct_with_many_fields.rs b/tests/source/issue-4926/deeply_nested_struct_with_many_fields.rs new file mode 100644 index 00000000000..38fd6f02cf0 --- /dev/null +++ b/tests/source/issue-4926/deeply_nested_struct_with_many_fields.rs @@ -0,0 +1,44 @@ +// rustfmt-struct_field_align_threshold: 30 + +struct X { + a: i32, + b: i32, + c: i32, + d: i32, + e: i32, + f: i32, + g: i32, + h: i32, + i: i32, + j: i32, + k: i32, +} + +fn test(x: X) { + let d = { + let e = { + let f = { + let g = { + let h = { + let i = { + let j = { + matches!( + x, + X { + a: 1_000, b: 1_000, c: 1_000, d: 1_000, e: 1_000, f: 1_000, g: 1_000, h: 1_000, i: 1_000, j: 1_000, .. + } + ) + }; + j + }; + i + }; + h + }; + g + }; + f + }; + e + }; +} diff --git a/tests/source/issue-4926/enum_struct_field.rs b/tests/source/issue-4926/enum_struct_field.rs new file mode 100644 index 00000000000..336378537df --- /dev/null +++ b/tests/source/issue-4926/enum_struct_field.rs @@ -0,0 +1,35 @@ +// rustfmt-struct_field_align_threshold: 30 +// rustfmt-enum_discrim_align_threshold: 30 +// rustfmt-imports_layout: HorizontalVertical + +#[derive(Default)] +struct InnerStructA { bbbbbbbbb: i32, cccccccc: i32 } + +enum SomeEnumNamedD { + E(InnerStructA), + F { + ggggggggggggggggggggggggg: bool, + h: bool, + } +} + +impl SomeEnumNamedD { + fn f_variant() -> Self { + Self::F { ggggggggggggggggggggggggg: true, h: true } + } +} + +fn main() { + let kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk = SomeEnumNamedD::f_variant(); + let something_we_care_about = matches!( + kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk, + SomeEnumNamedD::F { + ggggggggggggggggggggggggg: true, + .. + } + ); + + if something_we_care_about { + println!("Yup it happened"); + } +} diff --git a/tests/source/issue-4926/minimum_example.rs b/tests/source/issue-4926/minimum_example.rs new file mode 100644 index 00000000000..2c3045dea48 --- /dev/null +++ b/tests/source/issue-4926/minimum_example.rs @@ -0,0 +1,10 @@ +// rustfmt-struct_field_align_threshold: 30 + +struct X { a: i32, b: i32 } + +fn test(x: X) { + let y = matches!(x, X { + a: 1, + .. + }); +} diff --git a/tests/source/issue-4926/struct_with_long_field_names.rs b/tests/source/issue-4926/struct_with_long_field_names.rs new file mode 100644 index 00000000000..b8a37f0714e --- /dev/null +++ b/tests/source/issue-4926/struct_with_long_field_names.rs @@ -0,0 +1,21 @@ +// rustfmt-struct_field_align_threshold: 30 + +struct X { + really_really_long_field_a: i32, + really_really_really_long_field_b: i32, + really_really_really_really_long_field_c: i32, + really_really_really_really_really_long_field_d: i32, + really_really_really_really_really_really_long_field_e: i32, + f: i32, +} + +fn test(x: X) { + let y = matches!(x, X { + really_really_long_field_a: 10, + really_really_really_long_field_b: 10, + really_really_really_really_long_field_c: 10, + really_really_really_really_really_long_field_d: 10, + really_really_really_really_really_really_long_field_e: 10, + .. + }); +} diff --git a/tests/source/issue-4926/struct_with_many_fields.rs b/tests/source/issue-4926/struct_with_many_fields.rs new file mode 100644 index 00000000000..4adfd3b3062 --- /dev/null +++ b/tests/source/issue-4926/struct_with_many_fields.rs @@ -0,0 +1,21 @@ +// rustfmt-struct_field_align_threshold: 30 + +struct X { + a: i32, + b: i32, + c: i32, + d: i32, + e: i32, + f: i32, + g: i32, + h: i32, + i: i32, + j: i32, + k: i32, +} + +fn test(x: X) { + let y = matches!(x, X { + a: 1_000, b: 1_000, c: 1_000, d: 1_000, e: 1_000, f: 1_000, g: 1_000, h: 1_000, i: 1_000, j: 1_000, .. + }); +} \ No newline at end of file diff --git a/tests/target/issue-4926/deeply_nested_struct.rs b/tests/target/issue-4926/deeply_nested_struct.rs new file mode 100644 index 00000000000..072cf2f6674 --- /dev/null +++ b/tests/target/issue-4926/deeply_nested_struct.rs @@ -0,0 +1,38 @@ +// rustfmt-struct_field_align_threshold: 30 + +struct X { + a: i32, + b: i32, + c: i32, +} + +fn test(x: X) { + let d = { + let e = { + let f = { + let g = { + let h = { + let i = { + let j = { + matches!( + x, + X { + a: 1_000, + b: 1_000, + .. + } + ) + }; + j + }; + i + }; + h + }; + g + }; + f + }; + e + }; +} diff --git a/tests/target/issue-4926/deeply_nested_struct_with_long_field_names.rs b/tests/target/issue-4926/deeply_nested_struct_with_long_field_names.rs new file mode 100644 index 00000000000..c7bc7f7296d --- /dev/null +++ b/tests/target/issue-4926/deeply_nested_struct_with_long_field_names.rs @@ -0,0 +1,44 @@ +// rustfmt-struct_field_align_threshold: 30 + +struct X { + really_really_long_field_a: i32, + really_really_really_long_field_b: i32, + really_really_really_really_long_field_c: i32, + really_really_really_really_really_long_field_d: i32, + really_really_really_really_really_really_long_field_e: i32, + f: i32, +} + +fn test(x: X) { + let d = { + let e = { + let f = { + let g = { + let h = { + let i = { + let j = { + matches!( + x, + X { + really_really_long_field_a: 10, + really_really_really_long_field_b: 10, + really_really_really_really_long_field_c: 10, + really_really_really_really_really_long_field_d: 10, + really_really_really_really_really_really_long_field_e: 10, + .. + } + ) + }; + j + }; + i + }; + h + }; + g + }; + f + }; + e + }; +} diff --git a/tests/target/issue-4926/deeply_nested_struct_with_many_fields.rs b/tests/target/issue-4926/deeply_nested_struct_with_many_fields.rs new file mode 100644 index 00000000000..69793162519 --- /dev/null +++ b/tests/target/issue-4926/deeply_nested_struct_with_many_fields.rs @@ -0,0 +1,54 @@ +// rustfmt-struct_field_align_threshold: 30 + +struct X { + a: i32, + b: i32, + c: i32, + d: i32, + e: i32, + f: i32, + g: i32, + h: i32, + i: i32, + j: i32, + k: i32, +} + +fn test(x: X) { + let d = { + let e = { + let f = { + let g = { + let h = { + let i = { + let j = { + matches!( + x, + X { + a: 1_000, + b: 1_000, + c: 1_000, + d: 1_000, + e: 1_000, + f: 1_000, + g: 1_000, + h: 1_000, + i: 1_000, + j: 1_000, + .. + } + ) + }; + j + }; + i + }; + h + }; + g + }; + f + }; + e + }; +} diff --git a/tests/target/issue-4926/enum_struct_field.rs b/tests/target/issue-4926/enum_struct_field.rs new file mode 100644 index 00000000000..2471df84653 --- /dev/null +++ b/tests/target/issue-4926/enum_struct_field.rs @@ -0,0 +1,41 @@ +// rustfmt-struct_field_align_threshold: 30 +// rustfmt-enum_discrim_align_threshold: 30 +// rustfmt-imports_layout: HorizontalVertical + +#[derive(Default)] +struct InnerStructA { + bbbbbbbbb: i32, + cccccccc: i32, +} + +enum SomeEnumNamedD { + E(InnerStructA), + F { + ggggggggggggggggggggggggg: bool, + h: bool, + }, +} + +impl SomeEnumNamedD { + fn f_variant() -> Self { + Self::F { + ggggggggggggggggggggggggg: true, + h: true, + } + } +} + +fn main() { + let kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk = SomeEnumNamedD::f_variant(); + let something_we_care_about = matches!( + kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk, + SomeEnumNamedD::F { + ggggggggggggggggggggggggg: true, + .. + } + ); + + if something_we_care_about { + println!("Yup it happened"); + } +} diff --git a/tests/target/issue-4926/minimum_example.rs b/tests/target/issue-4926/minimum_example.rs new file mode 100644 index 00000000000..06e18427465 --- /dev/null +++ b/tests/target/issue-4926/minimum_example.rs @@ -0,0 +1,10 @@ +// rustfmt-struct_field_align_threshold: 30 + +struct X { + a: i32, + b: i32, +} + +fn test(x: X) { + let y = matches!(x, X { a: 1, .. }); +} diff --git a/tests/target/issue-4926/struct_with_long_field_names.rs b/tests/target/issue-4926/struct_with_long_field_names.rs new file mode 100644 index 00000000000..ac4674ab5d5 --- /dev/null +++ b/tests/target/issue-4926/struct_with_long_field_names.rs @@ -0,0 +1,24 @@ +// rustfmt-struct_field_align_threshold: 30 + +struct X { + really_really_long_field_a: i32, + really_really_really_long_field_b: i32, + really_really_really_really_long_field_c: i32, + really_really_really_really_really_long_field_d: i32, + really_really_really_really_really_really_long_field_e: i32, + f: i32, +} + +fn test(x: X) { + let y = matches!( + x, + X { + really_really_long_field_a: 10, + really_really_really_long_field_b: 10, + really_really_really_really_long_field_c: 10, + really_really_really_really_really_long_field_d: 10, + really_really_really_really_really_really_long_field_e: 10, + .. + } + ); +} diff --git a/tests/target/issue-4926/struct_with_many_fields.rs b/tests/target/issue-4926/struct_with_many_fields.rs new file mode 100644 index 00000000000..96dfe14bf7d --- /dev/null +++ b/tests/target/issue-4926/struct_with_many_fields.rs @@ -0,0 +1,34 @@ +// rustfmt-struct_field_align_threshold: 30 + +struct X { + a: i32, + b: i32, + c: i32, + d: i32, + e: i32, + f: i32, + g: i32, + h: i32, + i: i32, + j: i32, + k: i32, +} + +fn test(x: X) { + let y = matches!( + x, + X { + a: 1_000, + b: 1_000, + c: 1_000, + d: 1_000, + e: 1_000, + f: 1_000, + g: 1_000, + h: 1_000, + i: 1_000, + j: 1_000, + .. + } + ); +} -- cgit 1.4.1-3-g733a5 From f7c4a44149b4e3a683f5506929050f2b50117328 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Tue, 5 Oct 2021 01:24:10 -0400 Subject: Adjust non-empty tuple struct span to start before fields Resolves 5011 Tuple structs with visibility modifiers and comments before the first field were incorrectly formatted. Comments would duplicate part of the visibility modifier and struct name. When trying to parse the tuple fields the ``items::Context`` searches for the opening '(', but because the visibility modifier introduces another '(' -- for example ``pub(crate)`` -- the parsing gets messed up. Now the span is adjusted to start after the struct identifier, or after any generics. Adjusting the span in this way ensures that the ``items::Contex`` will correctly find the tuple fields. --- src/items.rs | 7 ++++++- tests/source/issue-5011.rs | 12 ++++++++++++ tests/target/issue-5011.rs | 8 ++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 tests/source/issue-5011.rs create mode 100644 tests/target/issue-5011.rs (limited to 'src') diff --git a/src/items.rs b/src/items.rs index e8eb1c5dfbb..471a365e470 100644 --- a/src/items.rs +++ b/src/items.rs @@ -1469,12 +1469,17 @@ fn format_tuple_struct( format_empty_struct_or_tuple(context, inner_span, offset, &mut result, "(", ")"); } else { let shape = Shape::indented(offset, context.config).sub_width(1)?; + let lo = if let Some(generics) = struct_parts.generics { + generics.span.hi() + } else { + struct_parts.ident.span.hi() + }; result = overflow::rewrite_with_parens( context, &result, fields.iter(), shape, - span, + mk_sp(lo, span.hi()), context.config.fn_call_width(), None, )?; diff --git a/tests/source/issue-5011.rs b/tests/source/issue-5011.rs new file mode 100644 index 00000000000..b48292164e4 --- /dev/null +++ b/tests/source/issue-5011.rs @@ -0,0 +1,12 @@ +pub(crate) struct ASlash( + // hello + i32 +); + +pub(crate) struct AStar( + /* hello */ + i32 +); + +pub(crate) struct BStar(/* hello */ i32); + diff --git a/tests/target/issue-5011.rs b/tests/target/issue-5011.rs new file mode 100644 index 00000000000..9ad4a1929bd --- /dev/null +++ b/tests/target/issue-5011.rs @@ -0,0 +1,8 @@ +pub(crate) struct ASlash( + // hello + i32, +); + +pub(crate) struct AStar(/* hello */ i32); + +pub(crate) struct BStar(/* hello */ i32); -- cgit 1.4.1-3-g733a5 From f2fb3c9659e072d7df6315906f1adbd06c3bc9e3 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Wed, 6 Oct 2021 13:09:24 -0400 Subject: Update connector search in ControlFlow::rewrite_pat_expr for for loops Resolves 5009 For loops represented by a ControlFlow object use " in" as their connector. rustfmt searches for the first uncommented occurrence of the word "in" within the current span and adjusts it's starting point to look for comments right after that. visually this looks like this: rustfmt starts looking for comments here | V for x in /* ... */ 0..1 {} This works well in most cases, however when the pattern also contains the word "in", this leads to issues. rustfmt starts looking for comments here | V for in_here in /* ... */ 0..1 {} ------- pattern In order to correctly identify the connector, the new approach first updates the span to start after the pattern and then searches for the first uncommented occurrence of "in". --- src/expr.rs | 2 +- tests/target/issue-5009/1_minimum_example.rs | 4 +++ .../issue-5009/2_many_in_connectors_in_pattern.rs | 3 ++ .../3_nested_for_loop_with_connector_in_pattern.rs | 5 ++++ .../4_nested_for_loop_with_if_elseif_else.rs | 13 +++++++++ ...ed_for_loop_with_connector_in_if_elseif_else.rs | 15 ++++++++++ ...ly_nested_for_loop_with_connector_in_pattern.rs | 32 ++++++++++++++++++++++ 7 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 tests/target/issue-5009/1_minimum_example.rs create mode 100644 tests/target/issue-5009/2_many_in_connectors_in_pattern.rs create mode 100644 tests/target/issue-5009/3_nested_for_loop_with_connector_in_pattern.rs create mode 100644 tests/target/issue-5009/4_nested_for_loop_with_if_elseif_else.rs create mode 100644 tests/target/issue-5009/5_nested_for_loop_with_connector_in_if_elseif_else.rs create mode 100644 tests/target/issue-5009/6_deeply_nested_for_loop_with_connector_in_pattern.rs (limited to 'src') diff --git a/src/expr.rs b/src/expr.rs index 3a54426b0dd..f40f80e4253 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -822,7 +822,7 @@ impl<'a> ControlFlow<'a> { let pat_string = pat.rewrite(context, pat_shape)?; let comments_lo = context .snippet_provider - .span_after(self.span, self.connector.trim()); + .span_after(self.span.with_lo(pat.span.hi()), self.connector.trim()); let comments_span = mk_sp(comments_lo, expr.span.lo()); return rewrite_assign_rhs_with_comments( context, diff --git a/tests/target/issue-5009/1_minimum_example.rs b/tests/target/issue-5009/1_minimum_example.rs new file mode 100644 index 00000000000..55836f4bf52 --- /dev/null +++ b/tests/target/issue-5009/1_minimum_example.rs @@ -0,0 +1,4 @@ +fn main() { + // the "in" inside the pattern produced invalid syntax + for variable_in_here /* ... */ in 0..1 {} +} diff --git a/tests/target/issue-5009/2_many_in_connectors_in_pattern.rs b/tests/target/issue-5009/2_many_in_connectors_in_pattern.rs new file mode 100644 index 00000000000..d83590c6852 --- /dev/null +++ b/tests/target/issue-5009/2_many_in_connectors_in_pattern.rs @@ -0,0 +1,3 @@ +fn main() { + for in_in_in_in_in_in_in_in /* ... */ in 0..1 {} +} diff --git a/tests/target/issue-5009/3_nested_for_loop_with_connector_in_pattern.rs b/tests/target/issue-5009/3_nested_for_loop_with_connector_in_pattern.rs new file mode 100644 index 00000000000..9c800723939 --- /dev/null +++ b/tests/target/issue-5009/3_nested_for_loop_with_connector_in_pattern.rs @@ -0,0 +1,5 @@ +fn main() { + for variable_in_x /* ... */ in 0..1 { + for variable_in_y /* ... */ in 0..1 {} + } +} diff --git a/tests/target/issue-5009/4_nested_for_loop_with_if_elseif_else.rs b/tests/target/issue-5009/4_nested_for_loop_with_if_elseif_else.rs new file mode 100644 index 00000000000..a716d0d3082 --- /dev/null +++ b/tests/target/issue-5009/4_nested_for_loop_with_if_elseif_else.rs @@ -0,0 +1,13 @@ +fn main() { + for variable_in_x /* ... */ in 0..1 { + for variable_in_y /* ... */ in 0..1 { + if false { + + } else if false { + + } else { + + } + } + } +} diff --git a/tests/target/issue-5009/5_nested_for_loop_with_connector_in_if_elseif_else.rs b/tests/target/issue-5009/5_nested_for_loop_with_connector_in_if_elseif_else.rs new file mode 100644 index 00000000000..41ea46d4cb9 --- /dev/null +++ b/tests/target/issue-5009/5_nested_for_loop_with_connector_in_if_elseif_else.rs @@ -0,0 +1,15 @@ +fn main() { + let in_ = false; + + for variable_in_x /* ... */ in 0..1 { + for variable_in_y /* ... */ in 0..1 { + if in_ { + + } else if in_ { + + } else { + + } + } + } +} diff --git a/tests/target/issue-5009/6_deeply_nested_for_loop_with_connector_in_pattern.rs b/tests/target/issue-5009/6_deeply_nested_for_loop_with_connector_in_pattern.rs new file mode 100644 index 00000000000..789e54f7e5f --- /dev/null +++ b/tests/target/issue-5009/6_deeply_nested_for_loop_with_connector_in_pattern.rs @@ -0,0 +1,32 @@ +fn main() { + for variable_in_a /* ... */ in 0..1 { + for variable_in_b /* ... */ in 0..1 { + for variable_in_c /* ... */ in 0..1 { + for variable_in_d /* ... */ in 0..1 { + for variable_in_e /* ... */ in 0..1 { + for variable_in_f /* ... */ in 0..1 { + for variable_in_g /* ... */ in 0..1 { + for variable_in_h /* ... */ in 0..1 { + for variable_in_i /* ... */ in 0..1 { + for variable_in_j /* ... */ in 0..1 { + for variable_in_k /* ... */ in 0..1 { + for variable_in_l /* ... */ in 0..1 { + for variable_in_m /* ... */ in 0..1 { + for variable_in_n /* ... */ in 0..1 { + for variable_in_o /* ... */ in 0..1 { + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } +} -- cgit 1.4.1-3-g733a5 From c9c1932be3299b40eab63106deeb5d5ad2283b61 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Wed, 13 Oct 2021 21:22:34 -0500 Subject: feat: stabilize disable_all_formatting --- Configurations.md | 6 ++++-- src/config/mod.rs | 2 +- src/test/mod.rs | 5 ----- 3 files changed, 5 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/Configurations.md b/Configurations.md index 06db897a42e..7a77dbe154b 100644 --- a/Configurations.md +++ b/Configurations.md @@ -521,11 +521,13 @@ fn main() { ## `disable_all_formatting` -Don't reformat anything +Don't reformat anything. + +Note that this option may be soft-deprecated in the future once the [ignore](#ignore) option is stabilized. Nightly toolchain users are encouraged to use [ignore](#ignore) instead when possible. - **Default value**: `false` - **Possible values**: `true`, `false` -- **Stable**: No (tracking issue: #3388) +- **Stable**: Yes ## `edition` diff --git a/src/config/mod.rs b/src/config/mod.rs index 398a1814d8d..c5419d860c9 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -155,7 +155,7 @@ create_config! { "Require a specific version of rustfmt"; unstable_features: bool, false, false, "Enables unstable features. Only available on nightly channel"; - disable_all_formatting: bool, false, false, "Don't reformat anything"; + disable_all_formatting: bool, false, true, "Don't reformat anything"; skip_children: bool, false, false, "Don't reformat out of line modules"; hide_parse_errors: bool, false, false, "Hide errors from the parser"; error_on_line_overflow: bool, false, false, "Error if unable to get all lines within max_width"; diff --git a/src/test/mod.rs b/src/test/mod.rs index ece1b91bfd7..48d61289a9b 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -469,11 +469,6 @@ fn stdin_works_with_modified_lines() { #[test] fn stdin_disable_all_formatting_test() { init_log(); - match option_env!("CFG_RELEASE_CHANNEL") { - None | Some("nightly") => {} - // These tests require nightly. - _ => return, - } let input = String::from("fn main() { println!(\"This should not be formatted.\"); }"); let mut child = Command::new(rustfmt().to_str().unwrap()) .stdin(Stdio::piped()) -- cgit 1.4.1-3-g733a5 From 5f4811ed7bc600e0cbe40c962e8933adb9baaddf Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Thu, 14 Oct 2021 17:16:28 -0400 Subject: Handle DefinitiveListTactic::SpecialMacro when writing pre-comments Resolves 4615 Previously only Vertical and Mixed enum variants of DefinitiveListTactic were considered when rewriting pre-comments for inner items in lists::write_list. Because we failed to considering the SpecialMacro variant we ended up in a scenario where a ListItem with a pre_comment and a pre_comment_style of ListItemCommentStyle::DifferentLine was written on the same line as the list item itself. Now we apply the same pre-comment formatting to SpecialMacro, Vertical, and Mixed variants of DefinitiveListTactic. --- src/lists.rs | 46 ++++++++++++++++-------------- tests/source/issue-4615/minimum_example.rs | 4 +++ tests/target/issue-4615/minimum_example.rs | 5 ++++ 3 files changed, 33 insertions(+), 22 deletions(-) create mode 100644 tests/source/issue-4615/minimum_example.rs create mode 100644 tests/target/issue-4615/minimum_example.rs (limited to 'src') diff --git a/src/lists.rs b/src/lists.rs index 73e886c5563..f0c2ae1499f 100644 --- a/src/lists.rs +++ b/src/lists.rs @@ -367,29 +367,31 @@ where result.push_str(&comment); if !inner_item.is_empty() { - if tactic == DefinitiveListTactic::Vertical || tactic == DefinitiveListTactic::Mixed - { - // We cannot keep pre-comments on the same line if the comment if normalized. - let keep_comment = if formatting.config.normalize_comments() - || item.pre_comment_style == ListItemCommentStyle::DifferentLine - { - false - } else { - // We will try to keep the comment on the same line with the item here. - // 1 = ` ` - let total_width = total_item_width(item) + item_sep_len + 1; - total_width <= formatting.shape.width - }; - if keep_comment { - result.push(' '); - } else { - result.push('\n'); - result.push_str(indent_str); - // This is the width of the item (without comments). - line_len = item.item.as_ref().map_or(0, |s| unicode_str_width(&s)); + match tactic { + DefinitiveListTactic::SpecialMacro(_) + | DefinitiveListTactic::Vertical + | DefinitiveListTactic::Mixed => { + // We cannot keep pre-comments on the same line if the comment is normalized + let keep_comment = if formatting.config.normalize_comments() + || item.pre_comment_style == ListItemCommentStyle::DifferentLine + { + false + } else { + // We will try to keep the comment on the same line with the item here. + // 1 = ` ` + let total_width = total_item_width(item) + item_sep_len + 1; + total_width <= formatting.shape.width + }; + if keep_comment { + result.push(' '); + } else { + result.push('\n'); + result.push_str(indent_str); + // This is the width of the item (without comments). + line_len = item.item.as_ref().map_or(0, |s| unicode_str_width(&s)); + } } - } else { - result.push(' '); + _ => result.push(' '), } } item_max_width = None; diff --git a/tests/source/issue-4615/minimum_example.rs b/tests/source/issue-4615/minimum_example.rs new file mode 100644 index 00000000000..89af5d1239d --- /dev/null +++ b/tests/source/issue-4615/minimum_example.rs @@ -0,0 +1,4 @@ +info!(//debug + "{}: sending function_code={:04x} data={:04x} crc=0x{:04X} data={:02X?}", + self.name, function_code, data, crc, output_cmd +); diff --git a/tests/target/issue-4615/minimum_example.rs b/tests/target/issue-4615/minimum_example.rs new file mode 100644 index 00000000000..223b89b812d --- /dev/null +++ b/tests/target/issue-4615/minimum_example.rs @@ -0,0 +1,5 @@ +info!( + //debug + "{}: sending function_code={:04x} data={:04x} crc=0x{:04X} data={:02X?}", + self.name, function_code, data, crc, output_cmd +); -- cgit 1.4.1-3-g733a5 From 1ae5c35f8d2a0d2ce5d914a479839dc0f3eb70f9 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Mon, 18 Oct 2021 20:48:58 -0400 Subject: Replace match expression with match! macro This is a follow up to 5f4811ed7bc600e0cbe40c962e8933adb9baaddf The matches! macro expresses the condition more succinctly and avoids the extra level of indentation introduced with the match arm body. --- src/lists.rs | 46 ++++++++++++++++++++++------------------------ 1 file changed, 22 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/lists.rs b/src/lists.rs index f0c2ae1499f..c04b4787616 100644 --- a/src/lists.rs +++ b/src/lists.rs @@ -367,31 +367,29 @@ where result.push_str(&comment); if !inner_item.is_empty() { - match tactic { - DefinitiveListTactic::SpecialMacro(_) - | DefinitiveListTactic::Vertical - | DefinitiveListTactic::Mixed => { - // We cannot keep pre-comments on the same line if the comment is normalized - let keep_comment = if formatting.config.normalize_comments() - || item.pre_comment_style == ListItemCommentStyle::DifferentLine - { - false - } else { - // We will try to keep the comment on the same line with the item here. - // 1 = ` ` - let total_width = total_item_width(item) + item_sep_len + 1; - total_width <= formatting.shape.width - }; - if keep_comment { - result.push(' '); - } else { - result.push('\n'); - result.push_str(indent_str); - // This is the width of the item (without comments). - line_len = item.item.as_ref().map_or(0, |s| unicode_str_width(&s)); - } + use DefinitiveListTactic::*; + if matches!(tactic, Vertical | Mixed | SpecialMacro(_)) { + // We cannot keep pre-comments on the same line if the comment is normalized. + let keep_comment = if formatting.config.normalize_comments() + || item.pre_comment_style == ListItemCommentStyle::DifferentLine + { + false + } else { + // We will try to keep the comment on the same line with the item here. + // 1 = ` ` + let total_width = total_item_width(item) + item_sep_len + 1; + total_width <= formatting.shape.width + }; + if keep_comment { + result.push(' '); + } else { + result.push('\n'); + result.push_str(indent_str); + // This is the width of the item (without comments). + line_len = item.item.as_ref().map_or(0, |s| unicode_str_width(&s)); } - _ => result.push(' '), + } else { + result.push(' ') } } item_max_width = None; -- cgit 1.4.1-3-g733a5 From 599b2fd9c47f913c6c3540b4805528d8bacd3d7e Mon Sep 17 00:00:00 2001 From: Martinez Date: Sat, 23 Oct 2021 19:01:48 +0300 Subject: Add One option to group_imports (#4966) * Add Together option to group_imports * Rename option to One * Rename files from Together to One --- Configurations.md | 19 ++++++++++++++++++- src/config/options.rs | 2 ++ src/reorder.rs | 4 +++- .../source/configs/group_imports/One-merge_imports.rs | 17 +++++++++++++++++ tests/source/configs/group_imports/One-nested.rs | 7 +++++++ tests/source/configs/group_imports/One-no_reorder.rs | 16 ++++++++++++++++ tests/source/configs/group_imports/One.rs | 15 +++++++++++++++ .../target/configs/group_imports/One-merge_imports.rs | 14 ++++++++++++++ tests/target/configs/group_imports/One-nested.rs | 6 ++++++ tests/target/configs/group_imports/One-no_reorder.rs | 12 ++++++++++++ tests/target/configs/group_imports/One.rs | 11 +++++++++++ 11 files changed, 121 insertions(+), 2 deletions(-) create mode 100644 tests/source/configs/group_imports/One-merge_imports.rs create mode 100644 tests/source/configs/group_imports/One-nested.rs create mode 100644 tests/source/configs/group_imports/One-no_reorder.rs create mode 100644 tests/source/configs/group_imports/One.rs create mode 100644 tests/target/configs/group_imports/One-merge_imports.rs create mode 100644 tests/target/configs/group_imports/One-nested.rs create mode 100644 tests/target/configs/group_imports/One-no_reorder.rs create mode 100644 tests/target/configs/group_imports/One.rs (limited to 'src') diff --git a/Configurations.md b/Configurations.md index 7a77dbe154b..13826883d2f 100644 --- a/Configurations.md +++ b/Configurations.md @@ -2062,7 +2062,7 @@ use sit; Controls the strategy for how imports are grouped together. - **Default value**: `Preserve` -- **Possible values**: `Preserve`, `StdExternalCrate` +- **Possible values**: `Preserve`, `StdExternalCrate`, `One` - **Stable**: No #### `Preserve` (default): @@ -2108,6 +2108,23 @@ use super::update::convert_publish_payload; use crate::models::Event; ``` +#### `One`: + +Discard existing import groups, and create a single group for everything + +```rust +use super::schema::{Context, Payload}; +use super::update::convert_publish_payload; +use crate::models::Event; +use alloc::alloc::Layout; +use broker::database::PooledConnection; +use chrono::Utc; +use core::f32; +use juniper::{FieldError, FieldResult}; +use std::sync::Arc; +use uuid::Uuid; +``` + ## `reorder_modules` Reorder `mod` declarations alphabetically in group. diff --git a/src/config/options.rs b/src/config/options.rs index e92f8e8a531..a17d48349c0 100644 --- a/src/config/options.rs +++ b/src/config/options.rs @@ -112,6 +112,8 @@ pub enum GroupImportsTactic { /// 2. other imports /// 3. `self` / `crate` / `super` imports StdExternalCrate, + /// Discard existing groups, and create a single group for everything + One, } #[config_type] diff --git a/src/reorder.rs b/src/reorder.rs index 2c58350d4fe..0732c8ee700 100644 --- a/src/reorder.rs +++ b/src/reorder.rs @@ -118,7 +118,9 @@ fn rewrite_reorderable_or_regroupable_items( }; let mut regrouped_items = match context.config.group_imports() { - GroupImportsTactic::Preserve => vec![normalized_items], + GroupImportsTactic::Preserve | GroupImportsTactic::One => { + vec![normalized_items] + } GroupImportsTactic::StdExternalCrate => group_imports(normalized_items), }; diff --git a/tests/source/configs/group_imports/One-merge_imports.rs b/tests/source/configs/group_imports/One-merge_imports.rs new file mode 100644 index 00000000000..157d3857908 --- /dev/null +++ b/tests/source/configs/group_imports/One-merge_imports.rs @@ -0,0 +1,17 @@ +// rustfmt-group_imports: One +// rustfmt-imports_granularity: Crate +use chrono::Utc; +use super::update::convert_publish_payload; + +use juniper::{FieldError, FieldResult}; +use uuid::Uuid; +use alloc::alloc::Layout; + +use std::sync::Arc; +use alloc::vec::Vec; + +use broker::database::PooledConnection; + +use super::schema::{Context, Payload}; +use core::f32; +use crate::models::Event; diff --git a/tests/source/configs/group_imports/One-nested.rs b/tests/source/configs/group_imports/One-nested.rs new file mode 100644 index 00000000000..109bd07e1ee --- /dev/null +++ b/tests/source/configs/group_imports/One-nested.rs @@ -0,0 +1,7 @@ +// rustfmt-group_imports: One +mod test { + use crate::foo::bar; + + use std::path; + use crate::foo::bar2; +} diff --git a/tests/source/configs/group_imports/One-no_reorder.rs b/tests/source/configs/group_imports/One-no_reorder.rs new file mode 100644 index 00000000000..f82f62c7f5b --- /dev/null +++ b/tests/source/configs/group_imports/One-no_reorder.rs @@ -0,0 +1,16 @@ +// rustfmt-group_imports: One +// rustfmt-reorder_imports: false +use chrono::Utc; +use super::update::convert_publish_payload; + +use juniper::{FieldError, FieldResult}; +use uuid::Uuid; +use alloc::alloc::Layout; + +use std::sync::Arc; + +use broker::database::PooledConnection; + +use super::schema::{Context, Payload}; +use core::f32; +use crate::models::Event; diff --git a/tests/source/configs/group_imports/One.rs b/tests/source/configs/group_imports/One.rs new file mode 100644 index 00000000000..5ab7a950805 --- /dev/null +++ b/tests/source/configs/group_imports/One.rs @@ -0,0 +1,15 @@ +// rustfmt-group_imports: One +use chrono::Utc; +use super::update::convert_publish_payload; + +use juniper::{FieldError, FieldResult}; +use uuid::Uuid; +use alloc::alloc::Layout; + +use std::sync::Arc; + +use broker::database::PooledConnection; + +use super::schema::{Context, Payload}; +use core::f32; +use crate::models::Event; diff --git a/tests/target/configs/group_imports/One-merge_imports.rs b/tests/target/configs/group_imports/One-merge_imports.rs new file mode 100644 index 00000000000..52e0e1c5ac2 --- /dev/null +++ b/tests/target/configs/group_imports/One-merge_imports.rs @@ -0,0 +1,14 @@ +// rustfmt-group_imports: One +// rustfmt-imports_granularity: Crate +use super::{ + schema::{Context, Payload}, + update::convert_publish_payload, +}; +use crate::models::Event; +use alloc::{alloc::Layout, vec::Vec}; +use broker::database::PooledConnection; +use chrono::Utc; +use core::f32; +use juniper::{FieldError, FieldResult}; +use std::sync::Arc; +use uuid::Uuid; diff --git a/tests/target/configs/group_imports/One-nested.rs b/tests/target/configs/group_imports/One-nested.rs new file mode 100644 index 00000000000..5b648548260 --- /dev/null +++ b/tests/target/configs/group_imports/One-nested.rs @@ -0,0 +1,6 @@ +// rustfmt-group_imports: One +mod test { + use crate::foo::bar; + use crate::foo::bar2; + use std::path; +} diff --git a/tests/target/configs/group_imports/One-no_reorder.rs b/tests/target/configs/group_imports/One-no_reorder.rs new file mode 100644 index 00000000000..015e841d014 --- /dev/null +++ b/tests/target/configs/group_imports/One-no_reorder.rs @@ -0,0 +1,12 @@ +// rustfmt-group_imports: One +// rustfmt-reorder_imports: false +use chrono::Utc; +use super::update::convert_publish_payload; +use juniper::{FieldError, FieldResult}; +use uuid::Uuid; +use alloc::alloc::Layout; +use std::sync::Arc; +use broker::database::PooledConnection; +use super::schema::{Context, Payload}; +use core::f32; +use crate::models::Event; diff --git a/tests/target/configs/group_imports/One.rs b/tests/target/configs/group_imports/One.rs new file mode 100644 index 00000000000..3094c7ae115 --- /dev/null +++ b/tests/target/configs/group_imports/One.rs @@ -0,0 +1,11 @@ +// rustfmt-group_imports: One +use super::schema::{Context, Payload}; +use super::update::convert_publish_payload; +use crate::models::Event; +use alloc::alloc::Layout; +use broker::database::PooledConnection; +use chrono::Utc; +use core::f32; +use juniper::{FieldError, FieldResult}; +use std::sync::Arc; +use uuid::Uuid; -- cgit 1.4.1-3-g733a5 From c493ee4828ab8e94ed175ec781afe7351bf89784 Mon Sep 17 00:00:00 2001 From: Matthias Krüger Date: Sat, 23 Oct 2021 23:07:57 +0200 Subject: fix clippy::needless_borrow --- src/attr.rs | 4 ++-- src/attr/doc_comment.rs | 2 +- src/cargo-fmt/main.rs | 6 +++--- src/chains.rs | 4 ++-- src/comment.rs | 14 +++++++------- src/emitter/checkstyle.rs | 4 ++-- src/emitter/diff.rs | 2 +- src/expr.rs | 12 ++++++------ src/formatting.rs | 4 ++-- src/imports.rs | 4 ++-- src/items.rs | 30 +++++++++++++++--------------- src/lib.rs | 4 ++-- src/lists.rs | 4 ++-- src/macros.rs | 16 ++++++++-------- src/matches.rs | 10 +++++----- src/modules.rs | 4 ++-- src/overflow.rs | 2 +- src/pairs.rs | 16 ++++++++-------- src/patterns.rs | 2 +- src/syntux/parser.rs | 2 +- src/syntux/session.rs | 2 +- src/test/mod.rs | 4 ++-- src/types.rs | 4 ++-- src/utils.rs | 6 +++--- src/visitor.rs | 20 ++++++++++---------- 25 files changed, 91 insertions(+), 91 deletions(-) (limited to 'src') diff --git a/src/attr.rs b/src/attr.rs index a5982820e3d..76b66e9da80 100644 --- a/src/attr.rs +++ b/src/attr.rs @@ -451,7 +451,7 @@ impl Rewrite for [ast::Attribute] { if next.is_doc_comment() { let snippet = context.snippet(missing_span); let (_, mlb) = has_newlines_before_after_comment(snippet); - result.push_str(&mlb); + result.push_str(mlb); } } result.push('\n'); @@ -484,7 +484,7 @@ impl Rewrite for [ast::Attribute] { if next.is_doc_comment() { let snippet = context.snippet(missing_span); let (_, mlb) = has_newlines_before_after_comment(snippet); - result.push_str(&mlb); + result.push_str(mlb); } } result.push('\n'); diff --git a/src/attr/doc_comment.rs b/src/attr/doc_comment.rs index c3dcb84c948..f653a12a8af 100644 --- a/src/attr/doc_comment.rs +++ b/src/attr/doc_comment.rs @@ -77,7 +77,7 @@ mod tests { ) { assert_eq!( expected_comment, - format!("{}", DocCommentFormatter::new(&literal, style)) + format!("{}", DocCommentFormatter::new(literal, style)) ); } } diff --git a/src/cargo-fmt/main.rs b/src/cargo-fmt/main.rs index 1d423ac3491..759b21218c3 100644 --- a/src/cargo-fmt/main.rs +++ b/src/cargo-fmt/main.rs @@ -401,12 +401,12 @@ fn get_targets_root_only( fn get_targets_recursive( manifest_path: Option<&Path>, - mut targets: &mut BTreeSet, + targets: &mut BTreeSet, visited: &mut BTreeSet, ) -> Result<(), io::Error> { let metadata = get_cargo_metadata(manifest_path)?; for package in &metadata.packages { - add_targets(&package.targets, &mut targets); + add_targets(&package.targets, targets); // Look for local dependencies using information available since cargo v1.51 // It's theoretically possible someone could use a newer version of rustfmt with @@ -427,7 +427,7 @@ fn get_targets_recursive( .any(|p| p.manifest_path.eq(&manifest_path)) { visited.insert(dependency.name.to_owned()); - get_targets_recursive(Some(&manifest_path), &mut targets, visited)?; + get_targets_recursive(Some(&manifest_path), targets, visited)?; } } } diff --git a/src/chains.rs b/src/chains.rs index 614638ea2ab..e26e24ec55a 100644 --- a/src/chains.rs +++ b/src/chains.rs @@ -568,7 +568,7 @@ impl<'a> ChainFormatterShared<'a> { } else { self.rewrites .iter() - .map(|rw| utils::unicode_str_width(&rw)) + .map(|rw| utils::unicode_str_width(rw)) .sum() } + last.tries; let one_line_budget = if self.child_count == 1 { @@ -673,7 +673,7 @@ impl<'a> ChainFormatterShared<'a> { ChainItemKind::Comment(_, CommentPosition::Top) => result.push_str(&connector), _ => result.push_str(&connector), } - result.push_str(&rewrite); + result.push_str(rewrite); } Some(result) diff --git a/src/comment.rs b/src/comment.rs index dc4f4516252..a3cd0359e6b 100644 --- a/src/comment.rs +++ b/src/comment.rs @@ -563,7 +563,7 @@ impl<'a> CommentRewrite<'a> { result.push_str(line); result.push_str(match iter.peek() { Some(next_line) if next_line.is_empty() => sep.trim_end(), - Some(..) => &sep, + Some(..) => sep, None => "", }); } @@ -622,7 +622,7 @@ impl<'a> CommentRewrite<'a> { let is_last = i == count_newlines(orig); if let Some(ref mut ib) = self.item_block { - if ib.add_line(&line) { + if ib.add_line(line) { return false; } self.is_prev_line_multi_line = false; @@ -684,8 +684,8 @@ impl<'a> CommentRewrite<'a> { self.item_block = None; if let Some(stripped) = line.strip_prefix("```") { self.code_block_attr = Some(CodeBlockAttribute::new(stripped)) - } else if self.fmt.config.wrap_comments() && ItemizedBlock::is_itemized_line(&line) { - let ib = ItemizedBlock::new(&line); + } else if self.fmt.config.wrap_comments() && ItemizedBlock::is_itemized_line(line) { + let ib = ItemizedBlock::new(line); self.item_block = Some(ib); return false; } @@ -941,7 +941,7 @@ fn left_trim_comment_line<'a>(line: &'a str, style: &CommentStyle<'_>) -> (&'a s { (&line[4..], true) } else if let CommentStyle::Custom(opener) = *style { - if let Some(ref stripped) = line.strip_prefix(opener) { + if let Some(stripped) = line.strip_prefix(opener) { (stripped, true) } else { (&line[opener.trim_end().len()..], false) @@ -1570,7 +1570,7 @@ pub(crate) fn recover_comment_removed( context.parse_sess.span_to_filename(span), vec![FormattingError::from_span( span, - &context.parse_sess, + context.parse_sess, ErrorKind::LostComment, )], ); @@ -1675,7 +1675,7 @@ impl<'a> Iterator for CommentReducer<'a> { fn remove_comment_header(comment: &str) -> &str { if comment.starts_with("///") || comment.starts_with("//!") { &comment[3..] - } else if let Some(ref stripped) = comment.strip_prefix("//") { + } else if let Some(stripped) = comment.strip_prefix("//") { stripped } else if (comment.starts_with("/**") && !comment.starts_with("/**/")) || comment.starts_with("/*!") diff --git a/src/emitter/checkstyle.rs b/src/emitter/checkstyle.rs index 4448214f3ff..76f2527db3d 100644 --- a/src/emitter/checkstyle.rs +++ b/src/emitter/checkstyle.rs @@ -121,7 +121,7 @@ mod tests { format!(r#""#, bin_file), format!( r#""#, - XmlEscaped(&r#" println!("Hello, world!");"#), + XmlEscaped(r#" println!("Hello, world!");"#), ), String::from(""), ]; @@ -129,7 +129,7 @@ mod tests { format!(r#""#, lib_file), format!( r#""#, - XmlEscaped(&r#" println!("Greetings!");"#), + XmlEscaped(r#" println!("Greetings!");"#), ), String::from(""), ]; diff --git a/src/emitter/diff.rs b/src/emitter/diff.rs index 2fbbfedb566..7264ad8bbf3 100644 --- a/src/emitter/diff.rs +++ b/src/emitter/diff.rs @@ -23,7 +23,7 @@ impl Emitter for DiffEmitter { }: FormattedFile<'_>, ) -> Result { const CONTEXT_SIZE: usize = 3; - let mismatch = make_diff(&original_text, formatted_text, CONTEXT_SIZE); + let mismatch = make_diff(original_text, formatted_text, CONTEXT_SIZE); let has_diff = !mismatch.is_empty(); if has_diff { diff --git a/src/expr.rs b/src/expr.rs index 7f1dd363f93..c67c14b1985 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -257,7 +257,7 @@ pub(crate) fn format_expr( } _ => false, }, - ast::ExprKind::Unary(_, ref expr) => needs_space_before_range(context, &expr), + ast::ExprKind::Unary(_, ref expr) => needs_space_before_range(context, expr), _ => false, } } @@ -423,7 +423,7 @@ fn rewrite_empty_block( prefix: &str, shape: Shape, ) -> Option { - if block_has_statements(&block) { + if block_has_statements(block) { return None; } @@ -1148,7 +1148,7 @@ pub(crate) fn is_empty_block( block: &ast::Block, attrs: Option<&[ast::Attribute]>, ) -> bool { - !block_has_statements(&block) + !block_has_statements(block) && !block_contains_comment(context, block) && attrs.map_or(true, |a| inner_attributes(a).is_empty()) } @@ -1621,7 +1621,7 @@ fn rewrite_struct_lit<'a>( }; let fields_str = - wrap_struct_field(context, &attrs, &fields_str, shape, v_shape, one_line_width)?; + wrap_struct_field(context, attrs, &fields_str, shape, v_shape, one_line_width)?; Some(format!("{} {{{}}}", path_str, fields_str)) // FIXME if context.config.indent_style() == Visual, but we run out @@ -1888,7 +1888,7 @@ pub(crate) fn rewrite_assign_rhs_expr( shape: Shape, rhs_tactics: RhsTactics, ) -> Option { - let last_line_width = last_line_width(&lhs).saturating_sub(if lhs.contains('\n') { + let last_line_width = last_line_width(lhs).saturating_sub(if lhs.contains('\n') { shape.indent.width() } else { 0 @@ -1947,7 +1947,7 @@ pub(crate) fn rewrite_assign_rhs_with_comments, R: Rewrite>( if contains_comment { let rhs = rhs.trim_start(); - combine_strs_with_missing_comments(context, &lhs, &rhs, between_span, shape, allow_extend) + combine_strs_with_missing_comments(context, &lhs, rhs, between_span, shape, allow_extend) } else { Some(lhs + &rhs) } diff --git a/src/formatting.rs b/src/formatting.rs index 9ef47b887ca..7d0facb8f12 100644 --- a/src/formatting.rs +++ b/src/formatting.rs @@ -155,7 +155,7 @@ impl<'a, T: FormatHandler + 'a> FormatContext<'a, T> { let snippet_provider = self.parse_session.snippet_provider(module.span); let mut visitor = FmtVisitor::from_parse_sess( &self.parse_session, - &self.config, + self.config, &snippet_provider, self.report.clone(), ); @@ -180,7 +180,7 @@ impl<'a, T: FormatHandler + 'a> FormatContext<'a, T> { &mut visitor.buffer, &path, &visitor.skipped_range.borrow(), - &self.config, + self.config, &self.report, ); diff --git a/src/imports.rs b/src/imports.rs index 5ac79936689..40e0d06f99d 100644 --- a/src/imports.rs +++ b/src/imports.rs @@ -275,7 +275,7 @@ impl UseTree { shape: Shape, ) -> Option { let vis = self.visibility.as_ref().map_or(Cow::from(""), |vis| { - crate::utils::format_visibility(context, &vis) + crate::utils::format_visibility(context, vis) }); let use_str = self .rewrite(context, shape.offset_left(vis.len())?) @@ -929,7 +929,7 @@ impl Rewrite for UseTree { fn rewrite(&self, context: &RewriteContext<'_>, mut shape: Shape) -> Option { let mut result = String::with_capacity(256); let mut iter = self.path.iter().peekable(); - while let Some(ref segment) = iter.next() { + while let Some(segment) = iter.next() { let segment_str = segment.rewrite(context, shape)?; result.push_str(&segment_str); if iter.peek().is_some() { diff --git a/src/items.rs b/src/items.rs index 1cb1a2701c3..1c7899b3ac3 100644 --- a/src/items.rs +++ b/src/items.rs @@ -226,7 +226,7 @@ impl<'a> FnSig<'a> { fn to_str(&self, context: &RewriteContext<'_>) -> String { let mut result = String::with_capacity(128); // Vis defaultness constness unsafety abi. - result.push_str(&*format_visibility(context, &self.visibility)); + result.push_str(&*format_visibility(context, self.visibility)); result.push_str(format_defaultness(self.defaultness)); result.push_str(format_constness(self.constness)); result.push_str(format_async(&self.is_async)); @@ -1220,7 +1220,7 @@ impl<'a> Rewrite for TraitAliasBounds<'a> { } else if fits_single_line { Cow::from(" ") } else { - shape.indent.to_string_with_newline(&context.config) + shape.indent.to_string_with_newline(context.config) }; Some(format!("{}{}{}", generic_bounds_str, space, where_str)) @@ -1238,7 +1238,7 @@ pub(crate) fn format_trait_alias( let alias = rewrite_ident(context, ident); // 6 = "trait ", 2 = " =" let g_shape = shape.offset_left(6)?.sub_width(2)?; - let generics_str = rewrite_generics(context, &alias, generics, g_shape)?; + let generics_str = rewrite_generics(context, alias, generics, g_shape)?; let vis_str = format_visibility(context, vis); let lhs = format!("{}trait {} =", vis_str, generics_str); // 1 = ";" @@ -1386,7 +1386,7 @@ fn format_empty_struct_or_tuple( closer: &str, ) { // 3 = " {}" or "();" - let used_width = last_line_used_width(&result, offset.width()) + 3; + let used_width = last_line_used_width(result, offset.width()) + 3; if used_width > context.config.max_width() { result.push_str(&offset.to_string_with_newline(context.config)) } @@ -2066,7 +2066,7 @@ fn rewrite_explicit_self( )?; Some(combine_strs_with_missing_comments( context, - ¶m_attrs, + param_attrs, &format!("&{} {}self", lifetime_str, mut_str), span, shape, @@ -2075,7 +2075,7 @@ fn rewrite_explicit_self( } None => Some(combine_strs_with_missing_comments( context, - ¶m_attrs, + param_attrs, &format!("&{}self", mut_str), span, shape, @@ -2091,7 +2091,7 @@ fn rewrite_explicit_self( Some(combine_strs_with_missing_comments( context, - ¶m_attrs, + param_attrs, &format!("{}self: {}", format_mutability(mutability), type_str), span, shape, @@ -2100,7 +2100,7 @@ fn rewrite_explicit_self( } ast::SelfKind::Value(mutability) => Some(combine_strs_with_missing_comments( context, - ¶m_attrs, + param_attrs, &format!("{}self", format_mutability(mutability)), span, shape, @@ -2226,7 +2226,7 @@ fn rewrite_fn_base( } // Skip `pub(crate)`. - let lo_after_visibility = get_bytepos_after_visibility(&fn_sig.visibility, span); + let lo_after_visibility = get_bytepos_after_visibility(fn_sig.visibility, span); // A conservative estimation, the goal is to be over all parens in generics let params_start = fn_sig .generics @@ -2984,7 +2984,7 @@ fn format_header( let mut result = String::with_capacity(128); let shape = Shape::indented(offset, context.config); - result.push_str(&format_visibility(context, vis).trim()); + result.push_str(format_visibility(context, vis).trim()); // Check for a missing comment between the visibility and the item name. let after_vis = vis.span.hi(); @@ -3005,7 +3005,7 @@ fn format_header( } } - result.push_str(&rewrite_ident(context, ident)); + result.push_str(rewrite_ident(context, ident)); result } @@ -3133,7 +3133,7 @@ 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, &fn_sig, &self.vis, Some(body)), + visit::FnKind::Fn(fn_ctxt, self.ident, fn_sig, &self.vis, Some(body)), generics, &fn_sig.decl, self.span, @@ -3146,7 +3146,7 @@ impl Rewrite for ast::ForeignItem { context, shape.indent, self.ident, - &FnSig::from_method_sig(&fn_sig, generics, &self.vis), + &FnSig::from_method_sig(fn_sig, generics, &self.vis), span, FnBraceStyle::None, ) @@ -3171,7 +3171,7 @@ impl Rewrite for ast::ForeignItem { let ast::TyAliasKind(_, ref generics, ref generic_bounds, ref type_default) = **ty_alias_kind; rewrite_type( - &context, + context, shape.indent, self.ident, &self.vis, @@ -3229,7 +3229,7 @@ fn rewrite_attrs( combine_strs_with_missing_comments( context, &attrs_str, - &item_str, + item_str, missed_span, shape, allow_extend, diff --git a/src/lib.rs b/src/lib.rs index 47a7b9d4dbe..792a1080f0e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -283,7 +283,7 @@ impl FormatReport { writeln!( t, "{}", - FormatReportFormatterBuilder::new(&self) + FormatReportFormatterBuilder::new(self) .enable_colors(true) .build() )?; @@ -297,7 +297,7 @@ impl FormatReport { impl fmt::Display for FormatReport { // Prints all the formatting errors. fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { - write!(fmt, "{}", FormatReportFormatterBuilder::new(&self).build())?; + write!(fmt, "{}", FormatReportFormatterBuilder::new(self).build())?; Ok(()) } } diff --git a/src/lists.rs b/src/lists.rs index c04b4787616..d341ec8e6b0 100644 --- a/src/lists.rs +++ b/src/lists.rs @@ -386,7 +386,7 @@ where result.push('\n'); result.push_str(indent_str); // This is the width of the item (without comments). - line_len = item.item.as_ref().map_or(0, |s| unicode_str_width(&s)); + line_len = item.item.as_ref().map_or(0, |s| unicode_str_width(s)); } } else { result.push(' ') @@ -820,7 +820,7 @@ where pub(crate) fn total_item_width(item: &ListItem) -> usize { comment_len(item.pre_comment.as_ref().map(|x| &(*x)[..])) + comment_len(item.post_comment.as_ref().map(|x| &(*x)[..])) - + item.item.as_ref().map_or(0, |s| unicode_str_width(&s)) + + item.item.as_ref().map_or(0, |s| unicode_str_width(s)) } fn comment_len(comment: Option<&str>) -> usize { diff --git a/src/macros.rs b/src/macros.rs index 927187dfd8a..ef747638e33 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -186,7 +186,7 @@ fn return_macro_parse_failure_fallback( }) .unwrap_or(false); if is_like_block_indent_style { - return trim_left_preserve_layout(context.snippet(span), indent, &context.config); + return trim_left_preserve_layout(context.snippet(span), indent, context.config); } context.skipped_range.borrow_mut().push(( @@ -437,7 +437,7 @@ fn rewrite_macro_inner( // the `macro_name!` and `{ /* macro_body */ }` but skip modifying // anything in between the braces (for now). let snippet = context.snippet(mac.span()).trim_start_matches(|c| c != '{'); - match trim_left_preserve_layout(snippet, shape.indent, &context.config) { + match trim_left_preserve_layout(snippet, shape.indent, context.config) { Some(macro_body) => Some(format!("{} {}", macro_name, macro_body)), None => Some(format!("{} {}", macro_name, snippet)), } @@ -901,7 +901,7 @@ impl MacroArgParser { break; } TokenTree::Token(ref t) => { - buffer.push_str(&pprust::token_to_string(&t)); + buffer.push_str(&pprust::token_to_string(t)); } _ => return None, } @@ -1045,7 +1045,7 @@ fn wrap_macro_args_inner( let mut iter = args.iter().peekable(); let indent_str = shape.indent.to_string_with_newline(context.config); - while let Some(ref arg) = iter.next() { + while let Some(arg) = iter.next() { result.push_str(&arg.rewrite(context, shape, use_multiple_lines)?); if use_multiple_lines @@ -1055,7 +1055,7 @@ fn wrap_macro_args_inner( result.pop(); } result.push_str(&indent_str); - } else if let Some(ref next_arg) = iter.peek() { + } else if let Some(next_arg) = iter.peek() { let space_before_dollar = !arg.kind.ends_with_space() && next_arg.kind.starts_with_dollar(); let space_before_brace = next_arg.kind.starts_with_brace(); @@ -1370,7 +1370,7 @@ impl MacroBranch { { s += &indent_str; } - (s + l + "\n", indent_next_line(kind, &l, &config)) + (s + l + "\n", indent_next_line(kind, l, &config)) }, ) .0; @@ -1514,11 +1514,11 @@ fn rewrite_macro_with_items( MacroArg::Item(item) => item, _ => return None, }; - visitor.visit_item(&item); + visitor.visit_item(item); } let mut result = String::with_capacity(256); - result.push_str(¯o_name); + result.push_str(macro_name); result.push_str(opener); result.push_str(&visitor.block_indent.to_string_with_newline(context.config)); result.push_str(visitor.buffer.trim()); diff --git a/src/matches.rs b/src/matches.rs index 5a6ed0ec06e..25b953ef425 100644 --- a/src/matches.rs +++ b/src/matches.rs @@ -319,7 +319,7 @@ fn flatten_arm_body<'a>( let can_extend = |expr| !context.config.force_multiline_blocks() && can_flatten_block_around_this(expr); - if let Some(ref block) = block_can_be_flattened(context, body) { + if let Some(block) = block_can_be_flattened(context, body) { if let ast::StmtKind::Expr(ref expr) = block.stmts[0].kind { if let ast::ExprKind::Block(..) = expr.kind { flatten_arm_body(context, expr, None) @@ -393,7 +393,7 @@ fn rewrite_match_body( if comment_str.is_empty() { String::new() } else { - rewrite_comment(comment_str, false, shape, &context.config)? + rewrite_comment(comment_str, false, shape, context.config)? } }; @@ -408,8 +408,8 @@ fn rewrite_match_body( result.push_str(&arrow_comment); } result.push_str(&nested_indent_str); - result.push_str(&body_str); - result.push_str(&comma); + result.push_str(body_str); + result.push_str(comma); return Some(result); } @@ -451,7 +451,7 @@ fn rewrite_match_body( result.push_str(&arrow_comment); } result.push_str(&block_sep); - result.push_str(&body_str); + result.push_str(body_str); result.push_str(&body_suffix); Some(result) }; diff --git a/src/modules.rs b/src/modules.rs index ded34d9032f..b0c1604a602 100644 --- a/src/modules.rs +++ b/src/modules.rs @@ -290,7 +290,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> { }; self.visit_sub_mod_after_directory_update(sub_mod, Some(directory)) } - SubModKind::Internal(ref item) => { + SubModKind::Internal(item) => { self.push_inline_mod_directory(item.ident, &item.attrs); self.visit_sub_mod_after_directory_update(sub_mod, None) } @@ -317,7 +317,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> { } match (sub_mod.ast_mod_kind, sub_mod.items) { (Some(Cow::Borrowed(ast::ModKind::Loaded(items, _, _))), _) => { - self.visit_mod_from_ast(&items) + self.visit_mod_from_ast(items) } (Some(Cow::Owned(..)), Cow::Owned(items)) => self.visit_mod_outside_ast(items), (_, _) => Ok(()), diff --git a/src/overflow.rs b/src/overflow.rs index ac24181c780..3475f5c378c 100644 --- a/src/overflow.rs +++ b/src/overflow.rs @@ -394,7 +394,7 @@ impl<'a> Context<'a> { ) -> Option { let last_item = self.last_item()?; let rewrite = match last_item { - OverflowableItem::Expr(ref expr) => { + OverflowableItem::Expr(expr) => { match expr.kind { // When overflowing the closure which consists of a single control flow // expression, force to use block if its condition uses multi line. diff --git a/src/pairs.rs b/src/pairs.rs index 0f3d5e8f878..d1c75126ea4 100644 --- a/src/pairs.rs +++ b/src/pairs.rs @@ -55,11 +55,11 @@ fn rewrite_pairs_one_line( for ((_, rewrite), s) in list.list.iter().zip(list.separators.iter()) { if let Some(rewrite) = rewrite { - if !is_single_line(&rewrite) || result.len() > shape.width { + if !is_single_line(rewrite) || result.len() > shape.width { return None; } - result.push_str(&rewrite); + result.push_str(rewrite); result.push(' '); result.push_str(s); result.push(' '); @@ -94,18 +94,18 @@ fn rewrite_pairs_multiline( shape: Shape, context: &RewriteContext<'_>, ) -> Option { - let rhs_offset = shape.rhs_overhead(&context.config); + let rhs_offset = shape.rhs_overhead(context.config); let nested_shape = (match context.config.indent_style() { IndentStyle::Visual => shape.visual_indent(0), IndentStyle::Block => shape.block_indent(context.config.tab_spaces()), }) - .with_max_width(&context.config) + .with_max_width(context.config) .sub_width(rhs_offset)?; let indent_str = nested_shape.indent.to_string_with_newline(context.config); let mut result = String::new(); - result.push_str(&list.list[0].1.as_ref()?); + result.push_str(list.list[0].1.as_ref()?); for ((e, default_rw), s) in list.list[1..].iter().zip(list.separators.iter()) { // The following test checks if we should keep two subexprs on the same @@ -144,7 +144,7 @@ fn rewrite_pairs_multiline( } } - result.push_str(&default_rw.as_ref()?); + result.push_str(default_rw.as_ref()?); } Some(result) } @@ -264,12 +264,12 @@ impl FlattenPair for ast::Expr { return node.rewrite(context, shape); } let nested_overhead = sep + 1; - let rhs_offset = shape.rhs_overhead(&context.config); + let rhs_offset = shape.rhs_overhead(context.config); let nested_shape = (match context.config.indent_style() { IndentStyle::Visual => shape.visual_indent(0), IndentStyle::Block => shape.block_indent(context.config.tab_spaces()), }) - .with_max_width(&context.config) + .with_max_width(context.config) .sub_width(rhs_offset)?; let default_shape = match context.config.binop_separator() { SeparatorPlace::Back => nested_shape.sub_width(nested_overhead)?, diff --git a/src/patterns.rs b/src/patterns.rs index ba8d8024a97..2676c647355 100644 --- a/src/patterns.rs +++ b/src/patterns.rs @@ -482,7 +482,7 @@ fn rewrite_tuple_pat( let path_str = path_str.unwrap_or_default(); overflow::rewrite_with_parens( - &context, + context, &path_str, pat_vec.iter(), shape, diff --git a/src/syntux/parser.rs b/src/syntux/parser.rs index b5fe4335dd3..14b92238cfa 100644 --- a/src/syntux/parser.rs +++ b/src/syntux/parser.rs @@ -112,7 +112,7 @@ impl<'a> Parser<'a> { span: Span, ) -> Result<(Vec, Vec>, Span), ParserError> { let result = catch_unwind(AssertUnwindSafe(|| { - let mut parser = new_parser_from_file(sess.inner(), &path, Some(span)); + let mut parser = new_parser_from_file(sess.inner(), path, Some(span)); match parser.parse_mod(&TokenKind::Eof) { Ok(result) => Some(result), Err(mut e) => { diff --git a/src/syntux/session.rs b/src/syntux/session.rs index 946c076d9f2..cdb4893d443 100644 --- a/src/syntux/session.rs +++ b/src/syntux/session.rs @@ -164,7 +164,7 @@ impl ParseSess { } pub(crate) fn ignore_file(&self, path: &FileName) -> bool { - self.ignore_path_set.as_ref().is_match(&path) + self.ignore_path_set.as_ref().is_match(path) } pub(crate) fn set_silent_emitter(&mut self) { diff --git a/src/test/mod.rs b/src/test/mod.rs index 48d61289a9b..e2620508c34 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -535,9 +535,9 @@ fn check_files(files: Vec, opt_config: &Option) -> (Vec { - print!("{}", FormatReportFormatterBuilder::new(&report).build()); + print!("{}", FormatReportFormatterBuilder::new(report).build()); fails += 1; } Ok(report) => reports.push(report), diff --git a/src/types.rs b/src/types.rs index 62c05ba078c..9ea90c5e46d 100644 --- a/src/types.rs +++ b/src/types.rs @@ -728,7 +728,7 @@ impl Rewrite for ast::Ty { result = combine_strs_with_missing_comments( context, result.trim_end(), - &mt.ty.rewrite(&context, shape)?, + &mt.ty.rewrite(context, shape)?, before_ty_span, shape, true, @@ -738,7 +738,7 @@ impl Rewrite for ast::Ty { let budget = shape.width.checked_sub(used_width)?; let ty_str = mt .ty - .rewrite(&context, Shape::legacy(budget, shape.indent + used_width))?; + .rewrite(context, Shape::legacy(budget, shape.indent + used_width))?; result.push_str(&ty_str); } diff --git a/src/utils.rs b/src/utils.rs index 29e1e070d41..3a8713c5bdb 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -42,7 +42,7 @@ pub(crate) fn is_same_visibility(a: &Visibility, b: &Visibility) -> bool { ( VisibilityKind::Restricted { path: p, .. }, VisibilityKind::Restricted { path: q, .. }, - ) => pprust::path_to_string(&p) == pprust::path_to_string(&q), + ) => pprust::path_to_string(p) == pprust::path_to_string(q), (VisibilityKind::Public, VisibilityKind::Public) | (VisibilityKind::Inherited, VisibilityKind::Inherited) | ( @@ -689,7 +689,7 @@ mod test { #[test] fn test_remove_trailing_white_spaces() { let s = " r#\"\n test\n \"#"; - assert_eq!(remove_trailing_white_spaces(&s), s); + assert_eq!(remove_trailing_white_spaces(s), s); } #[test] @@ -698,7 +698,7 @@ mod test { let config = Config::default(); let indent = Indent::new(4, 0); assert_eq!( - trim_left_preserve_layout(&s, indent, &config), + trim_left_preserve_layout(s, indent, &config), Some("aaa\n bbb\n ccc".to_string()) ); } diff --git a/src/visitor.rs b/src/visitor.rs index d854d90b40b..c37e1cb1011 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -164,7 +164,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { ); } else { let shape = self.shape(); - let rewrite = self.with_context(|ctx| stmt.rewrite(&ctx, shape)); + let rewrite = self.with_context(|ctx| stmt.rewrite(ctx, shape)); self.push_rewrite(stmt.span(), rewrite) } } @@ -273,9 +273,9 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { let comment_snippet = self.snippet(span); - let align_to_right = if unindent_comment && contains_comment(&comment_snippet) { + let align_to_right = if unindent_comment && contains_comment(comment_snippet) { let first_lines = comment_snippet.splitn(2, '/').next().unwrap_or(""); - last_line_width(first_lines) > last_line_width(&comment_snippet) + last_line_width(first_lines) > last_line_width(comment_snippet) } else { false }; @@ -439,7 +439,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { let filtered_attrs; let mut attrs = &item.attrs; let skip_context_saved = self.skip_context.clone(); - self.skip_context.update_with_attrs(&attrs); + self.skip_context.update_with_attrs(attrs); let should_visit_node_again = match item.kind { // For use/extern crate items, skip rewriting attributes but check for a skip attribute. @@ -488,12 +488,12 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { ast::ItemKind::Use(ref tree) => self.format_import(item, tree), ast::ItemKind::Impl { .. } => { let block_indent = self.block_indent; - let rw = self.with_context(|ctx| format_impl(&ctx, item, block_indent)); + let rw = self.with_context(|ctx| format_impl(ctx, item, block_indent)); self.push_rewrite(item.span, rw); } ast::ItemKind::Trait(..) => { let block_indent = self.block_indent; - let rw = self.with_context(|ctx| format_trait(&ctx, item, block_indent)); + let rw = self.with_context(|ctx| format_trait(ctx, item, block_indent)); self.push_rewrite(item.span, rw); } ast::ItemKind::TraitAlias(ref generics, ref generic_bounds) => { @@ -552,7 +552,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { visit::FnKind::Fn( fn_ctxt, item.ident, - &fn_signature, + fn_signature, &item.vis, Some(body), ), @@ -567,7 +567,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { let rewrite = self.rewrite_required_fn( indent, item.ident, - &fn_signature, + fn_signature, &item.vis, generics, item.span, @@ -718,7 +718,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { &ii.vis, defaultness, ty.as_ref(), - &generics, + generics, &self.get_context(), self.block_indent, ii.span, @@ -905,7 +905,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { } fn walk_mod_items(&mut self, items: &[rustc_ast::ptr::P]) { - self.visit_items_with_reordering(&ptr_vec_to_ref_vec(&items)); + self.visit_items_with_reordering(&ptr_vec_to_ref_vec(items)); } fn walk_stmts(&mut self, stmts: &[Stmt<'_>], include_current_empty_semi: bool) { -- cgit 1.4.1-3-g733a5 From 0b8ffac0297a46d7d2d2f8328cbc49de7e7144f2 Mon Sep 17 00:00:00 2001 From: Matthias Krüger Date: Sat, 23 Oct 2021 23:21:52 +0200 Subject: fix a bunch of the other clippy warnings that look interesting --- src/comment.rs | 4 ++-- src/expr.rs | 6 +++--- src/matches.rs | 2 +- src/modules.rs | 2 +- src/patterns.rs | 6 +++--- 5 files changed, 10 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/comment.rs b/src/comment.rs index a3cd0359e6b..7b76c232937 100644 --- a/src/comment.rs +++ b/src/comment.rs @@ -405,7 +405,7 @@ impl CodeBlockAttribute { /// attributes are valid rust attributes /// See fn new(attributes: &str) -> CodeBlockAttribute { - for attribute in attributes.split(",") { + for attribute in attributes.split(',') { match attribute.trim() { "" | "rust" | "should_panic" | "no_run" | "edition2015" | "edition2018" | "edition2021" => (), @@ -1384,7 +1384,7 @@ impl<'a> Iterator for LineClasses<'a> { None => unreachable!(), }; - while let Some((kind, c)) = self.base.next() { + for (kind, c) in self.base.by_ref() { // needed to set the kind of the ending character on the last line self.kind = kind; if c == '\n' { diff --git a/src/expr.rs b/src/expr.rs index c67c14b1985..1ca01f9db9a 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -1207,11 +1207,11 @@ fn rewrite_int_lit(context: &RewriteContext<'_>, lit: &ast::Lit, shape: Shape) - let span = lit.span; let symbol = lit.token.symbol.as_str(); - if symbol.starts_with("0x") { + if let Some(symbol_stripped) = symbol.strip_prefix("0x") { let hex_lit = match context.config.hex_literal_case() { HexLiteralCase::Preserve => None, - HexLiteralCase::Upper => Some(symbol[2..].to_ascii_uppercase()), - HexLiteralCase::Lower => Some(symbol[2..].to_ascii_lowercase()), + HexLiteralCase::Upper => Some(symbol_stripped.to_ascii_uppercase()), + HexLiteralCase::Lower => Some(symbol_stripped.to_ascii_lowercase()), }; if let Some(hex_lit) = hex_lit { return wrap_str( diff --git a/src/matches.rs b/src/matches.rs index 25b953ef425..22d23fc1cdb 100644 --- a/src/matches.rs +++ b/src/matches.rs @@ -168,7 +168,7 @@ fn collect_beginning_verts( .map(|a| { context .snippet(a.pat.span) - .starts_with("|") + .starts_with('|') .then(|| a.pat.span().lo()) }) .collect() diff --git a/src/modules.rs b/src/modules.rs index b0c1604a602..88d434d759d 100644 --- a/src/modules.rs +++ b/src/modules.rs @@ -197,7 +197,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> { /// Visit modules from AST. fn visit_mod_from_ast( &mut self, - items: &'ast Vec>, + items: &'ast [rustc_ast::ptr::P], ) -> Result<(), ModuleResolutionError> { for item in items { if is_cfg_if(item) { diff --git a/src/patterns.rs b/src/patterns.rs index 2676c647355..a80d63201f9 100644 --- a/src/patterns.rs +++ b/src/patterns.rs @@ -456,11 +456,11 @@ fn rewrite_tuple_pat( context: &RewriteContext<'_>, shape: Shape, ) -> Option { - let mut pat_vec: Vec<_> = pats.iter().map(|x| TuplePatField::Pat(x)).collect(); - - if pat_vec.is_empty() { + if pats.is_empty() { return Some(format!("{}()", path_str.unwrap_or_default())); } + let mut pat_vec: Vec<_> = pats.iter().map(TuplePatField::Pat).collect(); + let wildcard_suffix_len = count_wildcard_suffix_len(context, &pat_vec, span, shape); let (pat_vec, span) = if context.config.condense_wildcard_suffixes() && wildcard_suffix_len >= 2 { -- cgit 1.4.1-3-g733a5 From bc46af97423cef7484a806e8282c545d7607889e Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Tue, 19 Oct 2021 01:14:51 -0400 Subject: Retain trailing comments in module when using rustfmt::skip attribute Resolves 5033 Trailing comments at the end of the root Module were removed because the module span did not extend until the end of the file. The root Module's span now encompasses the entire file, which ensures that no comments are lost when using ``#![rustfmt::skip]`` --- src/modules.rs | 6 ++++-- tests/target/issue-5033/minimum_example.rs | 8 ++++++++ tests/target/issue-5033/nested_modules.rs | 11 +++++++++++ 3 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 tests/target/issue-5033/minimum_example.rs create mode 100644 tests/target/issue-5033/nested_modules.rs (limited to 'src') diff --git a/src/modules.rs b/src/modules.rs index 88d434d759d..9e75f41ae36 100644 --- a/src/modules.rs +++ b/src/modules.rs @@ -16,7 +16,7 @@ use crate::syntux::parser::{ Directory, DirectoryOwnership, ModError, ModulePathSuccess, Parser, ParserError, }; use crate::syntux::session::ParseSess; -use crate::utils::contains_skip; +use crate::utils::{contains_skip, mk_sp}; mod visitor; @@ -135,10 +135,12 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> { self.visit_mod_from_ast(&krate.items)?; } + let snippet_provider = self.parse_sess.snippet_provider(krate.span); + self.file_map.insert( root_filename, Module::new( - krate.span, + mk_sp(snippet_provider.start_pos(), snippet_provider.end_pos()), None, Cow::Borrowed(&krate.items), Cow::Borrowed(&krate.attrs), diff --git a/tests/target/issue-5033/minimum_example.rs b/tests/target/issue-5033/minimum_example.rs new file mode 100644 index 00000000000..0e7df41deb2 --- /dev/null +++ b/tests/target/issue-5033/minimum_example.rs @@ -0,0 +1,8 @@ +// leading comment + +#![rustfmt::skip] +fn main() { + println!("main"); // commented +} + +// post comment diff --git a/tests/target/issue-5033/nested_modules.rs b/tests/target/issue-5033/nested_modules.rs new file mode 100644 index 00000000000..7a11133b60b --- /dev/null +++ b/tests/target/issue-5033/nested_modules.rs @@ -0,0 +1,11 @@ +#![rustfmt::skip] + +mod a { + mod b { + + } + + // trailing comment b +} + +// trailing comment a -- cgit 1.4.1-3-g733a5 From ed5a0250d3f9401046253ebaf25105f2be7749f2 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Sat, 30 Oct 2021 10:10:08 -0500 Subject: refactor: minor parser cleanup --- src/syntux/parser.rs | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/syntux/parser.rs b/src/syntux/parser.rs index 14b92238cfa..d1bb2f80004 100644 --- a/src/syntux/parser.rs +++ b/src/syntux/parser.rs @@ -125,18 +125,12 @@ impl<'a> Parser<'a> { } })); match result { - Ok(Some(m)) => { - if !sess.has_errors() { - return Ok(m); - } - - if sess.can_reset_errors() { - sess.reset_errors(); - return Ok(m); - } - Err(ParserError::ParseError) + Ok(Some(m)) if !sess.has_errors() => Ok(m), + Ok(Some(m)) if sess.can_reset_errors() => { + sess.reset_errors(); + Ok(m) } - Ok(None) => Err(ParserError::ParseError), + Ok(_) => Err(ParserError::ParseError), Err(..) if path.exists() => Err(ParserError::ParseError), Err(_) => Err(ParserError::ParsePanicError), } -- cgit 1.4.1-3-g733a5 From 5ce82e15133501cdfa96d58370e9b4c3873546b1 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Fri, 8 Oct 2021 19:22:12 -0400 Subject: Prevent trailing whitespace in where clause bound predicate resolves 5012 resolves 4850 This behavior was noticed when using the ``trailing_comma = "Never"`` configuration option (5012). This behavior was also noticed when using default configurations (4850). rustfmt would add a trailing space to where clause bounds that had an empty right hand side. Now no trailing space is added to the end of these where clause bounds. --- src/expr.rs | 3 +++ tests/target/issue-5012/trailing_comma_always.rs | 8 ++++++++ tests/target/issue-5012/trailing_comma_never.rs | 8 ++++++++ tests/target/issue_4850.rs | 4 ++++ 4 files changed, 23 insertions(+) create mode 100644 tests/target/issue-5012/trailing_comma_always.rs create mode 100644 tests/target/issue-5012/trailing_comma_never.rs create mode 100644 tests/target/issue_4850.rs (limited to 'src') diff --git a/src/expr.rs b/src/expr.rs index 1ca01f9db9a..58942e442de 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -1962,6 +1962,9 @@ fn choose_rhs( has_rhs_comment: bool, ) -> Option { match orig_rhs { + Some(ref new_str) if new_str.is_empty() => { + return Some(String::new()); + } Some(ref new_str) if !new_str.contains('\n') && unicode_str_width(new_str) <= shape.width => { diff --git a/tests/target/issue-5012/trailing_comma_always.rs b/tests/target/issue-5012/trailing_comma_always.rs new file mode 100644 index 00000000000..ff9c40fbbd8 --- /dev/null +++ b/tests/target/issue-5012/trailing_comma_always.rs @@ -0,0 +1,8 @@ +// rustfmt-trailing_comma: Always + +pub struct Matrix +where + [T; R * C]:, +{ + contents: [T; R * C], +} diff --git a/tests/target/issue-5012/trailing_comma_never.rs b/tests/target/issue-5012/trailing_comma_never.rs new file mode 100644 index 00000000000..2fac8eae52b --- /dev/null +++ b/tests/target/issue-5012/trailing_comma_never.rs @@ -0,0 +1,8 @@ +// rustfmt-trailing_comma: Never + +pub struct Matrix +where + [T; R * C]: +{ + contents: [T; R * C] +} diff --git a/tests/target/issue_4850.rs b/tests/target/issue_4850.rs new file mode 100644 index 00000000000..7d4da9022fe --- /dev/null +++ b/tests/target/issue_4850.rs @@ -0,0 +1,4 @@ +impl ThisIsALongStructNameToPushTheWhereToWrapLolololol where + [(); this_is_a_long_const_function_name()]: +{ +} -- cgit 1.4.1-3-g733a5 From c1eab154c9139a281d17c5ae70151bac4fcbf60f Mon Sep 17 00:00:00 2001 From: Peter Hall Date: Wed, 7 Oct 2020 12:55:01 +0100 Subject: Use a custom env var for log settings intead of default RUST_LOG # Conflicts: # src/rustfmt/main.rs --- Contributing.md | 2 +- src/bin/main.rs | 2 +- src/format-diff/main.rs | 2 +- src/git-rustfmt/main.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/Contributing.md b/Contributing.md index e6dc6a22037..3073996019e 100644 --- a/Contributing.md +++ b/Contributing.md @@ -59,7 +59,7 @@ example, the `issue-1111.rs` test file is configured by the file ## Debugging Some `rewrite_*` methods use the `debug!` macro for printing useful information. -These messages can be printed by using the environment variable `RUST_LOG=rustfmt=DEBUG`. +These messages can be printed by using the environment variable `RUSTFMT_LOG=rustfmt=DEBUG`. These traces can be helpful in understanding which part of the code was used and get a better grasp on the execution flow. diff --git a/src/bin/main.rs b/src/bin/main.rs index 1bcc5c0dada..9d2e97c9479 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -20,7 +20,7 @@ use crate::rustfmt::{ }; fn main() { - env_logger::init(); + env_logger::Builder::from_env("RUSTFMT_LOG").init(); let opts = make_opts(); let exit_code = match execute(&opts) { diff --git a/src/format-diff/main.rs b/src/format-diff/main.rs index c751932273b..655aeda42bf 100644 --- a/src/format-diff/main.rs +++ b/src/format-diff/main.rs @@ -64,7 +64,7 @@ pub struct Opts { } fn main() { - env_logger::init(); + env_logger::Builder::from_env("RUSTFMT_LOG").init(); let opts = Opts::from_args(); if let Err(e) = run(opts) { println!("{}", e); diff --git a/src/git-rustfmt/main.rs b/src/git-rustfmt/main.rs index 16f5d1dd4f2..579778edbe7 100644 --- a/src/git-rustfmt/main.rs +++ b/src/git-rustfmt/main.rs @@ -170,7 +170,7 @@ impl Config { } fn main() { - env_logger::init(); + env_logger::Builder::from_env("RUSTFMT_LOG").init(); let opts = make_opts(); let matches = opts -- cgit 1.4.1-3-g733a5 From bd86077c58b0460a17ae071edbca9e6bba0aa6b1 Mon Sep 17 00:00:00 2001 From: r00ster Date: Mon, 1 Nov 2021 19:53:35 +0100 Subject: Remove grave accent that shouldn't be there --- src/config/options.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/config/options.rs b/src/config/options.rs index a17d48349c0..bce9e5d07f2 100644 --- a/src/config/options.rs +++ b/src/config/options.rs @@ -20,7 +20,7 @@ pub enum NewlineStyle { Windows, /// Force CR (`\n). Unix, - /// `\r\n` in Windows, `\n`` on other platforms. + /// `\r\n` in Windows, `\n` on other platforms. Native, } -- cgit 1.4.1-3-g733a5 From a5f85058ac2e3f330bd48dd8de26bf429fc28c30 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Thu, 4 Nov 2021 18:00:22 -0500 Subject: fix: handle external mods imported via external->inline load hierarchy --- src/modules.rs | 4 ++- src/test/mod_resolver.rs | 42 ++++++++++++++++++++-------- tests/mod-resolver/issue-5063/foo.rs | 2 ++ tests/mod-resolver/issue-5063/foo/bar/baz.rs | 1 + tests/mod-resolver/issue-5063/main.rs | 5 ++++ 5 files changed, 41 insertions(+), 13 deletions(-) create mode 100644 tests/mod-resolver/issue-5063/foo.rs create mode 100644 tests/mod-resolver/issue-5063/foo/bar/baz.rs create mode 100644 tests/mod-resolver/issue-5063/main.rs (limited to 'src') diff --git a/src/modules.rs b/src/modules.rs index 9e75f41ae36..b1f229d9daa 100644 --- a/src/modules.rs +++ b/src/modules.rs @@ -321,7 +321,9 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> { (Some(Cow::Borrowed(ast::ModKind::Loaded(items, _, _))), _) => { self.visit_mod_from_ast(items) } - (Some(Cow::Owned(..)), Cow::Owned(items)) => self.visit_mod_outside_ast(items), + (Some(Cow::Owned(ast::ModKind::Loaded(items, _, _))), _) | (_, Cow::Owned(items)) => { + self.visit_mod_outside_ast(items) + } (_, _) => Ok(()), } } diff --git a/src/test/mod_resolver.rs b/src/test/mod_resolver.rs index e0b55e3efb2..ae4a0d0fccb 100644 --- a/src/test/mod_resolver.rs +++ b/src/test/mod_resolver.rs @@ -5,21 +5,39 @@ use super::read_config; use crate::{FileName, Input, Session}; -#[test] -fn nested_out_of_line_mods_loaded() { - // See also https://github.com/rust-lang/rustfmt/issues/4874 - let filename = "tests/mod-resolver/issue-4874/main.rs"; - let input_file = PathBuf::from(filename); +fn verify_mod_resolution(input_file_name: &str, exp_misformatted_files: &[&str]) { + let input_file = PathBuf::from(input_file_name); let config = read_config(&input_file); let mut session = Session::::new(config, None); let report = session - .format(Input::File(filename.into())) + .format(Input::File(input_file_name.into())) .expect("Should not have had any execution errors"); let errors_by_file = &report.internal.borrow().0; - assert!(errors_by_file.contains_key(&FileName::Real(PathBuf::from( - "tests/mod-resolver/issue-4874/bar/baz.rs", - )))); - assert!(errors_by_file.contains_key(&FileName::Real(PathBuf::from( - "tests/mod-resolver/issue-4874/foo/qux.rs", - )))); + for exp_file in exp_misformatted_files { + assert!(errors_by_file.contains_key(&FileName::Real(PathBuf::from(exp_file)))); + } +} + +#[test] +fn nested_out_of_line_mods_loaded() { + // See also https://github.com/rust-lang/rustfmt/issues/4874 + verify_mod_resolution( + "tests/mod-resolver/issue-4874/main.rs", + &[ + "tests/mod-resolver/issue-4874/bar/baz.rs", + "tests/mod-resolver/issue-4874/foo/qux.rs", + ], + ); +} + +#[test] +fn out_of_line_nested_inline_within_out_of_line() { + // See also https://github.com/rust-lang/rustfmt/issues/5063 + verify_mod_resolution( + "tests/mod-resolver/issue-5063/main.rs", + &[ + "tests/mod-resolver/issue-5063/foo/bar/baz.rs", + "tests/mod-resolver/issue-5063/foo.rs", + ], + ); } diff --git a/tests/mod-resolver/issue-5063/foo.rs b/tests/mod-resolver/issue-5063/foo.rs new file mode 100644 index 00000000000..d56974773fb --- /dev/null +++ b/tests/mod-resolver/issue-5063/foo.rs @@ -0,0 +1,2 @@ +mod bar { + mod baz;} \ No newline at end of file diff --git a/tests/mod-resolver/issue-5063/foo/bar/baz.rs b/tests/mod-resolver/issue-5063/foo/bar/baz.rs new file mode 100644 index 00000000000..3519b0ee59c --- /dev/null +++ b/tests/mod-resolver/issue-5063/foo/bar/baz.rs @@ -0,0 +1 @@ +fn baz() { } \ No newline at end of file diff --git a/tests/mod-resolver/issue-5063/main.rs b/tests/mod-resolver/issue-5063/main.rs new file mode 100644 index 00000000000..41c81c7bb43 --- /dev/null +++ b/tests/mod-resolver/issue-5063/main.rs @@ -0,0 +1,5 @@ +fn main() { + println!("Hello, world!"); +} + +mod foo; \ No newline at end of file -- cgit 1.4.1-3-g733a5 From 4d50e7c7606efca32bd937a4c60772a616fdbc33 Mon Sep 17 00:00:00 2001 From: mujpao Date: Mon, 1 Nov 2021 23:13:30 -0700 Subject: Put empty trait braces on same line if possible --- src/items.rs | 15 ++++++-- tests/source/empty-item-single-line-false.rs | 46 +++++++++++++++++++++++ tests/source/item-brace-style-always-next-line.rs | 35 +++++++++++++++++ tests/target/empty-item-single-line-false.rs | 41 ++++++++++++++++++++ tests/target/item-brace-style-always-next-line.rs | 29 ++++++++++++++ 5 files changed, 163 insertions(+), 3 deletions(-) create mode 100644 tests/source/empty-item-single-line-false.rs create mode 100644 tests/target/empty-item-single-line-false.rs (limited to 'src') diff --git a/src/items.rs b/src/items.rs index 1c7899b3ac3..e37a1b69658 100644 --- a/src/items.rs +++ b/src/items.rs @@ -1122,12 +1122,24 @@ pub(crate) fn format_trait( } } + let block_span = mk_sp(generics.where_clause.span.hi(), item.span.hi()); + let snippet = context.snippet(block_span); + let open_pos = snippet.find_uncommented("{")? + 1; + match context.config.brace_style() { _ if last_line_contains_single_line_comment(&result) || last_line_width(&result) + 2 > context.budget(offset.width()) => { result.push_str(&offset.to_string_with_newline(context.config)); } + _ if context.config.empty_item_single_line() + && trait_items.is_empty() + && !result.contains('\n') + && !contains_comment(&snippet[open_pos..]) => + { + result.push_str(" {}"); + return Some(result); + } BraceStyle::AlwaysNextLine => { result.push_str(&offset.to_string_with_newline(context.config)); } @@ -1144,9 +1156,6 @@ pub(crate) fn format_trait( } result.push('{'); - let block_span = mk_sp(generics.where_clause.span.hi(), item.span.hi()); - let snippet = context.snippet(block_span); - let open_pos = snippet.find_uncommented("{")? + 1; let outer_indent_str = offset.block_only().to_string_with_newline(context.config); if !trait_items.is_empty() || contains_comment(&snippet[open_pos..]) { diff --git a/tests/source/empty-item-single-line-false.rs b/tests/source/empty-item-single-line-false.rs new file mode 100644 index 00000000000..20c5bc83b46 --- /dev/null +++ b/tests/source/empty-item-single-line-false.rs @@ -0,0 +1,46 @@ +// rustfmt-brace_style: AlwaysNextLine +// rustfmt-empty_item_single_line: false + +fn function() +{ + +} + +struct Struct +{ + +} + +enum Enum +{ + +} + +trait Trait +{ + +} + +impl Trait for T +{ + +} + +trait Trait2 +where + T: Copy + Display + Write + Read + FromStr, {} + +trait Trait3 +where + T: Something + + SomethingElse + + Sync + + Send + + Display + + Debug + + Copy + + Hash + + Debug + + Display + + Write + + Read, {} diff --git a/tests/source/item-brace-style-always-next-line.rs b/tests/source/item-brace-style-always-next-line.rs index 38094d67a77..0fb6405120a 100644 --- a/tests/source/item-brace-style-always-next-line.rs +++ b/tests/source/item-brace-style-always-next-line.rs @@ -27,3 +27,38 @@ mod M { struct D where T: Copy {} } + + +fn function() +{ + +} + +trait Trait +{ + +} + +impl Trait for T +{ + +} + +trait Trait2 +where + T: Copy + Display + Write + Read + FromStr, {} + +trait Trait3 +where + T: Something + + SomethingElse + + Sync + + Send + + Display + + Debug + + Copy + + Hash + + Debug + + Display + + Write + + Read, {} diff --git a/tests/target/empty-item-single-line-false.rs b/tests/target/empty-item-single-line-false.rs new file mode 100644 index 00000000000..bf7f70e7c43 --- /dev/null +++ b/tests/target/empty-item-single-line-false.rs @@ -0,0 +1,41 @@ +// rustfmt-brace_style: AlwaysNextLine +// rustfmt-empty_item_single_line: false + +fn function() +{ +} + +struct Struct {} + +enum Enum {} + +trait Trait +{ +} + +impl Trait for T +{ +} + +trait Trait2 +where + T: Copy + Display + Write + Read + FromStr, +{ +} + +trait Trait3 +where + T: Something + + SomethingElse + + Sync + + Send + + Display + + Debug + + Copy + + Hash + + Debug + + Display + + Write + + Read, +{ +} diff --git a/tests/target/item-brace-style-always-next-line.rs b/tests/target/item-brace-style-always-next-line.rs index 531ac598683..4935fac04f1 100644 --- a/tests/target/item-brace-style-always-next-line.rs +++ b/tests/target/item-brace-style-always-next-line.rs @@ -40,3 +40,32 @@ mod M where T: Copy, {} } + +fn function() {} + +trait Trait {} + +impl Trait for T {} + +trait Trait2 +where + T: Copy + Display + Write + Read + FromStr, +{ +} + +trait Trait3 +where + T: Something + + SomethingElse + + Sync + + Send + + Display + + Debug + + Copy + + Hash + + Debug + + Display + + Write + + Read, +{ +} -- cgit 1.4.1-3-g733a5 From 19c5c74951db8673aa3e3edba8393ce90346f96f Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Sat, 6 Nov 2021 12:59:06 -0500 Subject: refactor: dedupe & simplify ty alias formatting --- src/items.rs | 164 +++++++++++++++++++++++++-------------------------------- src/visitor.rs | 81 ++++++++-------------------- 2 files changed, 96 insertions(+), 149 deletions(-) (limited to 'src') diff --git a/src/items.rs b/src/items.rs index e37a1b69658..13d8a416a1e 100644 --- a/src/items.rs +++ b/src/items.rs @@ -1185,18 +1185,6 @@ pub(crate) fn format_trait( } } -struct OpaqueTypeBounds<'a> { - generic_bounds: &'a ast::GenericBounds, -} - -impl<'a> Rewrite for OpaqueTypeBounds<'a> { - fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option { - self.generic_bounds - .rewrite(context, shape) - .map(|s| format!("impl {}", s)) - } -} - pub(crate) struct TraitAliasBounds<'a> { generic_bounds: &'a ast::GenericBounds, generics: &'a ast::Generics, @@ -1518,17 +1506,79 @@ fn format_tuple_struct( Some(result) } -pub(crate) fn rewrite_type( - context: &RewriteContext<'_>, +pub(crate) enum ItemVisitorKind<'a> { + Item(&'a ast::Item), + AssocTraitItem(&'a ast::AssocItem), + AssocImplItem(&'a ast::AssocItem), + ForeignItem(&'a ast::ForeignItem), +} + +struct TyAliasRewriteInfo<'c, 'g>( + &'c RewriteContext<'c>, + Indent, + &'g ast::Generics, + symbol::Ident, + Span, +); + +pub(crate) fn rewrite_type_alias<'a, 'b>( + ty_alias_kind: &ast::TyAliasKind, + context: &RewriteContext<'a>, indent: Indent, - ident: symbol::Ident, - vis: &ast::Visibility, - generics: &ast::Generics, + visitor_kind: &ItemVisitorKind<'b>, + span: Span, +) -> Option { + use ItemVisitorKind::*; + + let ast::TyAliasKind(defaultness, ref generics, ref generic_bounds, ref ty) = *ty_alias_kind; + let ty_opt = ty.as_ref().map(|t| &**t); + let (ident, vis) = match visitor_kind { + Item(i) => (i.ident, &i.vis), + AssocTraitItem(i) | AssocImplItem(i) => (i.ident, &i.vis), + ForeignItem(i) => (i.ident, &i.vis), + }; + let rw_info = &TyAliasRewriteInfo(context, indent, generics, ident, span); + + // Type Aliases are formatted slightly differently depending on the context + // in which they appear, whether they are opaque, and whether they are associated. + // https://rustc-dev-guide.rust-lang.org/opaque-types-type-alias-impl-trait.html + // https://github.com/rust-dev-tools/fmt-rfcs/blob/master/guide/items.md#type-aliases + match (visitor_kind, ty_opt) { + (Item(_), None) => { + let op_ty = OpaqueType { generic_bounds }; + rewrite_ty(rw_info, Some(generic_bounds), Some(&op_ty), vis) + } + (Item(_), Some(ty)) => rewrite_ty(rw_info, Some(generic_bounds), Some(&*ty), vis), + (AssocImplItem(_), _) => { + let result = if let Some(ast::Ty { + kind: ast::TyKind::ImplTrait(_, ref generic_bounds), + .. + }) = ty_opt + { + let op_ty = OpaqueType { generic_bounds }; + rewrite_ty(rw_info, None, Some(&op_ty), &DEFAULT_VISIBILITY) + } else { + rewrite_ty(rw_info, None, ty.as_ref(), vis) + }?; + match defaultness { + ast::Defaultness::Default(..) => Some(format!("default {}", result)), + _ => Some(result), + } + } + (AssocTraitItem(_), _) | (ForeignItem(_), _) => { + rewrite_ty(rw_info, Some(generic_bounds), ty.as_ref(), vis) + } + } +} + +fn rewrite_ty( + rw_info: &TyAliasRewriteInfo<'_, '_>, generic_bounds_opt: Option<&ast::GenericBounds>, rhs: Option<&R>, - span: Span, + vis: &ast::Visibility, ) -> Option { let mut result = String::with_capacity(128); + let TyAliasRewriteInfo(context, indent, generics, ident, span) = *rw_info; result.push_str(&format!("{}type ", format_visibility(context, vis))); let ident_str = rewrite_ident(context, ident); @@ -1616,28 +1666,6 @@ pub(crate) fn rewrite_type( } } -pub(crate) fn rewrite_opaque_type( - context: &RewriteContext<'_>, - indent: Indent, - ident: symbol::Ident, - generic_bounds: &ast::GenericBounds, - generics: &ast::Generics, - vis: &ast::Visibility, - span: Span, -) -> Option { - let opaque_type_bounds = OpaqueTypeBounds { generic_bounds }; - rewrite_type( - context, - indent, - ident, - vis, - generics, - Some(generic_bounds), - Some(&opaque_type_bounds), - span, - ) -} - fn type_annotation_spacing(config: &Config) -> (&str, &str) { ( if config.space_before_colon() { " " } else { "" }, @@ -1863,54 +1891,18 @@ fn rewrite_static( } } struct OpaqueType<'a> { - bounds: &'a ast::GenericBounds, + generic_bounds: &'a ast::GenericBounds, } impl<'a> Rewrite for OpaqueType<'a> { fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option { let shape = shape.offset_left(5)?; // `impl ` - self.bounds + self.generic_bounds .rewrite(context, shape) .map(|s| format!("impl {}", s)) } } -pub(crate) fn rewrite_impl_type( - ident: symbol::Ident, - vis: &ast::Visibility, - defaultness: ast::Defaultness, - ty_opt: Option<&ptr::P>, - generics: &ast::Generics, - context: &RewriteContext<'_>, - indent: Indent, - span: Span, -) -> Option { - // Opaque type - let result = if let Some(rustc_ast::ast::Ty { - kind: ast::TyKind::ImplTrait(_, ref bounds), - .. - }) = ty_opt.map(|t| &**t) - { - rewrite_type( - context, - indent, - ident, - &DEFAULT_VISIBILITY, - generics, - None, - Some(&OpaqueType { bounds }), - span, - ) - } else { - rewrite_type(context, indent, ident, vis, generics, None, ty_opt, span) - }?; - - match defaultness { - ast::Defaultness::Default(..) => Some(format!("default {}", result)), - _ => Some(result), - } -} - impl Rewrite for ast::FnRetTy { fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option { match *self { @@ -3176,19 +3168,9 @@ impl Rewrite for ast::ForeignItem { // 1 = ; rewrite_assign_rhs(context, prefix, &**ty, shape.sub_width(1)?).map(|s| s + ";") } - ast::ForeignItemKind::TyAlias(ref ty_alias_kind) => { - let ast::TyAliasKind(_, ref generics, ref generic_bounds, ref type_default) = - **ty_alias_kind; - rewrite_type( - context, - shape.indent, - self.ident, - &self.vis, - generics, - Some(generic_bounds), - type_default.as_ref(), - self.span, - ) + ast::ForeignItemKind::TyAlias(ref ty_alias) => { + let (kind, span) = (&ItemVisitorKind::ForeignItem(&self), self.span); + rewrite_type_alias(ty_alias, context, shape.indent, kind, span) } ast::ForeignItemKind::MacCall(ref mac) => { rewrite_macro(mac, None, context, shape, MacroPosition::Item) diff --git a/src/visitor.rs b/src/visitor.rs index c37e1cb1011..f385245248d 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -12,8 +12,7 @@ use crate::config::{BraceStyle, Config}; use crate::coverage::transform_missing_snippet; use crate::items::{ format_impl, format_trait, format_trait_alias, is_mod_decl, is_use_item, rewrite_extern_crate, - rewrite_impl_type, rewrite_opaque_type, rewrite_type, FnBraceStyle, FnSig, StaticParts, - StructParts, + rewrite_type_alias, FnBraceStyle, FnSig, ItemVisitorKind, StaticParts, StructParts, }; use crate::macros::{macro_style, rewrite_macro, rewrite_macro_def, MacroPosition}; use crate::modules::Module; @@ -576,35 +575,8 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { } } ast::ItemKind::TyAlias(ref alias_kind) => { - let ast::TyAliasKind(_, ref generics, ref generic_bounds, ref ty) = - **alias_kind; - match ty { - Some(ty) => { - let rewrite = rewrite_type( - &self.get_context(), - self.block_indent, - item.ident, - &item.vis, - generics, - Some(generic_bounds), - Some(&*ty), - item.span, - ); - self.push_rewrite(item.span, rewrite); - } - None => { - let rewrite = rewrite_opaque_type( - &self.get_context(), - self.block_indent, - item.ident, - generic_bounds, - generics, - &item.vis, - item.span, - ); - self.push_rewrite(item.span, rewrite); - } - } + use ItemVisitorKind::Item; + self.visit_ty_alias_kind(alias_kind, &Item(&item), item.span); } ast::ItemKind::GlobalAsm(..) => { let snippet = Some(self.snippet(item.span).to_owned()); @@ -627,6 +599,22 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { self.skip_context = skip_context_saved; } + fn visit_ty_alias_kind( + &mut self, + ty_kind: &ast::TyAliasKind, + visitor_kind: &ItemVisitorKind<'_>, + span: Span, + ) { + let rewrite = rewrite_type_alias( + ty_kind, + &self.get_context(), + self.block_indent, + visitor_kind, + span, + ); + self.push_rewrite(span, rewrite); + } + pub(crate) fn visit_trait_item(&mut self, ti: &ast::AssocItem) { skip_out_of_file_lines_range_visitor!(self, ti.span); @@ -659,19 +647,8 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { } } ast::AssocItemKind::TyAlias(ref ty_alias_kind) => { - let ast::TyAliasKind(_, ref generics, ref generic_bounds, ref type_default) = - **ty_alias_kind; - let rewrite = rewrite_type( - &self.get_context(), - self.block_indent, - ti.ident, - &ti.vis, - generics, - Some(generic_bounds), - type_default.as_ref(), - ti.span, - ); - self.push_rewrite(ti.span, rewrite); + use ItemVisitorKind::AssocTraitItem; + self.visit_ty_alias_kind(ty_alias_kind, &AssocTraitItem(&ti), ti.span); } ast::AssocItemKind::MacCall(ref mac) => { self.visit_mac(mac, Some(ti.ident), MacroPosition::Item); @@ -710,20 +687,8 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { } ast::AssocItemKind::Const(..) => self.visit_static(&StaticParts::from_impl_item(ii)), ast::AssocItemKind::TyAlias(ref ty_alias_kind) => { - let ast::TyAliasKind(defaultness, ref generics, _, ref ty) = **ty_alias_kind; - self.push_rewrite( - ii.span, - rewrite_impl_type( - ii.ident, - &ii.vis, - defaultness, - ty.as_ref(), - generics, - &self.get_context(), - self.block_indent, - ii.span, - ), - ); + use ItemVisitorKind::AssocImplItem; + self.visit_ty_alias_kind(ty_alias_kind, &AssocImplItem(&ii), ii.span); } ast::AssocItemKind::MacCall(ref mac) => { self.visit_mac(mac, Some(ii.ident), MacroPosition::Item); -- cgit 1.4.1-3-g733a5 From e4472d3b07b2c34b27688303745d4cc0e74da9a5 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Sat, 6 Nov 2021 17:12:25 -0500 Subject: refactor: dedupe associated item visitation --- src/visitor.rs | 90 +++++++++++++++++++++++----------------------------------- 1 file changed, 35 insertions(+), 55 deletions(-) (limited to 'src') diff --git a/src/visitor.rs b/src/visitor.rs index f385245248d..25b0085b3ef 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -615,85 +615,65 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { self.push_rewrite(span, rewrite); } - pub(crate) fn visit_trait_item(&mut self, ti: &ast::AssocItem) { - skip_out_of_file_lines_range_visitor!(self, ti.span); + fn visit_assoc_item(&mut self, visitor_kind: &ItemVisitorKind<'_>) { + use ItemVisitorKind::*; + // TODO(calebcartwright): Not sure the skip spans are correct + let (ai, skip_span, assoc_ctxt) = match visitor_kind { + AssocTraitItem(ai) => (*ai, ai.span(), visit::AssocCtxt::Trait), + AssocImplItem(ai) => (*ai, ai.span, visit::AssocCtxt::Impl), + _ => unreachable!(), + }; + skip_out_of_file_lines_range_visitor!(self, ai.span); - if self.visit_attrs(&ti.attrs, ast::AttrStyle::Outer) { - self.push_skipped_with_span(ti.attrs.as_slice(), ti.span(), ti.span()); + if self.visit_attrs(&ai.attrs, ast::AttrStyle::Outer) { + self.push_skipped_with_span(&ai.attrs.as_slice(), skip_span, skip_span); return; } // TODO(calebcartwright): consider enabling box_patterns feature gate - match ti.kind { - ast::AssocItemKind::Const(..) => self.visit_static(&StaticParts::from_trait_item(ti)), - ast::AssocItemKind::Fn(ref fn_kind) => { + match (&ai.kind, visitor_kind) { + (ast::AssocItemKind::Const(..), AssocTraitItem(_)) => { + self.visit_static(&StaticParts::from_trait_item(&ai)) + } + (ast::AssocItemKind::Const(..), AssocImplItem(_)) => { + self.visit_static(&StaticParts::from_impl_item(&ai)) + } + (ast::AssocItemKind::Fn(ref fn_kind), _) => { let ast::FnKind(defaultness, ref sig, ref generics, ref block) = **fn_kind; if let Some(ref body) = block { - let inner_attrs = inner_attributes(&ti.attrs); - let fn_ctxt = visit::FnCtxt::Assoc(visit::AssocCtxt::Trait); + let inner_attrs = inner_attributes(&ai.attrs); + let fn_ctxt = visit::FnCtxt::Assoc(assoc_ctxt); self.visit_fn( - visit::FnKind::Fn(fn_ctxt, ti.ident, sig, &ti.vis, Some(body)), + visit::FnKind::Fn(fn_ctxt, ai.ident, sig, &ai.vis, Some(body)), generics, &sig.decl, - ti.span, + ai.span, defaultness, Some(&inner_attrs), ); } else { let indent = self.block_indent; let rewrite = - self.rewrite_required_fn(indent, ti.ident, sig, &ti.vis, generics, ti.span); - self.push_rewrite(ti.span, rewrite); + self.rewrite_required_fn(indent, ai.ident, sig, &ai.vis, generics, ai.span); + self.push_rewrite(ai.span, rewrite); } } - ast::AssocItemKind::TyAlias(ref ty_alias_kind) => { - use ItemVisitorKind::AssocTraitItem; - self.visit_ty_alias_kind(ty_alias_kind, &AssocTraitItem(&ti), ti.span); + (ast::AssocItemKind::TyAlias(ref ty_alias_kind), _) => { + self.visit_ty_alias_kind(ty_alias_kind, visitor_kind, ai.span); } - ast::AssocItemKind::MacCall(ref mac) => { - self.visit_mac(mac, Some(ti.ident), MacroPosition::Item); + (ast::AssocItemKind::MacCall(ref mac), _) => { + self.visit_mac(mac, Some(ai.ident), MacroPosition::Item); } + _ => unreachable!(), } } - pub(crate) fn visit_impl_item(&mut self, ii: &ast::AssocItem) { - skip_out_of_file_lines_range_visitor!(self, ii.span); - - if self.visit_attrs(&ii.attrs, ast::AttrStyle::Outer) { - self.push_skipped_with_span(ii.attrs.as_slice(), ii.span, ii.span); - return; - } + pub(crate) fn visit_trait_item(&mut self, ti: &ast::AssocItem) { + self.visit_assoc_item(&ItemVisitorKind::AssocTraitItem(ti)); + } - match ii.kind { - ast::AssocItemKind::Fn(ref fn_kind) => { - let ast::FnKind(defaultness, ref sig, ref generics, ref block) = **fn_kind; - if let Some(ref body) = block { - let inner_attrs = inner_attributes(&ii.attrs); - let fn_ctxt = visit::FnCtxt::Assoc(visit::AssocCtxt::Impl); - self.visit_fn( - visit::FnKind::Fn(fn_ctxt, ii.ident, sig, &ii.vis, Some(body)), - generics, - &sig.decl, - ii.span, - defaultness, - Some(&inner_attrs), - ); - } else { - let indent = self.block_indent; - let rewrite = - self.rewrite_required_fn(indent, ii.ident, sig, &ii.vis, generics, ii.span); - self.push_rewrite(ii.span, rewrite); - } - } - ast::AssocItemKind::Const(..) => self.visit_static(&StaticParts::from_impl_item(ii)), - ast::AssocItemKind::TyAlias(ref ty_alias_kind) => { - use ItemVisitorKind::AssocImplItem; - self.visit_ty_alias_kind(ty_alias_kind, &AssocImplItem(&ii), ii.span); - } - ast::AssocItemKind::MacCall(ref mac) => { - self.visit_mac(mac, Some(ii.ident), MacroPosition::Item); - } - } + pub(crate) fn visit_impl_item(&mut self, ii: &ast::AssocItem) { + self.visit_assoc_item(&ItemVisitorKind::AssocImplItem(ii)); } fn visit_mac(&mut self, mac: &ast::MacCall, ident: Option, pos: MacroPosition) { -- cgit 1.4.1-3-g733a5 From eee8f0419dca910187350ac38fe9694b8b7919b9 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Wed, 17 Nov 2021 12:51:37 -0600 Subject: refactor: cleanup duplicative Impl handling code --- src/items.rs | 453 ++++++++++++++++++++++++++------------------------------- src/visitor.rs | 4 +- 2 files changed, 212 insertions(+), 245 deletions(-) (limited to 'src') diff --git a/src/items.rs b/src/items.rs index 50121a8b6b5..849e6c06218 100644 --- a/src/items.rs +++ b/src/items.rs @@ -579,6 +579,25 @@ impl<'a> FmtVisitor<'a> { fn visit_impl_items(&mut self, items: &[ptr::P]) { if self.get_context().config.reorder_impl_items() { + type TyOpt = Option>; + use crate::ast::AssocItemKind::*; + let is_type = |ty: &TyOpt| { + ty.as_ref() + .map_or(true, |t| !matches!(t.kind, ast::TyKind::ImplTrait(..))) + }; + let is_opaque = |ty: &TyOpt| !is_type(ty); + let both_type = |left: &TyOpt, right: &TyOpt| is_type(left) && is_type(right); + let both_opaque = |left: &TyOpt, right: &TyOpt| is_opaque(left) && is_opaque(right); + let need_empty_line = |a: &ast::AssocItemKind, b: &ast::AssocItemKind| match (a, b) { + (TyAlias(lty), TyAlias(rty)) + if both_type(<y.ty, &rty.ty) || both_opaque(<y.ty, &rty.ty) => + { + false + } + (Const(..), Const(..)) => false, + _ => true, + }; + // Create visitor for each items, then reorder them. let mut buffer = vec![]; for item in items { @@ -587,50 +606,6 @@ impl<'a> FmtVisitor<'a> { self.buffer.clear(); } - fn is_type(ty: &Option>) -> bool { - if let Some(lty) = ty { - if let ast::TyKind::ImplTrait(..) = lty.kind { - return false; - } - } - true - } - - fn is_opaque(ty: &Option>) -> bool { - !is_type(ty) - } - - fn both_type( - a: &Option>, - b: &Option>, - ) -> bool { - is_type(a) && is_type(b) - } - - fn both_opaque( - a: &Option>, - b: &Option>, - ) -> bool { - is_opaque(a) && is_opaque(b) - } - - // In rustc-ap-v638 the `OpaqueTy` AssocItemKind variant was removed but - // we still need to differentiate to maintain sorting order. - - // type -> opaque -> const -> macro -> method - use crate::ast::AssocItemKind::*; - fn need_empty_line(a: &ast::AssocItemKind, b: &ast::AssocItemKind) -> bool { - match (a, b) { - (TyAlias(lty), TyAlias(rty)) - if both_type(<y.ty, &rty.ty) || both_opaque(<y.ty, &rty.ty) => - { - false - } - (Const(..), Const(..)) => false, - _ => true, - } - } - buffer.sort_by(|(_, a), (_, b)| match (&a.kind, &b.kind) { (TyAlias(lty), TyAlias(rty)) if both_type(<y.ty, &rty.ty) || both_opaque(<y.ty, &rty.ty) => @@ -676,136 +651,133 @@ impl<'a> FmtVisitor<'a> { pub(crate) fn format_impl( context: &RewriteContext<'_>, item: &ast::Item, + iimpl: &ast::Impl, offset: Indent, ) -> Option { - if let ast::ItemKind::Impl(impl_kind) = &item.kind { - let ast::Impl { - ref generics, - ref self_ty, - ref items, - .. - } = **impl_kind; - let mut result = String::with_capacity(128); - let ref_and_type = format_impl_ref_and_type(context, item, offset)?; - let sep = offset.to_string_with_newline(context.config); - result.push_str(&ref_and_type); + let ast::Impl { + generics, + self_ty, + items, + .. + } = iimpl; + let mut result = String::with_capacity(128); + let ref_and_type = format_impl_ref_and_type(context, item, iimpl, offset)?; + let sep = offset.to_string_with_newline(context.config); + result.push_str(&ref_and_type); - let where_budget = if result.contains('\n') { - context.config.max_width() - } else { - context.budget(last_line_width(&result)) - }; + let where_budget = if result.contains('\n') { + context.config.max_width() + } else { + context.budget(last_line_width(&result)) + }; - let mut option = WhereClauseOption::snuggled(&ref_and_type); - let snippet = context.snippet(item.span); - let open_pos = snippet.find_uncommented("{")? + 1; - if !contains_comment(&snippet[open_pos..]) - && items.is_empty() - && generics.where_clause.predicates.len() == 1 - && !result.contains('\n') - { - option.suppress_comma(); - option.snuggle(); - option.allow_single_line(); - } + let mut option = WhereClauseOption::snuggled(&ref_and_type); + let snippet = context.snippet(item.span); + let open_pos = snippet.find_uncommented("{")? + 1; + if !contains_comment(&snippet[open_pos..]) + && items.is_empty() + && generics.where_clause.predicates.len() == 1 + && !result.contains('\n') + { + option.suppress_comma(); + option.snuggle(); + option.allow_single_line(); + } - let missing_span = mk_sp(self_ty.span.hi(), item.span.hi()); - let where_span_end = context.snippet_provider.opt_span_before(missing_span, "{"); - let where_clause_str = rewrite_where_clause( - context, - &generics.where_clause, - context.config.brace_style(), - Shape::legacy(where_budget, offset.block_only()), - false, - "{", - where_span_end, - self_ty.span.hi(), - option, - )?; + let missing_span = mk_sp(self_ty.span.hi(), item.span.hi()); + let where_span_end = context.snippet_provider.opt_span_before(missing_span, "{"); + let where_clause_str = rewrite_where_clause( + context, + &generics.where_clause, + context.config.brace_style(), + Shape::legacy(where_budget, offset.block_only()), + false, + "{", + where_span_end, + self_ty.span.hi(), + option, + )?; - // If there is no where-clause, we may have missing comments between the trait name and - // the opening brace. - if generics.where_clause.predicates.is_empty() { - if let Some(hi) = where_span_end { - match recover_missing_comment_in_span( - mk_sp(self_ty.span.hi(), hi), - Shape::indented(offset, context.config), - context, - last_line_width(&result), - ) { - Some(ref missing_comment) if !missing_comment.is_empty() => { - result.push_str(missing_comment); - } - _ => (), + // If there is no where-clause, we may have missing comments between the trait name and + // the opening brace. + if generics.where_clause.predicates.is_empty() { + if let Some(hi) = where_span_end { + match recover_missing_comment_in_span( + mk_sp(self_ty.span.hi(), hi), + Shape::indented(offset, context.config), + context, + last_line_width(&result), + ) { + Some(ref missing_comment) if !missing_comment.is_empty() => { + result.push_str(missing_comment); } + _ => (), } } + } - if is_impl_single_line(context, items.as_slice(), &result, &where_clause_str, item)? { - result.push_str(&where_clause_str); - if where_clause_str.contains('\n') || last_line_contains_single_line_comment(&result) { - // if the where_clause contains extra comments AND - // there is only one where-clause predicate - // recover the suppressed comma in single line where_clause formatting - if generics.where_clause.predicates.len() == 1 { - result.push(','); - } - result.push_str(&format!("{}{{{}}}", sep, sep)); - } else { - result.push_str(" {}"); + if is_impl_single_line(context, items.as_slice(), &result, &where_clause_str, item)? { + result.push_str(&where_clause_str); + if where_clause_str.contains('\n') || last_line_contains_single_line_comment(&result) { + // if the where_clause contains extra comments AND + // there is only one where-clause predicate + // recover the suppressed comma in single line where_clause formatting + if generics.where_clause.predicates.len() == 1 { + result.push(','); } - return Some(result); + result.push_str(&format!("{}{{{}}}", sep, sep)); + } else { + result.push_str(" {}"); } + return Some(result); + } - result.push_str(&where_clause_str); + result.push_str(&where_clause_str); - let need_newline = last_line_contains_single_line_comment(&result) || result.contains('\n'); - match context.config.brace_style() { - _ if need_newline => result.push_str(&sep), - BraceStyle::AlwaysNextLine => result.push_str(&sep), - BraceStyle::PreferSameLine => result.push(' '), - BraceStyle::SameLineWhere => { - if !where_clause_str.is_empty() { - result.push_str(&sep); - } else { - result.push(' '); - } + let need_newline = last_line_contains_single_line_comment(&result) || result.contains('\n'); + match context.config.brace_style() { + _ if need_newline => result.push_str(&sep), + BraceStyle::AlwaysNextLine => result.push_str(&sep), + BraceStyle::PreferSameLine => result.push(' '), + BraceStyle::SameLineWhere => { + if !where_clause_str.is_empty() { + result.push_str(&sep); + } else { + result.push(' '); } } + } - result.push('{'); - // this is an impl body snippet(impl SampleImpl { /* here */ }) - let lo = max(self_ty.span.hi(), generics.where_clause.span.hi()); - let snippet = context.snippet(mk_sp(lo, item.span.hi())); - let open_pos = snippet.find_uncommented("{")? + 1; + result.push('{'); + // this is an impl body snippet(impl SampleImpl { /* here */ }) + let lo = max(self_ty.span.hi(), generics.where_clause.span.hi()); + let snippet = context.snippet(mk_sp(lo, item.span.hi())); + let open_pos = snippet.find_uncommented("{")? + 1; - if !items.is_empty() || contains_comment(&snippet[open_pos..]) { - let mut visitor = FmtVisitor::from_context(context); - let item_indent = offset.block_only().block_indent(context.config); - visitor.block_indent = item_indent; - visitor.last_pos = lo + BytePos(open_pos as u32); + if !items.is_empty() || contains_comment(&snippet[open_pos..]) { + let mut visitor = FmtVisitor::from_context(context); + let item_indent = offset.block_only().block_indent(context.config); + visitor.block_indent = item_indent; + visitor.last_pos = lo + BytePos(open_pos as u32); - visitor.visit_attrs(&item.attrs, ast::AttrStyle::Inner); - visitor.visit_impl_items(items); + visitor.visit_attrs(&item.attrs, ast::AttrStyle::Inner); + visitor.visit_impl_items(items); - visitor.format_missing(item.span.hi() - BytePos(1)); + visitor.format_missing(item.span.hi() - BytePos(1)); - let inner_indent_str = visitor.block_indent.to_string_with_newline(context.config); - let outer_indent_str = offset.block_only().to_string_with_newline(context.config); + let inner_indent_str = visitor.block_indent.to_string_with_newline(context.config); + let outer_indent_str = offset.block_only().to_string_with_newline(context.config); - result.push_str(&inner_indent_str); - result.push_str(visitor.buffer.trim()); - result.push_str(&outer_indent_str); - } else if need_newline || !context.config.empty_item_single_line() { - result.push_str(&sep); - } + result.push_str(&inner_indent_str); + result.push_str(visitor.buffer.trim()); + result.push_str(&outer_indent_str); + } else if need_newline || !context.config.empty_item_single_line() { + result.push_str(&sep); + } - result.push('}'); + result.push('}'); - Some(result) - } else { - unreachable!(); - } + Some(result) } fn is_impl_single_line( @@ -830,111 +802,106 @@ fn is_impl_single_line( fn format_impl_ref_and_type( context: &RewriteContext<'_>, item: &ast::Item, + iimpl: &ast::Impl, offset: Indent, ) -> Option { - if let ast::ItemKind::Impl(impl_kind) = &item.kind { - let ast::Impl { - unsafety, - polarity, - defaultness, - constness, - ref generics, - of_trait: ref trait_ref, - ref self_ty, - .. - } = **impl_kind; - let mut result = String::with_capacity(128); + let ast::Impl { + unsafety, + polarity, + defaultness, + constness, + ref generics, + of_trait: ref trait_ref, + ref self_ty, + .. + } = *iimpl; + let mut result = String::with_capacity(128); - result.push_str(&format_visibility(context, &item.vis)); - result.push_str(format_defaultness(defaultness)); - result.push_str(format_unsafety(unsafety)); + result.push_str(&format_visibility(context, &item.vis)); + result.push_str(format_defaultness(defaultness)); + result.push_str(format_unsafety(unsafety)); - let shape = if context.config.version() == Version::Two { - Shape::indented(offset + last_line_width(&result), context.config) - } else { - generics_shape_from_config( - context.config, - Shape::indented(offset + last_line_width(&result), context.config), - 0, - )? - }; - let generics_str = rewrite_generics(context, "impl", generics, shape)?; - result.push_str(&generics_str); - result.push_str(format_constness_right(constness)); + let shape = if context.config.version() == Version::Two { + Shape::indented(offset + last_line_width(&result), context.config) + } else { + generics_shape_from_config( + context.config, + Shape::indented(offset + last_line_width(&result), context.config), + 0, + )? + }; + let generics_str = rewrite_generics(context, "impl", generics, shape)?; + result.push_str(&generics_str); + result.push_str(format_constness_right(constness)); - let polarity_str = match polarity { - ast::ImplPolarity::Negative(_) => "!", - ast::ImplPolarity::Positive => "", - }; + let polarity_str = match polarity { + ast::ImplPolarity::Negative(_) => "!", + ast::ImplPolarity::Positive => "", + }; - let polarity_overhead; - let trait_ref_overhead; - if let Some(ref trait_ref) = *trait_ref { - let result_len = last_line_width(&result); - result.push_str(&rewrite_trait_ref( - context, - trait_ref, - offset, - polarity_str, - result_len, - )?); - polarity_overhead = 0; // already written - trait_ref_overhead = " for".len(); - } else { - polarity_overhead = polarity_str.len(); - trait_ref_overhead = 0; - } + let polarity_overhead; + let trait_ref_overhead; + if let Some(ref trait_ref) = *trait_ref { + let result_len = last_line_width(&result); + result.push_str(&rewrite_trait_ref( + context, + trait_ref, + offset, + polarity_str, + result_len, + )?); + polarity_overhead = 0; // already written + trait_ref_overhead = " for".len(); + } else { + polarity_overhead = polarity_str.len(); + trait_ref_overhead = 0; + } - // Try to put the self type in a single line. - let curly_brace_overhead = if generics.where_clause.predicates.is_empty() { - // If there is no where-clause adapt budget for type formatting to take space and curly - // brace into account. - match context.config.brace_style() { - BraceStyle::AlwaysNextLine => 0, - _ => 2, - } - } else { - 0 - }; - let used_space = last_line_width(&result) - + polarity_overhead - + trait_ref_overhead - + curly_brace_overhead; - // 1 = space before the type. - let budget = context.budget(used_space + 1); - if let Some(self_ty_str) = self_ty.rewrite(context, Shape::legacy(budget, offset)) { - if !self_ty_str.contains('\n') { - if trait_ref.is_some() { - result.push_str(" for "); - } else { - result.push(' '); - result.push_str(polarity_str); - } - result.push_str(&self_ty_str); - return Some(result); + // Try to put the self type in a single line. + let curly_brace_overhead = if generics.where_clause.predicates.is_empty() { + // If there is no where-clause adapt budget for type formatting to take space and curly + // brace into account. + match context.config.brace_style() { + BraceStyle::AlwaysNextLine => 0, + _ => 2, + } + } else { + 0 + }; + let used_space = + last_line_width(&result) + polarity_overhead + trait_ref_overhead + curly_brace_overhead; + // 1 = space before the type. + let budget = context.budget(used_space + 1); + if let Some(self_ty_str) = self_ty.rewrite(context, Shape::legacy(budget, offset)) { + if !self_ty_str.contains('\n') { + if trait_ref.is_some() { + result.push_str(" for "); + } else { + result.push(' '); + result.push_str(polarity_str); } + result.push_str(&self_ty_str); + return Some(result); } + } - // Couldn't fit the self type on a single line, put it on a new line. - result.push('\n'); - // Add indentation of one additional tab. - let new_line_offset = offset.block_indent(context.config); - result.push_str(&new_line_offset.to_string(context.config)); - if trait_ref.is_some() { - result.push_str("for "); - } else { - result.push_str(polarity_str); - } - let budget = context.budget(last_line_width(&result) + polarity_overhead); - let type_offset = match context.config.indent_style() { - IndentStyle::Visual => new_line_offset + trait_ref_overhead, - IndentStyle::Block => new_line_offset, - }; - result.push_str(&*self_ty.rewrite(context, Shape::legacy(budget, type_offset))?); - Some(result) + // Couldn't fit the self type on a single line, put it on a new line. + result.push('\n'); + // Add indentation of one additional tab. + let new_line_offset = offset.block_indent(context.config); + result.push_str(&new_line_offset.to_string(context.config)); + if trait_ref.is_some() { + result.push_str("for "); } else { - unreachable!(); + result.push_str(polarity_str); } + let budget = context.budget(last_line_width(&result) + polarity_overhead); + let type_offset = match context.config.indent_style() { + IndentStyle::Visual => new_line_offset + trait_ref_overhead, + IndentStyle::Block => new_line_offset, + }; + result.push_str(&*self_ty.rewrite(context, Shape::legacy(budget, type_offset))?); + Some(result) } fn rewrite_trait_ref( diff --git a/src/visitor.rs b/src/visitor.rs index 527042d098a..e4a7be742ab 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -485,9 +485,9 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { if should_visit_node_again { match item.kind { ast::ItemKind::Use(ref tree) => self.format_import(item, tree), - ast::ItemKind::Impl { .. } => { + ast::ItemKind::Impl(ref iimpl) => { let block_indent = self.block_indent; - let rw = self.with_context(|ctx| format_impl(ctx, item, block_indent)); + let rw = self.with_context(|ctx| format_impl(ctx, item, iimpl, block_indent)); self.push_rewrite(item.span, rw); } ast::ItemKind::Trait(..) => { -- cgit 1.4.1-3-g733a5 From 2c442ccf25a98c9e8f0a972d94f10ef44b7b09bf Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Thu, 18 Nov 2021 12:39:38 -0600 Subject: fix: correct some type alias issues --- src/items.rs | 49 ++++++++++++++++++++++++------------------------- src/types.rs | 8 ++++++++ 2 files changed, 32 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/items.rs b/src/items.rs index 849e6c06218..63c32e012df 100644 --- a/src/items.rs +++ b/src/items.rs @@ -28,6 +28,7 @@ use crate::shape::{Indent, Shape}; use crate::source_map::{LineRangeUtils, SpanUtils}; use crate::spanned::Spanned; use crate::stmt::Stmt; +use crate::types::opaque_ty; use crate::utils::*; use crate::vertical::rewrite_with_alignment; use crate::visitor::FmtVisitor; @@ -581,13 +582,10 @@ impl<'a> FmtVisitor<'a> { if self.get_context().config.reorder_impl_items() { type TyOpt = Option>; use crate::ast::AssocItemKind::*; - let is_type = |ty: &TyOpt| { - ty.as_ref() - .map_or(true, |t| !matches!(t.kind, ast::TyKind::ImplTrait(..))) - }; - let is_opaque = |ty: &TyOpt| !is_type(ty); - let both_type = |left: &TyOpt, right: &TyOpt| is_type(left) && is_type(right); - let both_opaque = |left: &TyOpt, right: &TyOpt| is_opaque(left) && is_opaque(right); + let is_type = |ty: &TyOpt| opaque_ty(ty).is_none(); + let is_opaque = |ty: &TyOpt| opaque_ty(ty).is_some(); + let both_type = |l: &TyOpt, r: &TyOpt| is_type(l) && is_type(r); + let both_opaque = |l: &TyOpt, r: &TyOpt| is_opaque(l) && is_opaque(r); let need_empty_line = |a: &ast::AssocItemKind, b: &ast::AssocItemKind| match (a, b) { (TyAlias(lty), TyAlias(rty)) if both_type(<y.ty, &rty.ty) || both_opaque(<y.ty, &rty.ty) => @@ -1508,43 +1506,38 @@ pub(crate) fn rewrite_type_alias<'a, 'b>( ref bounds, ref ty, } = *ty_alias_kind; - let ty_opt = ty.as_ref().map(|t| &**t); + let ty_opt = ty.as_ref(); let (ident, vis) = match visitor_kind { Item(i) => (i.ident, &i.vis), AssocTraitItem(i) | AssocImplItem(i) => (i.ident, &i.vis), ForeignItem(i) => (i.ident, &i.vis), }; let rw_info = &TyAliasRewriteInfo(context, indent, generics, ident, span); - + let op_ty = opaque_ty(ty); // Type Aliases are formatted slightly differently depending on the context // in which they appear, whether they are opaque, and whether they are associated. // https://rustc-dev-guide.rust-lang.org/opaque-types-type-alias-impl-trait.html // https://github.com/rust-dev-tools/fmt-rfcs/blob/master/guide/items.md#type-aliases - match (visitor_kind, ty_opt) { - (Item(_), None) => { - let op_ty = OpaqueType { bounds }; - rewrite_ty(rw_info, Some(bounds), Some(&op_ty), vis) + match (visitor_kind, &op_ty) { + (Item(_) | AssocTraitItem(_) | ForeignItem(_), Some(ref op_bounds)) => { + let op = OpaqueType { bounds: op_bounds }; + rewrite_ty(rw_info, Some(bounds), Some(&op), vis) + } + (Item(_) | AssocTraitItem(_) | ForeignItem(_), None) => { + rewrite_ty(rw_info, Some(bounds), ty_opt, vis) } - (Item(_), Some(ty)) => rewrite_ty(rw_info, Some(bounds), Some(&*ty), vis), (AssocImplItem(_), _) => { - let result = if let Some(ast::Ty { - kind: ast::TyKind::ImplTrait(_, ref bounds), - .. - }) = ty_opt - { - let op_ty = OpaqueType { bounds }; - rewrite_ty(rw_info, None, Some(&op_ty), &DEFAULT_VISIBILITY) + let result = if let Some(ref op_bounds) = op_ty { + let op = OpaqueType { bounds: op_bounds }; + rewrite_ty(rw_info, Some(bounds), Some(&op), &DEFAULT_VISIBILITY) } else { - rewrite_ty(rw_info, None, ty.as_ref(), vis) + rewrite_ty(rw_info, Some(bounds), ty_opt, vis) }?; match defaultness { ast::Defaultness::Default(..) => Some(format!("default {}", result)), _ => Some(result), } } - (AssocTraitItem(_), _) | (ForeignItem(_), _) => { - rewrite_ty(rw_info, Some(bounds), ty.as_ref(), vis) - } } } @@ -1867,6 +1860,12 @@ fn rewrite_static( Some(format!("{}{};", prefix, ty_str)) } } + +// FIXME(calebcartwright) - This is a hack around a bug in the handling of TyKind::ImplTrait. +// This should be removed once that bug is resolved, with the type alias formatting using the +// defined Ty for the RHS directly. +// https://github.com/rust-lang/rustfmt/issues/4373 +// https://github.com/rust-lang/rustfmt/issues/5027 struct OpaqueType<'a> { bounds: &'a ast::GenericBounds, } diff --git a/src/types.rs b/src/types.rs index 9ea90c5e46d..891609783b6 100644 --- a/src/types.rs +++ b/src/types.rs @@ -2,6 +2,7 @@ use std::iter::ExactSizeIterator; use std::ops::Deref; use rustc_ast::ast::{self, FnRetTy, Mutability}; +use rustc_ast::ptr; use rustc_span::{symbol::kw, BytePos, Pos, Span}; use crate::comment::{combine_strs_with_missing_comments, contains_comment}; @@ -1031,6 +1032,13 @@ fn join_bounds_inner( } } +pub(crate) fn opaque_ty(ty: &Option>) -> Option<&ast::GenericBounds> { + ty.as_ref().and_then(|t| match &t.kind { + ast::TyKind::ImplTrait(_, bounds) => Some(bounds), + _ => None, + }) +} + pub(crate) fn can_be_overflowed_type( context: &RewriteContext<'_>, ty: &ast::Ty, -- cgit 1.4.1-3-g733a5 From 196e6765048b8306208ac88d743ab02e8faf4b6b Mon Sep 17 00:00:00 2001 From: mujpao Date: Thu, 18 Nov 2021 17:06:49 -0800 Subject: Preserve normalized comments after last list item --- src/lists.rs | 13 ++- .../issue-4909/wrap-comments-not-normalized.rs | 108 +++++++++++++++++++ tests/source/issue-4909/wrap-comments-true.rs | 109 +++++++++++++++++++ tests/target/issue-4909/wrap-comments-false.rs | 72 +++++++++++++ .../issue-4909/wrap-comments-not-normalized.rs | 118 ++++++++++++++++++++ tests/target/issue-4909/wrap-comments-true.rs | 119 +++++++++++++++++++++ 6 files changed, 535 insertions(+), 4 deletions(-) create mode 100644 tests/source/issue-4909/wrap-comments-not-normalized.rs create mode 100644 tests/source/issue-4909/wrap-comments-true.rs create mode 100644 tests/target/issue-4909/wrap-comments-false.rs create mode 100644 tests/target/issue-4909/wrap-comments-not-normalized.rs create mode 100644 tests/target/issue-4909/wrap-comments-true.rs (limited to 'src') diff --git a/src/lists.rs b/src/lists.rs index d341ec8e6b0..3515dd17251 100644 --- a/src/lists.rs +++ b/src/lists.rs @@ -444,10 +444,15 @@ where let offset = formatting.shape.indent + overhead; let comment_shape = Shape::legacy(width, offset); - // Use block-style only for the last item or multiline comments. - let block_style = !formatting.ends_with_newline && last - || comment.trim().contains('\n') - || comment.trim().len() > width; + let block_style = if !formatting.ends_with_newline && last { + true + } else if starts_with_newline(comment) { + false + } else if comment.trim().contains('\n') || comment.trim().len() > width { + true + } else { + false + }; rewrite_comment( comment.trim_start(), diff --git a/tests/source/issue-4909/wrap-comments-not-normalized.rs b/tests/source/issue-4909/wrap-comments-not-normalized.rs new file mode 100644 index 00000000000..cd8de2707f1 --- /dev/null +++ b/tests/source/issue-4909/wrap-comments-not-normalized.rs @@ -0,0 +1,108 @@ +// rustfmt-wrap_comments: true + +pub enum E { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + Variant1, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + Variant2, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +} + +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 +} + +pub enum E3 { + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + Variant1, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + Variant2, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + +} + +pub struct S { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + some_field: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + last_field: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +} + +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 +} + +pub struct S3 { + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + some_field: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + last_field: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions +} + +fn foo( + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + a: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + b: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +) -> usize { + 5 +} + +fn foo2(// Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +) -> usize { + 5 +} + +fn foo3( + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + a: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + b: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + +) -> usize { + 5 +} + +fn main() { + let v = vec![ + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + 1, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + 2, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + ]; + + let v2: Vec = vec![ + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + ]; + + let v3 = vec![ + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + 1, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + 2, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + ]; +} diff --git a/tests/source/issue-4909/wrap-comments-true.rs b/tests/source/issue-4909/wrap-comments-true.rs new file mode 100644 index 00000000000..f18d8d686e1 --- /dev/null +++ b/tests/source/issue-4909/wrap-comments-true.rs @@ -0,0 +1,109 @@ +// rustfmt-normalize_comments: true +// rustfmt-wrap_comments: true + +pub enum E { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + Variant1, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + Variant2, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +} + +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 +} + +pub enum E3 { + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + Variant1, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + Variant2, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + +} + +pub struct S { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + some_field: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + last_field: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +} + +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 +} + +pub struct S3 { + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + some_field: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + last_field: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions +} + +fn foo( + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + a: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + b: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +) -> usize { + 5 +} + +fn foo2(// Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +) -> usize { + 5 +} + +fn foo3( + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + a: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + b: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + +) -> usize { + 5 +} + +fn main() { + let v = vec![ + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + 1, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + 2, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + ]; + + let v2: Vec = vec![ + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + ]; + + let v3 = vec![ + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + 1, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + 2, + // Expand as needed, numbers should be ascending according to the stage through the inclusion pipeline, or according to the descriptions + ]; +} diff --git a/tests/target/issue-4909/wrap-comments-false.rs b/tests/target/issue-4909/wrap-comments-false.rs new file mode 100644 index 00000000000..a8ead584f44 --- /dev/null +++ b/tests/target/issue-4909/wrap-comments-false.rs @@ -0,0 +1,72 @@ +// rustfmt-normalize_comments: true + +pub enum E { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + Variant1, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + Variant2, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +} + +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 +} + +pub struct S { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + some_field: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + last_field: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +} + +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 +} + +fn foo( + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + a: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + b: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +) -> usize { + 5 +} + +fn foo2(// Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +) -> usize { + 5 +} + +fn main() { + let v = vec![ + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + 1, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + 2, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + ]; + + let v2: Vec = vec![ + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + ]; +} diff --git a/tests/target/issue-4909/wrap-comments-not-normalized.rs b/tests/target/issue-4909/wrap-comments-not-normalized.rs new file mode 100644 index 00000000000..2a3d803b3b1 --- /dev/null +++ b/tests/target/issue-4909/wrap-comments-not-normalized.rs @@ -0,0 +1,118 @@ +// rustfmt-wrap_comments: true + +pub enum E { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + Variant1, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + Variant2, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +} + +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 +} + +pub enum E3 { + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions + Variant1, + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions + Variant2, + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions +} + +pub struct S { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + some_field: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + last_field: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +} + +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 +} + +pub struct S3 { + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions + some_field: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions + last_field: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions +} + +fn foo( + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + a: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + b: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +) -> usize { + 5 +} + +fn foo2(// Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +) -> usize { + 5 +} + +fn foo3( + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions + a: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions + b: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions +) -> usize { + 5 +} + +fn main() { + let v = vec![ + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + 1, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + 2, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + ]; + + let v2: Vec = vec![ + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + ]; + + let v3 = vec![ + // Expand as needed, numbers should be ascending according to the stage through the + // inclusion pipeline, or according to the descriptions + 1, + // Expand as needed, numbers should be ascending according to the stage through the + // inclusion pipeline, or according to the descriptions + 2, + // Expand as needed, numbers should be ascending according to the stage through the + // inclusion pipeline, or according to the descriptions + ]; +} diff --git a/tests/target/issue-4909/wrap-comments-true.rs b/tests/target/issue-4909/wrap-comments-true.rs new file mode 100644 index 00000000000..5376962a2ee --- /dev/null +++ b/tests/target/issue-4909/wrap-comments-true.rs @@ -0,0 +1,119 @@ +// rustfmt-normalize_comments: true +// rustfmt-wrap_comments: true + +pub enum E { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + Variant1, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + Variant2, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +} + +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 +} + +pub enum E3 { + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions + Variant1, + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions + Variant2, + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions +} + +pub struct S { + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + some_field: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + last_field: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +} + +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 +} + +pub struct S3 { + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions + some_field: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions + last_field: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions +} + +fn foo( + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + a: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + b: usize, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +) -> usize { + 5 +} + +fn foo2(// Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions +) -> usize { + 5 +} + +fn foo3( + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions + a: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions + b: usize, + // Expand as needed, numbers should be ascending according to the stage through the inclusion + // pipeline, or according to the descriptions +) -> usize { + 5 +} + +fn main() { + let v = vec![ + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + 1, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + 2, + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + ]; + + let v2: Vec = vec![ + // Expand as needed, numbers should be ascending according to the stage + // through the inclusion pipeline, or according to the descriptions + ]; + + let v3 = vec![ + // Expand as needed, numbers should be ascending according to the stage through the + // inclusion pipeline, or according to the descriptions + 1, + // Expand as needed, numbers should be ascending according to the stage through the + // inclusion pipeline, or according to the descriptions + 2, + // Expand as needed, numbers should be ascending according to the stage through the + // inclusion pipeline, or according to the descriptions + ]; +} -- cgit 1.4.1-3-g733a5 From 4389a4ce49e737915af1f1b27b96b05598a4e388 Mon Sep 17 00:00:00 2001 From: Dom Date: Fri, 19 Nov 2021 20:15:33 +0100 Subject: fix: do not wrap reference-style doc links Prevents wrap_comments from incorrectly wrapping reference-style doc links. --- src/comment.rs | 19 ++++++++++++++++++- tests/target/issue-5095.rs | 27 +++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 tests/target/issue-5095.rs (limited to 'src') diff --git a/src/comment.rs b/src/comment.rs index 7b76c232937..830d2b50aad 100644 --- a/src/comment.rs +++ b/src/comment.rs @@ -3,6 +3,8 @@ use std::{self, borrow::Cow, iter}; use itertools::{multipeek, MultiPeek}; +use lazy_static::lazy_static; +use regex::Regex; use rustc_span::Span; use crate::config::Config; @@ -15,6 +17,17 @@ use crate::utils::{ }; use crate::{ErrorKind, FormattingError}; +lazy_static! { + /// A regex matching reference doc links. + /// + /// ```markdown + /// /// An [example]. + /// /// + /// /// [example]: this::is::a::link + /// ``` + static ref REFERENCE_LINK_URL: Regex = Regex::new(r"^\[.+\]\s?:").unwrap(); +} + fn is_custom_comment(comment: &str) -> bool { if !comment.starts_with("//") { false @@ -842,7 +855,11 @@ fn trim_custom_comment_prefix(s: &str) -> String { /// Returns `true` if the given string MAY include URLs or alike. fn has_url(s: &str) -> bool { // This function may return false positive, but should get its job done in most cases. - s.contains("https://") || s.contains("http://") || s.contains("ftp://") || s.contains("file://") + s.contains("https://") + || s.contains("http://") + || s.contains("ftp://") + || s.contains("file://") + || REFERENCE_LINK_URL.is_match(s) } /// Given the span, rewrite the missing comment inside it if available. diff --git a/tests/target/issue-5095.rs b/tests/target/issue-5095.rs new file mode 100644 index 00000000000..6981a65808c --- /dev/null +++ b/tests/target/issue-5095.rs @@ -0,0 +1,27 @@ +// rustfmt-wrap_comments: true + +pub mod a_long_name { + pub mod b_long_name { + pub mod c_long_name { + pub mod d_long_name { + pub mod e_long_name { + pub struct Bananas; + impl Bananas { + pub fn fantastic() {} + } + + pub mod f_long_name { + pub struct Apples; + } + } + } + } + } +} + +/// Check out [my other struct] ([`Bananas`]) and [the method it has]. +/// +/// [my other struct]: a_long_name::b_long_name::c_long_name::d_long_name::e_long_name::f_long_name::Apples +/// [`Bananas`]: a_long_name::b_long_name::c_long_name::d_long_name::e_long_name::Bananas::fantastic() +/// [the method it has]: a_long_name::b_long_name::c_long_name::d_long_name::e_long_name::Bananas::fantastic() +pub struct A; -- cgit 1.4.1-3-g733a5 From a21f1b6c2a5734f39a1efe3fa84d6475843d14fe Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Sat, 27 Nov 2021 17:14:15 -0500 Subject: Conditionally compile tests based on CFG_RELEASE_CHANNEL env var Adds the ``nightly_only_test`` and ``stable_only_test`` attribute macros that prevent or allow certain tests to compile on nightly and stable respectively. This is achieved through conditionally outputting the tests TokenStream. If CFG_RELEASE_CHANNEL is not set, it's assumed that we're running in a nightly environment. To mark a test as nightly only: #[nightly_only_test] #[test] fn only_run_on_nightly() { ... } To mark a test a stable only: #[stable_only_test] #[test] fn only_run_on_stable() { ... } --- config_proc_macro/src/lib.rs | 42 ++++++++++++++++++++++ src/config/mod.rs | 86 +++++++++++++++++++------------------------- src/syntux/session.rs | 15 +++----- src/test/mod.rs | 13 +++---- 4 files changed, 88 insertions(+), 68 deletions(-) (limited to 'src') diff --git a/config_proc_macro/src/lib.rs b/config_proc_macro/src/lib.rs index 78e7e098ed9..51301821319 100644 --- a/config_proc_macro/src/lib.rs +++ b/config_proc_macro/src/lib.rs @@ -8,6 +8,8 @@ mod item_enum; mod item_struct; mod utils; +use std::str::FromStr; + use proc_macro::TokenStream; use syn::parse_macro_input; @@ -23,3 +25,43 @@ pub fn config_type(_args: TokenStream, input: TokenStream) -> TokenStream { TokenStream::from(output) } + +/// Used to conditionally output the TokenStream for tests that need to be run on nightly only. +/// +/// ```rust +/// #[nightly_only_test] +/// #[test] +/// fn test_needs_nightly_rustfmt() { +/// assert!(true); +/// } +/// ``` +#[proc_macro_attribute] +pub fn nightly_only_test(_args: TokenStream, input: TokenStream) -> TokenStream { + // if CFG_RELEASE_CHANNEL is not set we default to nightly, hence why the default is true + if option_env!("CFG_RELEASE_CHANNEL").map_or(true, |c| c == "nightly" || c == "dev") { + input + } else { + // output an empty token stream if CFG_RELEASE_CHANNEL is not set to "nightly" or "dev" + TokenStream::from_str("").unwrap() + } +} + +/// Used to conditionally output the TokenStream for tests that need to be run on stable only. +/// +/// ```rust +/// #[stable_only_test] +/// #[test] +/// fn test_needs_stable_rustfmt() { +/// assert!(true); +/// } +/// ``` +#[proc_macro_attribute] +pub fn stable_only_test(_args: TokenStream, input: TokenStream) -> TokenStream { + // if CFG_RELEASE_CHANNEL is not set we default to nightly, hence why the default is false + if option_env!("CFG_RELEASE_CHANNEL").map_or(false, |c| c == "stable") { + input + } else { + // output an empty token stream if CFG_RELEASE_CHANNEL is not set or is not 'stable' + TokenStream::from_str("").unwrap() + } +} diff --git a/src/config/mod.rs b/src/config/mod.rs index c5419d860c9..5dbe532ac38 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -405,6 +405,8 @@ mod test { use super::*; use std::str; + use rustfmt_config_proc_macro::{nightly_only_test, stable_only_test}; + #[allow(dead_code)] mod mock { use super::super::*; @@ -525,21 +527,17 @@ mod test { assert!(config.license_template.is_none()); } + #[nightly_only_test] #[test] fn test_valid_license_template_path() { - if !crate::is_nightly_channel!() { - return; - } 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() { - if !crate::is_nightly_channel!() { - return; - } 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()); @@ -634,48 +632,42 @@ make_backup = false assert_eq!(&toml, &default_config); } - // FIXME(#2183): these tests cannot be run in parallel because they use env vars. - // #[test] - // fn test_as_not_nightly_channel() { - // let mut config = Config::default(); - // assert_eq!(config.was_set().unstable_features(), false); - // config.set().unstable_features(true); - // assert_eq!(config.was_set().unstable_features(), false); - // } - - // #[test] - // fn test_as_nightly_channel() { - // let v = ::std::env::var("CFG_RELEASE_CHANNEL").unwrap_or(String::from("")); - // ::std::env::set_var("CFG_RELEASE_CHANNEL", "nightly"); - // let mut config = Config::default(); - // config.set().unstable_features(true); - // assert_eq!(config.was_set().unstable_features(), false); - // config.set().unstable_features(true); - // assert_eq!(config.unstable_features(), true); - // ::std::env::set_var("CFG_RELEASE_CHANNEL", v); - // } - - // #[test] - // fn test_unstable_from_toml() { - // let mut config = Config::from_toml("unstable_features = true").unwrap(); - // assert_eq!(config.was_set().unstable_features(), false); - // let v = ::std::env::var("CFG_RELEASE_CHANNEL").unwrap_or(String::from("")); - // ::std::env::set_var("CFG_RELEASE_CHANNEL", "nightly"); - // config = Config::from_toml("unstable_features = true").unwrap(); - // assert_eq!(config.was_set().unstable_features(), true); - // assert_eq!(config.unstable_features(), true); - // ::std::env::set_var("CFG_RELEASE_CHANNEL", v); - // } + #[stable_only_test] + #[test] + fn test_as_not_nightly_channel() { + let mut config = Config::default(); + assert_eq!(config.was_set().unstable_features(), false); + config.set().unstable_features(true); + assert_eq!(config.was_set().unstable_features(), false); + } + + #[nightly_only_test] + #[test] + fn test_as_nightly_channel() { + let mut config = Config::default(); + config.set().unstable_features(true); + // When we don't set the config from toml or command line options it + // doesn't get marked as set by the user. + assert_eq!(config.was_set().unstable_features(), false); + config.set().unstable_features(true); + assert_eq!(config.unstable_features(), true); + } + + #[nightly_only_test] + #[test] + fn test_unstable_from_toml() { + let config = Config::from_toml("unstable_features = true", Path::new("")).unwrap(); + assert_eq!(config.was_set().unstable_features(), true); + assert_eq!(config.unstable_features(), true); + } #[cfg(test)] mod deprecated_option_merge_imports { use super::*; + #[nightly_only_test] #[test] fn test_old_option_set() { - if !crate::is_nightly_channel!() { - return; - } let toml = r#" unstable_features = true merge_imports = true @@ -684,11 +676,9 @@ make_backup = false assert_eq!(config.imports_granularity(), ImportGranularity::Crate); } + #[nightly_only_test] #[test] fn test_both_set() { - if !crate::is_nightly_channel!() { - return; - } let toml = r#" unstable_features = true merge_imports = true @@ -698,11 +688,9 @@ make_backup = false assert_eq!(config.imports_granularity(), ImportGranularity::Preserve); } + #[nightly_only_test] #[test] fn test_new_overridden() { - if !crate::is_nightly_channel!() { - return; - } let toml = r#" unstable_features = true merge_imports = true @@ -712,11 +700,9 @@ make_backup = false assert_eq!(config.imports_granularity(), ImportGranularity::Preserve); } + #[nightly_only_test] #[test] fn test_old_overridden() { - if !crate::is_nightly_channel!() { - return; - } let toml = r#" unstable_features = true imports_granularity = "Module" diff --git a/src/syntux/session.rs b/src/syntux/session.rs index cdb4893d443..dd7c7352686 100644 --- a/src/syntux/session.rs +++ b/src/syntux/session.rs @@ -286,10 +286,11 @@ impl LineRangeUtils for ParseSess { mod tests { use super::*; + use rustfmt_config_proc_macro::nightly_only_test; + mod emitter { use super::*; use crate::config::IgnoreList; - use crate::is_nightly_channel; use crate::utils::mk_sp; use rustc_span::{FileName as SourceMapFileName, MultiSpan, RealFileName, DUMMY_SP}; use std::path::PathBuf; @@ -371,11 +372,9 @@ mod tests { assert_eq!(can_reset_errors.load(Ordering::Acquire), false); } + #[nightly_only_test] #[test] fn handles_recoverable_parse_error_in_ignored_file() { - if !is_nightly_channel!() { - return; - } let num_emitted_errors = Lrc::new(AtomicU32::new(0)); let can_reset_errors = Lrc::new(AtomicBool::new(false)); let ignore_list = get_ignore_list(r#"ignore = ["foo.rs"]"#); @@ -398,11 +397,9 @@ mod tests { assert_eq!(can_reset_errors.load(Ordering::Acquire), true); } + #[nightly_only_test] #[test] fn handles_recoverable_parse_error_in_non_ignored_file() { - if !is_nightly_channel!() { - return; - } let num_emitted_errors = Lrc::new(AtomicU32::new(0)); let can_reset_errors = Lrc::new(AtomicBool::new(false)); let source_map = Lrc::new(SourceMap::new(FilePathMapping::empty())); @@ -424,11 +421,9 @@ mod tests { assert_eq!(can_reset_errors.load(Ordering::Acquire), false); } + #[nightly_only_test] #[test] fn handles_mix_of_recoverable_parse_error() { - if !is_nightly_channel!() { - return; - } let num_emitted_errors = Lrc::new(AtomicU32::new(0)); let can_reset_errors = Lrc::new(AtomicBool::new(false)); let source_map = Lrc::new(SourceMap::new(FilePathMapping::empty())); diff --git a/src/test/mod.rs b/src/test/mod.rs index e2620508c34..cceb28dfea6 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -15,6 +15,8 @@ use crate::rustfmt_diff::{make_diff, print_diff, DiffLine, Mismatch, ModifiedChu use crate::source_file; use crate::{is_nightly_channel, FormatReport, FormatReportFormatterBuilder, Input, Session}; +use rustfmt_config_proc_macro::nightly_only_test; + mod configuration_snippet; mod mod_resolver; mod parser; @@ -307,14 +309,11 @@ fn assert_output(source: &Path, expected_filename: &Path) { // Idempotence tests. Files in tests/target are checked to be unaltered by // rustfmt. +#[nightly_only_test] #[test] fn idempotence_tests() { init_log(); run_test_with(&TestSetting::default(), || { - // these tests require nightly - if !is_nightly_channel!() { - return; - } // Get all files in the tests/target directory. let files = get_test_files(Path::new("tests/target"), true); let (_reports, count, fails) = check_files(files, &None); @@ -332,13 +331,11 @@ fn idempotence_tests() { // Run rustfmt on itself. This operation must be idempotent. We also check that // no warnings are emitted. +// Issue-3443: these tests require nightly +#[nightly_only_test] #[test] fn self_tests() { init_log(); - // Issue-3443: these tests require nightly - if !is_nightly_channel!() { - return; - } let mut files = get_test_files(Path::new("tests"), false); let bin_directories = vec!["cargo-fmt", "git-rustfmt", "bin", "format-diff"]; for dir in bin_directories { -- cgit 1.4.1-3-g733a5 From 0fc846f979bc20d556cc07177b384094a421c54c Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Sun, 28 Nov 2021 15:22:49 -0600 Subject: refactor: maintain more AST info when formatting a RHS --- src/expr.rs | 57 +++++++++++++++++++++++++++++++++++++++++++++++++-------- src/items.rs | 38 +++++++++++++++++++++++++++++++------- src/macros.rs | 5 +++-- src/types.rs | 5 +++-- 4 files changed, 86 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/expr.rs b/src/expr.rs index 58942e442de..5fd86c1a4ea 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -196,9 +196,10 @@ pub(crate) fn format_expr( capture, is_async, movability, fn_decl, body, expr.span, context, shape, ) } - ast::ExprKind::Try(..) | ast::ExprKind::Field(..) | ast::ExprKind::MethodCall(..) => { - rewrite_chain(expr, context, shape) - } + ast::ExprKind::Try(..) + | ast::ExprKind::Field(..) + | ast::ExprKind::MethodCall(..) + | ast::ExprKind::Await(_) => rewrite_chain(expr, context, shape), ast::ExprKind::MacCall(ref mac) => { rewrite_macro(mac, None, context, shape, MacroPosition::Expression).or_else(|| { wrap_str( @@ -377,7 +378,6 @@ pub(crate) fn format_expr( )) } } - ast::ExprKind::Await(_) => rewrite_chain(expr, context, shape), ast::ExprKind::Underscore => Some("_".to_owned()), ast::ExprKind::Err => None, }; @@ -829,6 +829,7 @@ impl<'a> ControlFlow<'a> { &format!("{}{}{}", matcher, pat_string, self.connector), expr, cond_shape, + &RhsAssignKind::Expr(&expr.kind, expr.span), RhsTactics::Default, comments_span, true, @@ -1839,6 +1840,34 @@ fn rewrite_unary_op( rewrite_unary_prefix(context, ast::UnOp::to_string(op), expr, shape) } +pub(crate) enum RhsAssignKind<'ast> { + Expr(&'ast ast::ExprKind, Span), + Bounds, + Ty, +} + +impl<'ast> RhsAssignKind<'ast> { + // TODO(calebcartwright) + // Preemptive addition for handling RHS with chains, not yet utilized. + // It may make more sense to construct the chain first and then check + // whether there are actually chain elements. + #[allow(dead_code)] + fn is_chain(&self) -> bool { + match self { + RhsAssignKind::Expr(kind, _) => { + matches!( + kind, + ast::ExprKind::Try(..) + | ast::ExprKind::Field(..) + | ast::ExprKind::MethodCall(..) + | ast::ExprKind::Await(_) + ) + } + _ => false, + } + } +} + fn rewrite_assignment( context: &RewriteContext<'_>, lhs: &ast::Expr, @@ -1855,7 +1884,13 @@ fn rewrite_assignment( let lhs_shape = shape.sub_width(operator_str.len() + 1)?; let lhs_str = format!("{} {}", lhs.rewrite(context, lhs_shape)?, operator_str); - rewrite_assign_rhs(context, lhs_str, rhs, shape) + rewrite_assign_rhs( + context, + lhs_str, + rhs, + &RhsAssignKind::Expr(&rhs.kind, rhs.span), + shape, + ) } /// Controls where to put the rhs. @@ -1876,9 +1911,10 @@ pub(crate) fn rewrite_assign_rhs, R: Rewrite>( context: &RewriteContext<'_>, lhs: S, ex: &R, + rhs_kind: &RhsAssignKind<'_>, shape: Shape, ) -> Option { - rewrite_assign_rhs_with(context, lhs, ex, shape, RhsTactics::Default) + rewrite_assign_rhs_with(context, lhs, ex, shape, rhs_kind, RhsTactics::Default) } pub(crate) fn rewrite_assign_rhs_expr( @@ -1886,6 +1922,7 @@ pub(crate) fn rewrite_assign_rhs_expr( lhs: &str, ex: &R, shape: Shape, + rhs_kind: &RhsAssignKind<'_>, rhs_tactics: RhsTactics, ) -> Option { let last_line_width = last_line_width(lhs).saturating_sub(if lhs.contains('\n') { @@ -1910,6 +1947,7 @@ pub(crate) fn rewrite_assign_rhs_expr( ex, orig_shape, ex.rewrite(context, orig_shape), + rhs_kind, rhs_tactics, has_rhs_comment, ) @@ -1920,10 +1958,11 @@ pub(crate) fn rewrite_assign_rhs_with, R: Rewrite>( lhs: S, ex: &R, shape: Shape, + rhs_kind: &RhsAssignKind<'_>, rhs_tactics: RhsTactics, ) -> Option { let lhs = lhs.into(); - let rhs = rewrite_assign_rhs_expr(context, &lhs, ex, shape, rhs_tactics)?; + let rhs = rewrite_assign_rhs_expr(context, &lhs, ex, shape, rhs_kind, rhs_tactics)?; Some(lhs + &rhs) } @@ -1932,6 +1971,7 @@ pub(crate) fn rewrite_assign_rhs_with_comments, R: Rewrite>( lhs: S, ex: &R, shape: Shape, + rhs_kind: &RhsAssignKind<'_>, rhs_tactics: RhsTactics, between_span: Span, allow_extend: bool, @@ -1943,7 +1983,7 @@ pub(crate) fn rewrite_assign_rhs_with_comments, R: Rewrite>( } else { shape }; - let rhs = rewrite_assign_rhs_expr(context, &lhs, ex, shape, rhs_tactics)?; + let rhs = rewrite_assign_rhs_expr(context, &lhs, ex, shape, rhs_kind, rhs_tactics)?; if contains_comment { let rhs = rhs.trim_start(); @@ -1958,6 +1998,7 @@ fn choose_rhs( expr: &R, shape: Shape, orig_rhs: Option, + _rhs_kind: &RhsAssignKind<'_>, rhs_tactics: RhsTactics, has_rhs_comment: bool, ) -> Option { diff --git a/src/items.rs b/src/items.rs index 63c32e012df..3fe827ce696 100644 --- a/src/items.rs +++ b/src/items.rs @@ -18,7 +18,7 @@ use crate::config::lists::*; use crate::config::{BraceStyle, Config, IndentStyle, Version}; use crate::expr::{ is_empty_block, is_simple_block_stmt, rewrite_assign_rhs, rewrite_assign_rhs_with, - rewrite_assign_rhs_with_comments, RhsTactics, + rewrite_assign_rhs_with_comments, RhsAssignKind, RhsTactics, }; use crate::lists::{definitive_tactic, itemize_list, write_list, ListFormatting, Separator}; use crate::macros::{rewrite_macro, MacroPosition}; @@ -116,7 +116,13 @@ impl Rewrite for ast::Local { // 1 = trailing semicolon; let nested_shape = shape.sub_width(1)?; - result = rewrite_assign_rhs(context, result, init, nested_shape)?; + result = rewrite_assign_rhs( + context, + result, + init, + &RhsAssignKind::Expr(&init.kind, init.span), + nested_shape, + )?; // todo else } @@ -564,11 +570,13 @@ impl<'a> FmtVisitor<'a> { let variant_body = if let Some(ref expr) = field.disr_expr { let lhs = format!("{:1$} =", variant_body, pad_discrim_ident_to); + let ex = &*expr.value; rewrite_assign_rhs_with( &context, lhs, - &*expr.value, + ex, shape, + &RhsAssignKind::Expr(&ex.kind, ex.span), RhsTactics::AllowOverflow, )? } else { @@ -1033,6 +1041,7 @@ pub(crate) fn format_trait( result + ":", bounds, shape, + &RhsAssignKind::Bounds, RhsTactics::ForceNextLineWithoutIndent, )?; } @@ -1213,7 +1222,14 @@ pub(crate) fn format_trait_alias( generic_bounds, generics, }; - rewrite_assign_rhs(context, lhs, &trait_alias_bounds, shape.sub_width(1)?).map(|s| s + ";") + rewrite_assign_rhs( + context, + lhs, + &trait_alias_bounds, + &RhsAssignKind::Bounds, + shape.sub_width(1)?, + ) + .map(|s| s + ";") } fn format_unit_struct( @@ -1630,7 +1646,7 @@ fn rewrite_ty( // 1 = `;` let shape = Shape::indented(indent, context.config).sub_width(1)?; - rewrite_assign_rhs(context, lhs, &*ty, shape).map(|s| s + ";") + rewrite_assign_rhs(context, lhs, &*ty, &RhsAssignKind::Ty, shape).map(|s| s + ";") } else { Some(format!("{};", result)) } @@ -1720,7 +1736,7 @@ pub(crate) fn rewrite_struct_field( let is_prefix_empty = prefix.is_empty(); // We must use multiline. We are going to put attributes and a field on different lines. - let field_str = rewrite_assign_rhs(context, prefix, &*field.ty, shape)?; + let field_str = rewrite_assign_rhs(context, prefix, &*field.ty, &RhsAssignKind::Ty, shape)?; // Remove a leading white-space from `rewrite_assign_rhs()` when rewriting a tuple struct. let field_str = if is_prefix_empty { field_str.trim_start() @@ -1850,6 +1866,7 @@ fn rewrite_static( &lhs, &**expr, Shape::legacy(remaining_width, offset.block_only()), + &RhsAssignKind::Expr(&expr.kind, expr.span), RhsTactics::Default, comments_span, true, @@ -3147,7 +3164,14 @@ impl Rewrite for ast::ForeignItem { rewrite_ident(context, self.ident) ); // 1 = ; - rewrite_assign_rhs(context, prefix, &**ty, shape.sub_width(1)?).map(|s| s + ";") + rewrite_assign_rhs( + context, + prefix, + &**ty, + &RhsAssignKind::Ty, + shape.sub_width(1)?, + ) + .map(|s| s + ";") } ast::ForeignItemKind::TyAlias(ref ty_alias) => { let (kind, span) = (&ItemVisitorKind::ForeignItem(&self), self.span); diff --git a/src/macros.rs b/src/macros.rs index ef747638e33..a52568be9ea 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -27,7 +27,7 @@ use crate::comment::{ contains_comment, CharClasses, FindUncommented, FullCodeCharKind, LineClasses, }; use crate::config::lists::*; -use crate::expr::rewrite_array; +use crate::expr::{rewrite_array, rewrite_assign_rhs, RhsAssignKind}; use crate::lists::{itemize_list, write_list, ListFormatting}; use crate::overflow; use crate::rewrite::{Rewrite, RewriteContext}; @@ -1468,10 +1468,11 @@ fn format_lazy_static( id, ty.rewrite(context, nested_shape)? )); - result.push_str(&crate::expr::rewrite_assign_rhs( + result.push_str(&rewrite_assign_rhs( context, stmt, &*expr, + &RhsAssignKind::Expr(&expr.kind, expr.span), nested_shape.sub_width(1)?, )?); result.push(';'); diff --git a/src/types.rs b/src/types.rs index 891609783b6..88f5dc43245 100644 --- a/src/types.rs +++ b/src/types.rs @@ -10,6 +10,7 @@ use crate::config::lists::*; use crate::config::{IndentStyle, TypeDensity, Version}; use crate::expr::{ format_expr, rewrite_assign_rhs, rewrite_call, rewrite_tuple, rewrite_unary_prefix, ExprType, + RhsAssignKind, }; use crate::lists::{ definitive_tactic, itemize_list, write_list, ListFormatting, ListItem, Separator, @@ -430,7 +431,7 @@ impl Rewrite for ast::WherePredicate { format!("{}{}", type_str, colon) }; - rewrite_assign_rhs(context, lhs, bounds, shape)? + rewrite_assign_rhs(context, lhs, bounds, &RhsAssignKind::Bounds, shape)? } ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate { ref lifetime, @@ -443,7 +444,7 @@ impl Rewrite for ast::WherePredicate { .. }) => { let lhs_ty_str = lhs_ty.rewrite(context, shape).map(|lhs| lhs + " =")?; - rewrite_assign_rhs(context, lhs_ty_str, &**rhs_ty, shape)? + rewrite_assign_rhs(context, lhs_ty_str, &**rhs_ty, &RhsAssignKind::Ty, shape)? } }; -- cgit 1.4.1-3-g733a5 From 1f28683ffacebc91b3bc47b94c56690633226ff9 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Sun, 28 Nov 2021 23:39:31 -0500 Subject: Update nightly only test with #[nightly_only_test] attribute --- src/ignore_path.rs | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/ignore_path.rs b/src/ignore_path.rs index d8974e12b8f..7738eee0a76 100644 --- a/src/ignore_path.rs +++ b/src/ignore_path.rs @@ -37,21 +37,17 @@ mod test { 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() { - match option_env!("CFG_RELEASE_CHANNEL") { - // this test requires nightly - None | Some("nightly") => { - 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(); - - assert!(ignore_path_set.is_match(&FileName::Real(PathBuf::from("src/foo.rs")))); - assert!(ignore_path_set.is_match(&FileName::Real(PathBuf::from("bar_dir/baz.rs")))); - assert!(!ignore_path_set.is_match(&FileName::Real(PathBuf::from("src/bar.rs")))); - } - _ => (), - }; + 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(); + + assert!(ignore_path_set.is_match(&FileName::Real(PathBuf::from("src/foo.rs")))); + assert!(ignore_path_set.is_match(&FileName::Real(PathBuf::from("bar_dir/baz.rs")))); + assert!(!ignore_path_set.is_match(&FileName::Real(PathBuf::from("src/bar.rs")))); } } -- cgit 1.4.1-3-g733a5 From ec46ffd981d3d50572f1ad3f6033a7c33d27033f Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Fri, 19 Nov 2021 18:52:52 -0500 Subject: Determine when new comment lines are needed for itemized blocks Fixes 5088 Previously, rustfmt would add a new comment line anytime it reformatted an itemized block within a comment when ``wrap_comments=true``. This would lead to rustfmt adding empty comments with trailing whitespace. Now, new comment lines are only added if the original comment spanned multiple lines, if the comment needs to be wrapped, or if the comment originally started with an empty comment line. --- src/comment.rs | 43 ++++++++++++++++--- ...eeply_nested_long_comment_wrap_comments_true.rs | 33 +++++++++++++++ ..._very_long_itemized_block_wrap_comments_true.rs | 19 +++++++++ .../very_long_comment_wrap_comments_true.rs | 13 ++++++ ...eply_nested_long_comment_wrap_comments_false.rs | 33 +++++++++++++++ ...eeply_nested_long_comment_wrap_comments_true.rs | 49 ++++++++++++++++++++++ ...ulti_line_itemized_block_wrap_comments_false.rs | 17 ++++++++ ...multi_line_itemized_block_wrap_comments_true.rs | 17 ++++++++ ...text_with_itemized_block_wrap_comments_false.rs | 37 ++++++++++++++++ ..._text_with_itemized_block_wrap_comments_true.rs | 37 ++++++++++++++++ ...ngle_line_itemized_block_wrap_comments_false.rs | 9 ++++ ...ingle_line_itemized_block_wrap_comments_true.rs | 9 ++++ ...very_long_itemized_block_wrap_comments_false.rs | 19 +++++++++ ..._very_long_itemized_block_wrap_comments_true.rs | 27 ++++++++++++ ...start_with_empty_comment_wrap_comments_false.rs | 17 ++++++++ .../start_with_empty_comment_wrap_comments_true.rs | 17 ++++++++ .../very_long_comment_wrap_comments_false.rs | 13 ++++++ .../very_long_comment_wrap_comments_true.rs | 21 ++++++++++ 18 files changed, 424 insertions(+), 6 deletions(-) create mode 100644 tests/source/issue-5088/deeply_nested_long_comment_wrap_comments_true.rs create mode 100644 tests/source/issue-5088/start_with_empty_comment_very_long_itemized_block_wrap_comments_true.rs create mode 100644 tests/source/issue-5088/very_long_comment_wrap_comments_true.rs create mode 100644 tests/target/issue-5088/deeply_nested_long_comment_wrap_comments_false.rs create mode 100644 tests/target/issue-5088/deeply_nested_long_comment_wrap_comments_true.rs create mode 100644 tests/target/issue-5088/multi_line_itemized_block_wrap_comments_false.rs create mode 100644 tests/target/issue-5088/multi_line_itemized_block_wrap_comments_true.rs create mode 100644 tests/target/issue-5088/multi_line_text_with_itemized_block_wrap_comments_false.rs create mode 100644 tests/target/issue-5088/multi_line_text_with_itemized_block_wrap_comments_true.rs create mode 100644 tests/target/issue-5088/single_line_itemized_block_wrap_comments_false.rs create mode 100644 tests/target/issue-5088/single_line_itemized_block_wrap_comments_true.rs create mode 100644 tests/target/issue-5088/start_with_empty_comment_very_long_itemized_block_wrap_comments_false.rs create mode 100644 tests/target/issue-5088/start_with_empty_comment_very_long_itemized_block_wrap_comments_true.rs create mode 100644 tests/target/issue-5088/start_with_empty_comment_wrap_comments_false.rs create mode 100644 tests/target/issue-5088/start_with_empty_comment_wrap_comments_true.rs create mode 100644 tests/target/issue-5088/very_long_comment_wrap_comments_false.rs create mode 100644 tests/target/issue-5088/very_long_comment_wrap_comments_true.rs (limited to 'src') diff --git a/src/comment.rs b/src/comment.rs index 830d2b50aad..0f850b9b2f2 100644 --- a/src/comment.rs +++ b/src/comment.rs @@ -519,6 +519,7 @@ struct CommentRewrite<'a> { opener: String, closer: String, line_start: String, + style: CommentStyle<'a>, } impl<'a> CommentRewrite<'a> { @@ -528,10 +529,14 @@ impl<'a> CommentRewrite<'a> { shape: Shape, config: &'a Config, ) -> CommentRewrite<'a> { - let (opener, closer, line_start) = if block_style { - CommentStyle::SingleBullet.to_str_tuplet() + let ((opener, closer, line_start), style) = if block_style { + ( + CommentStyle::SingleBullet.to_str_tuplet(), + CommentStyle::SingleBullet, + ) } else { - comment_style(orig, config.normalize_comments()).to_str_tuplet() + let style = comment_style(orig, config.normalize_comments()); + (style.to_str_tuplet(), style) }; let max_width = shape @@ -564,6 +569,7 @@ impl<'a> CommentRewrite<'a> { opener: opener.to_owned(), closer: closer.to_owned(), line_start: line_start.to_owned(), + style, }; cr.result.push_str(opener); cr @@ -583,6 +589,15 @@ impl<'a> CommentRewrite<'a> { result } + /// Check if any characters were written to the result buffer after the start of the comment. + /// when calling [`CommentRewrite::new()`] the result buffer is initiazlied with the opening + /// characters for the comment. + fn buffer_contains_comment(&self) -> bool { + // if self.result.len() < self.opener.len() then an empty comment is in the buffer + // if self.result.len() > self.opener.len() then a non empty comment is in the buffer + self.result.len() != self.opener.len() + } + fn finish(mut self) -> String { if !self.code_block_buffer.is_empty() { // There is a code block that is not properly enclosed by backticks. @@ -598,7 +613,12 @@ impl<'a> CommentRewrite<'a> { // the last few lines are part of an itemized block self.fmt.shape = Shape::legacy(self.max_width, self.fmt_indent); let item_fmt = ib.create_string_format(&self.fmt); - self.result.push_str(&self.comment_line_separator); + + // only push a comment_line_separator for ItemizedBlocks if the comment is not empty + if self.buffer_contains_comment() { + self.result.push_str(&self.comment_line_separator); + } + self.result.push_str(&ib.opener); match rewrite_string( &ib.trimmed_block_as_string(), @@ -632,7 +652,13 @@ impl<'a> CommentRewrite<'a> { line: &'a str, has_leading_whitespace: bool, ) -> bool { - let is_last = i == count_newlines(orig); + let num_newlines = count_newlines(orig); + let is_last = i == num_newlines; + let needs_new_comment_line = if self.style.is_block_comment() { + num_newlines > 0 || self.buffer_contains_comment() + } else { + self.buffer_contains_comment() + }; if let Some(ref mut ib) = self.item_block { if ib.add_line(line) { @@ -641,7 +667,12 @@ impl<'a> CommentRewrite<'a> { self.is_prev_line_multi_line = false; self.fmt.shape = Shape::legacy(self.max_width, self.fmt_indent); let item_fmt = ib.create_string_format(&self.fmt); - self.result.push_str(&self.comment_line_separator); + + // only push a comment_line_separator if we need to start a new comment line + if needs_new_comment_line { + self.result.push_str(&self.comment_line_separator); + } + self.result.push_str(&ib.opener); match rewrite_string( &ib.trimmed_block_as_string(), diff --git a/tests/source/issue-5088/deeply_nested_long_comment_wrap_comments_true.rs b/tests/source/issue-5088/deeply_nested_long_comment_wrap_comments_true.rs new file mode 100644 index 00000000000..09f68cae424 --- /dev/null +++ b/tests/source/issue-5088/deeply_nested_long_comment_wrap_comments_true.rs @@ -0,0 +1,33 @@ +// rustfmt-wrap_comments: true + +fn main() { + { + { + { + { + { + { + { + { + { + { + { + // - aaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa bbbbbbbbbb bbbbbbbbb bbbbbbbbb ccc cccccccccc ccccccc cccccccc + + // * aaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa bbbbbbbbbb bbbbbbbbb bbbbbbbbb ccc cccccccccc ccccccc cccccccc + + /* - aaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa bbbbbbbbbb bbbbbbbbb bbbbbbbbb ccc cccccccccc ccccccc cccccccc */ + + /* * aaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa bbbbbbbbbb bbbbbbbbb bbbbbbbbb ccc cccccccccc ccccccc cccccccc */ + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; +} diff --git a/tests/source/issue-5088/start_with_empty_comment_very_long_itemized_block_wrap_comments_true.rs b/tests/source/issue-5088/start_with_empty_comment_very_long_itemized_block_wrap_comments_true.rs new file mode 100644 index 00000000000..75f748000f9 --- /dev/null +++ b/tests/source/issue-5088/start_with_empty_comment_very_long_itemized_block_wrap_comments_true.rs @@ -0,0 +1,19 @@ +// rustfmt-wrap_comments: true + +// +// - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +// - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + +// +// * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +// * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + +/* + * - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ +/* + * - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ + +/* + * * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ +/* + * * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ diff --git a/tests/source/issue-5088/very_long_comment_wrap_comments_true.rs b/tests/source/issue-5088/very_long_comment_wrap_comments_true.rs new file mode 100644 index 00000000000..00437f00216 --- /dev/null +++ b/tests/source/issue-5088/very_long_comment_wrap_comments_true.rs @@ -0,0 +1,13 @@ +// rustfmt-wrap_comments: true + +// - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +// - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + +// * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +// * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + +/* - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ +/* - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ + +/* * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ +/* * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ diff --git a/tests/target/issue-5088/deeply_nested_long_comment_wrap_comments_false.rs b/tests/target/issue-5088/deeply_nested_long_comment_wrap_comments_false.rs new file mode 100644 index 00000000000..f4801de0184 --- /dev/null +++ b/tests/target/issue-5088/deeply_nested_long_comment_wrap_comments_false.rs @@ -0,0 +1,33 @@ +// rustfmt-wrap_comments: false + +fn main() { + { + { + { + { + { + { + { + { + { + { + { + // - aaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa bbbbbbbbbb bbbbbbbbb bbbbbbbbb ccc cccccccccc ccccccc cccccccc + + // * aaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa bbbbbbbbbb bbbbbbbbb bbbbbbbbb ccc cccccccccc ccccccc cccccccc + + /* - aaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa bbbbbbbbbb bbbbbbbbb bbbbbbbbb ccc cccccccccc ccccccc cccccccc */ + + /* * aaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa aaaaaaaaa bbbbbbbbbb bbbbbbbbb bbbbbbbbb ccc cccccccccc ccccccc cccccccc */ + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; +} diff --git a/tests/target/issue-5088/deeply_nested_long_comment_wrap_comments_true.rs b/tests/target/issue-5088/deeply_nested_long_comment_wrap_comments_true.rs new file mode 100644 index 00000000000..b289c9f859e --- /dev/null +++ b/tests/target/issue-5088/deeply_nested_long_comment_wrap_comments_true.rs @@ -0,0 +1,49 @@ +// rustfmt-wrap_comments: true + +fn main() { + { + { + { + { + { + { + { + { + { + { + { + // - aaaa aaaaaaaaa aaaaaaaaa + // aaaaaaaaa aaaaaaaaa + // bbbbbbbbbb bbbbbbbbb + // bbbbbbbbb ccc cccccccccc + // ccccccc cccccccc + + // * aaaa aaaaaaaaa aaaaaaaaa + // aaaaaaaaa aaaaaaaaa + // bbbbbbbbbb bbbbbbbbb + // bbbbbbbbb ccc cccccccccc + // ccccccc cccccccc + + /* - aaaa aaaaaaaaa aaaaaaaaa + * aaaaaaaaa aaaaaaaaa + * bbbbbbbbbb bbbbbbbbb + * bbbbbbbbb ccc cccccccccc + * ccccccc cccccccc */ + + /* * aaaa aaaaaaaaa aaaaaaaaa + * aaaaaaaaa aaaaaaaaa + * bbbbbbbbbb bbbbbbbbb + * bbbbbbbbb ccc cccccccccc + * ccccccc cccccccc */ + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; + }; +} diff --git a/tests/target/issue-5088/multi_line_itemized_block_wrap_comments_false.rs b/tests/target/issue-5088/multi_line_itemized_block_wrap_comments_false.rs new file mode 100644 index 00000000000..60beed1b048 --- /dev/null +++ b/tests/target/issue-5088/multi_line_itemized_block_wrap_comments_false.rs @@ -0,0 +1,17 @@ +// rustfmt-wrap_comments: false + +// - some itemized block 1 +// - some itemized block 2 + +// * some itemized block 3 +// * some itemized block 4 + +/* + * - some itemized block 5 + * - some itemized block 6 + */ + +/* + * * some itemized block 7 + * * some itemized block 8 + */ diff --git a/tests/target/issue-5088/multi_line_itemized_block_wrap_comments_true.rs b/tests/target/issue-5088/multi_line_itemized_block_wrap_comments_true.rs new file mode 100644 index 00000000000..84fba4b7c19 --- /dev/null +++ b/tests/target/issue-5088/multi_line_itemized_block_wrap_comments_true.rs @@ -0,0 +1,17 @@ +// rustfmt-wrap_comments: true + +// - some itemized block 1 +// - some itemized block 2 + +// * some itemized block 3 +// * some itemized block 4 + +/* + * - some itemized block 5 + * - some itemized block 6 + */ + +/* + * * some itemized block 7 + * * some itemized block 8 + */ diff --git a/tests/target/issue-5088/multi_line_text_with_itemized_block_wrap_comments_false.rs b/tests/target/issue-5088/multi_line_text_with_itemized_block_wrap_comments_false.rs new file mode 100644 index 00000000000..d1bf44f6c74 --- /dev/null +++ b/tests/target/issue-5088/multi_line_text_with_itemized_block_wrap_comments_false.rs @@ -0,0 +1,37 @@ +// rustfmt-wrap_comments: false + +// Some text +// - some itemized block 1 +// - some itemized block 2 +// Some more text +// - some itemized block 3 +// - some itemized block 4 +// Even more text + +// Some text +// * some itemized block 5 +// * some itemized block 6 +// Some more text +// * some itemized block 7 +// * some itemized block 8 +// Even more text + +/* + * Some text + * - some itemized block 9 + * - some itemized block 10 + * Some more text + * - some itemized block 11 + * - some itemized block 12 + * Even more text + */ + +/* + * Some text + * * some itemized block 13 + * * some itemized block 14 + * Some more text + * * some itemized block 15 + * * some itemized block 16 + * Even more text + */ diff --git a/tests/target/issue-5088/multi_line_text_with_itemized_block_wrap_comments_true.rs b/tests/target/issue-5088/multi_line_text_with_itemized_block_wrap_comments_true.rs new file mode 100644 index 00000000000..f767491f902 --- /dev/null +++ b/tests/target/issue-5088/multi_line_text_with_itemized_block_wrap_comments_true.rs @@ -0,0 +1,37 @@ +// rustfmt-wrap_comments: true + +// Some text +// - some itemized block 1 +// - some itemized block 2 +// Some more text +// - some itemized block 3 +// - some itemized block 4 +// Even more text + +// Some text +// * some itemized block 5 +// * some itemized block 6 +// Some more text +// * some itemized block 7 +// * some itemized block 8 +// Even more text + +/* + * Some text + * - some itemized block 9 + * - some itemized block 10 + * Some more text + * - some itemized block 11 + * - some itemized block 12 + * Even more text + */ + +/* + * Some text + * * some itemized block 13 + * * some itemized block 14 + * Some more text + * * some itemized block 15 + * * some itemized block 16 + * Even more text + */ diff --git a/tests/target/issue-5088/single_line_itemized_block_wrap_comments_false.rs b/tests/target/issue-5088/single_line_itemized_block_wrap_comments_false.rs new file mode 100644 index 00000000000..2cd85c787f9 --- /dev/null +++ b/tests/target/issue-5088/single_line_itemized_block_wrap_comments_false.rs @@ -0,0 +1,9 @@ +// rustfmt-wrap_comments: false + +// - some itemized block 1 + +// * some itemized block 2 + +/* - some itemized block 3 */ + +/* * some itemized block 4 */ diff --git a/tests/target/issue-5088/single_line_itemized_block_wrap_comments_true.rs b/tests/target/issue-5088/single_line_itemized_block_wrap_comments_true.rs new file mode 100644 index 00000000000..e9f343d75d5 --- /dev/null +++ b/tests/target/issue-5088/single_line_itemized_block_wrap_comments_true.rs @@ -0,0 +1,9 @@ +// rustfmt-wrap_comments: true + +// - some itemized block 1 + +// * some itemized block 2 + +/* - some itemized block 3 */ + +/* * some itemized block 4 */ diff --git a/tests/target/issue-5088/start_with_empty_comment_very_long_itemized_block_wrap_comments_false.rs b/tests/target/issue-5088/start_with_empty_comment_very_long_itemized_block_wrap_comments_false.rs new file mode 100644 index 00000000000..97bb7733d18 --- /dev/null +++ b/tests/target/issue-5088/start_with_empty_comment_very_long_itemized_block_wrap_comments_false.rs @@ -0,0 +1,19 @@ +// rustfmt-wrap_comments: false + +// +// - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +// - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + +// +// * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +// * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + +/* + * - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ +/* + * - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ + +/* + * * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ +/* + * * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ diff --git a/tests/target/issue-5088/start_with_empty_comment_very_long_itemized_block_wrap_comments_true.rs b/tests/target/issue-5088/start_with_empty_comment_very_long_itemized_block_wrap_comments_true.rs new file mode 100644 index 00000000000..c8af8383e05 --- /dev/null +++ b/tests/target/issue-5088/start_with_empty_comment_very_long_itemized_block_wrap_comments_true.rs @@ -0,0 +1,27 @@ +// rustfmt-wrap_comments: true + +// +// - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod +// tempor incididunt ut labore et dolore magna aliqua. +// - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod +// tempor incididunt ut labore et dolore magna aliqua. + +// +// * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod +// tempor incididunt ut labore et dolore magna aliqua. +// * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod +// tempor incididunt ut labore et dolore magna aliqua. + +/* + * - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod + * tempor incididunt ut labore et dolore magna aliqua. */ +/* + * - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod + * tempor incididunt ut labore et dolore magna aliqua. */ + +/* + * * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod + * tempor incididunt ut labore et dolore magna aliqua. */ +/* + * * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod + * tempor incididunt ut labore et dolore magna aliqua. */ diff --git a/tests/target/issue-5088/start_with_empty_comment_wrap_comments_false.rs b/tests/target/issue-5088/start_with_empty_comment_wrap_comments_false.rs new file mode 100644 index 00000000000..75cc42c0e66 --- /dev/null +++ b/tests/target/issue-5088/start_with_empty_comment_wrap_comments_false.rs @@ -0,0 +1,17 @@ +// rustfmt-wrap_comments: false + +// +// - some itemized block 1 +// - some itemized block 2 + +// +// * some itemized block 3 +// * some itemized block 4 + +/* + * - some itemized block 5 + * - some itemized block 6 */ + +/* + * * some itemized block 7 + * * some itemized block 8 */ diff --git a/tests/target/issue-5088/start_with_empty_comment_wrap_comments_true.rs b/tests/target/issue-5088/start_with_empty_comment_wrap_comments_true.rs new file mode 100644 index 00000000000..ef2c8f90cd3 --- /dev/null +++ b/tests/target/issue-5088/start_with_empty_comment_wrap_comments_true.rs @@ -0,0 +1,17 @@ +// rustfmt-wrap_comments: true + +// +// - some itemized block 1 +// - some itemized block 2 + +// +// * some itemized block 3 +// * some itemized block 4 + +/* + * - some itemized block 5 + * - some itemized block 6 */ + +/* + * * some itemized block 7 + * * some itemized block 8 */ diff --git a/tests/target/issue-5088/very_long_comment_wrap_comments_false.rs b/tests/target/issue-5088/very_long_comment_wrap_comments_false.rs new file mode 100644 index 00000000000..c826cc5d4da --- /dev/null +++ b/tests/target/issue-5088/very_long_comment_wrap_comments_false.rs @@ -0,0 +1,13 @@ +// rustfmt-wrap_comments: false + +// - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +// - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + +// * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +// * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + +/* - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ +/* - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ + +/* * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ +/* * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.*/ diff --git a/tests/target/issue-5088/very_long_comment_wrap_comments_true.rs b/tests/target/issue-5088/very_long_comment_wrap_comments_true.rs new file mode 100644 index 00000000000..7f764dbd8a2 --- /dev/null +++ b/tests/target/issue-5088/very_long_comment_wrap_comments_true.rs @@ -0,0 +1,21 @@ +// rustfmt-wrap_comments: true + +// - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod +// tempor incididunt ut labore et dolore magna aliqua. +// - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod +// tempor incididunt ut labore et dolore magna aliqua. + +// * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod +// tempor incididunt ut labore et dolore magna aliqua. +// * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod +// tempor incididunt ut labore et dolore magna aliqua. + +/* - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod + * tempor incididunt ut labore et dolore magna aliqua. */ +/* - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod + * tempor incididunt ut labore et dolore magna aliqua. */ + +/* * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod + * tempor incididunt ut labore et dolore magna aliqua. */ +/* * Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod + * tempor incididunt ut labore et dolore magna aliqua. */ -- cgit 1.4.1-3-g733a5 From f40b1d9f1aeabca7a6e28d2d32d8458943111957 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Wed, 24 Nov 2021 18:47:37 -0500 Subject: Backport: Do not touch module with #![rustfmt::skip] (4297) Although the implementation is slightly different than the original PR, the general idea is the same. After collecting all modules we want to exclude formatting those that contain the #![rustfmt::skip] attribute. --- src/formatting.rs | 52 +++++++++++++++++----- src/test/configuration_snippet.rs | 21 +++++---- src/test/mod_resolver.rs | 9 ++++ src/visitor.rs | 13 +++--- tests/mod-resolver/skip-files-issue-5065/foo.rs | 5 +++ .../skip-files-issue-5065/foo/bar/baz.rs | 1 + tests/mod-resolver/skip-files-issue-5065/main.rs | 9 ++++ tests/mod-resolver/skip-files-issue-5065/one.rs | 1 + tests/target/skip/preserve_trailing_comment.rs | 7 +++ 9 files changed, 93 insertions(+), 25 deletions(-) create mode 100644 tests/mod-resolver/skip-files-issue-5065/foo.rs create mode 100644 tests/mod-resolver/skip-files-issue-5065/foo/bar/baz.rs create mode 100644 tests/mod-resolver/skip-files-issue-5065/main.rs create mode 100644 tests/mod-resolver/skip-files-issue-5065/one.rs create mode 100644 tests/target/skip/preserve_trailing_comment.rs (limited to 'src') diff --git a/src/formatting.rs b/src/formatting.rs index 7d0facb8f12..1972b5a87a5 100644 --- a/src/formatting.rs +++ b/src/formatting.rs @@ -5,6 +5,7 @@ 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; @@ -15,7 +16,7 @@ use crate::issues::BadIssueSeeker; use crate::modules::Module; use crate::syntux::parser::{DirectoryOwnership, Parser, ParserError}; use crate::syntux::session::ParseSess; -use crate::utils::count_newlines; +use crate::utils::{contains_skip, count_newlines}; use crate::visitor::FmtVisitor; use crate::{modules, source_file, ErrorKind, FormatReport, Input, Session}; @@ -58,6 +59,39 @@ impl<'b, T: Write + 'b> Session<'b, T> { } } +/// Determine if a module should be skipped. True if the module should be skipped, false otherwise. +fn should_skip_module( + config: &Config, + context: &FormatContext<'_, T>, + input_is_stdin: bool, + main_file: &FileName, + path: &FileName, + module: &Module<'_>, +) -> bool { + if contains_skip(module.attrs()) { + return true; + } + + if config.skip_children() && path != main_file { + return true; + } + + if !input_is_stdin && context.ignore_file(&path) { + return true; + } + + if !config.format_generated_files() { + let source_file = context.parse_session.span_to_file_contents(module.span); + let src = source_file.src.as_ref().expect("SourceFile without src"); + + if is_generated_file(src) { + return true; + } + } + + false +} + // Format an entire crate (or subset of the module tree). fn format_project( input: Input, @@ -97,7 +131,12 @@ fn format_project( directory_ownership.unwrap_or(DirectoryOwnership::UnownedViaBlock), !input_is_stdin && !config.skip_children(), ) - .visit_crate(&krate)?; + .visit_crate(&krate)? + .into_iter() + .filter(|(path, module)| { + !should_skip_module(config, &context, input_is_stdin, &main_file, path, module) + }) + .collect::>(); timer = timer.done_parsing(); @@ -105,15 +144,6 @@ fn format_project( context.parse_session.set_silent_emitter(); for (path, module) in files { - let source_file = context.parse_session.span_to_file_contents(module.span); - let src = source_file.src.as_ref().expect("SourceFile without src"); - - let should_ignore = (!input_is_stdin && context.ignore_file(&path)) - || (!config.format_generated_files() && is_generated_file(src)); - - if (config.skip_children() && path != main_file) || should_ignore { - continue; - } should_emit_verbose(input_is_stdin, config, || println!("Formatting {}", path)); context.format_file(path, &module, is_macro_def)?; } diff --git a/src/test/configuration_snippet.rs b/src/test/configuration_snippet.rs index ef7dd0ddcd1..92949ab576a 100644 --- a/src/test/configuration_snippet.rs +++ b/src/test/configuration_snippet.rs @@ -110,14 +110,7 @@ impl ConfigCodeBlock { assert!(self.code_block.is_some() && self.code_block_start.is_some()); // See if code block begins with #![rustfmt::skip]. - let fmt_skip = self - .code_block - .as_ref() - .unwrap() - .lines() - .nth(0) - .unwrap_or("") - == "#![rustfmt::skip]"; + let fmt_skip = self.fmt_skip(); if self.config_name.is_none() && !fmt_skip { write_message(&format!( @@ -138,6 +131,17 @@ impl ConfigCodeBlock { true } + /// True if the code block starts with #![rustfmt::skip] + fn fmt_skip(&self) -> bool { + self.code_block + .as_ref() + .unwrap() + .lines() + .nth(0) + .unwrap_or("") + == "#![rustfmt::skip]" + } + fn has_parsing_errors(&self, session: &Session<'_, T>) -> bool { if session.has_parsing_errors() { write_message(&format!( @@ -251,6 +255,7 @@ fn configuration_snippet_tests() { let blocks = get_code_blocks(); let failures = blocks .iter() + .filter(|block| !block.fmt_skip()) .map(ConfigCodeBlock::formatted_is_idempotent) .fold(0, |acc, r| acc + (!r as u32)); diff --git a/src/test/mod_resolver.rs b/src/test/mod_resolver.rs index ae4a0d0fccb..ec9ed0f0b8d 100644 --- a/src/test/mod_resolver.rs +++ b/src/test/mod_resolver.rs @@ -41,3 +41,12 @@ fn out_of_line_nested_inline_within_out_of_line() { ], ); } + +#[test] +fn skip_out_of_line_nested_inline_within_out_of_line() { + // See also https://github.com/rust-lang/rustfmt/issues/5065 + verify_mod_resolution( + "tests/mod-resolver/skip-files-issue-5065/main.rs", + &["tests/mod-resolver/skip-files-issue-5065/one.rs"], + ); +} diff --git a/src/visitor.rs b/src/visitor.rs index e4a7be742ab..ba446200232 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -948,12 +948,13 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { pub(crate) fn format_separate_mod(&mut self, m: &Module<'_>, end_pos: BytePos) { self.block_indent = Indent::empty(); - if self.visit_attrs(m.attrs(), ast::AttrStyle::Inner) { - self.push_skipped_with_span(m.attrs(), m.span, m.span); - } else { - self.walk_mod_items(&m.items); - self.format_missing_with_indent(end_pos); - } + let skipped = self.visit_attrs(m.attrs(), ast::AttrStyle::Inner); + assert!( + !skipped, + "Skipping module must be handled before reaching this line." + ); + self.walk_mod_items(&m.items); + self.format_missing_with_indent(end_pos); } pub(crate) fn skip_empty_lines(&mut self, end_pos: BytePos) { diff --git a/tests/mod-resolver/skip-files-issue-5065/foo.rs b/tests/mod-resolver/skip-files-issue-5065/foo.rs new file mode 100644 index 00000000000..74889acf0c3 --- /dev/null +++ b/tests/mod-resolver/skip-files-issue-5065/foo.rs @@ -0,0 +1,5 @@ +#![rustfmt::skip] + +mod bar { + + mod baz;} \ No newline at end of file diff --git a/tests/mod-resolver/skip-files-issue-5065/foo/bar/baz.rs b/tests/mod-resolver/skip-files-issue-5065/foo/bar/baz.rs new file mode 100644 index 00000000000..3519b0ee59c --- /dev/null +++ b/tests/mod-resolver/skip-files-issue-5065/foo/bar/baz.rs @@ -0,0 +1 @@ +fn baz() { } \ No newline at end of file diff --git a/tests/mod-resolver/skip-files-issue-5065/main.rs b/tests/mod-resolver/skip-files-issue-5065/main.rs new file mode 100644 index 00000000000..3122e4f220f --- /dev/null +++ b/tests/mod-resolver/skip-files-issue-5065/main.rs @@ -0,0 +1,9 @@ +#![rustfmt::skip] + +mod foo; +mod one; + +fn main() {println!("Hello, world!"); +} + +// trailing commet diff --git a/tests/mod-resolver/skip-files-issue-5065/one.rs b/tests/mod-resolver/skip-files-issue-5065/one.rs new file mode 100644 index 00000000000..e7eb2c2d64d --- /dev/null +++ b/tests/mod-resolver/skip-files-issue-5065/one.rs @@ -0,0 +1 @@ +struct One { value: String } \ No newline at end of file diff --git a/tests/target/skip/preserve_trailing_comment.rs b/tests/target/skip/preserve_trailing_comment.rs new file mode 100644 index 00000000000..f85de33257c --- /dev/null +++ b/tests/target/skip/preserve_trailing_comment.rs @@ -0,0 +1,7 @@ +#![rustfmt::skip] + +fn main() { + println!("Hello, world!"); +} + +// Trailing Comment -- cgit 1.4.1-3-g733a5 From 740fb57f5ddacddd9bcf074df701bcc50b46e69f Mon Sep 17 00:00:00 2001 From: Matthias Krüger Date: Sun, 12 Dec 2021 20:15:08 +0100 Subject: clippy fixes --- src/bin/main.rs | 2 +- src/expr.rs | 4 +--- src/formatting.rs | 2 +- src/items.rs | 10 +++++----- src/lists.rs | 4 +--- src/visitor.rs | 12 ++++++------ 6 files changed, 15 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/bin/main.rs b/src/bin/main.rs index 9d2e97c9479..4d845547cdf 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.to_string()); + eprintln!("{}", e); 1 } }; diff --git a/src/expr.rs b/src/expr.rs index 5fd86c1a4ea..edd004ac63f 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -2003,9 +2003,7 @@ fn choose_rhs( has_rhs_comment: bool, ) -> Option { match orig_rhs { - Some(ref new_str) if new_str.is_empty() => { - return Some(String::new()); - } + Some(ref new_str) if new_str.is_empty() => Some(String::new()), Some(ref new_str) if !new_str.contains('\n') && unicode_str_width(new_str) <= shape.width => { diff --git a/src/formatting.rs b/src/formatting.rs index 1972b5a87a5..b39480a0ef9 100644 --- a/src/formatting.rs +++ b/src/formatting.rs @@ -76,7 +76,7 @@ fn should_skip_module( return true; } - if !input_is_stdin && context.ignore_file(&path) { + if !input_is_stdin && context.ignore_file(path) { return true; } diff --git a/src/items.rs b/src/items.rs index f36bdba26e9..a77b7c10876 100644 --- a/src/items.rs +++ b/src/items.rs @@ -1535,7 +1535,7 @@ pub(crate) fn rewrite_type_alias<'a, 'b>( // https://rustc-dev-guide.rust-lang.org/opaque-types-type-alias-impl-trait.html // https://github.com/rust-dev-tools/fmt-rfcs/blob/master/guide/items.md#type-aliases match (visitor_kind, &op_ty) { - (Item(_) | AssocTraitItem(_) | ForeignItem(_), Some(ref op_bounds)) => { + (Item(_) | AssocTraitItem(_) | ForeignItem(_), Some(op_bounds)) => { let op = OpaqueType { bounds: op_bounds }; rewrite_ty(rw_info, Some(bounds), Some(&op), vis) } @@ -1543,7 +1543,7 @@ pub(crate) fn rewrite_type_alias<'a, 'b>( rewrite_ty(rw_info, Some(bounds), ty_opt, vis) } (AssocImplItem(_), _) => { - let result = if let Some(ref op_bounds) = op_ty { + let result = if let Some(op_bounds) = op_ty { let op = OpaqueType { bounds: op_bounds }; rewrite_ty(rw_info, Some(bounds), Some(&op), &DEFAULT_VISIBILITY) } else { @@ -3124,7 +3124,7 @@ 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)), + visit::FnKind::Fn(fn_ctxt, self.ident, sig, &self.vis, Some(body)), generics, &sig.decl, self.span, @@ -3137,7 +3137,7 @@ impl Rewrite for ast::ForeignItem { context, shape.indent, self.ident, - &FnSig::from_method_sig(&sig, generics, &self.vis), + &FnSig::from_method_sig(sig, generics, &self.vis), span, FnBraceStyle::None, ) @@ -3166,7 +3166,7 @@ impl Rewrite for ast::ForeignItem { .map(|s| s + ";") } ast::ForeignItemKind::TyAlias(ref ty_alias) => { - let (kind, span) = (&ItemVisitorKind::ForeignItem(&self), self.span); + let (kind, span) = (&ItemVisitorKind::ForeignItem(self), self.span); rewrite_type_alias(ty_alias, context, shape.indent, kind, span) } ast::ForeignItemKind::MacCall(ref mac) => { diff --git a/src/lists.rs b/src/lists.rs index 3515dd17251..7aa0315f18c 100644 --- a/src/lists.rs +++ b/src/lists.rs @@ -448,10 +448,8 @@ where true } else if starts_with_newline(comment) { false - } else if comment.trim().contains('\n') || comment.trim().len() > width { - true } else { - false + comment.trim().contains('\n') || comment.trim().len() > width }; rewrite_comment( diff --git a/src/visitor.rs b/src/visitor.rs index ba446200232..1896a4744fe 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -552,7 +552,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { _ => visit::FnCtxt::Foreign, }; self.visit_fn( - visit::FnKind::Fn(fn_ctxt, item.ident, &sig, &item.vis, Some(body)), + visit::FnKind::Fn(fn_ctxt, item.ident, sig, &item.vis, Some(body)), generics, &sig.decl, item.span, @@ -562,14 +562,14 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { } else { let indent = self.block_indent; let rewrite = self.rewrite_required_fn( - indent, item.ident, &sig, &item.vis, generics, item.span, + indent, item.ident, sig, &item.vis, generics, item.span, ); self.push_rewrite(item.span, rewrite); } } ast::ItemKind::TyAlias(ref ty_alias) => { use ItemVisitorKind::Item; - self.visit_ty_alias_kind(ty_alias, &Item(&item), item.span); + self.visit_ty_alias_kind(ty_alias, &Item(item), item.span); } ast::ItemKind::GlobalAsm(..) => { let snippet = Some(self.snippet(item.span).to_owned()); @@ -619,17 +619,17 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { skip_out_of_file_lines_range_visitor!(self, ai.span); if self.visit_attrs(&ai.attrs, ast::AttrStyle::Outer) { - self.push_skipped_with_span(&ai.attrs.as_slice(), skip_span, skip_span); + self.push_skipped_with_span(ai.attrs.as_slice(), skip_span, skip_span); return; } // TODO(calebcartwright): consider enabling box_patterns feature gate match (&ai.kind, visitor_kind) { (ast::AssocItemKind::Const(..), AssocTraitItem(_)) => { - self.visit_static(&StaticParts::from_trait_item(&ai)) + self.visit_static(&StaticParts::from_trait_item(ai)) } (ast::AssocItemKind::Const(..), AssocImplItem(_)) => { - self.visit_static(&StaticParts::from_impl_item(&ai)) + self.visit_static(&StaticParts::from_impl_item(ai)) } (ast::AssocItemKind::Fn(ref fn_kind), _) => { let ast::Fn { -- cgit 1.4.1-3-g733a5 From 57ac92bf1658a576fdc066b82a37aa3a7de2c96b Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Wed, 17 Nov 2021 20:46:48 -0500 Subject: Prevent duplicate comma when formatting struct pattern with ".." Fixes 5066 When a struct pattern that contained a ".." was formatted, it was assumed that a trailing comma should always be added if the struct fields weren't formatted vertically. Now, a trailing comma is only added if not already included in the reformatted struct fields. --- src/patterns.rs | 7 ++++--- ...lti_line_struct_trailing_comma_always_struct_lit_width_0.rs | 10 ++++++++++ ...ulti_line_struct_trailing_comma_never_struct_lit_width_0.rs | 10 ++++++++++ .../issue-5066/multi_line_struct_with_trailing_comma_always.rs | 10 ++++++++++ .../issue-5066/multi_line_struct_with_trailing_comma_never.rs | 10 ++++++++++ tests/target/issue-5066/with_trailing_comma_always.rs | 5 +++++ tests/target/issue-5066/with_trailing_comma_never.rs | 5 +++++ 7 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 tests/target/issue-5066/multi_line_struct_trailing_comma_always_struct_lit_width_0.rs create mode 100644 tests/target/issue-5066/multi_line_struct_trailing_comma_never_struct_lit_width_0.rs create mode 100644 tests/target/issue-5066/multi_line_struct_with_trailing_comma_always.rs create mode 100644 tests/target/issue-5066/multi_line_struct_with_trailing_comma_never.rs create mode 100644 tests/target/issue-5066/with_trailing_comma_always.rs create mode 100644 tests/target/issue-5066/with_trailing_comma_never.rs (limited to 'src') diff --git a/src/patterns.rs b/src/patterns.rs index a80d63201f9..9b74b35f314 100644 --- a/src/patterns.rs +++ b/src/patterns.rs @@ -318,10 +318,12 @@ fn rewrite_struct_pat( let mut fields_str = write_list(&item_vec, &fmt)?; let one_line_width = h_shape.map_or(0, |shape| shape.width); + let has_trailing_comma = fmt.needs_trailing_separator(); + if ellipsis { if fields_str.contains('\n') || fields_str.len() > one_line_width { // Add a missing trailing comma. - if context.config.trailing_comma() == SeparatorTactic::Never { + if !has_trailing_comma { fields_str.push(','); } fields_str.push('\n'); @@ -329,8 +331,7 @@ fn rewrite_struct_pat( } else { if !fields_str.is_empty() { // there are preceding struct fields being matched on - if tactic == DefinitiveListTactic::Vertical { - // if the tactic is Vertical, write_list already added a trailing , + if has_trailing_comma { fields_str.push(' '); } else { fields_str.push_str(", "); diff --git a/tests/target/issue-5066/multi_line_struct_trailing_comma_always_struct_lit_width_0.rs b/tests/target/issue-5066/multi_line_struct_trailing_comma_always_struct_lit_width_0.rs new file mode 100644 index 00000000000..c7122c67623 --- /dev/null +++ b/tests/target/issue-5066/multi_line_struct_trailing_comma_always_struct_lit_width_0.rs @@ -0,0 +1,10 @@ +// rustfmt-trailing_comma: Always +// rustfmt-struct_lit_single_line: false +// rustfmt-struct_lit_width: 0 + +fn main() { + let Foo { + a, + .. + } = b; +} diff --git a/tests/target/issue-5066/multi_line_struct_trailing_comma_never_struct_lit_width_0.rs b/tests/target/issue-5066/multi_line_struct_trailing_comma_never_struct_lit_width_0.rs new file mode 100644 index 00000000000..68e89c4179f --- /dev/null +++ b/tests/target/issue-5066/multi_line_struct_trailing_comma_never_struct_lit_width_0.rs @@ -0,0 +1,10 @@ +// rustfmt-trailing_comma: Never +// rustfmt-struct_lit_single_line: false +// rustfmt-struct_lit_width: 0 + +fn main() { + let Foo { + a, + .. + } = b; +} diff --git a/tests/target/issue-5066/multi_line_struct_with_trailing_comma_always.rs b/tests/target/issue-5066/multi_line_struct_with_trailing_comma_always.rs new file mode 100644 index 00000000000..3368f070386 --- /dev/null +++ b/tests/target/issue-5066/multi_line_struct_with_trailing_comma_always.rs @@ -0,0 +1,10 @@ +// rustfmt-trailing_comma: Always +// rustfmt-struct_lit_single_line: false + +// There is an issue with how this is formatted. +// formatting should look like ./multi_line_struct_trailing_comma_always_struct_lit_width_0.rs +fn main() { + let Foo { + a, .. + } = b; +} diff --git a/tests/target/issue-5066/multi_line_struct_with_trailing_comma_never.rs b/tests/target/issue-5066/multi_line_struct_with_trailing_comma_never.rs new file mode 100644 index 00000000000..cf63c4c983c --- /dev/null +++ b/tests/target/issue-5066/multi_line_struct_with_trailing_comma_never.rs @@ -0,0 +1,10 @@ +// rustfmt-trailing_comma: Never +// rustfmt-struct_lit_single_line: false + +// There is an issue with how this is formatted. +// formatting should look like ./multi_line_struct_trailing_comma_never_struct_lit_width_0.rs +fn main() { + let Foo { + a, .. + } = b; +} diff --git a/tests/target/issue-5066/with_trailing_comma_always.rs b/tests/target/issue-5066/with_trailing_comma_always.rs new file mode 100644 index 00000000000..e20bcec9316 --- /dev/null +++ b/tests/target/issue-5066/with_trailing_comma_always.rs @@ -0,0 +1,5 @@ +// rustfmt-trailing_comma: Always + +fn main() { + let Foo { a, .. } = b; +} diff --git a/tests/target/issue-5066/with_trailing_comma_never.rs b/tests/target/issue-5066/with_trailing_comma_never.rs new file mode 100644 index 00000000000..8b95bb137bc --- /dev/null +++ b/tests/target/issue-5066/with_trailing_comma_never.rs @@ -0,0 +1,5 @@ +// rustfmt-trailing_comma: Never + +fn main() { + let Foo { a, .. } = b; +} -- cgit 1.4.1-3-g733a5 From 40b73d8feec5938a4b6d542840641eceb563930c Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Mon, 20 Dec 2021 17:55:48 -0600 Subject: refactor: rename syntux mod to parse --- src/formatting.rs | 4 +- src/lib.rs | 4 +- src/modules.rs | 4 +- src/modules/visitor.rs | 4 +- src/parse/mod.rs | 2 + src/parse/parser.rs | 258 +++++++++++++++++++++++++++ src/parse/session.rs | 465 +++++++++++++++++++++++++++++++++++++++++++++++++ src/rewrite.rs | 2 +- src/source_file.rs | 2 +- src/syntux/parser.rs | 258 --------------------------- src/syntux/session.rs | 465 ------------------------------------------------- src/visitor.rs | 2 +- 12 files changed, 736 insertions(+), 734 deletions(-) create mode 100644 src/parse/mod.rs create mode 100644 src/parse/parser.rs create mode 100644 src/parse/session.rs delete mode 100644 src/syntux/parser.rs delete mode 100644 src/syntux/session.rs (limited to 'src') diff --git a/src/formatting.rs b/src/formatting.rs index b39480a0ef9..67cf1232f66 100644 --- a/src/formatting.rs +++ b/src/formatting.rs @@ -14,8 +14,8 @@ use crate::config::{Config, FileName, Verbosity}; use crate::formatting::generated::is_generated_file; use crate::issues::BadIssueSeeker; use crate::modules::Module; -use crate::syntux::parser::{DirectoryOwnership, Parser, ParserError}; -use crate::syntux::session::ParseSess; +use crate::parse::parser::{DirectoryOwnership, Parser, ParserError}; +use crate::parse::session::ParseSess; use crate::utils::{contains_skip, count_newlines}; use crate::visitor::FmtVisitor; use crate::{modules, source_file, ErrorKind, FormatReport, Input, Session}; diff --git a/src/lib.rs b/src/lib.rs index 792a1080f0e..f59ebad97ce 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -40,8 +40,8 @@ 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; -use crate::syntux::parser::DirectoryOwnership; use crate::utils::indent_next_line; pub use crate::config::{ @@ -77,6 +77,7 @@ mod missed_spans; pub(crate) mod modules; mod overflow; mod pairs; +mod parse; mod patterns; mod release_channel; mod reorder; @@ -89,7 +90,6 @@ pub(crate) mod source_map; mod spanned; mod stmt; mod string; -mod syntux; #[cfg(test)] mod test; mod types; diff --git a/src/modules.rs b/src/modules.rs index 9d438a80d94..9c964b274e0 100644 --- a/src/modules.rs +++ b/src/modules.rs @@ -12,10 +12,10 @@ use thiserror::Error; use crate::attr::MetaVisitor; use crate::config::FileName; use crate::items::is_mod_decl; -use crate::syntux::parser::{ +use crate::parse::parser::{ Directory, DirectoryOwnership, ModError, ModulePathSuccess, Parser, ParserError, }; -use crate::syntux::session::ParseSess; +use crate::parse::session::ParseSess; use crate::utils::{contains_skip, mk_sp}; mod visitor; diff --git a/src/modules/visitor.rs b/src/modules/visitor.rs index d5acf3f1cbc..7486a4c4ee1 100644 --- a/src/modules/visitor.rs +++ b/src/modules/visitor.rs @@ -3,8 +3,8 @@ use rustc_ast::visit::Visitor; use rustc_span::Symbol; use crate::attr::MetaVisitor; -use crate::syntux::parser::Parser; -use crate::syntux::session::ParseSess; +use crate::parse::parser::Parser; +use crate::parse::session::ParseSess; pub(crate) struct ModItem { pub(crate) item: ast::Item, diff --git a/src/parse/mod.rs b/src/parse/mod.rs new file mode 100644 index 00000000000..bb7d9ca87d4 --- /dev/null +++ b/src/parse/mod.rs @@ -0,0 +1,2 @@ +pub(crate) mod parser; +pub(crate) mod session; diff --git a/src/parse/parser.rs b/src/parse/parser.rs new file mode 100644 index 00000000000..024b38cebb6 --- /dev/null +++ b/src/parse/parser.rs @@ -0,0 +1,258 @@ +use std::panic::{catch_unwind, AssertUnwindSafe}; +use std::path::{Path, PathBuf}; + +use rustc_ast::token::{DelimToken, TokenKind}; +use rustc_ast::{ast, ptr}; +use rustc_errors::Diagnostic; +use rustc_parse::{ + new_parser_from_file, + parser::{ForceCollect, Parser as RawParser}, +}; +use rustc_span::{sym, symbol::kw, Span}; + +use crate::attr::first_attr_value_str_by_name; +use crate::parse::session::ParseSess; +use crate::Input; + +pub(crate) type DirectoryOwnership = rustc_expand::module::DirOwnership; +pub(crate) type ModulePathSuccess = rustc_expand::module::ModulePathSuccess; +pub(crate) type ModError<'a> = rustc_expand::module::ModError<'a>; + +#[derive(Clone)] +pub(crate) struct Directory { + pub(crate) path: PathBuf, + pub(crate) ownership: DirectoryOwnership, +} + +/// A parser for Rust source code. +pub(crate) struct Parser<'a> { + parser: RawParser<'a>, +} + +/// A builder for the `Parser`. +#[derive(Default)] +pub(crate) struct ParserBuilder<'a> { + sess: Option<&'a ParseSess>, + input: Option, +} + +impl<'a> ParserBuilder<'a> { + pub(crate) fn input(mut self, input: Input) -> ParserBuilder<'a> { + self.input = Some(input); + self + } + + pub(crate) fn sess(mut self, sess: &'a ParseSess) -> ParserBuilder<'a> { + self.sess = Some(sess); + self + } + + pub(crate) fn build(self) -> Result, ParserError> { + let sess = self.sess.ok_or(ParserError::NoParseSess)?; + let input = self.input.ok_or(ParserError::NoInput)?; + + let parser = match Self::parser(sess.inner(), input) { + Ok(p) => p, + Err(db) => { + if let Some(diagnostics) = db { + sess.emit_diagnostics(diagnostics); + return Err(ParserError::ParserCreationError); + } + return Err(ParserError::ParsePanicError); + } + }; + + Ok(Parser { parser }) + } + + fn parser( + sess: &'a rustc_session::parse::ParseSess, + input: Input, + ) -> Result, Option>> { + match input { + Input::File(ref file) => catch_unwind(AssertUnwindSafe(move || { + new_parser_from_file(sess, file, None) + })) + .map_err(|_| None), + Input::Text(text) => rustc_parse::maybe_new_parser_from_source_str( + sess, + rustc_span::FileName::Custom("stdin".to_owned()), + text, + ) + .map_err(Some), + } + } +} + +#[derive(Debug, PartialEq)] +pub(crate) enum ParserError { + NoParseSess, + NoInput, + ParserCreationError, + ParseError, + ParsePanicError, +} + +impl<'a> Parser<'a> { + pub(crate) fn submod_path_from_attr(attrs: &[ast::Attribute], path: &Path) -> Option { + let path_sym = first_attr_value_str_by_name(attrs, sym::path)?; + let path_str = path_sym.as_str(); + + // On windows, the base path might have the form + // `\\?\foo\bar` in which case it does not tolerate + // mixed `/` and `\` separators, so canonicalize + // `/` to `\`. + #[cfg(windows)] + let path_str = path_str.replace("/", "\\"); + + Some(path.join(path_str)) + } + + pub(crate) fn parse_file_as_module( + sess: &'a ParseSess, + path: &Path, + span: Span, + ) -> Result<(Vec, Vec>, Span), ParserError> { + let result = catch_unwind(AssertUnwindSafe(|| { + let mut parser = new_parser_from_file(sess.inner(), path, Some(span)); + match parser.parse_mod(&TokenKind::Eof) { + Ok(result) => Some(result), + Err(mut e) => { + sess.emit_or_cancel_diagnostic(&mut e); + if sess.can_reset_errors() { + sess.reset_errors(); + } + None + } + } + })); + match result { + Ok(Some(m)) if !sess.has_errors() => Ok(m), + Ok(Some(m)) if sess.can_reset_errors() => { + sess.reset_errors(); + Ok(m) + } + Ok(_) => Err(ParserError::ParseError), + Err(..) if path.exists() => Err(ParserError::ParseError), + Err(_) => Err(ParserError::ParsePanicError), + } + } + + pub(crate) fn parse_crate( + input: Input, + sess: &'a ParseSess, + ) -> Result { + let krate = Parser::parse_crate_inner(input, sess)?; + if !sess.has_errors() { + return Ok(krate); + } + + if sess.can_reset_errors() { + sess.reset_errors(); + return Ok(krate); + } + + Err(ParserError::ParseError) + } + + fn parse_crate_inner(input: Input, sess: &'a ParseSess) -> Result { + ParserBuilder::default() + .input(input) + .sess(sess) + .build()? + .parse_crate_mod() + } + + fn parse_crate_mod(&mut self) -> Result { + let mut parser = AssertUnwindSafe(&mut self.parser); + + match catch_unwind(move || parser.parse_crate_mod()) { + Ok(Ok(k)) => Ok(k), + Ok(Err(mut db)) => { + db.emit(); + Err(ParserError::ParseError) + } + Err(_) => Err(ParserError::ParsePanicError), + } + } + + pub(crate) fn parse_cfg_if( + sess: &'a ParseSess, + mac: &'a ast::MacCall, + ) -> Result, &'static str> { + match catch_unwind(AssertUnwindSafe(|| Parser::parse_cfg_if_inner(sess, mac))) { + Ok(Ok(items)) => Ok(items), + Ok(err @ Err(_)) => err, + Err(..) => Err("failed to parse cfg_if!"), + } + } + + fn parse_cfg_if_inner( + sess: &'a ParseSess, + mac: &'a ast::MacCall, + ) -> Result, &'static str> { + let token_stream = mac.args.inner_tokens(); + let mut parser = rustc_parse::stream_to_parser(sess.inner(), token_stream, Some("")); + + let mut items = vec![]; + let mut process_if_cfg = true; + + while parser.token.kind != TokenKind::Eof { + if process_if_cfg { + if !parser.eat_keyword(kw::If) { + return Err("Expected `if`"); + } + // Inner attributes are not actually syntactically permitted here, but we don't + // care about inner vs outer attributes in this position. Our purpose with this + // special case parsing of cfg_if macros is to ensure we can correctly resolve + // imported modules that may have a custom `path` defined. + // + // As such, we just need to advance the parser past the attribute and up to + // to the opening brace. + // See also https://github.com/rust-lang/rust/pull/79433 + parser + .parse_attribute(rustc_parse::parser::attr::InnerAttrPolicy::Permitted) + .map_err(|_| "Failed to parse attributes")?; + } + + if !parser.eat(&TokenKind::OpenDelim(DelimToken::Brace)) { + return Err("Expected an opening brace"); + } + + while parser.token != TokenKind::CloseDelim(DelimToken::Brace) + && parser.token.kind != TokenKind::Eof + { + let item = match parser.parse_item(ForceCollect::No) { + Ok(Some(item_ptr)) => item_ptr.into_inner(), + Ok(None) => continue, + Err(mut err) => { + err.cancel(); + parser.sess.span_diagnostic.reset_err_count(); + return Err( + "Expected item inside cfg_if block, but failed to parse it as an item", + ); + } + }; + if let ast::ItemKind::Mod(..) = item.kind { + items.push(item); + } + } + + if !parser.eat(&TokenKind::CloseDelim(DelimToken::Brace)) { + return Err("Expected a closing brace"); + } + + if parser.eat(&TokenKind::Eof) { + break; + } + + if !parser.eat_keyword(kw::Else) { + return Err("Expected `else`"); + } + + process_if_cfg = parser.token.is_keyword(kw::If); + } + + Ok(items) + } +} diff --git a/src/parse/session.rs b/src/parse/session.rs new file mode 100644 index 00000000000..624fed0d2de --- /dev/null +++ b/src/parse/session.rs @@ -0,0 +1,465 @@ +use std::path::Path; +use std::sync::atomic::{AtomicBool, Ordering}; + +use rustc_data_structures::sync::{Lrc, Send}; +use rustc_errors::emitter::{Emitter, EmitterWriter}; +use rustc_errors::{ColorConfig, Diagnostic, Handler, Level as DiagnosticLevel}; +use rustc_session::parse::ParseSess as RawParseSess; +use rustc_span::{ + source_map::{FilePathMapping, SourceMap}, + symbol, BytePos, Span, +}; + +use crate::config::file_lines::LineRange; +use crate::ignore_path::IgnorePathSet; +use crate::source_map::LineRangeUtils; +use crate::utils::starts_with_newline; +use crate::visitor::SnippetProvider; +use crate::{Config, ErrorKind, FileName}; + +/// ParseSess holds structs necessary for constructing a parser. +pub(crate) struct ParseSess { + parse_sess: RawParseSess, + ignore_path_set: Lrc, + can_reset_errors: Lrc, +} + +/// Emitter which discards every error. +struct SilentEmitter; + +impl Emitter for SilentEmitter { + fn source_map(&self) -> Option<&Lrc> { + None + } + fn emit_diagnostic(&mut self, _db: &Diagnostic) {} +} + +fn silent_emitter() -> Box { + Box::new(SilentEmitter {}) +} + +/// Emit errors against every files expect ones specified in the `ignore_path_set`. +struct SilentOnIgnoredFilesEmitter { + ignore_path_set: Lrc, + source_map: Lrc, + emitter: Box, + has_non_ignorable_parser_errors: bool, + can_reset: Lrc, +} + +impl SilentOnIgnoredFilesEmitter { + fn handle_non_ignoreable_error(&mut self, db: &Diagnostic) { + self.has_non_ignorable_parser_errors = true; + self.can_reset.store(false, Ordering::Release); + self.emitter.emit_diagnostic(db); + } +} + +impl Emitter for SilentOnIgnoredFilesEmitter { + fn source_map(&self) -> Option<&Lrc> { + None + } + fn emit_diagnostic(&mut self, db: &Diagnostic) { + if db.level == DiagnosticLevel::Fatal { + return self.handle_non_ignoreable_error(db); + } + if let Some(primary_span) = &db.span.primary_span() { + let file_name = self.source_map.span_to_filename(*primary_span); + if let rustc_span::FileName::Real(rustc_span::RealFileName::LocalPath(ref path)) = + file_name + { + if self + .ignore_path_set + .is_match(&FileName::Real(path.to_path_buf())) + { + if !self.has_non_ignorable_parser_errors { + self.can_reset.store(true, Ordering::Release); + } + return; + } + }; + } + self.handle_non_ignoreable_error(db); + } +} + +fn default_handler( + source_map: Lrc, + ignore_path_set: Lrc, + can_reset: Lrc, + hide_parse_errors: bool, +) -> Handler { + let supports_color = term::stderr().map_or(false, |term| term.supports_color()); + let color_cfg = if supports_color { + ColorConfig::Auto + } else { + ColorConfig::Never + }; + + let emitter = if hide_parse_errors { + silent_emitter() + } else { + Box::new(EmitterWriter::stderr( + color_cfg, + Some(source_map.clone()), + false, + false, + None, + false, + )) + }; + Handler::with_emitter( + true, + None, + Box::new(SilentOnIgnoredFilesEmitter { + has_non_ignorable_parser_errors: false, + source_map, + emitter, + ignore_path_set, + can_reset, + }), + ) +} + +impl ParseSess { + pub(crate) fn new(config: &Config) -> Result { + let ignore_path_set = match IgnorePathSet::from_ignore_list(&config.ignore()) { + Ok(ignore_path_set) => Lrc::new(ignore_path_set), + Err(e) => return Err(ErrorKind::InvalidGlobPattern(e)), + }; + let source_map = Lrc::new(SourceMap::new(FilePathMapping::empty())); + let can_reset_errors = Lrc::new(AtomicBool::new(false)); + + let handler = default_handler( + Lrc::clone(&source_map), + Lrc::clone(&ignore_path_set), + Lrc::clone(&can_reset_errors), + config.hide_parse_errors(), + ); + let parse_sess = RawParseSess::with_span_handler(handler, source_map); + + Ok(ParseSess { + parse_sess, + ignore_path_set, + can_reset_errors, + }) + } + + 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) + } + + pub(crate) fn is_file_parsed(&self, path: &Path) -> bool { + self.parse_sess + .source_map() + .get_source_file(&rustc_span::FileName::Real( + rustc_span::RealFileName::LocalPath(path.to_path_buf()), + )) + .is_some() + } + + pub(crate) fn ignore_file(&self, path: &FileName) -> bool { + self.ignore_path_set.as_ref().is_match(path) + } + + pub(crate) fn set_silent_emitter(&mut self) { + self.parse_sess.span_diagnostic = Handler::with_emitter(true, None, silent_emitter()); + } + + pub(crate) fn span_to_filename(&self, span: Span) -> FileName { + self.parse_sess.source_map().span_to_filename(span).into() + } + + pub(crate) fn span_to_file_contents(&self, span: Span) -> Lrc { + self.parse_sess + .source_map() + .lookup_source_file(span.data().lo) + } + + pub(crate) fn span_to_first_line_string(&self, span: Span) -> String { + let file_lines = self.parse_sess.source_map().span_to_lines(span).ok(); + + match file_lines { + Some(fl) => fl + .file + .get_line(fl.lines[0].line_index) + .map_or_else(String::new, |s| s.to_string()), + None => String::new(), + } + } + + pub(crate) fn line_of_byte_pos(&self, pos: BytePos) -> usize { + self.parse_sess.source_map().lookup_char_pos(pos).line + } + + pub(crate) fn span_to_debug_info(&self, span: Span) -> String { + self.parse_sess.source_map().span_to_diagnostic_string(span) + } + + pub(crate) fn inner(&self) -> &RawParseSess { + &self.parse_sess + } + + pub(crate) fn snippet_provider(&self, span: Span) -> SnippetProvider { + let source_file = self.parse_sess.source_map().lookup_char_pos(span.lo()).file; + SnippetProvider::new( + source_file.start_pos, + source_file.end_pos, + Lrc::clone(source_file.src.as_ref().unwrap()), + ) + } + + pub(crate) fn get_original_snippet(&self, file_name: &FileName) -> Option> { + self.parse_sess + .source_map() + .get_source_file(&file_name.into()) + .and_then(|source_file| source_file.src.clone()) + } +} + +// Methods that should be restricted within the parse module. +impl ParseSess { + pub(super) fn emit_diagnostics(&self, diagnostics: Vec) { + for diagnostic in diagnostics { + self.parse_sess.span_diagnostic.emit_diagnostic(&diagnostic); + } + } + + pub(crate) fn emit_or_cancel_diagnostic(&self, diagnostic: &mut Diagnostic) { + self.parse_sess.span_diagnostic.emit_diagnostic(diagnostic); + // The Handler will check whether the diagnostic should be emitted + // based on the user's rustfmt configuration and the originating file + // that caused the parser error. If the Handler determined it should skip + // emission then we need to ensure the diagnostic is cancelled. + if !diagnostic.cancelled() { + diagnostic.cancel(); + } + } + + pub(super) fn can_reset_errors(&self) -> bool { + self.can_reset_errors.load(Ordering::Acquire) + } + + pub(super) fn has_errors(&self) -> bool { + self.parse_sess.span_diagnostic.has_errors() + } + + pub(super) fn reset_errors(&self) { + self.parse_sess.span_diagnostic.reset_err_count(); + } +} + +impl LineRangeUtils for ParseSess { + fn lookup_line_range(&self, span: Span) -> LineRange { + let snippet = self + .parse_sess + .source_map() + .span_to_snippet(span) + .unwrap_or_default(); + let lo = self.parse_sess.source_map().lookup_line(span.lo()).unwrap(); + let hi = self.parse_sess.source_map().lookup_line(span.hi()).unwrap(); + + debug_assert_eq!( + lo.sf.name, hi.sf.name, + "span crossed file boundary: lo: {:?}, hi: {:?}", + lo, hi + ); + + // in case the span starts with a newline, the line range is off by 1 without the + // adjustment below + let offset = 1 + if starts_with_newline(&snippet) { 1 } else { 0 }; + // Line numbers start at 1 + LineRange { + file: lo.sf.clone(), + lo: lo.line + offset, + hi: hi.line + offset, + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + use rustfmt_config_proc_macro::nightly_only_test; + + mod emitter { + use super::*; + use crate::config::IgnoreList; + use crate::utils::mk_sp; + use rustc_span::{FileName as SourceMapFileName, MultiSpan, RealFileName, DUMMY_SP}; + use std::path::PathBuf; + use std::sync::atomic::AtomicU32; + + struct TestEmitter { + num_emitted_errors: Lrc, + } + + impl Emitter for TestEmitter { + fn source_map(&self) -> Option<&Lrc> { + None + } + fn emit_diagnostic(&mut self, _db: &Diagnostic) { + self.num_emitted_errors.fetch_add(1, Ordering::Release); + } + } + + fn build_diagnostic(level: DiagnosticLevel, span: Option) -> Diagnostic { + Diagnostic { + level, + code: None, + message: vec![], + children: vec![], + suggestions: vec![], + span: span.unwrap_or_else(MultiSpan::new), + sort_span: DUMMY_SP, + is_lint: false, + } + } + + fn build_emitter( + num_emitted_errors: Lrc, + can_reset: Lrc, + source_map: Option>, + ignore_list: Option, + ) -> SilentOnIgnoredFilesEmitter { + let emitter_writer = TestEmitter { num_emitted_errors }; + let source_map = + source_map.unwrap_or_else(|| Lrc::new(SourceMap::new(FilePathMapping::empty()))); + let ignore_path_set = Lrc::new( + IgnorePathSet::from_ignore_list(&ignore_list.unwrap_or_default()).unwrap(), + ); + SilentOnIgnoredFilesEmitter { + has_non_ignorable_parser_errors: false, + source_map, + emitter: Box::new(emitter_writer), + ignore_path_set, + can_reset, + } + } + + fn get_ignore_list(config: &str) -> IgnoreList { + Config::from_toml(config, Path::new("")).unwrap().ignore() + } + + #[test] + fn handles_fatal_parse_error_in_ignored_file() { + let num_emitted_errors = Lrc::new(AtomicU32::new(0)); + let can_reset_errors = Lrc::new(AtomicBool::new(false)); + let ignore_list = get_ignore_list(r#"ignore = ["foo.rs"]"#); + let source_map = Lrc::new(SourceMap::new(FilePathMapping::empty())); + let source = + String::from(r#"extern "system" fn jni_symbol!( funcName ) ( ... ) -> {} "#); + source_map.new_source_file( + SourceMapFileName::Real(RealFileName::LocalPath(PathBuf::from("foo.rs"))), + source, + ); + let mut emitter = build_emitter( + Lrc::clone(&num_emitted_errors), + Lrc::clone(&can_reset_errors), + Some(Lrc::clone(&source_map)), + Some(ignore_list), + ); + let span = MultiSpan::from_span(mk_sp(BytePos(0), BytePos(1))); + let fatal_diagnostic = build_diagnostic(DiagnosticLevel::Fatal, Some(span)); + emitter.emit_diagnostic(&fatal_diagnostic); + assert_eq!(num_emitted_errors.load(Ordering::Acquire), 1); + assert_eq!(can_reset_errors.load(Ordering::Acquire), false); + } + + #[nightly_only_test] + #[test] + fn handles_recoverable_parse_error_in_ignored_file() { + let num_emitted_errors = Lrc::new(AtomicU32::new(0)); + let can_reset_errors = Lrc::new(AtomicBool::new(false)); + let ignore_list = get_ignore_list(r#"ignore = ["foo.rs"]"#); + let source_map = Lrc::new(SourceMap::new(FilePathMapping::empty())); + let source = String::from(r#"pub fn bar() { 1x; }"#); + source_map.new_source_file( + SourceMapFileName::Real(RealFileName::LocalPath(PathBuf::from("foo.rs"))), + source, + ); + let mut emitter = build_emitter( + Lrc::clone(&num_emitted_errors), + Lrc::clone(&can_reset_errors), + Some(Lrc::clone(&source_map)), + Some(ignore_list), + ); + let span = MultiSpan::from_span(mk_sp(BytePos(0), BytePos(1))); + let non_fatal_diagnostic = build_diagnostic(DiagnosticLevel::Warning, Some(span)); + emitter.emit_diagnostic(&non_fatal_diagnostic); + assert_eq!(num_emitted_errors.load(Ordering::Acquire), 0); + assert_eq!(can_reset_errors.load(Ordering::Acquire), true); + } + + #[nightly_only_test] + #[test] + fn handles_recoverable_parse_error_in_non_ignored_file() { + let num_emitted_errors = Lrc::new(AtomicU32::new(0)); + let can_reset_errors = Lrc::new(AtomicBool::new(false)); + let source_map = Lrc::new(SourceMap::new(FilePathMapping::empty())); + let source = String::from(r#"pub fn bar() { 1x; }"#); + source_map.new_source_file( + SourceMapFileName::Real(RealFileName::LocalPath(PathBuf::from("foo.rs"))), + source, + ); + let mut emitter = build_emitter( + Lrc::clone(&num_emitted_errors), + Lrc::clone(&can_reset_errors), + Some(Lrc::clone(&source_map)), + None, + ); + let span = MultiSpan::from_span(mk_sp(BytePos(0), BytePos(1))); + let non_fatal_diagnostic = build_diagnostic(DiagnosticLevel::Warning, Some(span)); + emitter.emit_diagnostic(&non_fatal_diagnostic); + assert_eq!(num_emitted_errors.load(Ordering::Acquire), 1); + assert_eq!(can_reset_errors.load(Ordering::Acquire), false); + } + + #[nightly_only_test] + #[test] + fn handles_mix_of_recoverable_parse_error() { + let num_emitted_errors = Lrc::new(AtomicU32::new(0)); + let can_reset_errors = Lrc::new(AtomicBool::new(false)); + let source_map = Lrc::new(SourceMap::new(FilePathMapping::empty())); + let ignore_list = get_ignore_list(r#"ignore = ["foo.rs"]"#); + let bar_source = String::from(r#"pub fn bar() { 1x; }"#); + let foo_source = String::from(r#"pub fn foo() { 1x; }"#); + let fatal_source = + String::from(r#"extern "system" fn jni_symbol!( funcName ) ( ... ) -> {} "#); + source_map.new_source_file( + SourceMapFileName::Real(RealFileName::LocalPath(PathBuf::from("bar.rs"))), + bar_source, + ); + source_map.new_source_file( + SourceMapFileName::Real(RealFileName::LocalPath(PathBuf::from("foo.rs"))), + foo_source, + ); + source_map.new_source_file( + SourceMapFileName::Real(RealFileName::LocalPath(PathBuf::from("fatal.rs"))), + fatal_source, + ); + let mut emitter = build_emitter( + Lrc::clone(&num_emitted_errors), + Lrc::clone(&can_reset_errors), + Some(Lrc::clone(&source_map)), + Some(ignore_list), + ); + let bar_span = MultiSpan::from_span(mk_sp(BytePos(0), BytePos(1))); + let foo_span = MultiSpan::from_span(mk_sp(BytePos(21), BytePos(22))); + let bar_diagnostic = build_diagnostic(DiagnosticLevel::Warning, Some(bar_span)); + let foo_diagnostic = build_diagnostic(DiagnosticLevel::Warning, Some(foo_span)); + let fatal_diagnostic = build_diagnostic(DiagnosticLevel::Fatal, None); + emitter.emit_diagnostic(&bar_diagnostic); + emitter.emit_diagnostic(&foo_diagnostic); + emitter.emit_diagnostic(&fatal_diagnostic); + assert_eq!(num_emitted_errors.load(Ordering::Acquire), 2); + assert_eq!(can_reset_errors.load(Ordering::Acquire), false); + } + } +} diff --git a/src/rewrite.rs b/src/rewrite.rs index c8abe70141b..4a3bd129d16 100644 --- a/src/rewrite.rs +++ b/src/rewrite.rs @@ -7,9 +7,9 @@ use rustc_ast::ptr; use rustc_span::Span; use crate::config::{Config, IndentStyle}; +use crate::parse::session::ParseSess; use crate::shape::Shape; use crate::skip::SkipContext; -use crate::syntux::session::ParseSess; use crate::visitor::SnippetProvider; use crate::FormatReport; diff --git a/src/source_file.rs b/src/source_file.rs index 853336004d8..56d4ab40038 100644 --- a/src/source_file.rs +++ b/src/source_file.rs @@ -4,7 +4,7 @@ use std::path::Path; use crate::config::FileName; use crate::emitter::{self, Emitter}; -use crate::syntux::session::ParseSess; +use crate::parse::session::ParseSess; use crate::NewlineStyle; #[cfg(test)] diff --git a/src/syntux/parser.rs b/src/syntux/parser.rs deleted file mode 100644 index 23d065c9cc9..00000000000 --- a/src/syntux/parser.rs +++ /dev/null @@ -1,258 +0,0 @@ -use std::panic::{catch_unwind, AssertUnwindSafe}; -use std::path::{Path, PathBuf}; - -use rustc_ast::token::{DelimToken, TokenKind}; -use rustc_ast::{ast, ptr}; -use rustc_errors::Diagnostic; -use rustc_parse::{ - new_parser_from_file, - parser::{ForceCollect, Parser as RawParser}, -}; -use rustc_span::{sym, symbol::kw, Span}; - -use crate::attr::first_attr_value_str_by_name; -use crate::syntux::session::ParseSess; -use crate::Input; - -pub(crate) type DirectoryOwnership = rustc_expand::module::DirOwnership; -pub(crate) type ModulePathSuccess = rustc_expand::module::ModulePathSuccess; -pub(crate) type ModError<'a> = rustc_expand::module::ModError<'a>; - -#[derive(Clone)] -pub(crate) struct Directory { - pub(crate) path: PathBuf, - pub(crate) ownership: DirectoryOwnership, -} - -/// A parser for Rust source code. -pub(crate) struct Parser<'a> { - parser: RawParser<'a>, -} - -/// A builder for the `Parser`. -#[derive(Default)] -pub(crate) struct ParserBuilder<'a> { - sess: Option<&'a ParseSess>, - input: Option, -} - -impl<'a> ParserBuilder<'a> { - pub(crate) fn input(mut self, input: Input) -> ParserBuilder<'a> { - self.input = Some(input); - self - } - - pub(crate) fn sess(mut self, sess: &'a ParseSess) -> ParserBuilder<'a> { - self.sess = Some(sess); - self - } - - pub(crate) fn build(self) -> Result, ParserError> { - let sess = self.sess.ok_or(ParserError::NoParseSess)?; - let input = self.input.ok_or(ParserError::NoInput)?; - - let parser = match Self::parser(sess.inner(), input) { - Ok(p) => p, - Err(db) => { - if let Some(diagnostics) = db { - sess.emit_diagnostics(diagnostics); - return Err(ParserError::ParserCreationError); - } - return Err(ParserError::ParsePanicError); - } - }; - - Ok(Parser { parser }) - } - - fn parser( - sess: &'a rustc_session::parse::ParseSess, - input: Input, - ) -> Result, Option>> { - match input { - Input::File(ref file) => catch_unwind(AssertUnwindSafe(move || { - new_parser_from_file(sess, file, None) - })) - .map_err(|_| None), - Input::Text(text) => rustc_parse::maybe_new_parser_from_source_str( - sess, - rustc_span::FileName::Custom("stdin".to_owned()), - text, - ) - .map_err(Some), - } - } -} - -#[derive(Debug, PartialEq)] -pub(crate) enum ParserError { - NoParseSess, - NoInput, - ParserCreationError, - ParseError, - ParsePanicError, -} - -impl<'a> Parser<'a> { - pub(crate) fn submod_path_from_attr(attrs: &[ast::Attribute], path: &Path) -> Option { - let path_sym = first_attr_value_str_by_name(attrs, sym::path)?; - let path_str = path_sym.as_str(); - - // On windows, the base path might have the form - // `\\?\foo\bar` in which case it does not tolerate - // mixed `/` and `\` separators, so canonicalize - // `/` to `\`. - #[cfg(windows)] - let path_str = path_str.replace("/", "\\"); - - Some(path.join(path_str)) - } - - pub(crate) fn parse_file_as_module( - sess: &'a ParseSess, - path: &Path, - span: Span, - ) -> Result<(Vec, Vec>, Span), ParserError> { - let result = catch_unwind(AssertUnwindSafe(|| { - let mut parser = new_parser_from_file(sess.inner(), path, Some(span)); - match parser.parse_mod(&TokenKind::Eof) { - Ok(result) => Some(result), - Err(mut e) => { - sess.emit_or_cancel_diagnostic(&mut e); - if sess.can_reset_errors() { - sess.reset_errors(); - } - None - } - } - })); - match result { - Ok(Some(m)) if !sess.has_errors() => Ok(m), - Ok(Some(m)) if sess.can_reset_errors() => { - sess.reset_errors(); - Ok(m) - } - Ok(_) => Err(ParserError::ParseError), - Err(..) if path.exists() => Err(ParserError::ParseError), - Err(_) => Err(ParserError::ParsePanicError), - } - } - - pub(crate) fn parse_crate( - input: Input, - sess: &'a ParseSess, - ) -> Result { - let krate = Parser::parse_crate_inner(input, sess)?; - if !sess.has_errors() { - return Ok(krate); - } - - if sess.can_reset_errors() { - sess.reset_errors(); - return Ok(krate); - } - - Err(ParserError::ParseError) - } - - fn parse_crate_inner(input: Input, sess: &'a ParseSess) -> Result { - ParserBuilder::default() - .input(input) - .sess(sess) - .build()? - .parse_crate_mod() - } - - fn parse_crate_mod(&mut self) -> Result { - let mut parser = AssertUnwindSafe(&mut self.parser); - - match catch_unwind(move || parser.parse_crate_mod()) { - Ok(Ok(k)) => Ok(k), - Ok(Err(mut db)) => { - db.emit(); - Err(ParserError::ParseError) - } - Err(_) => Err(ParserError::ParsePanicError), - } - } - - pub(crate) fn parse_cfg_if( - sess: &'a ParseSess, - mac: &'a ast::MacCall, - ) -> Result, &'static str> { - match catch_unwind(AssertUnwindSafe(|| Parser::parse_cfg_if_inner(sess, mac))) { - Ok(Ok(items)) => Ok(items), - Ok(err @ Err(_)) => err, - Err(..) => Err("failed to parse cfg_if!"), - } - } - - fn parse_cfg_if_inner( - sess: &'a ParseSess, - mac: &'a ast::MacCall, - ) -> Result, &'static str> { - let token_stream = mac.args.inner_tokens(); - let mut parser = rustc_parse::stream_to_parser(sess.inner(), token_stream, Some("")); - - let mut items = vec![]; - let mut process_if_cfg = true; - - while parser.token.kind != TokenKind::Eof { - if process_if_cfg { - if !parser.eat_keyword(kw::If) { - return Err("Expected `if`"); - } - // Inner attributes are not actually syntactically permitted here, but we don't - // care about inner vs outer attributes in this position. Our purpose with this - // special case parsing of cfg_if macros is to ensure we can correctly resolve - // imported modules that may have a custom `path` defined. - // - // As such, we just need to advance the parser past the attribute and up to - // to the opening brace. - // See also https://github.com/rust-lang/rust/pull/79433 - parser - .parse_attribute(rustc_parse::parser::attr::InnerAttrPolicy::Permitted) - .map_err(|_| "Failed to parse attributes")?; - } - - if !parser.eat(&TokenKind::OpenDelim(DelimToken::Brace)) { - return Err("Expected an opening brace"); - } - - while parser.token != TokenKind::CloseDelim(DelimToken::Brace) - && parser.token.kind != TokenKind::Eof - { - let item = match parser.parse_item(ForceCollect::No) { - Ok(Some(item_ptr)) => item_ptr.into_inner(), - Ok(None) => continue, - Err(mut err) => { - err.cancel(); - parser.sess.span_diagnostic.reset_err_count(); - return Err( - "Expected item inside cfg_if block, but failed to parse it as an item", - ); - } - }; - if let ast::ItemKind::Mod(..) = item.kind { - items.push(item); - } - } - - if !parser.eat(&TokenKind::CloseDelim(DelimToken::Brace)) { - return Err("Expected a closing brace"); - } - - if parser.eat(&TokenKind::Eof) { - break; - } - - if !parser.eat_keyword(kw::Else) { - return Err("Expected `else`"); - } - - process_if_cfg = parser.token.is_keyword(kw::If); - } - - Ok(items) - } -} diff --git a/src/syntux/session.rs b/src/syntux/session.rs deleted file mode 100644 index dd7c7352686..00000000000 --- a/src/syntux/session.rs +++ /dev/null @@ -1,465 +0,0 @@ -use std::path::Path; -use std::sync::atomic::{AtomicBool, Ordering}; - -use rustc_data_structures::sync::{Lrc, Send}; -use rustc_errors::emitter::{Emitter, EmitterWriter}; -use rustc_errors::{ColorConfig, Diagnostic, Handler, Level as DiagnosticLevel}; -use rustc_session::parse::ParseSess as RawParseSess; -use rustc_span::{ - source_map::{FilePathMapping, SourceMap}, - symbol, BytePos, Span, -}; - -use crate::config::file_lines::LineRange; -use crate::ignore_path::IgnorePathSet; -use crate::source_map::LineRangeUtils; -use crate::utils::starts_with_newline; -use crate::visitor::SnippetProvider; -use crate::{Config, ErrorKind, FileName}; - -/// ParseSess holds structs necessary for constructing a parser. -pub(crate) struct ParseSess { - parse_sess: RawParseSess, - ignore_path_set: Lrc, - can_reset_errors: Lrc, -} - -/// Emitter which discards every error. -struct SilentEmitter; - -impl Emitter for SilentEmitter { - fn source_map(&self) -> Option<&Lrc> { - None - } - fn emit_diagnostic(&mut self, _db: &Diagnostic) {} -} - -fn silent_emitter() -> Box { - Box::new(SilentEmitter {}) -} - -/// Emit errors against every files expect ones specified in the `ignore_path_set`. -struct SilentOnIgnoredFilesEmitter { - ignore_path_set: Lrc, - source_map: Lrc, - emitter: Box, - has_non_ignorable_parser_errors: bool, - can_reset: Lrc, -} - -impl SilentOnIgnoredFilesEmitter { - fn handle_non_ignoreable_error(&mut self, db: &Diagnostic) { - self.has_non_ignorable_parser_errors = true; - self.can_reset.store(false, Ordering::Release); - self.emitter.emit_diagnostic(db); - } -} - -impl Emitter for SilentOnIgnoredFilesEmitter { - fn source_map(&self) -> Option<&Lrc> { - None - } - fn emit_diagnostic(&mut self, db: &Diagnostic) { - if db.level == DiagnosticLevel::Fatal { - return self.handle_non_ignoreable_error(db); - } - if let Some(primary_span) = &db.span.primary_span() { - let file_name = self.source_map.span_to_filename(*primary_span); - if let rustc_span::FileName::Real(rustc_span::RealFileName::LocalPath(ref path)) = - file_name - { - if self - .ignore_path_set - .is_match(&FileName::Real(path.to_path_buf())) - { - if !self.has_non_ignorable_parser_errors { - self.can_reset.store(true, Ordering::Release); - } - return; - } - }; - } - self.handle_non_ignoreable_error(db); - } -} - -fn default_handler( - source_map: Lrc, - ignore_path_set: Lrc, - can_reset: Lrc, - hide_parse_errors: bool, -) -> Handler { - let supports_color = term::stderr().map_or(false, |term| term.supports_color()); - let color_cfg = if supports_color { - ColorConfig::Auto - } else { - ColorConfig::Never - }; - - let emitter = if hide_parse_errors { - silent_emitter() - } else { - Box::new(EmitterWriter::stderr( - color_cfg, - Some(source_map.clone()), - false, - false, - None, - false, - )) - }; - Handler::with_emitter( - true, - None, - Box::new(SilentOnIgnoredFilesEmitter { - has_non_ignorable_parser_errors: false, - source_map, - emitter, - ignore_path_set, - can_reset, - }), - ) -} - -impl ParseSess { - pub(crate) fn new(config: &Config) -> Result { - let ignore_path_set = match IgnorePathSet::from_ignore_list(&config.ignore()) { - Ok(ignore_path_set) => Lrc::new(ignore_path_set), - Err(e) => return Err(ErrorKind::InvalidGlobPattern(e)), - }; - let source_map = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let can_reset_errors = Lrc::new(AtomicBool::new(false)); - - let handler = default_handler( - Lrc::clone(&source_map), - Lrc::clone(&ignore_path_set), - Lrc::clone(&can_reset_errors), - config.hide_parse_errors(), - ); - let parse_sess = RawParseSess::with_span_handler(handler, source_map); - - Ok(ParseSess { - parse_sess, - ignore_path_set, - can_reset_errors, - }) - } - - 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) - } - - pub(crate) fn is_file_parsed(&self, path: &Path) -> bool { - self.parse_sess - .source_map() - .get_source_file(&rustc_span::FileName::Real( - rustc_span::RealFileName::LocalPath(path.to_path_buf()), - )) - .is_some() - } - - pub(crate) fn ignore_file(&self, path: &FileName) -> bool { - self.ignore_path_set.as_ref().is_match(path) - } - - pub(crate) fn set_silent_emitter(&mut self) { - self.parse_sess.span_diagnostic = Handler::with_emitter(true, None, silent_emitter()); - } - - pub(crate) fn span_to_filename(&self, span: Span) -> FileName { - self.parse_sess.source_map().span_to_filename(span).into() - } - - pub(crate) fn span_to_file_contents(&self, span: Span) -> Lrc { - self.parse_sess - .source_map() - .lookup_source_file(span.data().lo) - } - - pub(crate) fn span_to_first_line_string(&self, span: Span) -> String { - let file_lines = self.parse_sess.source_map().span_to_lines(span).ok(); - - match file_lines { - Some(fl) => fl - .file - .get_line(fl.lines[0].line_index) - .map_or_else(String::new, |s| s.to_string()), - None => String::new(), - } - } - - pub(crate) fn line_of_byte_pos(&self, pos: BytePos) -> usize { - self.parse_sess.source_map().lookup_char_pos(pos).line - } - - pub(crate) fn span_to_debug_info(&self, span: Span) -> String { - self.parse_sess.source_map().span_to_diagnostic_string(span) - } - - pub(crate) fn inner(&self) -> &RawParseSess { - &self.parse_sess - } - - pub(crate) fn snippet_provider(&self, span: Span) -> SnippetProvider { - let source_file = self.parse_sess.source_map().lookup_char_pos(span.lo()).file; - SnippetProvider::new( - source_file.start_pos, - source_file.end_pos, - Lrc::clone(source_file.src.as_ref().unwrap()), - ) - } - - pub(crate) fn get_original_snippet(&self, file_name: &FileName) -> Option> { - self.parse_sess - .source_map() - .get_source_file(&file_name.into()) - .and_then(|source_file| source_file.src.clone()) - } -} - -// Methods that should be restricted within the syntux module. -impl ParseSess { - pub(super) fn emit_diagnostics(&self, diagnostics: Vec) { - for diagnostic in diagnostics { - self.parse_sess.span_diagnostic.emit_diagnostic(&diagnostic); - } - } - - pub(crate) fn emit_or_cancel_diagnostic(&self, diagnostic: &mut Diagnostic) { - self.parse_sess.span_diagnostic.emit_diagnostic(diagnostic); - // The Handler will check whether the diagnostic should be emitted - // based on the user's rustfmt configuration and the originating file - // that caused the parser error. If the Handler determined it should skip - // emission then we need to ensure the diagnostic is cancelled. - if !diagnostic.cancelled() { - diagnostic.cancel(); - } - } - - pub(super) fn can_reset_errors(&self) -> bool { - self.can_reset_errors.load(Ordering::Acquire) - } - - pub(super) fn has_errors(&self) -> bool { - self.parse_sess.span_diagnostic.has_errors() - } - - pub(super) fn reset_errors(&self) { - self.parse_sess.span_diagnostic.reset_err_count(); - } -} - -impl LineRangeUtils for ParseSess { - fn lookup_line_range(&self, span: Span) -> LineRange { - let snippet = self - .parse_sess - .source_map() - .span_to_snippet(span) - .unwrap_or_default(); - let lo = self.parse_sess.source_map().lookup_line(span.lo()).unwrap(); - let hi = self.parse_sess.source_map().lookup_line(span.hi()).unwrap(); - - debug_assert_eq!( - lo.sf.name, hi.sf.name, - "span crossed file boundary: lo: {:?}, hi: {:?}", - lo, hi - ); - - // in case the span starts with a newline, the line range is off by 1 without the - // adjustment below - let offset = 1 + if starts_with_newline(&snippet) { 1 } else { 0 }; - // Line numbers start at 1 - LineRange { - file: lo.sf.clone(), - lo: lo.line + offset, - hi: hi.line + offset, - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - - use rustfmt_config_proc_macro::nightly_only_test; - - mod emitter { - use super::*; - use crate::config::IgnoreList; - use crate::utils::mk_sp; - use rustc_span::{FileName as SourceMapFileName, MultiSpan, RealFileName, DUMMY_SP}; - use std::path::PathBuf; - use std::sync::atomic::AtomicU32; - - struct TestEmitter { - num_emitted_errors: Lrc, - } - - impl Emitter for TestEmitter { - fn source_map(&self) -> Option<&Lrc> { - None - } - fn emit_diagnostic(&mut self, _db: &Diagnostic) { - self.num_emitted_errors.fetch_add(1, Ordering::Release); - } - } - - fn build_diagnostic(level: DiagnosticLevel, span: Option) -> Diagnostic { - Diagnostic { - level, - code: None, - message: vec![], - children: vec![], - suggestions: vec![], - span: span.unwrap_or_else(MultiSpan::new), - sort_span: DUMMY_SP, - is_lint: false, - } - } - - fn build_emitter( - num_emitted_errors: Lrc, - can_reset: Lrc, - source_map: Option>, - ignore_list: Option, - ) -> SilentOnIgnoredFilesEmitter { - let emitter_writer = TestEmitter { num_emitted_errors }; - let source_map = - source_map.unwrap_or_else(|| Lrc::new(SourceMap::new(FilePathMapping::empty()))); - let ignore_path_set = Lrc::new( - IgnorePathSet::from_ignore_list(&ignore_list.unwrap_or_default()).unwrap(), - ); - SilentOnIgnoredFilesEmitter { - has_non_ignorable_parser_errors: false, - source_map, - emitter: Box::new(emitter_writer), - ignore_path_set, - can_reset, - } - } - - fn get_ignore_list(config: &str) -> IgnoreList { - Config::from_toml(config, Path::new("")).unwrap().ignore() - } - - #[test] - fn handles_fatal_parse_error_in_ignored_file() { - let num_emitted_errors = Lrc::new(AtomicU32::new(0)); - let can_reset_errors = Lrc::new(AtomicBool::new(false)); - let ignore_list = get_ignore_list(r#"ignore = ["foo.rs"]"#); - let source_map = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let source = - String::from(r#"extern "system" fn jni_symbol!( funcName ) ( ... ) -> {} "#); - source_map.new_source_file( - SourceMapFileName::Real(RealFileName::LocalPath(PathBuf::from("foo.rs"))), - source, - ); - let mut emitter = build_emitter( - Lrc::clone(&num_emitted_errors), - Lrc::clone(&can_reset_errors), - Some(Lrc::clone(&source_map)), - Some(ignore_list), - ); - let span = MultiSpan::from_span(mk_sp(BytePos(0), BytePos(1))); - let fatal_diagnostic = build_diagnostic(DiagnosticLevel::Fatal, Some(span)); - emitter.emit_diagnostic(&fatal_diagnostic); - assert_eq!(num_emitted_errors.load(Ordering::Acquire), 1); - assert_eq!(can_reset_errors.load(Ordering::Acquire), false); - } - - #[nightly_only_test] - #[test] - fn handles_recoverable_parse_error_in_ignored_file() { - let num_emitted_errors = Lrc::new(AtomicU32::new(0)); - let can_reset_errors = Lrc::new(AtomicBool::new(false)); - let ignore_list = get_ignore_list(r#"ignore = ["foo.rs"]"#); - let source_map = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let source = String::from(r#"pub fn bar() { 1x; }"#); - source_map.new_source_file( - SourceMapFileName::Real(RealFileName::LocalPath(PathBuf::from("foo.rs"))), - source, - ); - let mut emitter = build_emitter( - Lrc::clone(&num_emitted_errors), - Lrc::clone(&can_reset_errors), - Some(Lrc::clone(&source_map)), - Some(ignore_list), - ); - let span = MultiSpan::from_span(mk_sp(BytePos(0), BytePos(1))); - let non_fatal_diagnostic = build_diagnostic(DiagnosticLevel::Warning, Some(span)); - emitter.emit_diagnostic(&non_fatal_diagnostic); - assert_eq!(num_emitted_errors.load(Ordering::Acquire), 0); - assert_eq!(can_reset_errors.load(Ordering::Acquire), true); - } - - #[nightly_only_test] - #[test] - fn handles_recoverable_parse_error_in_non_ignored_file() { - let num_emitted_errors = Lrc::new(AtomicU32::new(0)); - let can_reset_errors = Lrc::new(AtomicBool::new(false)); - let source_map = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let source = String::from(r#"pub fn bar() { 1x; }"#); - source_map.new_source_file( - SourceMapFileName::Real(RealFileName::LocalPath(PathBuf::from("foo.rs"))), - source, - ); - let mut emitter = build_emitter( - Lrc::clone(&num_emitted_errors), - Lrc::clone(&can_reset_errors), - Some(Lrc::clone(&source_map)), - None, - ); - let span = MultiSpan::from_span(mk_sp(BytePos(0), BytePos(1))); - let non_fatal_diagnostic = build_diagnostic(DiagnosticLevel::Warning, Some(span)); - emitter.emit_diagnostic(&non_fatal_diagnostic); - assert_eq!(num_emitted_errors.load(Ordering::Acquire), 1); - assert_eq!(can_reset_errors.load(Ordering::Acquire), false); - } - - #[nightly_only_test] - #[test] - fn handles_mix_of_recoverable_parse_error() { - let num_emitted_errors = Lrc::new(AtomicU32::new(0)); - let can_reset_errors = Lrc::new(AtomicBool::new(false)); - let source_map = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let ignore_list = get_ignore_list(r#"ignore = ["foo.rs"]"#); - let bar_source = String::from(r#"pub fn bar() { 1x; }"#); - let foo_source = String::from(r#"pub fn foo() { 1x; }"#); - let fatal_source = - String::from(r#"extern "system" fn jni_symbol!( funcName ) ( ... ) -> {} "#); - source_map.new_source_file( - SourceMapFileName::Real(RealFileName::LocalPath(PathBuf::from("bar.rs"))), - bar_source, - ); - source_map.new_source_file( - SourceMapFileName::Real(RealFileName::LocalPath(PathBuf::from("foo.rs"))), - foo_source, - ); - source_map.new_source_file( - SourceMapFileName::Real(RealFileName::LocalPath(PathBuf::from("fatal.rs"))), - fatal_source, - ); - let mut emitter = build_emitter( - Lrc::clone(&num_emitted_errors), - Lrc::clone(&can_reset_errors), - Some(Lrc::clone(&source_map)), - Some(ignore_list), - ); - let bar_span = MultiSpan::from_span(mk_sp(BytePos(0), BytePos(1))); - let foo_span = MultiSpan::from_span(mk_sp(BytePos(21), BytePos(22))); - let bar_diagnostic = build_diagnostic(DiagnosticLevel::Warning, Some(bar_span)); - let foo_diagnostic = build_diagnostic(DiagnosticLevel::Warning, Some(foo_span)); - let fatal_diagnostic = build_diagnostic(DiagnosticLevel::Fatal, None); - emitter.emit_diagnostic(&bar_diagnostic); - emitter.emit_diagnostic(&foo_diagnostic); - emitter.emit_diagnostic(&fatal_diagnostic); - assert_eq!(num_emitted_errors.load(Ordering::Acquire), 2); - assert_eq!(can_reset_errors.load(Ordering::Acquire), false); - } - } -} diff --git a/src/visitor.rs b/src/visitor.rs index 1896a4744fe..0177689958a 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -16,13 +16,13 @@ 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::shape::{Indent, Shape}; use crate::skip::{is_skip_attr, SkipContext}; use crate::source_map::{LineRangeUtils, SpanUtils}; use crate::spanned::Spanned; use crate::stmt::Stmt; -use crate::syntux::session::ParseSess; use crate::utils::{ self, contains_skip, count_newlines, depr_skip_annotation, format_unsafety, inner_attributes, last_line_width, mk_sp, ptr_vec_to_ref_vec, rewrite_ident, starts_with_newline, stmt_expr, -- cgit 1.4.1-3-g733a5 From 9ce5470a8ce0abdfdb5b19c8f9a2b0773f0b6432 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Mon, 20 Dec 2021 18:59:01 -0600 Subject: refactor: move macro arg parsing to parse mod --- src/macros.rs | 216 ++++-------------------------------------------- src/parse/macros/mod.rs | 216 ++++++++++++++++++++++++++++++++++++++++++++++++ src/parse/mod.rs | 1 + 3 files changed, 234 insertions(+), 199 deletions(-) create mode 100644 src/parse/macros/mod.rs (limited to 'src') diff --git a/src/macros.rs b/src/macros.rs index a52568be9ea..26a68dfdcf2 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -16,8 +16,6 @@ use rustc_ast::token::{BinOpToken, DelimToken, Token, TokenKind}; use rustc_ast::tokenstream::{Cursor, Spacing, TokenStream, TokenTree}; use rustc_ast::{ast, ptr}; use rustc_ast_pretty::pprust; -use rustc_parse::parser::{ForceCollect, Parser}; -use rustc_parse::{stream_to_parser, MACRO_ARGUMENTS}; use rustc_span::{ symbol::{self, kw}, BytePos, Span, Symbol, DUMMY_SP, @@ -30,6 +28,7 @@ use crate::config::lists::*; use crate::expr::{rewrite_array, rewrite_assign_rhs, RhsAssignKind}; use crate::lists::{itemize_list, write_list, ListFormatting}; use crate::overflow; +use crate::parse::macros::{build_parser, parse_macro_args, ParsedMacroArgs}; use crate::rewrite::{Rewrite, RewriteContext}; use crate::shape::{Indent, Shape}; use crate::source_map::SpanUtils; @@ -60,7 +59,7 @@ pub(crate) enum MacroArg { } impl MacroArg { - fn is_item(&self) -> bool { + pub(crate) fn is_item(&self) -> bool { match self { MacroArg::Item(..) => true, _ => false, @@ -90,61 +89,6 @@ impl Rewrite for MacroArg { } } -fn build_parser<'a>(context: &RewriteContext<'a>, cursor: Cursor) -> Parser<'a> { - stream_to_parser( - context.parse_sess.inner(), - cursor.collect(), - MACRO_ARGUMENTS, - ) -} - -fn parse_macro_arg<'a, 'b: 'a>(parser: &'a mut Parser<'b>) -> Option { - macro_rules! parse_macro_arg { - ($macro_arg:ident, $parser:expr, $f:expr) => { - let mut cloned_parser = (*parser).clone(); - match $parser(&mut cloned_parser) { - Ok(x) => { - if parser.sess.span_diagnostic.has_errors() { - parser.sess.span_diagnostic.reset_err_count(); - } else { - // Parsing succeeded. - *parser = cloned_parser; - return Some(MacroArg::$macro_arg($f(x)?)); - } - } - Err(mut e) => { - e.cancel(); - parser.sess.span_diagnostic.reset_err_count(); - } - } - }; - } - - parse_macro_arg!( - Expr, - |parser: &mut rustc_parse::parser::Parser<'b>| parser.parse_expr(), - |x: ptr::P| Some(x) - ); - parse_macro_arg!( - Ty, - |parser: &mut rustc_parse::parser::Parser<'b>| parser.parse_ty(), - |x: ptr::P| Some(x) - ); - parse_macro_arg!( - Pat, - |parser: &mut rustc_parse::parser::Parser<'b>| parser.parse_pat_no_top_alt(None), - |x: ptr::P| Some(x) - ); - // `parse_item` returns `Option>`. - parse_macro_arg!( - Item, - |parser: &mut rustc_parse::parser::Parser<'b>| parser.parse_item(ForceCollect::No), - |x: Option>| x - ); - - None -} - /// Rewrite macro name without using pretty-printer if possible. fn rewrite_macro_name( context: &RewriteContext<'_>, @@ -232,25 +176,6 @@ pub(crate) fn rewrite_macro( } } -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(DelimToken::NoDelim) - }) - { - parser.bump(); - return Some(MacroArg::Keyword( - symbol::Ident::with_dummy_span(keyword), - parser.prev_token.span, - )); - } - } - None -} - fn rewrite_macro_inner( mac: &ast::MacCall, extra_ident: Option, @@ -269,8 +194,9 @@ fn rewrite_macro_inner( let original_style = macro_style(mac, context); let macro_name = rewrite_macro_name(context, &mac.path, extra_ident); + let is_forced_bracket = FORCED_BRACKET_MACROS.contains(&¯o_name[..]); - let style = if FORCED_BRACKET_MACROS.contains(&¯o_name[..]) && !is_nested_macro { + let style = if is_forced_bracket && !is_nested_macro { DelimToken::Bracket } else { original_style @@ -294,67 +220,21 @@ 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) { + if let success @ Some(..) = format_lazy_static(context, shape, ts.trees().collect()) { return success; } } - let mut parser = build_parser(context, ts.trees()); - let mut arg_vec = Vec::new(); - let mut vec_with_semi = false; - let mut trailing_comma = false; - - if DelimToken::Brace != style { - loop { - if let Some(arg) = check_keyword(&mut parser) { - arg_vec.push(arg); - } else if let Some(arg) = parse_macro_arg(&mut parser) { - arg_vec.push(arg); - } else { - return return_macro_parse_failure_fallback(context, shape.indent, mac.span()); - } - - match parser.token.kind { - TokenKind::Eof => break, - TokenKind::Comma => (), - TokenKind::Semi => { - // Try to parse `vec![expr; expr]` - if FORCED_BRACKET_MACROS.contains(&¯o_name[..]) { - parser.bump(); - if parser.token.kind != TokenKind::Eof { - match parse_macro_arg(&mut parser) { - Some(arg) => { - arg_vec.push(arg); - parser.bump(); - if parser.token.kind == TokenKind::Eof && arg_vec.len() == 2 { - vec_with_semi = true; - break; - } - } - None => { - return return_macro_parse_failure_fallback( - context, - shape.indent, - mac.span(), - ); - } - } - } - } - return return_macro_parse_failure_fallback(context, shape.indent, mac.span()); - } - _ if arg_vec.last().map_or(false, MacroArg::is_item) => continue, - _ => return return_macro_parse_failure_fallback(context, shape.indent, mac.span()), - } - - parser.bump(); - - if parser.token.kind == TokenKind::Eof { - trailing_comma = true; - break; - } + let ParsedMacroArgs { + args: arg_vec, + vec_with_semi, + trailing_comma, + } = 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()); } - } + }; if !arg_vec.is_empty() && arg_vec.iter().all(MacroArg::is_item) { return rewrite_macro_with_items( @@ -1179,7 +1059,7 @@ pub(crate) fn convert_try_mac( let path = &pprust::path_to_string(&mac.path); if path == "try" || path == "r#try" { let ts = mac.args.inner_tokens(); - let mut parser = build_parser(context, ts.trees()); + let mut parser = build_parser(context, ts); Some(ast::Expr { id: ast::NodeId::root(), // dummy value @@ -1414,10 +1294,10 @@ impl MacroBranch { fn format_lazy_static( context: &RewriteContext<'_>, shape: Shape, - ts: &TokenStream, + ts: TokenStream, ) -> Option { let mut result = String::with_capacity(1024); - let mut parser = build_parser(context, ts.trees()); + let mut parser = build_parser(context, ts); let nested_shape = shape .block_indent(context.config.tab_spaces()) .with_max_width(context.config); @@ -1528,65 +1408,3 @@ fn rewrite_macro_with_items( result.push_str(trailing_semicolon); Some(result) } - -const RUST_KW: [Symbol; 59] = [ - kw::PathRoot, - kw::DollarCrate, - kw::Underscore, - kw::As, - kw::Box, - kw::Break, - kw::Const, - kw::Continue, - kw::Crate, - kw::Else, - kw::Enum, - kw::Extern, - kw::False, - kw::Fn, - kw::For, - kw::If, - kw::Impl, - kw::In, - kw::Let, - kw::Loop, - kw::Match, - kw::Mod, - kw::Move, - kw::Mut, - kw::Pub, - kw::Ref, - kw::Return, - kw::SelfLower, - kw::SelfUpper, - kw::Static, - kw::Struct, - kw::Super, - kw::Trait, - kw::True, - kw::Type, - kw::Unsafe, - kw::Use, - kw::Where, - kw::While, - kw::Abstract, - kw::Become, - kw::Do, - kw::Final, - kw::Macro, - kw::Override, - kw::Priv, - kw::Typeof, - kw::Unsized, - kw::Virtual, - kw::Yield, - kw::Dyn, - kw::Async, - kw::Try, - kw::UnderscoreLifetime, - kw::StaticLifetime, - kw::Auto, - kw::Catch, - kw::Default, - kw::Union, -]; diff --git a/src/parse/macros/mod.rs b/src/parse/macros/mod.rs new file mode 100644 index 00000000000..e7844c9a4dc --- /dev/null +++ b/src/parse/macros/mod.rs @@ -0,0 +1,216 @@ +use rustc_ast::token::{BinOpToken, DelimToken, Token, TokenKind}; +use rustc_ast::tokenstream::{Cursor, Spacing, TokenStream, TokenTree}; +use rustc_ast::{ast, ptr}; +use rustc_parse::parser::{ForceCollect, Parser}; +use rustc_parse::{stream_to_parser, MACRO_ARGUMENTS}; +use rustc_span::{ + symbol::{self, kw}, + BytePos, Span, Symbol, DUMMY_SP, +}; + +use crate::macros::MacroArg; +use crate::rewrite::{Rewrite, RewriteContext}; + +pub(crate) fn build_parser<'a>(context: &RewriteContext<'a>, tokens: TokenStream) -> Parser<'a> { + stream_to_parser(context.parse_sess.inner(), tokens, MACRO_ARGUMENTS) +} + +fn parse_macro_arg<'a, 'b: 'a>(parser: &'a mut Parser<'b>) -> Option { + macro_rules! parse_macro_arg { + ($macro_arg:ident, $parser:expr, $f:expr) => { + let mut cloned_parser = (*parser).clone(); + match $parser(&mut cloned_parser) { + Ok(x) => { + if parser.sess.span_diagnostic.has_errors() { + parser.sess.span_diagnostic.reset_err_count(); + } else { + // Parsing succeeded. + *parser = cloned_parser; + return Some(MacroArg::$macro_arg($f(x)?)); + } + } + Err(mut e) => { + e.cancel(); + parser.sess.span_diagnostic.reset_err_count(); + } + } + }; + } + + parse_macro_arg!( + Expr, + |parser: &mut rustc_parse::parser::Parser<'b>| parser.parse_expr(), + |x: ptr::P| Some(x) + ); + parse_macro_arg!( + Ty, + |parser: &mut rustc_parse::parser::Parser<'b>| parser.parse_ty(), + |x: ptr::P| Some(x) + ); + parse_macro_arg!( + Pat, + |parser: &mut rustc_parse::parser::Parser<'b>| parser.parse_pat_no_top_alt(None), + |x: ptr::P| Some(x) + ); + // `parse_item` returns `Option>`. + parse_macro_arg!( + Item, + |parser: &mut rustc_parse::parser::Parser<'b>| parser.parse_item(ForceCollect::No), + |x: Option>| x + ); + + None +} + +pub(crate) struct ParsedMacroArgs { + pub(crate) vec_with_semi: bool, + pub(crate) trailing_comma: bool, + pub(crate) args: Vec, +} + +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(DelimToken::NoDelim) + }) + { + parser.bump(); + return Some(MacroArg::Keyword( + symbol::Ident::with_dummy_span(keyword), + parser.prev_token.span, + )); + } + } + None +} + +pub(crate) fn parse_macro_args( + context: &RewriteContext<'_>, + tokens: TokenStream, + style: DelimToken, + forced_bracket: bool, +) -> Option { + let mut parser = build_parser(context, tokens); + let mut args = Vec::new(); + let mut vec_with_semi = false; + let mut trailing_comma = false; + + if DelimToken::Brace != style { + loop { + if let Some(arg) = check_keyword(&mut parser) { + args.push(arg); + } else if let Some(arg) = parse_macro_arg(&mut parser) { + args.push(arg); + } else { + return None; + } + + match parser.token.kind { + TokenKind::Eof => break, + TokenKind::Comma => (), + TokenKind::Semi => { + // Try to parse `vec![expr; expr]` + if forced_bracket { + parser.bump(); + if parser.token.kind != TokenKind::Eof { + match parse_macro_arg(&mut parser) { + Some(arg) => { + args.push(arg); + parser.bump(); + if parser.token.kind == TokenKind::Eof && args.len() == 2 { + vec_with_semi = true; + break; + } + } + None => { + return None; + } + } + } + } + return None; + } + _ if args.last().map_or(false, MacroArg::is_item) => continue, + _ => return None, + } + + parser.bump(); + + if parser.token.kind == TokenKind::Eof { + trailing_comma = true; + break; + } + } + } + + Some(ParsedMacroArgs { + vec_with_semi, + trailing_comma, + args, + }) +} + +const RUST_KW: [Symbol; 59] = [ + kw::PathRoot, + kw::DollarCrate, + kw::Underscore, + kw::As, + kw::Box, + kw::Break, + kw::Const, + kw::Continue, + kw::Crate, + kw::Else, + kw::Enum, + kw::Extern, + kw::False, + kw::Fn, + kw::For, + kw::If, + kw::Impl, + kw::In, + kw::Let, + kw::Loop, + kw::Match, + kw::Mod, + kw::Move, + kw::Mut, + kw::Pub, + kw::Ref, + kw::Return, + kw::SelfLower, + kw::SelfUpper, + kw::Static, + kw::Struct, + kw::Super, + kw::Trait, + kw::True, + kw::Type, + kw::Unsafe, + kw::Use, + kw::Where, + kw::While, + kw::Abstract, + kw::Become, + kw::Do, + kw::Final, + kw::Macro, + kw::Override, + kw::Priv, + kw::Typeof, + kw::Unsized, + kw::Virtual, + kw::Yield, + kw::Dyn, + kw::Async, + kw::Try, + kw::UnderscoreLifetime, + kw::StaticLifetime, + kw::Auto, + kw::Catch, + kw::Default, + kw::Union, +]; diff --git a/src/parse/mod.rs b/src/parse/mod.rs index bb7d9ca87d4..5e88826ea8c 100644 --- a/src/parse/mod.rs +++ b/src/parse/mod.rs @@ -1,2 +1,3 @@ +pub(crate) mod macros; pub(crate) mod parser; pub(crate) mod session; -- cgit 1.4.1-3-g733a5 From c8cf454173ec332acf3860863c7d2f088876e40b Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Mon, 20 Dec 2021 19:38:00 -0600 Subject: refactor: move lazy_static parsing to parse mod --- src/macros.rs | 43 +++++------------------------------ src/parse/macros/lazy_static.rs | 50 +++++++++++++++++++++++++++++++++++++++++ src/parse/macros/mod.rs | 2 ++ 3 files changed, 58 insertions(+), 37 deletions(-) create mode 100644 src/parse/macros/lazy_static.rs (limited to 'src') diff --git a/src/macros.rs b/src/macros.rs index 26a68dfdcf2..b14b67f2a0a 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -28,6 +28,7 @@ use crate::config::lists::*; use crate::expr::{rewrite_array, rewrite_assign_rhs, RhsAssignKind}; use crate::lists::{itemize_list, write_list, ListFormatting}; use crate::overflow; +use crate::parse::macros::lazy_static::parse_lazy_static; use crate::parse::macros::{build_parser, parse_macro_args, ParsedMacroArgs}; use crate::rewrite::{Rewrite, RewriteContext}; use crate::shape::{Indent, Shape}; @@ -1297,7 +1298,6 @@ fn format_lazy_static( ts: TokenStream, ) -> Option { let mut result = String::with_capacity(1024); - let mut parser = build_parser(context, ts); let nested_shape = shape .block_indent(context.config.tab_spaces()) .with_max_width(context.config); @@ -1305,42 +1305,11 @@ fn format_lazy_static( result.push_str("lazy_static! {"); result.push_str(&nested_shape.indent.to_string_with_newline(context.config)); - macro_rules! parse_or { - ($method:ident $(,)* $($arg:expr),* $(,)*) => { - match parser.$method($($arg,)*) { - Ok(val) => { - if parser.sess.span_diagnostic.has_errors() { - parser.sess.span_diagnostic.reset_err_count(); - return None; - } else { - val - } - } - Err(mut err) => { - err.cancel(); - parser.sess.span_diagnostic.reset_err_count(); - return None; - } - } - } - } - - while parser.token.kind != TokenKind::Eof { - // Parse a `lazy_static!` item. - let vis = crate::utils::format_visibility( - context, - &parse_or!(parse_visibility, rustc_parse::parser::FollowedByType::No), - ); - parser.eat_keyword(kw::Static); - parser.eat_keyword(kw::Ref); - let id = parse_or!(parse_ident); - parser.eat(&TokenKind::Colon); - let ty = parse_or!(parse_ty); - parser.eat(&TokenKind::Eq); - let expr = parse_or!(parse_expr); - parser.eat(&TokenKind::Semi); - + let parsed_elems = parse_lazy_static(context, ts)?; + let last = parsed_elems.len() - 1; + for (i, (vis, id, ty, expr)) in parsed_elems.iter().enumerate() { // Rewrite as a static item. + let vis = crate::utils::format_visibility(context, vis); let mut stmt = String::with_capacity(128); stmt.push_str(&format!( "{}static ref {}: {} =", @@ -1356,7 +1325,7 @@ fn format_lazy_static( nested_shape.sub_width(1)?, )?); result.push(';'); - if parser.token.kind != TokenKind::Eof { + if i != last { result.push_str(&nested_shape.indent.to_string_with_newline(context.config)); } } diff --git a/src/parse/macros/lazy_static.rs b/src/parse/macros/lazy_static.rs new file mode 100644 index 00000000000..9c8651aa3fa --- /dev/null +++ b/src/parse/macros/lazy_static.rs @@ -0,0 +1,50 @@ +use rustc_ast::ast; +use rustc_ast::ptr::P; +use rustc_ast::token::TokenKind; +use rustc_ast::tokenstream::TokenStream; +use rustc_span::symbol::{self, kw}; + +use crate::rewrite::RewriteContext; + +pub(crate) fn parse_lazy_static( + context: &RewriteContext<'_>, + ts: TokenStream, +) -> Option, P)>> { + let mut result = vec![]; + let mut parser = super::build_parser(context, ts); + macro_rules! parse_or { + ($method:ident $(,)* $($arg:expr),* $(,)*) => { + match parser.$method($($arg,)*) { + Ok(val) => { + if parser.sess.span_diagnostic.has_errors() { + parser.sess.span_diagnostic.reset_err_count(); + return None; + } else { + val + } + } + Err(mut err) => { + err.cancel(); + parser.sess.span_diagnostic.reset_err_count(); + return None; + } + } + } + } + + while parser.token.kind != TokenKind::Eof { + // Parse a `lazy_static!` item. + let vis = parse_or!(parse_visibility, rustc_parse::parser::FollowedByType::No); + parser.eat_keyword(kw::Static); + parser.eat_keyword(kw::Ref); + let id = parse_or!(parse_ident); + parser.eat(&TokenKind::Colon); + let ty = parse_or!(parse_ty); + parser.eat(&TokenKind::Eq); + let expr = parse_or!(parse_expr); + parser.eat(&TokenKind::Semi); + result.push((vis, id, ty, expr)); + } + + Some(result) +} diff --git a/src/parse/macros/mod.rs b/src/parse/macros/mod.rs index e7844c9a4dc..7115302a479 100644 --- a/src/parse/macros/mod.rs +++ b/src/parse/macros/mod.rs @@ -11,6 +11,8 @@ use rustc_span::{ use crate::macros::MacroArg; use crate::rewrite::{Rewrite, RewriteContext}; +pub(crate) mod lazy_static; + pub(crate) fn build_parser<'a>(context: &RewriteContext<'a>, tokens: TokenStream) -> Parser<'a> { stream_to_parser(context.parse_sess.inner(), tokens, MACRO_ARGUMENTS) } -- cgit 1.4.1-3-g733a5 From 62987562e2fbb6ea83fa20598b9e0c91bee536e3 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Mon, 20 Dec 2021 19:44:23 -0600 Subject: refactor: extract final rustc_parse touchpoint from macros.rs --- src/macros.rs | 5 ++--- src/parse/macros/mod.rs | 10 +++++++++- 2 files changed, 11 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/macros.rs b/src/macros.rs index b14b67f2a0a..f29552caf8d 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -29,7 +29,7 @@ use crate::expr::{rewrite_array, rewrite_assign_rhs, RhsAssignKind}; use crate::lists::{itemize_list, write_list, ListFormatting}; use crate::overflow; use crate::parse::macros::lazy_static::parse_lazy_static; -use crate::parse::macros::{build_parser, parse_macro_args, ParsedMacroArgs}; +use crate::parse::macros::{parse_expr, parse_macro_args, ParsedMacroArgs}; use crate::rewrite::{Rewrite, RewriteContext}; use crate::shape::{Indent, Shape}; use crate::source_map::SpanUtils; @@ -1060,11 +1060,10 @@ pub(crate) fn convert_try_mac( let path = &pprust::path_to_string(&mac.path); if path == "try" || path == "r#try" { let ts = mac.args.inner_tokens(); - let mut parser = build_parser(context, ts); Some(ast::Expr { id: ast::NodeId::root(), // dummy value - kind: ast::ExprKind::Try(parser.parse_expr().ok()?), + kind: ast::ExprKind::Try(parse_expr(context, ts)?), span: mac.span(), // incorrect span, but shouldn't matter too much attrs: ast::AttrVec::new(), tokens: None, diff --git a/src/parse/macros/mod.rs b/src/parse/macros/mod.rs index 7115302a479..414b72f2921 100644 --- a/src/parse/macros/mod.rs +++ b/src/parse/macros/mod.rs @@ -13,7 +13,7 @@ use crate::rewrite::{Rewrite, RewriteContext}; pub(crate) mod lazy_static; -pub(crate) fn build_parser<'a>(context: &RewriteContext<'a>, tokens: TokenStream) -> Parser<'a> { +fn build_parser<'a>(context: &RewriteContext<'a>, tokens: TokenStream) -> Parser<'a> { stream_to_parser(context.parse_sess.inner(), tokens, MACRO_ARGUMENTS) } @@ -155,6 +155,14 @@ pub(crate) fn parse_macro_args( }) } +pub(crate) fn parse_expr( + context: &RewriteContext<'_>, + tokens: TokenStream, +) -> Option> { + let mut parser = build_parser(context, tokens); + parser.parse_expr().ok() +} + const RUST_KW: [Symbol; 59] = [ kw::PathRoot, kw::DollarCrate, -- cgit 1.4.1-3-g733a5 From 97c3e48834c1485168a59473385cb755d76c9287 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Mon, 20 Dec 2021 20:28:55 -0600 Subject: refactor: encapsulate cfg_if parsing within parse mod --- src/modules/visitor.rs | 4 +-- src/parse/macros/cfg_if.rs | 89 ++++++++++++++++++++++++++++++++++++++++++++++ src/parse/macros/mod.rs | 8 ++++- src/parse/parser.rs | 80 ----------------------------------------- 4 files changed, 98 insertions(+), 83 deletions(-) create mode 100644 src/parse/macros/cfg_if.rs (limited to 'src') diff --git a/src/modules/visitor.rs b/src/modules/visitor.rs index 7486a4c4ee1..ea67977c17a 100644 --- a/src/modules/visitor.rs +++ b/src/modules/visitor.rs @@ -3,7 +3,7 @@ use rustc_ast::visit::Visitor; use rustc_span::Symbol; use crate::attr::MetaVisitor; -use crate::parse::parser::Parser; +use crate::parse::macros::cfg_if::parse_cfg_if; use crate::parse::session::ParseSess; pub(crate) struct ModItem { @@ -62,7 +62,7 @@ impl<'a, 'ast: 'a> CfgIfVisitor<'a> { } }; - let items = Parser::parse_cfg_if(self.parse_sess, mac)?; + let items = parse_cfg_if(self.parse_sess, mac)?; self.mods .append(&mut items.into_iter().map(|item| ModItem { item }).collect()); diff --git a/src/parse/macros/cfg_if.rs b/src/parse/macros/cfg_if.rs new file mode 100644 index 00000000000..e10fbe64bcd --- /dev/null +++ b/src/parse/macros/cfg_if.rs @@ -0,0 +1,89 @@ +use std::panic::{catch_unwind, AssertUnwindSafe}; + +use rustc_ast::ast; +use rustc_ast::token::{DelimToken, TokenKind}; +use rustc_parse::parser::ForceCollect; +use rustc_span::symbol::kw; + +use crate::parse::macros::build_stream_parser; +use crate::parse::session::ParseSess; + +pub(crate) fn parse_cfg_if<'a>( + sess: &'a ParseSess, + mac: &'a ast::MacCall, +) -> Result, &'static str> { + match catch_unwind(AssertUnwindSafe(|| parse_cfg_if_inner(sess, mac))) { + Ok(Ok(items)) => Ok(items), + Ok(err @ Err(_)) => err, + Err(..) => Err("failed to parse cfg_if!"), + } +} + +fn parse_cfg_if_inner<'a>( + sess: &'a ParseSess, + mac: &'a ast::MacCall, +) -> Result, &'static str> { + let ts = mac.args.inner_tokens(); + let mut parser = build_stream_parser(sess.inner(), ts); + + let mut items = vec![]; + let mut process_if_cfg = true; + + while parser.token.kind != TokenKind::Eof { + if process_if_cfg { + if !parser.eat_keyword(kw::If) { + return Err("Expected `if`"); + } + // Inner attributes are not actually syntactically permitted here, but we don't + // care about inner vs outer attributes in this position. Our purpose with this + // special case parsing of cfg_if macros is to ensure we can correctly resolve + // imported modules that may have a custom `path` defined. + // + // As such, we just need to advance the parser past the attribute and up to + // to the opening brace. + // See also https://github.com/rust-lang/rust/pull/79433 + parser + .parse_attribute(rustc_parse::parser::attr::InnerAttrPolicy::Permitted) + .map_err(|_| "Failed to parse attributes")?; + } + + if !parser.eat(&TokenKind::OpenDelim(DelimToken::Brace)) { + return Err("Expected an opening brace"); + } + + while parser.token != TokenKind::CloseDelim(DelimToken::Brace) + && parser.token.kind != TokenKind::Eof + { + let item = match parser.parse_item(ForceCollect::No) { + Ok(Some(item_ptr)) => item_ptr.into_inner(), + Ok(None) => continue, + Err(mut err) => { + err.cancel(); + parser.sess.span_diagnostic.reset_err_count(); + return Err( + "Expected item inside cfg_if block, but failed to parse it as an item", + ); + } + }; + if let ast::ItemKind::Mod(..) = item.kind { + items.push(item); + } + } + + if !parser.eat(&TokenKind::CloseDelim(DelimToken::Brace)) { + return Err("Expected a closing brace"); + } + + if parser.eat(&TokenKind::Eof) { + break; + } + + if !parser.eat_keyword(kw::Else) { + return Err("Expected `else`"); + } + + process_if_cfg = parser.token.is_keyword(kw::If); + } + + Ok(items) +} diff --git a/src/parse/macros/mod.rs b/src/parse/macros/mod.rs index 414b72f2921..fbd8c3f9095 100644 --- a/src/parse/macros/mod.rs +++ b/src/parse/macros/mod.rs @@ -3,6 +3,7 @@ use rustc_ast::tokenstream::{Cursor, Spacing, TokenStream, TokenTree}; use rustc_ast::{ast, ptr}; use rustc_parse::parser::{ForceCollect, Parser}; use rustc_parse::{stream_to_parser, MACRO_ARGUMENTS}; +use rustc_session::parse::ParseSess; use rustc_span::{ symbol::{self, kw}, BytePos, Span, Symbol, DUMMY_SP, @@ -11,10 +12,15 @@ use rustc_span::{ use crate::macros::MacroArg; use crate::rewrite::{Rewrite, RewriteContext}; +pub(crate) mod cfg_if; pub(crate) mod lazy_static; +fn build_stream_parser<'a>(sess: &'a ParseSess, tokens: TokenStream) -> Parser<'a> { + stream_to_parser(sess, tokens, MACRO_ARGUMENTS) +} + fn build_parser<'a>(context: &RewriteContext<'a>, tokens: TokenStream) -> Parser<'a> { - stream_to_parser(context.parse_sess.inner(), tokens, MACRO_ARGUMENTS) + build_stream_parser(context.parse_sess.inner(), tokens) } fn parse_macro_arg<'a, 'b: 'a>(parser: &'a mut Parser<'b>) -> Option { diff --git a/src/parse/parser.rs b/src/parse/parser.rs index 024b38cebb6..8efd2bf257b 100644 --- a/src/parse/parser.rs +++ b/src/parse/parser.rs @@ -175,84 +175,4 @@ impl<'a> Parser<'a> { Err(_) => Err(ParserError::ParsePanicError), } } - - pub(crate) fn parse_cfg_if( - sess: &'a ParseSess, - mac: &'a ast::MacCall, - ) -> Result, &'static str> { - match catch_unwind(AssertUnwindSafe(|| Parser::parse_cfg_if_inner(sess, mac))) { - Ok(Ok(items)) => Ok(items), - Ok(err @ Err(_)) => err, - Err(..) => Err("failed to parse cfg_if!"), - } - } - - fn parse_cfg_if_inner( - sess: &'a ParseSess, - mac: &'a ast::MacCall, - ) -> Result, &'static str> { - let token_stream = mac.args.inner_tokens(); - let mut parser = rustc_parse::stream_to_parser(sess.inner(), token_stream, Some("")); - - let mut items = vec![]; - let mut process_if_cfg = true; - - while parser.token.kind != TokenKind::Eof { - if process_if_cfg { - if !parser.eat_keyword(kw::If) { - return Err("Expected `if`"); - } - // Inner attributes are not actually syntactically permitted here, but we don't - // care about inner vs outer attributes in this position. Our purpose with this - // special case parsing of cfg_if macros is to ensure we can correctly resolve - // imported modules that may have a custom `path` defined. - // - // As such, we just need to advance the parser past the attribute and up to - // to the opening brace. - // See also https://github.com/rust-lang/rust/pull/79433 - parser - .parse_attribute(rustc_parse::parser::attr::InnerAttrPolicy::Permitted) - .map_err(|_| "Failed to parse attributes")?; - } - - if !parser.eat(&TokenKind::OpenDelim(DelimToken::Brace)) { - return Err("Expected an opening brace"); - } - - while parser.token != TokenKind::CloseDelim(DelimToken::Brace) - && parser.token.kind != TokenKind::Eof - { - let item = match parser.parse_item(ForceCollect::No) { - Ok(Some(item_ptr)) => item_ptr.into_inner(), - Ok(None) => continue, - Err(mut err) => { - err.cancel(); - parser.sess.span_diagnostic.reset_err_count(); - return Err( - "Expected item inside cfg_if block, but failed to parse it as an item", - ); - } - }; - if let ast::ItemKind::Mod(..) = item.kind { - items.push(item); - } - } - - if !parser.eat(&TokenKind::CloseDelim(DelimToken::Brace)) { - return Err("Expected a closing brace"); - } - - if parser.eat(&TokenKind::Eof) { - break; - } - - if !parser.eat_keyword(kw::Else) { - return Err("Expected `else`"); - } - - process_if_cfg = parser.token.is_keyword(kw::If); - } - - Ok(items) - } } -- cgit 1.4.1-3-g733a5 From 7b8303d47968a0e1fcad4b143e0ff4b5e512f37b Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Mon, 20 Dec 2021 20:33:20 -0600 Subject: chore: cleanup unused imports --- src/parse/macros/mod.rs | 12 +++++------- src/parse/parser.rs | 9 +++------ 2 files changed, 8 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/parse/macros/mod.rs b/src/parse/macros/mod.rs index fbd8c3f9095..7e12f82af15 100644 --- a/src/parse/macros/mod.rs +++ b/src/parse/macros/mod.rs @@ -1,16 +1,14 @@ -use rustc_ast::token::{BinOpToken, DelimToken, Token, TokenKind}; -use rustc_ast::tokenstream::{Cursor, Spacing, TokenStream, TokenTree}; +use rustc_ast::token::{DelimToken, TokenKind}; +use rustc_ast::tokenstream::TokenStream; use rustc_ast::{ast, ptr}; use rustc_parse::parser::{ForceCollect, Parser}; use rustc_parse::{stream_to_parser, MACRO_ARGUMENTS}; use rustc_session::parse::ParseSess; -use rustc_span::{ - symbol::{self, kw}, - BytePos, Span, Symbol, DUMMY_SP, -}; +use rustc_span::symbol::{self, kw}; +use rustc_span::Symbol; use crate::macros::MacroArg; -use crate::rewrite::{Rewrite, RewriteContext}; +use crate::rewrite::RewriteContext; pub(crate) mod cfg_if; pub(crate) mod lazy_static; diff --git a/src/parse/parser.rs b/src/parse/parser.rs index 8efd2bf257b..657217633f4 100644 --- a/src/parse/parser.rs +++ b/src/parse/parser.rs @@ -1,14 +1,11 @@ use std::panic::{catch_unwind, AssertUnwindSafe}; use std::path::{Path, PathBuf}; -use rustc_ast::token::{DelimToken, TokenKind}; +use rustc_ast::token::TokenKind; use rustc_ast::{ast, ptr}; use rustc_errors::Diagnostic; -use rustc_parse::{ - new_parser_from_file, - parser::{ForceCollect, Parser as RawParser}, -}; -use rustc_span::{sym, symbol::kw, Span}; +use rustc_parse::{new_parser_from_file, parser::Parser as RawParser}; +use rustc_span::{sym, Span}; use crate::attr::first_attr_value_str_by_name; use crate::parse::session::ParseSess; -- cgit 1.4.1-3-g733a5 From 0b2fd9b1329a41702ff2db51426003a37c1db510 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Thu, 23 Dec 2021 14:23:51 -0800 Subject: Fix static async closure qualifier order --- src/closures.rs | 14 +++++++------- tests/source/async_block.rs | 16 ++++++++++++++++ tests/target/async_block.rs | 10 ++++++++++ 3 files changed, 33 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/closures.rs b/src/closures.rs index 34d73a77fd3..e688db1c39d 100644 --- a/src/closures.rs +++ b/src/closures.rs @@ -236,21 +236,21 @@ fn rewrite_closure_fn_decl( context: &RewriteContext<'_>, shape: Shape, ) -> Option<(String, usize)> { - let is_async = if asyncness.is_async() { "async " } else { "" }; - let mover = if capture == ast::CaptureBy::Value { - "move " + let immovable = if movability == ast::Movability::Static { + "static " } else { "" }; - let immovable = if movability == ast::Movability::Static { - "static " + let is_async = if asyncness.is_async() { "async " } else { "" }; + let mover = if capture == ast::CaptureBy::Value { + "move " } else { "" }; // 4 = "|| {".len(), which is overconservative when the closure consists of // a single expression. let nested_shape = shape - .shrink_left(is_async.len() + mover.len() + immovable.len())? + .shrink_left(immovable.len() + is_async.len() + mover.len())? .sub_width(4)?; // 1 = | @@ -288,7 +288,7 @@ fn rewrite_closure_fn_decl( .tactic(tactic) .preserve_newline(true); let list_str = write_list(&item_vec, &fmt)?; - let mut prefix = format!("{}{}{}|{}|", is_async, immovable, mover, list_str); + let mut prefix = format!("{}{}{}|{}|", immovable, is_async, mover, list_str); if !ret_str.is_empty() { if prefix.contains('\n') { diff --git a/tests/source/async_block.rs b/tests/source/async_block.rs index 3de51a084d2..18cb4fb5f5c 100644 --- a/tests/source/async_block.rs +++ b/tests/source/async_block.rs @@ -32,4 +32,20 @@ fn baz() { Ok(()) }, ); + + spawn( + a, + static async || { + action(); + Ok(()) + }, + ); + + spawn( + a, + static async move || { + action(); + Ok(()) + }, + ); } diff --git a/tests/target/async_block.rs b/tests/target/async_block.rs index 258dd937a6f..137d849c9ee 100644 --- a/tests/target/async_block.rs +++ b/tests/target/async_block.rs @@ -22,4 +22,14 @@ fn baz() { action(); Ok(()) }); + + spawn(a, static async || { + action(); + Ok(()) + }); + + spawn(a, static async move || { + action(); + Ok(()) + }); } -- cgit 1.4.1-3-g733a5 From 76eb077fb298a01137c878a9f10854b44c5edf37 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Thu, 23 Dec 2021 20:22:09 -0500 Subject: Retain qualified path when rewriting struct literals Fixes 5151 Details about the qualified path are now passed along so that rustfmt can include them when formatting struct literals. --- src/expr.rs | 19 ++++++++++++++++--- tests/target/issue-5151/minimum_example.rs | 16 ++++++++++++++++ 2 files changed, 32 insertions(+), 3 deletions(-) create mode 100644 tests/target/issue-5151/minimum_example.rs (limited to 'src') diff --git a/src/expr.rs b/src/expr.rs index edd004ac63f..c9c8852cd3b 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -108,9 +108,21 @@ pub(crate) fn format_expr( ast::ExprKind::Unary(op, ref subexpr) => rewrite_unary_op(context, op, subexpr, shape), ast::ExprKind::Struct(ref struct_expr) => { let ast::StructExpr { - fields, path, rest, .. + qself, + fields, + path, + rest, } = &**struct_expr; - rewrite_struct_lit(context, path, fields, rest, &expr.attrs, expr.span, shape) + rewrite_struct_lit( + context, + path, + qself.as_ref(), + fields, + rest, + &expr.attrs, + expr.span, + shape, + ) } ast::ExprKind::Tup(ref items) => { rewrite_tuple(context, items.iter(), expr.span, shape, items.len() == 1) @@ -1511,6 +1523,7 @@ fn struct_lit_can_be_aligned(fields: &[ast::ExprField], has_base: bool) -> bool fn rewrite_struct_lit<'a>( context: &RewriteContext<'_>, path: &ast::Path, + qself: Option<&ast::QSelf>, fields: &'a [ast::ExprField], struct_rest: &ast::StructRest, attrs: &[ast::Attribute], @@ -1527,7 +1540,7 @@ fn rewrite_struct_lit<'a>( // 2 = " {".len() let path_shape = shape.sub_width(2)?; - let path_str = rewrite_path(context, PathContext::Expr, None, path, path_shape)?; + let path_str = rewrite_path(context, PathContext::Expr, qself, path, path_shape)?; let has_base_or_rest = match struct_rest { ast::StructRest::None if fields.is_empty() => return Some(format!("{} {{}}", path_str)), diff --git a/tests/target/issue-5151/minimum_example.rs b/tests/target/issue-5151/minimum_example.rs new file mode 100644 index 00000000000..2ed3d936e32 --- /dev/null +++ b/tests/target/issue-5151/minimum_example.rs @@ -0,0 +1,16 @@ +#![feature(more_qualified_paths)] + +struct Struct {} + +trait Trait { + type Type; +} + +impl Trait for Struct { + type Type = Self; +} + +fn main() { + // keep the qualified path details + let _ = ::Type {}; +} -- cgit 1.4.1-3-g733a5 From e8afb62c71f5c789c554e23c835efc019cb42685 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Mon, 27 Dec 2021 17:42:48 -0600 Subject: chore: reduce some vis. for updated unreachable_pub lint --- src/config/file_lines.rs | 8 ++++---- src/config/options.rs | 14 +++++++------- src/rustfmt_diff.rs | 10 +++++----- 3 files changed, 16 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/config/file_lines.rs b/src/config/file_lines.rs index 4b799780d85..7b498dc46b3 100644 --- a/src/config/file_lines.rs +++ b/src/config/file_lines.rs @@ -13,9 +13,9 @@ use thiserror::Error; /// A range of lines in a file, inclusive of both ends. pub struct LineRange { - pub file: Lrc, - pub lo: usize, - pub hi: usize, + pub(crate) file: Lrc, + pub(crate) lo: usize, + pub(crate) hi: usize, } /// Defines the name of an input - either a file or stdin. @@ -75,7 +75,7 @@ impl Serialize for FileName { } impl LineRange { - pub fn file_name(&self) -> FileName { + pub(crate) fn file_name(&self) -> FileName { self.file.name.clone().into() } } diff --git a/src/config/options.rs b/src/config/options.rs index bce9e5d07f2..d857c29be29 100644 --- a/src/config/options.rs +++ b/src/config/options.rs @@ -218,24 +218,24 @@ pub enum Verbosity { pub struct WidthHeuristics { // Maximum width of the args of a function call before falling back // to vertical formatting. - pub fn_call_width: usize, + pub(crate) fn_call_width: usize, // Maximum width of the args of a function-like attributes before falling // back to vertical formatting. - pub attr_fn_like_width: usize, + pub(crate) attr_fn_like_width: usize, // Maximum width in the body of a struct lit before falling back to // vertical formatting. - pub struct_lit_width: usize, + pub(crate) struct_lit_width: usize, // Maximum width in the body of a struct variant before falling back // to vertical formatting. - pub struct_variant_width: usize, + pub(crate) struct_variant_width: usize, // Maximum width of an array literal before falling back to vertical // formatting. - pub array_width: usize, + pub(crate) array_width: usize, // Maximum length of a chain to fit on a single line. - pub chain_width: usize, + pub(crate) chain_width: usize, // Maximum line length for single line if-else expressions. A value // of zero means always break if-else expressions. - pub single_line_if_else_max_width: usize, + pub(crate) single_line_if_else_max_width: usize, } impl fmt::Display for WidthHeuristics { diff --git a/src/rustfmt_diff.rs b/src/rustfmt_diff.rs index a394ce07398..1724a0f87bf 100644 --- a/src/rustfmt_diff.rs +++ b/src/rustfmt_diff.rs @@ -6,20 +6,20 @@ use std::io::Write; use crate::config::{Color, Config, Verbosity}; #[derive(Debug, PartialEq)] -pub enum DiffLine { +pub(crate) enum DiffLine { Context(String), Expected(String), Resulting(String), } #[derive(Debug, PartialEq)] -pub struct Mismatch { +pub(crate) struct Mismatch { /// The line number in the formatted version. - pub line_number: u32, + pub(crate) line_number: u32, /// The line number in the original version. - pub line_number_orig: u32, + pub(crate) line_number_orig: u32, /// The set of lines (context and old/new) in the mismatch. - pub lines: Vec, + pub(crate) lines: Vec, } impl Mismatch { -- cgit 1.4.1-3-g733a5 From f935f0cf89f53a9df3a443b9cc09bb1bcc33064b Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Tue, 28 Dec 2021 19:23:51 -0600 Subject: feat: support parsing asm! args --- src/lib.rs | 1 + src/parse/macros/asm.rs | 11 +++++++++++ src/parse/macros/mod.rs | 1 + 3 files changed, 13 insertions(+) create mode 100644 src/parse/macros/asm.rs (limited to 'src') diff --git a/src/lib.rs b/src/lib.rs index f59ebad97ce..ad23b16e02e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -15,6 +15,7 @@ extern crate log; // N.B. these crates are loaded from the sysroot, so they need extern crate. extern crate rustc_ast; extern crate rustc_ast_pretty; +extern crate rustc_builtin_macros; extern crate rustc_data_structures; extern crate rustc_errors; extern crate rustc_expand; diff --git a/src/parse/macros/asm.rs b/src/parse/macros/asm.rs new file mode 100644 index 00000000000..cc9fb5072ce --- /dev/null +++ b/src/parse/macros/asm.rs @@ -0,0 +1,11 @@ +use rustc_ast::ast; +use rustc_builtin_macros::asm::{parse_asm_args, AsmArgs}; + +use crate::rewrite::RewriteContext; + +#[allow(dead_code)] +pub(crate) fn parse_asm(context: &RewriteContext<'_>, mac: &ast::MacCall) -> Option { + let ts = mac.args.inner_tokens(); + let mut parser = super::build_parser(context, ts); + parse_asm_args(&mut parser, context.parse_sess.inner(), mac.span(), false).ok() +} diff --git a/src/parse/macros/mod.rs b/src/parse/macros/mod.rs index 7e12f82af15..2e9ce1d35f4 100644 --- a/src/parse/macros/mod.rs +++ b/src/parse/macros/mod.rs @@ -10,6 +10,7 @@ use rustc_span::Symbol; use crate::macros::MacroArg; use crate::rewrite::RewriteContext; +pub(crate) mod asm; pub(crate) mod cfg_if; pub(crate) mod lazy_static; -- cgit 1.4.1-3-g733a5 From 4a053f206fd6799a25823c307f7d7f9d897be118 Mon Sep 17 00:00:00 2001 From: David Lattimore Date: Thu, 30 Dec 2021 10:13:45 +1100 Subject: Do not flatten match arm block with leading attributes This is a backport of #4124. Fixes #4109 --- src/matches.rs | 6 +++++- tests/source/match.rs | 19 +++++++++++++++++++ tests/target/match.rs | 19 +++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/matches.rs b/src/matches.rs index 22d23fc1cdb..85d9c5d2b9b 100644 --- a/src/matches.rs +++ b/src/matches.rs @@ -322,7 +322,11 @@ fn flatten_arm_body<'a>( if let Some(block) = block_can_be_flattened(context, body) { if let ast::StmtKind::Expr(ref expr) = block.stmts[0].kind { if let ast::ExprKind::Block(..) = expr.kind { - flatten_arm_body(context, expr, None) + if expr.attrs.is_empty() { + flatten_arm_body(context, expr, None) + } else { + (true, body) + } } else { let cond_becomes_muti_line = opt_shape .and_then(|shape| rewrite_cond(context, expr, shape)) diff --git a/tests/source/match.rs b/tests/source/match.rs index da20517203a..b5dc9957a2c 100644 --- a/tests/source/match.rs +++ b/tests/source/match.rs @@ -568,3 +568,22 @@ fn issue_3774() { } } } + +// #4109 +fn issue_4109() { + match () { + _ => { +#[cfg(debug_assertions)] +{ +println!("Foo"); +} +} +} + +match () { +_ => { +#[allow(unsafe_code)] +unsafe {} +} +} +} diff --git a/tests/target/match.rs b/tests/target/match.rs index e2c522bea10..1bf3fb758ee 100644 --- a/tests/target/match.rs +++ b/tests/target/match.rs @@ -608,3 +608,22 @@ fn issue_3774() { } } } + +// #4109 +fn issue_4109() { + match () { + _ => { + #[cfg(debug_assertions)] + { + println!("Foo"); + } + } + } + + match () { + _ => { + #[allow(unsafe_code)] + unsafe {} + } + } +} -- cgit 1.4.1-3-g733a5 From 737e6f704671dbf30e81dababa0133b585c03b48 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Sun, 19 Dec 2021 21:27:25 -0500 Subject: Improve out of line module resolution Fixes 5119 When the directory structure was laid out as follows: ``` dir |---mod_a | |---sub_mod_1.rs | |---sub_mod_2.rs |---mod_a.rs ``` And ``mod_a.rs`` contains the following content: ```rust mod mod_a { mod sub_mod_1; mod sub_mod_2; } ``` rustfmt previously tried to find ``sub_mod_1.rs`` and ``sub_mod_2.rs`` in ``./mod_a/mod_a/``. This directory does not exist and this caused rustfmt to fail with the error message: Error writing files: failed to resolve mod Now, both ``sub_mod_1.rs`` and ``sub_mod_2.rs`` are resolved correctly and found at ``mod_a/sub_mod_1.rs`` and ``mod_a/sub_mod_2.rs``. --- src/modules.rs | 9 +++++++- src/test/mod_resolver.rs | 14 +++++++++++++ tests/cargo-fmt/main.rs | 24 ++++++++++++++++++++++ .../test-submodule-issue-5119/Cargo.toml | 8 ++++++++ .../test-submodule-issue-5119/src/lib.rs | 7 +++++++ .../test-submodule-issue-5119/tests/test1.rs | 8 ++++++++ .../test-submodule-issue-5119/tests/test1/sub1.rs | 6 ++++++ .../test-submodule-issue-5119/tests/test1/sub2.rs | 6 ++++++ .../tests/test1/sub3/mod.rs | 1 + .../tests/test1/sub3/sub4.rs | 0 10 files changed, 82 insertions(+), 1 deletion(-) 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 (limited to 'src') diff --git a/src/modules.rs b/src/modules.rs index 9c964b274e0..70b937b0283 100644 --- a/src/modules.rs +++ b/src/modules.rs @@ -458,6 +458,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 +469,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/test/mod_resolver.rs b/src/test/mod_resolver.rs index ec9ed0f0b8d..fcff6d14e6f 100644 --- a/src/test/mod_resolver.rs +++ b/src/test/mod_resolver.rs @@ -50,3 +50,17 @@ 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", + ], + ) +} diff --git a/tests/cargo-fmt/main.rs b/tests/cargo-fmt/main.rs index 5493b09e4aa..bf81f253f69 100644 --- a/tests/cargo-fmt/main.rs +++ b/tests/cargo-fmt/main.rs @@ -2,6 +2,7 @@ use std::env; use std::process::Command; +use std::path::Path; /// Run the cargo-fmt executable and return its output. fn cargo_fmt(args: &[&str]) -> (String, String) { @@ -71,3 +72,26 @@ fn rustfmt_help() { assert_that!(&["--", "-h"], contains("Format Rust code")); assert_that!(&["--", "--help=config"], contains("Configuration Options:")); } + +#[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/test-submodule-issue-5119/Cargo.toml b/tests/mod-resolver/test-submodule-issue-5119/Cargo.toml new file mode 100644 index 00000000000..0993f127959 --- /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 00000000000..3f7ddba8a28 --- /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 00000000000..da4e86169ad --- /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 00000000000..b760ba23cd2 --- /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 00000000000..4fd8286eac4 --- /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 00000000000..e029785bc24 --- /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 00000000000..e69de29bb2d -- cgit 1.4.1-3-g733a5 From 93b7de5b0110a1ab79714c3dfd009a4aae3e34b1 Mon Sep 17 00:00:00 2001 From: Chris Emerson Date: Wed, 6 Nov 2019 10:15:34 +0000 Subject: Make `--check` work when running from stdin. (#3896) # Conflicts: # src/bin/main.rs --- src/bin/main.rs | 31 ++++++------- src/emitter/checkstyle.rs | 12 ++--- src/emitter/json.rs | 20 ++++++--- src/test/mod.rs | 93 +++++++++++++++++++++++++++++++++++++++ tests/writemode/source/stdin.rs | 6 +++ tests/writemode/target/stdin.json | 1 + tests/writemode/target/stdin.xml | 2 + 7 files changed, 139 insertions(+), 26 deletions(-) create mode 100644 tests/writemode/source/stdin.rs create mode 100644 tests/writemode/target/stdin.json create mode 100644 tests/writemode/target/stdin.xml (limited to 'src') diff --git a/src/bin/main.rs b/src/bin/main.rs index 4d845547cdf..6f5b09fc86a 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -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 diff --git a/src/emitter/checkstyle.rs b/src/emitter/checkstyle.rs index 76f2527db3d..545b259979d 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/json.rs b/src/emitter/json.rs index 269dd2d4daf..4d6f972c5e3 100644 --- a/src/emitter/json.rs +++ b/src/emitter/json.rs @@ -3,7 +3,6 @@ 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 { @@ -47,7 +46,6 @@ 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(); @@ -62,7 +60,7 @@ impl Emitter for JsonEmitter { fn output_json_file( mut writer: T, - filename: &Path, + filename: &FileName, diff: Vec, num_emitted_files: u32, ) -> Result<(), io::Error> @@ -106,7 +104,7 @@ where }); } let json = to_json_string(&MismatchedFile { - name: String::from(filename.to_str().unwrap()), + name: format!("{}", filename), mismatches, })?; let prefix = if num_emitted_files > 0 { "," } else { "" }; @@ -148,7 +146,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); + let _ = output_json_file( + &mut writer, + &FileName::Real(PathBuf::from(file)), + vec![mismatch], + 0, + ); assert_eq!(&writer[..], format!("{}", exp_json).as_bytes()); } @@ -188,7 +191,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); + let _ = output_json_file( + &mut writer, + &FileName::Real(PathBuf::from(file)), + vec![mismatch], + 0, + ); assert_eq!(&writer[..], format!("{}", exp_json).as_bytes()); } diff --git a/src/test/mod.rs b/src/test/mod.rs index cceb28dfea6..e1a7972ec82 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] @@ -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(); @@ -896,3 +966,26 @@ 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()); +} diff --git a/tests/writemode/source/stdin.rs b/tests/writemode/source/stdin.rs new file mode 100644 index 00000000000..06f8a0c288d --- /dev/null +++ b/tests/writemode/source/stdin.rs @@ -0,0 +1,6 @@ + +fn + some( ) +{ +} +fn main () {} diff --git a/tests/writemode/target/stdin.json b/tests/writemode/target/stdin.json new file mode 100644 index 00000000000..20e38f57f4a --- /dev/null +++ b/tests/writemode/target/stdin.json @@ -0,0 +1 @@ +[{"name":"stdin","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 () {}","expected":"fn some() {}\nfn main() {}"}]}] \ No newline at end of file diff --git a/tests/writemode/target/stdin.xml b/tests/writemode/target/stdin.xml new file mode 100644 index 00000000000..e70708338f5 --- /dev/null +++ b/tests/writemode/target/stdin.xml @@ -0,0 +1,2 @@ + + -- cgit 1.4.1-3-g733a5 From 34263cd6bdb29df23258a96ea18fe986efe8dad0 Mon Sep 17 00:00:00 2001 From: Chris Emerson Date: Tue, 12 Nov 2019 02:55:04 +0000 Subject: Fix --check -l with stdin. (#3910) * Fix some possible panics when using `--check` with stdin. One case which doesn't work is when there are only line ending fixes; with stdin rustfmt is unable to detect the difference as it stores the input with Unix line endings. * Add test for `rustfmt --check -l` with stdin. --- src/emitter/diff.rs | 5 ++--- src/test/mod.rs | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/emitter/diff.rs b/src/emitter/diff.rs index 7264ad8bbf3..5e1f1344656 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/test/mod.rs b/src/test/mod.rs index e1a7972ec82..db1cf88479c 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -989,3 +989,29 @@ fn verify_check_works_with_stdin() { .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(), "stdin\n"); +} -- cgit 1.4.1-3-g733a5 From 776baf93f8fd1e2f3a66da4c2a1dd92114cef9c6 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Mon, 9 Dec 2019 04:41:16 -0600 Subject: refactor: update json emitter to better handle errors (#3953) --- src/emitter/json.rs | 169 +++++++++++++++++-------------------- tests/writemode/target/output.json | 2 +- tests/writemode/target/stdin.json | 2 +- 3 files changed, 80 insertions(+), 93 deletions(-) (limited to 'src') diff --git a/src/emitter/json.rs b/src/emitter/json.rs index 4d6f972c5e3..7c0f862cbc6 100644 --- a/src/emitter/json.rs +++ b/src/emitter/json.rs @@ -6,10 +6,10 @@ use std::io::{self, Write}; #[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, @@ -19,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, @@ -50,66 +44,61 @@ impl Emitter for JsonEmitter { 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: &FileName, - 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_lines = vec![]; + let mut expected_lines = vec![]; - 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_lines.push(msg) + } + DiffLine::Resulting(msg) => { + original_end_line = original_begin_line + original_line_counter; + original_line_counter += 1; + original_lines.push(msg) + } + 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: original_lines.join("\n"), + expected: expected_lines.join("\n"), + }); + } + self.mismatched_files.push(MismatchedFile { + name: format!("{}", filename), + mismatches, }); + Ok(()) } - let json = to_json_string(&MismatchedFile { - name: format!("{}", filename), - mismatches, - })?; - let prefix = if num_emitted_files > 0 { "," } else { "" }; - write!(writer, "{}{}", prefix, &json)?; - Ok(()) } #[cfg(test)] @@ -120,6 +109,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), @@ -144,19 +136,19 @@ mod tests { ], }; - let mut writer = Vec::new(); - let exp_json = to_json_string(&mismatched_file).unwrap(); - let _ = output_json_file( - &mut writer, - &FileName::Real(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), @@ -189,15 +181,12 @@ mod tests { ], }; - let mut writer = Vec::new(); - let exp_json = to_json_string(&mismatched_file).unwrap(); - let _ = output_json_file( - &mut writer, - &FileName::Real(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] @@ -217,7 +206,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] @@ -263,7 +252,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 { @@ -287,10 +276,10 @@ mod tests { ), }, ], - }) + }]) .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] @@ -325,7 +314,7 @@ 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, @@ -335,9 +324,9 @@ mod tests { original: String::from("println!(\"Hello, world!\");"), expected: String::from(" println!(\"Hello, world!\");"), }], - }) - .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, @@ -347,11 +336,9 @@ mod tests { original: String::from("println!(\"Greetings!\");"), expected: String::from(" println!(\"Greetings!\");"), }], - }) - .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/tests/writemode/target/output.json b/tests/writemode/target/output.json index b5f327b0a1c..acb33dea7ef 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}","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{"}]}] diff --git a/tests/writemode/target/stdin.json b/tests/writemode/target/stdin.json index 20e38f57f4a..ae6796863e5 100644 --- a/tests/writemode/target/stdin.json +++ b/tests/writemode/target/stdin.json @@ -1 +1 @@ -[{"name":"stdin","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 () {}","expected":"fn some() {}\nfn main() {}"}]}] \ No newline at end of file +[{"name":"stdin","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 () {}","expected":"fn some() {}\nfn main() {}"}]}] -- cgit 1.4.1-3-g733a5 From 894a3c0e7745ece39fcee89d38389a789cfe520a Mon Sep 17 00:00:00 2001 From: Tim Date: Tue, 23 Jun 2020 01:20:29 +0100 Subject: Fix newlines in JSON output (#4262) * Fix newlines in JSON output This changes the JSON output to be more consistent about where newlines are included. Previously it only included them between lines in a multiline diff. That meant single line changes were treated a bit weirdly. This changes it to append a newline to every line. When feeding the results into `arc lint` this behaves correctly. I have only done limited testing though, in particular there's a possibility it might not work with files with `\r\n` endings (though that would have been the case before too). Fixes #4259 * Update tests # Conflicts: # tests/writemode/target/output.json --- src/emitter/json.rs | 38 ++++++++++++++++++++------------------ tests/writemode/target/output.json | 2 +- tests/writemode/target/stdin.json | 2 +- 3 files changed, 22 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/emitter/json.rs b/src/emitter/json.rs index 7c0f862cbc6..c7f68d4675a 100644 --- a/src/emitter/json.rs +++ b/src/emitter/json.rs @@ -65,20 +65,22 @@ impl JsonEmitter { 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![]; + 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) + expected.push_str(&msg); + expected.push('\n'); } DiffLine::Resulting(msg) => { original_end_line = original_begin_line + original_line_counter; original_line_counter += 1; - original_lines.push(msg) + original.push_str(&msg); + original.push('\n'); } DiffLine::Context(_) => continue, } @@ -89,8 +91,8 @@ impl JsonEmitter { original_end_line, expected_begin_line, expected_end_line, - original: original_lines.join("\n"), - expected: expected_lines.join("\n"), + original, + expected, }); } self.mismatched_files.push(MismatchedFile { @@ -120,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 { @@ -158,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", ), }], }; @@ -260,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, @@ -269,10 +271,10 @@ 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", ), }, ], @@ -321,8 +323,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"), }], }; @@ -333,8 +335,8 @@ mod tests { 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"), }], }; diff --git a/tests/writemode/target/output.json b/tests/writemode/target/output.json index acb33dea7ef..d8b5467ee91 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{"}]}] +[{"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 index ae6796863e5..6f5d5bfb8ca 100644 --- a/tests/writemode/target/stdin.json +++ b/tests/writemode/target/stdin.json @@ -1 +1 @@ -[{"name":"stdin","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 () {}","expected":"fn some() {}\nfn main() {}"}]}] +[{"name":"stdin","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"}]}] -- cgit 1.4.1-3-g733a5 From 34d374ee5d23951d166ca3f51d477ddf6526a2fa Mon Sep 17 00:00:00 2001 From: Seiichi Uchida Date: Fri, 3 Jul 2020 11:13:16 +0900 Subject: Use when emitting stdin as filename (#4298) # Conflicts: # src/config/file_lines.rs # src/rustfmt/main.rs # src/test/mod.rs --- src/config/file_lines.rs | 2 +- src/test/mod.rs | 6 +++--- tests/writemode/target/stdin.json | 2 +- tests/writemode/target/stdin.xml | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/config/file_lines.rs b/src/config/file_lines.rs index 7b498dc46b3..e4e51a3f3b4 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/test/mod.rs b/src/test/mod.rs index db1cf88479c..2d5a8f22053 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -466,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] @@ -1013,5 +1013,5 @@ fn verify_check_l_works_with_stdin() { .wait_with_output() .expect("Failed to wait on rustfmt child"); assert!(output.status.success()); - assert_eq!(std::str::from_utf8(&output.stdout).unwrap(), "stdin\n"); + assert_eq!(std::str::from_utf8(&output.stdout).unwrap(), "\n"); } diff --git a/tests/writemode/target/stdin.json b/tests/writemode/target/stdin.json index 6f5d5bfb8ca..dbf2c486322 100644 --- a/tests/writemode/target/stdin.json +++ b/tests/writemode/target/stdin.json @@ -1 +1 @@ -[{"name":"stdin","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"}]}] +[{"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 index e70708338f5..a7301bbc553 100644 --- a/tests/writemode/target/stdin.xml +++ b/tests/writemode/target/stdin.xml @@ -1,2 +1,2 @@ - - + + -- cgit 1.4.1-3-g733a5 From 5056f4cfb311a084420f1828cd58af94d143f5e0 Mon Sep 17 00:00:00 2001 From: Matthias Krüger Date: Wed, 5 Jan 2022 21:19:36 +0100 Subject: some minor clippy fixes --- src/cargo-fmt/main.rs | 3 +-- src/format_report_formatter.rs | 1 + src/macros.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/cargo-fmt/main.rs b/src/cargo-fmt/main.rs index 759b21218c3..8cb7b4585ec 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/format_report_formatter.rs b/src/format_report_formatter.rs index c820259256c..90406cdb95e 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/macros.rs b/src/macros.rs index f29552caf8d..fdbe3374615 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -152,7 +152,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 { -- cgit 1.4.1-3-g733a5 From 9e1973f1d9b94914c3e5539f3ed992c19389b4a7 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Sun, 23 Jan 2022 11:18:17 -0600 Subject: chore: bump toolchain, update test --- rust-toolchain | 2 +- src/test/mod.rs | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/rust-toolchain b/rust-toolchain index d4cdcec2018..d8bf02aec85 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2021-12-29" +channel = "nightly-2022-01-23" components = ["rustc-dev"] diff --git a/src/test/mod.rs b/src/test/mod.rs index c399512ba7e..ab966d4a360 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -572,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] -- cgit 1.4.1-3-g733a5 From b4a4bf0bf8a16913b9f16f2aee7030065ff00931 Mon Sep 17 00:00:00 2001 From: Szymon Gibała Date: Sat, 29 Jan 2022 05:55:47 +0100 Subject: Fix formatting of comments in empty structs (#5171) * Fix formatting of comments in empty structs * Add tests * Add single line tests * Fix block comments * Revert changes of test source files --- src/items.rs | 10 +- tests/source/issue_4854.rs | 113 ++++++++++++++++++++ .../comments-in-lists/format-doc-comments.rs | 10 +- .../comments-in-lists/wrap-comments-false.rs | 10 +- .../wrap-comments-not-normalized.rs | 8 +- .../target/comments-in-lists/wrap-comments-true.rs | 8 +- tests/target/issue_4854.rs | 115 +++++++++++++++++++++ 7 files changed, 251 insertions(+), 23 deletions(-) create mode 100644 tests/source/issue_4854.rs create mode 100644 tests/target/issue_4854.rs (limited to 'src') diff --git a/src/items.rs b/src/items.rs index babc56f86ed..4c7a33c86d2 100644 --- a/src/items.rs +++ b/src/items.rs @@ -1374,17 +1374,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)); } } diff --git a/tests/source/issue_4854.rs b/tests/source/issue_4854.rs new file mode 100644 index 00000000000..35d6e21affe --- /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/comments-in-lists/format-doc-comments.rs b/tests/target/comments-in-lists/format-doc-comments.rs index be31bf0a331..be4b7a8c42e 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 80aea59d1b5..db4da622372 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 52315f470e4..9b9147eb124 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 e0bfcf0b500..c1531d22a4a 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/issue_4854.rs b/tests/target/issue_4854.rs new file mode 100644 index 00000000000..a81c5a5171f --- /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 */} +} -- cgit 1.4.1-3-g733a5 From 8b0b213cddb23a9bbe421b717d1a0e5fb3982712 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Thu, 9 Dec 2021 23:17:43 -0500 Subject: Prevent adding trailing whitespace when rewriting ast::Param Fixes 5125 Previously, a newline was always added, even if the parameter name was not preceded by any param attrs. Now a newline is only added if there were param attrs. --- src/items.rs | 8 +++++++- .../attributes_in_formal_fuction_parameter.rs | 6 ++++++ .../long_parameter_in_different_positions.rs | 24 ++++++++++++++++++++++ tests/target/issue-5125/minimum_example.rs | 6 ++++++ .../issue-5125/with_leading_and_inline_comments.rs | 7 +++++++ 5 files changed, 50 insertions(+), 1 deletion(-) 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 (limited to 'src') diff --git a/src/items.rs b/src/items.rs index 4c7a33c86d2..007609aba24 100644 --- a/src/items.rs +++ b/src/items.rs @@ -2018,9 +2018,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/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 00000000000..5d167932828 --- /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 00000000000..cab20381ce8 --- /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 00000000000..8003e66968c --- /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 00000000000..2340b2f3472 --- /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 +) { +} -- cgit 1.4.1-3-g733a5 From 368a9b7cef25c22c3e836453e73d8584b251b578 Mon Sep 17 00:00:00 2001 From: Stéphane Campinas Date: Wed, 2 Feb 2022 02:06:14 +0100 Subject: Handle non-ascii character at boundary (#5089) * Handle non-ascii character at boundary * Replace substraction underflow check with early termination --- src/string.rs | 5 ++++- tests/source/issue-5023.rs | 22 ++++++++++++++++++++++ tests/target/issue-5023.rs | 23 +++++++++++++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 tests/source/issue-5023.rs create mode 100644 tests/target/issue-5023.rs (limited to 'src') diff --git a/src/string.rs b/src/string.rs index 64ae15672df..b65aa5b33b2 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/tests/source/issue-5023.rs b/tests/source/issue-5023.rs new file mode 100644 index 00000000000..ae1c723eff7 --- /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/target/issue-5023.rs b/tests/target/issue-5023.rs new file mode 100644 index 00000000000..4e84c7d9842 --- /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(); + } +} -- cgit 1.4.1-3-g733a5 From 606894eb0b1dcc3a4616aff4b54dbd19a2a46ba5 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Sun, 19 Dec 2021 16:47:13 -0500 Subject: Retain trailing separator when extracting the last inline post comment Fixes 5042 Previously, trailing commas were removed from the last inline comment. This lead to rustfmt refusing to format code snippets because the original comment did not match the rewritten comment. Now, when rustfmt extracts the last inline comment it leaves trailing separators alone. Rustfmt does not need to remove these separators because they are commented out. --- src/lists.rs | 27 ++++++++++++++++------ .../multi-line_comment_with_trailing_comma.rs | 24 +++++++++++++++++++ .../multi-line_comment_without_trailing_comma.rs | 24 +++++++++++++++++++ .../single-line_comment_with_trailing_comma.rs | 9 ++++++++ .../single-line_comment_without_trailing_comma.rs | 10 ++++++++ .../multi-line_comment_with_trailing_comma.rs | 24 +++++++++++++++++++ .../multi-line_comment_without_trailing_comma.rs | 24 +++++++++++++++++++ .../single-line_comment_with_trailing_comma.rs | 7 ++++++ .../single-line_comment_without_trailing_comma.rs | 7 ++++++ 9 files changed, 149 insertions(+), 7 deletions(-) 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/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 (limited to 'src') diff --git a/src/lists.rs b/src/lists.rs index 7aa0315f18c..97eea19f932 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/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 00000000000..5d171f32a1a --- /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 00000000000..b8a824b34b7 --- /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 00000000000..bd765b7b41f --- /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 00000000000..2ed8de875ad --- /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/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 00000000000..1ae1212b488 --- /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 00000000000..30d174664c9 --- /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 00000000000..87b651dd285 --- /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 00000000000..116df86a4b5 --- /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 /* ... */); +} -- cgit 1.4.1-3-g733a5 From b2c7a52ea865f877bc0b57075fe1a88f83120546 Mon Sep 17 00:00:00 2001 From: Stéphane Campinas Date: Mon, 31 Jan 2022 23:45:30 +0100 Subject: Fix import_granularity option when the use tree has an alias --- src/imports.rs | 6 ++++-- tests/source/5131.rs | 33 +++++++++++++++++++++++++++++++++ tests/target/5131.rs | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 tests/source/5131.rs create mode 100644 tests/target/5131.rs (limited to 'src') diff --git a/src/imports.rs b/src/imports.rs index 40e0d06f99d..c60bec6d4a2 100644 --- a/src/imports.rs +++ b/src/imports.rs @@ -238,7 +238,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 +623,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; diff --git a/tests/source/5131.rs b/tests/source/5131.rs new file mode 100644 index 00000000000..3e9139177c5 --- /dev/null +++ b/tests/source/5131.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/target/5131.rs b/tests/target/5131.rs new file mode 100644 index 00000000000..763024d6fa4 --- /dev/null +++ b/tests/target/5131.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); + } + } +} -- cgit 1.4.1-3-g733a5 From 5df8c8f7e554e036fcb14a2d93d145c92d56bc2e Mon Sep 17 00:00:00 2001 From: Frank King Date: Mon, 7 Feb 2022 10:57:39 +0800 Subject: Fix doc of generic items formmating error (#5124) * Fix doc of generic items formmating error * Remove tracked `attrs_end_with_doc_comment` flag in `RewriteContext` * Fix duplicated doc comments of const generic params * Fix `::span()` * Remove duplicated source file of `doc-of-generic-item.rs` --- src/spanned.rs | 15 ++++----------- src/types.rs | 11 ++++++++++- tests/target/doc-of-generic-item.rs | 14 ++++++++++++++ 3 files changed, 28 insertions(+), 12 deletions(-) create mode 100644 tests/target/doc-of-generic-item.rs (limited to 'src') diff --git a/src/spanned.rs b/src/spanned.rs index 8e6c75a3744..2136cfeae1a 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/types.rs b/src/types.rs index 5de30129266..b13e75a93b3 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/tests/target/doc-of-generic-item.rs b/tests/target/doc-of-generic-item.rs new file mode 100644 index 00000000000..2efc5e09a3d --- /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, +>; -- cgit 1.4.1-3-g733a5 From ace7241087bedd2ea26d7b1dfcdd6133cbf77ce7 Mon Sep 17 00:00:00 2001 From: Gabriel Smith Date: Sat, 29 Jan 2022 16:44:49 -0500 Subject: Fix incorrect string indentation in macro defs with `format_strings` --- CHANGELOG.md | 4 ++++ src/utils.rs | 19 ++++++++++++++++--- tests/source/issue-4036/one.rs | 11 +++++++++++ tests/source/issue-4036/three.rs | 12 ++++++++++++ tests/source/issue-4036/two.rs | 11 +++++++++++ tests/target/issue-4036/one.rs | 12 ++++++++++++ tests/target/issue-4036/three.rs | 17 +++++++++++++++++ tests/target/issue-4036/two.rs | 16 ++++++++++++++++ 8 files changed, 99 insertions(+), 3 deletions(-) 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/target/issue-4036/one.rs create mode 100644 tests/target/issue-4036/three.rs create mode 100644 tests/target/issue-4036/two.rs (limited to 'src') diff --git a/CHANGELOG.md b/CHANGELOG.md index b59438dc4fe..1b9208d31e0 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 diff --git a/src/utils.rs b/src/utils.rs index 2428d8cb0fd..35512e78fa6 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/tests/source/issue-4036/one.rs b/tests/source/issue-4036/one.rs new file mode 100644 index 00000000000..9f9675f5163 --- /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 00000000000..e1865dd0868 --- /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 00000000000..fa54d2e3e09 --- /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/target/issue-4036/one.rs b/tests/target/issue-4036/one.rs new file mode 100644 index 00000000000..54e490b7fbe --- /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 00000000000..394dc8633f5 --- /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 00000000000..01cafa76b68 --- /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.", + ) + } + }; +} -- cgit 1.4.1-3-g733a5 From b05b3138001c97cbabeb3e20a0960b9f75341ee0 Mon Sep 17 00:00:00 2001 From: Tharun Rajendran Date: Fri, 11 Feb 2022 10:05:45 +0530 Subject: chore(rustfmt): remove executable path from usage string (#5216) * chore(rustfmt): remove executable path from usage string * add unit test for usage string * rename test and check usage text in a single assert --- src/bin/main.rs | 5 ++--- tests/rustfmt/main.rs | 9 +++++++++ 2 files changed, 11 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/bin/main.rs b/src/bin/main.rs index 6f5b09fc86a..196de6056b5 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -394,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/tests/rustfmt/main.rs b/tests/rustfmt/main.rs index 8effb1c6fca..6976cc4d346 100644 --- a/tests/rustfmt/main.rs +++ b/tests/rustfmt/main.rs @@ -106,3 +106,12 @@ fn inline_config() { && contains("format_strings = true") ); } + +#[test] +fn rustfmt_usage_text() { + let args = [ + "--help", + ]; + let (stdout, _) = rustfmt(&args); + assert!(stdout.contains(&format!("Format Rust code\n\nusage: rustfmt [options] ..."))); +} -- cgit 1.4.1-3-g733a5 From 1e78a2b258470fcab13e8c933212667e64b21d3e Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Wed, 29 Dec 2021 19:59:54 -0500 Subject: Leverage itemized blocks to support formatting markdown block quotes Fixes 5157 Doc comments support markdown, but rustfmt didn't previously assign any semantic value to leading '> ' in comments. This lead to poor formatting when using ``wrap_comments=true``. Now, rustfmt treats block quotes as itemized blocks, which greatly improves how block quotes are formatted when ``wrap_comments=true``. --- src/comment.rs | 46 ++++++++++++++++++---- .../indented_itemized_markdown_blockquote.rs | 4 ++ .../nested_itemized_markdown_blockquote.rs | 10 +++++ .../support_itemized_markdown_blockquote.rs | 4 ++ .../indented_itemized_markdown_blockquote.rs | 6 +++ .../nested_itemized_markdown_blockquote.rs | 18 +++++++++ .../support_itemized_markdown_blockquote.rs | 6 +++ 7 files changed, 87 insertions(+), 7 deletions(-) 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/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 (limited to 'src') diff --git a/src/comment.rs b/src/comment.rs index 0f850b9b2f2..96778c4ef1d 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, 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 00000000000..5c1d79a7430 --- /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 00000000000..cf200d04e08 --- /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 00000000000..eb436402e4e --- /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/target/issue-5157/indented_itemized_markdown_blockquote.rs b/tests/target/issue-5157/indented_itemized_markdown_blockquote.rs new file mode 100644 index 00000000000..e47677f2039 --- /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 00000000000..079510442b7 --- /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 00000000000..029ee37d22a --- /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() {} -- cgit 1.4.1-3-g733a5 From 6c476127aedc37b43769469f87e0fbc382382739 Mon Sep 17 00:00:00 2001 From: Travis Finkenauer Date: Tue, 15 Feb 2022 15:25:44 -0800 Subject: Add context to get_toml_path() error (#5207) * rustfmt: print full error chain * Add context to get_toml_path() error Instead of an error like: ``` Permission denied (os error 13) ``` Gives error like: ``` Failed to get metadata for config file "/root/.rustfmt.toml": Permission denied (os error 13) ``` --- src/bin/main.rs | 2 +- src/config/mod.rs | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/bin/main.rs b/src/bin/main.rs index 196de6056b5..ad10b9ede60 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 } }; diff --git a/src/config/mod.rs b/src/config/mod.rs index cd90e0904b6..5041e1e36dd 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -364,7 +364,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)); } } _ => {} -- cgit 1.4.1-3-g733a5 From c63d42e80473a0c18714b55058f27506fd24955c Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Tue, 1 Feb 2022 13:39:01 -0600 Subject: Use cargo-fmt in self_tests --- src/test/mod.rs | 46 ++++++++++++---------------------------------- 1 file changed, 12 insertions(+), 34 deletions(-) (limited to 'src') diff --git a/src/test/mod.rs b/src/test/mod.rs index ab966d4a360..4191e3e96b0 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -375,43 +375,21 @@ fn idempotence_tests() { }); } -// Run rustfmt on itself. This operation must be idempotent. We also check that -// no warnings are emitted. -// Issue-3443: these tests require nightly #[nightly_only_test] #[test] fn self_tests() { - init_log(); - let mut files = get_test_files(Path::new("tests"), false); - let bin_directories = vec!["cargo-fmt", "git-rustfmt", "bin", "format-diff"]; - for dir in bin_directories { - let mut path = PathBuf::from("src"); - path.push(dir); - path.push("main.rs"); - files.push(path); - } - files.push(PathBuf::from("src/lib.rs")); - - let (reports, count, fails) = check_files(files, &Some(PathBuf::from("rustfmt.toml"))); - let mut warnings = 0; - - // Display results. - println!("Ran {} self tests.", count); - assert_eq!(fails, 0, "{} self tests failed", fails); - - for format_report in reports { - println!( - "{}", - FormatReportFormatterBuilder::new(&format_report).build() - ); - warnings += format_report.warning_count(); - } - - assert_eq!( - warnings, 0, - "Rustfmt's code generated {} warnings", - warnings - ); + let get_exe_path = |name| { + let mut path = env::current_exe().unwrap(); + path.pop(); + path.set_file_name(format!("{name}{}", env::consts::EXE_SUFFIX)); + path + }; + let status = Command::new(get_exe_path("cargo-fmt")) + .args(["--check", "--all"]) + .env("RUSTFMT", get_exe_path("rustfmt")) + .status() + .unwrap(); + assert!(status.success()); } #[test] -- cgit 1.4.1-3-g733a5 From 89ca3f3a100456d652b156b1a62b8e244e526c4e Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Wed, 23 Feb 2022 21:37:42 -0600 Subject: fix: unused test imports on non-nightly, prevent regression --- .github/workflows/linux.yml | 4 ++++ src/ignore_path.rs | 9 ++++----- src/lib.rs | 1 - 3 files changed, 8 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index db497941642..45f63b83c05 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/src/ignore_path.rs b/src/ignore_path.rs index 7738eee0a76..d955949496a 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/lib.rs b/src/lib.rs index fae8080c02e..ad23b16e02e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,7 +3,6 @@ #![warn(unreachable_pub)] #![recursion_limit = "256"] #![allow(clippy::match_like_matches_macro)] -#![allow(unreachable_pub)] #[macro_use] extern crate derive_new; -- cgit 1.4.1-3-g733a5 From 12048e444f8a68b3c13e98b15c11a69de9f0b485 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Sun, 30 Jan 2022 13:46:53 -0500 Subject: fallback to dir_path when relative external mod resolution fails We only want to fall back if two conditions are met: 1) Initial module resolution is performed relative to some nested directory. 2) Module resolution fails because of a ModError::FileNotFound error. When these conditions are met we can try to fallback to searching for the module's file relative to the dir_path instead of the nested relative directory. Fixes 5198 As demonstrated by 5198, it's possible that a directory name conflicts with a rust file name. For example, src/lib/ and src/lib.rs. If src/lib.rs references an external module like ``mod foo;``, then module resolution will try to resolve ``foo`` to src/lib/foo.rs or src/lib/foo/mod.rs. Module resolution would fail with a file not found error if the ``foo`` module were defined at src/foo.rs. When encountering these kinds of module resolution issues we now fall back to the current directory and attempt to resolve the module again. Given the current example, this means that if we can't find the module ``foo`` at src/lib/foo.rs or src/lib/foo/mod.rs, we'll attempt to resolve the module to src/foo.rs. --- src/parse/session.rs | 22 ++++++++++++++++++++-- src/test/mod_resolver.rs | 16 ++++++++++++++++ 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 + tests/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 +++ tests/mod-resolver/issue-5198/lib/explanation.txt | 16 ++++++++++++++++ 12 files changed, 82 insertions(+), 2 deletions(-) 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 (limited to 'src') diff --git a/src/parse/session.rs b/src/parse/session.rs index 624fed0d2de..fb9182152d1 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,30 @@ 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 matches!(e, ModError::FileNotFound(..)) && relative.is_some() { + rustc_expand::module::default_submod_path(&self.parse_sess, id, None, dir_path) + } else { + Err(e) + } + }, + ) } pub(crate) fn is_file_parsed(&self, path: &Path) -> bool { diff --git a/src/test/mod_resolver.rs b/src/test/mod_resolver.rs index fcff6d14e6f..aacb2acc684 100644 --- a/src/test/mod_resolver.rs +++ b/src/test/mod_resolver.rs @@ -64,3 +64,19 @@ fn fmt_out_of_line_test_modules() { ], ) } + +#[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/tests/mod-resolver/issue-5198/a.rs b/tests/mod-resolver/issue-5198/a.rs new file mode 100644 index 00000000000..cd686f56116 --- /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 00000000000..696832913c8 --- /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 00000000000..cd686f56116 --- /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 00000000000..d1604aa23a3 --- /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 00000000000..92c9e302143 --- /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 00000000000..cd686f56116 --- /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 00000000000..cd686f56116 --- /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 00000000000..cd686f56116 --- /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 00000000000..81904619650 --- /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 00000000000..d436a8076cd --- /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. -- cgit 1.4.1-3-g733a5 From 272fb42f06479afb62a9503f181540101f67982a Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Fri, 25 Feb 2022 11:31:09 -0500 Subject: Prevent wrapping markdown headers in doc comments Fixes 5238 A markdown header is defined by a string that starts with `#`. Previously, rustfmt would wrap long markdown headers when `wrap_comments=true`. This lead to issues when rendering these headers in HTML using rustdoc. Now, rustfmt leaves markdown headers alone when wrapping comments. --- src/comment.rs | 18 ++++++++++++++---- .../issue-5238/markdown_header_wrap_comments_false.rs | 11 +++++++++++ .../issue-5238/markdown_header_wrap_comments_true.rs | 11 +++++++++++ .../issue-5238/markdown_header_wrap_comments_false.rs | 11 +++++++++++ .../issue-5238/markdown_header_wrap_comments_true.rs | 14 ++++++++++++++ 5 files changed, 61 insertions(+), 4 deletions(-) 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/target/issue-5238/markdown_header_wrap_comments_false.rs create mode 100644 tests/target/issue-5238/markdown_header_wrap_comments_true.rs (limited to 'src') diff --git a/src/comment.rs b/src/comment.rs index 96778c4ef1d..f9d8a0fa70c 100644 --- a/src/comment.rs +++ b/src/comment.rs @@ -683,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; @@ -789,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'); @@ -882,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/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 00000000000..229c6e5753d --- /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 00000000000..c547ff35c69 --- /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/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 00000000000..229c6e5753d --- /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 00000000000..87dae58eccd --- /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` +} -- cgit 1.4.1-3-g733a5 From ee130515e3788d886cdf18442871936a99c134b6 Mon Sep 17 00:00:00 2001 From: cassaundra Date: Wed, 29 Dec 2021 15:41:26 -0800 Subject: Fix missing struct field separators under certain conditions When struct_field_align_threshold is non-zero and trailing_comma is set to "Never," struct field separators are omitted between field groups. This issue is resolved by forcing separators between groups. Fixes #4791. A test is included with a minimal reproducible example. --- src/vertical.rs | 23 ++++++++++++++++++++--- tests/source/issue_4791.rs | 14 ++++++++++++++ tests/target/issue_4791.rs | 14 ++++++++++++++ 3 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 tests/source/issue_4791.rs create mode 100644 tests/target/issue_4791.rs (limited to 'src') diff --git a/src/vertical.rs b/src/vertical.rs index c4208848c6c..a06bc995aa5 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/source/issue_4791.rs b/tests/source/issue_4791.rs new file mode 100644 index 00000000000..4760022eeaf --- /dev/null +++ b/tests/source/issue_4791.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.rs b/tests/target/issue_4791.rs new file mode 100644 index 00000000000..fff58be99a5 --- /dev/null +++ b/tests/target/issue_4791.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 +} -- cgit 1.4.1-3-g733a5 From 18c0369688d5854ea67dbe29cfac3cc8380cb20e Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Mon, 10 Jan 2022 20:45:27 -0500 Subject: Improve mod resolution error for mods with multiple candidate files Fixes 5167 When ``a.rs`` and ``a/mod.rs`` are both present we would emit an error message telling the user that the module couldn't be found. However, this behavior is misleading because we're dealing with an ambiguous module path, not a "file not found" error. Is the file ``a.rs`` or is it ``a/mod.rs``? Rustfmt can't decide, and the user needs to resolve this ambiguity themselves. Now, the error message displayed to the user is in line with what they would see if they went to compile their code with these conflicting module names. --- src/modules.rs | 38 ++++++++++++++++--- src/parse/session.rs | 3 ++ 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 + .../module-not-found/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 + tests/rustfmt/main.rs | 44 ++++++++++++++++++++++ 10 files changed, 88 insertions(+), 6 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/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 (limited to 'src') diff --git a/src/modules.rs b/src/modules.rs index 70b937b0283..49c99403974 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(), + }, + }), + }, } } diff --git a/src/parse/session.rs b/src/parse/session.rs index fb9182152d1..87ab8fbf20a 100644 --- a/src/parse/session.rs +++ b/src/parse/session.rs @@ -163,8 +163,11 @@ impl ParseSess { |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) } 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 00000000000..e69de29bb2d 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 00000000000..e69de29bb2d 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 00000000000..f21af614da0 --- /dev/null +++ b/tests/mod-resolver/issue-5167/src/lib.rs @@ -0,0 +1 @@ +mod a; 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 00000000000..2a63c961be8 --- /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 00000000000..4a1eac8965d --- /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 00000000000..f21af614da0 --- /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 00000000000..d9d9e1e3c90 --- /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/rustfmt/main.rs b/tests/rustfmt/main.rs index 2262ae3aaac..450051d2fec 100644 --- a/tests/rustfmt/main.rs +++ b/tests/rustfmt/main.rs @@ -113,3 +113,47 @@ fn rustfmt_usage_text() { 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")); +} -- cgit 1.4.1-3-g733a5 From b4de150dbc65a6bb95c86517430726c55251d0b0 Mon Sep 17 00:00:00 2001 From: Tom Milligan Date: Fri, 4 Mar 2022 18:13:08 +0000 Subject: fix: imports_granularity module with path containing self --- src/imports.rs | 50 +++++++++++++++++++++++------- tests/source/imports_granularity_module.rs | 1 + tests/target/imports_granularity_module.rs | 2 ++ 3 files changed, 41 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/imports.rs b/src/imports.rs index c60bec6d4a2..02319809486 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() } @@ -635,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( @@ -1311,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/tests/source/imports_granularity_module.rs b/tests/source/imports_granularity_module.rs index 5a4fad5872b..2d7bb299aaa 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/target/imports_granularity_module.rs b/tests/target/imports_granularity_module.rs index 9c1387c466a..e4e1a299e58 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)] -- cgit 1.4.1-3-g733a5 From 5696e3859707d2abf12465e7bfbdcf2d9f42c8a2 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Sat, 12 Mar 2022 01:16:08 -0500 Subject: Add test to verify tracking issue links Now, tracking issue links are checked against the reference number listed in the link text to ensure they match. --- src/test/configuration_snippet.rs | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'src') diff --git a/src/test/configuration_snippet.rs b/src/test/configuration_snippet.rs index 92949ab576a..c8fda7c8556 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, + ); + } + } +} -- cgit 1.4.1-3-g733a5 From 1bb85bdf6b6dc0e205009b9f531a6220fe2031f9 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Wed, 9 Mar 2022 20:53:51 -0600 Subject: chore: add utility function for relative span positions --- src/parse/session.rs | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src') diff --git a/src/parse/session.rs b/src/parse/session.rs index 87ab8fbf20a..a95324bbb0e 100644 --- a/src/parse/session.rs +++ b/src/parse/session.rs @@ -218,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) } -- cgit 1.4.1-3-g733a5 From e41329ce87409df929ecfa191297f944472cc999 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Sun, 20 Mar 2022 13:21:44 -0400 Subject: Search for struct body span after any generic arguments Fixes 5273 Previously, rustfmt searched for the start of a struct body after the opening `{`. In most cases this works just fine, but const values can also be defined between `{ }`, which lead to issues when rewriting the struct body. Now, rustfmt will search for the `{` after the generic argument list to guarantee that the `{` it finds is the start of the struct body. --- src/items.rs | 8 +++++++- tests/target/issue_5273.rs | 3 +++ 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 tests/target/issue_5273.rs (limited to 'src') diff --git a/src/items.rs b/src/items.rs index 9b35d28f119..92f423bbb62 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( diff --git a/tests/target/issue_5273.rs b/tests/target/issue_5273.rs new file mode 100644 index 00000000000..3bb9048a5fd --- /dev/null +++ b/tests/target/issue_5273.rs @@ -0,0 +1,3 @@ +struct Example { + // +} -- cgit 1.4.1-3-g733a5 From 0dba01aee15a45b8417c06df69e38af6956e03a8 Mon Sep 17 00:00:00 2001 From: 123vivekr <123vivekr@gmail.com> Date: Sun, 13 Feb 2022 17:54:09 +0530 Subject: Add `short_item_threshold` config option Allow custom short item threshold values via config --- Configurations.md | 34 ++++++++++++++++++++++ src/config/mod.rs | 3 ++ src/overflow.rs | 13 +++++---- .../short_array_element_width_threshold/10.rs | 11 +++++++ .../short_array_element_width_threshold/20.rs | 11 +++++++ .../greater_than_max_width.rs | 12 ++++++++ .../short_array_element_width_threshold/10.rs | 11 +++++++ .../short_array_element_width_threshold/20.rs | 8 +++++ .../greater_than_max_width.rs | 12 ++++++++ 9 files changed, 110 insertions(+), 5 deletions(-) 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/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 (limited to 'src') diff --git a/Configurations.md b/Configurations.md index ecec97dca52..a47439b9ba9 100644 --- a/Configurations.md +++ b/Configurations.md @@ -2200,6 +2200,40 @@ 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 diff --git a/src/config/mod.rs b/src/config/mod.rs index 5041e1e36dd..18e1854612b 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, @@ -591,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/overflow.rs b/src/overflow.rs index 3475f5c378c..80aed998d73 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/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 00000000000..7d0d70919a6 --- /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 00000000000..8a93a51d6a2 --- /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 00000000000..710b6fe7c4b --- /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/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 00000000000..78c4adba1c1 --- /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 00000000000..6084690652f --- /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 00000000000..710b6fe7c4b --- /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, + ]; +} -- cgit 1.4.1-3-g733a5 From 8984438a6faf11e0cb8e876e80f177a42a43904d Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Fri, 18 Mar 2022 09:48:45 -0400 Subject: Honor `#[rustfmt::skip::attributes(derive)]` attribute Fixes 5270 Previously, rustfmt only checked the `merge_derives` configuration value to determine if it should merge_derives. This lead to derives being merged even when annotated with the `rustfmt::skip` attribute. Now, rustfmt also checks if derives are explicitly being skipped in the current context via the `rustfmt::skip` attribute. --- src/attr.rs | 6 ++- tests/source/issue-5270/merge_derives_true.rs | 62 ++++++++++++++++++++++++++ tests/target/issue-5270/merge_derives_false.rs | 62 ++++++++++++++++++++++++++ tests/target/issue-5270/merge_derives_true.rs | 60 +++++++++++++++++++++++++ 4 files changed, 189 insertions(+), 1 deletion(-) create mode 100644 tests/source/issue-5270/merge_derives_true.rs create mode 100644 tests/target/issue-5270/merge_derives_false.rs create mode 100644 tests/target/issue-5270/merge_derives_true.rs (limited to 'src') diff --git a/src/attr.rs b/src/attr.rs index 3887a8051f2..befe12ae2c4 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/tests/source/issue-5270/merge_derives_true.rs b/tests/source/issue-5270/merge_derives_true.rs new file mode 100644 index 00000000000..b31bbf095e7 --- /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/target/issue-5270/merge_derives_false.rs b/tests/target/issue-5270/merge_derives_false.rs new file mode 100644 index 00000000000..3b6f7e66993 --- /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 00000000000..5f488b4542d --- /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, + } +} -- cgit 1.4.1-3-g733a5 From 4fecede7fdaeeb859b066394bf27401fd13743a7 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Mon, 28 Mar 2022 20:27:42 -0500 Subject: Revert "Use cargo-fmt in self_tests" This reverts commit c63d42e80473a0c18714b55058f27506fd24955c. --- src/test/mod.rs | 46 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/test/mod.rs b/src/test/mod.rs index 4191e3e96b0..ab966d4a360 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -375,21 +375,43 @@ fn idempotence_tests() { }); } +// Run rustfmt on itself. This operation must be idempotent. We also check that +// no warnings are emitted. +// Issue-3443: these tests require nightly #[nightly_only_test] #[test] fn self_tests() { - let get_exe_path = |name| { - let mut path = env::current_exe().unwrap(); - path.pop(); - path.set_file_name(format!("{name}{}", env::consts::EXE_SUFFIX)); - path - }; - let status = Command::new(get_exe_path("cargo-fmt")) - .args(["--check", "--all"]) - .env("RUSTFMT", get_exe_path("rustfmt")) - .status() - .unwrap(); - assert!(status.success()); + init_log(); + let mut files = get_test_files(Path::new("tests"), false); + let bin_directories = vec!["cargo-fmt", "git-rustfmt", "bin", "format-diff"]; + for dir in bin_directories { + let mut path = PathBuf::from("src"); + path.push(dir); + path.push("main.rs"); + files.push(path); + } + files.push(PathBuf::from("src/lib.rs")); + + let (reports, count, fails) = check_files(files, &Some(PathBuf::from("rustfmt.toml"))); + let mut warnings = 0; + + // Display results. + println!("Ran {} self tests.", count); + assert_eq!(fails, 0, "{} self tests failed", fails); + + for format_report in reports { + println!( + "{}", + FormatReportFormatterBuilder::new(&format_report).build() + ); + warnings += format_report.warning_count(); + } + + assert_eq!( + warnings, 0, + "Rustfmt's code generated {} warnings", + warnings + ); } #[test] -- cgit 1.4.1-3-g733a5 From 5ff7b632a95bac6955611d85040859128902c580 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Tue, 29 Mar 2022 12:59:07 -0700 Subject: Preserve semicolon after macro call inside foreign mod --- src/macros.rs | 14 ++++++++++++-- tests/source/extern.rs | 4 ++-- tests/target/extern.rs | 4 ++-- 3 files changed, 16 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/macros.rs b/src/macros.rs index fdbe3374615..664f152e8be 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( @@ -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/tests/source/extern.rs b/tests/source/extern.rs index 5b981385d2b..f51ba6e98c9 100644 --- a/tests/source/extern.rs +++ b/tests/source/extern.rs @@ -84,9 +84,9 @@ macro_rules! x { extern "macros" { x!(ident); - // x!(#); FIXME + x!(#); x![ident]; - // x![#]; FIXME + x![#]; x! {ident} x! {#} } diff --git a/tests/target/extern.rs b/tests/target/extern.rs index 570d21c17df..d1741360cfd 100644 --- a/tests/target/extern.rs +++ b/tests/target/extern.rs @@ -89,9 +89,9 @@ macro_rules! x { extern "macros" { x!(ident); - // x!(#); FIXME + x!(#); x![ident]; - // x![#]; FIXME + x![#]; x! {ident} x! {#} } -- cgit 1.4.1-3-g733a5 From 1dcdfb276d8a10470ce1c6a6fd20a6104c313d82 Mon Sep 17 00:00:00 2001 From: Tharun Rajendran Date: Sat, 2 Apr 2022 05:30:53 +0530 Subject: 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 (limited to 'src') diff --git a/src/items.rs b/src/items.rs index 92f423bbb62..79f6ff69aa9 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 00000000000..191a6210045 --- /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 00000000000..ebb01a668f4 --- /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, +} -- cgit 1.4.1-3-g733a5 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: 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(-) (limited to 'src') diff --git a/Cargo.lock b/Cargo.lock index 1b444136585..4eaaee74cf9 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 4325f46db9f..0be9723bc4d 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 8cb7b4585ec..3542536f29b 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 360503632c7..56e52fbabb6 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 655aeda42bf..f6b739e1c2a 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() ); } -- cgit 1.4.1-3-g733a5 From 2d9bc460108df4e3587be82e36a58f2fb3f4813f Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Tue, 14 Jul 2020 00:03:13 -0500 Subject: Backport 4326 refactor: rename some private whitelist names --- src/overflow.rs | 12 ++++++------ src/test/mod.rs | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/overflow.rs b/src/overflow.rs index 80aed998d73..c296961d1f0 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 ab966d4a360..4bad8e71481 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)) } -- cgit 1.4.1-3-g733a5 From ba0351a1460e1e415293aa5e2b347b83e933703f Mon Sep 17 00:00:00 2001 From: Paul Gey Date: Sun, 17 Oct 2021 16:21:53 +0200 Subject: 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 (limited to 'src') diff --git a/src/imports.rs b/src/imports.rs index 02319809486..485a72b85da 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 13bfc92507d..f565612ded1 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 00000000000..f367e79f01f --- /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 00000000000..b371331ed00 --- /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; -- cgit 1.4.1-3-g733a5 From 9b1b3d69559750cf459638076dc32202110ec40e Mon Sep 17 00:00:00 2001 From: Tom Milligan Date: Sat, 16 Apr 2022 11:50:24 +0100 Subject: [review] rename internal function --- src/imports.rs | 7 +++++-- src/reorder.rs | 8 +++++--- 2 files changed, 10 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/imports.rs b/src/imports.rs index 485a72b85da..efe4e9498c9 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 f565612ded1..8ae297de25b 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 => { -- cgit 1.4.1-3-g733a5 From a37d3ab0e1c7c05f1a6410fb7ddf5539f0d030f8 Mon Sep 17 00:00:00 2001 From: hkalbasi Date: Wed, 15 Dec 2021 19:38:31 +0330 Subject: 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 (limited to 'src') diff --git a/src/expr.rs b/src/expr.rs index 4f333cd27ce..cfecc9b9d89 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 ca93955a549..281d3e4e808 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 4a3bd129d16..f97df70cc6a 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 4376fd12b52..b3f785a9470 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 3ebfa551d1c..06736e3079a 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 00000000000..8da3f19b62d --- /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 00000000000..3adce49601c --- /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 00000000000..30567f2644b --- /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 00000000000..336dae1b64a --- /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 00000000000..ba9ebfc6243 --- /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, +} -- cgit 1.4.1-3-g733a5 From c03e1842f637e34b23297fa3a0aeeb0fcdca1c47 Mon Sep 17 00:00:00 2001 From: cuishuang Date: Sat, 7 May 2022 23:56:21 +0800 Subject: fix some typos Signed-off-by: cuishuang --- src/parse/session.rs | 2 +- tests/rustfmt/main.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/parse/session.rs b/src/parse/session.rs index 7571e6d078a..55050571db7 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 450051d2fec..4c6d52726f3 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)] -- cgit 1.4.1-3-g733a5 From c65ba14d692bedab306b0426c36ab8f4fe4cbab2 Mon Sep 17 00:00:00 2001 From: Pascal Seitz Date: Sun, 13 Mar 2022 10:03:50 +0800 Subject: 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 (limited to 'src') diff --git a/src/comment.rs b/src/comment.rs index f9d8a0fa70c..eb195b1f762 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 b65aa5b33b2..78b72a50cb2 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 00000000000..c0606817290 --- /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 00000000000..171f6fa51b7 --- /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` +} -- cgit 1.4.1-3-g733a5 From 8a4c05865be17bac75b8d53eae5be18d749a0f5c Mon Sep 17 00:00:00 2001 From: Koichi ITO Date: Thu, 12 May 2022 00:44:25 +0900 Subject: 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(-) (limited to 'src') diff --git a/src/cargo-fmt/main.rs b/src/cargo-fmt/main.rs index 3542536f29b..55fd75f6de9 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; -- cgit 1.4.1-3-g733a5 From 95837832f4bb89a681fd7fae57dad42fca497e23 Mon Sep 17 00:00:00 2001 From: David Lattimore Date: Sat, 30 Apr 2022 15:12:06 +1000 Subject: 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(-) (limited to 'src') diff --git a/src/imports.rs b/src/imports.rs index efe4e9498c9..962f2126c66 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 d16681b01b5..f6f7761e82e 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 d0e94df66ae..b82c0d33caf 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 2d7bb299aaa..c7f68cea6d4 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 c21707df395..4d5a4795641 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 d75906d30f1..36e01558ff0 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 eace785e670..d2f5496fdac 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 e4e1a299e58..14f341016ff 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 78ec5e7325c..da4c6678db1 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, }; -- cgit 1.4.1-3-g733a5 From 4c8db8593905d09a872601c445005a594ac632dc Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Sun, 29 May 2022 21:35:12 -0500 Subject: 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(-) (limited to 'src') diff --git a/Configurations.md b/Configurations.md index 669da79087c..72499618755 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 18e1854612b..4c14d735689 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 281d3e4e808..8e6999643b1 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 33fb5522aea..3c39d813a6f 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 4bad8e71481..0eda9e4b116 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 35c8fd86467..598edda6abe 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 -- cgit 1.4.1-3-g733a5 From 825561deb86524107f1c22b59bddb16703d2c790 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Sun, 29 May 2022 21:48:59 -0500 Subject: 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(-) (limited to 'src') diff --git a/Configurations.md b/Configurations.md index 72499618755..edb2d1f7575 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 4c14d735689..fc724beae60 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 8e6999643b1..72bbe240f7b 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 3c39d813a6f..d95a80fe7fd 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 598edda6abe..c3cfd34317a 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 -- cgit 1.4.1-3-g733a5 From 5e4296767fadf87cea31c22edaef1a924dfbad40 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Sun, 29 May 2022 21:54:00 -0500 Subject: 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 (limited to 'src') diff --git a/src/format_report_formatter.rs b/src/format_report_formatter.rs index 90406cdb95e..9809f72f5ae 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 72bbe240f7b..869c6db647d 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 d95a80fe7fd..00000000000 --- 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 ad23b16e02e..f46a6914dd8 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 => { -- cgit 1.4.1-3-g733a5 From 79515f17ed4661da864347c90c76c51f9bf86069 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Sun, 29 May 2022 22:05:57 -0500 Subject: 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 - .../source/license-templates/empty_license_path.rs | 5 - tests/source/license-templates/license.rs | 6 - .../target/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 (limited to 'src') diff --git a/Configurations.md b/Configurations.md index edb2d1f7575..8c84614352c 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 7fc4486ddcd..e37ed798cb5 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 c7feb502ea9..00000000000 --- 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 fc724beae60..a5169528187 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 9809f72f5ae..fd536d4df41 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 869c6db647d..e6995210a94 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 f46a6914dd8..495010a297d 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 74ee8b010dd..00000000000 --- 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 ea4390371a0..00000000000 --- 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 d3a91e4231d..00000000000 --- 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 6816011c60d..00000000000 --- 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 950f103ed39..00000000000 --- 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 7169c7b2576..00000000000 --- 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!"); -} -- cgit 1.4.1-3-g733a5 From 64f1f57a4837694cb2449d6bc1f614e60c6ff42c Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Sat, 4 Jun 2022 10:08:33 -0500 Subject: fix: handle inner ignore attribute on stdin --- src/formatting.rs | 28 +++++++++++++++++++++------- src/test/mod.rs | 24 ++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/formatting.rs b/src/formatting.rs index e6995210a94..23d90d9e2e0 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 0eda9e4b116..18ec8620fac 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(); -- cgit 1.4.1-3-g733a5 From 5fa2727ddeef534a7cd437f9e288c221a2cf0b6a Mon Sep 17 00:00:00 2001 From: Urgau Date: Wed, 8 Jun 2022 18:15:22 +0200 Subject: Remove useless conditional compilation --- src/test/mod.rs | 6 ------ 1 file changed, 6 deletions(-) (limited to 'src') diff --git a/src/test/mod.rs b/src/test/mod.rs index 18ec8620fac..6b5bc2b30dd 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(), -- cgit 1.4.1-3-g733a5 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: 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 ++- tests/source/imports-impl-only-use.rs | 4 - tests/source/imports-reorder-lines-and-items.rs | 7 -- tests/source/imports-reorder-lines.rs | 32 ----- tests/source/imports-reorder.rs | 5 - tests/source/imports.rs | 107 ----------------- tests/source/imports/imports-impl-only-use.rs | 4 + .../imports/imports-reorder-lines-and-items.rs | 7 ++ tests/source/imports/imports-reorder-lines.rs | 32 +++++ tests/source/imports/imports-reorder.rs | 5 + tests/source/imports/imports.rs | 107 +++++++++++++++++ tests/source/imports/imports_block_indent.rs | 2 + tests/source/imports/imports_granularity_crate.rs | 65 +++++++++++ .../imports_granularity_default-with-dups.rs | 6 + ...y_item-with-dups-StdExternalCrate-no-reorder.rs | 13 +++ .../imports/imports_granularity_item-with-dups.rs | 11 ++ tests/source/imports/imports_granularity_item.rs | 34 ++++++ tests/source/imports/imports_granularity_module.rs | 47 ++++++++ tests/source/imports_block_indent.rs | 2 - tests/source/imports_granularity_crate.rs | 65 ----------- tests/source/imports_granularity_item.rs | 34 ------ tests/source/imports_granularity_module.rs | 47 -------- tests/target/import-fencepost-length.rs | 7 -- tests/target/imports-impl-only-use.rs | 4 - tests/target/imports-reorder-lines-and-items.rs | 7 -- tests/target/imports-reorder-lines.rs | 31 ----- tests/target/imports-reorder.rs | 5 - tests/target/imports.rs | 129 --------------------- tests/target/imports/import-fencepost-length.rs | 7 ++ tests/target/imports/imports-impl-only-use.rs | 4 + .../imports/imports-reorder-lines-and-items.rs | 7 ++ tests/target/imports/imports-reorder-lines.rs | 31 +++++ tests/target/imports/imports-reorder.rs | 5 + tests/target/imports/imports.rs | 129 +++++++++++++++++++++ tests/target/imports/imports_2021_edition.rs | 3 + tests/target/imports/imports_block_indent.rs | 4 + tests/target/imports/imports_granularity_crate.rs | 59 ++++++++++ .../imports_granularity_default-with-dups.rs | 6 + ...y_item-with-dups-StdExternalCrate-no-reorder.rs | 7 ++ .../imports/imports_granularity_item-with-dups.rs | 5 + tests/target/imports/imports_granularity_item.rs | 45 +++++++ tests/target/imports/imports_granularity_module.rs | 55 +++++++++ tests/target/imports_2021_edition.rs | 3 - tests/target/imports_block_indent.rs | 4 - tests/target/imports_granularity_crate.rs | 59 ---------- tests/target/imports_granularity_item.rs | 45 ------- tests/target/imports_granularity_module.rs | 55 --------- 47 files changed, 714 insertions(+), 653 deletions(-) delete mode 100644 tests/source/imports-impl-only-use.rs delete mode 100644 tests/source/imports-reorder-lines-and-items.rs delete mode 100644 tests/source/imports-reorder-lines.rs delete mode 100644 tests/source/imports-reorder.rs delete mode 100644 tests/source/imports.rs create mode 100644 tests/source/imports/imports-impl-only-use.rs create mode 100644 tests/source/imports/imports-reorder-lines-and-items.rs create mode 100644 tests/source/imports/imports-reorder-lines.rs create mode 100644 tests/source/imports/imports-reorder.rs create mode 100644 tests/source/imports/imports.rs create mode 100644 tests/source/imports/imports_block_indent.rs create mode 100644 tests/source/imports/imports_granularity_crate.rs 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 create mode 100644 tests/source/imports/imports_granularity_item.rs create mode 100644 tests/source/imports/imports_granularity_module.rs delete mode 100644 tests/source/imports_block_indent.rs delete mode 100644 tests/source/imports_granularity_crate.rs delete mode 100644 tests/source/imports_granularity_item.rs delete mode 100644 tests/source/imports_granularity_module.rs delete mode 100644 tests/target/import-fencepost-length.rs delete mode 100644 tests/target/imports-impl-only-use.rs delete mode 100644 tests/target/imports-reorder-lines-and-items.rs delete mode 100644 tests/target/imports-reorder-lines.rs delete mode 100644 tests/target/imports-reorder.rs delete mode 100644 tests/target/imports.rs create mode 100644 tests/target/imports/import-fencepost-length.rs create mode 100644 tests/target/imports/imports-impl-only-use.rs create mode 100644 tests/target/imports/imports-reorder-lines-and-items.rs create mode 100644 tests/target/imports/imports-reorder-lines.rs create mode 100644 tests/target/imports/imports-reorder.rs create mode 100644 tests/target/imports/imports.rs create mode 100644 tests/target/imports/imports_2021_edition.rs create mode 100644 tests/target/imports/imports_block_indent.rs create mode 100644 tests/target/imports/imports_granularity_crate.rs 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 create mode 100644 tests/target/imports/imports_granularity_item.rs create mode 100644 tests/target/imports/imports_granularity_module.rs delete mode 100644 tests/target/imports_2021_edition.rs delete mode 100644 tests/target/imports_block_indent.rs delete mode 100644 tests/target/imports_granularity_crate.rs delete mode 100644 tests/target/imports_granularity_item.rs delete mode 100644 tests/target/imports_granularity_module.rs (limited to 'src') diff --git a/src/imports.rs b/src/imports.rs index 962f2126c66..559ed3917db 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-impl-only-use.rs deleted file mode 100644 index d290d8d9185..00000000000 --- a/tests/source/imports-impl-only-use.rs +++ /dev/null @@ -1,4 +0,0 @@ -#![feature(underscore_imports)] - -use attr; -use std::iter::Iterator as _; diff --git a/tests/source/imports-reorder-lines-and-items.rs b/tests/source/imports-reorder-lines-and-items.rs deleted file mode 100644 index b6380f31c61..00000000000 --- a/tests/source/imports-reorder-lines-and-items.rs +++ /dev/null @@ -1,7 +0,0 @@ -/// This comment should stay with `use std::str;` -use std::str; -use std::cmp::{d, c, b, a}; -use std::ddd::aaa; -use std::ddd::{d as p, c as g, b, a}; -// This comment should stay with `use std::ddd:bbb;` -use std::ddd::bbb; diff --git a/tests/source/imports-reorder-lines.rs b/tests/source/imports-reorder-lines.rs deleted file mode 100644 index 2b018544eae..00000000000 --- a/tests/source/imports-reorder-lines.rs +++ /dev/null @@ -1,32 +0,0 @@ -use std::str; -use std::cmp::{d, c, b, a}; -use std::cmp::{b, e, g, f}; -use std::ddd::aaa; -// This comment should stay with `use std::ddd;` -use std::ddd; -use std::ddd::bbb; - -mod test { -} - -use aaa::bbb; -use aaa; -use aaa::*; - -mod test {} -// If item names are equal, order by rename - -use test::{a as bb, b}; -use test::{a as aa, c}; - -mod test {} -// If item names are equal, order by rename - no rename comes before a rename - -use test::{a as bb, b}; -use test::{a, c}; - -mod test {} -// `self` always comes first - -use test::{a as aa, c}; -use test::{self as bb, b}; diff --git a/tests/source/imports-reorder.rs b/tests/source/imports-reorder.rs deleted file mode 100644 index cbe9d6ca78a..00000000000 --- a/tests/source/imports-reorder.rs +++ /dev/null @@ -1,5 +0,0 @@ -// rustfmt-normalize_comments: true - -use path::{C,/*A*/ A, B /* B */, self /* self */}; - -use {ab, ac, aa, Z, b}; diff --git a/tests/source/imports.rs b/tests/source/imports.rs deleted file mode 100644 index 4dfc6ed94e3..00000000000 --- a/tests/source/imports.rs +++ /dev/null @@ -1,107 +0,0 @@ -// rustfmt-normalize_comments: true - -// Imports. - -// Long import. -use rustc_ast::ast::{ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic, ItemDefaultImpl}; -use exceedingly::looooooooooooooooooooooooooooooooooooooooooooooooooooooooooong::import::path::{ItemA, ItemB}; -use exceedingly::loooooooooooooooooooooooooooooooooooooooooooooooooooooooong::import::path::{ItemA, ItemB}; - -use list::{ - // Some item - SomeItem /* Comment */, /* Another item */ AnotherItem /* Another Comment */, // Last Item - LastItem -}; - -use test::{ Other /* C */ , /* A */ self /* B */ }; - -use rustc_ast::{self}; -use {/* Pre-comment! */ - Foo, Bar /* comment */}; -use Foo::{Bar, Baz}; -pub use rustc_ast::ast::{Expr_, Expr, ExprAssign, ExprCall, ExprMethodCall, ExprPath}; - -use rustc_ast::some::{}; - -use self; -use std::io::{self}; -use std::io::self; - -mod Foo { - pub use rustc_ast::ast::{ - ItemForeignMod, - ItemImpl, - ItemMac, - ItemMod, - ItemStatic, - ItemDefaultImpl - }; - - mod Foo2 { - pub use rustc_ast::ast::{ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic, self, ItemDefaultImpl}; - } -} - -fn test() { -use Baz::*; - use Qux; -} - -// Simple imports -use foo::bar::baz as baz ; -use bar::quux as kaas; -use foo; - -// With aliases. -use foo::{self as bar, baz}; -use foo::{self as bar}; -use foo::{qux as bar}; -use foo::{baz, qux as bar}; - -// With absolute paths -use ::foo; -use ::foo::{Bar}; -use ::foo::{Bar, Baz}; -use ::{Foo}; -use ::{Bar, Baz}; - -// Root globs -use *; -use ::*; - -// spaces used to cause glob imports to disappear (#1356) -use super:: * ; -use foo::issue_1356:: * ; - -// We shouldn't remove imports which have attributes attached (#1858) -#[cfg(unix)] -use self::unix::{}; - -// nested imports -use foo::{a, bar::{baz, qux, xxxxxxxxxxx, yyyyyyyyyyyyy, zzzzzzzzzzzzzzzz, foo::{a, b, cxxxxxxxxxxxxx, yyyyyyyyyyyyyy, zzzzzzzzzzzzzzzz}}, b, boo, c,}; - -use fooo::{baar::{foobar::{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy, zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz}}, z, bar, bar::*, x, y}; - -use exonum::{api::{Api, ApiError}, blockchain::{self, BlockProof, Blockchain, Transaction, TransactionSet}, crypto::{Hash, PublicKey}, helpers::Height, node::TransactionSend, storage::{ListProof, MapProof}}; - -// nested imports with a single sub-tree. -use a::{b::{c::*}}; -use a::{b::{c::{}}}; -use a::{b::{c::d}}; -use a::{b::{c::{xxx, yyy, zzz}}}; - -// #2645 -/// This line is not affected. -// This line is deleted. -use c; - -// #2670 -#[macro_use] -use imports_with_attr; - -// #2888 -use std::f64::consts::{SQRT_2, E, PI}; - -// #3273 -#[rustfmt::skip] -use std::fmt::{self, {Display, Formatter}}; diff --git a/tests/source/imports/imports-impl-only-use.rs b/tests/source/imports/imports-impl-only-use.rs new file mode 100644 index 00000000000..d290d8d9185 --- /dev/null +++ b/tests/source/imports/imports-impl-only-use.rs @@ -0,0 +1,4 @@ +#![feature(underscore_imports)] + +use attr; +use std::iter::Iterator as _; diff --git a/tests/source/imports/imports-reorder-lines-and-items.rs b/tests/source/imports/imports-reorder-lines-and-items.rs new file mode 100644 index 00000000000..b6380f31c61 --- /dev/null +++ b/tests/source/imports/imports-reorder-lines-and-items.rs @@ -0,0 +1,7 @@ +/// This comment should stay with `use std::str;` +use std::str; +use std::cmp::{d, c, b, a}; +use std::ddd::aaa; +use std::ddd::{d as p, c as g, b, a}; +// This comment should stay with `use std::ddd:bbb;` +use std::ddd::bbb; diff --git a/tests/source/imports/imports-reorder-lines.rs b/tests/source/imports/imports-reorder-lines.rs new file mode 100644 index 00000000000..2b018544eae --- /dev/null +++ b/tests/source/imports/imports-reorder-lines.rs @@ -0,0 +1,32 @@ +use std::str; +use std::cmp::{d, c, b, a}; +use std::cmp::{b, e, g, f}; +use std::ddd::aaa; +// This comment should stay with `use std::ddd;` +use std::ddd; +use std::ddd::bbb; + +mod test { +} + +use aaa::bbb; +use aaa; +use aaa::*; + +mod test {} +// If item names are equal, order by rename + +use test::{a as bb, b}; +use test::{a as aa, c}; + +mod test {} +// If item names are equal, order by rename - no rename comes before a rename + +use test::{a as bb, b}; +use test::{a, c}; + +mod test {} +// `self` always comes first + +use test::{a as aa, c}; +use test::{self as bb, b}; diff --git a/tests/source/imports/imports-reorder.rs b/tests/source/imports/imports-reorder.rs new file mode 100644 index 00000000000..cbe9d6ca78a --- /dev/null +++ b/tests/source/imports/imports-reorder.rs @@ -0,0 +1,5 @@ +// rustfmt-normalize_comments: true + +use path::{C,/*A*/ A, B /* B */, self /* self */}; + +use {ab, ac, aa, Z, b}; diff --git a/tests/source/imports/imports.rs b/tests/source/imports/imports.rs new file mode 100644 index 00000000000..4dfc6ed94e3 --- /dev/null +++ b/tests/source/imports/imports.rs @@ -0,0 +1,107 @@ +// rustfmt-normalize_comments: true + +// Imports. + +// Long import. +use rustc_ast::ast::{ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic, ItemDefaultImpl}; +use exceedingly::looooooooooooooooooooooooooooooooooooooooooooooooooooooooooong::import::path::{ItemA, ItemB}; +use exceedingly::loooooooooooooooooooooooooooooooooooooooooooooooooooooooong::import::path::{ItemA, ItemB}; + +use list::{ + // Some item + SomeItem /* Comment */, /* Another item */ AnotherItem /* Another Comment */, // Last Item + LastItem +}; + +use test::{ Other /* C */ , /* A */ self /* B */ }; + +use rustc_ast::{self}; +use {/* Pre-comment! */ + Foo, Bar /* comment */}; +use Foo::{Bar, Baz}; +pub use rustc_ast::ast::{Expr_, Expr, ExprAssign, ExprCall, ExprMethodCall, ExprPath}; + +use rustc_ast::some::{}; + +use self; +use std::io::{self}; +use std::io::self; + +mod Foo { + pub use rustc_ast::ast::{ + ItemForeignMod, + ItemImpl, + ItemMac, + ItemMod, + ItemStatic, + ItemDefaultImpl + }; + + mod Foo2 { + pub use rustc_ast::ast::{ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic, self, ItemDefaultImpl}; + } +} + +fn test() { +use Baz::*; + use Qux; +} + +// Simple imports +use foo::bar::baz as baz ; +use bar::quux as kaas; +use foo; + +// With aliases. +use foo::{self as bar, baz}; +use foo::{self as bar}; +use foo::{qux as bar}; +use foo::{baz, qux as bar}; + +// With absolute paths +use ::foo; +use ::foo::{Bar}; +use ::foo::{Bar, Baz}; +use ::{Foo}; +use ::{Bar, Baz}; + +// Root globs +use *; +use ::*; + +// spaces used to cause glob imports to disappear (#1356) +use super:: * ; +use foo::issue_1356:: * ; + +// We shouldn't remove imports which have attributes attached (#1858) +#[cfg(unix)] +use self::unix::{}; + +// nested imports +use foo::{a, bar::{baz, qux, xxxxxxxxxxx, yyyyyyyyyyyyy, zzzzzzzzzzzzzzzz, foo::{a, b, cxxxxxxxxxxxxx, yyyyyyyyyyyyyy, zzzzzzzzzzzzzzzz}}, b, boo, c,}; + +use fooo::{baar::{foobar::{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy, zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz}}, z, bar, bar::*, x, y}; + +use exonum::{api::{Api, ApiError}, blockchain::{self, BlockProof, Blockchain, Transaction, TransactionSet}, crypto::{Hash, PublicKey}, helpers::Height, node::TransactionSend, storage::{ListProof, MapProof}}; + +// nested imports with a single sub-tree. +use a::{b::{c::*}}; +use a::{b::{c::{}}}; +use a::{b::{c::d}}; +use a::{b::{c::{xxx, yyy, zzz}}}; + +// #2645 +/// This line is not affected. +// This line is deleted. +use c; + +// #2670 +#[macro_use] +use imports_with_attr; + +// #2888 +use std::f64::consts::{SQRT_2, E, PI}; + +// #3273 +#[rustfmt::skip] +use std::fmt::{self, {Display, Formatter}}; diff --git a/tests/source/imports/imports_block_indent.rs b/tests/source/imports/imports_block_indent.rs new file mode 100644 index 00000000000..016deefe58c --- /dev/null +++ b/tests/source/imports/imports_block_indent.rs @@ -0,0 +1,2 @@ +// #2569 +use apns2::request::notification::{Notificatio, NotificationBuilder, Priority, SilentNotificationBuilder}; diff --git a/tests/source/imports/imports_granularity_crate.rs b/tests/source/imports/imports_granularity_crate.rs new file mode 100644 index 00000000000..f6f7761e82e --- /dev/null +++ b/tests/source/imports/imports_granularity_crate.rs @@ -0,0 +1,65 @@ +// rustfmt-imports_granularity: Crate + +use a::{c,d,b}; +use a::{d, e, b, a, f}; +use a::{f, g, c}; + +#[doc(hidden)] +use a::b; +use a::c; +use a::d; + +use a::{c, d, e}; +#[doc(hidden)] +use a::b; +use a::d; + +pub use foo::bar; +use foo::{a, b, c}; +pub use foo::foobar; + +use a::{b::{c::*}}; +use a::{b::{c::{}}}; +use a::{b::{c::d}}; +use a::{b::{c::{xxx, yyy, zzz}}}; + +// https://github.com/rust-lang/rustfmt/issues/3808 +use d::{self}; +use e::{self as foo}; +use f::{self, b}; +use g::a; +use g::{self, b}; +use h::{a}; +use i::a::{self}; +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/imports_granularity_default-with-dups.rs b/tests/source/imports/imports_granularity_default-with-dups.rs new file mode 100644 index 00000000000..cbb21a9f1b3 --- /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 00000000000..e23705a884f --- /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 00000000000..3e9589c299f --- /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/imports_granularity_item.rs b/tests/source/imports/imports_granularity_item.rs new file mode 100644 index 00000000000..b82c0d33caf --- /dev/null +++ b/tests/source/imports/imports_granularity_item.rs @@ -0,0 +1,34 @@ +// rustfmt-imports_granularity: Item + +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/imports_granularity_module.rs b/tests/source/imports/imports_granularity_module.rs new file mode 100644 index 00000000000..c7f68cea6d4 --- /dev/null +++ b/tests/source/imports/imports_granularity_module.rs @@ -0,0 +1,47 @@ +// rustfmt-imports_granularity: Module + +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}; +use foo::e; + +use bar::{ + // comment + a::b, + // more comment + 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_block_indent.rs b/tests/source/imports_block_indent.rs deleted file mode 100644 index 016deefe58c..00000000000 --- a/tests/source/imports_block_indent.rs +++ /dev/null @@ -1,2 +0,0 @@ -// #2569 -use apns2::request::notification::{Notificatio, NotificationBuilder, Priority, SilentNotificationBuilder}; diff --git a/tests/source/imports_granularity_crate.rs b/tests/source/imports_granularity_crate.rs deleted file mode 100644 index f6f7761e82e..00000000000 --- a/tests/source/imports_granularity_crate.rs +++ /dev/null @@ -1,65 +0,0 @@ -// rustfmt-imports_granularity: Crate - -use a::{c,d,b}; -use a::{d, e, b, a, f}; -use a::{f, g, c}; - -#[doc(hidden)] -use a::b; -use a::c; -use a::d; - -use a::{c, d, e}; -#[doc(hidden)] -use a::b; -use a::d; - -pub use foo::bar; -use foo::{a, b, c}; -pub use foo::foobar; - -use a::{b::{c::*}}; -use a::{b::{c::{}}}; -use a::{b::{c::d}}; -use a::{b::{c::{xxx, yyy, zzz}}}; - -// https://github.com/rust-lang/rustfmt/issues/3808 -use d::{self}; -use e::{self as foo}; -use f::{self, b}; -use g::a; -use g::{self, b}; -use h::{a}; -use i::a::{self}; -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 deleted file mode 100644 index b82c0d33caf..00000000000 --- a/tests/source/imports_granularity_item.rs +++ /dev/null @@ -1,34 +0,0 @@ -// rustfmt-imports_granularity: Item - -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 deleted file mode 100644 index c7f68cea6d4..00000000000 --- a/tests/source/imports_granularity_module.rs +++ /dev/null @@ -1,47 +0,0 @@ -// rustfmt-imports_granularity: Module - -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}; -use foo::e; - -use bar::{ - // comment - a::b, - // more comment - 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/target/import-fencepost-length.rs b/tests/target/import-fencepost-length.rs deleted file mode 100644 index fd09d50d72d..00000000000 --- a/tests/target/import-fencepost-length.rs +++ /dev/null @@ -1,7 +0,0 @@ -use aaaaaaaaaaaaaaa::bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb; -use aaaaaaaaaaaaaaa::{ - bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, ccccccccccccccccccccccccccccccc, dddddddd, -}; -use aaaaaaaaaaaaaaa::{ - bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, ccccccccccccccccccccccccccccccc, ddddddddd, -}; diff --git a/tests/target/imports-impl-only-use.rs b/tests/target/imports-impl-only-use.rs deleted file mode 100644 index d290d8d9185..00000000000 --- a/tests/target/imports-impl-only-use.rs +++ /dev/null @@ -1,4 +0,0 @@ -#![feature(underscore_imports)] - -use attr; -use std::iter::Iterator as _; diff --git a/tests/target/imports-reorder-lines-and-items.rs b/tests/target/imports-reorder-lines-and-items.rs deleted file mode 100644 index 98a5afe4348..00000000000 --- a/tests/target/imports-reorder-lines-and-items.rs +++ /dev/null @@ -1,7 +0,0 @@ -use std::cmp::{a, b, c, d}; -use std::ddd::aaa; -use std::ddd::{a, b, c as g, d as p}; -/// This comment should stay with `use std::str;` -use std::str; -// This comment should stay with `use std::ddd:bbb;` -use std::ddd::bbb; diff --git a/tests/target/imports-reorder-lines.rs b/tests/target/imports-reorder-lines.rs deleted file mode 100644 index 5b85503b55d..00000000000 --- a/tests/target/imports-reorder-lines.rs +++ /dev/null @@ -1,31 +0,0 @@ -use std::cmp::{a, b, c, d}; -use std::cmp::{b, e, f, g}; -use std::ddd::aaa; -use std::str; -// This comment should stay with `use std::ddd;` -use std::ddd; -use std::ddd::bbb; - -mod test {} - -use aaa; -use aaa::bbb; -use aaa::*; - -mod test {} -// If item names are equal, order by rename - -use test::{a as bb, b}; -use test::{a as aa, c}; - -mod test {} -// If item names are equal, order by rename - no rename comes before a rename - -use test::{a as bb, b}; -use test::{a, c}; - -mod test {} -// `self` always comes first - -use test::{self as bb, b}; -use test::{a as aa, c}; diff --git a/tests/target/imports-reorder.rs b/tests/target/imports-reorder.rs deleted file mode 100644 index 84e97c0224f..00000000000 --- a/tests/target/imports-reorder.rs +++ /dev/null @@ -1,5 +0,0 @@ -// rustfmt-normalize_comments: true - -use path::{self /* self */, /* A */ A, B /* B */, C}; - -use {aa, ab, ac, b, Z}; diff --git a/tests/target/imports.rs b/tests/target/imports.rs deleted file mode 100644 index 87584d89f66..00000000000 --- a/tests/target/imports.rs +++ /dev/null @@ -1,129 +0,0 @@ -// rustfmt-normalize_comments: true - -// Imports. - -// Long import. -use exceedingly::loooooooooooooooooooooooooooooooooooooooooooooooooooooooong::import::path::{ - ItemA, ItemB, -}; -use exceedingly::looooooooooooooooooooooooooooooooooooooooooooooooooooooooooong::import::path::{ - ItemA, ItemB, -}; -use rustc_ast::ast::{ItemDefaultImpl, ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic}; - -use list::{ - // Another item - AnotherItem, // Another Comment - // Last Item - LastItem, - // Some item - SomeItem, // Comment -}; - -use test::{/* A */ self /* B */, Other /* C */}; - -pub use rustc_ast::ast::{Expr, ExprAssign, ExprCall, ExprMethodCall, ExprPath, Expr_}; -use rustc_ast::{self}; -use Foo::{Bar, Baz}; -use {Bar /* comment */, /* Pre-comment! */ Foo}; - -use std::io; -use std::io::{self}; - -mod Foo { - pub use rustc_ast::ast::{ - ItemDefaultImpl, ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic, - }; - - mod Foo2 { - pub use rustc_ast::ast::{ - self, ItemDefaultImpl, ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic, - }; - } -} - -fn test() { - use Baz::*; - use Qux; -} - -// Simple imports -use bar::quux as kaas; -use foo; -use foo::bar::baz; - -// With aliases. -use foo::qux as bar; -use foo::{self as bar}; -use foo::{self as bar, baz}; -use foo::{baz, qux as bar}; - -// With absolute paths -use foo; -use foo::Bar; -use foo::{Bar, Baz}; -use Foo; -use {Bar, Baz}; - -// Root globs -use *; -use *; - -// spaces used to cause glob imports to disappear (#1356) -use super::*; -use foo::issue_1356::*; - -// We shouldn't remove imports which have attributes attached (#1858) -#[cfg(unix)] -use self::unix::{}; - -// nested imports -use foo::{ - a, b, - bar::{ - baz, - foo::{a, b, cxxxxxxxxxxxxx, yyyyyyyyyyyyyy, zzzzzzzzzzzzzzzz}, - qux, xxxxxxxxxxx, yyyyyyyyyyyyy, zzzzzzzzzzzzzzzz, - }, - boo, c, -}; - -use fooo::{ - baar::foobar::{ - xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy, - zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz, - }, - bar, - bar::*, - x, y, z, -}; - -use exonum::{ - api::{Api, ApiError}, - blockchain::{self, BlockProof, Blockchain, Transaction, TransactionSet}, - crypto::{Hash, PublicKey}, - helpers::Height, - node::TransactionSend, - storage::{ListProof, MapProof}, -}; - -// nested imports with a single sub-tree. -use a::b::c::d; -use a::b::c::*; -use a::b::c::{xxx, yyy, zzz}; - -// #2645 -/// This line is not affected. -// This line is deleted. -use c; - -// #2670 -#[macro_use] -use imports_with_attr; - -// #2888 -use std::f64::consts::{E, PI, SQRT_2}; - -// #3273 -#[rustfmt::skip] -use std::fmt::{self, {Display, Formatter}}; diff --git a/tests/target/imports/import-fencepost-length.rs b/tests/target/imports/import-fencepost-length.rs new file mode 100644 index 00000000000..fd09d50d72d --- /dev/null +++ b/tests/target/imports/import-fencepost-length.rs @@ -0,0 +1,7 @@ +use aaaaaaaaaaaaaaa::bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb; +use aaaaaaaaaaaaaaa::{ + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, ccccccccccccccccccccccccccccccc, dddddddd, +}; +use aaaaaaaaaaaaaaa::{ + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, ccccccccccccccccccccccccccccccc, ddddddddd, +}; diff --git a/tests/target/imports/imports-impl-only-use.rs b/tests/target/imports/imports-impl-only-use.rs new file mode 100644 index 00000000000..d290d8d9185 --- /dev/null +++ b/tests/target/imports/imports-impl-only-use.rs @@ -0,0 +1,4 @@ +#![feature(underscore_imports)] + +use attr; +use std::iter::Iterator as _; diff --git a/tests/target/imports/imports-reorder-lines-and-items.rs b/tests/target/imports/imports-reorder-lines-and-items.rs new file mode 100644 index 00000000000..98a5afe4348 --- /dev/null +++ b/tests/target/imports/imports-reorder-lines-and-items.rs @@ -0,0 +1,7 @@ +use std::cmp::{a, b, c, d}; +use std::ddd::aaa; +use std::ddd::{a, b, c as g, d as p}; +/// This comment should stay with `use std::str;` +use std::str; +// This comment should stay with `use std::ddd:bbb;` +use std::ddd::bbb; diff --git a/tests/target/imports/imports-reorder-lines.rs b/tests/target/imports/imports-reorder-lines.rs new file mode 100644 index 00000000000..5b85503b55d --- /dev/null +++ b/tests/target/imports/imports-reorder-lines.rs @@ -0,0 +1,31 @@ +use std::cmp::{a, b, c, d}; +use std::cmp::{b, e, f, g}; +use std::ddd::aaa; +use std::str; +// This comment should stay with `use std::ddd;` +use std::ddd; +use std::ddd::bbb; + +mod test {} + +use aaa; +use aaa::bbb; +use aaa::*; + +mod test {} +// If item names are equal, order by rename + +use test::{a as bb, b}; +use test::{a as aa, c}; + +mod test {} +// If item names are equal, order by rename - no rename comes before a rename + +use test::{a as bb, b}; +use test::{a, c}; + +mod test {} +// `self` always comes first + +use test::{self as bb, b}; +use test::{a as aa, c}; diff --git a/tests/target/imports/imports-reorder.rs b/tests/target/imports/imports-reorder.rs new file mode 100644 index 00000000000..84e97c0224f --- /dev/null +++ b/tests/target/imports/imports-reorder.rs @@ -0,0 +1,5 @@ +// rustfmt-normalize_comments: true + +use path::{self /* self */, /* A */ A, B /* B */, C}; + +use {aa, ab, ac, b, Z}; diff --git a/tests/target/imports/imports.rs b/tests/target/imports/imports.rs new file mode 100644 index 00000000000..87584d89f66 --- /dev/null +++ b/tests/target/imports/imports.rs @@ -0,0 +1,129 @@ +// rustfmt-normalize_comments: true + +// Imports. + +// Long import. +use exceedingly::loooooooooooooooooooooooooooooooooooooooooooooooooooooooong::import::path::{ + ItemA, ItemB, +}; +use exceedingly::looooooooooooooooooooooooooooooooooooooooooooooooooooooooooong::import::path::{ + ItemA, ItemB, +}; +use rustc_ast::ast::{ItemDefaultImpl, ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic}; + +use list::{ + // Another item + AnotherItem, // Another Comment + // Last Item + LastItem, + // Some item + SomeItem, // Comment +}; + +use test::{/* A */ self /* B */, Other /* C */}; + +pub use rustc_ast::ast::{Expr, ExprAssign, ExprCall, ExprMethodCall, ExprPath, Expr_}; +use rustc_ast::{self}; +use Foo::{Bar, Baz}; +use {Bar /* comment */, /* Pre-comment! */ Foo}; + +use std::io; +use std::io::{self}; + +mod Foo { + pub use rustc_ast::ast::{ + ItemDefaultImpl, ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic, + }; + + mod Foo2 { + pub use rustc_ast::ast::{ + self, ItemDefaultImpl, ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic, + }; + } +} + +fn test() { + use Baz::*; + use Qux; +} + +// Simple imports +use bar::quux as kaas; +use foo; +use foo::bar::baz; + +// With aliases. +use foo::qux as bar; +use foo::{self as bar}; +use foo::{self as bar, baz}; +use foo::{baz, qux as bar}; + +// With absolute paths +use foo; +use foo::Bar; +use foo::{Bar, Baz}; +use Foo; +use {Bar, Baz}; + +// Root globs +use *; +use *; + +// spaces used to cause glob imports to disappear (#1356) +use super::*; +use foo::issue_1356::*; + +// We shouldn't remove imports which have attributes attached (#1858) +#[cfg(unix)] +use self::unix::{}; + +// nested imports +use foo::{ + a, b, + bar::{ + baz, + foo::{a, b, cxxxxxxxxxxxxx, yyyyyyyyyyyyyy, zzzzzzzzzzzzzzzz}, + qux, xxxxxxxxxxx, yyyyyyyyyyyyy, zzzzzzzzzzzzzzzz, + }, + boo, c, +}; + +use fooo::{ + baar::foobar::{ + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy, + zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz, + }, + bar, + bar::*, + x, y, z, +}; + +use exonum::{ + api::{Api, ApiError}, + blockchain::{self, BlockProof, Blockchain, Transaction, TransactionSet}, + crypto::{Hash, PublicKey}, + helpers::Height, + node::TransactionSend, + storage::{ListProof, MapProof}, +}; + +// nested imports with a single sub-tree. +use a::b::c::d; +use a::b::c::*; +use a::b::c::{xxx, yyy, zzz}; + +// #2645 +/// This line is not affected. +// This line is deleted. +use c; + +// #2670 +#[macro_use] +use imports_with_attr; + +// #2888 +use std::f64::consts::{E, PI, SQRT_2}; + +// #3273 +#[rustfmt::skip] +use std::fmt::{self, {Display, Formatter}}; diff --git a/tests/target/imports/imports_2021_edition.rs b/tests/target/imports/imports_2021_edition.rs new file mode 100644 index 00000000000..34dcc866a0b --- /dev/null +++ b/tests/target/imports/imports_2021_edition.rs @@ -0,0 +1,3 @@ +// rustfmt-edition: 2021 + +use ::happy::new::year; diff --git a/tests/target/imports/imports_block_indent.rs b/tests/target/imports/imports_block_indent.rs new file mode 100644 index 00000000000..8c90f7ce29c --- /dev/null +++ b/tests/target/imports/imports_block_indent.rs @@ -0,0 +1,4 @@ +// #2569 +use apns2::request::notification::{ + Notificatio, NotificationBuilder, Priority, SilentNotificationBuilder, +}; diff --git a/tests/target/imports/imports_granularity_crate.rs b/tests/target/imports/imports_granularity_crate.rs new file mode 100644 index 00000000000..36e01558ff0 --- /dev/null +++ b/tests/target/imports/imports_granularity_crate.rs @@ -0,0 +1,59 @@ +// rustfmt-imports_granularity: Crate + +use a::{a, b, c, d, e, f, g}; + +#[doc(hidden)] +use a::b; +use a::{c, d}; + +#[doc(hidden)] +use a::b; +use a::{c, d, e}; + +use foo::{a, b, c}; +pub use foo::{bar, foobar}; + +use a::b::c::{d, xxx, yyy, zzz, *}; + +// https://github.com/rust-lang/rustfmt/issues/3808 +use d::{self}; +use e::{self as foo}; +use f::{self, b}; +use g::{self, a, b}; +use h::a; +use i::a::{self}; +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/imports_granularity_default-with-dups.rs b/tests/target/imports/imports_granularity_default-with-dups.rs new file mode 100644 index 00000000000..5da6d588e6d --- /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 00000000000..ed4df544d6f --- /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 00000000000..00df37f9332 --- /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/imports_granularity_item.rs b/tests/target/imports/imports_granularity_item.rs new file mode 100644 index 00000000000..d2f5496fdac --- /dev/null +++ b/tests/target/imports/imports_granularity_item.rs @@ -0,0 +1,45 @@ +// rustfmt-imports_granularity: Item + +use a::b; +use a::c; +use a::d; +use a::f::g; +use a::h::i; +use a::h::j; +use a::l::m; +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/imports_granularity_module.rs b/tests/target/imports/imports_granularity_module.rs new file mode 100644 index 00000000000..14f341016ff --- /dev/null +++ b/tests/target/imports/imports_granularity_module.rs @@ -0,0 +1,55 @@ +// rustfmt-imports_granularity: Module + +use a::b::c; +use a::d::e; +use a::f; +use a::g::{h, i}; +use a::j::k::{self, l}; +use a::j::{self, m}; +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)] +use foo::{a::b, c::d}; + +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_2021_edition.rs b/tests/target/imports_2021_edition.rs deleted file mode 100644 index 34dcc866a0b..00000000000 --- a/tests/target/imports_2021_edition.rs +++ /dev/null @@ -1,3 +0,0 @@ -// rustfmt-edition: 2021 - -use ::happy::new::year; diff --git a/tests/target/imports_block_indent.rs b/tests/target/imports_block_indent.rs deleted file mode 100644 index 8c90f7ce29c..00000000000 --- a/tests/target/imports_block_indent.rs +++ /dev/null @@ -1,4 +0,0 @@ -// #2569 -use apns2::request::notification::{ - Notificatio, NotificationBuilder, Priority, SilentNotificationBuilder, -}; diff --git a/tests/target/imports_granularity_crate.rs b/tests/target/imports_granularity_crate.rs deleted file mode 100644 index 36e01558ff0..00000000000 --- a/tests/target/imports_granularity_crate.rs +++ /dev/null @@ -1,59 +0,0 @@ -// rustfmt-imports_granularity: Crate - -use a::{a, b, c, d, e, f, g}; - -#[doc(hidden)] -use a::b; -use a::{c, d}; - -#[doc(hidden)] -use a::b; -use a::{c, d, e}; - -use foo::{a, b, c}; -pub use foo::{bar, foobar}; - -use a::b::c::{d, xxx, yyy, zzz, *}; - -// https://github.com/rust-lang/rustfmt/issues/3808 -use d::{self}; -use e::{self as foo}; -use f::{self, b}; -use g::{self, a, b}; -use h::a; -use i::a::{self}; -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 deleted file mode 100644 index d2f5496fdac..00000000000 --- a/tests/target/imports_granularity_item.rs +++ /dev/null @@ -1,45 +0,0 @@ -// rustfmt-imports_granularity: Item - -use a::b; -use a::c; -use a::d; -use a::f::g; -use a::h::i; -use a::h::j; -use a::l::m; -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 deleted file mode 100644 index 14f341016ff..00000000000 --- a/tests/target/imports_granularity_module.rs +++ /dev/null @@ -1,55 +0,0 @@ -// rustfmt-imports_granularity: Module - -use a::b::c; -use a::d::e; -use a::f; -use a::g::{h, i}; -use a::j::k::{self, l}; -use a::j::{self, m}; -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)] -use foo::{a::b, c::d}; - -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, -}; -- cgit 1.4.1-3-g733a5 From 5ae94cc6b878f8004e3d354d77991146448c1f82 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Mon, 13 Jun 2022 08:34:47 -0400 Subject: Backport 3795 fix sorting of use statements with raw identifiers --- src/imports.rs | 24 ++++++++++++++++-------- tests/source/imports_raw_identifiers.rs | 3 +++ tests/target/imports_raw_identifiers.rs | 3 +++ 3 files changed, 22 insertions(+), 8 deletions(-) create mode 100644 tests/source/imports_raw_identifiers.rs create mode 100644 tests/target/imports_raw_identifiers.rs (limited to 'src') diff --git a/src/imports.rs b/src/imports.rs index 559ed3917db..6742b14c5a3 100644 --- a/src/imports.rs +++ b/src/imports.rs @@ -815,9 +815,16 @@ impl Ord for UseSegment { match (self, other) { (&Slf(ref a), &Slf(ref b)) | (&Super(ref a), &Super(ref b)) - | (&Crate(ref a), &Crate(ref b)) => a.cmp(b), + | (&Crate(ref a), &Crate(ref b)) => match (a, b) { + (Some(sa), Some(sb)) => { + sa.trim_start_matches("r#").cmp(sb.trim_start_matches("r#")) + } + (_, _) => a.cmp(b), + }, (&Glob, &Glob) => Ordering::Equal, - (&Ident(ref ia, ref aa), &Ident(ref ib, ref ab)) => { + (&Ident(ref pia, ref aa), &Ident(ref pib, ref ab)) => { + let ia = pia.trim_start_matches("r#"); + let ib = pib.trim_start_matches("r#"); // snake_case < CamelCase < UPPER_SNAKE_CASE if ia.starts_with(char::is_uppercase) && ib.starts_with(char::is_lowercase) { return Ordering::Greater; @@ -835,13 +842,14 @@ impl Ord for UseSegment { if ident_ord != Ordering::Equal { return ident_ord; } - if aa.is_none() && ab.is_some() { - return Ordering::Less; - } - if aa.is_some() && ab.is_none() { - return Ordering::Greater; + match (aa, ab) { + (None, Some(_)) => Ordering::Less, + (Some(_), None) => Ordering::Greater, + (Some(aas), Some(abs)) => aas + .trim_start_matches("r#") + .cmp(abs.trim_start_matches("r#")), + (None, None) => Ordering::Equal, } - aa.cmp(ab) } (&List(ref a), &List(ref b)) => { for (a, b) in a.iter().zip(b.iter()) { diff --git a/tests/source/imports_raw_identifiers.rs b/tests/source/imports_raw_identifiers.rs new file mode 100644 index 00000000000..d5857290b62 --- /dev/null +++ b/tests/source/imports_raw_identifiers.rs @@ -0,0 +1,3 @@ +use websocket::client::ClientBuilder; +use websocket::r#async::futures::Stream; +use websocket::result::WebSocketError; diff --git a/tests/target/imports_raw_identifiers.rs b/tests/target/imports_raw_identifiers.rs new file mode 100644 index 00000000000..6ae085c8a5f --- /dev/null +++ b/tests/target/imports_raw_identifiers.rs @@ -0,0 +1,3 @@ +use websocket::r#async::futures::Stream; +use websocket::client::ClientBuilder; +use websocket::result::WebSocketError; -- cgit 1.4.1-3-g733a5 From 795efb206892041e81107cc58797ea61fd1c7b16 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Mon, 13 Jun 2022 10:53:53 -0400 Subject: Add `Version` information to `UseSegment` There are some proposed import sorting changes for raw identifier `r#`. These changes constitute a breaking change, and need to be version gagted. Before version gating those changes we add the version information to the `UseSegment`. --- src/imports.rs | 311 +++++++++++++++++++++++++++++++++++++-------------------- src/reorder.rs | 10 +- 2 files changed, 206 insertions(+), 115 deletions(-) (limited to 'src') diff --git a/src/imports.rs b/src/imports.rs index 6742b14c5a3..58c5f31995e 100644 --- a/src/imports.rs +++ b/src/imports.rs @@ -15,7 +15,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::config::{Edition, IndentStyle, Version}; use crate::lists::{ definitive_tactic, itemize_list, write_list, ListFormatting, ListItem, Separator, }; @@ -92,7 +92,7 @@ impl<'a> FmtVisitor<'a> { // FIXME we do a lot of allocation to make our own representation. #[derive(Clone, Eq, Hash, PartialEq)] -pub(crate) enum UseSegment { +pub(crate) enum UseSegmentKind { Ident(String, Option), Slf(Option), Super(Option), @@ -101,6 +101,12 @@ pub(crate) enum UseSegment { List(Vec), } +#[derive(Clone, Eq, PartialEq)] +pub(crate) struct UseSegment { + pub(crate) kind: UseSegmentKind, + pub(crate) version: Version, +} + #[derive(Clone)] pub(crate) struct UseTree { pub(crate) path: Vec, @@ -134,34 +140,38 @@ impl Spanned for UseTree { impl UseSegment { // Clone a version of self with any top-level alias removed. fn remove_alias(&self) -> UseSegment { - match *self { - UseSegment::Ident(ref s, _) => UseSegment::Ident(s.clone(), None), - UseSegment::Slf(_) => UseSegment::Slf(None), - UseSegment::Super(_) => UseSegment::Super(None), - UseSegment::Crate(_) => UseSegment::Crate(None), - _ => self.clone(), + let kind = match self.kind { + UseSegmentKind::Ident(ref s, _) => UseSegmentKind::Ident(s.clone(), None), + UseSegmentKind::Slf(_) => UseSegmentKind::Slf(None), + UseSegmentKind::Super(_) => UseSegmentKind::Super(None), + UseSegmentKind::Crate(_) => UseSegmentKind::Crate(None), + _ => return self.clone(), + }; + UseSegment { + kind, + version: self.version, } } // Check if self == other with their aliases removed. fn equal_except_alias(&self, other: &Self) -> bool { - match (self, other) { - (UseSegment::Ident(ref s1, _), UseSegment::Ident(ref s2, _)) => s1 == s2, - (UseSegment::Slf(_), UseSegment::Slf(_)) - | (UseSegment::Super(_), UseSegment::Super(_)) - | (UseSegment::Crate(_), UseSegment::Crate(_)) - | (UseSegment::Glob, UseSegment::Glob) => true, - (UseSegment::List(ref list1), UseSegment::List(ref list2)) => list1 == list2, + match (&self.kind, &other.kind) { + (UseSegmentKind::Ident(ref s1, _), UseSegmentKind::Ident(ref s2, _)) => s1 == s2, + (UseSegmentKind::Slf(_), UseSegmentKind::Slf(_)) + | (UseSegmentKind::Super(_), UseSegmentKind::Super(_)) + | (UseSegmentKind::Crate(_), UseSegmentKind::Crate(_)) + | (UseSegmentKind::Glob, UseSegmentKind::Glob) => true, + (UseSegmentKind::List(ref list1), UseSegmentKind::List(ref list2)) => list1 == list2, _ => false, } } fn get_alias(&self) -> Option<&str> { - match self { - UseSegment::Ident(_, a) - | UseSegment::Slf(a) - | UseSegment::Super(a) - | UseSegment::Crate(a) => a.as_deref(), + match &self.kind { + UseSegmentKind::Ident(_, a) + | UseSegmentKind::Slf(a) + | UseSegmentKind::Super(a) + | UseSegmentKind::Crate(a) => a.as_deref(), _ => None, } } @@ -175,19 +185,24 @@ impl UseSegment { if name.is_empty() || name == "{{root}}" { return None; } - Some(match name { - "self" => UseSegment::Slf(None), - "super" => UseSegment::Super(None), - "crate" => UseSegment::Crate(None), + let kind = match name { + "self" => UseSegmentKind::Slf(None), + "super" => UseSegmentKind::Super(None), + "crate" => UseSegmentKind::Crate(None), _ => { let mod_sep = if modsep { "::" } else { "" }; - UseSegment::Ident(format!("{}{}", mod_sep, name), None) + UseSegmentKind::Ident(format!("{}{}", mod_sep, name), None) } + }; + + Some(UseSegment { + kind, + version: context.config.version(), }) } fn contains_comment(&self) -> bool { - if let UseSegment::List(list) = self { + if let UseSegmentKind::List(list) = &self.kind { list.iter().any(|subtree| subtree.contains_comment()) } else { false @@ -254,20 +269,38 @@ impl fmt::Debug for UseTree { impl fmt::Debug for UseSegment { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(self, f) + fmt::Display::fmt(&self.kind, f) } } impl fmt::Display for UseSegment { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(&self.kind, f) + } +} + +impl Hash for UseSegment { + fn hash(&self, state: &mut H) { + self.kind.hash(state); + } +} + +impl fmt::Debug for UseSegmentKind { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(self, f) + } +} + +impl fmt::Display for UseSegmentKind { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { - UseSegment::Glob => write!(f, "*"), - 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"), - UseSegment::List(ref list) => { + UseSegmentKind::Glob => write!(f, "*"), + UseSegmentKind::Ident(ref s, Some(ref alias)) => write!(f, "{} as {}", s, alias), + UseSegmentKind::Ident(ref s, None) => write!(f, "{}", s), + UseSegmentKind::Slf(..) => write!(f, "self"), + UseSegmentKind::Super(..) => write!(f, "super"), + UseSegmentKind::Crate(..) => write!(f, "crate"), + UseSegmentKind::List(ref list) => { write!(f, "{{")?; for (i, item) in list.iter().enumerate() { if i != 0 { @@ -411,13 +444,19 @@ impl UseTree { } } + let version = context.config.version(); + match a.kind { UseTreeKind::Glob => { // in case of a global path and the glob starts at the root, e.g., "::*" if a.prefix.segments.len() == 1 && leading_modsep { - result.path.push(UseSegment::Ident("".to_owned(), None)); + let kind = UseSegmentKind::Ident("".to_owned(), None); + result.path.push(UseSegment { kind, version }); } - result.path.push(UseSegment::Glob); + result.path.push(UseSegment { + kind: UseSegmentKind::Glob, + version, + }); } UseTreeKind::Nested(ref list) => { // Extract comments between nested use items. @@ -438,16 +477,18 @@ impl UseTree { // in case of a global path and the nested list starts at the root, // e.g., "::{foo, bar}" if a.prefix.segments.len() == 1 && leading_modsep { - result.path.push(UseSegment::Ident("".to_owned(), None)); + let kind = UseSegmentKind::Ident("".to_owned(), None); + result.path.push(UseSegment { kind, version }); } - result.path.push(UseSegment::List( + let kind = UseSegmentKind::List( list.iter() .zip(items) .map(|(t, list_item)| { Self::from_ast(context, &t.0, Some(list_item), None, None, None) }) .collect(), - )); + ); + result.path.push(UseSegment { kind, version }); } UseTreeKind::Simple(ref rename, ..) => { // If the path has leading double colons and is composed of only 2 segments, then we @@ -469,13 +510,15 @@ impl UseTree { Some(rewrite_ident(context, ident).to_owned()) } }); - let segment = match name.as_ref() { - "self" => UseSegment::Slf(alias), - "super" => UseSegment::Super(alias), - "crate" => UseSegment::Crate(alias), - _ => UseSegment::Ident(name, alias), + let kind = match name.as_ref() { + "self" => UseSegmentKind::Slf(alias), + "super" => UseSegmentKind::Super(alias), + "crate" => UseSegmentKind::Crate(alias), + _ => UseSegmentKind::Ident(name, alias), }; + let segment = UseSegment { kind, version }; + // `name` is already in result. result.path.pop(); result.path.push(segment); @@ -492,13 +535,13 @@ impl UseTree { let mut aliased_self = false; // Remove foo::{} or self without attributes. - match last { + match last.kind { _ if self.attrs.is_some() => (), - UseSegment::List(ref list) if list.is_empty() => { + UseSegmentKind::List(ref list) if list.is_empty() => { self.path = vec![]; return self; } - UseSegment::Slf(None) if self.path.is_empty() && self.visibility.is_some() => { + UseSegmentKind::Slf(None) if self.path.is_empty() && self.visibility.is_some() => { self.path = vec![]; return self; } @@ -506,15 +549,19 @@ impl UseTree { } // Normalise foo::self -> foo. - if let UseSegment::Slf(None) = last { + if let UseSegmentKind::Slf(None) = last.kind { if !self.path.is_empty() { return self; } } // Normalise foo::self as bar -> foo as bar. - if let UseSegment::Slf(_) = last { - if let Some(UseSegment::Ident(_, None)) = self.path.last() { + if let UseSegmentKind::Slf(_) = last.kind { + if let Some(UseSegment { + kind: UseSegmentKind::Ident(_, None), + .. + }) = self.path.last() + { aliased_self = true; } } @@ -522,9 +569,12 @@ impl UseTree { let mut done = false; if aliased_self { match self.path.last_mut() { - Some(UseSegment::Ident(_, ref mut old_rename)) => { + Some(UseSegment { + kind: UseSegmentKind::Ident(_, ref mut old_rename), + .. + }) => { assert!(old_rename.is_none()); - if let UseSegment::Slf(Some(rename)) = last.clone() { + if let UseSegmentKind::Slf(Some(rename)) = last.clone().kind { *old_rename = Some(rename); done = true; } @@ -538,15 +588,15 @@ impl UseTree { } // Normalise foo::{bar} -> foo::bar - if let UseSegment::List(ref list) = last { + if let UseSegmentKind::List(ref list) = last.kind { if list.len() == 1 && list[0].to_string() != "self" { normalize_sole_list = true; } } if normalize_sole_list { - match last { - UseSegment::List(list) => { + match last.kind { + UseSegmentKind::List(list) => { for seg in &list[0].path { self.path.push(seg.clone()); } @@ -557,10 +607,13 @@ impl UseTree { } // Recursively normalize elements of a list use (including sorting the list). - if let UseSegment::List(list) = last { + if let UseSegmentKind::List(list) = last.kind { let mut list = list.into_iter().map(UseTree::normalize).collect::>(); list.sort(); - last = UseSegment::List(list); + last = UseSegment { + kind: UseSegmentKind::List(list), + version: last.version, + }; } self.path.push(last); @@ -620,10 +673,10 @@ impl UseTree { if self.path.is_empty() || self.contains_comment() { return vec![self]; } - match self.path.clone().last().unwrap() { - UseSegment::List(list) => { + match &self.path.clone().last().unwrap().kind { + UseSegmentKind::List(list) => { if list.len() == 1 && list[0].path.len() == 1 { - if let UseSegment::Slf(..) = list[0].path[0] { + if let UseSegmentKind::Slf(..) = list[0].path[0].kind { return vec![self]; }; } @@ -671,12 +724,15 @@ impl UseTree { /// 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() { + if let Some(UseSegment { + kind: UseSegmentKind::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, - )])); + let version = self_segment.version; + let kind = UseSegmentKind::List(vec![UseTree::from_path(vec![self_segment], DUMMY_SP)]); + self.path.push(UseSegment { kind, version }); } self } @@ -692,7 +748,8 @@ fn merge_rest( return None; } if a.len() != len && b.len() != len { - if let UseSegment::List(ref list) = a[len] { + let version = a[len].version; + if let UseSegmentKind::List(ref list) = a[len].kind { let mut list = list.clone(); merge_use_trees_inner( &mut list, @@ -700,7 +757,8 @@ fn merge_rest( merge_by, ); let mut new_path = b[..len].to_vec(); - new_path.push(UseSegment::List(list)); + let kind = UseSegmentKind::List(list); + new_path.push(UseSegment { kind, version }); return Some(new_path); } } else if len == 1 { @@ -709,15 +767,28 @@ fn merge_rest( } else { (&b[0], &a[1..]) }; + let kind = UseSegmentKind::Slf(common.get_alias().map(ToString::to_string)); + let version = a[0].version; let mut list = vec![UseTree::from_path( - vec![UseSegment::Slf(common.get_alias().map(ToString::to_string))], + vec![UseSegment { kind, version }], DUMMY_SP, )]; match rest { - [UseSegment::List(rest_list)] => list.extend(rest_list.clone()), + [ + UseSegment { + kind: UseSegmentKind::List(rest_list), + .. + }, + ] => list.extend(rest_list.clone()), _ => list.push(UseTree::from_path(rest.to_vec(), DUMMY_SP)), } - return Some(vec![b[0].clone(), UseSegment::List(list)]); + return Some(vec![ + b[0].clone(), + UseSegment { + kind: UseSegmentKind::List(list), + version, + }, + ]); } else { len -= 1; } @@ -727,7 +798,9 @@ fn merge_rest( ]; list.sort(); let mut new_path = b[..len].to_vec(); - new_path.push(UseSegment::List(list)); + let kind = UseSegmentKind::List(list); + let version = a[0].version; + new_path.push(UseSegment { kind, version }); Some(new_path) } @@ -805,24 +878,24 @@ impl PartialOrd for UseTree { } impl Ord for UseSegment { fn cmp(&self, other: &UseSegment) -> Ordering { - use self::UseSegment::*; + use self::UseSegmentKind::*; fn is_upper_snake_case(s: &str) -> bool { s.chars() .all(|c| c.is_uppercase() || c == '_' || c.is_numeric()) } - match (self, other) { - (&Slf(ref a), &Slf(ref b)) - | (&Super(ref a), &Super(ref b)) - | (&Crate(ref a), &Crate(ref b)) => match (a, b) { + match (&self.kind, &other.kind) { + (Slf(ref a), Slf(ref b)) + | (Super(ref a), Super(ref b)) + | (Crate(ref a), Crate(ref b)) => match (a, b) { (Some(sa), Some(sb)) => { sa.trim_start_matches("r#").cmp(sb.trim_start_matches("r#")) } (_, _) => a.cmp(b), }, - (&Glob, &Glob) => Ordering::Equal, - (&Ident(ref pia, ref aa), &Ident(ref pib, ref ab)) => { + (Glob, Glob) => Ordering::Equal, + (Ident(ref pia, ref aa), Ident(ref pib, ref ab)) => { let ia = pia.trim_start_matches("r#"); let ib = pib.trim_start_matches("r#"); // snake_case < CamelCase < UPPER_SNAKE_CASE @@ -851,7 +924,7 @@ impl Ord for UseSegment { (None, None) => Ordering::Equal, } } - (&List(ref a), &List(ref b)) => { + (List(ref a), List(ref b)) => { for (a, b) in a.iter().zip(b.iter()) { let ord = a.cmp(b); if ord != Ordering::Equal { @@ -861,16 +934,16 @@ impl Ord for UseSegment { a.len().cmp(&b.len()) } - (&Slf(_), _) => Ordering::Less, - (_, &Slf(_)) => Ordering::Greater, - (&Super(_), _) => Ordering::Less, - (_, &Super(_)) => Ordering::Greater, - (&Crate(_), _) => Ordering::Less, - (_, &Crate(_)) => Ordering::Greater, - (&Ident(..), _) => Ordering::Less, - (_, &Ident(..)) => Ordering::Greater, - (&Glob, _) => Ordering::Less, - (_, &Glob) => Ordering::Greater, + (Slf(_), _) => Ordering::Less, + (_, Slf(_)) => Ordering::Greater, + (Super(_), _) => Ordering::Less, + (_, Super(_)) => Ordering::Greater, + (Crate(_), _) => Ordering::Less, + (_, Crate(_)) => Ordering::Greater, + (Ident(..), _) => Ordering::Less, + (_, Ident(..)) => Ordering::Greater, + (Glob, _) => Ordering::Less, + (_, Glob) => Ordering::Greater, } } } @@ -914,7 +987,7 @@ fn rewrite_nested_use_tree( } let has_nested_list = use_tree_list.iter().any(|use_segment| { use_segment.path.last().map_or(false, |last_segment| { - matches!(last_segment, UseSegment::List(..)) + matches!(last_segment.kind, UseSegmentKind::List(..)) }) }); @@ -965,17 +1038,19 @@ fn rewrite_nested_use_tree( impl Rewrite for UseSegment { fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option { - Some(match self { - UseSegment::Ident(ref ident, Some(ref rename)) => format!("{} as {}", ident, rename), - UseSegment::Ident(ref ident, None) => ident.clone(), - UseSegment::Slf(Some(ref rename)) => format!("self as {}", rename), - UseSegment::Slf(None) => "self".to_owned(), - UseSegment::Super(Some(ref rename)) => format!("super as {}", rename), - UseSegment::Super(None) => "super".to_owned(), - UseSegment::Crate(Some(ref rename)) => format!("crate as {}", rename), - UseSegment::Crate(None) => "crate".to_owned(), - UseSegment::Glob => "*".to_owned(), - UseSegment::List(ref use_tree_list) => rewrite_nested_use_tree( + Some(match self.kind { + UseSegmentKind::Ident(ref ident, Some(ref rename)) => { + format!("{} as {}", ident, rename) + } + UseSegmentKind::Ident(ref ident, None) => ident.clone(), + UseSegmentKind::Slf(Some(ref rename)) => format!("self as {}", rename), + UseSegmentKind::Slf(None) => "self".to_owned(), + UseSegmentKind::Super(Some(ref rename)) => format!("super as {}", rename), + UseSegmentKind::Super(None) => "super".to_owned(), + UseSegmentKind::Crate(Some(ref rename)) => format!("crate as {}", rename), + UseSegmentKind::Crate(None) => "crate".to_owned(), + UseSegmentKind::Glob => "*".to_owned(), + UseSegmentKind::List(ref use_tree_list) => rewrite_nested_use_tree( context, use_tree_list, // 1 = "{" and "}" @@ -1024,6 +1099,7 @@ mod test { struct Parser<'a> { input: Peekable>, + version: Version, } impl<'a> Parser<'a> { @@ -1036,34 +1112,40 @@ mod test { } fn push_segment( + &self, result: &mut Vec, buf: &mut String, alias_buf: &mut Option, ) { + let version = self.version; if !buf.is_empty() { let mut alias = None; swap(alias_buf, &mut alias); match buf.as_ref() { "self" => { - result.push(UseSegment::Slf(alias)); + let kind = UseSegmentKind::Slf(alias); + result.push(UseSegment { kind, version }); *buf = String::new(); *alias_buf = None; } "super" => { - result.push(UseSegment::Super(alias)); + let kind = UseSegmentKind::Super(alias); + result.push(UseSegment { kind, version }); *buf = String::new(); *alias_buf = None; } "crate" => { - result.push(UseSegment::Crate(alias)); + let kind = UseSegmentKind::Crate(alias); + result.push(UseSegment { kind, version }); *buf = String::new(); *alias_buf = None; } _ => { let mut name = String::new(); swap(buf, &mut name); - result.push(UseSegment::Ident(name, alias)); + let kind = UseSegmentKind::Ident(name, alias); + result.push(UseSegment { kind, version }); } } } @@ -1078,21 +1160,29 @@ mod test { '{' => { assert!(buf.is_empty()); self.bump(); - result.push(UseSegment::List(self.parse_list())); + let kind = UseSegmentKind::List(self.parse_list()); + result.push(UseSegment { + kind, + version: self.version, + }); self.eat('}'); } '*' => { assert!(buf.is_empty()); self.bump(); - result.push(UseSegment::Glob); + let kind = UseSegmentKind::Glob; + result.push(UseSegment { + kind, + version: self.version, + }); } ':' => { self.bump(); self.eat(':'); - Self::push_segment(&mut result, &mut buf, &mut alias_buf); + self.push_segment(&mut result, &mut buf, &mut alias_buf); } '}' | ',' => { - Self::push_segment(&mut result, &mut buf, &mut alias_buf); + self.push_segment(&mut result, &mut buf, &mut alias_buf); return UseTree { path: result, span: DUMMY_SP, @@ -1118,7 +1208,7 @@ mod test { } } } - Self::push_segment(&mut result, &mut buf, &mut alias_buf); + self.push_segment(&mut result, &mut buf, &mut alias_buf); UseTree { path: result, span: DUMMY_SP, @@ -1144,6 +1234,7 @@ mod test { let mut parser = Parser { input: s.chars().peekable(), + version: Version::One, }; parser.parse_in_list() } diff --git a/src/reorder.rs b/src/reorder.rs index 8ae297de25b..9e4a668aa49 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::{normalize_use_trees_with_granularity, UseSegment, UseTree}; +use crate::imports::{normalize_use_trees_with_granularity, UseSegmentKind, 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; @@ -182,16 +182,16 @@ fn group_imports(uts: Vec) -> Vec> { external_imports.push(ut); continue; } - match &ut.path[0] { - UseSegment::Ident(id, _) => match id.as_ref() { + match &ut.path[0].kind { + UseSegmentKind::Ident(id, _) => match id.as_ref() { "std" | "alloc" | "core" => std_imports.push(ut), _ => external_imports.push(ut), }, - UseSegment::Slf(_) | UseSegment::Super(_) | UseSegment::Crate(_) => { + UseSegmentKind::Slf(_) | UseSegmentKind::Super(_) | UseSegmentKind::Crate(_) => { local_imports.push(ut) } // These are probably illegal here - UseSegment::Glob | UseSegment::List(_) => external_imports.push(ut), + UseSegmentKind::Glob | UseSegmentKind::List(_) => external_imports.push(ut), } } -- cgit 1.4.1-3-g733a5 From e44380b34167ff554ca7bd6ccd446a511927e8aa Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Mon, 13 Jun 2022 11:36:20 -0400 Subject: Version gate raw identifier use statement sorting When useing `version=One` rustfmt will treat the leading `r#` as part of the `UseSegment` used for sorting. When using `version=Two` rustfmt will ignore the leading `r#` and only consider the name of the identifier when sorting the `UseSegment`. --- src/imports.rs | 24 ++++++++++++++++------ tests/source/imports_raw_identifiers.rs | 3 --- .../source/imports_raw_identifiers/version_One.rs | 5 +++++ .../source/imports_raw_identifiers/version_Two.rs | 5 +++++ tests/target/imports_raw_identifiers.rs | 3 --- .../target/imports_raw_identifiers/version_One.rs | 5 +++++ .../target/imports_raw_identifiers/version_Two.rs | 5 +++++ 7 files changed, 38 insertions(+), 12 deletions(-) delete mode 100644 tests/source/imports_raw_identifiers.rs create mode 100644 tests/source/imports_raw_identifiers/version_One.rs create mode 100644 tests/source/imports_raw_identifiers/version_Two.rs delete mode 100644 tests/target/imports_raw_identifiers.rs create mode 100644 tests/target/imports_raw_identifiers/version_One.rs create mode 100644 tests/target/imports_raw_identifiers/version_Two.rs (limited to 'src') diff --git a/src/imports.rs b/src/imports.rs index 58c5f31995e..8d41c881589 100644 --- a/src/imports.rs +++ b/src/imports.rs @@ -890,14 +890,21 @@ impl Ord for UseSegment { | (Super(ref a), Super(ref b)) | (Crate(ref a), Crate(ref b)) => match (a, b) { (Some(sa), Some(sb)) => { - sa.trim_start_matches("r#").cmp(sb.trim_start_matches("r#")) + if self.version == Version::Two { + sa.trim_start_matches("r#").cmp(sb.trim_start_matches("r#")) + } else { + a.cmp(b) + } } (_, _) => a.cmp(b), }, (Glob, Glob) => Ordering::Equal, (Ident(ref pia, ref aa), Ident(ref pib, ref ab)) => { - let ia = pia.trim_start_matches("r#"); - let ib = pib.trim_start_matches("r#"); + let (ia, ib) = if self.version == Version::Two { + (pia.trim_start_matches("r#"), pib.trim_start_matches("r#")) + } else { + (pia.as_str(), pib.as_str()) + }; // snake_case < CamelCase < UPPER_SNAKE_CASE if ia.starts_with(char::is_uppercase) && ib.starts_with(char::is_lowercase) { return Ordering::Greater; @@ -918,9 +925,14 @@ impl Ord for UseSegment { match (aa, ab) { (None, Some(_)) => Ordering::Less, (Some(_), None) => Ordering::Greater, - (Some(aas), Some(abs)) => aas - .trim_start_matches("r#") - .cmp(abs.trim_start_matches("r#")), + (Some(aas), Some(abs)) => { + if self.version == Version::Two { + aas.trim_start_matches("r#") + .cmp(abs.trim_start_matches("r#")) + } else { + aas.cmp(abs) + } + } (None, None) => Ordering::Equal, } } diff --git a/tests/source/imports_raw_identifiers.rs b/tests/source/imports_raw_identifiers.rs deleted file mode 100644 index d5857290b62..00000000000 --- a/tests/source/imports_raw_identifiers.rs +++ /dev/null @@ -1,3 +0,0 @@ -use websocket::client::ClientBuilder; -use websocket::r#async::futures::Stream; -use websocket::result::WebSocketError; diff --git a/tests/source/imports_raw_identifiers/version_One.rs b/tests/source/imports_raw_identifiers/version_One.rs new file mode 100644 index 00000000000..bc4b5b13569 --- /dev/null +++ b/tests/source/imports_raw_identifiers/version_One.rs @@ -0,0 +1,5 @@ +// rustfmt-version:One + +use websocket::client::ClientBuilder; +use websocket::r#async::futures::Stream; +use websocket::result::WebSocketError; diff --git a/tests/source/imports_raw_identifiers/version_Two.rs b/tests/source/imports_raw_identifiers/version_Two.rs new file mode 100644 index 00000000000..88e7fbd01ca --- /dev/null +++ b/tests/source/imports_raw_identifiers/version_Two.rs @@ -0,0 +1,5 @@ +// rustfmt-version:Two + +use websocket::client::ClientBuilder; +use websocket::r#async::futures::Stream; +use websocket::result::WebSocketError; diff --git a/tests/target/imports_raw_identifiers.rs b/tests/target/imports_raw_identifiers.rs deleted file mode 100644 index 6ae085c8a5f..00000000000 --- a/tests/target/imports_raw_identifiers.rs +++ /dev/null @@ -1,3 +0,0 @@ -use websocket::r#async::futures::Stream; -use websocket::client::ClientBuilder; -use websocket::result::WebSocketError; diff --git a/tests/target/imports_raw_identifiers/version_One.rs b/tests/target/imports_raw_identifiers/version_One.rs new file mode 100644 index 00000000000..bc4b5b13569 --- /dev/null +++ b/tests/target/imports_raw_identifiers/version_One.rs @@ -0,0 +1,5 @@ +// rustfmt-version:One + +use websocket::client::ClientBuilder; +use websocket::r#async::futures::Stream; +use websocket::result::WebSocketError; diff --git a/tests/target/imports_raw_identifiers/version_Two.rs b/tests/target/imports_raw_identifiers/version_Two.rs new file mode 100644 index 00000000000..22bfe93122f --- /dev/null +++ b/tests/target/imports_raw_identifiers/version_Two.rs @@ -0,0 +1,5 @@ +// rustfmt-version:Two + +use websocket::r#async::futures::Stream; +use websocket::client::ClientBuilder; +use websocket::result::WebSocketError; -- cgit 1.4.1-3-g733a5 From 33c60740d3e1387a5979cac93785e605de8470e0 Mon Sep 17 00:00:00 2001 From: sec65 <106604020+sec65@users.noreply.github.com> Date: Fri, 17 Jun 2022 05:15:16 +0200 Subject: Add width for codeblocks in comments (#5372) * add doc_comment_code_block_width configuration * updated config docu * Updated docu and changed tests to config folder --- Configurations.md | 8 ++++++ src/comment.rs | 4 +++ src/config/mod.rs | 3 +++ .../configs/doc_comment_code_block_width/100.rs | 16 ++++++++++++ .../100_greater_max_width.rs | 17 +++++++++++++ .../configs/doc_comment_code_block_width/50.rs | 16 ++++++++++++ .../configs/doc_comment_code_block_width/100.rs | 16 ++++++++++++ .../100_greater_max_width.rs | 29 ++++++++++++++++++++++ .../configs/doc_comment_code_block_width/50.rs | 22 ++++++++++++++++ 9 files changed, 131 insertions(+) create mode 100644 tests/source/configs/doc_comment_code_block_width/100.rs create mode 100644 tests/source/configs/doc_comment_code_block_width/100_greater_max_width.rs create mode 100644 tests/source/configs/doc_comment_code_block_width/50.rs create mode 100644 tests/target/configs/doc_comment_code_block_width/100.rs create mode 100644 tests/target/configs/doc_comment_code_block_width/100_greater_max_width.rs create mode 100644 tests/target/configs/doc_comment_code_block_width/50.rs (limited to 'src') diff --git a/Configurations.md b/Configurations.md index 8c84614352c..8b96b9d3689 100644 --- a/Configurations.md +++ b/Configurations.md @@ -926,6 +926,14 @@ fn add_one(x: i32) -> i32 { } ``` +## `doc_comment_code_block_width` + +Max width for code snippets included in doc comments. Only used if [`format_code_in_doc_comments`](#format_code_in_doc_comments) is true. + +- **Default value**: `100` +- **Possible values**: any positive integer that is less than or equal to the value specified for [`max_width`](#max_width) +- **Stable**: No (tracking issue: [#5359](https://github.com/rust-lang/rustfmt/issues/5359)) + ## `format_generated_files` Format generated files. A file is considered generated diff --git a/src/comment.rs b/src/comment.rs index eb195b1f762..4d565afc1e0 100644 --- a/src/comment.rs +++ b/src/comment.rs @@ -730,6 +730,10 @@ impl<'a> CommentRewrite<'a> { { let mut config = self.fmt.config.clone(); config.set().wrap_comments(false); + let comment_max_width = config + .doc_comment_code_block_width() + .min(config.max_width()); + config.set().max_width(comment_max_width); if let Some(s) = crate::format_code_block(&self.code_block_buffer, &config, false) { diff --git a/src/config/mod.rs b/src/config/mod.rs index a5169528187..f49c18d3a46 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -57,6 +57,8 @@ create_config! { // Comments. macros, and strings wrap_comments: bool, false, false, "Break comments to fit on the line"; format_code_in_doc_comments: bool, false, false, "Format the code snippet in doc comments."; + doc_comment_code_block_width: usize, 100, false, "Maximum width for code snippets in doc \ + comments. No effect unless format_code_in_doc_comments = true"; comment_width: usize, 80, false, "Maximum length of comments. No effect unless wrap_comments = true"; normalize_comments: bool, false, false, "Convert /* */ comments to // comments where possible"; @@ -532,6 +534,7 @@ chain_width = 60 single_line_if_else_max_width = 50 wrap_comments = false format_code_in_doc_comments = false +doc_comment_code_block_width = 100 comment_width = 80 normalize_comments = false normalize_doc_attributes = false diff --git a/tests/source/configs/doc_comment_code_block_width/100.rs b/tests/source/configs/doc_comment_code_block_width/100.rs new file mode 100644 index 00000000000..51578076167 --- /dev/null +++ b/tests/source/configs/doc_comment_code_block_width/100.rs @@ -0,0 +1,16 @@ +// rustfmt-format_code_in_doc_comments: true +// rustfmt-doc_comment_code_block_width: 100 + +/// ```rust +/// impl Test { +/// pub const fn from_bytes(v: &[u8]) -> Result { +/// Self::from_bytes_manual_slice(v, 0, v.len() ) +/// } +/// } +/// ``` + +impl Test { + pub const fn from_bytes(v: &[u8]) -> Result { + Self::from_bytes_manual_slice(v, 0, v.len() ) + } +} diff --git a/tests/source/configs/doc_comment_code_block_width/100_greater_max_width.rs b/tests/source/configs/doc_comment_code_block_width/100_greater_max_width.rs new file mode 100644 index 00000000000..96505c69714 --- /dev/null +++ b/tests/source/configs/doc_comment_code_block_width/100_greater_max_width.rs @@ -0,0 +1,17 @@ +// rustfmt-max_width: 50 +// rustfmt-format_code_in_doc_comments: true +// rustfmt-doc_comment_code_block_width: 100 + +/// ```rust +/// impl Test { +/// pub const fn from_bytes(v: &[u8]) -> Result { +/// Self::from_bytes_manual_slice(v, 0, v.len() ) +/// } +/// } +/// ``` + +impl Test { + pub const fn from_bytes(v: &[u8]) -> Result { + Self::from_bytes_manual_slice(v, 0, v.len() ) + } +} diff --git a/tests/source/configs/doc_comment_code_block_width/50.rs b/tests/source/configs/doc_comment_code_block_width/50.rs new file mode 100644 index 00000000000..2c6307951c8 --- /dev/null +++ b/tests/source/configs/doc_comment_code_block_width/50.rs @@ -0,0 +1,16 @@ +// rustfmt-format_code_in_doc_comments: true +// rustfmt-doc_comment_code_block_width: 50 + +/// ```rust +/// impl Test { +/// pub const fn from_bytes(v: &[u8]) -> Result { +/// Self::from_bytes_manual_slice(v, 0, v.len() ) +/// } +/// } +/// ``` + +impl Test { + pub const fn from_bytes(v: &[u8]) -> Result { + Self::from_bytes_manual_slice(v, 0, v.len() ) + } +} diff --git a/tests/target/configs/doc_comment_code_block_width/100.rs b/tests/target/configs/doc_comment_code_block_width/100.rs new file mode 100644 index 00000000000..c010a28aab6 --- /dev/null +++ b/tests/target/configs/doc_comment_code_block_width/100.rs @@ -0,0 +1,16 @@ +// rustfmt-format_code_in_doc_comments: true +// rustfmt-doc_comment_code_block_width: 100 + +/// ```rust +/// impl Test { +/// pub const fn from_bytes(v: &[u8]) -> Result { +/// Self::from_bytes_manual_slice(v, 0, v.len()) +/// } +/// } +/// ``` + +impl Test { + pub const fn from_bytes(v: &[u8]) -> Result { + Self::from_bytes_manual_slice(v, 0, v.len()) + } +} diff --git a/tests/target/configs/doc_comment_code_block_width/100_greater_max_width.rs b/tests/target/configs/doc_comment_code_block_width/100_greater_max_width.rs new file mode 100644 index 00000000000..6bcb99b915f --- /dev/null +++ b/tests/target/configs/doc_comment_code_block_width/100_greater_max_width.rs @@ -0,0 +1,29 @@ +// rustfmt-max_width: 50 +// rustfmt-format_code_in_doc_comments: true +// rustfmt-doc_comment_code_block_width: 100 + +/// ```rust +/// impl Test { +/// pub const fn from_bytes( +/// v: &[u8], +/// ) -> Result { +/// Self::from_bytes_manual_slice( +/// v, +/// 0, +/// v.len(), +/// ) +/// } +/// } +/// ``` + +impl Test { + pub const fn from_bytes( + v: &[u8], + ) -> Result { + Self::from_bytes_manual_slice( + v, + 0, + v.len(), + ) + } +} diff --git a/tests/target/configs/doc_comment_code_block_width/50.rs b/tests/target/configs/doc_comment_code_block_width/50.rs new file mode 100644 index 00000000000..e8ab6f28bdc --- /dev/null +++ b/tests/target/configs/doc_comment_code_block_width/50.rs @@ -0,0 +1,22 @@ +// rustfmt-format_code_in_doc_comments: true +// rustfmt-doc_comment_code_block_width: 50 + +/// ```rust +/// impl Test { +/// pub const fn from_bytes( +/// v: &[u8], +/// ) -> Result { +/// Self::from_bytes_manual_slice( +/// v, +/// 0, +/// v.len(), +/// ) +/// } +/// } +/// ``` + +impl Test { + pub const fn from_bytes(v: &[u8]) -> Result { + Self::from_bytes_manual_slice(v, 0, v.len()) + } +} -- cgit 1.4.1-3-g733a5 From 0156575a32511a2d58d129415e9ce31ccb80e7e8 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Wed, 22 Jun 2022 13:36:01 -0400 Subject: Revert "Memoize format_expr" Fixes 5399 Memoizing expressions lead to cases where rustfmt's stability guarantees were violated. This reverts commit a37d3ab0e1c7c05f1a6410fb7ddf5539f0d030f8. --- 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, 4 insertions(+), 11454 deletions(-) delete mode 100644 tests/source/performance/issue-4476.rs delete mode 100644 tests/source/performance/issue-5128.rs delete mode 100644 tests/target/performance/issue-4476.rs delete mode 100644 tests/target/performance/issue-4867.rs delete mode 100644 tests/target/performance/issue-5128.rs (limited to 'src') diff --git a/src/expr.rs b/src/expr.rs index 4ccf1ca70c9..e4cc93026f1 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -1,6 +1,5 @@ use std::borrow::Cow; use std::cmp::min; -use std::collections::HashMap; use itertools::Itertools; use rustc_ast::token::{Delimiter, LitKind}; @@ -23,7 +22,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::{QueryId, Rewrite, RewriteContext}; +use crate::rewrite::{Rewrite, RewriteContext}; use crate::shape::{Indent, Shape}; use crate::source_map::{LineRangeUtils, SpanUtils}; use crate::spanned::Spanned; @@ -54,54 +53,6 @@ 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 e644ea50eff..1dfd8a514f0 100644 --- a/src/formatting.rs +++ b/src/formatting.rs @@ -2,7 +2,6 @@ use std::collections::HashMap; use std::io::{self, Write}; -use std::rc::Rc; use std::time::{Duration, Instant}; use rustc_ast::ast; @@ -203,7 +202,6 @@ 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 f97df70cc6a..4a3bd129d16 100644 --- a/src/rewrite.rs +++ b/src/rewrite.rs @@ -12,7 +12,6 @@ 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. @@ -25,22 +24,10 @@ 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 b3f785a9470..4376fd12b52 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, PartialEq, Eq, Hash)] +#[derive(Copy, Clone, Debug)] 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, PartialEq, Eq, Hash)] +#[derive(Copy, Clone, Debug)] pub(crate) struct Shape { pub(crate) width: usize, // The current indentation of code. diff --git a/src/visitor.rs b/src/visitor.rs index 3ff56d52f92..9a0e0752c12 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::{Memoize, Rewrite, RewriteContext}; +use crate::rewrite::{Rewrite, RewriteContext}; use crate::shape::{Indent, Shape}; use crate::skip::{is_skip_attr, SkipContext}; use crate::source_map::{LineRangeUtils, SpanUtils}; @@ -71,7 +71,6 @@ 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, @@ -759,7 +758,6 @@ 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); @@ -771,12 +769,10 @@ 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(), @@ -999,7 +995,6 @@ 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 deleted file mode 100644 index 8da3f19b62d..00000000000 --- a/tests/source/performance/issue-4476.rs +++ /dev/null @@ -1,638 +0,0 @@ -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 deleted file mode 100644 index 3adce49601c..00000000000 --- a/tests/source/performance/issue-5128.rs +++ /dev/null @@ -1,5127 +0,0 @@ - -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 deleted file mode 100644 index 30567f2644b..00000000000 --- a/tests/target/performance/issue-4476.rs +++ /dev/null @@ -1,705 +0,0 @@ -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 deleted file mode 100644 index 336dae1b64a..00000000000 --- a/tests/target/performance/issue-4867.rs +++ /dev/null @@ -1,13 +0,0 @@ -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 deleted file mode 100644 index ba9ebfc6243..00000000000 --- a/tests/target/performance/issue-5128.rs +++ /dev/null @@ -1,4898 +0,0 @@ -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, -} -- cgit 1.4.1-3-g733a5 From 08105e80b7c48782cfd7acbf3695c7f14c839cfd Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Tue, 21 Jun 2022 18:55:24 -0400 Subject: Fix issue where `cargo fmt --version` would not display version info Fixes 5395 In PR 5239 we switched from using `structopt` to `clap`. It seems that the default behavior for `clap` is to override the `--version` flag, which prevented our custom version display code from running. The fix as outlined in https://github.com/clap-rs/clap/issues/3405 was to set `#[clap(global_setting(AppSettings::NoAutoVersion))]` to prevent clap from setting its own default behavior for the `--version` flag. --- src/cargo-fmt/main.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/cargo-fmt/main.rs b/src/cargo-fmt/main.rs index 55fd75f6de9..9031d29b45f 100644 --- a/src/cargo-fmt/main.rs +++ b/src/cargo-fmt/main.rs @@ -14,7 +14,7 @@ use std::path::{Path, PathBuf}; use std::process::Command; use std::str; -use clap::{CommandFactory, Parser}; +use clap::{AppSettings, CommandFactory, Parser}; #[path = "test/mod.rs"] #[cfg(test)] @@ -22,6 +22,7 @@ mod cargo_fmt_tests; #[derive(Parser)] #[clap( + global_setting(AppSettings::NoAutoVersion), bin_name = "cargo fmt", about = "This utility formats all bin and lib files of \ the current crate using rustfmt." -- cgit 1.4.1-3-g733a5 From 778e1b1a76d4c6f6d7b56d4613db4a94e2bc434d Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Wed, 22 Jun 2022 19:29:38 -0500 Subject: Revert "Memoize format_expr" This reverts commit a37d3ab0e1c7c05f1a6410fb7ddf5539f0d030f8. --- 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, 4 insertions(+), 11454 deletions(-) delete mode 100644 tests/source/performance/issue-4476.rs delete mode 100644 tests/source/performance/issue-5128.rs delete mode 100644 tests/target/performance/issue-4476.rs delete mode 100644 tests/target/performance/issue-4867.rs delete mode 100644 tests/target/performance/issue-5128.rs (limited to 'src') diff --git a/src/expr.rs b/src/expr.rs index 4ccf1ca70c9..e4cc93026f1 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -1,6 +1,5 @@ use std::borrow::Cow; use std::cmp::min; -use std::collections::HashMap; use itertools::Itertools; use rustc_ast::token::{Delimiter, LitKind}; @@ -23,7 +22,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::{QueryId, Rewrite, RewriteContext}; +use crate::rewrite::{Rewrite, RewriteContext}; use crate::shape::{Indent, Shape}; use crate::source_map::{LineRangeUtils, SpanUtils}; use crate::spanned::Spanned; @@ -54,54 +53,6 @@ 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 e644ea50eff..1dfd8a514f0 100644 --- a/src/formatting.rs +++ b/src/formatting.rs @@ -2,7 +2,6 @@ use std::collections::HashMap; use std::io::{self, Write}; -use std::rc::Rc; use std::time::{Duration, Instant}; use rustc_ast::ast; @@ -203,7 +202,6 @@ 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 f97df70cc6a..4a3bd129d16 100644 --- a/src/rewrite.rs +++ b/src/rewrite.rs @@ -12,7 +12,6 @@ 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. @@ -25,22 +24,10 @@ 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 b3f785a9470..4376fd12b52 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, PartialEq, Eq, Hash)] +#[derive(Copy, Clone, Debug)] 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, PartialEq, Eq, Hash)] +#[derive(Copy, Clone, Debug)] pub(crate) struct Shape { pub(crate) width: usize, // The current indentation of code. diff --git a/src/visitor.rs b/src/visitor.rs index 3ff56d52f92..9a0e0752c12 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::{Memoize, Rewrite, RewriteContext}; +use crate::rewrite::{Rewrite, RewriteContext}; use crate::shape::{Indent, Shape}; use crate::skip::{is_skip_attr, SkipContext}; use crate::source_map::{LineRangeUtils, SpanUtils}; @@ -71,7 +71,6 @@ 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, @@ -759,7 +758,6 @@ 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); @@ -771,12 +769,10 @@ 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(), @@ -999,7 +995,6 @@ 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 deleted file mode 100644 index 8da3f19b62d..00000000000 --- a/tests/source/performance/issue-4476.rs +++ /dev/null @@ -1,638 +0,0 @@ -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 deleted file mode 100644 index 3adce49601c..00000000000 --- a/tests/source/performance/issue-5128.rs +++ /dev/null @@ -1,5127 +0,0 @@ - -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 deleted file mode 100644 index 30567f2644b..00000000000 --- a/tests/target/performance/issue-4476.rs +++ /dev/null @@ -1,705 +0,0 @@ -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 deleted file mode 100644 index 336dae1b64a..00000000000 --- a/tests/target/performance/issue-4867.rs +++ /dev/null @@ -1,13 +0,0 @@ -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 deleted file mode 100644 index ba9ebfc6243..00000000000 --- a/tests/target/performance/issue-5128.rs +++ /dev/null @@ -1,4898 +0,0 @@ -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, -} -- cgit 1.4.1-3-g733a5 From 2ae63f0018a7e18deb7ac0063379c2350a631fca Mon Sep 17 00:00:00 2001 From: Tom Milligan Date: Fri, 10 Jun 2022 12:17:29 +0100 Subject: config_type: add unstable_variant attribute --- Cargo.lock | 2 +- Cargo.toml | 2 +- config_proc_macro/Cargo.lock | 2 +- config_proc_macro/Cargo.toml | 2 +- config_proc_macro/src/attrs.rs | 27 +++++++-- config_proc_macro/src/item_enum.rs | 40 ++++++++++++- config_proc_macro/tests/smoke.rs | 1 + src/config/config_type.rs | 90 +++++++++++++++++++++++------ src/config/mod.rs | 112 ++++++++++++++++++++++++++++++++++--- 9 files changed, 244 insertions(+), 34 deletions(-) (limited to 'src') diff --git a/Cargo.lock b/Cargo.lock index 311df226da1..e5175528970 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -476,7 +476,7 @@ checksum = "fc71d2faa173b74b232dedc235e3ee1696581bb132fc116fa3626d6151a1a8fb" [[package]] name = "rustfmt-config_proc_macro" -version = "0.2.0" +version = "0.3.0" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 7a4e02d69ed..7438335eaa7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -57,7 +57,7 @@ unicode-segmentation = "1.9" unicode-width = "0.1" unicode_categories = "0.1" -rustfmt-config_proc_macro = { version = "0.2", path = "config_proc_macro" } +rustfmt-config_proc_macro = { version = "0.3", 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` diff --git a/config_proc_macro/Cargo.lock b/config_proc_macro/Cargo.lock index ecf561f28fb..49f2f72a8d2 100644 --- a/config_proc_macro/Cargo.lock +++ b/config_proc_macro/Cargo.lock @@ -22,7 +22,7 @@ dependencies = [ [[package]] name = "rustfmt-config_proc_macro" -version = "0.2.0" +version = "0.3.0" dependencies = [ "proc-macro2", "quote", diff --git a/config_proc_macro/Cargo.toml b/config_proc_macro/Cargo.toml index a41b3a5e6bf..d10d0469cc4 100644 --- a/config_proc_macro/Cargo.toml +++ b/config_proc_macro/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rustfmt-config_proc_macro" -version = "0.2.0" +version = "0.3.0" edition = "2018" description = "A collection of procedural macros for rustfmt" license = "Apache-2.0/MIT" diff --git a/config_proc_macro/src/attrs.rs b/config_proc_macro/src/attrs.rs index 0baba046f9e..dd18ff572cb 100644 --- a/config_proc_macro/src/attrs.rs +++ b/config_proc_macro/src/attrs.rs @@ -1,8 +1,10 @@ //! This module provides utilities for handling attributes on variants -//! of `config_type` enum. Currently there are two types of attributes -//! that could appear on the variants of `config_type` enum: `doc_hint` -//! and `value`. Both comes in the form of name-value pair whose value -//! is string literal. +//! of `config_type` enum. Currently there are the following attributes +//! that could appear on the variants of `config_type` enum: +//! +//! - `doc_hint`: name-value pair whose value is string literal +//! - `value`: name-value pair whose value is string literal +//! - `unstable_variant`: name only /// Returns the value of the first `doc_hint` attribute in the given slice or /// `None` if `doc_hint` attribute is not available. @@ -27,6 +29,11 @@ pub fn find_config_value(attrs: &[syn::Attribute]) -> Option { attrs.iter().filter_map(config_value).next() } +/// Returns `true` if the there is at least one `unstable` attribute in the given slice. +pub fn any_unstable_variant(attrs: &[syn::Attribute]) -> bool { + attrs.iter().any(is_unstable_variant) +} + /// Returns a string literal value if the given attribute is `value` /// attribute or `None` otherwise. pub fn config_value(attr: &syn::Attribute) -> Option { @@ -38,6 +45,11 @@ pub fn is_config_value(attr: &syn::Attribute) -> bool { is_attr_name_value(attr, "value") } +/// Returns `true` if the given attribute is an `unstable` attribute. +pub fn is_unstable_variant(attr: &syn::Attribute) -> bool { + is_attr_path(attr, "unstable_variant") +} + fn is_attr_name_value(attr: &syn::Attribute, name: &str) -> bool { attr.parse_meta().ok().map_or(false, |meta| match meta { syn::Meta::NameValue(syn::MetaNameValue { ref path, .. }) if path.is_ident(name) => true, @@ -45,6 +57,13 @@ fn is_attr_name_value(attr: &syn::Attribute, name: &str) -> bool { }) } +fn is_attr_path(attr: &syn::Attribute, name: &str) -> bool { + attr.parse_meta().ok().map_or(false, |meta| match meta { + syn::Meta::Path(path) if path.is_ident(name) => true, + _ => false, + }) +} + fn get_name_value_str_lit(attr: &syn::Attribute, name: &str) -> Option { attr.parse_meta().ok().and_then(|meta| match meta { syn::Meta::NameValue(syn::MetaNameValue { diff --git a/config_proc_macro/src/item_enum.rs b/config_proc_macro/src/item_enum.rs index dcee77a8549..731a7ea0607 100644 --- a/config_proc_macro/src/item_enum.rs +++ b/config_proc_macro/src/item_enum.rs @@ -1,5 +1,6 @@ use proc_macro2::TokenStream; -use quote::quote; +use quote::{quote, quote_spanned}; +use syn::spanned::Spanned; use crate::attrs::*; use crate::utils::*; @@ -47,12 +48,23 @@ fn process_variant(variant: &syn::Variant) -> TokenStream { let metas = variant .attrs .iter() - .filter(|attr| !is_doc_hint(attr) && !is_config_value(attr)); + .filter(|attr| !is_doc_hint(attr) && !is_config_value(attr) && !is_unstable_variant(attr)); let attrs = fold_quote(metas, |meta| quote!(#meta)); let syn::Variant { ident, fields, .. } = variant; quote!(#attrs #ident #fields) } +/// Return the correct syntax to pattern match on the enum variant, discarding all +/// internal field data. +fn fields_in_variant(variant: &syn::Variant) -> TokenStream { + // With thanks to https://stackoverflow.com/a/65182902 + match &variant.fields { + syn::Fields::Unnamed(_) => quote_spanned! { variant.span() => (..) }, + syn::Fields::Unit => quote_spanned! { variant.span() => }, + syn::Fields::Named(_) => quote_spanned! { variant.span() => {..} }, + } +} + fn impl_doc_hint(ident: &syn::Ident, variants: &Variants) -> TokenStream { let doc_hint = variants .iter() @@ -60,12 +72,26 @@ fn impl_doc_hint(ident: &syn::Ident, variants: &Variants) -> TokenStream { .collect::>() .join("|"); let doc_hint = format!("[{}]", doc_hint); + + let variant_stables = variants + .iter() + .map(|v| (&v.ident, fields_in_variant(&v), !unstable_of_variant(v))); + let match_patterns = fold_quote(variant_stables, |(v, fields, stable)| { + quote! { + #ident::#v #fields => #stable, + } + }); quote! { use crate::config::ConfigType; impl ConfigType for #ident { fn doc_hint() -> String { #doc_hint.to_owned() } + fn stable_variant(&self) -> bool { + match self { + #match_patterns + } + } } } } @@ -123,13 +149,21 @@ fn impl_from_str(ident: &syn::Ident, variants: &Variants) -> TokenStream { } fn doc_hint_of_variant(variant: &syn::Variant) -> String { - find_doc_hint(&variant.attrs).unwrap_or(variant.ident.to_string()) + let mut text = find_doc_hint(&variant.attrs).unwrap_or(variant.ident.to_string()); + if unstable_of_variant(&variant) { + text.push_str(" (unstable)") + }; + text } fn config_value_of_variant(variant: &syn::Variant) -> String { find_config_value(&variant.attrs).unwrap_or(variant.ident.to_string()) } +fn unstable_of_variant(variant: &syn::Variant) -> bool { + any_unstable_variant(&variant.attrs) +} + fn impl_serde(ident: &syn::Ident, variants: &Variants) -> TokenStream { let arms = fold_quote(variants.iter(), |v| { let v_ident = &v.ident; diff --git a/config_proc_macro/tests/smoke.rs b/config_proc_macro/tests/smoke.rs index 940a8a0c251..c8a83e39c9e 100644 --- a/config_proc_macro/tests/smoke.rs +++ b/config_proc_macro/tests/smoke.rs @@ -1,6 +1,7 @@ pub mod config { pub trait ConfigType: Sized { fn doc_hint() -> String; + fn stable_variant(&self) -> bool; } } diff --git a/src/config/config_type.rs b/src/config/config_type.rs index e37ed798cb5..26d57a13791 100644 --- a/src/config/config_type.rs +++ b/src/config/config_type.rs @@ -6,6 +6,14 @@ pub(crate) trait ConfigType: Sized { /// Returns hint text for use in `Config::print_docs()`. For enum types, this is a /// pipe-separated list of variants; for other types it returns "". fn doc_hint() -> String; + + /// Return `true` if the variant (i.e. value of this type) is stable. + /// + /// By default, return true for all values. Enums annotated with `#[config_type]` + /// are automatically implemented, based on the `#[unstable_variant]` annotation. + fn stable_variant(&self) -> bool { + true + } } impl ConfigType for bool { @@ -51,6 +59,13 @@ impl ConfigType for IgnoreList { } macro_rules! create_config { + // Options passed in to the macro. + // + // - $i: the ident name of the option + // - $ty: the type of the option value + // - $def: the default value of the option + // - $stb: true if the option is stable + // - $dstring: description of the option ($($i:ident: $ty:ty, $def:expr, $stb:expr, $( $dstring:expr ),+ );+ $(;)*) => ( #[cfg(test)] use std::collections::HashSet; @@ -61,9 +76,12 @@ macro_rules! create_config { #[derive(Clone)] #[allow(unreachable_pub)] pub struct Config { - // 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, + // For each config item, we store: + // + // - 0: true if the value has been access + // - 1: true if the option was manually initialized + // - 2: the option value + // - 3: true if the option is unstable $($i: (Cell, bool, $ty, bool)),+ } @@ -143,18 +161,13 @@ macro_rules! create_config { fn fill_from_parsed_config(mut self, parsed: PartialConfig, dir: &Path) -> Config { $( - if let Some(val) = parsed.$i { - if self.$i.3 { + if let Some(option_value) = parsed.$i { + let option_stable = self.$i.3; + if $crate::config::config_type::is_stable_option_and_value( + stringify!($i), option_stable, &option_value + ) { self.$i.1 = true; - self.$i.2 = val; - } else { - if crate::is_nightly_channel!() { - self.$i.1 = true; - self.$i.2 = val; - } else { - eprintln!("Warning: can't set `{} = {:?}`, unstable features are only \ - available in nightly channel.", stringify!($i), val); - } + self.$i.2 = option_value; } } )+ @@ -221,12 +234,22 @@ macro_rules! create_config { match key { $( stringify!($i) => { - self.$i.1 = true; - self.$i.2 = val.parse::<$ty>() + let option_value = val.parse::<$ty>() .expect(&format!("Failed to parse override for {} (\"{}\") as a {}", stringify!($i), val, stringify!($ty))); + + // Users are currently allowed to set unstable + // options/variants via the `--config` options override. + // + // There is ongoing discussion about how to move forward here: + // https://github.com/rust-lang/rustfmt/pull/5379 + // + // For now, do not validate whether the option or value is stable, + // just always set it. + self.$i.1 = true; + self.$i.2 = option_value; } )+ _ => panic!("Unknown config key in override: {}", key) @@ -424,3 +447,38 @@ macro_rules! create_config { } ) } + +pub(crate) fn is_stable_option_and_value( + option_name: &str, + option_stable: bool, + option_value: &T, +) -> bool +where + T: PartialEq + std::fmt::Debug + ConfigType, +{ + let nightly = crate::is_nightly_channel!(); + let variant_stable = option_value.stable_variant(); + match (nightly, option_stable, variant_stable) { + // Stable with an unstable option + (false, false, _) => { + eprintln!( + "Warning: can't set `{} = {:?}`, unstable features are only \ + available in nightly channel.", + option_name, option_value + ); + false + } + // Stable with a stable option, but an unstable variant + (false, true, false) => { + eprintln!( + "Warning: can't set `{} = {:?}`, unstable variants are only \ + available in nightly channel.", + option_name, option_value + ); + false + } + // Nightly: everything allowed + // Stable with stable option and variant: allowed + (true, _, _) | (false, true, true) => true, + } +} diff --git a/src/config/mod.rs b/src/config/mod.rs index f49c18d3a46..eaada8db090 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -408,6 +408,15 @@ mod test { #[allow(dead_code)] mod mock { use super::super::*; + use rustfmt_config_proc_macro::config_type; + + #[config_type] + pub enum PartiallyUnstableOption { + V1, + V2, + #[unstable_variant] + V3, + } create_config! { // Options that are used by the generated functions @@ -451,6 +460,63 @@ mod test { // Options that are used by the tests stable_option: bool, false, true, "A stable option"; unstable_option: bool, false, false, "An unstable option"; + partially_unstable_option: PartiallyUnstableOption, PartiallyUnstableOption::V1, true, + "A partially unstable option"; + } + + #[cfg(test)] + mod partially_unstable_option { + use super::{Config, PartialConfig, PartiallyUnstableOption}; + use rustfmt_config_proc_macro::{nightly_only_test, stable_only_test}; + use std::path::Path; + + /// From the config file, we can fill with a stable variant + #[test] + fn test_from_toml_stable_value() { + let toml = r#" + partially_unstable_option = "V2" + "#; + let partial_config: PartialConfig = toml::from_str(toml).unwrap(); + let config = Config::default(); + let config = config.fill_from_parsed_config(partial_config, Path::new("")); + assert_eq!( + config.partially_unstable_option(), + PartiallyUnstableOption::V2 + ); + } + + /// From the config file, we cannot fill with an unstable variant (stable only) + #[stable_only_test] + #[test] + fn test_from_toml_unstable_value_on_stable() { + let toml = r#" + partially_unstable_option = "V3" + "#; + let partial_config: PartialConfig = toml::from_str(toml).unwrap(); + let config = Config::default(); + let config = config.fill_from_parsed_config(partial_config, Path::new("")); + assert_eq!( + config.partially_unstable_option(), + // default value from config, i.e. fill failed + PartiallyUnstableOption::V1 + ); + } + + /// From the config file, we can fill with an unstable variant (nightly only) + #[nightly_only_test] + #[test] + fn test_from_toml_unstable_value_on_nightly() { + let toml = r#" + partially_unstable_option = "V3" + "#; + let partial_config: PartialConfig = toml::from_str(toml).unwrap(); + let config = Config::default(); + let config = config.fill_from_parsed_config(partial_config, Path::new("")); + assert_eq!( + config.partially_unstable_option(), + PartiallyUnstableOption::V3 + ); + } } } @@ -489,6 +555,11 @@ mod test { assert_eq!(config.was_set().verbose(), false); } + const PRINT_DOCS_STABLE_OPTION: &str = "stable_option Default: false"; + const PRINT_DOCS_UNSTABLE_OPTION: &str = "unstable_option Default: false (unstable)"; + const PRINT_DOCS_PARTIALLY_UNSTABLE_OPTION: &str = + "partially_unstable_option [V1|V2|V3 (unstable)] Default: V1"; + #[test] fn test_print_docs_exclude_unstable() { use self::mock::Config; @@ -497,10 +568,9 @@ mod test { Config::print_docs(&mut output, false); let s = str::from_utf8(&output).unwrap(); - - assert_eq!(s.contains("stable_option"), true); - assert_eq!(s.contains("unstable_option"), false); - assert_eq!(s.contains("(unstable)"), false); + assert_eq!(s.contains(PRINT_DOCS_STABLE_OPTION), true); + assert_eq!(s.contains(PRINT_DOCS_UNSTABLE_OPTION), false); + assert_eq!(s.contains(PRINT_DOCS_PARTIALLY_UNSTABLE_OPTION), true); } #[test] @@ -511,9 +581,9 @@ mod test { Config::print_docs(&mut output, true); let s = str::from_utf8(&output).unwrap(); - assert_eq!(s.contains("stable_option"), true); - assert_eq!(s.contains("unstable_option"), true); - assert_eq!(s.contains("(unstable)"), true); + assert_eq!(s.contains(PRINT_DOCS_STABLE_OPTION), true); + assert_eq!(s.contains(PRINT_DOCS_UNSTABLE_OPTION), true); + assert_eq!(s.contains(PRINT_DOCS_PARTIALLY_UNSTABLE_OPTION), true); } #[test] @@ -921,4 +991,32 @@ make_backup = false assert_eq!(config.single_line_if_else_max_width(), 100); } } + + #[cfg(test)] + mod partially_unstable_option { + use super::mock::{Config, PartiallyUnstableOption}; + use super::*; + + /// From the command line, we can override with a stable variant. + #[test] + fn test_override_stable_value() { + let mut config = Config::default(); + config.override_value("partially_unstable_option", "V2"); + assert_eq!( + config.partially_unstable_option(), + PartiallyUnstableOption::V2 + ); + } + + /// From the command line, we can override with an unstable variant. + #[test] + fn test_override_unstable_value() { + let mut config = Config::default(); + config.override_value("partially_unstable_option", "V3"); + assert_eq!( + config.partially_unstable_option(), + PartiallyUnstableOption::V3 + ); + } + } } -- cgit 1.4.1-3-g733a5 From 35f4c55bf476884feadf525e110453f6815f8dd8 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Sun, 3 Jul 2022 22:09:42 -0500 Subject: refactor: remove some unnecessary clones --- src/chains.rs | 21 ++++++++++----------- src/expr.rs | 9 ++++----- src/macros.rs | 15 +++++++-------- src/utils.rs | 5 +++-- 4 files changed, 24 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/chains.rs b/src/chains.rs index e26e24ec55a..5bccb22db4c 100644 --- a/src/chains.rs +++ b/src/chains.rs @@ -70,8 +70,8 @@ use crate::rewrite::{Rewrite, RewriteContext}; use crate::shape::Shape; use crate::source_map::SpanUtils; use crate::utils::{ - self, first_line_width, last_line_extendable, last_line_width, mk_sp, rewrite_ident, - trimmed_last_line_width, wrap_str, + self, filtered_str_fits, first_line_width, last_line_extendable, last_line_width, mk_sp, + rewrite_ident, trimmed_last_line_width, wrap_str, }; pub(crate) fn rewrite_chain( @@ -810,15 +810,14 @@ impl<'a> ChainFormatter for ChainFormatterVisual<'a> { .visual_indent(self.offset) .sub_width(self.offset)?; let rewrite = item.rewrite(context, child_shape)?; - match wrap_str(rewrite, context.config.max_width(), shape) { - Some(rewrite) => root_rewrite.push_str(&rewrite), - None => { - // We couldn't fit in at the visual indent, try the last - // indent. - let rewrite = item.rewrite(context, parent_shape)?; - root_rewrite.push_str(&rewrite); - self.offset = 0; - } + if filtered_str_fits(&rewrite, context.config.max_width(), shape) { + root_rewrite.push_str(&rewrite); + } else { + // We couldn't fit in at the visual indent, try the last + // indent. + let rewrite = item.rewrite(context, parent_shape)?; + root_rewrite.push_str(&rewrite); + self.offset = 0; } self.shared.children = &self.shared.children[1..]; diff --git a/src/expr.rs b/src/expr.rs index e4cc93026f1..13d068d0c2d 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -29,9 +29,9 @@ use crate::spanned::Spanned; use crate::string::{rewrite_string, StringFormat}; use crate::types::{rewrite_path, PathContext}; use crate::utils::{ - colon_spaces, contains_skip, count_newlines, first_line_ends_with, inner_attributes, - last_line_extendable, last_line_width, mk_sp, outer_attributes, semicolon_for_expr, - unicode_str_width, wrap_str, + colon_spaces, contains_skip, count_newlines, filtered_str_fits, first_line_ends_with, + inner_attributes, last_line_extendable, last_line_width, mk_sp, outer_attributes, + semicolon_for_expr, unicode_str_width, wrap_str, }; use crate::vertical::rewrite_with_alignment; use crate::visitor::FmtVisitor; @@ -2037,8 +2037,7 @@ fn choose_rhs( match (orig_rhs, new_rhs) { (Some(ref orig_rhs), Some(ref new_rhs)) - if wrap_str(new_rhs.clone(), context.config.max_width(), new_shape) - .is_none() => + if !filtered_str_fits(&new_rhs, context.config.max_width(), new_shape) => { Some(format!("{}{}", before_space_str, orig_rhs)) } diff --git a/src/macros.rs b/src/macros.rs index f4b2bcf2815..e78ef1f8066 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -35,8 +35,8 @@ use crate::shape::{Indent, Shape}; use crate::source_map::SpanUtils; use crate::spanned::Spanned; use crate::utils::{ - format_visibility, indent_next_line, is_empty_line, mk_sp, remove_trailing_white_spaces, - rewrite_ident, trim_left_preserve_layout, wrap_str, NodeIdExt, + filtered_str_fits, format_visibility, indent_next_line, is_empty_line, mk_sp, + remove_trailing_white_spaces, rewrite_ident, trim_left_preserve_layout, NodeIdExt, }; use crate::visitor::FmtVisitor; @@ -1241,15 +1241,14 @@ impl MacroBranch { } } }; - let new_body = wrap_str( - new_body_snippet.snippet.to_string(), - config.max_width(), - shape, - )?; + + if !filtered_str_fits(&new_body_snippet.snippet, config.max_width(), shape) { + return None; + } // Indent the body since it is in a block. let indent_str = body_indent.to_string(&config); - let mut new_body = LineClasses::new(new_body.trim_end()) + let mut new_body = LineClasses::new(new_body_snippet.snippet.trim_end()) .enumerate() .fold( (String::new(), true), diff --git a/src/utils.rs b/src/utils.rs index 58fd95c656e..0e87d6bb50e 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -384,14 +384,15 @@ macro_rules! skip_out_of_file_lines_range_visitor { // Wraps String in an Option. Returns Some when the string adheres to the // Rewrite constraints defined for the Rewrite trait and None otherwise. pub(crate) fn wrap_str(s: String, max_width: usize, shape: Shape) -> Option { - if is_valid_str(&filter_normal_code(&s), max_width, shape) { + if filtered_str_fits(&s, max_width, shape) { Some(s) } else { None } } -fn is_valid_str(snippet: &str, max_width: usize, shape: Shape) -> bool { +pub(crate) fn filtered_str_fits(snippet: &str, max_width: usize, shape: Shape) -> bool { + let snippet = &filter_normal_code(snippet); if !snippet.is_empty() { // First line must fits with `shape.width`. if first_line_width(snippet) > shape.width { -- cgit 1.4.1-3-g733a5 From c240f3a6b3f0b7f91113dc999217f40f029a2776 Mon Sep 17 00:00:00 2001 From: Tom Milligan Date: Wed, 13 Jul 2022 01:31:19 +0100 Subject: feat: add skip_macro_invocations option (#5347) * feat: add skip_macro_names option * [review] update configuration documentation * [review] fix docstring * [feat] implement wildcard macro invocation skip * commit missed files * [review] test override skip macro names * [review] skip_macro_names -> skip_macro_invocations * [review] expand doc configuration * [review] add lots more tests * [review] add use alias test examples * [review] add link to standard macro behaviour --- Configurations.md | 56 ++++++++++ src/config/config_type.rs | 7 ++ src/config/macro_names.rs | 118 +++++++++++++++++++++ src/config/mod.rs | 20 ++++ src/skip.rs | 10 +- src/test/configuration_snippet.rs | 7 +- src/visitor.rs | 13 ++- tests/source/skip_macro_invocations/all.rs | 11 ++ .../source/skip_macro_invocations/all_and_name.rs | 11 ++ tests/source/skip_macro_invocations/empty.rs | 11 ++ tests/source/skip_macro_invocations/name.rs | 11 ++ .../source/skip_macro_invocations/name_unknown.rs | 6 ++ tests/source/skip_macro_invocations/names.rs | 16 +++ .../path_qualified_invocation_mismatch.rs | 6 ++ .../skip_macro_invocations/path_qualified_match.rs | 6 ++ .../path_qualified_name_mismatch.rs | 6 ++ .../skip_macro_invocations/use_alias_examples.rs | 32 ++++++ tests/target/skip_macro_invocations/all.rs | 11 ++ .../target/skip_macro_invocations/all_and_name.rs | 11 ++ tests/target/skip_macro_invocations/empty.rs | 11 ++ tests/target/skip_macro_invocations/name.rs | 11 ++ .../target/skip_macro_invocations/name_unknown.rs | 6 ++ tests/target/skip_macro_invocations/names.rs | 16 +++ .../path_qualified_invocation_mismatch.rs | 6 ++ .../skip_macro_invocations/path_qualified_match.rs | 6 ++ .../path_qualified_name_mismatch.rs | 6 ++ .../skip_macro_invocations/use_alias_examples.rs | 32 ++++++ 27 files changed, 459 insertions(+), 4 deletions(-) create mode 100644 src/config/macro_names.rs create mode 100644 tests/source/skip_macro_invocations/all.rs create mode 100644 tests/source/skip_macro_invocations/all_and_name.rs create mode 100644 tests/source/skip_macro_invocations/empty.rs create mode 100644 tests/source/skip_macro_invocations/name.rs create mode 100644 tests/source/skip_macro_invocations/name_unknown.rs create mode 100644 tests/source/skip_macro_invocations/names.rs create mode 100644 tests/source/skip_macro_invocations/path_qualified_invocation_mismatch.rs create mode 100644 tests/source/skip_macro_invocations/path_qualified_match.rs create mode 100644 tests/source/skip_macro_invocations/path_qualified_name_mismatch.rs create mode 100644 tests/source/skip_macro_invocations/use_alias_examples.rs create mode 100644 tests/target/skip_macro_invocations/all.rs create mode 100644 tests/target/skip_macro_invocations/all_and_name.rs create mode 100644 tests/target/skip_macro_invocations/empty.rs create mode 100644 tests/target/skip_macro_invocations/name.rs create mode 100644 tests/target/skip_macro_invocations/name_unknown.rs create mode 100644 tests/target/skip_macro_invocations/names.rs create mode 100644 tests/target/skip_macro_invocations/path_qualified_invocation_mismatch.rs create mode 100644 tests/target/skip_macro_invocations/path_qualified_match.rs create mode 100644 tests/target/skip_macro_invocations/path_qualified_name_mismatch.rs create mode 100644 tests/target/skip_macro_invocations/use_alias_examples.rs (limited to 'src') diff --git a/Configurations.md b/Configurations.md index 8b96b9d3689..5579b5095af 100644 --- a/Configurations.md +++ b/Configurations.md @@ -1014,6 +1014,62 @@ macro_rules! foo { See also [`format_macro_matchers`](#format_macro_matchers). +## `skip_macro_invocations` + +Skip formatting the bodies of macro invocations with the following names. + +rustfmt will not format any macro invocation for macros with names set in this list. +Including the special value "*" will prevent any macro invocations from being formatted. + +Note: This option does not have any impact on how rustfmt formats macro definitions. + +- **Default value**: `[]` +- **Possible values**: a list of macro name idents, `["name_0", "name_1", ..., "*"]` +- **Stable**: No (tracking issue: [#5346](https://github.com/rust-lang/rustfmt/issues/5346)) + +#### `[]` (default): + +rustfmt will follow its standard approach to formatting macro invocations. + +No macro invocations will be skipped based on their name. More information about rustfmt's standard macro invocation formatting behavior can be found in [#5437](https://github.com/rust-lang/rustfmt/discussions/5437). + +```rust +lorem!( + const _: u8 = 0; +); + +ipsum!( + const _: u8 = 0; +); +``` + +#### `["lorem"]`: + +The named macro invocations will be skipped. + +```rust +lorem!( + const _: u8 = 0; +); + +ipsum!( + const _: u8 = 0; +); +``` + +#### `["*"]`: + +The special selector `*` will skip all macro invocations. + +```rust +lorem!( + const _: u8 = 0; +); + +ipsum!( + const _: u8 = 0; +); +``` ## `format_strings` diff --git a/src/config/config_type.rs b/src/config/config_type.rs index 26d57a13791..48f4d9ce80e 100644 --- a/src/config/config_type.rs +++ b/src/config/config_type.rs @@ -1,4 +1,5 @@ use crate::config::file_lines::FileLines; +use crate::config::macro_names::MacroSelectors; use crate::config::options::{IgnoreList, WidthHeuristics}; /// Trait for types that can be used in `Config`. @@ -46,6 +47,12 @@ impl ConfigType for FileLines { } } +impl ConfigType for MacroSelectors { + fn doc_hint() -> String { + String::from("[, ...]") + } +} + impl ConfigType for WidthHeuristics { fn doc_hint() -> String { String::new() diff --git a/src/config/macro_names.rs b/src/config/macro_names.rs new file mode 100644 index 00000000000..26ad78d6dca --- /dev/null +++ b/src/config/macro_names.rs @@ -0,0 +1,118 @@ +//! This module contains types and functions to support formatting specific macros. + +use itertools::Itertools; +use std::{fmt, str}; + +use serde::{Deserialize, Serialize}; +use serde_json as json; +use thiserror::Error; + +/// Defines the name of a macro. +#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd, Deserialize, Serialize)] +pub struct MacroName(String); + +impl MacroName { + pub fn new(other: String) -> Self { + Self(other) + } +} + +impl fmt::Display for MacroName { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.0.fmt(f) + } +} + +impl From for String { + fn from(other: MacroName) -> Self { + other.0 + } +} + +/// Defines a selector to match against a macro. +#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd, Deserialize, Serialize)] +pub enum MacroSelector { + Name(MacroName), + All, +} + +impl fmt::Display for MacroSelector { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Name(name) => name.fmt(f), + Self::All => write!(f, "*"), + } + } +} + +impl str::FromStr for MacroSelector { + type Err = std::convert::Infallible; + + fn from_str(s: &str) -> Result { + Ok(match s { + "*" => MacroSelector::All, + name => MacroSelector::Name(MacroName(name.to_owned())), + }) + } +} + +/// A set of macro selectors. +#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)] +pub struct MacroSelectors(pub Vec); + +impl fmt::Display for MacroSelectors { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.0.iter().format(", ")) + } +} + +#[derive(Error, Debug)] +pub enum MacroSelectorsError { + #[error("{0}")] + Json(json::Error), +} + +// This impl is needed for `Config::override_value` to work for use in tests. +impl str::FromStr for MacroSelectors { + type Err = MacroSelectorsError; + + fn from_str(s: &str) -> Result { + let raw: Vec<&str> = json::from_str(s).map_err(MacroSelectorsError::Json)?; + Ok(Self( + raw.into_iter() + .map(|raw| { + MacroSelector::from_str(raw).expect("MacroSelector from_str is infallible") + }) + .collect(), + )) + } +} + +#[cfg(test)] +mod test { + use super::*; + use std::str::FromStr; + + #[test] + fn macro_names_from_str() { + let macro_names = MacroSelectors::from_str(r#"["foo", "*", "bar"]"#).unwrap(); + assert_eq!( + macro_names, + MacroSelectors( + [ + MacroSelector::Name(MacroName("foo".to_owned())), + MacroSelector::All, + MacroSelector::Name(MacroName("bar".to_owned())) + ] + .into_iter() + .collect() + ) + ); + } + + #[test] + fn macro_names_display() { + let macro_names = MacroSelectors::from_str(r#"["foo", "*", "bar"]"#).unwrap(); + assert_eq!(format!("{}", macro_names), "foo, *, bar"); + } +} diff --git a/src/config/mod.rs b/src/config/mod.rs index eaada8db090..0c6a3cbc953 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -13,6 +13,8 @@ pub use crate::config::file_lines::{FileLines, FileName, Range}; #[allow(unreachable_pub)] pub use crate::config::lists::*; #[allow(unreachable_pub)] +pub use crate::config::macro_names::{MacroSelector, MacroSelectors}; +#[allow(unreachable_pub)] pub use crate::config::options::*; #[macro_use] @@ -22,6 +24,7 @@ pub(crate) mod options; pub(crate) mod file_lines; pub(crate) mod lists; +pub(crate) mod macro_names; // This macro defines configuration options used in rustfmt. Each option // is defined as follows: @@ -67,6 +70,8 @@ create_config! { format_macro_matchers: bool, false, false, "Format the metavariable matching patterns in macros"; format_macro_bodies: bool, true, false, "Format the bodies of macros"; + skip_macro_invocations: MacroSelectors, MacroSelectors::default(), false, + "Skip formatting the bodies of macros invoked with the following names."; hex_literal_case: HexLiteralCase, HexLiteralCase::Preserve, false, "Format hexadecimal integer literals"; @@ -403,6 +408,7 @@ mod test { use super::*; use std::str; + use crate::config::macro_names::MacroName; use rustfmt_config_proc_macro::{nightly_only_test, stable_only_test}; #[allow(dead_code)] @@ -611,6 +617,7 @@ normalize_doc_attributes = false format_strings = false format_macro_matchers = false format_macro_bodies = true +skip_macro_invocations = [] hex_literal_case = "Preserve" empty_item_single_line = true struct_lit_single_line = true @@ -1019,4 +1026,17 @@ make_backup = false ); } } + + #[test] + fn test_override_skip_macro_invocations() { + let mut config = Config::default(); + config.override_value("skip_macro_invocations", r#"["*", "println"]"#); + assert_eq!( + config.skip_macro_invocations(), + MacroSelectors(vec![ + MacroSelector::All, + MacroSelector::Name(MacroName::new("println".to_owned())) + ]) + ); + } } diff --git a/src/skip.rs b/src/skip.rs index 0fdc097efc2..8b2fd7736ae 100644 --- a/src/skip.rs +++ b/src/skip.rs @@ -7,6 +7,7 @@ use rustc_ast_pretty::pprust; /// by other context. Query this context to know if you need skip a block. #[derive(Default, Clone)] pub(crate) struct SkipContext { + pub(crate) all_macros: bool, macros: Vec, attributes: Vec, } @@ -23,8 +24,15 @@ impl SkipContext { self.attributes.append(&mut other.attributes); } + pub(crate) fn update_macros(&mut self, other: T) + where + T: IntoIterator, + { + self.macros.extend(other.into_iter()); + } + pub(crate) fn skip_macro(&self, name: &str) -> bool { - self.macros.iter().any(|n| n == name) + self.all_macros || self.macros.iter().any(|n| n == name) } pub(crate) fn skip_attribute(&self, name: &str) -> bool { diff --git a/src/test/configuration_snippet.rs b/src/test/configuration_snippet.rs index c8fda7c8556..c70b3c5facd 100644 --- a/src/test/configuration_snippet.rs +++ b/src/test/configuration_snippet.rs @@ -27,8 +27,13 @@ impl ConfigurationSection { lazy_static! { static ref CONFIG_NAME_REGEX: regex::Regex = regex::Regex::new(r"^## `([^`]+)`").expect("failed creating configuration pattern"); + // Configuration values, which will be passed to `from_str`: + // + // - must be prefixed with `####` + // - must be wrapped in backticks + // - may by wrapped in double quotes (which will be stripped) static ref CONFIG_VALUE_REGEX: regex::Regex = - regex::Regex::new(r#"^#### `"?([^`"]+)"?`"#) + regex::Regex::new(r#"^#### `"?([^`]+?)"?`"#) .expect("failed creating configuration value pattern"); } diff --git a/src/visitor.rs b/src/visitor.rs index 9a0e0752c12..b93153de154 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -8,7 +8,7 @@ use rustc_span::{symbol, BytePos, Pos, Span}; use crate::attr::*; use crate::comment::{contains_comment, rewrite_comment, CodeCharKind, CommentCodeSlices}; use crate::config::Version; -use crate::config::{BraceStyle, Config}; +use crate::config::{BraceStyle, Config, MacroSelector}; use crate::coverage::transform_missing_snippet; use crate::items::{ format_impl, format_trait, format_trait_alias, is_mod_decl, is_use_item, rewrite_extern_crate, @@ -770,6 +770,15 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { snippet_provider: &'a SnippetProvider, report: FormatReport, ) -> FmtVisitor<'a> { + let mut skip_context = SkipContext::default(); + let mut macro_names = Vec::new(); + for macro_selector in config.skip_macro_invocations().0 { + match macro_selector { + MacroSelector::Name(name) => macro_names.push(name.to_string()), + MacroSelector::All => skip_context.all_macros = true, + } + } + skip_context.update_macros(macro_names); FmtVisitor { parent_context: None, parse_sess: parse_session, @@ -784,7 +793,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { is_macro_def: false, macro_rewrite_failure: false, report, - skip_context: Default::default(), + skip_context, } } diff --git a/tests/source/skip_macro_invocations/all.rs b/tests/source/skip_macro_invocations/all.rs new file mode 100644 index 00000000000..d0437ee10fd --- /dev/null +++ b/tests/source/skip_macro_invocations/all.rs @@ -0,0 +1,11 @@ +// rustfmt-skip_macro_invocations: ["*"] + +// Should skip this invocation +items!( + const _: u8 = 0; +); + +// Should skip this invocation +renamed_items!( + const _: u8 = 0; +); diff --git a/tests/source/skip_macro_invocations/all_and_name.rs b/tests/source/skip_macro_invocations/all_and_name.rs new file mode 100644 index 00000000000..1f6722344fe --- /dev/null +++ b/tests/source/skip_macro_invocations/all_and_name.rs @@ -0,0 +1,11 @@ +// rustfmt-skip_macro_invocations: ["*","items"] + +// Should skip this invocation +items!( + const _: u8 = 0; +); + +// Should also skip this invocation, as the wildcard covers it +renamed_items!( + const _: u8 = 0; +); diff --git a/tests/source/skip_macro_invocations/empty.rs b/tests/source/skip_macro_invocations/empty.rs new file mode 100644 index 00000000000..f3dd89dc4db --- /dev/null +++ b/tests/source/skip_macro_invocations/empty.rs @@ -0,0 +1,11 @@ +// rustfmt-skip_macro_invocations: [] + +// Should not skip this invocation +items!( + const _: u8 = 0; +); + +// Should not skip this invocation +renamed_items!( + const _: u8 = 0; +); diff --git a/tests/source/skip_macro_invocations/name.rs b/tests/source/skip_macro_invocations/name.rs new file mode 100644 index 00000000000..7fa5d3a6f71 --- /dev/null +++ b/tests/source/skip_macro_invocations/name.rs @@ -0,0 +1,11 @@ +// rustfmt-skip_macro_invocations: ["items"] + +// Should skip this invocation +items!( + const _: u8 = 0; +); + +// Should not skip this invocation +renamed_items!( + const _: u8 = 0; +); diff --git a/tests/source/skip_macro_invocations/name_unknown.rs b/tests/source/skip_macro_invocations/name_unknown.rs new file mode 100644 index 00000000000..d5669532524 --- /dev/null +++ b/tests/source/skip_macro_invocations/name_unknown.rs @@ -0,0 +1,6 @@ +// rustfmt-skip_macro_invocations: ["unknown"] + +// Should not skip this invocation +items!( + const _: u8 = 0; +); diff --git a/tests/source/skip_macro_invocations/names.rs b/tests/source/skip_macro_invocations/names.rs new file mode 100644 index 00000000000..a920381a455 --- /dev/null +++ b/tests/source/skip_macro_invocations/names.rs @@ -0,0 +1,16 @@ +// rustfmt-skip_macro_invocations: ["foo","bar"] + +// Should skip this invocation +foo!( + const _: u8 = 0; +); + +// Should skip this invocation +bar!( + const _: u8 = 0; +); + +// Should not skip this invocation +baz!( + const _: u8 = 0; +); diff --git a/tests/source/skip_macro_invocations/path_qualified_invocation_mismatch.rs b/tests/source/skip_macro_invocations/path_qualified_invocation_mismatch.rs new file mode 100644 index 00000000000..61296869a50 --- /dev/null +++ b/tests/source/skip_macro_invocations/path_qualified_invocation_mismatch.rs @@ -0,0 +1,6 @@ +// rustfmt-skip_macro_invocations: ["items"] + +// Should not skip this invocation +self::items!( + const _: u8 = 0; +); diff --git a/tests/source/skip_macro_invocations/path_qualified_match.rs b/tests/source/skip_macro_invocations/path_qualified_match.rs new file mode 100644 index 00000000000..9398918a9e1 --- /dev/null +++ b/tests/source/skip_macro_invocations/path_qualified_match.rs @@ -0,0 +1,6 @@ +// rustfmt-skip_macro_invocations: ["self::items"] + +// Should skip this invocation +self::items!( + const _: u8 = 0; +); diff --git a/tests/source/skip_macro_invocations/path_qualified_name_mismatch.rs b/tests/source/skip_macro_invocations/path_qualified_name_mismatch.rs new file mode 100644 index 00000000000..4e3eb542dbe --- /dev/null +++ b/tests/source/skip_macro_invocations/path_qualified_name_mismatch.rs @@ -0,0 +1,6 @@ +// rustfmt-skip_macro_invocations: ["self::items"] + +// Should not skip this invocation +items!( + const _: u8 = 0; +); diff --git a/tests/source/skip_macro_invocations/use_alias_examples.rs b/tests/source/skip_macro_invocations/use_alias_examples.rs new file mode 100644 index 00000000000..43cb8015de5 --- /dev/null +++ b/tests/source/skip_macro_invocations/use_alias_examples.rs @@ -0,0 +1,32 @@ +// rustfmt-skip_macro_invocations: ["aaa","ccc"] + +// These tests demonstrate a realistic use case with use aliases. +// The use statements should not impact functionality in any way. + +use crate::{aaa, bbb, ddd}; + +// No use alias, invocation in list +// Should skip this invocation +aaa!( + const _: u8 = 0; +); + +// Use alias, invocation in list +// Should skip this invocation +use crate::bbb as ccc; +ccc!( + const _: u8 = 0; +); + +// Use alias, invocation not in list +// Should not skip this invocation +use crate::ddd as eee; +eee!( + const _: u8 = 0; +); + +// No use alias, invocation not in list +// Should not skip this invocation +fff!( + const _: u8 = 0; +); diff --git a/tests/target/skip_macro_invocations/all.rs b/tests/target/skip_macro_invocations/all.rs new file mode 100644 index 00000000000..d0437ee10fd --- /dev/null +++ b/tests/target/skip_macro_invocations/all.rs @@ -0,0 +1,11 @@ +// rustfmt-skip_macro_invocations: ["*"] + +// Should skip this invocation +items!( + const _: u8 = 0; +); + +// Should skip this invocation +renamed_items!( + const _: u8 = 0; +); diff --git a/tests/target/skip_macro_invocations/all_and_name.rs b/tests/target/skip_macro_invocations/all_and_name.rs new file mode 100644 index 00000000000..1f6722344fe --- /dev/null +++ b/tests/target/skip_macro_invocations/all_and_name.rs @@ -0,0 +1,11 @@ +// rustfmt-skip_macro_invocations: ["*","items"] + +// Should skip this invocation +items!( + const _: u8 = 0; +); + +// Should also skip this invocation, as the wildcard covers it +renamed_items!( + const _: u8 = 0; +); diff --git a/tests/target/skip_macro_invocations/empty.rs b/tests/target/skip_macro_invocations/empty.rs new file mode 100644 index 00000000000..4a398cc59c6 --- /dev/null +++ b/tests/target/skip_macro_invocations/empty.rs @@ -0,0 +1,11 @@ +// rustfmt-skip_macro_invocations: [] + +// Should not skip this invocation +items!( + const _: u8 = 0; +); + +// Should not skip this invocation +renamed_items!( + const _: u8 = 0; +); diff --git a/tests/target/skip_macro_invocations/name.rs b/tests/target/skip_macro_invocations/name.rs new file mode 100644 index 00000000000..c4d577269c6 --- /dev/null +++ b/tests/target/skip_macro_invocations/name.rs @@ -0,0 +1,11 @@ +// rustfmt-skip_macro_invocations: ["items"] + +// Should skip this invocation +items!( + const _: u8 = 0; +); + +// Should not skip this invocation +renamed_items!( + const _: u8 = 0; +); diff --git a/tests/target/skip_macro_invocations/name_unknown.rs b/tests/target/skip_macro_invocations/name_unknown.rs new file mode 100644 index 00000000000..7ab1440395c --- /dev/null +++ b/tests/target/skip_macro_invocations/name_unknown.rs @@ -0,0 +1,6 @@ +// rustfmt-skip_macro_invocations: ["unknown"] + +// Should not skip this invocation +items!( + const _: u8 = 0; +); diff --git a/tests/target/skip_macro_invocations/names.rs b/tests/target/skip_macro_invocations/names.rs new file mode 100644 index 00000000000..c6b41ff93d7 --- /dev/null +++ b/tests/target/skip_macro_invocations/names.rs @@ -0,0 +1,16 @@ +// rustfmt-skip_macro_invocations: ["foo","bar"] + +// Should skip this invocation +foo!( + const _: u8 = 0; +); + +// Should skip this invocation +bar!( + const _: u8 = 0; +); + +// Should not skip this invocation +baz!( + const _: u8 = 0; +); diff --git a/tests/target/skip_macro_invocations/path_qualified_invocation_mismatch.rs b/tests/target/skip_macro_invocations/path_qualified_invocation_mismatch.rs new file mode 100644 index 00000000000..6e372c72695 --- /dev/null +++ b/tests/target/skip_macro_invocations/path_qualified_invocation_mismatch.rs @@ -0,0 +1,6 @@ +// rustfmt-skip_macro_invocations: ["items"] + +// Should not skip this invocation +self::items!( + const _: u8 = 0; +); diff --git a/tests/target/skip_macro_invocations/path_qualified_match.rs b/tests/target/skip_macro_invocations/path_qualified_match.rs new file mode 100644 index 00000000000..9398918a9e1 --- /dev/null +++ b/tests/target/skip_macro_invocations/path_qualified_match.rs @@ -0,0 +1,6 @@ +// rustfmt-skip_macro_invocations: ["self::items"] + +// Should skip this invocation +self::items!( + const _: u8 = 0; +); diff --git a/tests/target/skip_macro_invocations/path_qualified_name_mismatch.rs b/tests/target/skip_macro_invocations/path_qualified_name_mismatch.rs new file mode 100644 index 00000000000..aa57a2a655c --- /dev/null +++ b/tests/target/skip_macro_invocations/path_qualified_name_mismatch.rs @@ -0,0 +1,6 @@ +// rustfmt-skip_macro_invocations: ["self::items"] + +// Should not skip this invocation +items!( + const _: u8 = 0; +); diff --git a/tests/target/skip_macro_invocations/use_alias_examples.rs b/tests/target/skip_macro_invocations/use_alias_examples.rs new file mode 100644 index 00000000000..799dd8c08af --- /dev/null +++ b/tests/target/skip_macro_invocations/use_alias_examples.rs @@ -0,0 +1,32 @@ +// rustfmt-skip_macro_invocations: ["aaa","ccc"] + +// These tests demonstrate a realistic use case with use aliases. +// The use statements should not impact functionality in any way. + +use crate::{aaa, bbb, ddd}; + +// No use alias, invocation in list +// Should skip this invocation +aaa!( + const _: u8 = 0; +); + +// Use alias, invocation in list +// Should skip this invocation +use crate::bbb as ccc; +ccc!( + const _: u8 = 0; +); + +// Use alias, invocation not in list +// Should not skip this invocation +use crate::ddd as eee; +eee!( + const _: u8 = 0; +); + +// No use alias, invocation not in list +// Should not skip this invocation +fff!( + const _: u8 = 0; +); -- cgit 1.4.1-3-g733a5 From 0cb294f05c421d6b6ef266e3ec01c2d8739194b3 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Wed, 15 Jun 2022 22:43:51 -0400 Subject: Deprecate and Rename `fn_args_layout` -> `fn_params_layout` fn_args_layout is now deprecated. This option was renamed to better communicate that it affects the layout of parameters in function signatures and not the layout of arguments in function calls. Because the `fn_args_layout` is a stable option the renamed option is also stable, however users who set `fn_args_layout` will get a warning message letting them know that the option has been renamed. --- Configurations.md | 116 ++++++++++++++++++++- src/config/config_type.rs | 25 ++++- src/config/mod.rs | 13 ++- src/items.rs | 2 +- tests/config/small_tabs.toml | 2 +- tests/source/configs/fn_args_layout/compressed.rs | 16 --- tests/source/configs/fn_args_layout/tall.rs | 16 --- tests/source/configs/fn_args_layout/vertical.rs | 16 --- .../source/configs/fn_params_layout/compressed.rs | 16 +++ tests/source/configs/fn_params_layout/tall.rs | 16 +++ tests/source/configs/fn_params_layout/vertical.rs | 16 +++ tests/source/fn-custom-7.rs | 2 +- tests/source/fn-custom.rs | 2 +- tests/source/fn_args_layout-vertical.rs | 2 +- tests/target/configs/fn_args_layout/compressed.rs | 22 ---- tests/target/configs/fn_args_layout/tall.rs | 32 ------ tests/target/configs/fn_args_layout/vertical.rs | 42 -------- .../target/configs/fn_params_layout/compressed.rs | 22 ++++ tests/target/configs/fn_params_layout/tall.rs | 32 ++++++ tests/target/configs/fn_params_layout/vertical.rs | 42 ++++++++ tests/target/fn-custom-7.rs | 2 +- tests/target/fn-custom.rs | 2 +- tests/target/fn_args_layout-vertical.rs | 2 +- tests/target/issue-4791/issue_4928.rs | 2 +- 24 files changed, 302 insertions(+), 158 deletions(-) delete mode 100644 tests/source/configs/fn_args_layout/compressed.rs delete mode 100644 tests/source/configs/fn_args_layout/tall.rs delete mode 100644 tests/source/configs/fn_args_layout/vertical.rs create mode 100644 tests/source/configs/fn_params_layout/compressed.rs create mode 100644 tests/source/configs/fn_params_layout/tall.rs create mode 100644 tests/source/configs/fn_params_layout/vertical.rs delete mode 100644 tests/target/configs/fn_args_layout/compressed.rs delete mode 100644 tests/target/configs/fn_args_layout/tall.rs delete mode 100644 tests/target/configs/fn_args_layout/vertical.rs create mode 100644 tests/target/configs/fn_params_layout/compressed.rs create mode 100644 tests/target/configs/fn_params_layout/tall.rs create mode 100644 tests/target/configs/fn_params_layout/vertical.rs (limited to 'src') diff --git a/Configurations.md b/Configurations.md index 5579b5095af..17eabd48759 100644 --- a/Configurations.md +++ b/Configurations.md @@ -645,7 +645,8 @@ trailing whitespaces. ## `fn_args_layout` -Control the layout of arguments in a function +This option is deprecated and has been renamed to `fn_params_layout` to better communicate that +it affects the layout of parameters in function signatures. - **Default value**: `"Tall"` - **Possible values**: `"Compressed"`, `"Tall"`, `"Vertical"` @@ -753,6 +754,8 @@ trait Lorem { } ``` +See also [`fn_params_layout`](#fn_params_layout) + ## `fn_call_width` Maximum width of the args of a function call before falling back to vertical formatting. @@ -765,6 +768,117 @@ By default this option is set as a percentage of [`max_width`](#max_width) provi See also [`max_width`](#max_width) and [`use_small_heuristics`](#use_small_heuristics) +## `fn_params_layout` + +Control the layout of parameters in function signatures. + +- **Default value**: `"Tall"` +- **Possible values**: `"Compressed"`, `"Tall"`, `"Vertical"` +- **Stable**: Yes + +#### `"Tall"` (default): + +```rust +trait Lorem { + fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet); + + fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet) { + // body + } + + fn lorem( + ipsum: Ipsum, + dolor: Dolor, + sit: Sit, + amet: Amet, + consectetur: Consectetur, + adipiscing: Adipiscing, + elit: Elit, + ); + + fn lorem( + ipsum: Ipsum, + dolor: Dolor, + sit: Sit, + amet: Amet, + consectetur: Consectetur, + adipiscing: Adipiscing, + elit: Elit, + ) { + // body + } +} +``` + +#### `"Compressed"`: + +```rust +trait Lorem { + fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet); + + fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet) { + // body + } + + fn lorem( + ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet, consectetur: Consectetur, + adipiscing: Adipiscing, elit: Elit, + ); + + fn lorem( + ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet, consectetur: Consectetur, + adipiscing: Adipiscing, elit: Elit, + ) { + // body + } +} +``` + +#### `"Vertical"`: + +```rust +trait Lorem { + fn lorem( + ipsum: Ipsum, + dolor: Dolor, + sit: Sit, + amet: Amet, + ); + + fn lorem( + ipsum: Ipsum, + dolor: Dolor, + sit: Sit, + amet: Amet, + ) { + // body + } + + fn lorem( + ipsum: Ipsum, + dolor: Dolor, + sit: Sit, + amet: Amet, + consectetur: Consectetur, + adipiscing: Adipiscing, + elit: Elit, + ); + + fn lorem( + ipsum: Ipsum, + dolor: Dolor, + sit: Sit, + amet: Amet, + consectetur: Consectetur, + adipiscing: Adipiscing, + elit: Elit, + ) { + // body + } +} +``` + + ## `fn_single_line` Put single-expression functions on a single line diff --git a/src/config/config_type.rs b/src/config/config_type.rs index 48f4d9ce80e..90a67e12c5a 100644 --- a/src/config/config_type.rs +++ b/src/config/config_type.rs @@ -127,6 +127,7 @@ macro_rules! create_config { | "array_width" | "chain_width" => self.0.set_heuristics(), "merge_imports" => self.0.set_merge_imports(), + "fn_args_layout" => self.0.set_fn_args_layout(), &_ => (), } } @@ -181,6 +182,7 @@ macro_rules! create_config { self.set_heuristics(); self.set_ignore(dir); self.set_merge_imports(); + self.set_fn_args_layout(); self } @@ -273,14 +275,21 @@ macro_rules! create_config { | "array_width" | "chain_width" => self.set_heuristics(), "merge_imports" => self.set_merge_imports(), + "fn_args_layout" => self.set_fn_args_layout(), &_ => (), } } #[allow(unreachable_pub)] pub fn is_hidden_option(name: &str) -> bool { - const HIDE_OPTIONS: [&str; 5] = - ["verbose", "verbose_diff", "file_lines", "width_heuristics", "merge_imports"]; + const HIDE_OPTIONS: [&str; 6] = [ + "verbose", + "verbose_diff", + "file_lines", + "width_heuristics", + "merge_imports", + "fn_args_layout" + ]; HIDE_OPTIONS.contains(&name) } @@ -430,6 +439,18 @@ macro_rules! create_config { } } + fn set_fn_args_layout(&mut self) { + if self.was_set().fn_args_layout() { + eprintln!( + "Warning: the `fn_args_layout` option is deprecated. \ + Use `fn_params_layout`. instead" + ); + if !self.was_set().fn_params_layout() { + self.fn_params_layout.2 = self.fn_args_layout(); + } + } + } + #[allow(unreachable_pub)] /// Returns `true` if the config key was explicitly set and is the default value. pub fn is_default(&self, key: &str) -> bool { diff --git a/src/config/mod.rs b/src/config/mod.rs index 0c6a3cbc953..5492519f389 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -124,7 +124,9 @@ create_config! { force_multiline_blocks: bool, false, false, "Force multiline closure bodies and match arms to be wrapped in a block"; fn_args_layout: Density, Density::Tall, true, - "Control the layout of arguments in a function"; + "(deprecated: use fn_params_layout instead)"; + fn_params_layout: Density, Density::Tall, true, + "Control the layout of parameters in function signatures."; brace_style: BraceStyle, BraceStyle::SameLineWhere, false, "Brace style for items"; control_brace_style: ControlBraceStyle, ControlBraceStyle::AlwaysSameLine, false, "Brace style for control flow constructs"; @@ -196,6 +198,7 @@ impl PartialConfig { cloned.width_heuristics = None; cloned.print_misformatted_file_names = None; cloned.merge_imports = None; + cloned.fn_args_layout = None; ::toml::to_string(&cloned).map_err(ToTomlError) } @@ -442,6 +445,12 @@ mod test { "Merge imports"; merge_imports: bool, false, false, "(deprecated: use imports_granularity instead)"; + // fn_args_layout renamed to fn_params_layout + fn_args_layout: Density, Density::Tall, true, + "(deprecated: use fn_params_layout instead)"; + fn_params_layout: Density, Density::Tall, true, + "Control the layout of parameters in a function signatures."; + // Width Heuristics use_small_heuristics: Heuristics, Heuristics::Default, true, "Whether to use different formatting for items and \ @@ -644,7 +653,7 @@ enum_discrim_align_threshold = 0 match_arm_blocks = true match_arm_leading_pipes = "Never" force_multiline_blocks = false -fn_args_layout = "Tall" +fn_params_layout = "Tall" brace_style = "SameLineWhere" control_brace_style = "AlwaysSameLine" trailing_semicolon = true diff --git a/src/items.rs b/src/items.rs index bab881f4b4e..6ab02e7f923 100644 --- a/src/items.rs +++ b/src/items.rs @@ -2602,7 +2602,7 @@ fn rewrite_params( ¶m_items, context .config - .fn_args_layout() + .fn_params_layout() .to_list_tactic(param_items.len()), Separator::Comma, one_line_budget, diff --git a/tests/config/small_tabs.toml b/tests/config/small_tabs.toml index c3cfd34317a..4c37100894f 100644 --- a/tests/config/small_tabs.toml +++ b/tests/config/small_tabs.toml @@ -3,7 +3,7 @@ comment_width = 80 tab_spaces = 2 newline_style = "Unix" brace_style = "SameLineWhere" -fn_args_layout = "Tall" +fn_params_layout = "Tall" trailing_comma = "Vertical" indent_style = "Block" reorder_imports = false diff --git a/tests/source/configs/fn_args_layout/compressed.rs b/tests/source/configs/fn_args_layout/compressed.rs deleted file mode 100644 index 66a371c259f..00000000000 --- a/tests/source/configs/fn_args_layout/compressed.rs +++ /dev/null @@ -1,16 +0,0 @@ -// rustfmt-fn_args_layout: Compressed -// Function arguments density - -trait Lorem { - fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet); - - fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet) { - // body - } - - fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet, consectetur: onsectetur, adipiscing: Adipiscing, elit: Elit); - - fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet, consectetur: onsectetur, adipiscing: Adipiscing, elit: Elit) { - // body - } -} diff --git a/tests/source/configs/fn_args_layout/tall.rs b/tests/source/configs/fn_args_layout/tall.rs deleted file mode 100644 index f11e86fd313..00000000000 --- a/tests/source/configs/fn_args_layout/tall.rs +++ /dev/null @@ -1,16 +0,0 @@ -// rustfmt-fn_args_layout: Tall -// Function arguments density - -trait Lorem { - fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet); - - fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet) { - // body - } - - fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet, consectetur: onsectetur, adipiscing: Adipiscing, elit: Elit); - - fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet, consectetur: onsectetur, adipiscing: Adipiscing, elit: Elit) { - // body - } -} diff --git a/tests/source/configs/fn_args_layout/vertical.rs b/tests/source/configs/fn_args_layout/vertical.rs deleted file mode 100644 index a23cc025225..00000000000 --- a/tests/source/configs/fn_args_layout/vertical.rs +++ /dev/null @@ -1,16 +0,0 @@ -// rustfmt-fn_args_layout: Vertical -// Function arguments density - -trait Lorem { - fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet); - - fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet) { - // body - } - - fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet, consectetur: onsectetur, adipiscing: Adipiscing, elit: Elit); - - fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet, consectetur: onsectetur, adipiscing: Adipiscing, elit: Elit) { - // body - } -} diff --git a/tests/source/configs/fn_params_layout/compressed.rs b/tests/source/configs/fn_params_layout/compressed.rs new file mode 100644 index 00000000000..eb573d3121f --- /dev/null +++ b/tests/source/configs/fn_params_layout/compressed.rs @@ -0,0 +1,16 @@ +// rustfmt-fn_params_layout: Compressed +// Function arguments density + +trait Lorem { + fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet); + + fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet) { + // body + } + + fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet, consectetur: onsectetur, adipiscing: Adipiscing, elit: Elit); + + fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet, consectetur: onsectetur, adipiscing: Adipiscing, elit: Elit) { + // body + } +} diff --git a/tests/source/configs/fn_params_layout/tall.rs b/tests/source/configs/fn_params_layout/tall.rs new file mode 100644 index 00000000000..4be34f0fe4a --- /dev/null +++ b/tests/source/configs/fn_params_layout/tall.rs @@ -0,0 +1,16 @@ +// rustfmt-fn_params_layout: Tall +// Function arguments density + +trait Lorem { + fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet); + + fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet) { + // body + } + + fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet, consectetur: onsectetur, adipiscing: Adipiscing, elit: Elit); + + fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet, consectetur: onsectetur, adipiscing: Adipiscing, elit: Elit) { + // body + } +} diff --git a/tests/source/configs/fn_params_layout/vertical.rs b/tests/source/configs/fn_params_layout/vertical.rs new file mode 100644 index 00000000000..674968023f9 --- /dev/null +++ b/tests/source/configs/fn_params_layout/vertical.rs @@ -0,0 +1,16 @@ +// rustfmt-fn_params_layout: Vertical +// Function arguments density + +trait Lorem { + fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet); + + fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet) { + // body + } + + fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet, consectetur: onsectetur, adipiscing: Adipiscing, elit: Elit); + + fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet, consectetur: onsectetur, adipiscing: Adipiscing, elit: Elit) { + // body + } +} diff --git a/tests/source/fn-custom-7.rs b/tests/source/fn-custom-7.rs index d5330196bf7..3ecd8701727 100644 --- a/tests/source/fn-custom-7.rs +++ b/tests/source/fn-custom-7.rs @@ -1,5 +1,5 @@ // rustfmt-normalize_comments: true -// rustfmt-fn_args_layout: Vertical +// rustfmt-fn_params_layout: Vertical // rustfmt-brace_style: AlwaysNextLine // Case with only one variable. diff --git a/tests/source/fn-custom.rs b/tests/source/fn-custom.rs index 77ced4c5e0e..64ef0ecfaae 100644 --- a/tests/source/fn-custom.rs +++ b/tests/source/fn-custom.rs @@ -1,4 +1,4 @@ -// rustfmt-fn_args_layout: Compressed +// rustfmt-fn_params_layout: Compressed // Test some of the ways function signatures can be customised. // Test compressed layout of args. diff --git a/tests/source/fn_args_layout-vertical.rs b/tests/source/fn_args_layout-vertical.rs index 759bc83d015..fd6e3f0442e 100644 --- a/tests/source/fn_args_layout-vertical.rs +++ b/tests/source/fn_args_layout-vertical.rs @@ -1,4 +1,4 @@ -// rustfmt-fn_args_layout: Vertical +// rustfmt-fn_params_layout: Vertical // Empty list should stay on one line. fn do_bar( diff --git a/tests/target/configs/fn_args_layout/compressed.rs b/tests/target/configs/fn_args_layout/compressed.rs deleted file mode 100644 index f189446e25d..00000000000 --- a/tests/target/configs/fn_args_layout/compressed.rs +++ /dev/null @@ -1,22 +0,0 @@ -// rustfmt-fn_args_layout: Compressed -// Function arguments density - -trait Lorem { - fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet); - - fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet) { - // body - } - - fn lorem( - ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet, consectetur: onsectetur, - adipiscing: Adipiscing, elit: Elit, - ); - - fn lorem( - ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet, consectetur: onsectetur, - adipiscing: Adipiscing, elit: Elit, - ) { - // body - } -} diff --git a/tests/target/configs/fn_args_layout/tall.rs b/tests/target/configs/fn_args_layout/tall.rs deleted file mode 100644 index 20f308973ac..00000000000 --- a/tests/target/configs/fn_args_layout/tall.rs +++ /dev/null @@ -1,32 +0,0 @@ -// rustfmt-fn_args_layout: Tall -// Function arguments density - -trait Lorem { - fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet); - - fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet) { - // body - } - - fn lorem( - ipsum: Ipsum, - dolor: Dolor, - sit: Sit, - amet: Amet, - consectetur: onsectetur, - adipiscing: Adipiscing, - elit: Elit, - ); - - fn lorem( - ipsum: Ipsum, - dolor: Dolor, - sit: Sit, - amet: Amet, - consectetur: onsectetur, - adipiscing: Adipiscing, - elit: Elit, - ) { - // body - } -} diff --git a/tests/target/configs/fn_args_layout/vertical.rs b/tests/target/configs/fn_args_layout/vertical.rs deleted file mode 100644 index 6c695a75df9..00000000000 --- a/tests/target/configs/fn_args_layout/vertical.rs +++ /dev/null @@ -1,42 +0,0 @@ -// rustfmt-fn_args_layout: Vertical -// Function arguments density - -trait Lorem { - fn lorem( - ipsum: Ipsum, - dolor: Dolor, - sit: Sit, - amet: Amet, - ); - - fn lorem( - ipsum: Ipsum, - dolor: Dolor, - sit: Sit, - amet: Amet, - ) { - // body - } - - fn lorem( - ipsum: Ipsum, - dolor: Dolor, - sit: Sit, - amet: Amet, - consectetur: onsectetur, - adipiscing: Adipiscing, - elit: Elit, - ); - - fn lorem( - ipsum: Ipsum, - dolor: Dolor, - sit: Sit, - amet: Amet, - consectetur: onsectetur, - adipiscing: Adipiscing, - elit: Elit, - ) { - // body - } -} diff --git a/tests/target/configs/fn_params_layout/compressed.rs b/tests/target/configs/fn_params_layout/compressed.rs new file mode 100644 index 00000000000..ff32f0f1d58 --- /dev/null +++ b/tests/target/configs/fn_params_layout/compressed.rs @@ -0,0 +1,22 @@ +// rustfmt-fn_params_layout: Compressed +// Function arguments density + +trait Lorem { + fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet); + + fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet) { + // body + } + + fn lorem( + ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet, consectetur: onsectetur, + adipiscing: Adipiscing, elit: Elit, + ); + + fn lorem( + ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet, consectetur: onsectetur, + adipiscing: Adipiscing, elit: Elit, + ) { + // body + } +} diff --git a/tests/target/configs/fn_params_layout/tall.rs b/tests/target/configs/fn_params_layout/tall.rs new file mode 100644 index 00000000000..25a86799af0 --- /dev/null +++ b/tests/target/configs/fn_params_layout/tall.rs @@ -0,0 +1,32 @@ +// rustfmt-fn_params_layout: Tall +// Function arguments density + +trait Lorem { + fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet); + + fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet) { + // body + } + + fn lorem( + ipsum: Ipsum, + dolor: Dolor, + sit: Sit, + amet: Amet, + consectetur: onsectetur, + adipiscing: Adipiscing, + elit: Elit, + ); + + fn lorem( + ipsum: Ipsum, + dolor: Dolor, + sit: Sit, + amet: Amet, + consectetur: onsectetur, + adipiscing: Adipiscing, + elit: Elit, + ) { + // body + } +} diff --git a/tests/target/configs/fn_params_layout/vertical.rs b/tests/target/configs/fn_params_layout/vertical.rs new file mode 100644 index 00000000000..7a0e42415f3 --- /dev/null +++ b/tests/target/configs/fn_params_layout/vertical.rs @@ -0,0 +1,42 @@ +// rustfmt-fn_params_layout: Vertical +// Function arguments density + +trait Lorem { + fn lorem( + ipsum: Ipsum, + dolor: Dolor, + sit: Sit, + amet: Amet, + ); + + fn lorem( + ipsum: Ipsum, + dolor: Dolor, + sit: Sit, + amet: Amet, + ) { + // body + } + + fn lorem( + ipsum: Ipsum, + dolor: Dolor, + sit: Sit, + amet: Amet, + consectetur: onsectetur, + adipiscing: Adipiscing, + elit: Elit, + ); + + fn lorem( + ipsum: Ipsum, + dolor: Dolor, + sit: Sit, + amet: Amet, + consectetur: onsectetur, + adipiscing: Adipiscing, + elit: Elit, + ) { + // body + } +} diff --git a/tests/target/fn-custom-7.rs b/tests/target/fn-custom-7.rs index 2c20ac5a752..f6a1a90c3fc 100644 --- a/tests/target/fn-custom-7.rs +++ b/tests/target/fn-custom-7.rs @@ -1,5 +1,5 @@ // rustfmt-normalize_comments: true -// rustfmt-fn_args_layout: Vertical +// rustfmt-fn_params_layout: Vertical // rustfmt-brace_style: AlwaysNextLine // Case with only one variable. diff --git a/tests/target/fn-custom.rs b/tests/target/fn-custom.rs index 2eb2a973d24..506d9de3437 100644 --- a/tests/target/fn-custom.rs +++ b/tests/target/fn-custom.rs @@ -1,4 +1,4 @@ -// rustfmt-fn_args_layout: Compressed +// rustfmt-fn_params_layout: Compressed // Test some of the ways function signatures can be customised. // Test compressed layout of args. diff --git a/tests/target/fn_args_layout-vertical.rs b/tests/target/fn_args_layout-vertical.rs index da0ac981d87..bfeca15c967 100644 --- a/tests/target/fn_args_layout-vertical.rs +++ b/tests/target/fn_args_layout-vertical.rs @@ -1,4 +1,4 @@ -// rustfmt-fn_args_layout: Vertical +// rustfmt-fn_params_layout: Vertical // Empty list should stay on one line. fn do_bar() -> u8 { diff --git a/tests/target/issue-4791/issue_4928.rs b/tests/target/issue-4791/issue_4928.rs index 588656b535f..29f6bda9063 100644 --- a/tests/target/issue-4791/issue_4928.rs +++ b/tests/target/issue-4791/issue_4928.rs @@ -1,7 +1,7 @@ // rustfmt-brace_style: SameLineWhere // rustfmt-comment_width: 100 // rustfmt-edition: 2018 -// rustfmt-fn_args_layout: Compressed +// rustfmt-fn_params_layout: Compressed // rustfmt-hard_tabs: false // rustfmt-match_block_trailing_comma: true // rustfmt-max_width: 100 -- cgit 1.4.1-3-g733a5 From 85fdf8ecec5551e79dc5ac3a8babaf514a58ef86 Mon Sep 17 00:00:00 2001 From: Urgau Date: Sun, 17 Jul 2022 14:18:57 +0200 Subject: Remove useless conditional compilation - 2 --- src/test/mod.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'src') diff --git a/src/test/mod.rs b/src/test/mod.rs index 6b5bc2b30dd..cfad4a8ed0e 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -982,11 +982,7 @@ fn rustfmt() -> PathBuf { assert!( me.is_file() || me.with_extension("exe").is_file(), "{}", - if cfg!(release) { - "no rustfmt bin, try running `cargo build --release` before testing" - } else { - "no rustfmt bin, try running `cargo build` before testing" - } + "no rustfmt bin, try running `cargo build` or `cargo build --release` before testing" ); me } -- cgit 1.4.1-3-g733a5 From a7bf0090347d8523dd62c0508a4c8413cdba099a Mon Sep 17 00:00:00 2001 From: Jorge Martin Juarez <50276574+jmj0502@users.noreply.github.com> Date: Sun, 17 Jul 2022 21:39:25 -0400 Subject: Fix/comments inside trait generics gets duplicated (#5446) * Bugfix: Now slash/start comments aren't duplicated on trait parameters. * Removing unnecesary comment. * Improvements: Improving the BytePos offset. * Improvements: Improving the description of the test cases. --- src/items.rs | 6 +++++- tests/target/issue-5358.rs | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 tests/target/issue-5358.rs (limited to 'src') diff --git a/src/items.rs b/src/items.rs index 6ab02e7f923..a76e88b77d4 100644 --- a/src/items.rs +++ b/src/items.rs @@ -1084,7 +1084,11 @@ pub(crate) fn format_trait( let item_snippet = context.snippet(item.span); if let Some(lo) = item_snippet.find('/') { // 1 = `{` - let comment_hi = body_lo - BytePos(1); + let comment_hi = if generics.params.len() > 0 { + generics.span.lo() - BytePos(1) + } else { + body_lo - BytePos(1) + }; let comment_lo = item.span.lo() + BytePos(lo as u32); if comment_lo < comment_hi { match recover_missing_comment_in_span( diff --git a/tests/target/issue-5358.rs b/tests/target/issue-5358.rs new file mode 100644 index 00000000000..d4bf4909ad7 --- /dev/null +++ b/tests/target/issue-5358.rs @@ -0,0 +1,4 @@ +// Test /* comment */ inside trait generics does not get duplicated. +trait Test {} + +trait TestTwo {} -- cgit 1.4.1-3-g733a5 From 7cc126180f8340071741586c9b455b88b920b116 Mon Sep 17 00:00:00 2001 From: Tom Milligan Date: Wed, 20 Jul 2022 07:46:49 +0100 Subject: feat: nicer skip context for macro/attribute --- src/attr.rs | 4 ++-- src/macros.rs | 3 ++- src/skip.rs | 59 ++++++++++++++++++++++++++++++++++++++-------------------- src/visitor.rs | 4 ++-- 4 files changed, 45 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/attr.rs b/src/attr.rs index 41ba9a847e6..b1efaa21f27 100644 --- a/src/attr.rs +++ b/src/attr.rs @@ -337,7 +337,7 @@ impl Rewrite for ast::Attribute { } else { let should_skip = self .ident() - .map(|s| context.skip_context.skip_attribute(s.name.as_str())) + .map(|s| context.skip_context.attributes.skip(s.name.as_str())) .unwrap_or(false); let prefix = attr_prefix(self); @@ -391,7 +391,7 @@ impl Rewrite for [ast::Attribute] { // 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"); + let skip_derives = context.skip_context.attributes.skip("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 diff --git a/src/macros.rs b/src/macros.rs index e78ef1f8066..1ef5a095bf9 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -157,7 +157,8 @@ pub(crate) fn rewrite_macro( ) -> Option { let should_skip = context .skip_context - .skip_macro(context.snippet(mac.path.span)); + .macros + .skip(context.snippet(mac.path.span)); if should_skip { None } else { diff --git a/src/skip.rs b/src/skip.rs index 8b2fd7736ae..4ebbee542a2 100644 --- a/src/skip.rs +++ b/src/skip.rs @@ -2,41 +2,60 @@ use rustc_ast::ast; use rustc_ast_pretty::pprust; +use std::collections::HashSet; -/// Take care of skip name stack. You can update it by attributes slice or -/// by other context. Query this context to know if you need skip a block. +/// Track which blocks of code are to be skipped when formatting. +/// +/// You can update it by: +/// +/// - attributes slice +/// - manually feeding values into the underlying contexts +/// +/// Query this context to know if you need skip a block. #[derive(Default, Clone)] pub(crate) struct SkipContext { - pub(crate) all_macros: bool, - macros: Vec, - attributes: Vec, + pub(crate) macros: SkipNameContext, + pub(crate) attributes: SkipNameContext, } impl SkipContext { pub(crate) fn update_with_attrs(&mut self, attrs: &[ast::Attribute]) { - self.macros.append(&mut get_skip_names("macros", attrs)); - self.attributes - .append(&mut get_skip_names("attributes", attrs)); + self.macros.append(get_skip_names("macros", attrs)); + self.attributes.append(get_skip_names("attributes", attrs)); } - pub(crate) fn update(&mut self, mut other: SkipContext) { - self.macros.append(&mut other.macros); - self.attributes.append(&mut other.attributes); + pub(crate) fn update(&mut self, other: SkipContext) { + let SkipContext { macros, attributes } = other; + self.macros.update(macros); + self.attributes.update(attributes); + } +} + +/// Track which names to skip. +/// +/// Query this context with a string to know whether to skip it. +#[derive(Default, Clone)] +pub(crate) struct SkipNameContext { + all: bool, + values: HashSet, +} + +impl SkipNameContext { + pub(crate) fn append(&mut self, values: Vec) { + self.values.extend(values); } - pub(crate) fn update_macros(&mut self, other: T) - where - T: IntoIterator, - { - self.macros.extend(other.into_iter()); + pub(crate) fn update(&mut self, other: Self) { + self.all = self.all || other.all; + self.values.extend(other.values); } - pub(crate) fn skip_macro(&self, name: &str) -> bool { - self.all_macros || self.macros.iter().any(|n| n == name) + pub(crate) fn skip(&self, name: &str) -> bool { + self.all || self.values.contains(name) } - pub(crate) fn skip_attribute(&self, name: &str) -> bool { - self.attributes.iter().any(|n| n == name) + pub(crate) fn set_all(&mut self, all: bool) { + self.all = all; } } diff --git a/src/visitor.rs b/src/visitor.rs index b93153de154..4b3ee7f76e1 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -775,10 +775,10 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { for macro_selector in config.skip_macro_invocations().0 { match macro_selector { MacroSelector::Name(name) => macro_names.push(name.to_string()), - MacroSelector::All => skip_context.all_macros = true, + MacroSelector::All => skip_context.macros.set_all(true), } } - skip_context.update_macros(macro_names); + skip_context.macros.append(macro_names); FmtVisitor { parent_context: None, parse_sess: parse_session, -- cgit 1.4.1-3-g733a5 From 3fa81c6dbf72a83e4612d9490cdceade5eb2d2ae Mon Sep 17 00:00:00 2001 From: Tom Milligan Date: Wed, 20 Jul 2022 22:24:50 +0100 Subject: [review] use extend trait, enum for skip context --- src/skip.rs | 54 +++++++++++++++++++++++++++++++++++++++--------------- src/visitor.rs | 4 ++-- 2 files changed, 41 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/skip.rs b/src/skip.rs index 4ebbee542a2..59d6d84c964 100644 --- a/src/skip.rs +++ b/src/skip.rs @@ -11,7 +11,7 @@ use std::collections::HashSet; /// - attributes slice /// - manually feeding values into the underlying contexts /// -/// Query this context to know if you need skip a block. +/// Query this context to know if you need to skip a block. #[derive(Default, Clone)] pub(crate) struct SkipContext { pub(crate) macros: SkipNameContext, @@ -20,8 +20,8 @@ pub(crate) struct SkipContext { impl SkipContext { pub(crate) fn update_with_attrs(&mut self, attrs: &[ast::Attribute]) { - self.macros.append(get_skip_names("macros", attrs)); - self.attributes.append(get_skip_names("attributes", attrs)); + self.macros.extend(get_skip_names("macros", attrs)); + self.attributes.extend(get_skip_names("attributes", attrs)); } pub(crate) fn update(&mut self, other: SkipContext) { @@ -34,28 +34,52 @@ impl SkipContext { /// Track which names to skip. /// /// Query this context with a string to know whether to skip it. -#[derive(Default, Clone)] -pub(crate) struct SkipNameContext { - all: bool, - values: HashSet, +#[derive(Clone)] +pub(crate) enum SkipNameContext { + All, + Values(HashSet), } -impl SkipNameContext { - pub(crate) fn append(&mut self, values: Vec) { - self.values.extend(values); +impl Default for SkipNameContext { + fn default() -> Self { + Self::Values(Default::default()) + } +} + +impl Extend for SkipNameContext { + fn extend>(&mut self, iter: T) { + match self { + Self::All => {} + Self::Values(values) => values.extend(iter), + } } +} +impl SkipNameContext { pub(crate) fn update(&mut self, other: Self) { - self.all = self.all || other.all; - self.values.extend(other.values); + match (self, other) { + // If we're already skipping everything, nothing more can be added + (Self::All, _) => {} + // If we want to skip all, set it + (this, Self::All) => { + *this = Self::All; + } + // If we have some new values to skip, add them + (Self::Values(existing_values), Self::Values(new_values)) => { + existing_values.extend(new_values) + } + } } pub(crate) fn skip(&self, name: &str) -> bool { - self.all || self.values.contains(name) + match self { + Self::All => true, + Self::Values(values) => values.contains(name), + } } - pub(crate) fn set_all(&mut self, all: bool) { - self.all = all; + pub(crate) fn skip_all(&mut self) { + *self = Self::All; } } diff --git a/src/visitor.rs b/src/visitor.rs index 4b3ee7f76e1..c0fc37eaaa8 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -775,10 +775,10 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { for macro_selector in config.skip_macro_invocations().0 { match macro_selector { MacroSelector::Name(name) => macro_names.push(name.to_string()), - MacroSelector::All => skip_context.macros.set_all(true), + MacroSelector::All => skip_context.macros.skip_all(), } } - skip_context.macros.append(macro_names); + skip_context.macros.extend(macro_names); FmtVisitor { parent_context: None, parse_sess: parse_session, -- cgit 1.4.1-3-g733a5 From 23ef4b7ac476714886582865b39d396d615a3901 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Sun, 31 Jul 2022 13:53:37 -0500 Subject: refactor(chains): encapsulate shared code, prep for overflows --- src/chains.rs | 99 ++++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 77 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/chains.rs b/src/chains.rs index 5bccb22db4c..a2976bbe92a 100644 --- a/src/chains.rs +++ b/src/chains.rs @@ -74,6 +74,60 @@ use crate::utils::{ rewrite_ident, trimmed_last_line_width, wrap_str, }; +/// Provides the original input contents from the span +/// of a chain element with trailing spaces trimmed. +fn format_overflow_style(span: Span, context: &RewriteContext<'_>) -> Option { + context.snippet_provider.span_to_snippet(span).map(|s| { + s.lines() + .map(|l| l.trim_end()) + .collect::>() + .join("\n") + }) +} + +fn format_chain_item( + item: &ChainItem, + context: &RewriteContext<'_>, + rewrite_shape: Shape, + allow_overflow: bool, +) -> Option { + if allow_overflow { + item.rewrite(context, rewrite_shape) + .or_else(|| format_overflow_style(item.span, context)) + } else { + item.rewrite(context, rewrite_shape) + } +} + +fn get_block_child_shape( + prev_ends_with_block: bool, + context: &RewriteContext<'_>, + shape: Shape, +) -> Shape { + if prev_ends_with_block { + shape.block_indent(0) + } else { + shape.block_indent(context.config.tab_spaces()) + } + .with_max_width(context.config) +} + +fn get_visual_style_child_shape( + context: &RewriteContext<'_>, + shape: Shape, + offset: usize, + parent_overflowing: bool, +) -> Option { + if !parent_overflowing { + shape + .with_max_width(context.config) + .offset_left(offset) + .map(|s| s.visual_indent(0)) + } else { + Some(shape.visual_indent(offset)) + } +} + pub(crate) fn rewrite_chain( expr: &ast::Expr, context: &RewriteContext<'_>, @@ -498,6 +552,8 @@ struct ChainFormatterShared<'a> { // The number of children in the chain. This is not equal to `self.children.len()` // because `self.children` will change size as we process the chain. child_count: usize, + // Whether elements are allowed to overflow past the max_width limit + allow_overflow: bool, } impl<'a> ChainFormatterShared<'a> { @@ -507,6 +563,8 @@ impl<'a> ChainFormatterShared<'a> { rewrites: Vec::with_capacity(chain.children.len() + 1), fits_single_line: false, child_count: chain.children.len(), + // TODO(calebcartwright) + allow_overflow: false, } } @@ -519,6 +577,14 @@ impl<'a> ChainFormatterShared<'a> { } } + fn format_children(&mut self, context: &RewriteContext<'_>, child_shape: Shape) -> Option<()> { + for item in &self.children[..self.children.len() - 1] { + let rewrite = format_chain_item(item, context, child_shape, self.allow_overflow)?; + self.rewrites.push(rewrite); + } + Some(()) + } + // Rewrite the last child. The last child of a chain requires special treatment. We need to // know whether 'overflowing' the last child make a better formatting: // @@ -731,22 +797,12 @@ impl<'a> ChainFormatter for ChainFormatterBlock<'a> { } fn child_shape(&self, context: &RewriteContext<'_>, shape: Shape) -> Option { - Some( - if self.root_ends_with_block { - shape.block_indent(0) - } else { - shape.block_indent(context.config.tab_spaces()) - } - .with_max_width(context.config), - ) + let block_end = self.root_ends_with_block; + Some(get_block_child_shape(block_end, context, shape)) } fn format_children(&mut self, context: &RewriteContext<'_>, child_shape: Shape) -> Option<()> { - for item in &self.shared.children[..self.shared.children.len() - 1] { - let rewrite = item.rewrite(context, child_shape)?; - self.shared.rewrites.push(rewrite); - } - Some(()) + self.shared.format_children(context, child_shape) } fn format_last_child( @@ -828,18 +884,17 @@ impl<'a> ChainFormatter for ChainFormatterVisual<'a> { } fn child_shape(&self, context: &RewriteContext<'_>, shape: Shape) -> Option { - shape - .with_max_width(context.config) - .offset_left(self.offset) - .map(|s| s.visual_indent(0)) + get_visual_style_child_shape( + context, + shape, + self.offset, + // TODO(calebcartwright): self.shared.permissibly_overflowing_parent, + false, + ) } fn format_children(&mut self, context: &RewriteContext<'_>, child_shape: Shape) -> Option<()> { - for item in &self.shared.children[..self.shared.children.len() - 1] { - let rewrite = item.rewrite(context, child_shape)?; - self.shared.rewrites.push(rewrite); - } - Some(()) + self.shared.format_children(context, child_shape) } fn format_last_child( -- cgit 1.4.1-3-g733a5 From 662702eb54b12f16729d6559ce0478b00ef153a8 Mon Sep 17 00:00:00 2001 From: alexey semenyuk Date: Sun, 7 Aug 2022 02:53:03 +0300 Subject: Fix typos (#5486) * Fix typos * Fix typos --- CHANGELOG.md | 2 +- Processes.md | 2 +- src/bin/main.rs | 2 +- src/config/mod.rs | 2 +- src/imports.rs | 4 ++-- tests/mod-resolver/issue-5198/lib/c/d/explanation.txt | 2 +- tests/mod-resolver/issue-5198/lib/explanation.txt | 2 +- tests/source/cfg_if/detect/arch/x86.rs | 2 +- tests/source/enum.rs | 2 +- tests/source/tuple.rs | 2 +- tests/source/wrap_comments_should_not_imply_format_doc_comments.rs | 2 +- tests/target/cfg_if/detect/arch/x86.rs | 2 +- tests/target/enum.rs | 2 +- tests/target/tuple.rs | 2 +- tests/target/wrap_comments_should_not_imply_format_doc_comments.rs | 2 +- 15 files changed, 16 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c1893bf8c3..e9ce930dabc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -840,7 +840,7 @@ from formatting an attribute #3665 - Fix formatting of raw string literals #2983 - Handle chain with try operators with spaces #2986 - Use correct shape in Visual tuple rewriting #2987 -- Impove formatting of arguments with `visual_style = "Visual"` option #2988 +- Improve formatting of arguments with `visual_style = "Visual"` option #2988 - Change `print_diff` to output the correct line number 992b179 - Propagate errors about failing to rewrite a macro 6f318e3 - Handle formatting of long function signature #3010 diff --git a/Processes.md b/Processes.md index 9d86d52b122..334414702b1 100644 --- a/Processes.md +++ b/Processes.md @@ -2,7 +2,7 @@ This document outlines processes regarding management of rustfmt. # Stabilising an Option -In this Section, we describe how to stabilise an option of the rustfmt's configration. +In this Section, we describe how to stabilise an option of the rustfmt's configuration. ## Conditions diff --git a/src/bin/main.rs b/src/bin/main.rs index 8e871e61f26..be64559e877 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -136,7 +136,7 @@ fn make_opts() -> Options { "l", "files-with-diff", "Prints the names of mismatched files that were formatted. Prints the names of \ - files that would be formated when used with `--check` mode. ", + files that would be formatted when used with `--check` mode. ", ); opts.optmulti( "", diff --git a/src/config/mod.rs b/src/config/mod.rs index 5492519f389..4ec7e924bf6 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -182,7 +182,7 @@ create_config! { make_backup: bool, false, false, "Backup changed files"; print_misformatted_file_names: bool, false, true, "Prints the names of mismatched files that were formatted. Prints the names of \ - files that would be formated when used with `--check` mode. "; + files that would be formatted when used with `--check` mode. "; } #[derive(Error, Debug)] diff --git a/src/imports.rs b/src/imports.rs index 8d41c881589..140d8953abc 100644 --- a/src/imports.rs +++ b/src/imports.rs @@ -251,8 +251,8 @@ 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. + // Return non-sorted single occurrence of the use-trees text string; + // order is by first occurrence of the use-tree. use_trees .into_iter() .flat_map(|tree| tree.flatten(import_granularity)) diff --git a/tests/mod-resolver/issue-5198/lib/c/d/explanation.txt b/tests/mod-resolver/issue-5198/lib/c/d/explanation.txt index 92c9e302143..254102ebabd 100644 --- a/tests/mod-resolver/issue-5198/lib/c/d/explanation.txt +++ b/tests/mod-resolver/issue-5198/lib/c/d/explanation.txt @@ -9,7 +9,7 @@ The directory name './lib/c/d/' conflicts with the './lib/c/d.rs' file name. * 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 +so we should fall back to looking for './lib/c/e.rs', which correctly finds the module, 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 diff --git a/tests/mod-resolver/issue-5198/lib/explanation.txt b/tests/mod-resolver/issue-5198/lib/explanation.txt index d436a8076cd..90464def8eb 100644 --- a/tests/mod-resolver/issue-5198/lib/explanation.txt +++ b/tests/mod-resolver/issue-5198/lib/explanation.txt @@ -9,7 +9,7 @@ The directory name './lib' conflicts with the './lib.rs' file name. * 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 +so we should fall back to looking for './a.rs', which correctly finds the module that rustfmt should format. './lib/b.rs' and './lib/c/mod.rs' exist at the default submodule paths so we should be able diff --git a/tests/source/cfg_if/detect/arch/x86.rs b/tests/source/cfg_if/detect/arch/x86.rs index d26f4ee894f..131cbb855f1 100644 --- a/tests/source/cfg_if/detect/arch/x86.rs +++ b/tests/source/cfg_if/detect/arch/x86.rs @@ -329,7 +329,7 @@ pub enum Feature { tbm, /// POPCNT (Population Count) popcnt, - /// FXSR (Floating-point context fast save and restor) + /// FXSR (Floating-point context fast save and restore) fxsr, /// XSAVE (Save Processor Extended States) xsave, diff --git a/tests/source/enum.rs b/tests/source/enum.rs index 0ed9651abe7..a7b9616929c 100644 --- a/tests/source/enum.rs +++ b/tests/source/enum.rs @@ -36,7 +36,7 @@ enum StructLikeVariants { Normal(u32, String, ), StructLike { x: i32, // Test comment // Pre-comment - #[Attr50] y: SomeType, // Aanother Comment + #[Attr50] y: SomeType, // Another Comment }, SL { a: A } } diff --git a/tests/source/tuple.rs b/tests/source/tuple.rs index 9a0f979fbca..5189a7454f3 100644 --- a/tests/source/tuple.rs +++ b/tests/source/tuple.rs @@ -1,4 +1,4 @@ -// Test tuple litterals +// Test tuple literals fn foo() { let a = (a, a, a, a, a); diff --git a/tests/source/wrap_comments_should_not_imply_format_doc_comments.rs b/tests/source/wrap_comments_should_not_imply_format_doc_comments.rs index 78b3ce146f2..56064e4a4cc 100644 --- a/tests/source/wrap_comments_should_not_imply_format_doc_comments.rs +++ b/tests/source/wrap_comments_should_not_imply_format_doc_comments.rs @@ -11,6 +11,6 @@ /// fn foo() {} -/// A long commment for wrapping +/// A long comment for wrapping /// This is a long long long long long long long long long long long long long long long long long long long long sentence. fn bar() {} diff --git a/tests/target/cfg_if/detect/arch/x86.rs b/tests/target/cfg_if/detect/arch/x86.rs index 02d5eed1c29..47210cae2aa 100644 --- a/tests/target/cfg_if/detect/arch/x86.rs +++ b/tests/target/cfg_if/detect/arch/x86.rs @@ -314,7 +314,7 @@ pub enum Feature { tbm, /// POPCNT (Population Count) popcnt, - /// FXSR (Floating-point context fast save and restor) + /// FXSR (Floating-point context fast save and restore) fxsr, /// XSAVE (Save Processor Extended States) xsave, diff --git a/tests/target/enum.rs b/tests/target/enum.rs index 9a25126b44e..70fc8ab376c 100644 --- a/tests/target/enum.rs +++ b/tests/target/enum.rs @@ -43,7 +43,7 @@ enum StructLikeVariants { x: i32, // Test comment // Pre-comment #[Attr50] - y: SomeType, // Aanother Comment + y: SomeType, // Another Comment }, SL { a: A, diff --git a/tests/target/tuple.rs b/tests/target/tuple.rs index 68bb2f3bc28..24fcf8cfd7c 100644 --- a/tests/target/tuple.rs +++ b/tests/target/tuple.rs @@ -1,4 +1,4 @@ -// Test tuple litterals +// Test tuple literals fn foo() { let a = (a, a, a, a, a); diff --git a/tests/target/wrap_comments_should_not_imply_format_doc_comments.rs b/tests/target/wrap_comments_should_not_imply_format_doc_comments.rs index d61d4d7c216..6ccecc7e0bb 100644 --- a/tests/target/wrap_comments_should_not_imply_format_doc_comments.rs +++ b/tests/target/wrap_comments_should_not_imply_format_doc_comments.rs @@ -10,7 +10,7 @@ /// ``` fn foo() {} -/// A long commment for wrapping +/// A long comment for wrapping /// This is a long long long long long long long long long long long long long /// long long long long long long long sentence. fn bar() {} -- cgit 1.4.1-3-g733a5 From 437de8d17fc39231cc8424069579855a94e8c245 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Sat, 6 Aug 2022 19:59:52 -0500 Subject: chore: disable unreachable pub lint on config items --- src/config/mod.rs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/config/mod.rs b/src/config/mod.rs index 4ec7e924bf6..1fc6d033541 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -20,9 +20,11 @@ pub use crate::config::options::*; #[macro_use] pub(crate) mod config_type; #[macro_use] +#[allow(unreachable_pub)] pub(crate) mod options; pub(crate) mod file_lines; +#[allow(unreachable_pub)] pub(crate) mod lists; pub(crate) mod macro_names; -- cgit 1.4.1-3-g733a5 From c78ef92add17c545c387bee12428d3dd51d90003 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Sat, 6 Aug 2022 20:29:46 -0500 Subject: chore: fix another config unreachable-pub --- src/config/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/config/mod.rs b/src/config/mod.rs index 1fc6d033541..14f27f3f8b6 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -422,7 +422,7 @@ mod test { use rustfmt_config_proc_macro::config_type; #[config_type] - pub enum PartiallyUnstableOption { + pub(crate) enum PartiallyUnstableOption { V1, V2, #[unstable_variant] -- cgit 1.4.1-3-g733a5 From a67d909627b7ec93e315bfe1c66895904055c75c Mon Sep 17 00:00:00 2001 From: alex-semenyuk Date: Mon, 8 Aug 2022 15:23:41 +0300 Subject: Fix some clippy issues --- src/cargo-fmt/main.rs | 12 +++++------- src/cargo-fmt/test/mod.rs | 4 ++-- 2 files changed, 7 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/cargo-fmt/main.rs b/src/cargo-fmt/main.rs index 9031d29b45f..2b714b68df0 100644 --- a/src/cargo-fmt/main.rs +++ b/src/cargo-fmt/main.rs @@ -198,12 +198,10 @@ fn convert_message_format_to_rustfmt_args( Ok(()) } "human" => Ok(()), - _ => { - return Err(format!( - "invalid --message-format value: {}. Allowed values are: short|json|human", - message_format - )); - } + _ => Err(format!( + "invalid --message-format value: {}. Allowed values are: short|json|human", + message_format + )), } } @@ -215,7 +213,7 @@ fn print_usage_to_stderr(reason: &str) { .expect("failed to write to stderr"); } -#[derive(Debug, Clone, Copy, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum Verbosity { Verbose, Normal, diff --git a/src/cargo-fmt/test/mod.rs b/src/cargo-fmt/test/mod.rs index 56e52fbabb6..696326e4f94 100644 --- a/src/cargo-fmt/test/mod.rs +++ b/src/cargo-fmt/test/mod.rs @@ -70,9 +70,9 @@ fn mandatory_separator() { .is_err() ); assert!( - !Opts::command() + Opts::command() .try_get_matches_from(&["test", "--", "--emit"]) - .is_err() + .is_ok() ); } -- cgit 1.4.1-3-g733a5 From ea017d7f84e218c4a8048d2ecd9d63bbda014209 Mon Sep 17 00:00:00 2001 From: David Bar-On <61089727+davidBar-On@users.noreply.github.com> Date: Tue, 9 Aug 2022 16:30:49 +0300 Subject: Backport PR #4730 (#5390) * Backport PR #4730 that fix issue #4689 * Test files for each Verion One and Two * Simplify per review comment - use defer and matches! * Changes per reviewer comments for reducing indentations --- src/types.rs | 43 ++++++++++-- tests/source/issue-4689/one.rs | 149 ++++++++++++++++++++++++++++++++++++++++ tests/source/issue-4689/two.rs | 149 ++++++++++++++++++++++++++++++++++++++++ tests/target/issue-4689/one.rs | 150 ++++++++++++++++++++++++++++++++++++++++ tests/target/issue-4689/two.rs | 152 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 639 insertions(+), 4 deletions(-) create mode 100644 tests/source/issue-4689/one.rs create mode 100644 tests/source/issue-4689/two.rs create mode 100644 tests/target/issue-4689/one.rs create mode 100644 tests/target/issue-4689/two.rs (limited to 'src') diff --git a/src/types.rs b/src/types.rs index 2627886db10..25ad587ba85 100644 --- a/src/types.rs +++ b/src/types.rs @@ -941,6 +941,28 @@ fn join_bounds_inner( ast::GenericBound::Trait(..) => last_line_extendable(s), }; + // Whether a GenericBound item is a PathSegment segment that includes internal array + // that contains more than one item + let is_item_with_multi_items_array = |item: &ast::GenericBound| match item { + ast::GenericBound::Trait(ref poly_trait_ref, ..) => { + let segments = &poly_trait_ref.trait_ref.path.segments; + if segments.len() > 1 { + true + } else { + if let Some(args_in) = &segments[0].args { + matches!( + args_in.deref(), + ast::GenericArgs::AngleBracketed(bracket_args) + if bracket_args.args.len() > 1 + ) + } else { + false + } + } + } + _ => false, + }; + let result = items.iter().enumerate().try_fold( (String::new(), None, false), |(strs, prev_trailing_span, prev_extendable), (i, item)| { @@ -1035,10 +1057,23 @@ fn join_bounds_inner( }, )?; - if !force_newline - && items.len() > 1 - && (result.0.contains('\n') || result.0.len() > shape.width) - { + // Whether retry the function with forced newline is needed: + // Only if result is not already multiline and did not exceed line width, + // and either there is more than one item; + // or the single item is of type `Trait`, + // and any of the internal arrays contains more than one item; + let retry_with_force_newline = + if force_newline || (!result.0.contains('\n') && result.0.len() <= shape.width) { + false + } else { + if items.len() > 1 { + true + } else { + is_item_with_multi_items_array(&items[0]) + } + }; + + if retry_with_force_newline { join_bounds_inner(context, shape, items, need_indent, true) } else { Some(result.0) diff --git a/tests/source/issue-4689/one.rs b/tests/source/issue-4689/one.rs new file mode 100644 index 00000000000..d048eb10fb1 --- /dev/null +++ b/tests/source/issue-4689/one.rs @@ -0,0 +1,149 @@ +// rustfmt-version: One + +// Based on the issue description +pub trait PrettyPrinter<'tcx>: +Printer< +'tcx, +Error = fmt::Error, +Path = Self, +Region = Self, +Type = Self, +DynExistential = Self, +Const = Self, +> +{ +// +} +pub trait PrettyPrinter<'tcx>: +Printer< +'tcx, +Error = fmt::Error, +Path = Self, +Region = Self, +Type = Self, +DynExistential = Self, +Const = Self, +> + fmt::Write +{ +// +} +pub trait PrettyPrinter<'tcx>: +Printer< +'tcx, +Error = fmt::Error, +Path = Self, +Region = Self, +Type = Self, +DynExistential = Self, +Const = Self, +> + fmt::Write1 + fmt::Write2 +{ +// +} +pub trait PrettyPrinter<'tcx>: +fmt::Write + Printer< +'tcx, +Error = fmt::Error, +Path = Self, +Region = Self, +Type = Self, +DynExistential = Self, +Const = Self, +> +{ +// +} +pub trait PrettyPrinter<'tcx>: +fmt::Write + Printer1< +'tcx, +Error = fmt::Error, +Path = Self, +Region = Self, +Type = Self, +DynExistential = Self, +Const = Self, +> + Printer2< +'tcx, +Error = fmt::Error, +Path = Self, +Region = Self, +Type = Self, +DynExistential = Self, +Const = Self, +> +{ +// +} + +// Some test cases to ensure other cases formatting were not changed +fn f() -> Box< +FnMut() -> Thing< +WithType = LongItemName, +Error = LONGLONGLONGLONGLONGONGEvenLongerErrorNameLongerLonger, +>, +> { +} +fn f() -> Box< +FnMut() -> Thing< +WithType = LongItemName, +Error = LONGLONGLONGLONGLONGONGEvenLongerErrorNameLongerLonger, +> + fmt::Write1 ++ fmt::Write2, +> { +} + +fn foo(foo2: F) +where +F: Fn( +// this comment is deleted +) +{ +} +fn foo(foo2: F) +where +F: Fn( +// this comment is deleted +) + fmt::Write +{ +} + +fn elaborate_bounds(mut mk_cand: F) +where +F: for<> FnMut( +&mut ProbeContext<>, +ty::PolyTraitRefffffffffffffffffffffffffffffffff<>, +tyyyyyyyyyyyyyyyyyyyyy::AssociatedItem, +), +{ +} +fn elaborate_bounds(mut mk_cand: F) +where +F: for<> FnMut( +&mut ProbeContext<>, +ty::PolyTraitRefffffffffffffffffffffffffffffffff<>, +tyyyyyyyyyyyyyyyyyyyyy::AssociatedItem, +) + fmt::Write, +{ +} + +fn build_sorted_static_get_entry_names( +mut entries: entryyyyyyyy, +) -> ( +impl Fn( +AlphabeticalTraversal, +Seconddddddddddddddddddddddddddddddddddd +) -> Parammmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm ++ Sendddddddddddddddddddddddddddddddddddddddddddd +) { +} + +pub trait SomeTrait: +Cloneeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee ++ Eqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq +{ +} + +trait B = where +for<'b> &'b Self: Send ++ Cloneeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee ++ Copyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy; diff --git a/tests/source/issue-4689/two.rs b/tests/source/issue-4689/two.rs new file mode 100644 index 00000000000..ea7feda825d --- /dev/null +++ b/tests/source/issue-4689/two.rs @@ -0,0 +1,149 @@ +// rustfmt-version: Two + +// Based on the issue description +pub trait PrettyPrinter<'tcx>: +Printer< +'tcx, +Error = fmt::Error, +Path = Self, +Region = Self, +Type = Self, +DynExistential = Self, +Const = Self, +> +{ +// +} +pub trait PrettyPrinter<'tcx>: +Printer< +'tcx, +Error = fmt::Error, +Path = Self, +Region = Self, +Type = Self, +DynExistential = Self, +Const = Self, +> + fmt::Write +{ +// +} +pub trait PrettyPrinter<'tcx>: +Printer< +'tcx, +Error = fmt::Error, +Path = Self, +Region = Self, +Type = Self, +DynExistential = Self, +Const = Self, +> + fmt::Write1 + fmt::Write2 +{ +// +} +pub trait PrettyPrinter<'tcx>: +fmt::Write + Printer< +'tcx, +Error = fmt::Error, +Path = Self, +Region = Self, +Type = Self, +DynExistential = Self, +Const = Self, +> +{ +// +} +pub trait PrettyPrinter<'tcx>: +fmt::Write + Printer1< +'tcx, +Error = fmt::Error, +Path = Self, +Region = Self, +Type = Self, +DynExistential = Self, +Const = Self, +> + Printer2< +'tcx, +Error = fmt::Error, +Path = Self, +Region = Self, +Type = Self, +DynExistential = Self, +Const = Self, +> +{ +// +} + +// Some test cases to ensure other cases formatting were not changed +fn f() -> Box< +FnMut() -> Thing< +WithType = LongItemName, +Error = LONGLONGLONGLONGLONGONGEvenLongerErrorNameLongerLonger, +>, +> { +} +fn f() -> Box< +FnMut() -> Thing< +WithType = LongItemName, +Error = LONGLONGLONGLONGLONGONGEvenLongerErrorNameLongerLonger, +> + fmt::Write1 ++ fmt::Write2, +> { +} + +fn foo(foo2: F) +where +F: Fn( +// this comment is deleted +) +{ +} +fn foo(foo2: F) +where +F: Fn( +// this comment is deleted +) + fmt::Write +{ +} + +fn elaborate_bounds(mut mk_cand: F) +where +F: for<> FnMut( +&mut ProbeContext<>, +ty::PolyTraitRefffffffffffffffffffffffffffffffff<>, +tyyyyyyyyyyyyyyyyyyyyy::AssociatedItem, +), +{ +} +fn elaborate_bounds(mut mk_cand: F) +where +F: for<> FnMut( +&mut ProbeContext<>, +ty::PolyTraitRefffffffffffffffffffffffffffffffff<>, +tyyyyyyyyyyyyyyyyyyyyy::AssociatedItem, +) + fmt::Write, +{ +} + +fn build_sorted_static_get_entry_names( +mut entries: entryyyyyyyy, +) -> ( +impl Fn( +AlphabeticalTraversal, +Seconddddddddddddddddddddddddddddddddddd +) -> Parammmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm ++ Sendddddddddddddddddddddddddddddddddddddddddddd +) { +} + +pub trait SomeTrait: +Cloneeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee ++ Eqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq +{ +} + +trait B = where +for<'b> &'b Self: Send ++ Cloneeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee ++ Copyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy; diff --git a/tests/target/issue-4689/one.rs b/tests/target/issue-4689/one.rs new file mode 100644 index 00000000000..df1a507bc1d --- /dev/null +++ b/tests/target/issue-4689/one.rs @@ -0,0 +1,150 @@ +// rustfmt-version: One + +// Based on the issue description +pub trait PrettyPrinter<'tcx>: + Printer< + 'tcx, + Error = fmt::Error, + Path = Self, + Region = Self, + Type = Self, + DynExistential = Self, + Const = Self, + > +{ + // +} +pub trait PrettyPrinter<'tcx>: + Printer< + 'tcx, + Error = fmt::Error, + Path = Self, + Region = Self, + Type = Self, + DynExistential = Self, + Const = Self, + > + fmt::Write +{ + // +} +pub trait PrettyPrinter<'tcx>: + Printer< + 'tcx, + Error = fmt::Error, + Path = Self, + Region = Self, + Type = Self, + DynExistential = Self, + Const = Self, + > + fmt::Write1 + + fmt::Write2 +{ + // +} +pub trait PrettyPrinter<'tcx>: + fmt::Write + + Printer< + 'tcx, + Error = fmt::Error, + Path = Self, + Region = Self, + Type = Self, + DynExistential = Self, + Const = Self, + > +{ + // +} +pub trait PrettyPrinter<'tcx>: + fmt::Write + + Printer1< + 'tcx, + Error = fmt::Error, + Path = Self, + Region = Self, + Type = Self, + DynExistential = Self, + Const = Self, + > + Printer2< + 'tcx, + Error = fmt::Error, + Path = Self, + Region = Self, + Type = Self, + DynExistential = Self, + Const = Self, + > +{ + // +} + +// Some test cases to ensure other cases formatting were not changed +fn f() -> Box< + FnMut() -> Thing< + WithType = LongItemName, + Error = LONGLONGLONGLONGLONGONGEvenLongerErrorNameLongerLonger, + >, +> { +} +fn f() -> Box< + FnMut() -> Thing< + WithType = LongItemName, + Error = LONGLONGLONGLONGLONGONGEvenLongerErrorNameLongerLonger, + > + fmt::Write1 + + fmt::Write2, +> { +} + +fn foo(foo2: F) +where + F: Fn( + // this comment is deleted + ), +{ +} +fn foo(foo2: F) +where + F: Fn( + // this comment is deleted + ) + fmt::Write, +{ +} + +fn elaborate_bounds(mut mk_cand: F) +where + F: FnMut( + &mut ProbeContext, + ty::PolyTraitRefffffffffffffffffffffffffffffffff, + tyyyyyyyyyyyyyyyyyyyyy::AssociatedItem, + ), +{ +} +fn elaborate_bounds(mut mk_cand: F) +where + F: FnMut( + &mut ProbeContext, + ty::PolyTraitRefffffffffffffffffffffffffffffffff, + tyyyyyyyyyyyyyyyyyyyyy::AssociatedItem, + ) + fmt::Write, +{ +} + +fn build_sorted_static_get_entry_names( + mut entries: entryyyyyyyy, +) -> (impl Fn( + AlphabeticalTraversal, + Seconddddddddddddddddddddddddddddddddddd, +) -> Parammmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm + + Sendddddddddddddddddddddddddddddddddddddddddddd) { +} + +pub trait SomeTrait: + Cloneeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee + + Eqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq +{ +} + +trait B = where + for<'b> &'b Self: Send + + Cloneeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee + + Copyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy; diff --git a/tests/target/issue-4689/two.rs b/tests/target/issue-4689/two.rs new file mode 100644 index 00000000000..e3b5cd22810 --- /dev/null +++ b/tests/target/issue-4689/two.rs @@ -0,0 +1,152 @@ +// rustfmt-version: Two + +// Based on the issue description +pub trait PrettyPrinter<'tcx>: + Printer< + 'tcx, + Error = fmt::Error, + Path = Self, + Region = Self, + Type = Self, + DynExistential = Self, + Const = Self, + > +{ + // +} +pub trait PrettyPrinter<'tcx>: + Printer< + 'tcx, + Error = fmt::Error, + Path = Self, + Region = Self, + Type = Self, + DynExistential = Self, + Const = Self, + > + fmt::Write +{ + // +} +pub trait PrettyPrinter<'tcx>: + Printer< + 'tcx, + Error = fmt::Error, + Path = Self, + Region = Self, + Type = Self, + DynExistential = Self, + Const = Self, + > + fmt::Write1 + + fmt::Write2 +{ + // +} +pub trait PrettyPrinter<'tcx>: + fmt::Write + + Printer< + 'tcx, + Error = fmt::Error, + Path = Self, + Region = Self, + Type = Self, + DynExistential = Self, + Const = Self, + > +{ + // +} +pub trait PrettyPrinter<'tcx>: + fmt::Write + + Printer1< + 'tcx, + Error = fmt::Error, + Path = Self, + Region = Self, + Type = Self, + DynExistential = Self, + Const = Self, + > + Printer2< + 'tcx, + Error = fmt::Error, + Path = Self, + Region = Self, + Type = Self, + DynExistential = Self, + Const = Self, + > +{ + // +} + +// Some test cases to ensure other cases formatting were not changed +fn f() -> Box< + FnMut() -> Thing< + WithType = LongItemName, + Error = LONGLONGLONGLONGLONGONGEvenLongerErrorNameLongerLonger, + >, +> { +} +fn f() -> Box< + FnMut() -> Thing< + WithType = LongItemName, + Error = LONGLONGLONGLONGLONGONGEvenLongerErrorNameLongerLonger, + > + fmt::Write1 + + fmt::Write2, +> { +} + +fn foo(foo2: F) +where + F: Fn( + // this comment is deleted + ), +{ +} +fn foo(foo2: F) +where + F: Fn( + // this comment is deleted + ) + fmt::Write, +{ +} + +fn elaborate_bounds(mut mk_cand: F) +where + F: FnMut( + &mut ProbeContext, + ty::PolyTraitRefffffffffffffffffffffffffffffffff, + tyyyyyyyyyyyyyyyyyyyyy::AssociatedItem, + ), +{ +} +fn elaborate_bounds(mut mk_cand: F) +where + F: FnMut( + &mut ProbeContext, + ty::PolyTraitRefffffffffffffffffffffffffffffffff, + tyyyyyyyyyyyyyyyyyyyyy::AssociatedItem, + ) + fmt::Write, +{ +} + +fn build_sorted_static_get_entry_names( + mut entries: entryyyyyyyy, +) -> ( + impl Fn( + AlphabeticalTraversal, + Seconddddddddddddddddddddddddddddddddddd, + ) -> Parammmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm + + Sendddddddddddddddddddddddddddddddddddddddddddd +) { +} + +pub trait SomeTrait: + Cloneeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee + + Eqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq +{ +} + +trait B = where + for<'b> &'b Self: Send + + Cloneeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee + + Copyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy; -- cgit 1.4.1-3-g733a5 From 38659ec6ad5f341cf8eb3139725bf695872c6de7 Mon Sep 17 00:00:00 2001 From: A-Walrus <58790821+A-Walrus@users.noreply.github.com> Date: Fri, 19 Aug 2022 02:44:29 +0300 Subject: Unicode comment align (#5505) * Fix comment alignment with unicode Also added tests for this behaviour * Simplify tests * Improve tests --- src/lists.rs | 16 ++--- tests/source/comments_unicode.rs | 140 +++++++++++++++++++++++++++++++++++++++ tests/target/comments_unicode.rs | 140 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 288 insertions(+), 8 deletions(-) create mode 100644 tests/source/comments_unicode.rs create mode 100644 tests/target/comments_unicode.rs (limited to 'src') diff --git a/src/lists.rs b/src/lists.rs index e8785050782..a878e6cf9b2 100644 --- a/src/lists.rs +++ b/src/lists.rs @@ -297,9 +297,9 @@ where } else { inner_item.as_ref() }; - let mut item_last_line_width = item_last_line.len() + item_sep_len; + let mut item_last_line_width = unicode_str_width(item_last_line) + item_sep_len; if item_last_line.starts_with(&**indent_str) { - item_last_line_width -= indent_str.len(); + item_last_line_width -= unicode_str_width(indent_str); } if !item.is_substantial() { @@ -449,7 +449,7 @@ where } else if starts_with_newline(comment) { false } else { - comment.trim().contains('\n') || comment.trim().len() > width + comment.trim().contains('\n') || unicode_str_width(comment.trim()) > width }; rewrite_comment( @@ -465,7 +465,7 @@ where if !starts_with_newline(comment) { if formatting.align_comments { let mut comment_alignment = - post_comment_alignment(item_max_width, inner_item.len()); + post_comment_alignment(item_max_width, unicode_str_width(inner_item)); if first_line_width(&formatted_comment) + last_line_width(&result) + comment_alignment @@ -475,7 +475,7 @@ where item_max_width = None; formatted_comment = rewrite_post_comment(&mut item_max_width)?; comment_alignment = - post_comment_alignment(item_max_width, inner_item.len()); + post_comment_alignment(item_max_width, unicode_str_width(inner_item)); } for _ in 0..=comment_alignment { result.push(' '); @@ -533,7 +533,7 @@ where let mut first = true; for item in items.clone().into_iter().skip(i) { let item = item.as_ref(); - let inner_item_width = item.inner_as_ref().len(); + let inner_item_width = unicode_str_width(item.inner_as_ref()); if !first && (item.is_different_group() || item.post_comment.is_none() @@ -552,8 +552,8 @@ where max_width } -fn post_comment_alignment(item_max_width: Option, inner_item_len: usize) -> usize { - item_max_width.unwrap_or(0).saturating_sub(inner_item_len) +fn post_comment_alignment(item_max_width: Option, inner_item_width: usize) -> usize { + item_max_width.unwrap_or(0).saturating_sub(inner_item_width) } pub(crate) struct ListItems<'a, I, F1, F2, F3> diff --git a/tests/source/comments_unicode.rs b/tests/source/comments_unicode.rs new file mode 100644 index 00000000000..e65a245ba93 --- /dev/null +++ b/tests/source/comments_unicode.rs @@ -0,0 +1,140 @@ +impl Default for WhitespaceCharacters { + fn default() -> Self { + Self { + space: '·', // U+00B7 + nbsp: '⍽', // U+237D + tab: '→', // U+2192 + newline: '⏎', // U+23CE + } + } +} + +const RAINBOWS: &[&str] = &[ + "rаinЬοѡ", // hue: 0 + "raіnЬοw", // hue: 2 + "rаіɴЬow", // hue: 2 + "raіɴЬoѡ", // hue: 8 + "ʀainЬow", // hue: 8 + "ʀaіɴboѡ", // hue: 8 + "ʀаіnbοw", // hue: 11 + "rainЬoѡ", // hue: 14 + "raіɴbow", // hue: 14 + "rаiɴЬow", // hue: 20 + "raіnЬow", // hue: 26 + "ʀaiɴbοw", // hue: 32 + "raіɴboѡ", // hue: 35 + "rаiɴbow", // hue: 35 + "rаіnbοw", // hue: 38 + "rаinЬow", // hue: 47 + "ʀaіnboѡ", // hue: 47 + "ʀaіnЬoѡ", // hue: 47 + "ʀаіɴbοw", // hue: 53 + "ʀaіnЬοѡ", // hue: 57 + "raiɴЬoѡ", // hue: 68 + "ʀainbοѡ", // hue: 68 + "ʀаinboѡ", // hue: 68 + "ʀаiɴbοw", // hue: 68 + "ʀаіnbow", // hue: 68 + "rаіnЬοѡ", // hue: 69 + "ʀainЬοw", // hue: 71 + "raiɴbow", // hue: 73 + "raіnЬoѡ", // hue: 74 + "rаіɴbοw", // hue: 77 + "raіnЬοѡ", // hue: 81 + "raiɴЬow", // hue: 83 + "ʀainbοw", // hue: 83 + "ʀаinbow", // hue: 83 + "ʀаiɴbοѡ", // hue: 83 + "ʀаіnboѡ", // hue: 83 + "ʀаіɴЬοѡ", // hue: 84 + "rainЬow", // hue: 85 + "ʀаiɴЬοw", // hue: 86 + "ʀаіnbοѡ", // hue: 89 + "ʀаіnЬοw", // hue: 92 + "rаiɴbοw", // hue: 95 + "ʀаіɴbοѡ", // hue: 98 + "ʀаiɴЬοѡ", // hue: 99 + "raіnbοw", // hue: 101 + "ʀаіɴЬοw", // hue: 101 + "ʀaiɴboѡ", // hue: 104 + "ʀаinbοѡ", // hue: 104 + "rаiɴbοѡ", // hue: 107 + "ʀаinЬοw", // hue: 107 + "rаiɴЬοw", // hue: 110 + "rаіnboѡ", // hue: 110 + "rаіnbοѡ", // hue: 113 + "ʀainЬοѡ", // hue: 114 + "rаіnЬοw", // hue: 116 + "ʀaіɴЬow", // hue: 116 + "rаinbοw", // hue: 122 + "ʀаіɴboѡ", // hue: 125 + "rаinbοѡ", // hue: 131 + "rainbow", // hue: 134 + "rаinЬοw", // hue: 134 + "ʀаiɴboѡ", // hue: 140 + "rainЬοѡ", // hue: 141 + "raіɴЬow", // hue: 143 + "ʀainЬoѡ", // hue: 143 + "ʀaіɴbow", // hue: 143 + "ʀainbow", // hue: 148 + "rаіɴboѡ", // hue: 149 + "ʀainboѡ", // hue: 155 + "ʀaіnbow", // hue: 155 + "ʀaіnЬow", // hue: 155 + "raiɴbοw", // hue: 158 + "ʀаiɴЬoѡ", // hue: 158 + "rainbοw", // hue: 160 + "rаinbow", // hue: 160 + "ʀaіɴbοѡ", // hue: 164 + "ʀаiɴbow", // hue: 164 + "ʀаіnЬoѡ", // hue: 164 + "ʀaiɴЬοѡ", // hue: 165 + "rаiɴboѡ", // hue: 167 + "ʀaіɴЬοw", // hue: 167 + "ʀaіɴЬοѡ", // hue: 171 + "raіnboѡ", // hue: 173 + "ʀаіɴЬoѡ", // hue: 173 + "rаіɴbοѡ", // hue: 176 + "ʀаinЬow", // hue: 176 + "rаiɴЬοѡ", // hue: 177 + "rаіɴЬοw", // hue: 179 + "ʀаinЬoѡ", // hue: 179 + "ʀаіɴbow", // hue: 179 + "rаiɴЬoѡ", // hue: 182 + "raіɴbοѡ", // hue: 188 + "rаіnЬoѡ", // hue: 188 + "raiɴЬοѡ", // hue: 189 + "raіɴЬοw", // hue: 191 + "ʀaіɴbοw", // hue: 191 + "ʀаіnЬow", // hue: 191 + "rainbοѡ", // hue: 194 + "rаinboѡ", // hue: 194 + "rаіnbow", // hue: 194 + "rainЬοw", // hue: 197 + "rаinЬoѡ", // hue: 206 + "rаіɴbow", // hue: 206 + "rаіɴЬοѡ", // hue: 210 + "ʀaiɴЬow", // hue: 212 + "raіɴbοw", // hue: 218 + "rаіnЬow", // hue: 218 + "ʀaiɴbοѡ", // hue: 221 + "ʀaiɴЬοw", // hue: 224 + "ʀaіnbοѡ", // hue: 227 + "raiɴboѡ", // hue: 230 + "ʀaіnbοw", // hue: 230 + "ʀaіnЬοw", // hue: 230 + "ʀаinЬοѡ", // hue: 231 + "rainboѡ", // hue: 232 + "raіnbow", // hue: 232 + "ʀаіɴЬow", // hue: 233 + "ʀaіɴЬoѡ", // hue: 239 + "ʀаіnЬοѡ", // hue: 246 + "raiɴbοѡ", // hue: 248 + "ʀаiɴЬow", // hue: 248 + "raіɴЬοѡ", // hue: 249 + "raiɴЬοw", // hue: 251 + "rаіɴЬoѡ", // hue: 251 + "ʀaiɴbow", // hue: 251 + "ʀаinbοw", // hue: 251 + "raіnbοѡ", // hue: 254 +]; diff --git a/tests/target/comments_unicode.rs b/tests/target/comments_unicode.rs new file mode 100644 index 00000000000..3e1b6b0a28f --- /dev/null +++ b/tests/target/comments_unicode.rs @@ -0,0 +1,140 @@ +impl Default for WhitespaceCharacters { + fn default() -> Self { + Self { + space: '·', // U+00B7 + nbsp: '⍽', // U+237D + tab: '→', // U+2192 + newline: '⏎', // U+23CE + } + } +} + +const RAINBOWS: &[&str] = &[ + "rаinЬοѡ", // hue: 0 + "raіnЬοw", // hue: 2 + "rаіɴЬow", // hue: 2 + "raіɴЬoѡ", // hue: 8 + "ʀainЬow", // hue: 8 + "ʀaіɴboѡ", // hue: 8 + "ʀаіnbοw", // hue: 11 + "rainЬoѡ", // hue: 14 + "raіɴbow", // hue: 14 + "rаiɴЬow", // hue: 20 + "raіnЬow", // hue: 26 + "ʀaiɴbοw", // hue: 32 + "raіɴboѡ", // hue: 35 + "rаiɴbow", // hue: 35 + "rаіnbοw", // hue: 38 + "rаinЬow", // hue: 47 + "ʀaіnboѡ", // hue: 47 + "ʀaіnЬoѡ", // hue: 47 + "ʀаіɴbοw", // hue: 53 + "ʀaіnЬοѡ", // hue: 57 + "raiɴЬoѡ", // hue: 68 + "ʀainbοѡ", // hue: 68 + "ʀаinboѡ", // hue: 68 + "ʀаiɴbοw", // hue: 68 + "ʀаіnbow", // hue: 68 + "rаіnЬοѡ", // hue: 69 + "ʀainЬοw", // hue: 71 + "raiɴbow", // hue: 73 + "raіnЬoѡ", // hue: 74 + "rаіɴbοw", // hue: 77 + "raіnЬοѡ", // hue: 81 + "raiɴЬow", // hue: 83 + "ʀainbοw", // hue: 83 + "ʀаinbow", // hue: 83 + "ʀаiɴbοѡ", // hue: 83 + "ʀаіnboѡ", // hue: 83 + "ʀаіɴЬοѡ", // hue: 84 + "rainЬow", // hue: 85 + "ʀаiɴЬοw", // hue: 86 + "ʀаіnbοѡ", // hue: 89 + "ʀаіnЬοw", // hue: 92 + "rаiɴbοw", // hue: 95 + "ʀаіɴbοѡ", // hue: 98 + "ʀаiɴЬοѡ", // hue: 99 + "raіnbοw", // hue: 101 + "ʀаіɴЬοw", // hue: 101 + "ʀaiɴboѡ", // hue: 104 + "ʀаinbοѡ", // hue: 104 + "rаiɴbοѡ", // hue: 107 + "ʀаinЬοw", // hue: 107 + "rаiɴЬοw", // hue: 110 + "rаіnboѡ", // hue: 110 + "rаіnbοѡ", // hue: 113 + "ʀainЬοѡ", // hue: 114 + "rаіnЬοw", // hue: 116 + "ʀaіɴЬow", // hue: 116 + "rаinbοw", // hue: 122 + "ʀаіɴboѡ", // hue: 125 + "rаinbοѡ", // hue: 131 + "rainbow", // hue: 134 + "rаinЬοw", // hue: 134 + "ʀаiɴboѡ", // hue: 140 + "rainЬοѡ", // hue: 141 + "raіɴЬow", // hue: 143 + "ʀainЬoѡ", // hue: 143 + "ʀaіɴbow", // hue: 143 + "ʀainbow", // hue: 148 + "rаіɴboѡ", // hue: 149 + "ʀainboѡ", // hue: 155 + "ʀaіnbow", // hue: 155 + "ʀaіnЬow", // hue: 155 + "raiɴbοw", // hue: 158 + "ʀаiɴЬoѡ", // hue: 158 + "rainbοw", // hue: 160 + "rаinbow", // hue: 160 + "ʀaіɴbοѡ", // hue: 164 + "ʀаiɴbow", // hue: 164 + "ʀаіnЬoѡ", // hue: 164 + "ʀaiɴЬοѡ", // hue: 165 + "rаiɴboѡ", // hue: 167 + "ʀaіɴЬοw", // hue: 167 + "ʀaіɴЬοѡ", // hue: 171 + "raіnboѡ", // hue: 173 + "ʀаіɴЬoѡ", // hue: 173 + "rаіɴbοѡ", // hue: 176 + "ʀаinЬow", // hue: 176 + "rаiɴЬοѡ", // hue: 177 + "rаіɴЬοw", // hue: 179 + "ʀаinЬoѡ", // hue: 179 + "ʀаіɴbow", // hue: 179 + "rаiɴЬoѡ", // hue: 182 + "raіɴbοѡ", // hue: 188 + "rаіnЬoѡ", // hue: 188 + "raiɴЬοѡ", // hue: 189 + "raіɴЬοw", // hue: 191 + "ʀaіɴbοw", // hue: 191 + "ʀаіnЬow", // hue: 191 + "rainbοѡ", // hue: 194 + "rаinboѡ", // hue: 194 + "rаіnbow", // hue: 194 + "rainЬοw", // hue: 197 + "rаinЬoѡ", // hue: 206 + "rаіɴbow", // hue: 206 + "rаіɴЬοѡ", // hue: 210 + "ʀaiɴЬow", // hue: 212 + "raіɴbοw", // hue: 218 + "rаіnЬow", // hue: 218 + "ʀaiɴbοѡ", // hue: 221 + "ʀaiɴЬοw", // hue: 224 + "ʀaіnbοѡ", // hue: 227 + "raiɴboѡ", // hue: 230 + "ʀaіnbοw", // hue: 230 + "ʀaіnЬοw", // hue: 230 + "ʀаinЬοѡ", // hue: 231 + "rainboѡ", // hue: 232 + "raіnbow", // hue: 232 + "ʀаіɴЬow", // hue: 233 + "ʀaіɴЬoѡ", // hue: 239 + "ʀаіnЬοѡ", // hue: 246 + "raiɴbοѡ", // hue: 248 + "ʀаiɴЬow", // hue: 248 + "raіɴЬοѡ", // hue: 249 + "raiɴЬοw", // hue: 251 + "rаіɴЬoѡ", // hue: 251 + "ʀaiɴbow", // hue: 251 + "ʀаinbοw", // hue: 251 + "raіnbοѡ", // hue: 254 +]; -- cgit 1.4.1-3-g733a5 From aae222c974a982e878f279b95bd1a9d0166ff229 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Mon, 23 Jan 2023 10:54:05 -0600 Subject: fix: correct span for structs with const generics --- src/items.rs | 2 +- tests/target/issue_5668.rs | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 tests/target/issue_5668.rs (limited to 'src') diff --git a/src/items.rs b/src/items.rs index 755a41f6bf0..063a6428a08 100644 --- a/src/items.rs +++ b/src/items.rs @@ -1245,7 +1245,7 @@ fn format_unit_struct( ) -> Option { let header_str = format_header(context, p.prefix, p.ident, p.vis, offset); let generics_str = if let Some(generics) = p.generics { - let hi = context.snippet_provider.span_before(p.span, ";"); + let hi = context.snippet_provider.span_before_last(p.span, ";"); format_generics( context, generics, diff --git a/tests/target/issue_5668.rs b/tests/target/issue_5668.rs new file mode 100644 index 00000000000..bbd9a530b81 --- /dev/null +++ b/tests/target/issue_5668.rs @@ -0,0 +1,8 @@ +type Foo = impl Send; +struct Struct< + const C: usize = { + let _: Foo = (); + //~^ ERROR: mismatched types + 0 + }, +>; -- cgit 1.4.1-3-g733a5 From 5139b14620832d08a436ad85c1bef4037c36395b Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Tue, 24 Jan 2023 11:13:54 -0600 Subject: fix: version gate changes for multiline single generic bound --- src/types.rs | 23 ++++++++++++----------- tests/target/issue-4689/one.rs | 16 ++++++++-------- 2 files changed, 20 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/types.rs b/src/types.rs index 2cae5498107..01e2fb6e61e 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1057,21 +1057,22 @@ fn join_bounds_inner( }, )?; - // Whether retry the function with forced newline is needed: + // Whether to retry with a forced newline: // Only if result is not already multiline and did not exceed line width, // and either there is more than one item; // or the single item is of type `Trait`, // and any of the internal arrays contains more than one item; - let retry_with_force_newline = - if force_newline || (!result.0.contains('\n') && result.0.len() <= shape.width) { - false - } else { - if items.len() > 1 { - true - } else { - is_item_with_multi_items_array(&items[0]) - } - }; + let retry_with_force_newline = match context.config.version() { + Version::One => { + !force_newline + && items.len() > 1 + && (result.0.contains('\n') || result.0.len() > shape.width) + } + Version::Two if force_newline => false, + Version::Two if (!result.0.contains('\n') && result.0.len() <= shape.width) => false, + Version::Two if items.len() > 1 => true, + Version::Two => is_item_with_multi_items_array(&items[0]), + }; if retry_with_force_newline { join_bounds_inner(context, shape, items, need_indent, true) diff --git a/tests/target/issue-4689/one.rs b/tests/target/issue-4689/one.rs index df1a507bc1d..7735e34f3b5 100644 --- a/tests/target/issue-4689/one.rs +++ b/tests/target/issue-4689/one.rs @@ -3,14 +3,14 @@ // Based on the issue description pub trait PrettyPrinter<'tcx>: Printer< - 'tcx, - Error = fmt::Error, - Path = Self, - Region = Self, - Type = Self, - DynExistential = Self, - Const = Self, - > + 'tcx, + Error = fmt::Error, + Path = Self, + Region = Self, + Type = Self, + DynExistential = Self, + Const = Self, +> { // } -- cgit 1.4.1-3-g733a5 From 567bd977230f3fe64781e9946b9f692919d30d38 Mon Sep 17 00:00:00 2001 From: Arthur Carcano <53921575+krtab@users.noreply.github.com> Date: Sat, 28 Jan 2023 22:16:46 +0100 Subject: Document which comments are excluded from wrapping (#5637) * Document which comments are excluded from wrapping Cf: https://github.com/rust-lang/rustfmt/issues/5634 * Add examples in wrap_commments doc * fix failling tests --- Configurations.md | 20 ++++++++++++++++++++ src/comment.rs | 2 ++ 2 files changed, 22 insertions(+) (limited to 'src') diff --git a/Configurations.md b/Configurations.md index 49e7e4e6489..ac638ff91e6 100644 --- a/Configurations.md +++ b/Configurations.md @@ -2997,6 +2997,10 @@ See also [`brace_style`](#brace_style), [`control_brace_style`](#control_brace_s Break comments to fit on the line +Note that no wrapping will happen if: +1. The comment is the start of a markdown header doc comment +2. An URL was found in the comment + - **Default value**: `false` - **Possible values**: `true`, `false` - **Stable**: No (tracking issue: [#3347](https://github.com/rust-lang/rustfmt/issues/3347)) @@ -3011,6 +3015,11 @@ Break comments to fit on the line // commodo consequat. // 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. + +// Information on the lorem ipsum can be found at the following url: https://en.wikipedia.org/wiki/Lorem_ipsum. Its text is: 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. + +/// # This doc comment is a very long header (it starts with a '#'). Had it not been a header it would have been wrapped. But because it is a header, it will not be. That is because wrapping a markdown header breaks it. +struct Foo {} ``` #### `true`: @@ -3021,6 +3030,17 @@ Break comments to fit on the line // magna aliqua. Ut enim ad minim veniam, quis nostrud // exercitation ullamco laboris nisi ut aliquip ex ea // commodo consequat. + +// 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. + +// Information on the lorem ipsum can be found at the following url: https://en.wikipedia.org/wiki/Lorem_ipsum. Its text is: 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. + +/// # This doc comment is a very long header (it starts with a '#'). Had it not been a header it would have been wrapped. But because it is a header, it will not be. That is because wrapping a markdown header breaks it. +struct Foo {} ``` # Internal Options diff --git a/src/comment.rs b/src/comment.rs index 4d565afc1e0..261fa5e93d8 100644 --- a/src/comment.rs +++ b/src/comment.rs @@ -801,6 +801,8 @@ impl<'a> CommentRewrite<'a> { // 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 comment + // If this changes, the documentation in ../Configurations.md#wrap_comments + // should be changed accordingly. let should_wrap_comment = self.fmt.config.wrap_comments() && !is_markdown_header_doc_comment && unicode_str_width(line) > self.fmt.shape.width -- cgit 1.4.1-3-g733a5 From b08130c59070bb9c95128341d712c0e02bba58d9 Mon Sep 17 00:00:00 2001 From: David Bar-On <61089727+davidBar-On@users.noreply.github.com> Date: Sun, 29 Jan 2023 20:55:14 +0200 Subject: Fix #5234 - handling of empty code block (#5601) --- src/comment.rs | 2 +- tests/source/issue-5234.rs | 51 ++++++++++++++++++++++++++++++++++++++++++++++ tests/target/issue-5234.rs | 47 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 tests/source/issue-5234.rs create mode 100644 tests/target/issue-5234.rs (limited to 'src') diff --git a/src/comment.rs b/src/comment.rs index 261fa5e93d8..0677fdc2b89 100644 --- a/src/comment.rs +++ b/src/comment.rs @@ -726,7 +726,7 @@ impl<'a> CommentRewrite<'a> { let code_block = match self.code_block_attr.as_ref().unwrap() { CodeBlockAttribute::Rust if self.fmt.config.format_code_in_doc_comments() - && !self.code_block_buffer.is_empty() => + && !self.code_block_buffer.trim().is_empty() => { let mut config = self.fmt.config.clone(); config.set().wrap_comments(false); diff --git a/tests/source/issue-5234.rs b/tests/source/issue-5234.rs new file mode 100644 index 00000000000..67266f485d3 --- /dev/null +++ b/tests/source/issue-5234.rs @@ -0,0 +1,51 @@ +// rustfmt-format_code_in_doc_comments: true + +/// ``` +/// ``` +fn foo() {} + +/// ``` +///Something +/// ``` +fn foo() {} + +/// ``` +/// +/// ``` +fn foo() {} + + +/// /// ``` +fn foo() {} + +/// /// ``` +/// ``` +/// +/// ``` +/// ``` +fn foo() {} + +fn foo() { +/// ``` +/// +/// ``` +struct bar {} +} + +/// ``` +/// fn com(){ +/// let i = 5; +/// +/// let j = 6; +/// } +/// ``` +fn foo() {} + +fn foo() { +/// ``` +///fn com(){ +///let i = 5; +///} +/// ``` +struct bar {} +} diff --git a/tests/target/issue-5234.rs b/tests/target/issue-5234.rs new file mode 100644 index 00000000000..7ee9e46d1ef --- /dev/null +++ b/tests/target/issue-5234.rs @@ -0,0 +1,47 @@ +// rustfmt-format_code_in_doc_comments: true + +/// ``` +/// ``` +fn foo() {} + +/// ``` +/// Something +/// ``` +fn foo() {} + +/// ``` +/// ``` +fn foo() {} + +/// /// ``` +fn foo() {} + +/// /// ``` +/// ``` +/// ``` +/// ``` +fn foo() {} + +fn foo() { + /// ``` + /// ``` + struct bar {} +} + +/// ``` +/// fn com() { +/// let i = 5; +/// +/// let j = 6; +/// } +/// ``` +fn foo() {} + +fn foo() { + /// ``` + /// fn com() { + /// let i = 5; + /// } + /// ``` + struct bar {} +} -- cgit 1.4.1-3-g733a5 From 61d82acf53c62d19d366c47bead15b8fc67028bc Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Sun, 29 Jan 2023 22:43:40 +0000 Subject: refactor: fix typo in comment (#5581) --- src/bin/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/bin/main.rs b/src/bin/main.rs index be64559e877..8f5d980f561 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -75,7 +75,7 @@ pub enum OperationError { #[error("{0}")] IoError(IoError), /// Attempt to use --emit with a mode which is not currently - /// supported with stdandard input. + /// supported with standard input. #[error("Emit mode {0} not supported with standard output.")] StdinBadEmit(EmitMode), } -- cgit 1.4.1-3-g733a5 From 846662cdb36b5e0663d2be533f5e4178705c982b Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Sat, 30 May 2020 09:36:44 -0700 Subject: Don't wrap comments that are part of a table Closes #4210 --- src/comment.rs | 15 ++++++++++++++- tests/target/issue-4210.rs | 15 +++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 tests/target/issue-4210.rs (limited to 'src') diff --git a/src/comment.rs b/src/comment.rs index 0677fdc2b89..7167783872f 100644 --- a/src/comment.rs +++ b/src/comment.rs @@ -806,7 +806,8 @@ impl<'a> CommentRewrite<'a> { 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) + && !is_table_item(line); if should_wrap_comment { match rewrite_string(line, &self.fmt, self.max_width) { @@ -941,6 +942,18 @@ fn has_url(s: &str) -> bool { || REFERENCE_LINK_URL.is_match(s) } +/// Returns true if the given string may be part of a Markdown talble. +fn is_table_item(mut s: &str) -> bool { + // This function may return false positive, but should get its job done in most cases (i.e. + // markdown tables with two column delimiters). + s = s.trim_start(); + return s.starts_with('|') + && match s.rfind('|') { + Some(0) | None => false, + _ => true, + }; +} + /// Given the span, rewrite the missing comment inside it if available. /// Note that the given span must only include comments (or leading/trailing whitespaces). pub(crate) fn rewrite_missing_comment( diff --git a/tests/target/issue-4210.rs b/tests/target/issue-4210.rs new file mode 100644 index 00000000000..e96ba1b3fd0 --- /dev/null +++ b/tests/target/issue-4210.rs @@ -0,0 +1,15 @@ +// rustfmt-wrap_comments: true + +/// Table that is > 80 symbols: +/// +/// | table | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx | +/// |-------|-----------------------------------------------------------------------------| +/// | val | x | +pub struct Item; + +/// Table that is > 80 symbols: +/// +/// | table | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +/// |-------|----------------------------------------------------------------------------- +/// | val | x +pub struct Item; -- cgit 1.4.1-3-g733a5 From 368a63305cea7a472fec37757bf962cdfc12be26 Mon Sep 17 00:00:00 2001 From: Wim Looman Date: Sat, 10 Sep 2022 13:30:41 +0200 Subject: Fix typo --- src/comment.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/comment.rs b/src/comment.rs index 7167783872f..17b4af1717d 100644 --- a/src/comment.rs +++ b/src/comment.rs @@ -942,7 +942,7 @@ fn has_url(s: &str) -> bool { || REFERENCE_LINK_URL.is_match(s) } -/// Returns true if the given string may be part of a Markdown talble. +/// Returns true if the given string may be part of a Markdown table. fn is_table_item(mut s: &str) -> bool { // This function may return false positive, but should get its job done in most cases (i.e. // markdown tables with two column delimiters). -- cgit 1.4.1-3-g733a5 From e2996a807b411218bb3dca0f2a0e420839cd3875 Mon Sep 17 00:00:00 2001 From: Thaqib <65588695+thaqibm@users.noreply.github.com> Date: Wed, 1 Feb 2023 22:26:12 -0500 Subject: Lists doc comments fix4041 (#5560) * add + start of an itemized line * add test * fix format * fix tests * update doc comment --- src/comment.rs | 5 +++-- tests/source/issue-4041.rs | 5 +++++ tests/target/issue-4041.rs | 6 ++++++ 3 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 tests/source/issue-4041.rs create mode 100644 tests/target/issue-4041.rs (limited to 'src') diff --git a/src/comment.rs b/src/comment.rs index 17b4af1717d..bc0e8774f49 100644 --- a/src/comment.rs +++ b/src/comment.rs @@ -432,7 +432,7 @@ impl CodeBlockAttribute { /// Block that is formatted as an item. /// -/// An item starts with either a star `*` a dash `-` or a greater-than `>`. +/// An item starts with either a star `*` a dash `-` a greater-than `>` or a plus '+'. /// Different level of indentation are handled by shrinking the shape accordingly. struct ItemizedBlock { /// the lines that are identified as part of an itemized block @@ -449,7 +449,8 @@ 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("> ") + let itemized_start = ["* ", "- ", "> ", "+ "]; + itemized_start.iter().any(|s| trimmed.starts_with(s)) } /// Creates a new ItemizedBlock described with the given line. diff --git a/tests/source/issue-4041.rs b/tests/source/issue-4041.rs new file mode 100644 index 00000000000..274b80f1bc5 --- /dev/null +++ b/tests/source/issue-4041.rs @@ -0,0 +1,5 @@ +// rustfmt-wrap_comments: true +//! List: +//! - Sub list: +//! + very long #1 blah blah blah blah blah blah blah blah blah blah blah blah foo baar baxxxxxxxx long line 1231421230912i3091238192038 +//! + very long #2 blah blah blah blah blah blah blah blah blah blah blah blah diff --git a/tests/target/issue-4041.rs b/tests/target/issue-4041.rs new file mode 100644 index 00000000000..e9c693836f2 --- /dev/null +++ b/tests/target/issue-4041.rs @@ -0,0 +1,6 @@ +// rustfmt-wrap_comments: true +//! List: +//! - Sub list: +//! + very long #1 blah blah blah blah blah blah blah blah blah blah blah blah +//! foo baar baxxxxxxxx long line 1231421230912i3091238192038 +//! + very long #2 blah blah blah blah blah blah blah blah blah blah blah blah -- cgit 1.4.1-3-g733a5 From 5391847ea5a12262704657a0708b1674fb344403 Mon Sep 17 00:00:00 2001 From: Rajiv Sharma Date: Sun, 28 Aug 2022 00:36:16 +0100 Subject: Fix #5488 - prevent shorthand init for tuple struct Closes #5488 Fix for #5488. Before applying shorthand initialization for structs, check if identifier is a literal (e.g. tuple struct). If yes, then do not apply short hand initialization. Added test case to validate the changes for the fix. --- src/expr.rs | 6 ++++-- tests/source/issue-5488.rs | 17 +++++++++++++++++ tests/target/issue-5488.rs | 17 +++++++++++++++++ 3 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 tests/source/issue-5488.rs create mode 100644 tests/target/issue-5488.rs (limited to 'src') diff --git a/src/expr.rs b/src/expr.rs index 0be4c3cf168..91f3cc81bae 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -1723,9 +1723,11 @@ pub(crate) fn rewrite_field( let overhead = name.len() + separator.len(); let expr_shape = shape.offset_left(overhead)?; let expr = field.expr.rewrite(context, expr_shape); - + let is_lit = matches!(field.expr.kind, ast::ExprKind::Lit(_)); match expr { - Some(ref e) if e.as_str() == name && context.config.use_field_init_shorthand() => { + Some(ref e) + if !is_lit && e.as_str() == name && context.config.use_field_init_shorthand() => + { Some(attrs_str + name) } Some(e) => Some(format!("{}{}{}{}", attrs_str, name, separator, e)), diff --git a/tests/source/issue-5488.rs b/tests/source/issue-5488.rs new file mode 100644 index 00000000000..d361632e29e --- /dev/null +++ b/tests/source/issue-5488.rs @@ -0,0 +1,17 @@ +// rustfmt-use_field_init_shorthand: true + +struct MyStruct(u32); +struct AnotherStruct { + a: u32, +} + +fn main() { + // Since MyStruct is a tuple struct, it should not be shorthanded to + // MyStruct { 0 } even if use_field_init_shorthand is enabled. + let instance = MyStruct { 0: 0 }; + + // Since AnotherStruct is not a tuple struct, the shorthand should + // apply. + let a = 10; + let instance = AnotherStruct { a: a }; +} diff --git a/tests/target/issue-5488.rs b/tests/target/issue-5488.rs new file mode 100644 index 00000000000..0cb37c56f39 --- /dev/null +++ b/tests/target/issue-5488.rs @@ -0,0 +1,17 @@ +// rustfmt-use_field_init_shorthand: true + +struct MyStruct(u32); +struct AnotherStruct { + a: u32, +} + +fn main() { + // Since MyStruct is a tuple struct, it should not be shorthanded to + // MyStruct { 0 } even if use_field_init_shorthand is enabled. + let instance = MyStruct { 0: 0 }; + + // Since AnotherStruct is not a tuple struct, the shorthand should + // apply. + let a = 10; + let instance = AnotherStruct { a }; +} -- cgit 1.4.1-3-g733a5 From 34f9ca28f2f4ae3ac462c6dcd862b513e107e459 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Wed, 15 Feb 2023 22:24:03 -0600 Subject: fix: use correct span for struct generics --- src/items.rs | 2 +- tests/target/issue_5691.rs | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 tests/target/issue_5691.rs (limited to 'src') diff --git a/src/items.rs b/src/items.rs index 25e8a024857..3c5293b6bf5 100644 --- a/src/items.rs +++ b/src/items.rs @@ -1278,7 +1278,7 @@ pub(crate) fn format_struct_struct( let header_hi = struct_parts.ident.span.hi(); 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()); + let span = span.with_lo(generics.where_clause.span.hi()); context.snippet_provider.span_after(span, "{") } else { context.snippet_provider.span_after(span, "{") diff --git a/tests/target/issue_5691.rs b/tests/target/issue_5691.rs new file mode 100644 index 00000000000..e3aad15db0d --- /dev/null +++ b/tests/target/issue_5691.rs @@ -0,0 +1,16 @@ +struct S +where + [(); { num_slots!(C) }]:, { + /* An asterisk-based, or a double-slash-prefixed, comment here is + required to trigger the fmt bug. + + A single-line triple-slash-prefixed comment (with a field following it) is not enough - it will not trigger the fmt bug. + + Side note: If you have a combination of two, or all three of the + above mentioned types of comments here, some of them disappear + after `cargo fmt`. + + The bug gets triggered even if a field definition following the + (asterisk-based, or a double-slash-prefixed) comment, too. + */ +} -- cgit 1.4.1-3-g733a5 From 475396a03c767a4a3a7e7d3be62f91751c2ba85e Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Thu, 30 Mar 2023 13:00:18 -0400 Subject: Prevent ICE when calling parse_attribute in parse_cfg_if_inner Fixes 5728 Previously we were ignoring the diagnostic error, which lead to the ICE. Now we properly cancel the error. --- src/parse/macros/cfg_if.rs | 5 ++++- tests/rustfmt/main.rs | 12 ++++++++++++ tests/target/issue_5728.rs | 5 +++++ 3 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 tests/target/issue_5728.rs (limited to 'src') diff --git a/src/parse/macros/cfg_if.rs b/src/parse/macros/cfg_if.rs index ace1a76b3fe..ac03409a784 100644 --- a/src/parse/macros/cfg_if.rs +++ b/src/parse/macros/cfg_if.rs @@ -44,7 +44,10 @@ fn parse_cfg_if_inner<'a>( // See also https://github.com/rust-lang/rust/pull/79433 parser .parse_attribute(rustc_parse::parser::attr::InnerAttrPolicy::Permitted) - .map_err(|_| "Failed to parse attributes")?; + .map_err(|e| { + e.cancel(); + "Failed to parse attributes" + })?; } if !parser.eat(&TokenKind::OpenDelim(Delimiter::Brace)) { diff --git a/tests/rustfmt/main.rs b/tests/rustfmt/main.rs index 7ff301e8019..f00b0e09604 100644 --- a/tests/rustfmt/main.rs +++ b/tests/rustfmt/main.rs @@ -174,3 +174,15 @@ fn rustfmt_emits_error_on_line_overflow_true() { "line formatted, but exceeded maximum width (maximum: 100 (see `max_width` option)" )) } + +#[test] +#[allow(non_snake_case)] +fn dont_emit_ICE() { + let files = ["tests/target/issue_5728.rs"]; + + for file in files { + let args = [file]; + let (_stdout, stderr) = rustfmt(&args); + assert!(!stderr.contains("thread 'main' panicked")); + } +} diff --git a/tests/target/issue_5728.rs b/tests/target/issue_5728.rs new file mode 100644 index 00000000000..e1355416faf --- /dev/null +++ b/tests/target/issue_5728.rs @@ -0,0 +1,5 @@ +cfg_if::cfg_if! { + if #[cfg(windows)] { + } else if #(&cpus) { + } else [libc::CTL_HW, libc::HW_NCPU, 0, 0] +} -- cgit 1.4.1-3-g733a5 From a3b2bfc2db33ec3bed266404e6391c145e000df0 Mon Sep 17 00:00:00 2001 From: Greg Jandl Date: Mon, 27 Mar 2023 12:02:02 -0500 Subject: Honor --color option when emitting errors Fixes issue 5717. --- src/parse/session.rs | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/parse/session.rs b/src/parse/session.rs index 6bfec79cd70..1956e1b8cd7 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::config::options::Color; use crate::ignore_path::IgnorePathSet; use crate::parse::parser::{ModError, ModulePathSuccess}; use crate::source_map::LineRangeUtils; @@ -107,15 +108,26 @@ impl Emitter for SilentOnIgnoredFilesEmitter { } } +impl From for ColorConfig { + fn from(color: Color) -> Self { + match color { + Color::Auto => ColorConfig::Auto, + Color::Always => ColorConfig::Always, + Color::Never => ColorConfig::Never, + } + } +} + fn default_handler( source_map: Lrc, ignore_path_set: Lrc, can_reset: Lrc, hide_parse_errors: bool, + color: Color, ) -> Handler { let supports_color = term::stderr().map_or(false, |term| term.supports_color()); - let color_cfg = if supports_color { - ColorConfig::Auto + let emit_color = if supports_color { + ColorConfig::from(color) } else { ColorConfig::Never }; @@ -126,7 +138,7 @@ fn default_handler( let fallback_bundle = rustc_errors::fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false); Box::new(EmitterWriter::stderr( - color_cfg, + emit_color, Some(source_map.clone()), None, fallback_bundle, @@ -164,6 +176,7 @@ impl ParseSess { Lrc::clone(&ignore_path_set), Lrc::clone(&can_reset_errors), config.hide_parse_errors(), + config.color(), ); let parse_sess = RawParseSess::with_span_handler(handler, source_map); -- cgit 1.4.1-3-g733a5 From a44c7ea5923caa8f908ae0fdd6563033a7ad88da Mon Sep 17 00:00:00 2001 From: Lukas Markeffsky <@> Date: Thu, 27 Apr 2023 20:20:18 +0200 Subject: fix broken markdown --- src/config/options.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/config/options.rs b/src/config/options.rs index 257a17b2703..408017d2432 100644 --- a/src/config/options.rs +++ b/src/config/options.rs @@ -18,7 +18,7 @@ pub enum NewlineStyle { Auto, /// Force CRLF (`\r\n`). Windows, - /// Force CR (`\n). + /// Force CR (`\n`). Unix, /// `\r\n` in Windows, `\n` on other platforms. Native, -- cgit 1.4.1-3-g733a5 From 5f9de6bfc9f1a3308d97bf6598acd56229cbe293 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sat, 10 Jun 2023 17:27:24 +0000 Subject: Recover comments between attrs and generic param Fixes #5320. --- src/overflow.rs | 4 ++ src/types.rs | 76 ++++++++++++++++++++++--------------- tests/target/doc-of-generic-item.rs | 18 +++++++++ 3 files changed, 67 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/overflow.rs b/src/overflow.rs index af0b95430a1..d81bf24dbd1 100644 --- a/src/overflow.rs +++ b/src/overflow.rs @@ -589,6 +589,8 @@ impl<'a> Context<'a> { fn rewrite_items(&self) -> Option<(bool, String)> { let span = self.items_span(); + debug!("items: {:?}", self.items); + let items = itemize_list( self.context.snippet_provider, self.items.iter(), @@ -603,6 +605,8 @@ impl<'a> Context<'a> { ); let mut list_items: Vec<_> = items.collect(); + debug!("items: {list_items:?}"); + // Try letting the last argument overflow to the next line with block // indentation. If its first line fits on one line with the other arguments, // we format the function arguments horizontally. diff --git a/src/types.rs b/src/types.rs index 01e2fb6e61e..b4be6546efb 100644 --- a/src/types.rs +++ b/src/types.rs @@ -572,49 +572,41 @@ impl Rewrite for ast::GenericBounds { impl Rewrite for ast::GenericParam { fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option { - 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(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(' '); - } - } - _ => (), - } + let mut result = self.attrs.rewrite(context, shape).unwrap_or(String::new()); + let has_attrs = !result.is_empty(); - if let ast::GenericParamKind::Const { + let mut param = String::with_capacity(128); + + let param_start = if let ast::GenericParamKind::Const { ref ty, - kw_span: _, + kw_span, default, } = &self.kind { - result.push_str("const "); - result.push_str(rewrite_ident(context, self.ident)); - result.push_str(": "); - result.push_str(&ty.rewrite(context, shape)?); + param.push_str("const "); + param.push_str(rewrite_ident(context, self.ident)); + param.push_str(": "); + param.push_str(&ty.rewrite(context, shape)?); if let Some(default) = default { let eq_str = match context.config.type_punctuation_density() { TypeDensity::Compressed => "=", TypeDensity::Wide => " = ", }; - result.push_str(eq_str); - let budget = shape.width.checked_sub(result.len())?; + param.push_str(eq_str); + let budget = shape.width.checked_sub(param.len())?; let rewrite = default.rewrite(context, Shape::legacy(budget, shape.indent))?; - result.push_str(&rewrite); + param.push_str(&rewrite); } + kw_span.lo() } else { - result.push_str(rewrite_ident(context, self.ident)); - } + param.push_str(rewrite_ident(context, self.ident)); + self.ident.span.lo() + }; if !self.bounds.is_empty() { - result.push_str(type_bound_colon(context)); - result.push_str(&self.bounds.rewrite(context, shape)?) + param.push_str(type_bound_colon(context)); + param.push_str(&self.bounds.rewrite(context, shape)?) } if let ast::GenericParamKind::Type { default: Some(ref def), @@ -624,11 +616,33 @@ impl Rewrite for ast::GenericParam { TypeDensity::Compressed => "=", TypeDensity::Wide => " = ", }; - result.push_str(eq_str); - let budget = shape.width.checked_sub(result.len())?; + param.push_str(eq_str); + let budget = shape.width.checked_sub(param.len())?; let rewrite = - def.rewrite(context, Shape::legacy(budget, shape.indent + result.len()))?; - result.push_str(&rewrite); + def.rewrite(context, Shape::legacy(budget, shape.indent + param.len()))?; + param.push_str(&rewrite); + } + + if let Some(last_attr) = self.attrs.last().filter(|last_attr| { + contains_comment(context.snippet(mk_sp(last_attr.span.hi(), param_start))) + }) { + result = combine_strs_with_missing_comments( + context, + &result, + ¶m, + mk_sp(last_attr.span.hi(), param_start), + shape, + !last_attr.is_doc_comment(), + )?; + } else { + // 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 if has_attrs { + result.push(' '); + } + result.push_str(¶m); } Some(result) diff --git a/tests/target/doc-of-generic-item.rs b/tests/target/doc-of-generic-item.rs index 2efc5e09a3d..80886e74f83 100644 --- a/tests/target/doc-of-generic-item.rs +++ b/tests/target/doc-of-generic-item.rs @@ -12,3 +12,21 @@ struct Foo< /// doc of N const N: item, >; + +// 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 + // Non-doc post-comment of 'a + 'a, + // Non-doc pre-comment of T + /// doc of T + // Non-doc post-comment of T + T, + // Non-doc pre-comment of N + /// doc of N + // Non-doc post-comment of N + const N: item, +>; -- cgit 1.4.1-3-g733a5 From 7d48be355a6342690b48fc0675103ae822024e71 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Wed, 12 Apr 2023 18:54:32 +0800 Subject: bump deps to new versions that use syn 2.0 --- Cargo.toml | 6 +++--- src/cargo-fmt/main.rs | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/Cargo.toml b/Cargo.toml index 12ed65453e1..78b970c4c98 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,7 +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"] } +clap = { version = "4.2.1", features = ["derive"] } derive-new = "0.5" diff = "0.1" dirs = "4.0" @@ -48,10 +48,10 @@ itertools = "0.10" lazy_static = "1.4" log = "0.4" regex = "1.5" -serde = { version = "1.0", features = ["derive"] } +serde = { version = "1.0.160", features = ["derive"] } serde_json = "1.0" term = "0.7" -thiserror = "1.0" +thiserror = "1.0.40" toml = "0.5" unicode-segmentation = "1.9" unicode-width = "0.1" diff --git a/src/cargo-fmt/main.rs b/src/cargo-fmt/main.rs index 2b714b68df0..a106181ec7e 100644 --- a/src/cargo-fmt/main.rs +++ b/src/cargo-fmt/main.rs @@ -14,7 +14,7 @@ use std::path::{Path, PathBuf}; use std::process::Command; use std::str; -use clap::{AppSettings, CommandFactory, Parser}; +use clap::{CommandFactory, Parser}; #[path = "test/mod.rs"] #[cfg(test)] @@ -22,7 +22,7 @@ mod cargo_fmt_tests; #[derive(Parser)] #[clap( - global_setting(AppSettings::NoAutoVersion), + disable_version_flag = true, bin_name = "cargo fmt", about = "This utility formats all bin and lib files of \ the current crate using rustfmt." @@ -45,7 +45,7 @@ pub struct Opts { short = 'p', long = "package", value_name = "package", - multiple_values = true + num_args = 1.. )] packages: Vec, -- cgit 1.4.1-3-g733a5 From a463f231f5410ceca88f3eb5dfb8a85b97a63b25 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Wed, 12 Apr 2023 18:55:07 +0800 Subject: remove `derive_new` dependency --- Cargo.lock | 422 +++++++++++++++++++++++++++++++++++------------- Cargo.toml | 1 - src/attr/doc_comment.rs | 7 +- src/formatting.rs | 17 +- src/lib.rs | 2 - src/macros.rs | 5 +- src/pairs.rs | 9 +- 7 files changed, 346 insertions(+), 117 deletions(-) (limited to 'src') diff --git a/Cargo.lock b/Cargo.lock index 5b0fd5ae735..8487dc58b4e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21,6 +21,46 @@ dependencies = [ "yansi-term", ] +[[package]] +name = "anstream" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "342258dd14006105c2b75ab1bd7543a03bdf0cfc94383303ac212a04939dff6f" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-wincon", + "concolor-override", + "concolor-query", + "is-terminal", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23ea9e81bd02e310c216d080f6223c179012256e5151c41db88d12c88a1684d2" + +[[package]] +name = "anstyle-parse" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7d1bb534e9efed14f3e5f44e7dd1a4f709384023a4165199a4241e18dff0116" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-wincon" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3127af6145b149f3287bb9a0d10ad9c5692dba8c53ad48285e5bec4063834fa" +dependencies = [ + "anstyle", + "windows-sys 0.45.0", +] + [[package]] name = "anyhow" version = "1.0.56" @@ -33,17 +73,11 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi", + "hermit-abi 0.1.19", "libc", "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" @@ -99,6 +133,12 @@ dependencies = [ "serde_json", ] +[[package]] +name = "cc" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" + [[package]] name = "cfg-if" version = "1.0.0" @@ -107,53 +147,69 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "3.1.8" +version = "4.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71c47df61d9e16dc010b55dba1952a57d8c215dbb533fd13cdd13369aac73b1c" +checksum = "046ae530c528f252094e4a77886ee1374437744b2bff1497aa898bbddbbb29b3" dependencies = [ - "atty", - "bitflags", + "clap_builder", "clap_derive", - "indexmap", - "lazy_static", - "os_str_bytes", + "once_cell", +] + +[[package]] +name = "clap_builder" +version = "4.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "223163f58c9a40c3b0a43e1c4b50a9ce09f007ea2cb1ec258a687945b4b7929f" +dependencies = [ + "anstream", + "anstyle", + "bitflags", + "clap_lex", "strsim", - "termcolor", - "textwrap", ] [[package]] name = "clap_derive" -version = "3.1.7" +version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3aab4734e083b809aaf5794e14e756d1c798d2c69c7f7de7a09a2f5214993c1" +checksum = "3f9644cd56d6b87dbe899ef8b053e331c0637664e9e21a33dfcdc36093f5c5c4" dependencies = [ "heck", - "proc-macro-error", "proc-macro2", "quote", "syn", ] [[package]] -name = "crossbeam-utils" -version = "0.8.8" +name = "clap_lex" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38" +checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1" + +[[package]] +name = "concolor-override" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a855d4a1978dc52fb0536a04d384c2c0c1aa273597f08b77c8c4d3b2eec6037f" + +[[package]] +name = "concolor-query" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88d11d52c3d7ca2e6d0040212be9e4dbbcd78b6447f535b6b561f449427944cf" dependencies = [ - "cfg-if", - "lazy_static", + "windows-sys 0.45.0", ] [[package]] -name = "derive-new" -version = "0.5.9" +name = "crossbeam-utils" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3418329ca0ad70234b9735dc4ceed10af4df60eff9c8e7b06cb5e520d92c3535" +checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38" dependencies = [ - "proc-macro2", - "quote", - "syn", + "cfg-if", + "lazy_static", ] [[package]] @@ -222,6 +278,27 @@ dependencies = [ "termcolor", ] +[[package]] +name = "errno" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "fnv" version = "1.0.7" @@ -261,12 +338,6 @@ 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.4.0" @@ -282,6 +353,12 @@ dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" + [[package]] name = "humantime" version = "2.1.0" @@ -307,13 +384,26 @@ dependencies = [ ] [[package]] -name = "indexmap" -version = "1.8.1" +name = "io-lifetimes" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee" +checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" dependencies = [ - "autocfg", - "hashbrown", + "hermit-abi 0.3.1", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "is-terminal" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" +dependencies = [ + "hermit-abi 0.3.1", + "io-lifetimes", + "rustix", + "windows-sys 0.48.0", ] [[package]] @@ -339,9 +429,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.122" +version = "0.2.141" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec647867e2bf0772e28c8bcde4f0d19a9216916e890543b5a03ed8ef27b8f259" +checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5" [[package]] name = "libm" @@ -349,6 +439,12 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a" +[[package]] +name = "linux-raw-sys" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d59d8c75012853d2e872fb56bc8a2e53718e2cafe1a4c823143141c6d90c322f" + [[package]] name = "log" version = "0.4.16" @@ -366,18 +462,9 @@ checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" [[package]] name = "once_cell" -version = "1.10.0" +version = "1.17.1" 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", -] +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" [[package]] name = "packed_simd_2" @@ -389,44 +476,20 @@ dependencies = [ "libm", ] -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - [[package]] name = "proc-macro2" -version = "1.0.37" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1" +checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" dependencies = [ - "unicode-xid", + "unicode-ident", ] [[package]] name = "quote" -version = "1.0.17" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "632d02bff7f874a36f33ea8bb416cd484b90cc66c1194b1a1110d067a7013f58" +checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" dependencies = [ "proc-macro2", ] @@ -486,7 +549,6 @@ dependencies = [ "bytecount", "cargo_metadata", "clap", - "derive-new", "diff", "dirs", "env_logger", @@ -507,6 +569,20 @@ dependencies = [ "unicode_categories", ] +[[package]] +name = "rustix" +version = "0.37.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85597d61f83914ddeba6a47b3b8ffe7365107221c2e557ed94426489fefb5f77" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys 0.48.0", +] + [[package]] name = "rustversion" version = "1.0.6" @@ -539,18 +615,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.136" +version = "1.0.160" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" +checksum = "bb2f3770c8bce3bcda7e149193a069a0f4365bda1fa5cd88e03bca26afc1216c" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.136" +version = "1.0.160" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" +checksum = "291a097c63d8497e00160b166a967a4a79c64f3facdd01cbd7502231688d77df" dependencies = [ "proc-macro2", "quote", @@ -576,13 +652,13 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "1.0.91" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d" +checksum = "fcf316d5356ed6847742d036f8a39c3b8435cac10bd528a4bd461928a6ab34d5" dependencies = [ "proc-macro2", "quote", - "unicode-xid", + "unicode-ident", ] [[package]] @@ -605,26 +681,20 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "textwrap" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" - [[package]] name = "thiserror" -version = "1.0.30" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.30" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", @@ -649,6 +719,12 @@ dependencies = [ "serde", ] +[[package]] +name = "unicode-ident" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" + [[package]] name = "unicode-segmentation" version = "1.9.0" @@ -661,12 +737,6 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" -[[package]] -name = "unicode-xid" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" - [[package]] name = "unicode_categories" version = "0.1.1" @@ -674,10 +744,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" [[package]] -name = "version_check" -version = "0.9.4" +name = "utf8parse" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "walkdir" @@ -727,6 +797,138 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.0", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +dependencies = [ + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + [[package]] name = "yansi-term" version = "0.1.2" diff --git a/Cargo.toml b/Cargo.toml index 78b970c4c98..0093b975e86 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,7 +38,6 @@ anyhow = "1.0" bytecount = "0.6" cargo_metadata = "0.14" clap = { version = "4.2.1", features = ["derive"] } -derive-new = "0.5" diff = "0.1" dirs = "4.0" env_logger = "0.9" diff --git a/src/attr/doc_comment.rs b/src/attr/doc_comment.rs index f653a12a8af..25c8158df8c 100644 --- a/src/attr/doc_comment.rs +++ b/src/attr/doc_comment.rs @@ -2,12 +2,17 @@ use crate::comment::CommentStyle; use std::fmt::{self, Display}; /// Formats a string as a doc comment using the given [`CommentStyle`]. -#[derive(new)] pub(super) struct DocCommentFormatter<'a> { literal: &'a str, style: CommentStyle<'a>, } +impl<'a> DocCommentFormatter<'a> { + pub(super) const fn new(literal: &'a str, style: CommentStyle<'a>) -> Self { + Self { literal, style } + } +} + impl Display for DocCommentFormatter<'_> { fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { let opener = self.style.opener().trim_end(); diff --git a/src/formatting.rs b/src/formatting.rs index 1dfd8a514f0..1f4ad6960e2 100644 --- a/src/formatting.rs +++ b/src/formatting.rs @@ -175,7 +175,6 @@ fn format_project( } // Used for formatting files. -#[derive(new)] struct FormatContext<'a, T: FormatHandler> { krate: &'a ast::Crate, report: FormatReport, @@ -185,6 +184,22 @@ struct FormatContext<'a, T: FormatHandler> { } impl<'a, T: FormatHandler + 'a> FormatContext<'a, T> { + fn new( + krate: &'a ast::Crate, + report: FormatReport, + parse_session: ParseSess, + config: &'a Config, + handler: &'a mut T, + ) -> Self { + FormatContext { + krate, + report, + parse_session, + config, + handler, + } + } + fn ignore_file(&self, path: &FileName) -> bool { self.parse_session.ignore_file(path) } diff --git a/src/lib.rs b/src/lib.rs index 487fcc3a0df..0f111f32a4a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,8 +4,6 @@ #![recursion_limit = "256"] #![allow(clippy::match_like_matches_macro)] -#[macro_use] -extern crate derive_new; #[cfg(test)] #[macro_use] extern crate lazy_static; diff --git a/src/macros.rs b/src/macros.rs index d58f7547fef..5e8bbee7722 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -1119,12 +1119,15 @@ pub(crate) fn macro_style(mac: &ast::MacCall, context: &RewriteContext<'_>) -> D // A very simple parser that just parses a macros 2.0 definition into its branches. // Currently we do not attempt to parse any further than that. -#[derive(new)] struct MacroParser { toks: Cursor, } impl MacroParser { + const fn new(toks: Cursor) -> Self { + Self { toks } + } + // (`(` ... `)` `=>` `{` ... `}`)* fn parse(&mut self) -> Option { let mut branches = vec![]; diff --git a/src/pairs.rs b/src/pairs.rs index d1c75126ea4..d135da7e359 100644 --- a/src/pairs.rs +++ b/src/pairs.rs @@ -9,7 +9,7 @@ use crate::utils::{ }; /// Sigils that decorate a binop pair. -#[derive(new, Clone, Copy)] +#[derive(Clone, Copy)] pub(crate) struct PairParts<'a> { prefix: &'a str, infix: &'a str, @@ -17,6 +17,13 @@ pub(crate) struct PairParts<'a> { } impl<'a> PairParts<'a> { + pub(crate) const fn new(prefix: &'a str, infix: &'a str, suffix: &'a str) -> Self { + Self { + prefix, + infix, + suffix, + } + } pub(crate) fn infix(infix: &'a str) -> PairParts<'a> { PairParts { prefix: "", -- cgit 1.4.1-3-g733a5 From ac2ebd3a78246d2dab16aec39d2aaace618a17eb Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Thu, 30 Mar 2023 13:18:28 -0400 Subject: Prevent ICE when calling parse_attribute without an attribute Fixes 5729 `parse_attribute` will panic if the first token is not a `#`. To prevent this we return early instead of trying to parse an invalid attribute. --- src/parse/macros/cfg_if.rs | 5 +++++ tests/rustfmt/main.rs | 2 +- tests/target/issue_5729.rs | 5 +++++ 3 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 tests/target/issue_5729.rs (limited to 'src') diff --git a/src/parse/macros/cfg_if.rs b/src/parse/macros/cfg_if.rs index ac03409a784..cbc4c90b8f9 100644 --- a/src/parse/macros/cfg_if.rs +++ b/src/parse/macros/cfg_if.rs @@ -34,6 +34,11 @@ fn parse_cfg_if_inner<'a>( if !parser.eat_keyword(kw::If) { return Err("Expected `if`"); } + + if !matches!(parser.token.kind, TokenKind::Pound) { + return Err("Failed to parse attributes"); + } + // Inner attributes are not actually syntactically permitted here, but we don't // care about inner vs outer attributes in this position. Our purpose with this // special case parsing of cfg_if macros is to ensure we can correctly resolve diff --git a/tests/rustfmt/main.rs b/tests/rustfmt/main.rs index f00b0e09604..4936a717463 100644 --- a/tests/rustfmt/main.rs +++ b/tests/rustfmt/main.rs @@ -178,7 +178,7 @@ fn rustfmt_emits_error_on_line_overflow_true() { #[test] #[allow(non_snake_case)] fn dont_emit_ICE() { - let files = ["tests/target/issue_5728.rs"]; + let files = ["tests/target/issue_5728.rs", "tests/target/issue_5729.rs"]; for file in files { let args = [file]; diff --git a/tests/target/issue_5729.rs b/tests/target/issue_5729.rs new file mode 100644 index 00000000000..d63c83e88f8 --- /dev/null +++ b/tests/target/issue_5729.rs @@ -0,0 +1,5 @@ +cfg_if::cfg_if! { + if { + } else if #(&cpus) { + } else [libc::CTL_HW, libc::HW_NCPU, 0, 0] +} -- cgit 1.4.1-3-g733a5 From 2c30fa5a8292ab5d32a3b1129c9ab897897b1689 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Tue, 7 Feb 2023 18:43:07 -0500 Subject: Adjust enum variant spans to exclude any explicit discriminant Fixes 5686 For reference, explicit discriminants were proposed in [RFC-2363]. `ast::Variant` spans extend to include explicit discriminants when they are present. Now we'll adjust the span of enum variants to exclude any explicit discriminant. [RFC-2363]: https://rust-lang.github.io/rfcs/2363-arbitrary-enum-discriminant.html --- src/items.rs | 25 ++++++++++++++++++++++--- tests/source/issue_5686.rs | 40 ++++++++++++++++++++++++++++++++++++++++ tests/target/issue_5686.rs | 42 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 104 insertions(+), 3 deletions(-) create mode 100644 tests/source/issue_5686.rs create mode 100644 tests/target/issue_5686.rs (limited to 'src') diff --git a/src/items.rs b/src/items.rs index 3c5293b6bf5..714bcbc10b4 100644 --- a/src/items.rs +++ b/src/items.rs @@ -560,7 +560,7 @@ impl<'a> FmtVisitor<'a> { let variant_body = match field.data { ast::VariantData::Tuple(..) | ast::VariantData::Struct(..) => format_struct( &context, - &StructParts::from_variant(field), + &StructParts::from_variant(field, &context), self.block_indent, Some(one_line_width), )?, @@ -951,14 +951,14 @@ impl<'a> StructParts<'a> { format_header(context, self.prefix, self.ident, self.vis, offset) } - fn from_variant(variant: &'a ast::Variant) -> Self { + fn from_variant(variant: &'a ast::Variant, context: &RewriteContext<'_>) -> Self { StructParts { prefix: "", ident: variant.ident, vis: &DEFAULT_VISIBILITY, def: &variant.data, generics: None, - span: variant.span, + span: enum_variant_span(variant, context), } } @@ -979,6 +979,25 @@ impl<'a> StructParts<'a> { } } +fn enum_variant_span(variant: &ast::Variant, context: &RewriteContext<'_>) -> Span { + use ast::VariantData::*; + if let Some(ref anon_const) = variant.disr_expr { + let span_before_consts = variant.span.until(anon_const.value.span); + let hi = match &variant.data { + Struct(..) => context + .snippet_provider + .span_after_last(span_before_consts, "}"), + Tuple(..) => context + .snippet_provider + .span_after_last(span_before_consts, ")"), + Unit(..) => variant.ident.span.hi(), + }; + mk_sp(span_before_consts.lo(), hi) + } else { + variant.span + } +} + fn format_struct( context: &RewriteContext<'_>, struct_parts: &StructParts<'_>, diff --git a/tests/source/issue_5686.rs b/tests/source/issue_5686.rs new file mode 100644 index 00000000000..3bf96f73b2c --- /dev/null +++ b/tests/source/issue_5686.rs @@ -0,0 +1,40 @@ +#[repr(u8)] +enum MyEnum { + UnitWithExplicitDiscriminant = 0, + EmptyStructSingleLineBlockComment { + /* Comment */ + } = 1, + EmptyStructMultiLineBlockComment { + /* + * Comment + */ + } = 2, + EmptyStructLineComment { + // comment + } = 3, + EmptyTupleSingleLineBlockComment( + /* Comment */ + ) = 4, + EmptyTupleMultiLineBlockComment( + /* + * Comment + */ + ) = 5, + EmptyTupleLineComment( + // comment + ) = 6, +} + +enum Animal { + Dog(/* tuple variant closer in comment -> ) */) = 1, + #[hello(world)] + Cat(/* tuple variant close in leading attribute */) = 2, + Bee(/* tuple variant closer on associated field attribute */ #[hello(world)] usize) = 3, + Fox(/* tuple variant closer on const fn call */) = some_const_fn(), + Ant(/* tuple variant closer on macro call */) = some_macro!(), + Snake {/* stuct variant closer in comment -> } */} = 6, + #[hell{world}] + Cobra {/* struct variant close in leading attribute */} = 6, + Eagle {/* struct variant closer on associated field attribute */ #[hell{world}]value: Sting} = 7, + Koala {/* struct variant closer on macro call */} = some_macro!{} +} diff --git a/tests/target/issue_5686.rs b/tests/target/issue_5686.rs new file mode 100644 index 00000000000..993f12b5316 --- /dev/null +++ b/tests/target/issue_5686.rs @@ -0,0 +1,42 @@ +#[repr(u8)] +enum MyEnum { + UnitWithExplicitDiscriminant = 0, + EmptyStructSingleLineBlockComment {/* Comment */} = 1, + EmptyStructMultiLineBlockComment { + /* + * Comment + */ + } = 2, + EmptyStructLineComment { + // comment + } = 3, + EmptyTupleSingleLineBlockComment(/* Comment */) = 4, + EmptyTupleMultiLineBlockComment( + /* + * Comment + */ + ) = 5, + EmptyTupleLineComment( + // comment + ) = 6, +} + +enum Animal { + Dog(/* tuple variant closer in comment -> ) */) = 1, + #[hello(world)] + Cat(/* tuple variant close in leading attribute */) = 2, + Bee( + /* tuple variant closer on associated field attribute */ #[hello(world)] usize, + ) = 3, + Fox(/* tuple variant closer on const fn call */) = some_const_fn(), + Ant(/* tuple variant closer on macro call */) = some_macro!(), + Snake {/* stuct variant closer in comment -> } */} = 6, + #[hell{world}] + Cobra {/* struct variant close in leading attribute */} = 6, + Eagle { + /* struct variant closer on associated field attribute */ + #[hell{world}] + value: Sting, + } = 7, + Koala {/* struct variant closer on macro call */} = some_macro! {}, +} -- cgit 1.4.1-3-g733a5 From 66b9951dcdc76bbda5e6c75b4a2974d21a9e747f Mon Sep 17 00:00:00 2001 From: KaDiWa Date: Wed, 1 Feb 2023 00:20:15 +0100 Subject: update some dependencies --- Cargo.lock | 98 +++++++++++++++++++++++++++++++------------ Cargo.toml | 6 +-- src/cargo-fmt/main.rs | 7 ++-- src/cargo-fmt/test/targets.rs | 22 +++++----- 4 files changed, 90 insertions(+), 43 deletions(-) (limited to 'src') diff --git a/Cargo.lock b/Cargo.lock index 8487dc58b4e..a59e0b6819b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -68,15 +68,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4361135be9122e0870de935d7c439aef945b9f9ddd4199a553b5270b49c82a27" [[package]] -name = "atty" -version = "0.2.14" +name = "autocfg" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi 0.1.19", - "libc", - "winapi", -] +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "bitflags" @@ -122,15 +117,16 @@ dependencies = [ [[package]] name = "cargo_metadata" -version = "0.14.2" +version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4acbb09d9ee8e23699b9634375c72795d095bf268439da88562cf9b501f181fa" +checksum = "eee4243f1f26fc7a42710e7439c149e2b10b05472f88090acce52632f231a73a" dependencies = [ "camino", "cargo-platform", "semver", "serde", "serde_json", + "thiserror", ] [[package]] @@ -267,12 +263,12 @@ checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" [[package]] name = "env_logger" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" +checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" dependencies = [ - "atty", "humantime", + "is-terminal", "log", "regex", "termcolor", @@ -339,19 +335,16 @@ dependencies = [ ] [[package]] -name = "heck" -version = "0.4.0" +name = "hashbrown" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] -name = "hermit-abi" -version = "0.1.19" +name = "heck" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" [[package]] name = "hermit-abi" @@ -383,13 +376,23 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown", +] + [[package]] name = "io-lifetimes" version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" dependencies = [ - "hermit-abi 0.3.1", + "hermit-abi", "libc", "windows-sys 0.48.0", ] @@ -400,7 +403,7 @@ version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" dependencies = [ - "hermit-abi 0.3.1", + "hermit-abi", "io-lifetimes", "rustix", "windows-sys 0.48.0", @@ -644,6 +647,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_spanned" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93107647184f6027e3b7dcb2e11034cf95ffa1e3a682c67951963ac69c1c007d" +dependencies = [ + "serde", +] + [[package]] name = "strsim" version = "0.10.0" @@ -712,11 +724,36 @@ dependencies = [ [[package]] name = "toml" -version = "0.5.8" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6135d499e69981f9ff0ef2167955a5333c35e36f6937d382974566b3d5b94ec" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a76a9312f5ba4c2dec6b9161fdf25d87ad8a09256ccea5a556fef03c706a10f" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.19.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" +checksum = "2380d56e8670370eee6566b0bfd4265f65b3f432e8c6d85623f728d4fa31f739" dependencies = [ + "indexmap", "serde", + "serde_spanned", + "toml_datetime", + "winnow", ] [[package]] @@ -929,6 +966,15 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +[[package]] +name = "winnow" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca0ace3845f0d96209f0375e6d367e3eb87eb65d27d445bdc9f1843a26f39448" +dependencies = [ + "memchr", +] + [[package]] name = "yansi-term" version = "0.1.2" diff --git a/Cargo.toml b/Cargo.toml index 0093b975e86..5f483693a11 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,11 +36,11 @@ generic-simd = ["bytecount/generic-simd"] annotate-snippets = { version = "0.9", features = ["color"] } anyhow = "1.0" bytecount = "0.6" -cargo_metadata = "0.14" +cargo_metadata = "0.15.4" clap = { version = "4.2.1", features = ["derive"] } diff = "0.1" dirs = "4.0" -env_logger = "0.9" +env_logger = "0.10.0" getopts = "0.2" ignore = "0.4" itertools = "0.10" @@ -51,7 +51,7 @@ serde = { version = "1.0.160", features = ["derive"] } serde_json = "1.0" term = "0.7" thiserror = "1.0.40" -toml = "0.5" +toml = "0.7.4" unicode-segmentation = "1.9" unicode-width = "0.1" unicode_categories = "0.1" diff --git a/src/cargo-fmt/main.rs b/src/cargo-fmt/main.rs index a106181ec7e..bc9745275f2 100644 --- a/src/cargo-fmt/main.rs +++ b/src/cargo-fmt/main.rs @@ -14,6 +14,7 @@ use std::path::{Path, PathBuf}; use std::process::Command; use std::str; +use cargo_metadata::Edition; use clap::{CommandFactory, Parser}; #[path = "test/mod.rs"] @@ -270,7 +271,7 @@ pub struct Target { /// A kind of target (e.g., lib, bin, example, ...). kind: String, /// Rust edition for this target. - edition: String, + edition: Edition, } impl Target { @@ -281,7 +282,7 @@ impl Target { Target { path: canonicalized, kind: target.kind[0].clone(), - edition: target.edition.clone(), + edition: target.edition, } } } @@ -506,7 +507,7 @@ fn run_rustfmt( let mut command = rustfmt_command() .stdout(stdout) .args(files) - .args(&["--edition", edition]) + .args(&["--edition", edition.as_str()]) .args(fmt_args) .spawn() .map_err(|e| match e.kind() { diff --git a/src/cargo-fmt/test/targets.rs b/src/cargo-fmt/test/targets.rs index b7e7fabdf71..34accb2136a 100644 --- a/src/cargo-fmt/test/targets.rs +++ b/src/cargo-fmt/test/targets.rs @@ -2,7 +2,7 @@ use super::*; struct ExpTarget { path: &'static str, - edition: &'static str, + edition: Edition, kind: &'static str, } @@ -26,7 +26,7 @@ mod all_targets { for target in exp_targets { assert!(targets.contains(&Target { path: get_path(target.path), - edition: target.edition.to_owned(), + edition: target.edition, kind: target.kind.to_owned(), })); } @@ -39,17 +39,17 @@ mod all_targets { let exp_targets = vec![ ExpTarget { path: "dependency-dir-name/subdep-dir-name/src/lib.rs", - edition: "2018", + edition: Edition::E2018, kind: "lib", }, ExpTarget { path: "dependency-dir-name/src/lib.rs", - edition: "2018", + edition: Edition::E2018, kind: "lib", }, ExpTarget { path: "src/main.rs", - edition: "2018", + edition: Edition::E2018, kind: "main", }, ]; @@ -79,32 +79,32 @@ mod all_targets { let exp_targets = vec![ ExpTarget { path: "ws/a/src/main.rs", - edition: "2018", + edition: Edition::E2018, kind: "bin", }, ExpTarget { path: "ws/b/src/main.rs", - edition: "2018", + edition: Edition::E2018, kind: "bin", }, ExpTarget { path: "ws/c/src/lib.rs", - edition: "2018", + edition: Edition::E2018, kind: "lib", }, ExpTarget { path: "ws/a/d/src/lib.rs", - edition: "2018", + edition: Edition::E2018, kind: "lib", }, ExpTarget { path: "e/src/main.rs", - edition: "2018", + edition: Edition::E2018, kind: "main", }, ExpTarget { path: "ws/a/d/f/src/lib.rs", - edition: "2018", + edition: Edition::E2018, kind: "lib", }, ]; -- cgit 1.4.1-3-g733a5 From f4201ef2cb89c28bcdb82cab292720eb66b75695 Mon Sep 17 00:00:00 2001 From: Lukasz Anforowicz Date: Mon, 10 Oct 2022 16:33:31 +0000 Subject: Handling of numbered markdown lists. Fixes issue #5416 --- src/comment.rs | 174 ++++++++++++++++++++++++++++---- tests/source/itemized-blocks/no_wrap.rs | 36 ++++++- tests/source/itemized-blocks/wrap.rs | 36 ++++++- tests/target/itemized-blocks/no_wrap.rs | 36 ++++++- tests/target/itemized-blocks/wrap.rs | 62 +++++++++++- 5 files changed, 319 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/comment.rs b/src/comment.rs index bc0e8774f49..85918ecc116 100644 --- a/src/comment.rs +++ b/src/comment.rs @@ -432,12 +432,18 @@ impl CodeBlockAttribute { /// Block that is formatted as an item. /// -/// An item starts with either a star `*` a dash `-` a greater-than `>` or a plus '+'. +/// An item starts with either a star `*`, a dash `-`, a greater-than `>`, a plus '+', or a number +/// `12.` or `34)` (with at most 2 digits). An item represents CommonMark's ["list +/// items"](https://spec.commonmark.org/0.30/#list-items) and/or ["block +/// quotes"](https://spec.commonmark.org/0.30/#block-quotes), but note that only a subset of +/// CommonMark is recognized - see the doc comment of [`ItemizedBlock::get_marker_length`] for more +/// details. +/// /// 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 characters (typically whitespaces) up to the item sigil + /// the number of characters (typically whitespaces) up to the item marker indent: usize, /// the string that marks the start of an item opener: String, @@ -446,37 +452,70 @@ struct ItemizedBlock { } impl ItemizedBlock { - /// Returns `true` if the line is formatted as an item - fn is_itemized_line(line: &str) -> bool { - let trimmed = line.trim_start(); + /// Checks whether the `trimmed` line includes an item marker. Returns `None` if there is no + /// marker. Returns the length of the marker (in bytes) if one is present. Note that the length + /// includes the whitespace that follows the marker, for example the marker in `"* list item"` + /// has the length of 2. + /// + /// This function recognizes item markers that correspond to CommonMark's + /// ["bullet list marker"](https://spec.commonmark.org/0.30/#bullet-list-marker), + /// ["block quote marker"](https://spec.commonmark.org/0.30/#block-quote-marker), and/or + /// ["ordered list marker"](https://spec.commonmark.org/0.30/#ordered-list-marker). + /// + /// Compared to CommonMark specification, the number of digits that are allowed in an ["ordered + /// list marker"](https://spec.commonmark.org/0.30/#ordered-list-marker) is more limited (to at + /// most 2 digits). Limiting the length of the marker helps reduce the risk of recognizing + /// arbitrary numbers as markers. See also + /// which gives the + /// following example where a number (i.e. "1868") doesn't signify an ordered list: + /// ```md + /// The Captain died in + /// 1868. He wes buried in... + /// ``` + fn get_marker_length(trimmed: &str) -> Option { + // https://spec.commonmark.org/0.30/#bullet-list-marker or + // https://spec.commonmark.org/0.30/#block-quote-marker let itemized_start = ["* ", "- ", "> ", "+ "]; - itemized_start.iter().any(|s| trimmed.starts_with(s)) + if itemized_start.iter().any(|s| trimmed.starts_with(s)) { + return Some(2); // All items in `itemized_start` have length 2. + } + + // https://spec.commonmark.org/0.30/#ordered-list-marker, where at most 2 digits are + // allowed. + for suffix in [". ", ") "] { + if let Some((prefix, _)) = trimmed.split_once(suffix) { + if prefix.len() <= 2 && prefix.chars().all(|c| char::is_ascii_digit(&c)) { + return Some(prefix.len() + suffix.len()); + } + } + } + + None // No markers found. } - /// 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(); - // +2 = '* ', which will add the appropriate amount of whitespace to keep itemized - // content formatted correctly. - let mut indent = space_to_sigil + 2; + /// Creates a new `ItemizedBlock` described with the given `line`. + /// Returns `None` if `line` doesn't start an item. + fn new(line: &str) -> Option { + let marker_length = ItemizedBlock::get_marker_length(line.trim_start())?; + let space_to_marker = line.chars().take_while(|c| c.is_whitespace()).count(); + let mut indent = space_to_marker + marker_length; 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 the 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 { + Some(ItemizedBlock { lines: vec![line[indent..].to_string()], indent, opener: line[..indent].to_string(), line_start, - } + }) } /// Returns a `StringFormat` used for formatting the content of an item. @@ -495,7 +534,7 @@ impl ItemizedBlock { /// Returns `true` if the line is part of the current itemized block. /// If it is, then it is added to the internal lines list. fn add_line(&mut self, line: &str) -> bool { - if !ItemizedBlock::is_itemized_line(line) + if ItemizedBlock::get_marker_length(line.trim_start()).is_none() && self.indent <= line.chars().take_while(|c| c.is_whitespace()).count() { self.lines.push(line.to_string()); @@ -766,10 +805,11 @@ impl<'a> CommentRewrite<'a> { self.item_block = None; if let Some(stripped) = line.strip_prefix("```") { self.code_block_attr = Some(CodeBlockAttribute::new(stripped)) - } else if self.fmt.config.wrap_comments() && ItemizedBlock::is_itemized_line(line) { - let ib = ItemizedBlock::new(line); - self.item_block = Some(ib); - return false; + } else if self.fmt.config.wrap_comments() { + if let Some(ib) = ItemizedBlock::new(line) { + self.item_block = Some(ib); + return false; + } } if self.result == self.opener { @@ -2020,4 +2060,96 @@ fn main() { "#; assert_eq!(s, filter_normal_code(s_with_comment)); } + + #[test] + fn test_itemized_block_first_line_handling() { + fn run_test( + test_input: &str, + expected_line: &str, + expected_indent: usize, + expected_opener: &str, + expected_line_start: &str, + ) { + let block = ItemizedBlock::new(test_input).unwrap(); + assert_eq!(1, block.lines.len(), "test_input: {:?}", test_input); + assert_eq!( + expected_line, &block.lines[0], + "test_input: {:?}", + test_input + ); + assert_eq!( + expected_indent, block.indent, + "test_input: {:?}", + test_input + ); + assert_eq!( + expected_opener, &block.opener, + "test_input: {:?}", + test_input + ); + assert_eq!( + expected_line_start, &block.line_start, + "test_input: {:?}", + test_input + ); + } + + run_test("- foo", "foo", 2, "- ", " "); + run_test("* foo", "foo", 2, "* ", " "); + run_test("> foo", "foo", 2, "> ", "> "); + + run_test("1. foo", "foo", 3, "1. ", " "); + run_test("12. foo", "foo", 4, "12. ", " "); + run_test("1) foo", "foo", 3, "1) ", " "); + run_test("12) foo", "foo", 4, "12) ", " "); + + run_test(" - foo", "foo", 6, " - ", " "); + + // https://spec.commonmark.org/0.30 says: "A start number may begin with 0s": + run_test("0. foo", "foo", 3, "0. ", " "); + run_test("01. foo", "foo", 4, "01. ", " "); + } + + #[test] + fn test_itemized_block_nonobvious_markers_are_rejected() { + let test_inputs = vec![ + // Non-numeric item markers (e.g. `a.` or `iv.`) are not allowed by + // https://spec.commonmark.org/0.30/#ordered-list-marker. We also note that allowing + // them would risk misidentifying regular words as item markers. See also the + // discussion in https://talk.commonmark.org/t/blank-lines-before-lists-revisited/1990 + "word. rest of the paragraph.", + "a. maybe this is a list item? maybe not?", + "iv. maybe this is a list item? maybe not?", + // Numbers with 3 or more digits are not recognized as item markers, to avoid + // formatting the following example as a list: + // + // ``` + // The Captain died in + // 1868. He was buried in... + // ``` + "123. only 2-digit numbers are recognized as item markers.", + // Parens: + "123) giving some coverage to parens as well.", + "a) giving some coverage to parens as well.", + // https://spec.commonmark.org/0.30 says that "at least one space or tab is needed + // between the list marker and any following content": + "1.Not a list item.", + "1.2.3. Not a list item.", + "1)Not a list item.", + "-Not a list item.", + "+Not a list item.", + "+1 not a list item.", + // https://spec.commonmark.org/0.30 says: "A start number may not be negative": + "-1. Not a list item.", + "-1 Not a list item.", + ]; + for line in test_inputs.iter() { + let maybe_block = ItemizedBlock::new(line); + assert!( + maybe_block.is_none(), + "The following line shouldn't be classified as a list item: {}", + line + ); + } + } } diff --git a/tests/source/itemized-blocks/no_wrap.rs b/tests/source/itemized-blocks/no_wrap.rs index a7b6a10a010..e5699e76684 100644 --- a/tests/source/itemized-blocks/no_wrap.rs +++ b/tests/source/itemized-blocks/no_wrap.rs @@ -1,7 +1,7 @@ // rustfmt-normalize_comments: true // rustfmt-format_code_in_doc_comments: true -//! This is a list: +//! This is an itemized markdown list (see also issue #3224): //! * Outer //! * Outer //! * Inner @@ -13,6 +13,40 @@ //! - when the log level is info, the level name is green and the rest of the line is white //! - when the log level is debug, the whole line is white //! - when the log level is trace, the whole line is gray ("bright black") +//! +//! This is a numbered markdown list (see also issue #5416): +//! 1. Long long long long long long long long long long long long long long long long long line +//! 2. Another very long long long long long long long long long long long long long long long line +//! 3. Nested list +//! 1. Long long long long long long long long long long long long long long long long line +//! 2. Another very long long long long long long long long long long long long long long line +//! 4. Last item +//! +//! Using the ')' instead of '.' character after the number: +//! 1) Long long long long long long long long long long long long long long long long long line +//! 2) Another very long long long long long long long long long long long long long long long line +//! +//! Deep list that mixes various bullet and number formats: +//! 1. First level with a long long long long long long long long long long long long long long +//! long long long line +//! 2. First level with another very long long long long long long long long long long long long +//! long long long line +//! * Second level with a long long long long long long long long long long long long long +//! long long long line +//! * Second level with another very long long long long long long long long long long long +//! long long long line +//! 1) Third level with a long long long long long long long long long long long long long +//! long long long line +//! 2) Third level with another very long long long long long long long long long long +//! long long long long line +//! - Forth level with a long long long long long long long long long long long long +//! long long long long line +//! - Forth level with another very long long long long long long long long long long +//! long long long long line +//! 3) One more item at the third level +//! 4) Last item of the third level +//! * Last item of second level +//! 3. Last item of first level /// All the parameters ***except for `from_theater`*** should be inserted as sent by the remote /// theater, i.e., as passed to [`Theater::send`] on the remote actor: diff --git a/tests/source/itemized-blocks/wrap.rs b/tests/source/itemized-blocks/wrap.rs index 955cc698b79..768461a43f9 100644 --- a/tests/source/itemized-blocks/wrap.rs +++ b/tests/source/itemized-blocks/wrap.rs @@ -2,7 +2,7 @@ // rustfmt-format_code_in_doc_comments: true // rustfmt-max_width: 50 -//! This is a list: +//! This is an itemized markdown list (see also issue #3224): //! * Outer //! * Outer //! * Inner @@ -14,6 +14,40 @@ //! - when the log level is info, the level name is green and the rest of the line is white //! - when the log level is debug, the whole line is white //! - when the log level is trace, the whole line is gray ("bright black") +//! +//! This is a numbered markdown list (see also issue #5416): +//! 1. Long long long long long long long long long long long long long long long long long line +//! 2. Another very long long long long long long long long long long long long long long long line +//! 3. Nested list +//! 1. Long long long long long long long long long long long long long long long long line +//! 2. Another very long long long long long long long long long long long long long long line +//! 4. Last item +//! +//! Using the ')' instead of '.' character after the number: +//! 1) Long long long long long long long long long long long long long long long long long line +//! 2) Another very long long long long long long long long long long long long long long long line +//! +//! Deep list that mixes various bullet and number formats: +//! 1. First level with a long long long long long long long long long long long long long long +//! long long long line +//! 2. First level with another very long long long long long long long long long long long long +//! long long long line +//! * Second level with a long long long long long long long long long long long long long +//! long long long line +//! * Second level with another very long long long long long long long long long long long +//! long long long line +//! 1) Third level with a long long long long long long long long long long long long long +//! long long long line +//! 2) Third level with another very long long long long long long long long long long +//! long long long long line +//! - Forth level with a long long long long long long long long long long long long +//! long long long long line +//! - Forth level with another very long long long long long long long long long long +//! long long long long line +//! 3) One more item at the third level +//! 4) Last item of the third level +//! * Last item of second level +//! 3. Last item of first level // This example shows how to configure fern to output really nicely colored logs // - when the log level is error, the whole line is red diff --git a/tests/target/itemized-blocks/no_wrap.rs b/tests/target/itemized-blocks/no_wrap.rs index de885638272..86818b44745 100644 --- a/tests/target/itemized-blocks/no_wrap.rs +++ b/tests/target/itemized-blocks/no_wrap.rs @@ -1,7 +1,7 @@ // rustfmt-normalize_comments: true // rustfmt-format_code_in_doc_comments: true -//! This is a list: +//! This is an itemized markdown list (see also issue #3224): //! * Outer //! * Outer //! * Inner @@ -13,6 +13,40 @@ //! - when the log level is info, the level name is green and the rest of the line is white //! - when the log level is debug, the whole line is white //! - when the log level is trace, the whole line is gray ("bright black") +//! +//! This is a numbered markdown list (see also issue #5416): +//! 1. Long long long long long long long long long long long long long long long long long line +//! 2. Another very long long long long long long long long long long long long long long long line +//! 3. Nested list +//! 1. Long long long long long long long long long long long long long long long long line +//! 2. Another very long long long long long long long long long long long long long long line +//! 4. Last item +//! +//! Using the ')' instead of '.' character after the number: +//! 1) Long long long long long long long long long long long long long long long long long line +//! 2) Another very long long long long long long long long long long long long long long long line +//! +//! Deep list that mixes various bullet and number formats: +//! 1. First level with a long long long long long long long long long long long long long long +//! long long long line +//! 2. First level with another very long long long long long long long long long long long long +//! long long long line +//! * Second level with a long long long long long long long long long long long long long +//! long long long line +//! * Second level with another very long long long long long long long long long long long +//! long long long line +//! 1) Third level with a long long long long long long long long long long long long long +//! long long long line +//! 2) Third level with another very long long long long long long long long long long +//! long long long long line +//! - Forth level with a long long long long long long long long long long long long +//! long long long long line +//! - Forth level with another very long long long long long long long long long long +//! long long long long line +//! 3) One more item at the third level +//! 4) Last item of the third level +//! * Last item of second level +//! 3. Last item of first level /// All the parameters ***except for `from_theater`*** should be inserted as sent by the remote /// theater, i.e., as passed to [`Theater::send`] on the remote actor: diff --git a/tests/target/itemized-blocks/wrap.rs b/tests/target/itemized-blocks/wrap.rs index a4907303c9e..4826590ea59 100644 --- a/tests/target/itemized-blocks/wrap.rs +++ b/tests/target/itemized-blocks/wrap.rs @@ -2,7 +2,8 @@ // rustfmt-format_code_in_doc_comments: true // rustfmt-max_width: 50 -//! This is a list: +//! This is an itemized markdown list (see also +//! issue #3224): //! * Outer //! * Outer //! * Inner @@ -23,6 +24,65 @@ //! is white //! - when the log level is trace, the whole line //! is gray ("bright black") +//! +//! This is a numbered markdown list (see also +//! issue #5416): +//! 1. Long long long long long long long long +//! long long long long long long long long +//! long line +//! 2. Another very long long long long long long +//! long long long long long long long long +//! long line +//! 3. Nested list +//! 1. Long long long long long long long long +//! long long long long long long long long +//! line +//! 2. Another very long long long long long +//! long long long long long long long long +//! long line +//! 4. Last item +//! +//! Using the ')' instead of '.' character after +//! the number: +//! 1) Long long long long long long long long +//! long long long long long long long long +//! long line +//! 2) Another very long long long long long long +//! long long long long long long long long +//! long line +//! +//! Deep list that mixes various bullet and number +//! formats: +//! 1. First level with a long long long long long +//! long long long long long long long long +//! long long long long line +//! 2. First level with another very long long +//! long long long long long long long long +//! long long long long long line +//! * Second level with a long long long long +//! long long long long long long long long +//! long long long long line +//! * Second level with another very long long +//! long long long long long long long long +//! long long long long line +//! 1) Third level with a long long long +//! long long long long long long long +//! long long long long long long line +//! 2) Third level with another very long +//! long long long long long long long +//! long long long long long long line +//! - Forth level with a long long +//! long long long long long long +//! long long long long long long +//! long long line +//! - Forth level with another very +//! long long long long long long +//! long long long long long long +//! long long line +//! 3) One more item at the third level +//! 4) Last item of the third level +//! * Last item of second level +//! 3. Last item of first level // This example shows how to configure fern to // output really nicely colored logs -- cgit 1.4.1-3-g733a5 From 0b17d7ea4605fcd3675c80069e0b5e82c4332b05 Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Mon, 19 Jun 2023 21:29:15 -0500 Subject: chore: address merge and bump toolchain --- config_proc_macro/src/attrs.rs | 7 ------- rust-toolchain | 2 +- src/macros.rs | 2 +- 3 files changed, 2 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/config_proc_macro/src/attrs.rs b/config_proc_macro/src/attrs.rs index 2c01b9a1321..d8de9aae088 100644 --- a/config_proc_macro/src/attrs.rs +++ b/config_proc_macro/src/attrs.rs @@ -64,13 +64,6 @@ fn is_attr_path(attr: &syn::Attribute, name: &str) -> bool { } } -fn is_attr_path(attr: &syn::Attribute, name: &str) -> bool { - attr.parse_meta().ok().map_or(false, |meta| match meta { - syn::Meta::Path(path) if path.is_ident(name) => true, - _ => false, - }) -} - fn get_name_value_str_lit(attr: &syn::Attribute, name: &str) -> Option { match &attr.meta { syn::Meta::NameValue(syn::MetaNameValue { diff --git a/rust-toolchain b/rust-toolchain index 22283b3d620..03b909cd80c 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2023-01-24" +channel = "nightly-2023-06-19" components = ["llvm-tools", "rustc-dev"] diff --git a/src/macros.rs b/src/macros.rs index 9f4beae7350..e9a298a2769 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -1124,7 +1124,7 @@ struct MacroParser { } impl MacroParser { - const fn new(toks: Cursor) -> Self { + const fn new(toks: TokenTreeCursor) -> Self { Self { toks } } -- cgit 1.4.1-3-g733a5 From 75870c55b94b1b927445a35131462fb9db402fd3 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Sun, 12 Feb 2023 13:51:50 -0500 Subject: Extract logic for rewriting `else` keyword into function The function properly handles recovering comments before and after the `else` keyword, and properly handles how to write the else when users configure `control_brace_style`. --- src/expr.rs | 80 ++++++++++++++++++++++++++++-------------------- tests/source/let_else.rs | 3 -- tests/target/let_else.rs | 3 -- 3 files changed, 46 insertions(+), 40 deletions(-) delete mode 100644 tests/source/let_else.rs delete mode 100644 tests/target/let_else.rs (limited to 'src') diff --git a/src/expr.rs b/src/expr.rs index e179b4646ef..aa81d6a93cc 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -1004,6 +1004,46 @@ impl<'a> ControlFlow<'a> { } } +/// Rewrite the `else` keyword with surrounding comments. +/// +/// is_last: true if this is an `else` and `false` if this is an `else if` block. +/// context: rewrite context +/// span: Span between the end of the last expression and the start of the else block, +/// which contains the `else` keyword +/// shape: Shape +pub(crate) fn rewrite_else_kw_with_comments( + is_last: bool, + context: &RewriteContext<'_>, + span: Span, + shape: Shape, +) -> String { + let else_kw_lo = context.snippet_provider.span_before(span, "else"); + let before_else_kw = mk_sp(span.lo(), else_kw_lo); + let before_else_kw_comment = extract_comment(before_else_kw, context, shape); + + let else_kw_hi = context.snippet_provider.span_after(span, "else"); + let after_else_kw = mk_sp(else_kw_hi, span.hi()); + let after_else_kw_comment = extract_comment(after_else_kw, context, shape); + + let newline_sep = &shape.indent.to_string_with_newline(context.config); + let before_sep = match context.config.control_brace_style() { + ControlBraceStyle::AlwaysNextLine | ControlBraceStyle::ClosingNextLine => { + newline_sep.as_ref() + } + ControlBraceStyle::AlwaysSameLine => " ", + }; + let after_sep = match context.config.control_brace_style() { + ControlBraceStyle::AlwaysNextLine if is_last => newline_sep.as_ref(), + _ => " ", + }; + + format!( + "{}else{}", + before_else_kw_comment.as_ref().map_or(before_sep, |s| &**s), + after_else_kw_comment.as_ref().map_or(after_sep, |s| &**s), + ) +} + impl<'a> Rewrite for ControlFlow<'a> { fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option { debug!("ControlFlow::rewrite {:?} {:?}", self, shape); @@ -1070,41 +1110,13 @@ impl<'a> Rewrite for ControlFlow<'a> { } }; - let between_kwd_else_block = mk_sp( - self.block.span.hi(), - context - .snippet_provider - .span_before(mk_sp(self.block.span.hi(), else_block.span.lo()), "else"), - ); - let between_kwd_else_block_comment = - extract_comment(between_kwd_else_block, context, shape); - - let after_else = mk_sp( - context - .snippet_provider - .span_after(mk_sp(self.block.span.hi(), else_block.span.lo()), "else"), - else_block.span.lo(), + let else_kw = rewrite_else_kw_with_comments( + last_in_chain, + context, + self.block.span.between(else_block.span), + shape, ); - let after_else_comment = extract_comment(after_else, context, shape); - - let between_sep = match context.config.control_brace_style() { - ControlBraceStyle::AlwaysNextLine | ControlBraceStyle::ClosingNextLine => { - &*alt_block_sep - } - ControlBraceStyle::AlwaysSameLine => " ", - }; - let after_sep = match context.config.control_brace_style() { - ControlBraceStyle::AlwaysNextLine if last_in_chain => &*alt_block_sep, - _ => " ", - }; - - result.push_str(&format!( - "{}else{}", - between_kwd_else_block_comment - .as_ref() - .map_or(between_sep, |s| &**s), - after_else_comment.as_ref().map_or(after_sep, |s| &**s), - )); + result.push_str(&else_kw); result.push_str(&rewrite?); } diff --git a/tests/source/let_else.rs b/tests/source/let_else.rs deleted file mode 100644 index a6e816fb524..00000000000 --- a/tests/source/let_else.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - let Some(1) = Some(1) else { return }; -} diff --git a/tests/target/let_else.rs b/tests/target/let_else.rs deleted file mode 100644 index a6e816fb524..00000000000 --- a/tests/target/let_else.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - let Some(1) = Some(1) else { return }; -} -- cgit 1.4.1-3-g733a5 From 9316df0ca2e709258d0d146fb311b24222116547 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Mon, 16 Jan 2023 12:19:47 -0500 Subject: Initial pass at implementing let-else --- src/items.rs | 20 +++++++++++++++----- tests/source/let_else.rs | 10 ++++++++++ tests/target/let_else.rs | 12 ++++++++++++ 3 files changed, 37 insertions(+), 5 deletions(-) create mode 100644 tests/source/let_else.rs create mode 100644 tests/target/let_else.rs (limited to 'src') diff --git a/src/items.rs b/src/items.rs index 3ecdb5b4c60..75c42605ccf 100644 --- a/src/items.rs +++ b/src/items.rs @@ -18,7 +18,7 @@ use crate::config::lists::*; use crate::config::{BraceStyle, Config, IndentStyle, Version}; use crate::expr::{ is_empty_block, is_simple_block_stmt, rewrite_assign_rhs, rewrite_assign_rhs_with, - rewrite_assign_rhs_with_comments, RhsAssignKind, RhsTactics, + rewrite_assign_rhs_with_comments, rewrite_else_kw_with_comments, RhsAssignKind, RhsTactics, }; use crate::lists::{definitive_tactic, itemize_list, write_list, ListFormatting, Separator}; use crate::macros::{rewrite_macro, MacroPosition}; @@ -44,7 +44,7 @@ fn type_annotation_separator(config: &Config) -> &str { } // Statements of the form -// let pat: ty = init; +// let pat: ty = init; or let pat: ty = init else { .. }; impl Rewrite for ast::Local { fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option { debug!( @@ -54,7 +54,7 @@ impl Rewrite for ast::Local { skip_out_of_file_lines_range!(context, self.span); - if contains_skip(&self.attrs) || matches!(self.kind, ast::LocalKind::InitElse(..)) { + if contains_skip(&self.attrs) { return None; } @@ -112,7 +112,7 @@ impl Rewrite for ast::Local { result.push_str(&infix); - if let Some((init, _els)) = self.kind.init_else_opt() { + if let Some((init, else_block)) = self.kind.init_else_opt() { // 1 = trailing semicolon; let nested_shape = shape.sub_width(1)?; @@ -123,7 +123,17 @@ impl Rewrite for ast::Local { &RhsAssignKind::Expr(&init.kind, init.span), nested_shape, )?; - // todo else + + if let Some(block) = else_block { + let else_kw = rewrite_else_kw_with_comments( + true, + context, + init.span.between(block.span), + shape, + ); + result.push_str(&else_kw); + result.push_str(&block.rewrite(context, shape)?); + }; } result.push(';'); diff --git a/tests/source/let_else.rs b/tests/source/let_else.rs new file mode 100644 index 00000000000..26e0ebf0736 --- /dev/null +++ b/tests/source/let_else.rs @@ -0,0 +1,10 @@ +fn main() { + let Some(x) = opt else { return }; + + let Some(x) = opt else { return; }; + + let Some(x) = opt else { + // nope + return; + }; +} diff --git a/tests/target/let_else.rs b/tests/target/let_else.rs new file mode 100644 index 00000000000..a910f5389a3 --- /dev/null +++ b/tests/target/let_else.rs @@ -0,0 +1,12 @@ +fn main() { + let Some(x) = opt else { return }; + + let Some(x) = opt else { + return; + }; + + let Some(x) = opt else { + // nope + return; + }; +} -- cgit 1.4.1-3-g733a5 From 8be748dbb7bd95547bc770e2b0c75b7568ba97e6 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Sun, 12 Feb 2023 14:31:38 -0500 Subject: Allow callers to determine if blocks can be formatted on a single line This will make it easier to format the divergent blocks of `let-else` statements since it'll be easier to prevent the block from being formatted on a single line if the preconditions aren't met. --- src/expr.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/expr.rs b/src/expr.rs index aa81d6a93cc..eadaf206781 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -575,6 +575,17 @@ fn rewrite_block( label: Option, context: &RewriteContext<'_>, shape: Shape, +) -> Option { + rewrite_block_inner(block, attrs, label, true, context, shape) +} + +fn rewrite_block_inner( + block: &ast::Block, + attrs: Option<&[ast::Attribute]>, + label: Option, + allow_single_line: bool, + context: &RewriteContext<'_>, + shape: Shape, ) -> Option { let prefix = block_prefix(context, block, shape)?; @@ -586,7 +597,7 @@ fn rewrite_block( let result = rewrite_block_with_visitor(context, &prefix, block, attrs, label, shape, true); if let Some(ref result_str) = result { - if result_str.lines().count() <= 3 { + if allow_single_line && result_str.lines().count() <= 3 { if let rw @ Some(_) = rewrite_single_line_block(context, &prefix, block, attrs, label, shape) { -- cgit 1.4.1-3-g733a5 From 7a3e4fca4003ab3f0ccfddaa0a92969e676a2881 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Sun, 12 Feb 2023 14:46:06 -0500 Subject: Implement `let-else` rewriting in terms of rewrite_let_else_block `rewrite_let_else_block` gives us more control over allowing the `else` block to be formatted on a single line than `::rewrite`. --- src/expr.rs | 10 ++++++++++ src/items.rs | 11 +++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/expr.rs b/src/expr.rs index eadaf206781..a4e60659a0e 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -609,6 +609,16 @@ fn rewrite_block_inner( result } +/// Rewrite the divergent block of a `let-else` statement. +pub(crate) fn rewrite_let_else_block( + block: &ast::Block, + allow_single_line: bool, + context: &RewriteContext<'_>, + shape: Shape, +) -> Option { + rewrite_block_inner(block, None, None, allow_single_line, context, shape) +} + // Rewrite condition if the given expression has one. pub(crate) fn rewrite_cond( context: &RewriteContext<'_>, diff --git a/src/items.rs b/src/items.rs index 75c42605ccf..4693e57b8a1 100644 --- a/src/items.rs +++ b/src/items.rs @@ -18,7 +18,8 @@ use crate::config::lists::*; use crate::config::{BraceStyle, Config, IndentStyle, Version}; use crate::expr::{ is_empty_block, is_simple_block_stmt, rewrite_assign_rhs, rewrite_assign_rhs_with, - rewrite_assign_rhs_with_comments, rewrite_else_kw_with_comments, RhsAssignKind, RhsTactics, + rewrite_assign_rhs_with_comments, rewrite_else_kw_with_comments, rewrite_let_else_block, + RhsAssignKind, RhsTactics, }; use crate::lists::{definitive_tactic, itemize_list, write_list, ListFormatting, Separator}; use crate::macros::{rewrite_macro, MacroPosition}; @@ -132,7 +133,13 @@ impl Rewrite for ast::Local { shape, ); result.push_str(&else_kw); - result.push_str(&block.rewrite(context, shape)?); + let allow_single_line = !result.contains('\n'); + result.push_str(&rewrite_let_else_block( + block, + allow_single_line, + context, + shape, + )?); }; } -- cgit 1.4.1-3-g733a5 From 00fef2d51d417b62c2154a05237a16bed37244f5 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Sun, 12 Feb 2023 14:50:44 -0500 Subject: Implement wrapping rules to force `else` on a newline in `let-else` --- src/expr.rs | 4 ++++ src/items.rs | 47 ++++++++++++++++++++++++++++++++++++++++++++++- tests/source/let_else.rs | 4 ++++ tests/target/let_else.rs | 25 +++++++++++++++++++++++++ 4 files changed, 79 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/expr.rs b/src/expr.rs index a4e60659a0e..715be57ada8 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -1027,12 +1027,14 @@ impl<'a> ControlFlow<'a> { /// Rewrite the `else` keyword with surrounding comments. /// +/// force_newline_else: whether or not to rewrite the `else` keyword on a newline. /// is_last: true if this is an `else` and `false` if this is an `else if` block. /// context: rewrite context /// span: Span between the end of the last expression and the start of the else block, /// which contains the `else` keyword /// shape: Shape pub(crate) fn rewrite_else_kw_with_comments( + force_newline_else: bool, is_last: bool, context: &RewriteContext<'_>, span: Span, @@ -1048,6 +1050,7 @@ pub(crate) fn rewrite_else_kw_with_comments( let newline_sep = &shape.indent.to_string_with_newline(context.config); let before_sep = match context.config.control_brace_style() { + _ if force_newline_else => newline_sep.as_ref(), ControlBraceStyle::AlwaysNextLine | ControlBraceStyle::ClosingNextLine => { newline_sep.as_ref() } @@ -1132,6 +1135,7 @@ impl<'a> Rewrite for ControlFlow<'a> { }; let else_kw = rewrite_else_kw_with_comments( + false, last_in_chain, context, self.block.span.between(else_block.span), diff --git a/src/items.rs b/src/items.rs index 4693e57b8a1..64d2ace2bee 100644 --- a/src/items.rs +++ b/src/items.rs @@ -126,10 +126,14 @@ impl Rewrite for ast::Local { )?; if let Some(block) = else_block { + let else_kw_span = init.span.between(block.span); + let force_newline_else = + !same_line_else_kw_and_brace(&result, context, else_kw_span, nested_shape); let else_kw = rewrite_else_kw_with_comments( + force_newline_else, true, context, - init.span.between(block.span), + else_kw_span, shape, ); result.push_str(&else_kw); @@ -148,6 +152,47 @@ impl Rewrite for ast::Local { } } +/// When the initializer expression is multi-lined, then the else keyword and opening brace of the +/// block ( i.e. "else {") should be put on the same line as the end of the initializer expression +/// if all the following are true: +/// +/// 1. The initializer expression ends with one or more closing parentheses, square brackets, +/// or braces +/// 2. There is nothing else on that line +/// 3. That line is not indented beyond the indent on the first line of the let keyword +fn same_line_else_kw_and_brace( + init_str: &str, + context: &RewriteContext<'_>, + else_kw_span: Span, + init_shape: Shape, +) -> bool { + if !init_str.contains('\n') { + // initializer expression is single lined so the "else {" should be placed on the same line + return true; + } + + // 1. The initializer expression ends with one or more `)`, `]`, `}`. + if !init_str.ends_with([')', ']', '}']) { + return false; + } + + // 2. There is nothing else on that line + // For example, there are no comments + let else_kw_snippet = context.snippet(else_kw_span).trim(); + if else_kw_snippet != "else" { + return false; + } + + // 3. The last line of the initializer expression is not indented beyond the `let` keyword + let indent = init_shape.indent.to_string(context.config); + init_str + .lines() + .last() + .expect("initializer expression is multi-lined") + .strip_prefix(indent.as_ref()) + .map_or(false, |l| !l.starts_with(char::is_whitespace)) +} + // FIXME convert to using rewrite style rather than visitor // FIXME format modules in this style #[allow(dead_code)] diff --git a/tests/source/let_else.rs b/tests/source/let_else.rs index 26e0ebf0736..932a64a050f 100644 --- a/tests/source/let_else.rs +++ b/tests/source/let_else.rs @@ -7,4 +7,8 @@ fn main() { // nope return; }; + + let Some(x) = y.foo("abc", fairly_long_identifier, "def", "123456", "string", "cheese") else { bar() }; + + let Some(x) = abcdef().foo("abc", some_really_really_really_long_ident, "ident", "123456").bar().baz().qux("fffffffffffffffff") else { foo_bar() }; } diff --git a/tests/target/let_else.rs b/tests/target/let_else.rs index a910f5389a3..fafbe7932ea 100644 --- a/tests/target/let_else.rs +++ b/tests/target/let_else.rs @@ -9,4 +9,29 @@ fn main() { // nope return; }; + + let Some(x) = y.foo( + "abc", + fairly_long_identifier, + "def", + "123456", + "string", + "cheese", + ) else { + bar() + }; + + let Some(x) = abcdef() + .foo( + "abc", + some_really_really_really_long_ident, + "ident", + "123456", + ) + .bar() + .baz() + .qux("fffffffffffffffff") + else { + foo_bar() + }; } -- cgit 1.4.1-3-g733a5 From 521f86bae5242b5553705e50e095a991ff1323d1 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Wed, 22 Mar 2023 21:32:29 -0400 Subject: Prevent single-line `let-else` if it would exceed `max_width` --- src/items.rs | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/items.rs b/src/items.rs index 64d2ace2bee..c2b9a26708d 100644 --- a/src/items.rs +++ b/src/items.rs @@ -137,13 +137,21 @@ impl Rewrite for ast::Local { shape, ); result.push_str(&else_kw); - let allow_single_line = !result.contains('\n'); - result.push_str(&rewrite_let_else_block( - block, - allow_single_line, - context, - shape, - )?); + + let allow_single_line = allow_single_line_let_else_block(&result, block); + + let mut rw_else_block = + rewrite_let_else_block(block, allow_single_line, context, shape)?; + + if allow_single_line && !rw_else_block.contains('\n') { + let available_space = shape.width.saturating_sub(result.len()); + if available_space <= rw_else_block.len() { + // writing this on one line would exceed the available width + rw_else_block = rewrite_let_else_block(block, false, context, shape)?; + } + } + + result.push_str(&rw_else_block); }; } @@ -193,6 +201,18 @@ fn same_line_else_kw_and_brace( .map_or(false, |l| !l.starts_with(char::is_whitespace)) } +fn allow_single_line_let_else_block(result: &str, block: &ast::Block) -> bool { + if result.contains('\n') { + return false; + } + + if block.stmts.len() <= 1 { + return true; + } + + false +} + // FIXME convert to using rewrite style rather than visitor // FIXME format modules in this style #[allow(dead_code)] -- cgit 1.4.1-3-g733a5 From 9386b32f5a72bb276a97461d33aab415314201d8 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Sat, 1 Apr 2023 11:02:27 -0400 Subject: wrap `else {` for long, single-lined initializer expressions This helps to prevent max width errors. --- src/items.rs | 6 ++++-- tests/source/let_else.rs | 12 ++++++------ tests/target/let_else.rs | 18 ++++++++++-------- 3 files changed, 20 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/items.rs b/src/items.rs index c2b9a26708d..97a76f6bb32 100644 --- a/src/items.rs +++ b/src/items.rs @@ -175,8 +175,10 @@ fn same_line_else_kw_and_brace( init_shape: Shape, ) -> bool { if !init_str.contains('\n') { - // initializer expression is single lined so the "else {" should be placed on the same line - return true; + // initializer expression is single lined. The "else {" can only be placed on the same line + // as the initializer expression if there is enough room for it. + // 7 = ` else {` + return init_shape.width.saturating_sub(init_str.len()) >= 7; } // 1. The initializer expression ends with one or more `)`, `]`, `}`. diff --git a/tests/source/let_else.rs b/tests/source/let_else.rs index 78465e64edc..9c02117c6e8 100644 --- a/tests/source/let_else.rs +++ b/tests/source/let_else.rs @@ -79,18 +79,18 @@ fn unbreakable_initializer_expr_pre_formatting_let_else_length_near_max_width() fn unbreakable_initializer_expr_pre_formatting_length_up_to_opening_brace_near_max_width() { // Pre Formatting: - // The length of `(indent)let pat = init else {` is 100 (max_width) + // The length of `(indent)let pat = init else {` is 99 (< max_width) // Post Formatting: // The else keyword and opening brace remain on the same line as the initializer expr, // and the else block is formatted over multiple lines because we can't fit the // else block on the same line as the initializer expr. - let Some(x) = some_really_really_really_really_really_really_really_really_long_name____E else {return}; + let Some(x) = some_really_really_really_really_really_really_really_really_long_name___E else {return}; // Pre Formatting: // The length of `(indent)let pat = init else {` is 101 (> max_width) // Post Formatting: - // The else keyword and opening brace remain on the same line as the initializer expr, - // which leads to the `{` exceeding the max width + // The else keyword and opening brace cannot fit on the same line as the initializer expr. + // They are formatted on the next line. let Some(x) = some_really_really_really_really_really_really_really_really_long_name_____F else {return}; } @@ -98,8 +98,8 @@ fn unbreakable_initializer_expr_pre_formatting_length_through_initializer_expr_n // Pre Formatting: // The length of `(indent)let pat = init` is 99 (< max_width) // Post Formatting: - // The else keyword and opening brace remain on the same line as the initializer expr, - // which leads to the `else {` exceeding the max width + // The else keyword and opening brace cannot fit on the same line as the initializer expr. + // They are formatted on the next line. let Some(x) = some_really_really_really_really_really_really_really_really_really_long_name___G else {return}; // Pre Formatting: diff --git a/tests/target/let_else.rs b/tests/target/let_else.rs index 5ada7d44657..88115d129aa 100644 --- a/tests/target/let_else.rs +++ b/tests/target/let_else.rs @@ -130,21 +130,22 @@ fn unbreakable_initializer_expr_pre_formatting_let_else_length_near_max_width() fn unbreakable_initializer_expr_pre_formatting_length_up_to_opening_brace_near_max_width() { // Pre Formatting: - // The length of `(indent)let pat = init else {` is 100 (max_width) + // The length of `(indent)let pat = init else {` is 99 (< max_width) // Post Formatting: // The else keyword and opening brace remain on the same line as the initializer expr, // and the else block is formatted over multiple lines because we can't fit the // else block on the same line as the initializer expr. - let Some(x) = some_really_really_really_really_really_really_really_really_long_name____E else { + let Some(x) = some_really_really_really_really_really_really_really_really_long_name___E else { return; }; // Pre Formatting: // The length of `(indent)let pat = init else {` is 101 (> max_width) // Post Formatting: - // The else keyword and opening brace remain on the same line as the initializer expr, - // which leads to the `{` exceeding the max width - let Some(x) = some_really_really_really_really_really_really_really_really_long_name_____F else { + // The else keyword and opening brace cannot fit on the same line as the initializer expr. + // They are formatted on the next line. + let Some(x) = some_really_really_really_really_really_really_really_really_long_name_____F + else { return; }; } @@ -153,9 +154,10 @@ fn unbreakable_initializer_expr_pre_formatting_length_through_initializer_expr_n // Pre Formatting: // The length of `(indent)let pat = init` is 99 (< max_width) // Post Formatting: - // The else keyword and opening brace remain on the same line as the initializer expr, - // which leads to the `else {` exceeding the max width - let Some(x) = some_really_really_really_really_really_really_really_really_really_long_name___G else { + // The else keyword and opening brace cannot fit on the same line as the initializer expr. + // They are formatted on the next line. + let Some(x) = some_really_really_really_really_really_really_really_really_really_long_name___G + else { return; }; -- cgit 1.4.1-3-g733a5 From fe8b72d98e58e05420be9c1227ebdbe7a742dcf9 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Sun, 9 Apr 2023 02:13:11 -0400 Subject: implement single_line_let_else_max_width This allows users to configure the maximum length of a single line `let-else` statements. `let-else` statements that otherwise meet the requirements to be formatted on a single line will have their divergent `else` block formatted over multiple lines if they exceed this length. **Note**: `single_line_let_else_max_widt` will be introduced as a stable configuration option. --- Configurations.md | 77 ++++++++++++++++++++++ src/config/config_type.rs | 10 +++ src/config/mod.rs | 7 ++ src/config/options.rs | 6 ++ src/items.rs | 27 ++++++-- .../configs/single_line_let_else_max_width/100.rs | 40 +++++++++++ .../configs/single_line_let_else_max_width/50.rs | 40 +++++++++++ .../configs/single_line_let_else_max_width/zero.rs | 40 +++++++++++ .../source/configs/use_small_heuristics/default.rs | 10 +++ tests/source/configs/use_small_heuristics/max.rs | 10 +++ tests/source/configs/use_small_heuristics/off.rs | 10 +++ tests/source/let_else.rs | 11 ++++ .../configs/single_line_let_else_max_width/100.rs | 59 +++++++++++++++++ .../configs/single_line_let_else_max_width/50.rs | 61 +++++++++++++++++ .../configs/single_line_let_else_max_width/zero.rs | 65 ++++++++++++++++++ .../target/configs/use_small_heuristics/default.rs | 12 ++++ tests/target/configs/use_small_heuristics/max.rs | 10 +++ tests/target/configs/use_small_heuristics/off.rs | 16 +++++ tests/target/let_else.rs | 24 +++++++ 19 files changed, 528 insertions(+), 7 deletions(-) create mode 100644 tests/source/configs/single_line_let_else_max_width/100.rs create mode 100644 tests/source/configs/single_line_let_else_max_width/50.rs create mode 100644 tests/source/configs/single_line_let_else_max_width/zero.rs create mode 100644 tests/target/configs/single_line_let_else_max_width/100.rs create mode 100644 tests/target/configs/single_line_let_else_max_width/50.rs create mode 100644 tests/target/configs/single_line_let_else_max_width/zero.rs (limited to 'src') diff --git a/Configurations.md b/Configurations.md index ac638ff91e6..ac5747800b2 100644 --- a/Configurations.md +++ b/Configurations.md @@ -2392,6 +2392,78 @@ By default this option is set as a percentage of [`max_width`](#max_width) provi See also [`max_width`](#max_width) and [`use_small_heuristics`](#use_small_heuristics) +## `single_line_let_else_max_width` + +Maximum line length for single line let-else statements. +See the [let-else statement section of the Rust Style Guide](https://github.com/rust-lang/rust/blob/master/src/doc/style-guide/src/statements.md#else-blocks-let-else-statements) for more details on when a let-else statement may be written on a single line. +A value of `0` (zero) means the divergent `else` block will always be formatted over multiple lines. +Note this occurs when `use_small_heuristics` is set to `Off`. + +By default this option is set as a percentage of [`max_width`](#max_width) provided by [`use_small_heuristics`](#use_small_heuristics), but a value set directly for `single_line_let_else_max_width` will take precedence. + +- **Default value**: `50` +- **Possible values**: any positive integer that is less than or equal to the value specified for [`max_width`](#max_width) +- **Stable**: Yes + +#### `50` (default): + +```rust +fn main() { + let Some(w) = opt else { return Ok(()) }; + + let Some(x) = opt else { return }; + + let Some(y) = opt else { + return; + }; + + let Some(z) = some_very_very_very_very_long_name else { + return; + }; +} +``` + +#### `0`: + +```rust +fn main() { + let Some(w) = opt else { + return Ok(()); + }; + + let Some(x) = opt else { + return; + }; + + let Some(y) = opt else { + return; + }; + + let Some(z) = some_very_very_very_very_long_name else { + return; + }; +} +``` + +#### `100`: + +```rust +fn main() { + let Some(w) = opt else { return Ok(()) }; + + let Some(x) = opt else { return }; + + let Some(y) = opt else { + return; + }; + + let Some(z) = some_very_very_very_very_long_name else { return }; +} +``` + +See also [`max_width`](#max_width) and [`use_small_heuristics`](#use_small_heuristics) + + ## `space_after_colon` Leave a space after the colon. @@ -2804,6 +2876,7 @@ The ratios are: * [`array_width`](#array_width) - `60%` * [`chain_width`](#chain_width) - `60%` * [`single_line_if_else_max_width`](#single_line_if_else_max_width) - `50%` +* [`single_line_let_else_max_width`](#single_line_let_else_max_width) - `50%` For example when `max_width` is set to `100`, the width settings are: * `fn_call_width=60` @@ -2813,6 +2886,7 @@ For example when `max_width` is set to `100`, the width settings are: * `array_width=60` * `chain_width=60` * `single_line_if_else_max_width=50` +* `single_line_let_else_max_width=50` and when `max_width` is set to `200`: * `fn_call_width=120` @@ -2822,6 +2896,7 @@ and when `max_width` is set to `200`: * `array_width=120` * `chain_width=120` * `single_line_if_else_max_width=100` +* `single_line_let_else_max_width=100` ```rust enum Lorem { @@ -2891,6 +2966,7 @@ So if `max_width` is set to `200`, then all the width settings are also set to ` * `array_width=200` * `chain_width=200` * `single_line_if_else_max_width=200` +* `single_line_let_else_max_width=200` ```rust enum Lorem { @@ -2918,6 +2994,7 @@ See also: * [`array_width`](#array_width) * [`chain_width`](#chain_width) * [`single_line_if_else_max_width`](#single_line_if_else_max_width) +* [`single_line_let_else_max_width`](#single_line_let_else_max_width) ## `use_try_shorthand` diff --git a/src/config/config_type.rs b/src/config/config_type.rs index 54ca7676dfc..c836b4bbb78 100644 --- a/src/config/config_type.rs +++ b/src/config/config_type.rs @@ -121,6 +121,7 @@ macro_rules! create_config { | "use_small_heuristics" | "fn_call_width" | "single_line_if_else_max_width" + | "single_line_let_else_max_width" | "attr_fn_like_width" | "struct_lit_width" | "struct_variant_width" @@ -269,6 +270,7 @@ macro_rules! create_config { | "use_small_heuristics" | "fn_call_width" | "single_line_if_else_max_width" + | "single_line_let_else_max_width" | "attr_fn_like_width" | "struct_lit_width" | "struct_variant_width" @@ -407,6 +409,14 @@ macro_rules! create_config { "single_line_if_else_max_width", ); self.single_line_if_else_max_width.2 = single_line_if_else_max_width; + + let single_line_let_else_max_width = get_width_value( + self.was_set().single_line_let_else_max_width(), + self.single_line_let_else_max_width.2, + heuristics.single_line_let_else_max_width, + "single_line_let_else_max_width", + ); + self.single_line_let_else_max_width.2 = single_line_let_else_max_width; } fn set_heuristics(&mut self) { diff --git a/src/config/mod.rs b/src/config/mod.rs index 14f27f3f8b6..6f41b299e87 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -58,6 +58,9 @@ create_config! { chain_width: usize, 60, true, "Maximum length of a chain to fit on a single line."; single_line_if_else_max_width: usize, 50, true, "Maximum line length for single line if-else \ expressions. A value of zero means always break if-else expressions."; + single_line_let_else_max_width: usize, 50, true, "Maximum line length for single line \ + let-else statements. A value of zero means always format the divergent `else` block \ + over multiple lines."; // Comments. macros, and strings wrap_comments: bool, false, false, "Break comments to fit on the line"; @@ -473,6 +476,9 @@ mod test { chain_width: usize, 60, true, "Maximum length of a chain to fit on a single line."; single_line_if_else_max_width: usize, 50, true, "Maximum line length for single \ line if-else expressions. A value of zero means always break if-else expressions."; + single_line_let_else_max_width: usize, 50, false, "Maximum line length for single \ + line let-else statements. A value of zero means always format the divergent \ + `else` block over multiple lines."; // Options that are used by the tests stable_option: bool, false, true, "A stable option"; @@ -619,6 +625,7 @@ struct_variant_width = 35 array_width = 60 chain_width = 60 single_line_if_else_max_width = 50 +single_line_let_else_max_width = 50 wrap_comments = false format_code_in_doc_comments = false doc_comment_code_block_width = 100 diff --git a/src/config/options.rs b/src/config/options.rs index 408017d2432..3aa1a4de99d 100644 --- a/src/config/options.rs +++ b/src/config/options.rs @@ -236,6 +236,9 @@ pub struct WidthHeuristics { // Maximum line length for single line if-else expressions. A value // of zero means always break if-else expressions. pub(crate) single_line_if_else_max_width: usize, + // Maximum line length for single line let-else statements. A value of zero means + // always format the divergent `else` block over multiple lines. + pub(crate) single_line_let_else_max_width: usize, } impl fmt::Display for WidthHeuristics { @@ -255,6 +258,7 @@ impl WidthHeuristics { array_width: usize::max_value(), chain_width: usize::max_value(), single_line_if_else_max_width: 0, + single_line_let_else_max_width: 0, } } @@ -267,6 +271,7 @@ impl WidthHeuristics { array_width: max_width, chain_width: max_width, single_line_if_else_max_width: max_width, + single_line_let_else_max_width: max_width, } } @@ -288,6 +293,7 @@ impl WidthHeuristics { array_width: (60.0 * max_width_ratio).round() as usize, chain_width: (60.0 * max_width_ratio).round() as usize, single_line_if_else_max_width: (50.0 * max_width_ratio).round() as usize, + single_line_let_else_max_width: (50.0 * max_width_ratio).round() as usize, } } } diff --git a/src/items.rs b/src/items.rs index 97a76f6bb32..157ae931a24 100644 --- a/src/items.rs +++ b/src/items.rs @@ -138,17 +138,30 @@ impl Rewrite for ast::Local { ); result.push_str(&else_kw); - let allow_single_line = allow_single_line_let_else_block(&result, block); + // At this point we've written `let {pat} = {expr} else' into the buffer, and we + // want to calculate up front if there's room to write the divergent block on the + // same line. The available space varies based on indentation so we clamp the width + // on the smaller of `shape.width` and `single_line_let_else_max_width`. + let max_width = + std::cmp::min(shape.width, context.config.single_line_let_else_max_width()); + + // If available_space hits zero we know for sure this will be a multi-lined block + let available_space = max_width.saturating_sub(result.len()); + + let allow_single_line = !force_newline_else + && available_space > 0 + && allow_single_line_let_else_block(&result, block); let mut rw_else_block = rewrite_let_else_block(block, allow_single_line, context, shape)?; - if allow_single_line && !rw_else_block.contains('\n') { - let available_space = shape.width.saturating_sub(result.len()); - if available_space <= rw_else_block.len() { - // writing this on one line would exceed the available width - rw_else_block = rewrite_let_else_block(block, false, context, shape)?; - } + let single_line_else = !rw_else_block.contains('\n'); + let else_block_exceeds_width = available_space <= rw_else_block.len(); + + if allow_single_line && single_line_else && else_block_exceeds_width { + // writing this on one line would exceed the available width + // so rewrite the else block over multiple lines. + rw_else_block = rewrite_let_else_block(block, false, context, shape)?; } result.push_str(&rw_else_block); diff --git a/tests/source/configs/single_line_let_else_max_width/100.rs b/tests/source/configs/single_line_let_else_max_width/100.rs new file mode 100644 index 00000000000..a73c9084bf2 --- /dev/null +++ b/tests/source/configs/single_line_let_else_max_width/100.rs @@ -0,0 +1,40 @@ +// rustfmt-single_line_let_else_max_width: 100 + +fn main() { + let Some(a) = opt else {}; + + let Some(b) = opt else { return }; + + let Some(c) = opt else { + return + }; + + let Some(c) = opt else { + // a comment should always force the block to be multi-lined + return + }; + + let Some(c) = opt else { /* a comment should always force the block to be multi-lined */ return }; + + let Some(d) = some_very_very_very_very_long_name else { return }; + + let Expr::Slice(ast::ExprSlice { lower, upper, step, range: _ }) = slice.as_ref() else { + return + }; + + let Some((base_place, current)) = self.lower_expr_as_place(current, *base, true)? else { + return Ok(None) + }; + + let Some(doc_attr) = variant.attrs.iter().find(|attr| attr.path().is_ident("doc")) else { + return Err(Error::new(variant.span(), r#"expected a doc comment"#)) + }; + + let Some((base_place, current)) = self.lower_expr_as_place(current, *base, true) else { + return Ok(None) + }; + + let Stmt::Expr(Expr::Call(ExprCall { args: some_args, .. }), _) = last_stmt else { + return Err(Error::new(last_stmt.span(), "expected last expression to be `Some(match (..) { .. })`")) + }; +} diff --git a/tests/source/configs/single_line_let_else_max_width/50.rs b/tests/source/configs/single_line_let_else_max_width/50.rs new file mode 100644 index 00000000000..87d0583c552 --- /dev/null +++ b/tests/source/configs/single_line_let_else_max_width/50.rs @@ -0,0 +1,40 @@ +// rustfmt-single_line_let_else_max_width: 50 + +fn main() { + let Some(a) = opt else {}; + + let Some(b) = opt else { return }; + + let Some(c) = opt else { + return + }; + + let Some(c) = opt else { + // a comment should always force the block to be multi-lined + return + }; + + let Some(c) = opt else { /* a comment should always force the block to be multi-lined */ return }; + + let Some(d) = some_very_very_very_very_long_name else { return }; + + let Expr::Slice(ast::ExprSlice { lower, upper, step, range: _ }) = slice.as_ref() else { + return + }; + + let Some((base_place, current)) = self.lower_expr_as_place(current, *base, true)? else { + return Ok(None) + }; + + let Some(doc_attr) = variant.attrs.iter().find(|attr| attr.path().is_ident("doc")) else { + return Err(Error::new(variant.span(), r#"expected a doc comment"#)) + }; + + let Some((base_place, current)) = self.lower_expr_as_place(current, *base, true) else { + return Ok(None) + }; + + let Stmt::Expr(Expr::Call(ExprCall { args: some_args, .. }), _) = last_stmt else { + return Err(Error::new(last_stmt.span(), "expected last expression to be `Some(match (..) { .. })`")) + }; +} diff --git a/tests/source/configs/single_line_let_else_max_width/zero.rs b/tests/source/configs/single_line_let_else_max_width/zero.rs new file mode 100644 index 00000000000..afb9e503307 --- /dev/null +++ b/tests/source/configs/single_line_let_else_max_width/zero.rs @@ -0,0 +1,40 @@ +// rustfmt-single_line_let_else_max_width: 0 + +fn main() { + let Some(a) = opt else {}; + + let Some(b) = opt else { return }; + + let Some(c) = opt else { + return + }; + + let Some(c) = opt else { + // a comment should always force the block to be multi-lined + return + }; + + let Some(c) = opt else { /* a comment should always force the block to be multi-lined */ return }; + + let Some(d) = some_very_very_very_very_long_name else { return }; + + let Expr::Slice(ast::ExprSlice { lower, upper, step, range: _ }) = slice.as_ref() else { + return + }; + + let Some((base_place, current)) = self.lower_expr_as_place(current, *base, true)? else { + return Ok(None) + }; + + let Some(doc_attr) = variant.attrs.iter().find(|attr| attr.path().is_ident("doc")) else { + return Err(Error::new(variant.span(), r#"expected a doc comment"#)) + }; + + let Some((base_place, current)) = self.lower_expr_as_place(current, *base, true) else { + return Ok(None) + }; + + let Stmt::Expr(Expr::Call(ExprCall { args: some_args, .. }), _) = last_stmt else { + return Err(Error::new(last_stmt.span(), "expected last expression to be `Some(match (..) { .. })`")) + }; +} diff --git a/tests/source/configs/use_small_heuristics/default.rs b/tests/source/configs/use_small_heuristics/default.rs index 68bc40271a1..95238c54844 100644 --- a/tests/source/configs/use_small_heuristics/default.rs +++ b/tests/source/configs/use_small_heuristics/default.rs @@ -23,3 +23,13 @@ fn main() { sit }; } + +fn format_let_else() { + let Some(a) = opt else {}; + + let Some(b) = opt else { return }; + + let Some(c) = opt else { return }; + + let Some(d) = some_very_very_very_very_long_name else { return }; +} diff --git a/tests/source/configs/use_small_heuristics/max.rs b/tests/source/configs/use_small_heuristics/max.rs index 8d30932e2c2..b79302e22ab 100644 --- a/tests/source/configs/use_small_heuristics/max.rs +++ b/tests/source/configs/use_small_heuristics/max.rs @@ -23,3 +23,13 @@ fn main() { sit }; } + +fn format_let_else() { + let Some(a) = opt else {}; + + let Some(b) = opt else { return }; + + let Some(c) = opt else { return }; + + let Some(d) = some_very_very_very_very_long_name else { return }; +} diff --git a/tests/source/configs/use_small_heuristics/off.rs b/tests/source/configs/use_small_heuristics/off.rs index f76392d2404..80bcdd89896 100644 --- a/tests/source/configs/use_small_heuristics/off.rs +++ b/tests/source/configs/use_small_heuristics/off.rs @@ -23,3 +23,13 @@ fn main() { sit }; } + +fn format_let_else() { + let Some(a) = opt else {}; + + let Some(b) = opt else { return }; + + let Some(c) = opt else { return }; + + let Some(d) = some_very_very_very_very_long_name else { return }; +} diff --git a/tests/source/let_else.rs b/tests/source/let_else.rs index 9c02117c6e8..85b3604ad3c 100644 --- a/tests/source/let_else.rs +++ b/tests/source/let_else.rs @@ -1,3 +1,5 @@ +// rustfmt-single_line_let_else_max_width: 100 + fn main() { // Although this won't compile it still parses so make sure we can format empty else blocks let Some(x) = opt else {}; @@ -149,3 +151,12 @@ fn long_patterns() { return; }; } + +fn with_trailing_try_operator() { + // Currently the trailing ? forces the else on the next line + // This may be revisited in style edition 2024 + let Some(next_bucket) = ranking_rules[cur_ranking_rule_index].next_bucket(ctx, logger, &ranking_rule_universes[cur_ranking_rule_index])? else { return }; + + // Maybe this is a workaround? + let Ok(Some(next_bucket)) = ranking_rules[cur_ranking_rule_index].next_bucket(ctx, logger, &ranking_rule_universes[cur_ranking_rule_index]) else { return }; +} diff --git a/tests/target/configs/single_line_let_else_max_width/100.rs b/tests/target/configs/single_line_let_else_max_width/100.rs new file mode 100644 index 00000000000..2310ff8a228 --- /dev/null +++ b/tests/target/configs/single_line_let_else_max_width/100.rs @@ -0,0 +1,59 @@ +// rustfmt-single_line_let_else_max_width: 100 + +fn main() { + let Some(a) = opt else {}; + + let Some(b) = opt else { return }; + + let Some(c) = opt else { return }; + + let Some(c) = opt else { + // a comment should always force the block to be multi-lined + return; + }; + + let Some(c) = opt else { + /* a comment should always force the block to be multi-lined */ + return; + }; + + let Some(d) = some_very_very_very_very_long_name else { return }; + + let Expr::Slice(ast::ExprSlice { + lower, + upper, + step, + range: _, + }) = slice.as_ref() else { + return; + }; + + let Some((base_place, current)) = self.lower_expr_as_place(current, *base, true)? else { + return Ok(None); + }; + + let Some(doc_attr) = variant + .attrs + .iter() + .find(|attr| attr.path().is_ident("doc")) + else { + return Err(Error::new(variant.span(), r#"expected a doc comment"#)); + }; + + let Some((base_place, current)) = self.lower_expr_as_place(current, *base, true) else { + return Ok(None); + }; + + let Stmt::Expr( + Expr::Call(ExprCall { + args: some_args, .. + }), + _, + ) = last_stmt + else { + return Err(Error::new( + last_stmt.span(), + "expected last expression to be `Some(match (..) { .. })`", + )); + }; +} diff --git a/tests/target/configs/single_line_let_else_max_width/50.rs b/tests/target/configs/single_line_let_else_max_width/50.rs new file mode 100644 index 00000000000..df2c40d72d6 --- /dev/null +++ b/tests/target/configs/single_line_let_else_max_width/50.rs @@ -0,0 +1,61 @@ +// rustfmt-single_line_let_else_max_width: 50 + +fn main() { + let Some(a) = opt else {}; + + let Some(b) = opt else { return }; + + let Some(c) = opt else { return }; + + let Some(c) = opt else { + // a comment should always force the block to be multi-lined + return; + }; + + let Some(c) = opt else { + /* a comment should always force the block to be multi-lined */ + return; + }; + + let Some(d) = some_very_very_very_very_long_name else { + return; + }; + + let Expr::Slice(ast::ExprSlice { + lower, + upper, + step, + range: _, + }) = slice.as_ref() else { + return; + }; + + let Some((base_place, current)) = self.lower_expr_as_place(current, *base, true)? else { + return Ok(None); + }; + + let Some(doc_attr) = variant + .attrs + .iter() + .find(|attr| attr.path().is_ident("doc")) + else { + return Err(Error::new(variant.span(), r#"expected a doc comment"#)); + }; + + let Some((base_place, current)) = self.lower_expr_as_place(current, *base, true) else { + return Ok(None); + }; + + let Stmt::Expr( + Expr::Call(ExprCall { + args: some_args, .. + }), + _, + ) = last_stmt + else { + return Err(Error::new( + last_stmt.span(), + "expected last expression to be `Some(match (..) { .. })`", + )); + }; +} diff --git a/tests/target/configs/single_line_let_else_max_width/zero.rs b/tests/target/configs/single_line_let_else_max_width/zero.rs new file mode 100644 index 00000000000..f4d26ad3757 --- /dev/null +++ b/tests/target/configs/single_line_let_else_max_width/zero.rs @@ -0,0 +1,65 @@ +// rustfmt-single_line_let_else_max_width: 0 + +fn main() { + let Some(a) = opt else {}; + + let Some(b) = opt else { + return; + }; + + let Some(c) = opt else { + return; + }; + + let Some(c) = opt else { + // a comment should always force the block to be multi-lined + return; + }; + + let Some(c) = opt else { + /* a comment should always force the block to be multi-lined */ + return; + }; + + let Some(d) = some_very_very_very_very_long_name else { + return; + }; + + let Expr::Slice(ast::ExprSlice { + lower, + upper, + step, + range: _, + }) = slice.as_ref() else { + return; + }; + + let Some((base_place, current)) = self.lower_expr_as_place(current, *base, true)? else { + return Ok(None); + }; + + let Some(doc_attr) = variant + .attrs + .iter() + .find(|attr| attr.path().is_ident("doc")) + else { + return Err(Error::new(variant.span(), r#"expected a doc comment"#)); + }; + + let Some((base_place, current)) = self.lower_expr_as_place(current, *base, true) else { + return Ok(None); + }; + + let Stmt::Expr( + Expr::Call(ExprCall { + args: some_args, .. + }), + _, + ) = last_stmt + else { + return Err(Error::new( + last_stmt.span(), + "expected last expression to be `Some(match (..) { .. })`", + )); + }; +} diff --git a/tests/target/configs/use_small_heuristics/default.rs b/tests/target/configs/use_small_heuristics/default.rs index d67bd9aafaf..ad40739233e 100644 --- a/tests/target/configs/use_small_heuristics/default.rs +++ b/tests/target/configs/use_small_heuristics/default.rs @@ -24,3 +24,15 @@ fn main() { let lorem = if ipsum { dolor } else { sit }; } + +fn format_let_else() { + let Some(a) = opt else {}; + + let Some(b) = opt else { return }; + + let Some(c) = opt else { return }; + + let Some(d) = some_very_very_very_very_long_name else { + return; + }; +} diff --git a/tests/target/configs/use_small_heuristics/max.rs b/tests/target/configs/use_small_heuristics/max.rs index 785dfbea014..fe57f853d9d 100644 --- a/tests/target/configs/use_small_heuristics/max.rs +++ b/tests/target/configs/use_small_heuristics/max.rs @@ -13,3 +13,13 @@ fn main() { let lorem = if ipsum { dolor } else { sit }; } + +fn format_let_else() { + let Some(a) = opt else {}; + + let Some(b) = opt else { return }; + + let Some(c) = opt else { return }; + + let Some(d) = some_very_very_very_very_long_name else { return }; +} diff --git a/tests/target/configs/use_small_heuristics/off.rs b/tests/target/configs/use_small_heuristics/off.rs index f76392d2404..b0b4e4ee49f 100644 --- a/tests/target/configs/use_small_heuristics/off.rs +++ b/tests/target/configs/use_small_heuristics/off.rs @@ -23,3 +23,19 @@ fn main() { sit }; } + +fn format_let_else() { + let Some(a) = opt else {}; + + let Some(b) = opt else { + return; + }; + + let Some(c) = opt else { + return; + }; + + let Some(d) = some_very_very_very_very_long_name else { + return; + }; +} diff --git a/tests/target/let_else.rs b/tests/target/let_else.rs index 88115d129aa..6554a0961c0 100644 --- a/tests/target/let_else.rs +++ b/tests/target/let_else.rs @@ -1,3 +1,5 @@ +// rustfmt-single_line_let_else_max_width: 100 + fn main() { // Although this won't compile it still parses so make sure we can format empty else blocks let Some(x) = opt else {}; @@ -228,3 +230,25 @@ fn long_patterns() { return; }; } + +fn with_trailing_try_operator() { + // Currently the trailing ? forces the else on the next line + // This may be revisited in style edition 2024 + let Some(next_bucket) = ranking_rules[cur_ranking_rule_index].next_bucket( + ctx, + logger, + &ranking_rule_universes[cur_ranking_rule_index], + )? + else { + return; + }; + + // Maybe this is a workaround? + let Ok(Some(next_bucket)) = ranking_rules[cur_ranking_rule_index].next_bucket( + ctx, + logger, + &ranking_rule_universes[cur_ranking_rule_index], + ) else { + return; + }; +} -- cgit 1.4.1-3-g733a5 From 7b4e8a6d31a9b1ae404934a348f33cadf33ee764 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Fri, 23 Jun 2023 00:05:31 -0400 Subject: update `else_block_exceeds_width` calculation in `let-else` rewrite By reversing the logic I felt that the code became a clearer. Also, added a comment to make it clear that we need to take the trailing semicolon for the `let-else` statement into account. --- src/items.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/items.rs b/src/items.rs index 157ae931a24..fe35953715c 100644 --- a/src/items.rs +++ b/src/items.rs @@ -156,7 +156,8 @@ impl Rewrite for ast::Local { rewrite_let_else_block(block, allow_single_line, context, shape)?; let single_line_else = !rw_else_block.contains('\n'); - let else_block_exceeds_width = available_space <= rw_else_block.len(); + // +1 for the trailing `;` + let else_block_exceeds_width = rw_else_block.len() + 1 > available_space; if allow_single_line && single_line_else && else_block_exceeds_width { // writing this on one line would exceed the available width -- cgit 1.4.1-3-g733a5 From 1de65a2711d9274cffbd2cc0597b14327a053ebb Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Tue, 27 Jun 2023 12:30:27 -0400 Subject: wrap `else` to next line if `let-else` pattern is multi-lined This rule wasn't explicity stated in the style guide so it was missed, but luckily we caught it during testing. --- src/items.rs | 4 ++-- tests/target/configs/single_line_let_else_max_width/100.rs | 3 ++- tests/target/configs/single_line_let_else_max_width/50.rs | 3 ++- tests/target/configs/single_line_let_else_max_width/zero.rs | 3 ++- 4 files changed, 8 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/items.rs b/src/items.rs index fe35953715c..d5bc38303e0 100644 --- a/src/items.rs +++ b/src/items.rs @@ -127,8 +127,8 @@ impl Rewrite for ast::Local { if let Some(block) = else_block { let else_kw_span = init.span.between(block.span); - let force_newline_else = - !same_line_else_kw_and_brace(&result, context, else_kw_span, nested_shape); + let force_newline_else = pat_str.contains('\n') + || !same_line_else_kw_and_brace(&result, context, else_kw_span, nested_shape); let else_kw = rewrite_else_kw_with_comments( force_newline_else, true, diff --git a/tests/target/configs/single_line_let_else_max_width/100.rs b/tests/target/configs/single_line_let_else_max_width/100.rs index 2310ff8a228..0409124a5b0 100644 --- a/tests/target/configs/single_line_let_else_max_width/100.rs +++ b/tests/target/configs/single_line_let_else_max_width/100.rs @@ -24,7 +24,8 @@ fn main() { upper, step, range: _, - }) = slice.as_ref() else { + }) = slice.as_ref() + else { return; }; diff --git a/tests/target/configs/single_line_let_else_max_width/50.rs b/tests/target/configs/single_line_let_else_max_width/50.rs index df2c40d72d6..6afc2b6f2b0 100644 --- a/tests/target/configs/single_line_let_else_max_width/50.rs +++ b/tests/target/configs/single_line_let_else_max_width/50.rs @@ -26,7 +26,8 @@ fn main() { upper, step, range: _, - }) = slice.as_ref() else { + }) = slice.as_ref() + else { return; }; diff --git a/tests/target/configs/single_line_let_else_max_width/zero.rs b/tests/target/configs/single_line_let_else_max_width/zero.rs index f4d26ad3757..b5fd0b9edaf 100644 --- a/tests/target/configs/single_line_let_else_max_width/zero.rs +++ b/tests/target/configs/single_line_let_else_max_width/zero.rs @@ -30,7 +30,8 @@ fn main() { upper, step, range: _, - }) = slice.as_ref() else { + }) = slice.as_ref() + else { return; }; -- cgit 1.4.1-3-g733a5 From aa691480c006fadc834d0c36872efe1cb994d07a Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Tue, 9 May 2023 21:29:15 +0000 Subject: Implement `become` expression formatting in rustfmt --- src/expr.rs | 1 + src/utils.rs | 1 + 2 files changed, 2 insertions(+) (limited to 'src') diff --git a/src/expr.rs b/src/expr.rs index 715be57ada8..5b1b4fbd491 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -232,6 +232,7 @@ pub(crate) fn format_expr( ast::ExprKind::Ret(Some(ref expr)) => { rewrite_unary_prefix(context, "return ", &**expr, shape) } + ast::ExprKind::Become(ref expr) => rewrite_unary_prefix(context, "become ", &**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) diff --git a/src/utils.rs b/src/utils.rs index ca171657407..890a05b8c82 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -505,6 +505,7 @@ pub(crate) fn is_block_expr(context: &RewriteContext<'_>, expr: &ast::Expr, repr | ast::ExprKind::Range(..) | ast::ExprKind::Repeat(..) | ast::ExprKind::Ret(..) + | ast::ExprKind::Become(..) | ast::ExprKind::Yeet(..) | ast::ExprKind::Tup(..) | ast::ExprKind::Type(..) -- cgit 1.4.1-3-g733a5 From 326af2bd2146e6502ea87b63f72a9de45ff38f85 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sun, 25 Jun 2023 16:01:29 +0000 Subject: Switch to tracing for logging --- Cargo.lock | 163 ++++++++++++++++++++++++++++++++++++++---------- Cargo.toml | 6 +- src/bin/main.rs | 5 +- src/format-diff/main.rs | 7 ++- src/git-rustfmt/main.rs | 7 ++- src/test/mod.rs | 2 +- 6 files changed, 147 insertions(+), 43 deletions(-) (limited to 'src') diff --git a/Cargo.lock b/Cargo.lock index bd28df7a757..e867f2cb840 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -261,19 +261,6 @@ version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" -[[package]] -name = "env_logger" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" -dependencies = [ - "humantime", - "is-terminal", - "log", - "regex", - "termcolor", -] - [[package]] name = "errno" version = "0.3.1" @@ -352,12 +339,6 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" -[[package]] -name = "humantime" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" - [[package]] name = "ignore" version = "0.4.18" @@ -457,18 +438,43 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata", +] + [[package]] name = "memchr" version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + [[package]] name = "once_cell" version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + [[package]] name = "packed_simd_2" version = "0.3.7" @@ -479,6 +485,12 @@ dependencies = [ "libm", ] +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + [[package]] name = "proc-macro2" version = "1.0.63" @@ -519,20 +531,29 @@ dependencies = [ [[package]] name = "regex" -version = "1.5.5" +version = "1.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286" +checksum = "8b1f693b24f6ac912f4893ef08244d70b6067480d2f1a46e950c9691e6749d1d" dependencies = [ "aho-corasick", "memchr", "regex-syntax", ] +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax", +] + [[package]] name = "regex-syntax" -version = "0.6.25" +version = "0.6.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "rustfmt-config_proc_macro" @@ -554,12 +575,10 @@ dependencies = [ "clap", "diff", "dirs", - "env_logger", "getopts", "ignore", "itertools", "lazy_static", - "log", "regex", "rustfmt-config_proc_macro", "serde", @@ -567,6 +586,8 @@ dependencies = [ "term", "thiserror", "toml", + "tracing", + "tracing-subscriber", "unicode-segmentation", "unicode-width", "unicode_categories", @@ -656,6 +677,21 @@ dependencies = [ "serde", ] +[[package]] +name = "sharded-slab" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "smallvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" + [[package]] name = "strsim" version = "0.10.0" @@ -684,15 +720,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "termcolor" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" -dependencies = [ - "winapi-util", -] - [[package]] name = "thiserror" version = "1.0.40" @@ -756,6 +783,68 @@ dependencies = [ "winnow", ] +[[package]] +name = "tracing" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +dependencies = [ + "cfg-if", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" +dependencies = [ + "lazy_static", + "log", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + [[package]] name = "unicode-ident" version = "1.0.8" @@ -786,6 +875,12 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + [[package]] name = "walkdir" version = "2.3.2" diff --git a/Cargo.toml b/Cargo.toml index 8c312f47a28..f4c4bab37cb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,18 +40,18 @@ cargo_metadata = "0.15.4" clap = { version = "4.2.1", features = ["derive"] } diff = "0.1" dirs = "4.0" -env_logger = "0.10.0" getopts = "0.2" ignore = "0.4" itertools = "0.10" lazy_static = "1.4" -log = "0.4" -regex = "1.5" +regex = "1.7" serde = { version = "1.0.160", features = ["derive"] } serde_json = "1.0" term = "0.7" thiserror = "1.0.40" toml = "0.7.4" +tracing = "0.1.37" +tracing-subscriber = { version = "0.3.17", features = ["env-filter"] } unicode-segmentation = "1.9" unicode-width = "0.1" unicode_categories = "0.1" diff --git a/src/bin/main.rs b/src/bin/main.rs index 03b75c1b041..2ff67d27e1b 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -6,6 +6,7 @@ use io::Error as IoError; use thiserror::Error; use rustfmt_nightly as rustfmt; +use tracing_subscriber::EnvFilter; use std::collections::HashMap; use std::env; @@ -29,7 +30,9 @@ extern crate rustc_driver; fn main() { rustc_driver::install_ice_hook(BUG_REPORT_URL, |_| ()); - env_logger::Builder::from_env("RUSTFMT_LOG").init(); + tracing_subscriber::fmt() + .with_env_filter(EnvFilter::from_env("RUSTFMT_LOG")) + .init(); let opts = make_opts(); let exit_code = match execute(&opts) { diff --git a/src/format-diff/main.rs b/src/format-diff/main.rs index f6b739e1c2a..db4a21ba09e 100644 --- a/src/format-diff/main.rs +++ b/src/format-diff/main.rs @@ -5,11 +5,12 @@ #![deny(warnings)] #[macro_use] -extern crate log; +extern crate tracing; use serde::{Deserialize, Serialize}; use serde_json as json; use thiserror::Error; +use tracing_subscriber::EnvFilter; use std::collections::HashSet; use std::env; @@ -63,7 +64,9 @@ pub struct Opts { } fn main() { - env_logger::Builder::from_env("RUSTFMT_LOG").init(); + tracing_subscriber::fmt() + .with_env_filter(EnvFilter::from_env("RUSTFMT_LOG")) + .init(); let opts = Opts::parse(); if let Err(e) = run(opts) { println!("{}", e); diff --git a/src/git-rustfmt/main.rs b/src/git-rustfmt/main.rs index 579778edbe7..efeda53e7ec 100644 --- a/src/git-rustfmt/main.rs +++ b/src/git-rustfmt/main.rs @@ -1,5 +1,5 @@ #[macro_use] -extern crate log; +extern crate tracing; use std::env; use std::io::stdout; @@ -9,6 +9,7 @@ use std::str::FromStr; use getopts::{Matches, Options}; use rustfmt_nightly as rustfmt; +use tracing_subscriber::EnvFilter; use crate::rustfmt::{load_config, CliOptions, FormatReportFormatterBuilder, Input, Session}; @@ -170,7 +171,9 @@ impl Config { } fn main() { - env_logger::Builder::from_env("RUSTFMT_LOG").init(); + tracing_subscriber::fmt() + .with_env_filter(EnvFilter::from_env("RUSTFMT_LOG")) + .init(); let opts = make_opts(); let matches = opts diff --git a/src/test/mod.rs b/src/test/mod.rs index cfad4a8ed0e..f88ab3f194b 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -47,7 +47,7 @@ const FILE_SKIP_LIST: &[&str] = &[ ]; fn init_log() { - let _ = env_logger::builder().is_test(true).try_init(); + let _ = tracing_subscriber::fmt().with_test_writer().try_init(); } struct TestSetting { -- cgit 1.4.1-3-g733a5 From bb87a1b717a88d7cd0447b58bbb071f29ea8bcf5 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Wed, 21 Jun 2023 14:11:26 +0000 Subject: Rewrite float literals ending in dots with parens in method calls --- src/chains.rs | 74 ++++++++++++++++++++++++++++++++++++---------- src/expr.rs | 15 +++++----- tests/source/issue-5791.rs | 3 ++ tests/target/issue-5791.rs | 3 ++ 4 files changed, 71 insertions(+), 24 deletions(-) create mode 100644 tests/source/issue-5791.rs create mode 100644 tests/target/issue-5791.rs (limited to 'src') diff --git a/src/chains.rs b/src/chains.rs index 0afce7cf659..bf09d817ed1 100644 --- a/src/chains.rs +++ b/src/chains.rs @@ -153,7 +153,13 @@ enum CommentPosition { Top, } -// An expression plus trailing `?`s to be formatted together. +/// Information about an expression in a chain. +struct SubExpr { + expr: ast::Expr, + is_method_call_receiver: bool, +} + +/// An expression plus trailing `?`s to be formatted together. #[derive(Debug)] struct ChainItem { kind: ChainItemKind, @@ -166,7 +172,10 @@ struct ChainItem { // would remove a lot of cloning. #[derive(Debug)] enum ChainItemKind { - Parent(ast::Expr), + Parent { + expr: ast::Expr, + parens: bool, + }, MethodCall( ast::PathSegment, Vec, @@ -181,7 +190,7 @@ enum ChainItemKind { impl ChainItemKind { fn is_block_like(&self, context: &RewriteContext<'_>, reps: &str) -> bool { match self { - ChainItemKind::Parent(ref expr) => utils::is_block_expr(context, expr, reps), + ChainItemKind::Parent { expr, .. } => utils::is_block_expr(context, expr, reps), ChainItemKind::MethodCall(..) | ChainItemKind::StructField(..) | ChainItemKind::TupleField(..) @@ -199,7 +208,11 @@ impl ChainItemKind { } } - fn from_ast(context: &RewriteContext<'_>, expr: &ast::Expr) -> (ChainItemKind, Span) { + fn from_ast( + context: &RewriteContext<'_>, + expr: &ast::Expr, + is_method_call_receiver: bool, + ) -> (ChainItemKind, Span) { let (kind, span) = match expr.kind { ast::ExprKind::MethodCall(ref call) => { let types = if let Some(ref generic_args) = call.seg.args { @@ -236,7 +249,19 @@ impl ChainItemKind { let span = mk_sp(nested.span.hi(), expr.span.hi()); (ChainItemKind::Await, span) } - _ => return (ChainItemKind::Parent(expr.clone()), expr.span), + _ => { + return ( + ChainItemKind::Parent { + expr: expr.clone(), + parens: is_method_call_receiver + && matches!( + &expr.kind, + ast::ExprKind::Lit(lit) if crate::expr::lit_ends_in_dot(lit) + ), + }, + expr.span, + ); + } }; // Remove comments from the span. @@ -249,7 +274,14 @@ impl Rewrite for ChainItem { fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option { let shape = shape.sub_width(self.tries)?; let rewrite = match self.kind { - ChainItemKind::Parent(ref expr) => expr.rewrite(context, shape)?, + ChainItemKind::Parent { + ref expr, + parens: true, + } => crate::expr::rewrite_paren(context, &expr, shape, expr.span)?, + ChainItemKind::Parent { + ref expr, + parens: false, + } => expr.rewrite(context, shape)?, ChainItemKind::MethodCall(ref segment, ref types, ref exprs) => { Self::rewrite_method_call(segment.ident, types, exprs, self.span, context, shape)? } @@ -273,8 +305,9 @@ impl Rewrite for ChainItem { } impl ChainItem { - fn new(context: &RewriteContext<'_>, expr: &ast::Expr, tries: usize) -> ChainItem { - let (kind, span) = ChainItemKind::from_ast(context, expr); + fn new(context: &RewriteContext<'_>, expr: &SubExpr, tries: usize) -> ChainItem { + let (kind, span) = + ChainItemKind::from_ast(context, &expr.expr, expr.is_method_call_receiver); ChainItem { kind, tries, span } } @@ -327,7 +360,7 @@ impl Chain { let mut rev_children = vec![]; let mut sub_tries = 0; for subexpr in &subexpr_list { - match subexpr.kind { + match subexpr.expr.kind { ast::ExprKind::Try(_) => sub_tries += 1, _ => { rev_children.push(ChainItem::new(context, subexpr, sub_tries)); @@ -442,11 +475,14 @@ impl Chain { // Returns a Vec of the prefixes of the chain. // E.g., for input `a.b.c` we return [`a.b.c`, `a.b`, 'a'] - fn make_subexpr_list(expr: &ast::Expr, context: &RewriteContext<'_>) -> Vec { - let mut subexpr_list = vec![expr.clone()]; + fn make_subexpr_list(expr: &ast::Expr, context: &RewriteContext<'_>) -> Vec { + let mut subexpr_list = vec![SubExpr { + expr: expr.clone(), + is_method_call_receiver: false, + }]; while let Some(subexpr) = Self::pop_expr_chain(subexpr_list.last().unwrap(), context) { - subexpr_list.push(subexpr.clone()); + subexpr_list.push(subexpr); } subexpr_list @@ -454,12 +490,18 @@ impl Chain { // Returns the expression's subexpression, if it exists. When the subexpr // is a try! macro, we'll convert it to shorthand when the option is set. - fn pop_expr_chain(expr: &ast::Expr, context: &RewriteContext<'_>) -> Option { - match expr.kind { - ast::ExprKind::MethodCall(ref call) => Some(Self::convert_try(&call.receiver, context)), + fn pop_expr_chain(expr: &SubExpr, context: &RewriteContext<'_>) -> Option { + match expr.expr.kind { + ast::ExprKind::MethodCall(ref call) => Some(SubExpr { + expr: Self::convert_try(&call.receiver, context), + is_method_call_receiver: true, + }), ast::ExprKind::Field(ref subexpr, _) | ast::ExprKind::Try(ref subexpr) - | ast::ExprKind::Await(ref subexpr, _) => Some(Self::convert_try(subexpr, context)), + | ast::ExprKind::Await(ref subexpr, _) => Some(SubExpr { + expr: Self::convert_try(subexpr, context), + is_method_call_receiver: false, + }), _ => None, } } diff --git a/src/expr.rs b/src/expr.rs index 5b1b4fbd491..41cc3651992 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::{Delimiter, LitKind}; +use rustc_ast::token::{Delimiter, Lit, LitKind}; use rustc_ast::{ast, ptr, token}; use rustc_span::{BytePos, Span}; @@ -48,6 +48,10 @@ pub(crate) enum ExprType { SubExpression, } +pub(crate) fn lit_ends_in_dot(lit: &Lit) -> bool { + matches!(lit, Lit { kind: LitKind::Float, suffix: None, symbol } if symbol.as_str().ends_with('.')) +} + pub(crate) fn format_expr( expr: &ast::Expr, expr_type: ExprType, @@ -275,12 +279,7 @@ pub(crate) fn format_expr( fn needs_space_before_range(context: &RewriteContext<'_>, lhs: &ast::Expr) -> bool { match lhs.kind { - ast::ExprKind::Lit(token_lit) => match token_lit.kind { - token::LitKind::Float if token_lit.suffix.is_none() => { - context.snippet(lhs.span).ends_with('.') - } - _ => false, - }, + ast::ExprKind::Lit(token_lit) => lit_ends_in_dot(&token_lit), ast::ExprKind::Unary(_, ref expr) => needs_space_before_range(context, expr), _ => false, } @@ -1440,7 +1439,7 @@ pub(crate) fn span_ends_with_comma(context: &RewriteContext<'_>, span: Span) -> result } -fn rewrite_paren( +pub(crate) fn rewrite_paren( context: &RewriteContext<'_>, mut subexpr: &ast::Expr, shape: Shape, diff --git a/tests/source/issue-5791.rs b/tests/source/issue-5791.rs new file mode 100644 index 00000000000..40bc6daa9f9 --- /dev/null +++ b/tests/source/issue-5791.rs @@ -0,0 +1,3 @@ +pub fn main() { + 0. .to_string(); +} diff --git a/tests/target/issue-5791.rs b/tests/target/issue-5791.rs new file mode 100644 index 00000000000..3a44cf19a1b --- /dev/null +++ b/tests/target/issue-5791.rs @@ -0,0 +1,3 @@ +pub fn main() { + (0.).to_string(); +} -- cgit 1.4.1-3-g733a5 From 885085474653573cb3c49ed29cd3030555bfcae8 Mon Sep 17 00:00:00 2001 From: Cosmic Horror Date: Fri, 23 Jun 2023 19:07:12 -0600 Subject: Don't skip semicolon if exprs follow --- src/stmt.rs | 13 ++++++++++--- src/utils.rs | 10 ++++++++-- 2 files changed, 18 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/stmt.rs b/src/stmt.rs index 0b3854425ea..0148de8190b 100644 --- a/src/stmt.rs +++ b/src/stmt.rs @@ -80,13 +80,19 @@ impl<'a> Rewrite for Stmt<'a> { } else { ExprType::Statement }; - format_stmt(context, shape, self.as_ast_node(), expr_type) + format_stmt( + context, + shape, + self.as_ast_node(), + expr_type, + Some(self.is_last_expr()), + ) } } impl Rewrite for ast::Stmt { fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option { - format_stmt(context, shape, self, ExprType::Statement) + format_stmt(context, shape, self, ExprType::Statement, None) } } @@ -95,13 +101,14 @@ fn format_stmt( shape: Shape, stmt: &ast::Stmt, expr_type: ExprType, + is_last_expr: Option, ) -> Option { skip_out_of_file_lines_range!(context, stmt.span()); let result = match stmt.kind { ast::StmtKind::Local(ref local) => local.rewrite(context, shape), ast::StmtKind::Expr(ref ex) | ast::StmtKind::Semi(ref ex) => { - let suffix = if semicolon_for_stmt(context, stmt) { + let suffix = if semicolon_for_stmt(context, stmt, is_last_expr) { ";" } else { "" diff --git a/src/utils.rs b/src/utils.rs index 890a05b8c82..e768ae0a1bc 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -292,14 +292,20 @@ pub(crate) fn semicolon_for_expr(context: &RewriteContext<'_>, expr: &ast::Expr) } #[inline] -pub(crate) fn semicolon_for_stmt(context: &RewriteContext<'_>, stmt: &ast::Stmt) -> bool { +pub(crate) fn semicolon_for_stmt( + context: &RewriteContext<'_>, + stmt: &ast::Stmt, + is_last_expr: Option, +) -> bool { match stmt.kind { ast::StmtKind::Semi(ref expr) => match expr.kind { ast::ExprKind::While(..) | ast::ExprKind::Loop(..) | ast::ExprKind::ForLoop(..) => { false } ast::ExprKind::Break(..) | ast::ExprKind::Continue(..) | ast::ExprKind::Ret(..) => { - context.config.trailing_semicolon() + // The only time we can skip the semi-colon is if the config option is set to false + // **and** this is the last expr (even though any following exprs are unreachable) + context.config.trailing_semicolon() || !is_last_expr.unwrap_or(false) } _ => true, }, -- cgit 1.4.1-3-g733a5 From d9a09925d7ecfb46fb6a218dbf5479b51acc67c6 Mon Sep 17 00:00:00 2001 From: Cosmic Horror Date: Sat, 24 Jun 2023 12:35:20 -0600 Subject: Switch `ast::Stmt` rewriting use to `stmt::Stmt::from_simple_block` --- src/expr.rs | 23 ++++++++++++----------- src/stmt.rs | 27 ++++++++++++++++++--------- src/utils.rs | 4 ++-- 3 files changed, 32 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/expr.rs b/src/expr.rs index 41cc3651992..9a605d6427e 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -26,6 +26,7 @@ use crate::rewrite::{Rewrite, RewriteContext}; use crate::shape::{Indent, Shape}; use crate::source_map::{LineRangeUtils, SpanUtils}; use crate::spanned::Spanned; +use crate::stmt; use crate::string::{rewrite_string, StringFormat}; use crate::types::{rewrite_path, PathContext}; use crate::utils::{ @@ -515,9 +516,9 @@ fn rewrite_single_line_block( label: Option, shape: Shape, ) -> Option { - if is_simple_block(context, block, attrs) { + if let Some(block_expr) = stmt::Stmt::from_simple_block(context, block, attrs) { let expr_shape = shape.offset_left(last_line_width(prefix))?; - let expr_str = block.stmts[0].rewrite(context, expr_shape)?; + let expr_str = block_expr.rewrite(context, expr_shape)?; let label_str = rewrite_label(label); let result = format!("{}{}{{ {} }}", prefix, label_str, expr_str); if result.len() <= shape.width && !result.contains('\n') { @@ -799,19 +800,19 @@ impl<'a> ControlFlow<'a> { let fixed_cost = self.keyword.len() + " { } else { }".len(); if let ast::ExprKind::Block(ref else_node, _) = else_block.kind { - if !is_simple_block(context, self.block, None) - || !is_simple_block(context, else_node, None) - || pat_expr_str.contains('\n') - { - return None; - } + let (if_expr, else_expr) = match ( + stmt::Stmt::from_simple_block(context, self.block, None), + stmt::Stmt::from_simple_block(context, else_node, None), + pat_expr_str.contains('\n'), + ) { + (Some(if_expr), Some(else_expr), false) => (if_expr, else_expr), + _ => return None, + }; let new_width = width.checked_sub(pat_expr_str.len() + fixed_cost)?; - let expr = &self.block.stmts[0]; - let if_str = expr.rewrite(context, Shape::legacy(new_width, Indent::empty()))?; + let if_str = if_expr.rewrite(context, Shape::legacy(new_width, Indent::empty()))?; let new_width = new_width.checked_sub(if_str.len())?; - let else_expr = &else_node.stmts[0]; let else_str = else_expr.rewrite(context, Shape::legacy(new_width, Indent::empty()))?; if if_str.contains('\n') || else_str.contains('\n') { diff --git a/src/stmt.rs b/src/stmt.rs index 0148de8190b..e3fe4ebca11 100644 --- a/src/stmt.rs +++ b/src/stmt.rs @@ -3,7 +3,7 @@ use rustc_span::Span; use crate::comment::recover_comment_removed; use crate::config::Version; -use crate::expr::{format_expr, ExprType}; +use crate::expr::{format_expr, is_simple_block, ExprType}; use crate::rewrite::{Rewrite, RewriteContext}; use crate::shape::Shape; use crate::source_map::LineRangeUtils; @@ -33,6 +33,21 @@ impl<'a> Stmt<'a> { } } + pub(crate) fn from_simple_block( + context: &RewriteContext<'_>, + block: &'a ast::Block, + attrs: Option<&[ast::Attribute]>, + ) -> Option { + if is_simple_block(context, block, attrs) { + let inner = &block.stmts[0]; + // Simple blocks only contain one expr and no stmts + let is_last = true; + Some(Stmt { inner, is_last }) + } else { + None + } + } + pub(crate) fn from_ast_node(inner: &'a ast::Stmt, is_last: bool) -> Self { Stmt { inner, is_last } } @@ -85,23 +100,17 @@ impl<'a> Rewrite for Stmt<'a> { shape, self.as_ast_node(), expr_type, - Some(self.is_last_expr()), + self.is_last_expr(), ) } } -impl Rewrite for ast::Stmt { - fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option { - format_stmt(context, shape, self, ExprType::Statement, None) - } -} - fn format_stmt( context: &RewriteContext<'_>, shape: Shape, stmt: &ast::Stmt, expr_type: ExprType, - is_last_expr: Option, + is_last_expr: bool, ) -> Option { skip_out_of_file_lines_range!(context, stmt.span()); diff --git a/src/utils.rs b/src/utils.rs index e768ae0a1bc..b8a44d4bade 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -295,7 +295,7 @@ pub(crate) fn semicolon_for_expr(context: &RewriteContext<'_>, expr: &ast::Expr) pub(crate) fn semicolon_for_stmt( context: &RewriteContext<'_>, stmt: &ast::Stmt, - is_last_expr: Option, + is_last_expr: bool, ) -> bool { match stmt.kind { ast::StmtKind::Semi(ref expr) => match expr.kind { @@ -305,7 +305,7 @@ pub(crate) fn semicolon_for_stmt( ast::ExprKind::Break(..) | ast::ExprKind::Continue(..) | ast::ExprKind::Ret(..) => { // The only time we can skip the semi-colon is if the config option is set to false // **and** this is the last expr (even though any following exprs are unreachable) - context.config.trailing_semicolon() || !is_last_expr.unwrap_or(false) + context.config.trailing_semicolon() || !is_last_expr } _ => true, }, -- cgit 1.4.1-3-g733a5 From f2bad9c7af308e6290f69bdf31390f9359a0e77b Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Wed, 5 Jul 2023 14:05:53 -0500 Subject: fix: handle skip_macro_invocations from config file --- src/config/macro_names.rs | 14 ++++++++++++-- tests/config/issue-5816.toml | 1 + tests/source/skip_macro_invocations/config_file.rs | 9 +++++++++ tests/target/skip_macro_invocations/config_file.rs | 7 +++++++ 4 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 tests/config/issue-5816.toml create mode 100644 tests/source/skip_macro_invocations/config_file.rs create mode 100644 tests/target/skip_macro_invocations/config_file.rs (limited to 'src') diff --git a/src/config/macro_names.rs b/src/config/macro_names.rs index 26ad78d6dca..61658f0a212 100644 --- a/src/config/macro_names.rs +++ b/src/config/macro_names.rs @@ -3,7 +3,7 @@ use itertools::Itertools; use std::{fmt, str}; -use serde::{Deserialize, Serialize}; +use serde::{Deserialize, Deserializer, Serialize}; use serde_json as json; use thiserror::Error; @@ -30,12 +30,22 @@ impl From for String { } /// Defines a selector to match against a macro. -#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd, Deserialize, Serialize)] +#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd, Serialize)] pub enum MacroSelector { Name(MacroName), All, } +impl<'de> Deserialize<'de> for MacroSelector { + fn deserialize(de: D) -> Result + where + D: Deserializer<'de>, + { + let s = String::deserialize(de)?; + std::str::FromStr::from_str(&s).map_err(serde::de::Error::custom) + } +} + impl fmt::Display for MacroSelector { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { diff --git a/tests/config/issue-5816.toml b/tests/config/issue-5816.toml new file mode 100644 index 00000000000..00375746e3f --- /dev/null +++ b/tests/config/issue-5816.toml @@ -0,0 +1 @@ +skip_macro_invocations=["*", "println"] diff --git a/tests/source/skip_macro_invocations/config_file.rs b/tests/source/skip_macro_invocations/config_file.rs new file mode 100644 index 00000000000..e0f5ddf52e7 --- /dev/null +++ b/tests/source/skip_macro_invocations/config_file.rs @@ -0,0 +1,9 @@ +// rustfmt-unstable: true +// rustfmt-config: issue-5816.toml + +fn main() { + println!( "Hello, world!"); + let x = +7 +; +} diff --git a/tests/target/skip_macro_invocations/config_file.rs b/tests/target/skip_macro_invocations/config_file.rs new file mode 100644 index 00000000000..008e28db42d --- /dev/null +++ b/tests/target/skip_macro_invocations/config_file.rs @@ -0,0 +1,7 @@ +// rustfmt-unstable: true +// rustfmt-config: issue-5816.toml + +fn main() { + println!( "Hello, world!"); + let x = 7; +} -- cgit 1.4.1-3-g733a5 From 5ed7f74d103ff6032088ea43dc50cba6c590e216 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Thu, 6 Jul 2023 05:21:33 +0000 Subject: Actually use `tracing` for logging --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib.rs b/src/lib.rs index 2bd17e9982b..b9ab3ffd989 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,7 +8,7 @@ #[macro_use] extern crate lazy_static; #[macro_use] -extern crate log; +extern crate tracing; // N.B. these crates are loaded from the sysroot, so they need extern crate. extern crate rustc_ast; -- cgit 1.4.1-3-g733a5 From e0e633ef14e85fac498ec68bf68253e8473c23c5 Mon Sep 17 00:00:00 2001 From: Jordan McQueen Date: Tue, 18 Jul 2023 07:51:51 +0900 Subject: Use matches!() macro to improve readability (#5830) * Use matches!() macro to improve readability 1. Use `matches!()` macro in `is_line_comment` and `is_block_comment` to improve readability. 2. Very sightly improve the wording of the doc comment for these two functions. * Update wording on doc comment on is_line_comment() --- src/comment.rs | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/comment.rs b/src/comment.rs index 85918ecc116..c241e12c56a 100644 --- a/src/comment.rs +++ b/src/comment.rs @@ -58,25 +58,23 @@ fn custom_opener(s: &str) -> &str { } impl<'a> CommentStyle<'a> { - /// Returns `true` if the commenting style covers a line only. + /// Returns `true` if the commenting style cannot span multiple lines. pub(crate) fn is_line_comment(&self) -> bool { - match *self { + matches!( + self, CommentStyle::DoubleSlash - | CommentStyle::TripleSlash - | CommentStyle::Doc - | CommentStyle::Custom(_) => true, - _ => false, - } + | CommentStyle::TripleSlash + | CommentStyle::Doc + | CommentStyle::Custom(_) + ) } - /// Returns `true` if the commenting style can span over multiple lines. + /// Returns `true` if the commenting style can span multiple lines. pub(crate) fn is_block_comment(&self) -> bool { - match *self { - CommentStyle::SingleBullet | CommentStyle::DoubleBullet | CommentStyle::Exclamation => { - true - } - _ => false, - } + matches!( + self, + CommentStyle::SingleBullet | CommentStyle::DoubleBullet | CommentStyle::Exclamation + ) } /// Returns `true` if the commenting style is for documentation. -- cgit 1.4.1-3-g733a5 From b944a32e5cd153344ec93827821d8607c3988a09 Mon Sep 17 00:00:00 2001 From: tdanniels Date: Tue, 18 Jul 2023 18:48:57 -0700 Subject: Prevent ICE when formatting an empty-ish macro arm (#5833) Fixes 5730 Previously rustfmt was attempting to slice a string with an invalid range (`start > end`), leading to the ICE. When formatting a macro transcriber snippet consisting of a lone semicolon, the snippet was being formatted into the empty string, leading the enclosing `fn main() {\n}` added by `format_code_block` to be formatted into `fn main() {}`. However, rustfmt was assuming that the enclosing function string's length had been left unchanged. This was leading to an invalid range being constructed when attempting to trim off the enclosing function. The fix is to just clamp the range's start to be less than or equal to the range's end, since if `end < start` there's nothing to iterate over anyway. --- src/lib.rs | 9 ++++++++- tests/source/issue_5730.rs | 3 +++ tests/target/issue_5730.rs | 3 +++ 3 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 tests/source/issue_5730.rs create mode 100644 tests/target/issue_5730.rs (limited to 'src') diff --git a/src/lib.rs b/src/lib.rs index b9ab3ffd989..8800e200fa4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -28,6 +28,7 @@ extern crate thin_vec; extern crate rustc_driver; use std::cell::RefCell; +use std::cmp::min; use std::collections::HashMap; use std::fmt; use std::io::{self, Write}; @@ -385,9 +386,15 @@ fn format_code_block( .snippet .rfind('}') .unwrap_or_else(|| formatted.snippet.len()); + + // It's possible that `block_len < FN_MAIN_PREFIX.len()`. This can happen if the code block was + // formatted into the empty string, leading to the enclosing `fn main() {\n}` being formatted + // into `fn main() {}`. In this case no unindentation is done. + let block_start = min(FN_MAIN_PREFIX.len(), block_len); + let mut is_indented = true; let indent_str = Indent::from_width(config, config.tab_spaces()).to_string(config); - for (kind, ref line) in LineClasses::new(&formatted.snippet[FN_MAIN_PREFIX.len()..block_len]) { + for (kind, ref line) in LineClasses::new(&formatted.snippet[block_start..block_len]) { if !is_first { result.push('\n'); } else { diff --git a/tests/source/issue_5730.rs b/tests/source/issue_5730.rs new file mode 100644 index 00000000000..9a3f4f0d07a --- /dev/null +++ b/tests/source/issue_5730.rs @@ -0,0 +1,3 @@ +macro_rules! statement { + () => {;}; +} diff --git a/tests/target/issue_5730.rs b/tests/target/issue_5730.rs new file mode 100644 index 00000000000..7922fdcc90f --- /dev/null +++ b/tests/target/issue_5730.rs @@ -0,0 +1,3 @@ +macro_rules! statement { + () => {}; +} -- cgit 1.4.1-3-g733a5 From 2db13f448c889fa543e9b8060e865afe4d427bc4 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 19 Jul 2023 16:50:00 -0400 Subject: Support non-lifetime binders --- src/closures.rs | 4 ++-- src/types.rs | 19 ++++++++----------- tests/source/issue_5721.rs | 8 ++++++++ tests/source/non-lifetime-binders.rs | 10 ++++++++++ tests/target/issue_5721.rs | 10 ++++++++++ tests/target/non-lifetime-binders.rs | 10 ++++++++++ 6 files changed, 48 insertions(+), 13 deletions(-) create mode 100644 tests/source/issue_5721.rs create mode 100644 tests/source/non-lifetime-binders.rs create mode 100644 tests/target/issue_5721.rs create mode 100644 tests/target/non-lifetime-binders.rs (limited to 'src') diff --git a/src/closures.rs b/src/closures.rs index c95e9a97b43..cf128752919 100644 --- a/src/closures.rs +++ b/src/closures.rs @@ -12,7 +12,7 @@ use crate::overflow::OverflowableItem; use crate::rewrite::{Rewrite, RewriteContext}; use crate::shape::Shape; use crate::source_map::SpanUtils; -use crate::types::rewrite_lifetime_param; +use crate::types::rewrite_bound_params; use crate::utils::{last_line_width, left_most_sub_expr, stmt_expr, NodeIdExt}; // This module is pretty messy because of the rules around closures and blocks: @@ -246,7 +246,7 @@ fn rewrite_closure_fn_decl( "for<> ".to_owned() } ast::ClosureBinder::For { generic_params, .. } => { - let lifetime_str = rewrite_lifetime_param(context, shape, generic_params)?; + let lifetime_str = rewrite_bound_params(context, shape, generic_params)?; format!("for<{lifetime_str}> ") } ast::ClosureBinder::NotPresent => "".to_owned(), diff --git a/src/types.rs b/src/types.rs index 18a08f17ba0..bb236a386e4 100644 --- a/src/types.rs +++ b/src/types.rs @@ -426,10 +426,10 @@ impl Rewrite for ast::WherePredicate { }) => { let type_str = bounded_ty.rewrite(context, shape)?; let colon = type_bound_colon(context).trim_end(); - let lhs = if let Some(lifetime_str) = - rewrite_lifetime_param(context, shape, bound_generic_params) + let lhs = if let Some(binder_str) = + rewrite_bound_params(context, shape, bound_generic_params) { - format!("for<{}> {}{}", lifetime_str, type_str, colon) + format!("for<{}> {}{}", binder_str, type_str, colon) } else { format!("{}{}", type_str, colon) }; @@ -657,8 +657,7 @@ impl Rewrite for ast::GenericParam { impl Rewrite for ast::PolyTraitRef { fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option { - if let Some(lifetime_str) = - rewrite_lifetime_param(context, shape, &self.bound_generic_params) + if let Some(lifetime_str) = rewrite_bound_params(context, shape, &self.bound_generic_params) { // 6 is "for<> ".len() let extra_offset = lifetime_str.len() + 6; @@ -881,8 +880,7 @@ fn rewrite_bare_fn( let mut result = String::with_capacity(128); - if let Some(ref lifetime_str) = rewrite_lifetime_param(context, shape, &bare_fn.generic_params) - { + if let Some(ref lifetime_str) = rewrite_bound_params(context, shape, &bare_fn.generic_params) { result.push_str("for<"); // 6 = "for<> ".len(), 4 = "for<". // This doesn't work out so nicely for multiline situation with lots of @@ -1122,16 +1120,15 @@ pub(crate) fn can_be_overflowed_type( } } -/// Returns `None` if there is no `LifetimeDef` in the given generic parameters. -pub(crate) fn rewrite_lifetime_param( +/// Returns `None` if there is no `GenericParam` in the list +pub(crate) fn rewrite_bound_params( context: &RewriteContext<'_>, shape: Shape, generic_params: &[ast::GenericParam], ) -> Option { let result = generic_params .iter() - .filter(|p| matches!(p.kind, ast::GenericParamKind::Lifetime)) - .map(|lt| lt.rewrite(context, shape)) + .map(|param| param.rewrite(context, shape)) .collect::>>()? .join(", "); if result.is_empty() { diff --git a/tests/source/issue_5721.rs b/tests/source/issue_5721.rs new file mode 100644 index 00000000000..e5ae9612c98 --- /dev/null +++ b/tests/source/issue_5721.rs @@ -0,0 +1,8 @@ +#![feature(non_lifetime_binders)] +#![allow(incomplete_features)] + +trait Other {} + +trait Trait +where + for U: Other {} diff --git a/tests/source/non-lifetime-binders.rs b/tests/source/non-lifetime-binders.rs new file mode 100644 index 00000000000..c26393c8f89 --- /dev/null +++ b/tests/source/non-lifetime-binders.rs @@ -0,0 +1,10 @@ +fn main() where for<'a, T: Sized + 'a, const C: usize> [&'a T; C]: Sized { + let x = for + || {}; + + let y: dyn + for Into; + + let z: for + fn(T); +} diff --git a/tests/target/issue_5721.rs b/tests/target/issue_5721.rs new file mode 100644 index 00000000000..d073b09cac2 --- /dev/null +++ b/tests/target/issue_5721.rs @@ -0,0 +1,10 @@ +#![feature(non_lifetime_binders)] +#![allow(incomplete_features)] + +trait Other {} + +trait Trait +where + for U: Other, +{ +} diff --git a/tests/target/non-lifetime-binders.rs b/tests/target/non-lifetime-binders.rs new file mode 100644 index 00000000000..ca6941a0c00 --- /dev/null +++ b/tests/target/non-lifetime-binders.rs @@ -0,0 +1,10 @@ +fn main() +where + for<'a, T: Sized + 'a, const C: usize> [&'a T; C]: Sized, +{ + let x = for || {}; + + let y: dyn for Into; + + let z: for fn(T); +} -- cgit 1.4.1-3-g733a5 From a9ae746267e8ad4c2f4aaa7c2cf16d88d7886192 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Tue, 18 Jul 2023 17:31:22 +0000 Subject: misc code cleanup --- src/items.rs | 310 +++++++++++++++++++++++++++++------------------------------ 1 file changed, 154 insertions(+), 156 deletions(-) (limited to 'src') diff --git a/src/items.rs b/src/items.rs index d5bc38303e0..fd4e08ed403 100644 --- a/src/items.rs +++ b/src/items.rs @@ -306,22 +306,20 @@ impl<'a> FnSig<'a> { defaultness: ast::Defaultness, ) -> FnSig<'a> { match *fn_kind { - 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; - fn_sig - } - _ => FnSig { - decl, - generics, - ext: fn_sig.header.ext, - constness: fn_sig.header.constness, - is_async: Cow::Borrowed(&fn_sig.header.asyncness), - defaultness, - unsafety: fn_sig.header.unsafety, - visibility: vis, - }, + visit::FnKind::Fn(visit::FnCtxt::Assoc(..), _, fn_sig, vis, generics, _) => { + let mut fn_sig = FnSig::from_method_sig(fn_sig, generics, vis); + fn_sig.defaultness = defaultness; + fn_sig + } + visit::FnKind::Fn(_, _, fn_sig, vis, generics, _) => FnSig { + decl, + generics, + ext: fn_sig.header.ext, + constness: fn_sig.header.constness, + is_async: Cow::Borrowed(&fn_sig.header.asyncness), + defaultness, + unsafety: fn_sig.header.unsafety, + visibility: vis, }, _ => unreachable!(), } @@ -1118,172 +1116,172 @@ pub(crate) fn format_trait( item: &ast::Item, offset: Indent, ) -> Option { - if let ast::ItemKind::Trait(trait_kind) = &item.kind { - let ast::Trait { - is_auto, - unsafety, - ref generics, - ref bounds, - ref items, - } = **trait_kind; - let mut result = String::with_capacity(128); - let header = format!( - "{}{}{}trait ", - format_visibility(context, &item.vis), - format_unsafety(unsafety), - format_auto(is_auto), - ); - result.push_str(&header); + let ast::ItemKind::Trait(trait_kind) = &item.kind else { + unreachable!(); + }; + let ast::Trait { + is_auto, + unsafety, + ref generics, + ref bounds, + ref items, + } = **trait_kind; - let body_lo = context.snippet_provider.span_after(item.span, "{"); + let mut result = String::with_capacity(128); + let header = format!( + "{}{}{}trait ", + format_visibility(context, &item.vis), + format_unsafety(unsafety), + format_auto(is_auto), + ); + result.push_str(&header); - let shape = Shape::indented(offset, context.config).offset_left(result.len())?; - let generics_str = - rewrite_generics(context, rewrite_ident(context, item.ident), generics, shape)?; - result.push_str(&generics_str); + let body_lo = context.snippet_provider.span_after(item.span, "{"); - // FIXME(#2055): rustfmt fails to format when there are comments between trait bounds. - if !bounds.is_empty() { - let ident_hi = context - .snippet_provider - .span_after(item.span, item.ident.as_str()); - let bound_hi = bounds.last().unwrap().span().hi(); - let snippet = context.snippet(mk_sp(ident_hi, bound_hi)); - if contains_comment(snippet) { - return None; - } + let shape = Shape::indented(offset, context.config).offset_left(result.len())?; + let generics_str = + rewrite_generics(context, rewrite_ident(context, item.ident), generics, shape)?; + result.push_str(&generics_str); - result = rewrite_assign_rhs_with( - context, - result + ":", - bounds, - shape, - &RhsAssignKind::Bounds, - RhsTactics::ForceNextLineWithoutIndent, - )?; + // FIXME(#2055): rustfmt fails to format when there are comments between trait bounds. + if !bounds.is_empty() { + let ident_hi = context + .snippet_provider + .span_after(item.span, item.ident.as_str()); + let bound_hi = bounds.last().unwrap().span().hi(); + let snippet = context.snippet(mk_sp(ident_hi, bound_hi)); + if contains_comment(snippet) { + return None; } - // Rewrite where-clause. - if !generics.where_clause.predicates.is_empty() { - let where_on_new_line = context.config.indent_style() != IndentStyle::Block; + result = rewrite_assign_rhs_with( + context, + result + ":", + bounds, + shape, + &RhsAssignKind::Bounds, + RhsTactics::ForceNextLineWithoutIndent, + )?; + } + + // Rewrite where-clause. + if !generics.where_clause.predicates.is_empty() { + let where_on_new_line = context.config.indent_style() != IndentStyle::Block; - let where_budget = context.budget(last_line_width(&result)); - let pos_before_where = if bounds.is_empty() { - generics.where_clause.span.lo() + let where_budget = context.budget(last_line_width(&result)); + let pos_before_where = if bounds.is_empty() { + generics.where_clause.span.lo() + } else { + bounds[bounds.len() - 1].span().hi() + }; + let option = WhereClauseOption::snuggled(&generics_str); + let where_clause_str = rewrite_where_clause( + context, + &generics.where_clause.predicates, + generics.where_clause.span, + context.config.brace_style(), + Shape::legacy(where_budget, offset.block_only()), + where_on_new_line, + "{", + None, + pos_before_where, + option, + )?; + // If the where-clause cannot fit on the same line, + // put the where-clause on a new line + if !where_clause_str.contains('\n') + && last_line_width(&result) + where_clause_str.len() + offset.width() + > context.config.comment_width() + { + let width = offset.block_indent + context.config.tab_spaces() - 1; + let where_indent = Indent::new(0, width); + result.push_str(&where_indent.to_string_with_newline(context.config)); + } + result.push_str(&where_clause_str); + } else { + let item_snippet = context.snippet(item.span); + if let Some(lo) = item_snippet.find('/') { + // 1 = `{` + let comment_hi = if generics.params.len() > 0 { + generics.span.lo() - BytePos(1) } else { - bounds[bounds.len() - 1].span().hi() + body_lo - BytePos(1) }; - let option = WhereClauseOption::snuggled(&generics_str); - let where_clause_str = rewrite_where_clause( - context, - &generics.where_clause.predicates, - generics.where_clause.span, - context.config.brace_style(), - Shape::legacy(where_budget, offset.block_only()), - where_on_new_line, - "{", - None, - pos_before_where, - option, - )?; - // If the where-clause cannot fit on the same line, - // put the where-clause on a new line - if !where_clause_str.contains('\n') - && last_line_width(&result) + where_clause_str.len() + offset.width() - > context.config.comment_width() - { - let width = offset.block_indent + context.config.tab_spaces() - 1; - let where_indent = Indent::new(0, width); - result.push_str(&where_indent.to_string_with_newline(context.config)); - } - result.push_str(&where_clause_str); - } else { - let item_snippet = context.snippet(item.span); - if let Some(lo) = item_snippet.find('/') { - // 1 = `{` - let comment_hi = if generics.params.len() > 0 { - generics.span.lo() - BytePos(1) - } else { - body_lo - BytePos(1) - }; - let comment_lo = item.span.lo() + BytePos(lo as u32); - if comment_lo < comment_hi { - match recover_missing_comment_in_span( - mk_sp(comment_lo, comment_hi), - Shape::indented(offset, context.config), - context, - last_line_width(&result), - ) { - Some(ref missing_comment) if !missing_comment.is_empty() => { - result.push_str(missing_comment); - } - _ => (), + let comment_lo = item.span.lo() + BytePos(lo as u32); + if comment_lo < comment_hi { + match recover_missing_comment_in_span( + mk_sp(comment_lo, comment_hi), + Shape::indented(offset, context.config), + context, + last_line_width(&result), + ) { + Some(ref missing_comment) if !missing_comment.is_empty() => { + result.push_str(missing_comment); } + _ => (), } } } + } - let block_span = mk_sp(generics.where_clause.span.hi(), item.span.hi()); - let snippet = context.snippet(block_span); - let open_pos = snippet.find_uncommented("{")? + 1; + let block_span = mk_sp(generics.where_clause.span.hi(), item.span.hi()); + let snippet = context.snippet(block_span); + let open_pos = snippet.find_uncommented("{")? + 1; - match context.config.brace_style() { - _ if last_line_contains_single_line_comment(&result) - || last_line_width(&result) + 2 > context.budget(offset.width()) => - { - result.push_str(&offset.to_string_with_newline(context.config)); - } - _ if context.config.empty_item_single_line() - && items.is_empty() - && !result.contains('\n') - && !contains_comment(&snippet[open_pos..]) => + match context.config.brace_style() { + _ if last_line_contains_single_line_comment(&result) + || last_line_width(&result) + 2 > context.budget(offset.width()) => + { + result.push_str(&offset.to_string_with_newline(context.config)); + } + _ if context.config.empty_item_single_line() + && items.is_empty() + && !result.contains('\n') + && !contains_comment(&snippet[open_pos..]) => + { + result.push_str(" {}"); + return Some(result); + } + BraceStyle::AlwaysNextLine => { + result.push_str(&offset.to_string_with_newline(context.config)); + } + BraceStyle::PreferSameLine => result.push(' '), + BraceStyle::SameLineWhere => { + if result.contains('\n') + || (!generics.where_clause.predicates.is_empty() && !items.is_empty()) { - result.push_str(" {}"); - return Some(result); - } - BraceStyle::AlwaysNextLine => { result.push_str(&offset.to_string_with_newline(context.config)); - } - BraceStyle::PreferSameLine => result.push(' '), - BraceStyle::SameLineWhere => { - if result.contains('\n') - || (!generics.where_clause.predicates.is_empty() && !items.is_empty()) - { - result.push_str(&offset.to_string_with_newline(context.config)); - } else { - result.push(' '); - } + } else { + result.push(' '); } } - result.push('{'); - - let outer_indent_str = offset.block_only().to_string_with_newline(context.config); + } + result.push('{'); - if !items.is_empty() || contains_comment(&snippet[open_pos..]) { - let mut visitor = FmtVisitor::from_context(context); - visitor.block_indent = offset.block_only().block_indent(context.config); - visitor.last_pos = block_span.lo() + BytePos(open_pos as u32); + let outer_indent_str = offset.block_only().to_string_with_newline(context.config); - for item in items { - visitor.visit_trait_item(item); - } + if !items.is_empty() || contains_comment(&snippet[open_pos..]) { + let mut visitor = FmtVisitor::from_context(context); + visitor.block_indent = offset.block_only().block_indent(context.config); + visitor.last_pos = block_span.lo() + BytePos(open_pos as u32); - visitor.format_missing(item.span.hi() - BytePos(1)); + for item in items { + visitor.visit_trait_item(item); + } - let inner_indent_str = visitor.block_indent.to_string_with_newline(context.config); + visitor.format_missing(item.span.hi() - BytePos(1)); - result.push_str(&inner_indent_str); - result.push_str(visitor.buffer.trim()); - result.push_str(&outer_indent_str); - } else if result.contains('\n') { - result.push_str(&outer_indent_str); - } + let inner_indent_str = visitor.block_indent.to_string_with_newline(context.config); - result.push('}'); - Some(result) - } else { - unreachable!(); + result.push_str(&inner_indent_str); + result.push_str(visitor.buffer.trim()); + result.push_str(&outer_indent_str); + } else if result.contains('\n') { + result.push_str(&outer_indent_str); } + + result.push('}'); + Some(result) } pub(crate) struct TraitAliasBounds<'a> { -- cgit 1.4.1-3-g733a5 From cdfa2f86b729b0bbba8661bca075a5974cec83bf Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Fri, 30 Sep 2022 12:41:44 -0400 Subject: Handle `dyn*` syntax when rewriting `ast::TyKind::TraitObject` Resolves 5542 Prior to rust-lang/rust#101212 the `ast::TraitObjectSyntax` enum only had two variants `Dyn` and `None`. The PR that introduced the `dyn*` syntax added a new variant `DynStar`, but did not update the formatting rules to account for the new variant. Now the new `DynStar` variant is properly handled and is no longer removed by rustfmt. --- src/types.rs | 14 ++++++-------- tests/target/issue_5542.rs | 10 ++++++++++ 2 files changed, 16 insertions(+), 8 deletions(-) create mode 100644 tests/target/issue_5542.rs (limited to 'src') diff --git a/src/types.rs b/src/types.rs index bb236a386e4..aef85598f06 100644 --- a/src/types.rs +++ b/src/types.rs @@ -683,9 +683,11 @@ impl Rewrite for ast::Ty { match self.kind { ast::TyKind::TraitObject(ref bounds, tobj_syntax) => { // we have to consider 'dyn' keyword is used or not!!! - let is_dyn = tobj_syntax == ast::TraitObjectSyntax::Dyn; - // 4 is length of 'dyn ' - let shape = if is_dyn { shape.offset_left(4)? } else { shape }; + let (shape, prefix) = match tobj_syntax { + ast::TraitObjectSyntax::Dyn => (shape.offset_left(4)?, "dyn "), + ast::TraitObjectSyntax::DynStar => (shape.offset_left(5)?, "dyn* "), + ast::TraitObjectSyntax::None => (shape, ""), + }; let mut res = bounds.rewrite(context, shape)?; // We may have falsely removed a trailing `+` inside macro call. if context.inside_macro() && bounds.len() == 1 { @@ -693,11 +695,7 @@ impl Rewrite for ast::Ty { res.push('+'); } } - if is_dyn { - Some(format!("dyn {}", res)) - } else { - Some(res) - } + Some(format!("{}{}", prefix, res)) } ast::TyKind::Ptr(ref mt) => { let prefix = match mt.mutbl { diff --git a/tests/target/issue_5542.rs b/tests/target/issue_5542.rs new file mode 100644 index 00000000000..730bb7b681a --- /dev/null +++ b/tests/target/issue_5542.rs @@ -0,0 +1,10 @@ +#![feature(dyn_star)] +#![allow(incomplete_features)] + +use core::fmt::Debug; + +fn main() { + let i = 42; + let dyn_i = i as dyn* Debug; + dbg!(dyn_i); +} -- cgit 1.4.1-3-g733a5 From a72613be50f8afa39c2d46f732252463dc9cc14f Mon Sep 17 00:00:00 2001 From: Catherine <114838443+Centri3@users.noreply.github.com> Date: Tue, 18 Jul 2023 09:41:56 -0500 Subject: Add parenthesis around closure method call --- src/chains.rs | 25 ++++++++++++++++++++----- tests/source/issue-4808.rs | 13 +++++++++++++ tests/target/issue-4808.rs | 13 +++++++++++++ 3 files changed, 46 insertions(+), 5 deletions(-) create mode 100644 tests/source/issue-4808.rs create mode 100644 tests/target/issue-4808.rs (limited to 'src') diff --git a/src/chains.rs b/src/chains.rs index bf09d817ed1..d4876389c86 100644 --- a/src/chains.rs +++ b/src/chains.rs @@ -253,11 +253,7 @@ impl ChainItemKind { return ( ChainItemKind::Parent { expr: expr.clone(), - parens: is_method_call_receiver - && matches!( - &expr.kind, - ast::ExprKind::Lit(lit) if crate::expr::lit_ends_in_dot(lit) - ), + parens: is_method_call_receiver && should_add_parens(expr), }, expr.span, ); @@ -982,3 +978,22 @@ fn trim_tries(s: &str) -> String { } result } + +/// Whether a method call's receiver needs parenthesis, like +/// ```rust,ignore +/// || .. .method(); +/// || 1.. .method(); +/// 1. .method(); +/// ``` +/// Which all need parenthesis or a space before `.method()`. +fn should_add_parens(expr: &ast::Expr) -> bool { + match expr.kind { + ast::ExprKind::Lit(ref lit) => crate::expr::lit_ends_in_dot(lit), + ast::ExprKind::Closure(ref cl) => match cl.body.kind { + ast::ExprKind::Range(_, _, ast::RangeLimits::HalfOpen) => true, + ast::ExprKind::Lit(ref lit) => crate::expr::lit_ends_in_dot(lit), + _ => false, + }, + _ => false, + } +} diff --git a/tests/source/issue-4808.rs b/tests/source/issue-4808.rs new file mode 100644 index 00000000000..93076edcdce --- /dev/null +++ b/tests/source/issue-4808.rs @@ -0,0 +1,13 @@ +trait Trait { + fn method(&self) {} +} + +impl T, T> Trait for F {} + +impl Trait for f32 {} + +fn main() { + || 10. .method(); + || .. .method(); + || 1.. .method(); +} diff --git a/tests/target/issue-4808.rs b/tests/target/issue-4808.rs new file mode 100644 index 00000000000..cdef53a1bfc --- /dev/null +++ b/tests/target/issue-4808.rs @@ -0,0 +1,13 @@ +trait Trait { + fn method(&self) {} +} + +impl T, T> Trait for F {} + +impl Trait for f32 {} + +fn main() { + || (10.).method(); + (|| ..).method(); + (|| 1..).method(); +} -- cgit 1.4.1-3-g733a5 From 36af403e6b4968b622975888a22adab36f75b64e Mon Sep 17 00:00:00 2001 From: Richard Date: Sat, 12 Aug 2023 17:05:04 -0500 Subject: improve the --file-lines help (#5846) * improve the file-lines example * fix help order --- src/bin/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/bin/main.rs b/src/bin/main.rs index 2ff67d27e1b..97d31852d63 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -422,7 +422,7 @@ are 1-based and inclusive of both end points. Specifying an empty array will result in no files being formatted. For example, ``` -rustfmt --file-lines '[ +rustfmt src/lib.rs src/foo.rs --file-lines '[ {{\"file\":\"src/lib.rs\",\"range\":[7,13]}}, {{\"file\":\"src/lib.rs\",\"range\":[21,29]}}, {{\"file\":\"src/foo.rs\",\"range\":[10,11]}}, -- cgit 1.4.1-3-g733a5 From 9f58224123f8185edca08035b74d741fbc0620fb Mon Sep 17 00:00:00 2001 From: Charles Lew Date: Sat, 29 Jul 2023 09:10:09 +0800 Subject: Update Unicode data to 15.0 --- Cargo.lock | 20 ++++++++++---------- Cargo.toml | 2 +- src/string.rs | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/Cargo.lock b/Cargo.lock index e867f2cb840..bcac61ef342 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -588,9 +588,9 @@ dependencies = [ "toml", "tracing", "tracing-subscriber", + "unicode-properties", "unicode-segmentation", "unicode-width", - "unicode_categories", ] [[package]] @@ -852,22 +852,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" [[package]] -name = "unicode-segmentation" -version = "1.9.0" +name = "unicode-properties" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" +checksum = "c7f91c8b21fbbaa18853c3d0801c78f4fc94cdb976699bb03e832e75f7fd22f0" [[package]] -name = "unicode-width" -version = "0.1.9" +name = "unicode-segmentation" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" [[package]] -name = "unicode_categories" -version = "0.1.1" +name = "unicode-width" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" [[package]] name = "utf8parse" diff --git a/Cargo.toml b/Cargo.toml index f4c4bab37cb..5a800e95a0d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -54,7 +54,7 @@ tracing = "0.1.37" tracing-subscriber = { version = "0.3.17", features = ["env-filter"] } unicode-segmentation = "1.9" unicode-width = "0.1" -unicode_categories = "0.1" +unicode-properties = { version = "0.1", default-features = false, features = ["general-category"] } rustfmt-config_proc_macro = { version = "0.3", path = "config_proc_macro" } diff --git a/src/string.rs b/src/string.rs index 78b72a50cb2..cb666fff695 100644 --- a/src/string.rs +++ b/src/string.rs @@ -1,7 +1,7 @@ // Format string literals. use regex::Regex; -use unicode_categories::UnicodeCategories; +use unicode_properties::{GeneralCategory, UnicodeGeneralCategory}; use unicode_segmentation::UnicodeSegmentation; use crate::config::Config; @@ -366,7 +366,7 @@ fn is_whitespace(grapheme: &str) -> bool { fn is_punctuation(grapheme: &str) -> bool { grapheme .chars() - .all(UnicodeCategories::is_punctuation_other) + .all(|c| c.general_category() == GeneralCategory::OtherPunctuation) } fn graphemes_width(graphemes: &[&str]) -> usize { -- cgit 1.4.1-3-g733a5 From 0d4c1431f58ca10300a323cb4a3b7e472da11551 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Fri, 11 Aug 2023 09:02:04 -0400 Subject: Improve formatting of empty macro_rules! definitions Fixes 5882 --- src/macros.rs | 24 ++++++++++++++++++++++++ tests/source/issue_5882.rs | 7 +++++++ tests/target/issue_5882.rs | 7 +++++++ 3 files changed, 38 insertions(+) create mode 100644 tests/source/issue_5882.rs create mode 100644 tests/target/issue_5882.rs (limited to 'src') diff --git a/src/macros.rs b/src/macros.rs index e9a298a2769..88d26358b87 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -379,6 +379,23 @@ fn handle_vec_semi( } } +fn rewrite_empty_macro_def_body( + context: &RewriteContext<'_>, + span: Span, + shape: Shape, +) -> Option { + // Create an empty, dummy `ast::Block` representing an empty macro body + let block = ast::Block { + stmts: vec![].into(), + id: rustc_ast::node_id::DUMMY_NODE_ID, + rules: ast::BlockCheckMode::Default, + span: span, + tokens: None, + could_be_bare_literal: false, + }; + block.rewrite(context, shape) +} + pub(crate) fn rewrite_macro_def( context: &RewriteContext<'_>, shape: Shape, @@ -419,6 +436,13 @@ pub(crate) fn rewrite_macro_def( shape }; + if parsed_def.branches.len() == 0 { + let lo = context.snippet_provider.span_before(span, "{"); + result += " "; + result += &rewrite_empty_macro_def_body(context, span.with_lo(lo), shape)?; + return Some(result); + } + let branch_items = itemize_list( context.snippet_provider, parsed_def.branches.iter(), diff --git a/tests/source/issue_5882.rs b/tests/source/issue_5882.rs new file mode 100644 index 00000000000..e36f9965438 --- /dev/null +++ b/tests/source/issue_5882.rs @@ -0,0 +1,7 @@ +macro_rules!foo{} +macro_rules!bar{/*comment*/} +macro_rules!baz{//comment +} +macro_rules!foobar{ +//comment +} diff --git a/tests/target/issue_5882.rs b/tests/target/issue_5882.rs new file mode 100644 index 00000000000..565fb434a6a --- /dev/null +++ b/tests/target/issue_5882.rs @@ -0,0 +1,7 @@ +macro_rules! foo {} +macro_rules! bar { /*comment*/ } +macro_rules! baz { //comment +} +macro_rules! foobar { + //comment +} -- cgit 1.4.1-3-g733a5 From d8aeabaee103bc1788ee237c6bdcd4c345923963 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Thu, 26 Jan 2023 13:50:02 -0500 Subject: include block label length when calculating pat_shape of a match arm Previously we alwasy assumed the match arm pattern would have `shape.width` - 5 characters of space to work with. Now if we're formatting a block expression with a label we'll take the label into account. --- src/matches.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/matches.rs b/src/matches.rs index aac5e59b860..fe9e7836ba7 100644 --- a/src/matches.rs +++ b/src/matches.rs @@ -246,8 +246,18 @@ fn rewrite_match_arm( }; // Patterns - // 5 = ` => {` - let pat_shape = shape.sub_width(5)?.offset_left(pipe_offset)?; + let pat_shape = match &arm.body.kind { + ast::ExprKind::Block(_, Some(label)) => { + // Some block with a label ` => 'label: {` + // 7 = ` => : {` + let label_len = label.ident.as_str().len(); + shape.sub_width(7 + label_len)?.offset_left(pipe_offset)? + } + _ => { + // 5 = ` => {` + shape.sub_width(5)?.offset_left(pipe_offset)? + } + }; let pats_str = arm.pat.rewrite(context, pat_shape)?; // Guard -- cgit 1.4.1-3-g733a5 From e86c2ba5459679cf264fd2f037e246f1924686ac Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Thu, 26 Jan 2023 13:50:18 -0500 Subject: Don't flatten blocks that have labels --- src/matches.rs | 5 +++-- tests/target/issue_5676.rs | 8 ++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 tests/target/issue_5676.rs (limited to 'src') diff --git a/src/matches.rs b/src/matches.rs index fe9e7836ba7..a7677c3a35c 100644 --- a/src/matches.rs +++ b/src/matches.rs @@ -306,8 +306,9 @@ fn block_can_be_flattened<'a>( expr: &'a ast::Expr, ) -> Option<&'a ast::Block> { match expr.kind { - ast::ExprKind::Block(ref block, _) - if !is_unsafe_block(block) + ast::ExprKind::Block(ref block, label) + if label.is_none() + && !is_unsafe_block(block) && !context.inside_macro() && is_simple_block(context, block, Some(&expr.attrs)) && !stmt_is_expr_mac(&block.stmts[0]) => diff --git a/tests/target/issue_5676.rs b/tests/target/issue_5676.rs new file mode 100644 index 00000000000..25877110545 --- /dev/null +++ b/tests/target/issue_5676.rs @@ -0,0 +1,8 @@ +fn main() { + match true { + true => 'a: { + break 'a; + } + _ => (), + } +} -- cgit 1.4.1-3-g733a5 From b069aac44ddfdb70d55d9ae40695be44515e5bb0 Mon Sep 17 00:00:00 2001 From: Yuri Astrakhan Date: Sun, 13 Aug 2023 21:14:31 +0200 Subject: Inline format arguments for easier reading (#5881) * Inline format arguments for easier reading Code becomes shorter and often easier to read when format args are inlined. Note that I skipped the mixed cases to make it more straightforward (could be done separatelly). Also, there are two FIXME comments - for some reasons inlining makes format string exceed 100 char line width and crash. ``` cargo clippy --workspace --allow-dirty --fix --benches --tests --bins -- -A clippy::all -W clippy::uninlined_format_args ``` * address feedback --- src/attr.rs | 8 +++--- src/attr/doc_comment.rs | 6 ++--- src/bin/main.rs | 19 ++++++------- src/cargo-fmt/main.rs | 9 +++---- src/chains.rs | 2 +- src/closures.rs | 7 ++--- src/comment.rs | 35 +++++++----------------- src/config/config_type.rs | 10 +++---- src/config/file_lines.rs | 2 +- src/config/macro_names.rs | 2 +- src/config/mod.rs | 15 +++++------ src/config/options.rs | 2 +- src/emitter.rs | 2 +- src/emitter/checkstyle.rs | 4 +-- src/emitter/checkstyle/xml.rs | 2 +- src/emitter/diff.rs | 6 ++--- src/emitter/json.rs | 6 ++--- src/emitter/stdout.rs | 4 +-- src/expr.rs | 57 +++++++++++++++++++-------------------- src/format-diff/main.rs | 8 +++--- src/formatting.rs | 2 +- src/git-rustfmt/main.rs | 4 +-- src/imports.rs | 20 +++++++------- src/items.rs | 40 +++++++++++++-------------- src/macros.rs | 32 +++++++++++----------- src/matches.rs | 6 ++--- src/pairs.rs | 4 +-- src/parse/session.rs | 3 +-- src/patterns.rs | 8 +++--- src/rustfmt_diff.rs | 17 ++++++------ src/skip.rs | 2 +- src/source_file.rs | 2 +- src/test/configuration_snippet.rs | 10 +++---- src/test/mod.rs | 22 +++++++-------- src/types.rs | 16 +++++------ src/utils.rs | 4 +-- tests/cargo-fmt/main.rs | 2 +- tests/rustfmt/main.rs | 6 ++--- 38 files changed, 183 insertions(+), 223 deletions(-) (limited to 'src') diff --git a/src/attr.rs b/src/attr.rs index 22e45082a9f..4d83547d664 100644 --- a/src/attr.rs +++ b/src/attr.rs @@ -308,7 +308,7 @@ impl Rewrite for ast::MetaItem { // See #2479 for example. let value = rewrite_literal(context, lit.as_token_lit(), lit.span, lit_shape) .unwrap_or_else(|| context.snippet(lit.span).to_owned()); - format!("{} = {}", path, value) + format!("{path} = {value}") } }) } @@ -342,7 +342,7 @@ impl Rewrite for ast::Attribute { let literal_str = literal.as_str(); let doc_comment_formatter = DocCommentFormatter::new(literal_str, comment_style); - let doc_comment = format!("{}", doc_comment_formatter); + let doc_comment = format!("{doc_comment_formatter}"); return rewrite_doc_comment( &doc_comment, shape.comment(context.config), @@ -406,9 +406,9 @@ impl Rewrite for [ast::Attribute] { 0, )?; let comment = if comment.is_empty() { - format!("\n{}", mlb) + format!("\n{mlb}") } else { - format!("{}{}\n{}", mla, comment, mlb) + format!("{mla}{comment}\n{mlb}") }; result.push_str(&comment); result.push_str(&shape.indent.to_string(context.config)); diff --git a/src/attr/doc_comment.rs b/src/attr/doc_comment.rs index 25c8158df8c..f55201839b5 100644 --- a/src/attr/doc_comment.rs +++ b/src/attr/doc_comment.rs @@ -20,15 +20,15 @@ impl Display for DocCommentFormatter<'_> { // Handle `#[doc = ""]`. if lines.peek().is_none() { - return write!(formatter, "{}", opener); + return write!(formatter, "{opener}"); } while let Some(line) = lines.next() { let is_last_line = lines.peek().is_none(); if is_last_line { - write!(formatter, "{}{}", opener, line)?; + write!(formatter, "{opener}{line}")?; } else { - writeln!(formatter, "{}{}", opener, line)?; + writeln!(formatter, "{opener}{line}")?; } } Ok(()) diff --git a/src/bin/main.rs b/src/bin/main.rs index 97d31852d63..6f564083656 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -38,7 +38,7 @@ fn main() { let exit_code = match execute(&opts) { Ok(code) => code, Err(e) => { - eprintln!("{:#}", e); + eprintln!("{e:#}"); 1 } }; @@ -284,7 +284,7 @@ fn format_string(input: String, options: GetOptsOptions) -> Result { for f in config.file_lines().files() { match *f { FileName::Stdin => {} - _ => eprintln!("Warning: Extra file listed in file_lines option '{}'", f), + _ => eprintln!("Warning: Extra file listed in file_lines option '{f}'"), } } @@ -380,7 +380,7 @@ fn format_and_emit_report(session: &mut Session<'_, T>, input: Input) } } Err(msg) => { - eprintln!("Error writing files: {}", msg); + eprintln!("Error writing files: {msg}"); session.add_operational_error(); } } @@ -403,12 +403,9 @@ fn print_usage_to_stdout(opts: &Options, reason: &str) { let sep = if reason.is_empty() { String::new() } else { - format!("{}\n\n", reason) + format!("{reason}\n\n") }; - let msg = format!( - "{}Format Rust code\n\nusage: rustfmt [options] ...", - sep - ); + let msg = format!("{sep}Format Rust code\n\nusage: rustfmt [options] ..."); println!("{}", opts.usage(&msg)); } @@ -442,7 +439,7 @@ fn print_version() { include_str!(concat!(env!("OUT_DIR"), "/commit-info.txt")) ); - println!("rustfmt {}", version_info); + println!("rustfmt {version_info}"); } fn determine_operation(matches: &Matches) -> Result { @@ -647,9 +644,9 @@ impl GetOptsOptions { match *f { FileName::Real(ref f) if files.contains(f) => {} FileName::Real(_) => { - eprintln!("Warning: Extra file listed in file_lines option '{}'", f) + eprintln!("Warning: Extra file listed in file_lines option '{f}'") } - FileName::Stdin => eprintln!("Warning: Not a file '{}'", f), + FileName::Stdin => eprintln!("Warning: Not a file '{f}'"), } } } diff --git a/src/cargo-fmt/main.rs b/src/cargo-fmt/main.rs index bc9745275f2..3d399c12978 100644 --- a/src/cargo-fmt/main.rs +++ b/src/cargo-fmt/main.rs @@ -200,14 +200,13 @@ fn convert_message_format_to_rustfmt_args( } "human" => Ok(()), _ => Err(format!( - "invalid --message-format value: {}. Allowed values are: short|json|human", - message_format + "invalid --message-format value: {message_format}. Allowed values are: short|json|human" )), } } fn print_usage_to_stderr(reason: &str) { - eprintln!("{}", reason); + eprintln!("{reason}"); let app = Opts::command(); app.after_help("") .write_help(&mut io::stderr()) @@ -460,7 +459,7 @@ fn get_targets_with_hitlist( let package = workspace_hitlist.iter().next().unwrap(); Err(io::Error::new( io::ErrorKind::InvalidInput, - format!("package `{}` is not a member of the workspace", package), + format!("package `{package}` is not a member of the workspace"), )) } } @@ -498,7 +497,7 @@ fn run_rustfmt( if verbosity == Verbosity::Verbose { print!("rustfmt"); - print!(" --edition {}", edition); + print!(" --edition {edition}"); fmt_args.iter().for_each(|f| print!(" {}", f)); files.iter().for_each(|f| print!(" {}", f.display())); println!(); diff --git a/src/chains.rs b/src/chains.rs index d4876389c86..ea23690caed 100644 --- a/src/chains.rs +++ b/src/chains.rs @@ -296,7 +296,7 @@ impl Rewrite for ChainItem { rewrite_comment(comment, false, shape, context.config)? } }; - Some(format!("{}{}", rewrite, "?".repeat(self.tries))) + Some(format!("{rewrite}{}", "?".repeat(self.tries))) } } diff --git a/src/closures.rs b/src/closures.rs index cf128752919..a09146e9592 100644 --- a/src/closures.rs +++ b/src/closures.rs @@ -175,7 +175,7 @@ fn rewrite_closure_with_block( shape, false, )?; - Some(format!("{} {}", prefix, block)) + Some(format!("{prefix} {block}")) } // Rewrite closure with a single expression without wrapping its body with block. @@ -310,10 +310,7 @@ fn rewrite_closure_fn_decl( .tactic(tactic) .preserve_newline(true); let list_str = write_list(&item_vec, &fmt)?; - let mut prefix = format!( - "{}{}{}{}{}|{}|", - binder, const_, immovable, is_async, mover, list_str - ); + let mut prefix = format!("{binder}{const_}{immovable}{is_async}{mover}|{list_str}|"); if !ret_str.is_empty() { if prefix.contains('\n') { diff --git a/src/comment.rs b/src/comment.rs index c241e12c56a..a000d110daa 100644 --- a/src/comment.rs +++ b/src/comment.rs @@ -621,7 +621,7 @@ impl<'a> CommentRewrite<'a> { is_prev_line_multi_line: false, code_block_attr: None, item_block: None, - comment_line_separator: format!("{}{}", indent_str, line_start), + comment_line_separator: format!("{indent_str}{line_start}"), max_width, indent_str, fmt_indent: shape.indent, @@ -951,7 +951,7 @@ const RUSTFMT_CUSTOM_COMMENT_PREFIX: &str = "//#### "; fn hide_sharp_behind_comment(s: &str) -> Cow<'_, str> { let s_trimmed = s.trim(); if s_trimmed.starts_with("# ") || s_trimmed == "#" { - Cow::from(format!("{}{}", RUSTFMT_CUSTOM_COMMENT_PREFIX, s)) + Cow::from(format!("{RUSTFMT_CUSTOM_COMMENT_PREFIX}{s}")) } else { Cow::from(s) } @@ -1035,7 +1035,7 @@ pub(crate) fn recover_missing_comment_in_span( } else { Cow::from(" ") }; - Some(format!("{}{}", sep, missing_comment)) + Some(format!("{sep}{missing_comment}")) } } @@ -1832,8 +1832,7 @@ fn remove_comment_header(comment: &str) -> &str { } else { assert!( comment.starts_with("/*"), - "string '{}' is not a comment", - comment + "string '{comment}' is not a comment" ); &comment[2..comment.len() - 2] } @@ -2069,26 +2068,13 @@ fn main() { expected_line_start: &str, ) { let block = ItemizedBlock::new(test_input).unwrap(); - assert_eq!(1, block.lines.len(), "test_input: {:?}", test_input); - assert_eq!( - expected_line, &block.lines[0], - "test_input: {:?}", - test_input - ); - assert_eq!( - expected_indent, block.indent, - "test_input: {:?}", - test_input - ); - assert_eq!( - expected_opener, &block.opener, - "test_input: {:?}", - test_input - ); + assert_eq!(1, block.lines.len(), "test_input: {test_input:?}"); + assert_eq!(expected_line, &block.lines[0], "test_input: {test_input:?}"); + assert_eq!(expected_indent, block.indent, "test_input: {test_input:?}"); + assert_eq!(expected_opener, &block.opener, "test_input: {test_input:?}"); assert_eq!( expected_line_start, &block.line_start, - "test_input: {:?}", - test_input + "test_input: {test_input:?}" ); } @@ -2145,8 +2131,7 @@ fn main() { let maybe_block = ItemizedBlock::new(line); assert!( maybe_block.is_none(), - "The following line shouldn't be classified as a list item: {}", - line + "The following line shouldn't be classified as a list item: {line}" ); } } diff --git a/src/config/config_type.rs b/src/config/config_type.rs index c836b4bbb78..feb452d7235 100644 --- a/src/config/config_type.rs +++ b/src/config/config_type.rs @@ -500,18 +500,16 @@ where // Stable with an unstable option (false, false, _) => { eprintln!( - "Warning: can't set `{} = {:?}`, unstable features are only \ - available in nightly channel.", - option_name, option_value + "Warning: can't set `{option_name} = {option_value:?}`, unstable features are only \ + available in nightly channel." ); false } // Stable with a stable option, but an unstable variant (false, true, false) => { eprintln!( - "Warning: can't set `{} = {:?}`, unstable variants are only \ - available in nightly channel.", - option_name, option_value + "Warning: can't set `{option_name} = {option_value:?}`, unstable variants are only \ + available in nightly channel." ); false } diff --git a/src/config/file_lines.rs b/src/config/file_lines.rs index e4e51a3f3b4..e33fe9bb283 100644 --- a/src/config/file_lines.rs +++ b/src/config/file_lines.rs @@ -162,7 +162,7 @@ impl fmt::Display for FileLines { None => write!(f, "None")?, Some(map) => { for (file_name, ranges) in map.iter() { - write!(f, "{}: ", file_name)?; + write!(f, "{file_name}: ")?; write!(f, "{}\n", ranges.iter().format(", "))?; } } diff --git a/src/config/macro_names.rs b/src/config/macro_names.rs index 61658f0a212..edfe925c2b3 100644 --- a/src/config/macro_names.rs +++ b/src/config/macro_names.rs @@ -123,6 +123,6 @@ mod test { #[test] fn macro_names_display() { let macro_names = MacroSelectors::from_str(r#"["foo", "*", "bar"]"#).unwrap(); - assert_eq!(format!("{}", macro_names), "foo, *, bar"); + assert_eq!(format!("{macro_names}"), "foo, *, bar"); } } diff --git a/src/config/mod.rs b/src/config/mod.rs index 6f41b299e87..7538b26522d 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -216,8 +216,8 @@ impl Config { let required_version = self.required_version(); if version != required_version { println!( - "Error: rustfmt version ({}) doesn't match the required version ({})", - version, required_version, + "Error: rustfmt version ({version}) doesn't match the required version \ +({required_version})" ); return false; } @@ -310,20 +310,20 @@ impl Config { .ok_or_else(|| String::from("Parsed config was not table"))?; for key in table.keys() { if !Config::is_valid_name(key) { - let msg = &format!("Warning: Unknown configuration option `{}`\n", key); + let msg = &format!("Warning: Unknown configuration option `{key}`\n"); err.push_str(msg) } } match parsed.try_into() { Ok(parsed_config) => { if !err.is_empty() { - eprint!("{}", err); + eprint!("{err}"); } Ok(Config::default().fill_from_parsed_config(parsed_config, dir)) } Err(e) => { err.push_str("Error: Decoding config file failed:\n"); - err.push_str(format!("{}\n", e).as_str()); + err.push_str(format!("{e}\n").as_str()); err.push_str("Please check your config file."); Err(err) } @@ -563,10 +563,7 @@ mod test { let toml = used_options.to_toml().unwrap(); assert_eq!( toml, - format!( - "merge_derives = {}\nskip_children = {}\n", - merge_derives, skip_children, - ) + format!("merge_derives = {merge_derives}\nskip_children = {skip_children}\n",) ); } diff --git a/src/config/options.rs b/src/config/options.rs index 3aa1a4de99d..e37f4027e4a 100644 --- a/src/config/options.rs +++ b/src/config/options.rs @@ -243,7 +243,7 @@ pub struct WidthHeuristics { impl fmt::Display for WidthHeuristics { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{:?}", self) + write!(f, "{self:?}") } } diff --git a/src/emitter.rs b/src/emitter.rs index dc2c99a301e..9c335314d75 100644 --- a/src/emitter.rs +++ b/src/emitter.rs @@ -47,6 +47,6 @@ pub(crate) trait Emitter { fn ensure_real_path(filename: &FileName) -> &Path { match *filename { FileName::Real(ref path) => path, - _ => panic!("cannot format `{}` and emit to files", filename), + _ => panic!("cannot format `{filename}` and emit to files"), } } diff --git a/src/emitter/checkstyle.rs b/src/emitter/checkstyle.rs index 545b259979d..56d6a0ed681 100644 --- a/src/emitter/checkstyle.rs +++ b/src/emitter/checkstyle.rs @@ -43,7 +43,7 @@ pub(crate) fn output_checkstyle_file( where T: Write, { - write!(writer, r#""#, filename)?; + write!(writer, r#""#)?; for mismatch in diff { let begin_line = mismatch.line_number; let mut current_line; @@ -82,7 +82,7 @@ mod tests { ); assert_eq!( &writer[..], - format!(r#""#, file_name).as_bytes() + format!(r#""#).as_bytes() ); } diff --git a/src/emitter/checkstyle/xml.rs b/src/emitter/checkstyle/xml.rs index f251aabe878..d1d9af70857 100644 --- a/src/emitter/checkstyle/xml.rs +++ b/src/emitter/checkstyle/xml.rs @@ -13,7 +13,7 @@ impl<'a> Display for XmlEscaped<'a> { '"' => write!(formatter, """), '\'' => write!(formatter, "'"), '&' => write!(formatter, "&"), - _ => write!(formatter, "{}", char), + _ => write!(formatter, "{char}"), }?; } diff --git a/src/emitter/diff.rs b/src/emitter/diff.rs index 5e1f1344656..764cd136e01 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, "{}", filename)?; + writeln!(output, "{filename}")?; } else { print_diff( mismatch, @@ -40,7 +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. - writeln!(output, "Incorrect newline style in {}", filename)?; + writeln!(output, "Incorrect newline style in {filename}")?; return Ok(EmitterResult { has_diff: true }); } @@ -110,7 +110,7 @@ mod tests { assert_eq!( String::from_utf8(writer).unwrap(), - format!("{}\n{}\n", bin_file, lib_file), + format!("{bin_file}\n{lib_file}\n"), ) } diff --git a/src/emitter/json.rs b/src/emitter/json.rs index c7f68d4675a..5594196bed9 100644 --- a/src/emitter/json.rs +++ b/src/emitter/json.rs @@ -96,7 +96,7 @@ impl JsonEmitter { }); } self.mismatched_files.push(MismatchedFile { - name: format!("{}", filename), + name: format!("{filename}"), mismatches, }); Ok(()) @@ -281,7 +281,7 @@ mod tests { }]) .unwrap(); assert_eq!(result.has_diff, true); - assert_eq!(&writer[..], format!("{}\n", exp_json).as_bytes()); + assert_eq!(&writer[..], format!("{exp_json}\n").as_bytes()); } #[test] @@ -341,6 +341,6 @@ mod tests { }; let exp_json = to_json_string(&vec![exp_bin, exp_lib]).unwrap(); - assert_eq!(&writer[..], format!("{}\n", exp_json).as_bytes()); + assert_eq!(&writer[..], format!("{exp_json}\n").as_bytes()); } } diff --git a/src/emitter/stdout.rs b/src/emitter/stdout.rs index 9fddd515e49..0bbc7332dfe 100644 --- a/src/emitter/stdout.rs +++ b/src/emitter/stdout.rs @@ -24,9 +24,9 @@ impl Emitter for StdoutEmitter { }: FormattedFile<'_>, ) -> Result { if self.verbosity != Verbosity::Quiet { - writeln!(output, "{}:\n", filename)?; + writeln!(output, "{filename}:\n")?; } - write!(output, "{}", formatted_text)?; + write!(output, "{formatted_text}")?; Ok(EmitterResult::default()) } } diff --git a/src/expr.rs b/src/expr.rs index 9a605d6427e..450f1476db0 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -187,7 +187,7 @@ pub(crate) fn format_expr( Some(label) => format!(" {}", label.ident), None => String::new(), }; - Some(format!("continue{}", id_str)) + Some(format!("continue{id_str}")) } ast::ExprKind::Break(ref opt_label, ref opt_expr) => { let id_str = match *opt_label { @@ -196,9 +196,9 @@ pub(crate) fn format_expr( }; if let Some(ref expr) = *opt_expr { - rewrite_unary_prefix(context, &format!("break{} ", id_str), &**expr, shape) + rewrite_unary_prefix(context, &format!("break{id_str} "), &**expr, shape) } else { - Some(format!("break{}", id_str)) + Some(format!("break{id_str}")) } } ast::ExprKind::Yield(ref opt_expr) => { @@ -309,7 +309,7 @@ pub(crate) fn format_expr( match (lhs.as_ref().map(|x| &**x), rhs.as_ref().map(|x| &**x)) { (Some(lhs), Some(rhs)) => { let sp_delim = if context.config.spaces_around_ranges() { - format!(" {} ", delim) + format!(" {delim} ") } else { default_sp_delim(Some(lhs), Some(rhs)) }; @@ -324,7 +324,7 @@ pub(crate) fn format_expr( } (None, Some(rhs)) => { let sp_delim = if context.config.spaces_around_ranges() { - format!("{} ", delim) + format!("{delim} ") } else { default_sp_delim(None, Some(rhs)) }; @@ -332,7 +332,7 @@ pub(crate) fn format_expr( } (Some(lhs), None) => { let sp_delim = if context.config.spaces_around_ranges() { - format!(" {}", delim) + format!(" {delim}") } else { default_sp_delim(Some(lhs), None) }; @@ -375,7 +375,7 @@ pub(crate) fn format_expr( }; if let rw @ Some(_) = rewrite_single_line_block( context, - format!("{}{}", "async ", mover).as_str(), + format!("async {mover}").as_str(), block, Some(&expr.attrs), None, @@ -386,9 +386,7 @@ pub(crate) fn format_expr( // 6 = `async ` let budget = shape.width.saturating_sub(6); Some(format!( - "{}{}{}", - "async ", - mover, + "async {mover}{}", rewrite_block( block, Some(&expr.attrs), @@ -460,7 +458,7 @@ fn rewrite_empty_block( } if !block_contains_comment(context, block) && shape.width >= 2 { - return Some(format!("{}{}{{}}", prefix, label_str)); + return Some(format!("{prefix}{label_str}{{}}")); } // If a block contains only a single-line comment, then leave it on one line. @@ -473,7 +471,7 @@ fn rewrite_empty_block( && !comment_str.starts_with("//") && comment_str.len() + 4 <= shape.width { - return Some(format!("{}{}{{ {} }}", prefix, label_str, comment_str)); + return Some(format!("{prefix}{label_str}{{ {comment_str} }}")); } } @@ -520,7 +518,7 @@ fn rewrite_single_line_block( let expr_shape = shape.offset_left(last_line_width(prefix))?; let expr_str = block_expr.rewrite(context, expr_shape)?; let label_str = rewrite_label(label); - let result = format!("{}{}{{ {} }}", prefix, label_str, expr_str); + let result = format!("{prefix}{label_str}{{ {expr_str} }}"); if result.len() <= shape.width && !result.contains('\n') { return Some(result); } @@ -1100,7 +1098,7 @@ impl<'a> Rewrite for ControlFlow<'a> { result? }; - let mut result = format!("{}{}", cond_str, block_str); + let mut result = format!("{cond_str}{block_str}"); if let Some(else_block) = self.else_block { let shape = Shape::indented(shape.indent, context.config); @@ -1160,8 +1158,7 @@ fn rewrite_label(opt_label: Option) -> Cow<'static, str> { fn extract_comment(span: Span, context: &RewriteContext<'_>, shape: Shape) -> Option { match rewrite_missing_comment(span, shape, context) { Some(ref comment) if !comment.is_empty() => Some(format!( - "{indent}{}{indent}", - comment, + "{indent}{comment}{indent}", indent = shape.indent.to_string_with_newline(context.config) )), _ => None, @@ -1478,7 +1475,7 @@ pub(crate) fn rewrite_paren( let subexpr_str = subexpr.rewrite(context, sub_shape)?; let fits_single_line = !pre_comment.contains("//") && !post_comment.contains("//"); if fits_single_line { - Some(format!("({}{}{})", pre_comment, subexpr_str, post_comment)) + Some(format!("({pre_comment}{subexpr_str}{post_comment})")) } else { rewrite_paren_in_multi_line(context, subexpr, shape, pre_span, post_span) } @@ -1542,7 +1539,7 @@ fn rewrite_index( // Return if index fits in a single line. match orig_index_rw { Some(ref index_str) if !index_str.contains('\n') => { - return Some(format!("{}[{}]", expr_str, index_str)); + return Some(format!("{expr_str}[{index_str}]")); } _ => (), } @@ -1565,7 +1562,7 @@ fn rewrite_index( indent.to_string_with_newline(context.config), new_index_str, )), - (Some(ref index_str), _) => Some(format!("{}[{}]", expr_str, index_str)), + (Some(ref index_str), _) => Some(format!("{expr_str}[{index_str}]")), _ => None, } } @@ -1597,9 +1594,9 @@ fn rewrite_struct_lit<'a>( let path_str = rewrite_path(context, PathContext::Expr, qself, path, path_shape)?; let has_base_or_rest = match struct_rest { - ast::StructRest::None if fields.is_empty() => return Some(format!("{} {{}}", path_str)), + ast::StructRest::None if fields.is_empty() => return Some(format!("{path_str} {{}}")), ast::StructRest::Rest(_) if fields.is_empty() => { - return Some(format!("{} {{ .. }}", path_str)); + return Some(format!("{path_str} {{ .. }}")); } ast::StructRest::Rest(_) | ast::StructRest::Base(_) => true, _ => false, @@ -1690,7 +1687,7 @@ fn rewrite_struct_lit<'a>( let fields_str = wrap_struct_field(context, attrs, &fields_str, shape, v_shape, one_line_width)?; - Some(format!("{} {{{}}}", path_str, fields_str)) + Some(format!("{path_str} {{{fields_str}}}")) // FIXME if context.config.indent_style() == Visual, but we run out // of space, we should fall back to BlockIndent. @@ -1720,7 +1717,7 @@ pub(crate) fn wrap_struct_field( )) } else { // One liner or visual indent. - Some(format!(" {} ", fields_str)) + Some(format!(" {fields_str} ")) } } else { Some(format!( @@ -1769,7 +1766,7 @@ pub(crate) fn rewrite_field( { Some(attrs_str + name) } - Some(e) => Some(format!("{}{}{}{}", attrs_str, name, separator, e)), + Some(e) => Some(format!("{attrs_str}{name}{separator}{e}")), None => { let expr_offset = shape.indent.block_indent(context.config); let expr = field @@ -1834,7 +1831,7 @@ fn rewrite_tuple_in_visual_indent_style<'a, T: 'a + IntoOverflowableItem<'a>>( .ends_with_newline(false); let list_str = write_list(&item_vec, &fmt)?; - Some(format!("({})", list_str)) + Some(format!("({list_str})")) } pub(crate) fn rewrite_tuple<'a, T: 'a + IntoOverflowableItem<'a>>( @@ -2076,7 +2073,7 @@ fn choose_rhs( Some(ref new_str) if !new_str.contains('\n') && unicode_str_width(new_str) <= shape.width => { - Some(format!(" {}", new_str)) + Some(format!(" {new_str}")) } _ => { // Expression did not fit on the same line as the identifier. @@ -2093,21 +2090,21 @@ fn choose_rhs( (Some(ref orig_rhs), Some(ref new_rhs)) if !filtered_str_fits(&new_rhs, context.config.max_width(), new_shape) => { - Some(format!("{}{}", before_space_str, orig_rhs)) + Some(format!("{before_space_str}{orig_rhs}")) } (Some(ref orig_rhs), Some(ref new_rhs)) if prefer_next_line(orig_rhs, new_rhs, rhs_tactics) => { - Some(format!("{}{}", new_indent_str, new_rhs)) + Some(format!("{new_indent_str}{new_rhs}")) } - (None, Some(ref new_rhs)) => Some(format!("{}{}", new_indent_str, new_rhs)), + (None, Some(ref new_rhs)) => Some(format!("{new_indent_str}{new_rhs}")), (None, None) if rhs_tactics == RhsTactics::AllowOverflow => { let shape = shape.infinite_width(); expr.rewrite(context, shape) .map(|s| format!("{}{}", before_space_str, s)) } (None, None) => None, - (Some(orig_rhs), _) => Some(format!("{}{}", before_space_str, orig_rhs)), + (Some(orig_rhs), _) => Some(format!("{before_space_str}{orig_rhs}")), } } } diff --git a/src/format-diff/main.rs b/src/format-diff/main.rs index db4a21ba09e..61e2cb711a5 100644 --- a/src/format-diff/main.rs +++ b/src/format-diff/main.rs @@ -69,7 +69,7 @@ fn main() { .init(); let opts = Opts::parse(); if let Err(e) = run(opts) { - println!("{}", e); + println!("{e}"); Opts::command() .print_help() .expect("cannot write to stdout"); @@ -113,7 +113,7 @@ fn run_rustfmt(files: &HashSet, ranges: &[Range]) -> Result<(), FormatDi if !exit_status.success() { return Err(FormatDiffError::IoError(io::Error::new( io::ErrorKind::Other, - format!("rustfmt failed with {}", exit_status), + format!("rustfmt failed with {exit_status}"), ))); } Ok(()) @@ -129,12 +129,12 @@ fn scan_diff( where R: io::Read, { - let diff_pattern = format!(r"^\+\+\+\s(?:.*?/){{{}}}(\S*)", skip_prefix); + let diff_pattern = format!(r"^\+\+\+\s(?:.*?/){{{skip_prefix}}}(\S*)"); let diff_pattern = Regex::new(&diff_pattern).unwrap(); let lines_pattern = Regex::new(r"^@@.*\+(\d+)(,(\d+))?").unwrap(); - let file_filter = Regex::new(&format!("^{}$", file_filter))?; + let file_filter = Regex::new(&format!("^{file_filter}$"))?; let mut current_file = None; diff --git a/src/formatting.rs b/src/formatting.rs index 1f4ad6960e2..cd57a025b67 100644 --- a/src/formatting.rs +++ b/src/formatting.rs @@ -296,7 +296,7 @@ impl<'b, T: Write + 'b> FormatHandler for Session<'b, T> { Ok(ref result) if result.has_diff => report.add_diff(), Err(e) => { // Create a new error with path_str to help users see which files failed - let err_msg = format!("{}: {}", path, e); + let err_msg = format!("{path}: {e}"); return Err(io::Error::new(e.kind(), err_msg).into()); } _ => {} diff --git a/src/git-rustfmt/main.rs b/src/git-rustfmt/main.rs index efeda53e7ec..3059d917c6b 100644 --- a/src/git-rustfmt/main.rs +++ b/src/git-rustfmt/main.rs @@ -43,7 +43,7 @@ fn git_diff(commits: &str) -> String { let mut cmd = Command::new("git"); cmd.arg("diff"); if commits != "0" { - cmd.arg(format!("HEAD~{}", commits)); + cmd.arg(format!("HEAD~{commits}")); } let output = cmd.output().expect("Couldn't execute `git diff`"); String::from_utf8_lossy(&output.stdout).into_owned() @@ -108,7 +108,7 @@ fn check_uncommitted() { if !uncommitted.is_empty() { println!("Found untracked changes:"); for f in &uncommitted { - println!(" {}", f); + println!(" {f}"); } println!("Commit your work, or run with `-u`."); println!("Exiting."); diff --git a/src/imports.rs b/src/imports.rs index 339e5cef5af..6f0050647dc 100644 --- a/src/imports.rs +++ b/src/imports.rs @@ -191,7 +191,7 @@ impl UseSegment { "crate" => UseSegmentKind::Crate(None), _ => { let mod_sep = if modsep { "::" } else { "" }; - UseSegmentKind::Ident(format!("{}{}", mod_sep, name), None) + UseSegmentKind::Ident(format!("{mod_sep}{name}"), None) } }; @@ -295,8 +295,8 @@ impl fmt::Display for UseSegmentKind { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { UseSegmentKind::Glob => write!(f, "*"), - UseSegmentKind::Ident(ref s, Some(ref alias)) => write!(f, "{} as {}", s, alias), - UseSegmentKind::Ident(ref s, None) => write!(f, "{}", s), + UseSegmentKind::Ident(ref s, Some(ref alias)) => write!(f, "{s} as {alias}"), + UseSegmentKind::Ident(ref s, None) => write!(f, "{s}"), UseSegmentKind::Slf(..) => write!(f, "self"), UseSegmentKind::Super(..) => write!(f, "super"), UseSegmentKind::Crate(..) => write!(f, "crate"), @@ -306,7 +306,7 @@ impl fmt::Display for UseSegmentKind { if i != 0 { write!(f, ", ")?; } - write!(f, "{}", item)?; + write!(f, "{item}")?; } write!(f, "}}") } @@ -319,7 +319,7 @@ impl fmt::Display for UseTree { if i != 0 { write!(f, "::")?; } - write!(f, "{}", segment)?; + write!(f, "{segment}")?; } Ok(()) } @@ -1042,7 +1042,7 @@ fn rewrite_nested_use_tree( shape.indent.to_string(context.config) ) } else { - format!("{{{}}}", list_str) + format!("{{{list_str}}}") }; Some(result) @@ -1052,14 +1052,14 @@ impl Rewrite for UseSegment { fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option { Some(match self.kind { UseSegmentKind::Ident(ref ident, Some(ref rename)) => { - format!("{} as {}", ident, rename) + format!("{ident} as {rename}") } UseSegmentKind::Ident(ref ident, None) => ident.clone(), - UseSegmentKind::Slf(Some(ref rename)) => format!("self as {}", rename), + UseSegmentKind::Slf(Some(ref rename)) => format!("self as {rename}"), UseSegmentKind::Slf(None) => "self".to_owned(), - UseSegmentKind::Super(Some(ref rename)) => format!("super as {}", rename), + UseSegmentKind::Super(Some(ref rename)) => format!("super as {rename}"), UseSegmentKind::Super(None) => "super".to_owned(), - UseSegmentKind::Crate(Some(ref rename)) => format!("crate as {}", rename), + UseSegmentKind::Crate(Some(ref rename)) => format!("crate as {rename}"), UseSegmentKind::Crate(None) => "crate".to_owned(), UseSegmentKind::Glob => "*".to_owned(), UseSegmentKind::List(ref use_tree_list) => rewrite_nested_use_tree( diff --git a/src/items.rs b/src/items.rs index fd4e08ed403..a72646ef897 100644 --- a/src/items.rs +++ b/src/items.rs @@ -470,7 +470,7 @@ impl<'a> FmtVisitor<'a> { && self.block_indent.width() + fn_str.len() + 3 <= self.config.max_width() && !last_line_contains_single_line_comment(fn_str) { - return Some(format!("{} {{}}", fn_str)); + return Some(format!("{fn_str} {{}}")); } if !self.config.fn_single_line() || !is_simple_block_stmt(&context, block, None) { @@ -482,7 +482,7 @@ impl<'a> FmtVisitor<'a> { let width = self.block_indent.width() + fn_str.len() + res.len() + 5; if !res.contains('\n') && width <= self.config.max_width() { - Some(format!("{} {{ {} }}", fn_str, res)) + Some(format!("{fn_str} {{ {res} }}")) } else { None } @@ -664,7 +664,7 @@ impl<'a> FmtVisitor<'a> { }; let variant_body = if let Some(ref expr) = field.disr_expr { - let lhs = format!("{:1$} =", variant_body, pad_discrim_ident_to); + let lhs = format!("{variant_body:pad_discrim_ident_to$} ="); let ex = &*expr.value; rewrite_assign_rhs_with( &context, @@ -827,7 +827,7 @@ pub(crate) fn format_impl( if generics.where_clause.predicates.len() == 1 { result.push(','); } - result.push_str(&format!("{}{{{}}}", sep, sep)); + result.push_str(&format!("{sep}{{{sep}}}")); } else { result.push_str(" {}"); } @@ -1018,7 +1018,7 @@ fn rewrite_trait_ref( let shape = Shape::indented(offset + used_space, context.config); if let Some(trait_ref_str) = trait_ref.rewrite(context, shape) { if !trait_ref_str.contains('\n') { - return Some(format!(" {}{}", polarity_str, trait_ref_str)); + return Some(format!(" {polarity_str}{trait_ref_str}")); } } // We could not make enough space for trait_ref, so put it on new line. @@ -1320,7 +1320,7 @@ impl<'a> Rewrite for TraitAliasBounds<'a> { shape.indent.to_string_with_newline(context.config) }; - Some(format!("{}{}{}", generic_bounds_str, space, where_str)) + Some(format!("{generic_bounds_str}{space}{where_str}")) } } @@ -1337,7 +1337,7 @@ pub(crate) fn format_trait_alias( let g_shape = shape.offset_left(6)?.sub_width(2)?; let generics_str = rewrite_generics(context, alias, generics, g_shape)?; let vis_str = format_visibility(context, vis); - let lhs = format!("{}trait {} =", vis_str, generics_str); + let lhs = format!("{vis_str}trait {generics_str} ="); // 1 = ";" let trait_alias_bounds = TraitAliasBounds { generic_bounds, @@ -1374,7 +1374,7 @@ fn format_unit_struct( } else { String::new() }; - Some(format!("{}{};", header_str, generics_str)) + Some(format!("{header_str}{generics_str};")) } pub(crate) fn format_struct_struct( @@ -1464,7 +1464,7 @@ pub(crate) fn format_struct_struct( && items_str.len() <= one_line_budget && !last_line_contains_single_line_comment(&items_str) { - Some(format!("{} {} }}", result, items_str)) + Some(format!("{result} {items_str} }}")) } else { Some(format!( "{}\n{}{}\n{}}}", @@ -1694,7 +1694,7 @@ pub(crate) fn rewrite_type_alias<'a, 'b>( rewrite_ty(rw_info, Some(bounds), ty_opt, vis) }?; match defaultness { - ast::Defaultness::Default(..) => Some(format!("default {}", result)), + ast::Defaultness::Default(..) => Some(format!("default {result}")), _ => Some(result), } } @@ -1801,14 +1801,14 @@ fn rewrite_ty( true, )? } - _ => format!("{}=", result), + _ => format!("{result}="), }; // 1 = `;` let shape = Shape::indented(indent, context.config).sub_width(1)?; rewrite_assign_rhs(context, lhs, &*ty, &RhsAssignKind::Ty, shape).map(|s| s + ";") } else { - Some(format!("{};", result)) + Some(format!("{result};")) } } @@ -2017,7 +2017,7 @@ fn rewrite_static( let expr_lo = expr.span.lo(); let comments_span = mk_sp(comments_lo, expr_lo); - let lhs = format!("{}{} =", prefix, ty_str); + let lhs = format!("{prefix}{ty_str} ="); // 1 = ; let remaining_width = context.budget(offset.block_indent + 1); @@ -2034,7 +2034,7 @@ fn rewrite_static( .and_then(|res| recover_comment_removed(res, static_parts.span, context)) .map(|s| if s.ends_with(';') { s } else { s + ";" }) } else { - Some(format!("{}{};", prefix, ty_str)) + Some(format!("{prefix}{ty_str};")) } } @@ -2227,7 +2227,7 @@ fn rewrite_explicit_self( Some(combine_strs_with_missing_comments( context, param_attrs, - &format!("&{} {}self", lifetime_str, mut_str), + &format!("&{lifetime_str} {mut_str}self"), span, shape, !has_multiple_attr_lines, @@ -2236,7 +2236,7 @@ fn rewrite_explicit_self( None => Some(combine_strs_with_missing_comments( context, param_attrs, - &format!("&{}self", mut_str), + &format!("&{mut_str}self"), span, shape, !has_multiple_attr_lines, @@ -2906,7 +2906,7 @@ fn rewrite_where_clause_rfc_style( clause_shape.indent.to_string_with_newline(context.config) }; - Some(format!("{}{}{}", where_keyword, clause_sep, preds_str)) + Some(format!("{where_keyword}{clause_sep}{preds_str}")) } /// Rewrite `where` and comment around it. @@ -2946,8 +2946,8 @@ fn rewrite_where_keyword( let newline_before_where = comment_separator(&comment_before, shape); let newline_after_where = comment_separator(&comment_after, clause_shape); let result = format!( - "{}{}{}where{}{}", - starting_newline, comment_before, newline_before_where, newline_after_where, comment_after + "{starting_newline}{comment_before}{newline_before_where}where\ +{newline_after_where}{comment_after}" ); let allow_single_line = where_clause_option.allow_single_line && comment_before.is_empty() @@ -3102,7 +3102,7 @@ fn rewrite_where_clause( preds_str )) } else { - Some(format!(" where {}", preds_str)) + Some(format!(" where {preds_str}")) } } diff --git a/src/macros.rs b/src/macros.rs index 88d26358b87..b6a49536d17 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -103,7 +103,7 @@ fn rewrite_macro_name( format!("{}!", pprust::path_to_string(path)) }; match extra_ident { - Some(ident) if ident.name != kw::Empty => format!("{} {}", name, ident), + Some(ident) if ident.name != kw::Empty => format!("{name} {ident}"), _ => name, } } @@ -214,14 +214,14 @@ fn rewrite_macro_inner( if ts.is_empty() && !has_comment { return match style { Delimiter::Parenthesis if position == MacroPosition::Item => { - Some(format!("{}();", macro_name)) + Some(format!("{macro_name}();")) } Delimiter::Bracket if position == MacroPosition::Item => { - Some(format!("{}[];", macro_name)) + Some(format!("{macro_name}[];")) } - Delimiter::Parenthesis => Some(format!("{}()", macro_name)), - Delimiter::Bracket => Some(format!("{}[]", macro_name)), - Delimiter::Brace => Some(format!("{} {{}}", macro_name)), + Delimiter::Parenthesis => Some(format!("{macro_name}()")), + Delimiter::Bracket => Some(format!("{macro_name}[]")), + Delimiter::Brace => Some(format!("{macro_name} {{}}")), _ => unreachable!(), }; } @@ -321,7 +321,7 @@ fn rewrite_macro_inner( _ => "", }; - Some(format!("{}{}", rewrite, comma)) + Some(format!("{rewrite}{comma}")) } } Delimiter::Brace => { @@ -330,8 +330,8 @@ fn rewrite_macro_inner( // anything in between the braces (for now). let snippet = context.snippet(mac.span()).trim_start_matches(|c| c != '{'); match trim_left_preserve_layout(snippet, shape.indent, context.config) { - Some(macro_body) => Some(format!("{} {}", macro_name, macro_body)), - None => Some(format!("{} {}", macro_name, snippet)), + Some(macro_body) => Some(format!("{macro_name} {macro_body}")), + None => Some(format!("{macro_name} {snippet}")), } } _ => unreachable!(), @@ -362,7 +362,7 @@ fn handle_vec_semi( && lhs.len() + rhs.len() + total_overhead <= shape.width { // macro_name(lhs; rhs) or macro_name[lhs; rhs] - Some(format!("{}{}{}; {}{}", macro_name, left, lhs, rhs, right)) + Some(format!("{macro_name}{left}{lhs}; {rhs}{right}")) } else { // macro_name(\nlhs;\nrhs\n) or macro_name[\nlhs;\nrhs\n] Some(format!( @@ -596,8 +596,8 @@ fn delim_token_to_str( .block_indent(context.config) .to_string_with_newline(context.config); ( - format!("{}{}", lhs, nested_indent_str), - format!("{}{}", indent_str, rhs), + format!("{lhs}{nested_indent_str}"), + format!("{indent_str}{rhs}"), ) } else { (lhs.to_owned(), rhs.to_owned()) @@ -654,7 +654,7 @@ impl MacroArgKind { }; match *self { - MacroArgKind::MetaVariable(ty, ref name) => Some(format!("${}:{}", name, ty)), + MacroArgKind::MetaVariable(ty, ref name) => Some(format!("${name}:{ty}")), MacroArgKind::Repeat(delim_tok, ref args, ref another, ref tok) => { let (lhs, inner, rhs) = rewrite_delimited_inner(delim_tok, args)?; let another = another @@ -663,14 +663,14 @@ impl MacroArgKind { .unwrap_or_else(|| "".to_owned()); let repeat_tok = pprust::token_to_string(tok); - Some(format!("${}{}{}{}{}", lhs, inner, rhs, another, repeat_tok)) + Some(format!("${lhs}{inner}{rhs}{another}{repeat_tok}")) } MacroArgKind::Delimited(delim_tok, ref args) => { rewrite_delimited_inner(delim_tok, args) .map(|(lhs, inner, rhs)| format!("{}{}{}", lhs, inner, rhs)) } - MacroArgKind::Separator(ref sep, ref prefix) => Some(format!("{}{} ", prefix, sep)), - MacroArgKind::Other(ref inner, ref prefix) => Some(format!("{}{}", prefix, inner)), + MacroArgKind::Separator(ref sep, ref prefix) => Some(format!("{prefix}{sep} ")), + MacroArgKind::Other(ref inner, ref prefix) => Some(format!("{prefix}{inner}")), } } } diff --git a/src/matches.rs b/src/matches.rs index a7677c3a35c..27a9c1d3130 100644 --- a/src/matches.rs +++ b/src/matches.rs @@ -124,7 +124,7 @@ pub(crate) fn rewrite_match( if arms.is_empty() { let snippet = context.snippet(mk_sp(open_brace_pos, span.hi() - BytePos(1))); if snippet.trim().is_empty() { - Some(format!("match {} {{}}", cond_str)) + Some(format!("match {cond_str} {{}}")) } else { // Empty match with comments or inner attributes? We are not going to bother, sorry ;) Some(context.snippet(span).to_owned()) @@ -274,7 +274,7 @@ fn rewrite_match_arm( let lhs_str = combine_strs_with_missing_comments( context, &attrs_str, - &format!("{}{}{}", pipe_str, pats_str, guard_str), + &format!("{pipe_str}{pats_str}{guard_str}"), missing_span, shape, false, @@ -543,7 +543,7 @@ fn rewrite_guard( if let Some(cond_shape) = cond_shape { if let Some(cond_str) = guard.rewrite(context, cond_shape) { if !cond_str.contains('\n') || pattern_width <= context.config.tab_spaces() { - return Some(format!(" if {}", cond_str)); + return Some(format!(" if {cond_str}")); } } } diff --git a/src/pairs.rs b/src/pairs.rs index d135da7e359..96f023b3b0e 100644 --- a/src/pairs.rs +++ b/src/pairs.rs @@ -234,8 +234,8 @@ where let rhs_result = rhs.rewrite(context, rhs_shape)?; let indent_str = rhs_shape.indent.to_string_with_newline(context.config); let infix_with_sep = match separator_place { - SeparatorPlace::Back => format!("{}{}", infix, indent_str), - SeparatorPlace::Front => format!("{}{}", indent_str, infix), + SeparatorPlace::Back => format!("{infix}{indent_str}"), + SeparatorPlace::Front => format!("{indent_str}{infix}"), }; Some(format!( "{}{}{}{}", diff --git a/src/parse/session.rs b/src/parse/session.rs index 81b5015dde3..2edb830a573 100644 --- a/src/parse/session.rs +++ b/src/parse/session.rs @@ -331,8 +331,7 @@ impl LineRangeUtils for ParseSess { debug_assert_eq!( lo.sf.name, hi.sf.name, - "span crossed file boundary: lo: {:?}, hi: {:?}", - lo, hi + "span crossed file boundary: lo: {lo:?}, hi: {hi:?}" ); // in case the span starts with a newline, the line range is off by 1 without the diff --git a/src/patterns.rs b/src/patterns.rs index 3f335172590..33f3b4b8a21 100644 --- a/src/patterns.rs +++ b/src/patterns.rs @@ -208,7 +208,7 @@ impl Rewrite for Pat { None => "", Some(_) => " ", }; - format!("{}{}{}", lhs_spacing, infix, rhs_spacing) + format!("{lhs_spacing}{infix}{rhs_spacing}") } else { infix.to_owned() }; @@ -283,7 +283,7 @@ fn rewrite_struct_pat( let path_str = rewrite_path(context, PathContext::Expr, qself, path, path_shape)?; if fields.is_empty() && !ellipsis { - return Some(format!("{} {{}}", path_str)); + return Some(format!("{path_str} {{}}")); } let (ellipsis_str, terminator) = if ellipsis { (", ..", "..") } else { ("", "}") }; @@ -344,7 +344,7 @@ fn rewrite_struct_pat( // ast::Pat doesn't have attrs so use &[] let fields_str = wrap_struct_field(context, &[], &fields_str, shape, v_shape, one_line_width)?; - Some(format!("{} {{{}}}", path_str, fields_str)) + Some(format!("{path_str} {{{fields_str}}}")) } impl Rewrite for PatField { @@ -376,7 +376,7 @@ impl Rewrite for PatField { let id_str = rewrite_ident(context, self.ident); let one_line_width = id_str.len() + 2 + pat_str.len(); let pat_and_id_str = if one_line_width <= shape.width { - format!("{}: {}", id_str, pat_str) + format!("{id_str}: {pat_str}") } else { format!( "{}:\n{}{}", diff --git a/src/rustfmt_diff.rs b/src/rustfmt_diff.rs index 1724a0f87bf..c9883452185 100644 --- a/src/rustfmt_diff.rs +++ b/src/rustfmt_diff.rs @@ -95,7 +95,7 @@ impl fmt::Display for ModifiedLines { )?; for line in &chunk.lines { - writeln!(f, "{}", line)?; + writeln!(f, "{line}")?; } } @@ -166,12 +166,12 @@ impl OutputWriter { if let Some(color) = color { t.fg(color).unwrap(); } - writeln!(t, "{}", msg).unwrap(); + writeln!(t, "{msg}").unwrap(); if color.is_some() { t.reset().unwrap(); } } - None => println!("{}", msg), + None => println!("{msg}"), } } } @@ -265,16 +265,15 @@ where for line in mismatch.lines { match line { DiffLine::Context(ref str) => { - writer.writeln(&format!(" {}{}", str, line_terminator), None) + writer.writeln(&format!(" {str}{line_terminator}"), None) } DiffLine::Expected(ref str) => writer.writeln( - &format!("+{}{}", str, line_terminator), + &format!("+{str}{line_terminator}"), Some(term::color::GREEN), ), - DiffLine::Resulting(ref str) => writer.writeln( - &format!("-{}{}", str, line_terminator), - Some(term::color::RED), - ), + DiffLine::Resulting(ref str) => { + writer.writeln(&format!("-{str}{line_terminator}"), Some(term::color::RED)) + } } } } diff --git a/src/skip.rs b/src/skip.rs index 68f85b2ade4..d733f7068fd 100644 --- a/src/skip.rs +++ b/src/skip.rs @@ -105,7 +105,7 @@ pub(crate) fn is_skip_attr(segments: &[ast::PathSegment]) -> bool { fn get_skip_names(kind: &str, attrs: &[ast::Attribute]) -> Vec { let mut skip_names = vec![]; - let path = format!("{}::{}::{}", RUSTFMT, SKIP, kind); + let path = format!("{RUSTFMT}::{SKIP}::{kind}"); for attr in attrs { // rustc_ast::ast::Path is implemented partialEq // but it is designed for segments.len() == 1 diff --git a/src/source_file.rs b/src/source_file.rs index 56d4ab40038..958f9b0154f 100644 --- a/src/source_file.rs +++ b/src/source_file.rs @@ -62,7 +62,7 @@ where fn ensure_real_path(filename: &FileName) -> &Path { match *filename { FileName::Real(ref path) => path, - _ => panic!("cannot format `{}` and emit to files", filename), + _ => panic!("cannot format `{filename}` and emit to files"), } } diff --git a/src/test/configuration_snippet.rs b/src/test/configuration_snippet.rs index c70b3c5facd..80b61c88a00 100644 --- a/src/test/configuration_snippet.rs +++ b/src/test/configuration_snippet.rs @@ -233,13 +233,11 @@ impl ConfigCodeBlock { Some(ConfigurationSection::ConfigName(name)) => { assert!( Config::is_valid_name(&name), - "an unknown configuration option was found: {}", - name + "an unknown configuration option was found: {name}" ); assert!( hash_set.remove(&name), - "multiple configuration guides found for option {}", - name + "multiple configuration guides found for option {name}" ); code_block.set_config_name(Some(name)); } @@ -266,7 +264,7 @@ fn configuration_snippet_tests() { // Display results. println!("Ran {} configurations tests.", blocks.len()); - assert_eq!(failures, 0, "{} configurations tests failed", failures); + assert_eq!(failures, 0, "{failures} configurations tests failed"); } // Read Configurations.md and build a `Vec` of `ConfigCodeBlock` structs with one @@ -289,7 +287,7 @@ fn get_code_blocks() -> Vec { for name in hash_set { if !Config::is_hidden_option(&name) { - panic!("{} does not have a configuration guide", name); + panic!("{name} does not have a configuration guide"); } } diff --git a/src/test/mod.rs b/src/test/mod.rs index f88ab3f194b..c8137c1bd28 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -203,8 +203,8 @@ fn coverage_tests() { let files = get_test_files(Path::new("tests/coverage/source"), true); let (_reports, count, fails) = check_files(files, &None); - println!("Ran {} tests in coverage mode.", count); - assert_eq!(fails, 0, "{} tests failed", fails); + println!("Ran {count} tests in coverage mode."); + assert_eq!(fails, 0, "{fails} tests failed"); } #[test] @@ -396,8 +396,8 @@ fn self_tests() { let mut warnings = 0; // Display results. - println!("Ran {} self tests.", count); - assert_eq!(fails, 0, "{} self tests failed", fails); + println!("Ran {count} self tests."); + assert_eq!(fails, 0, "{fails} self tests failed"); for format_report in reports { println!( @@ -407,11 +407,7 @@ fn self_tests() { warnings += format_report.warning_count(); } - assert_eq!( - warnings, 0, - "Rustfmt's code generated {} warnings", - warnings - ); + assert_eq!(warnings, 0, "Rustfmt's code generated {warnings} warnings"); } #[test] @@ -606,7 +602,7 @@ fn stdin_handles_mod_inner_ignore_attr() { fn format_lines_errors_are_reported() { init_log(); let long_identifier = String::from_utf8(vec![b'a'; 239]).unwrap(); - let input = Input::Text(format!("fn {}() {{}}", long_identifier)); + let input = Input::Text(format!("fn {long_identifier}() {{}}")); let mut config = Config::default(); config.set().error_on_line_overflow(true); let mut session = Session::::new(config, None); @@ -618,7 +614,7 @@ fn format_lines_errors_are_reported() { fn format_lines_errors_are_reported_with_tabs() { init_log(); let long_identifier = String::from_utf8(vec![b'a'; 97]).unwrap(); - let input = Input::Text(format!("fn a() {{\n\t{}\n}}", long_identifier)); + let input = Input::Text(format!("fn a() {{\n\t{long_identifier}\n}}")); let mut config = Config::default(); config.set().error_on_line_overflow(true); config.set().hard_tabs(true); @@ -829,11 +825,11 @@ fn handle_result( for (file_name, fmt_text) in result { // If file is in tests/source, compare to file with same name in tests/target. let target = get_target(&file_name, target); - let open_error = format!("couldn't open target {:?}", target); + let open_error = format!("couldn't open target {target:?}"); let mut f = fs::File::open(&target).expect(&open_error); let mut text = String::new(); - let read_error = format!("failed reading target {:?}", target); + let read_error = format!("failed reading target {target:?}"); f.read_to_string(&mut text).expect(&read_error); // Ignore LF and CRLF difference for Windows. diff --git a/src/types.rs b/src/types.rs index aef85598f06..8be474d5bca 100644 --- a/src/types.rs +++ b/src/types.rs @@ -301,7 +301,7 @@ where let output = match *output { FnRetTy::Ty(ref ty) => { let type_str = ty.rewrite(context, ty_shape)?; - format!(" -> {}", type_str) + format!(" -> {type_str}") } FnRetTy::Default(..) => String::new(), }; @@ -373,7 +373,7 @@ where || !context.use_block_indent() || is_inputs_empty { - format!("({})", list_str) + format!("({list_str})") } else { format!( "({}{}{})", @@ -383,7 +383,7 @@ where ) }; if output.is_empty() || last_line_width(&args) + first_line_width(&output) <= shape.width { - Some(format!("{}{}", args, output)) + Some(format!("{args}{output}")) } else { Some(format!( "{}\n{}{}", @@ -429,9 +429,9 @@ impl Rewrite for ast::WherePredicate { let lhs = if let Some(binder_str) = rewrite_bound_params(context, shape, bound_generic_params) { - format!("for<{}> {}{}", binder_str, type_str, colon) + format!("for<{binder_str}> {type_str}{colon}") } else { - format!("{}{}", type_str, colon) + format!("{type_str}{colon}") }; rewrite_assign_rhs(context, lhs, bounds, &RhsAssignKind::Bounds, shape)? @@ -665,7 +665,7 @@ impl Rewrite for ast::PolyTraitRef { .trait_ref .rewrite(context, shape.offset_left(extra_offset)?)?; - Some(format!("for<{}> {}", lifetime_str, path_str)) + Some(format!("for<{lifetime_str}> {path_str}")) } else { self.trait_ref.rewrite(context, shape) } @@ -695,7 +695,7 @@ impl Rewrite for ast::Ty { res.push('+'); } } - Some(format!("{}{}", prefix, res)) + Some(format!("{prefix}{res}")) } ast::TyKind::Ptr(ref mt) => { let prefix = match mt.mutbl { @@ -791,7 +791,7 @@ impl Rewrite for ast::Ty { if let Some(sh) = shape.sub_width(2) { if let Some(ref s) = ty.rewrite(context, sh) { if !s.contains('\n') { - return Some(format!("({})", s)); + return Some(format!("({s})")); } } } diff --git a/src/utils.rs b/src/utils.rs index b8a44d4bade..d1cb197cb51 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -69,7 +69,7 @@ pub(crate) fn format_visibility( let path = segments_iter.collect::>().join("::"); let in_str = if is_keyword(&path) { "" } else { "in " }; - Cow::from(format!("pub({}{}) ", in_str, path)) + Cow::from(format!("pub({in_str}{path}) ")) } } } @@ -147,7 +147,7 @@ pub(crate) fn format_extern( } else if abi == "C" && !explicit_abi { Cow::from("extern ") } else { - Cow::from(format!(r#"extern "{}" "#, abi)) + Cow::from(format!(r#"extern "{abi}" "#)) } } diff --git a/tests/cargo-fmt/main.rs b/tests/cargo-fmt/main.rs index 701c36fadea..63573bf341b 100644 --- a/tests/cargo-fmt/main.rs +++ b/tests/cargo-fmt/main.rs @@ -26,7 +26,7 @@ fn cargo_fmt(args: &[&str]) -> (String, String) { String::from_utf8(output.stdout).expect("utf-8"), String::from_utf8(output.stderr).expect("utf-8"), ), - Err(e) => panic!("failed to run `{:?} {:?}`: {}", cmd, args, e), + Err(e) => panic!("failed to run `{cmd:?} {args:?}`: {e}"), } } diff --git a/tests/rustfmt/main.rs b/tests/rustfmt/main.rs index 4936a717463..7dcf7c8416e 100644 --- a/tests/rustfmt/main.rs +++ b/tests/rustfmt/main.rs @@ -27,7 +27,7 @@ fn rustfmt(args: &[&str]) -> (String, String) { String::from_utf8(output.stdout).expect("utf-8"), String::from_utf8(output.stderr).expect("utf-8"), ), - Err(e) => panic!("failed to run `{:?} {:?}`: {}", cmd, args, e), + Err(e) => panic!("failed to run `{cmd:?} {args:?}`: {e}"), } } @@ -71,9 +71,7 @@ fn print_config() { ]); assert!( Path::new("minimal-config").exists(), - "stdout:\n{}\nstderr:\n{}", - stdout, - stderr + "stdout:\n{stdout}\nstderr:\n{stderr}" ); remove_file("minimal-config").unwrap(); } -- cgit 1.4.1-3-g733a5 From 4b01e62943866588e4cf2be8605f0124195b2c55 Mon Sep 17 00:00:00 2001 From: fee1-dead Date: Mon, 14 Aug 2023 20:19:23 +0800 Subject: refactor ABI formatting (#5845) fixes 5701 Whenever we see an `extern "Rust"` on a function, we don't strip it from the function. If there's any future desire to have rustfmt remove an explicit "Rust" ABI, as it historically did prior to this change, then we can consider updating the rustfmt config surface to support that scenario --- src/items.rs | 2 -- src/types.rs | 1 - src/utils.rs | 29 ++++++++++++----------------- tests/target/extern-rust.rs | 1 + 4 files changed, 13 insertions(+), 20 deletions(-) create mode 100644 tests/target/extern-rust.rs (limited to 'src') diff --git a/src/items.rs b/src/items.rs index a72646ef897..1f4a14211b5 100644 --- a/src/items.rs +++ b/src/items.rs @@ -248,7 +248,6 @@ impl<'a> Item<'a> { abi: format_extern( ast::Extern::from_abi(fm.abi, DUMMY_SP), config.force_explicit_abi(), - true, ), vis: None, body: fm @@ -336,7 +335,6 @@ impl<'a> FnSig<'a> { result.push_str(&format_extern( self.ext, context.config.force_explicit_abi(), - false, )); result } diff --git a/src/types.rs b/src/types.rs index 8be474d5bca..f2e229d7477 100644 --- a/src/types.rs +++ b/src/types.rs @@ -892,7 +892,6 @@ fn rewrite_bare_fn( result.push_str(&format_extern( bare_fn.ext, context.config.force_explicit_abi(), - false, )); result.push_str("fn"); diff --git a/src/utils.rs b/src/utils.rs index d1cb197cb51..ae7c50b4ca2 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -131,23 +131,18 @@ pub(crate) fn format_mutability(mutability: ast::Mutability) -> &'static str { } #[inline] -pub(crate) fn format_extern( - ext: ast::Extern, - explicit_abi: bool, - is_mod: bool, -) -> Cow<'static, str> { - let abi = match ext { - ast::Extern::None => "Rust".to_owned(), - ast::Extern::Implicit(_) => "C".to_owned(), - ast::Extern::Explicit(abi, _) => abi.symbol_unescaped.to_string(), - }; - - if abi == "Rust" && !is_mod { - Cow::from("") - } else if abi == "C" && !explicit_abi { - Cow::from("extern ") - } else { - Cow::from(format!(r#"extern "{abi}" "#)) +pub(crate) fn format_extern(ext: ast::Extern, explicit_abi: bool) -> Cow<'static, str> { + match ext { + ast::Extern::None => Cow::from(""), + ast::Extern::Implicit(_) if explicit_abi => Cow::from("extern \"C\" "), + ast::Extern::Implicit(_) => Cow::from("extern "), + // turn `extern "C"` into `extern` when `explicit_abi` is set to false + ast::Extern::Explicit(abi, _) if abi.symbol_unescaped == sym::C && !explicit_abi => { + Cow::from("extern ") + } + ast::Extern::Explicit(abi, _) => { + Cow::from(format!(r#"extern "{}" "#, abi.symbol_unescaped)) + } } } diff --git a/tests/target/extern-rust.rs b/tests/target/extern-rust.rs new file mode 100644 index 00000000000..32824c91203 --- /dev/null +++ b/tests/target/extern-rust.rs @@ -0,0 +1 @@ +extern "Rust" fn uwu() {} -- cgit 1.4.1-3-g733a5 From a57d57b16a2411e9081a083f25b25c7d76e2c2ff Mon Sep 17 00:00:00 2001 From: Kevin Ji <1146876+kevinji@users.noreply.github.com> Date: Sat, 29 Jul 2023 22:46:17 -0700 Subject: Remove newlines in where clauses for v2 Fixes #5655. --- src/items.rs | 4 +++- tests/source/issue-5655/one.rs | 9 +++++++++ tests/source/issue-5655/two.rs | 9 +++++++++ tests/target/issue-5655/one.rs | 9 +++++++++ tests/target/issue-5655/two.rs | 8 ++++++++ 5 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 tests/source/issue-5655/one.rs create mode 100644 tests/source/issue-5655/two.rs create mode 100644 tests/target/issue-5655/one.rs create mode 100644 tests/target/issue-5655/two.rs (limited to 'src') diff --git a/src/items.rs b/src/items.rs index 1f4a14211b5..4d82e192b7d 100644 --- a/src/items.rs +++ b/src/items.rs @@ -2996,10 +2996,12 @@ fn rewrite_bounds_on_where_clause( DefinitiveListTactic::Vertical }; + let preserve_newline = context.config.version() == Version::One; + let fmt = ListFormatting::new(shape, context.config) .tactic(shape_tactic) .trailing_separator(comma_tactic) - .preserve_newline(true); + .preserve_newline(preserve_newline); write_list(&items.collect::>(), &fmt) } diff --git a/tests/source/issue-5655/one.rs b/tests/source/issue-5655/one.rs new file mode 100644 index 00000000000..1758ec56f8b --- /dev/null +++ b/tests/source/issue-5655/one.rs @@ -0,0 +1,9 @@ +// rustfmt-version: One + +fn foo(_: T) +where + T: std::fmt::Debug, + + T: std::fmt::Display, +{ +} diff --git a/tests/source/issue-5655/two.rs b/tests/source/issue-5655/two.rs new file mode 100644 index 00000000000..e37ebbea8af --- /dev/null +++ b/tests/source/issue-5655/two.rs @@ -0,0 +1,9 @@ +// rustfmt-version: Two + +fn foo(_: T) +where + T: std::fmt::Debug, + + T: std::fmt::Display, +{ +} diff --git a/tests/target/issue-5655/one.rs b/tests/target/issue-5655/one.rs new file mode 100644 index 00000000000..1758ec56f8b --- /dev/null +++ b/tests/target/issue-5655/one.rs @@ -0,0 +1,9 @@ +// rustfmt-version: One + +fn foo(_: T) +where + T: std::fmt::Debug, + + T: std::fmt::Display, +{ +} diff --git a/tests/target/issue-5655/two.rs b/tests/target/issue-5655/two.rs new file mode 100644 index 00000000000..14fbc3d1321 --- /dev/null +++ b/tests/target/issue-5655/two.rs @@ -0,0 +1,8 @@ +// rustfmt-version: Two + +fn foo(_: T) +where + T: std::fmt::Debug, + T: std::fmt::Display, +{ +} -- cgit 1.4.1-3-g733a5 From e480739e56b19c8f580e8fdc6a2f83cde784126c Mon Sep 17 00:00:00 2001 From: tdanniels Date: Thu, 17 Aug 2023 12:21:53 -0700 Subject: Prevent ICE when formatting item-only `vec!{}` (#5879) * Prevent ICE when formatting item-only `vec!{}` Fixes 5735 Attempting to format invocations of macros which are considered "forced bracket macros" (currently only `vec!`), but are invoked with braces instead of brackets, and contain only items in their token trees, currently triggers an ICE in rustfmt. This is because the function that handles formatting macro invocations containing only items, `rewrite_macro_with_items`, assumes that the forced delimiter style of the macro being formatted is the same as the delimiter style in the macro's source text when attempting to locate the span after the macro's opening delimiter. This leads to the construction of an invalid span, triggering the ICE. The fix here is to pass the old delimiter style to `rewrite_macro_with_items` as well, so that it can successfully locate the span. --- src/macros.rs | 28 +++++++++++++++++++--------- tests/source/issue_5735.rs | 6 ++++++ tests/target/issue_5735.rs | 6 ++++++ 3 files changed, 31 insertions(+), 9 deletions(-) create mode 100644 tests/source/issue_5735.rs create mode 100644 tests/target/issue_5735.rs (limited to 'src') diff --git a/src/macros.rs b/src/macros.rs index b6a49536d17..8047ab03687 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -255,6 +255,7 @@ fn rewrite_macro_inner( ¯o_name, shape, style, + original_style, position, mac.span(), ); @@ -295,20 +296,19 @@ fn rewrite_macro_inner( // If we are rewriting `vec!` macro or other special macros, // then we can rewrite this as a usual array literal. // Otherwise, we must preserve the original existence of trailing comma. - let macro_name = ¯o_name.as_str(); let mut force_trailing_comma = if trailing_comma { Some(SeparatorTactic::Always) } else { Some(SeparatorTactic::Never) }; - if FORCED_BRACKET_MACROS.contains(macro_name) && !is_nested_macro { + if is_forced_bracket && !is_nested_macro { context.leave_macro(); if context.use_block_indent() { force_trailing_comma = Some(SeparatorTactic::Vertical); }; } let rewrite = rewrite_array( - macro_name, + ¯o_name, arg_vec.iter(), mac.span(), context, @@ -1402,15 +1402,19 @@ fn rewrite_macro_with_items( macro_name: &str, shape: Shape, style: Delimiter, + original_style: Delimiter, position: MacroPosition, span: Span, ) -> Option { - let (opener, closer) = match style { - Delimiter::Parenthesis => ("(", ")"), - Delimiter::Bracket => ("[", "]"), - Delimiter::Brace => (" {", "}"), - _ => return None, + let style_to_delims = |style| match style { + Delimiter::Parenthesis => Some(("(", ")")), + Delimiter::Bracket => Some(("[", "]")), + Delimiter::Brace => Some((" {", "}")), + _ => None, }; + + let (opener, closer) = style_to_delims(style)?; + let (original_opener, _) = style_to_delims(original_style)?; let trailing_semicolon = match style { Delimiter::Parenthesis | Delimiter::Bracket if position == MacroPosition::Item => ";", _ => "", @@ -1418,7 +1422,13 @@ fn rewrite_macro_with_items( let mut visitor = FmtVisitor::from_context(context); visitor.block_indent = shape.indent.block_indent(context.config); - visitor.last_pos = context.snippet_provider.span_after(span, opener.trim()); + + // The current opener may be different from the original opener. This can happen + // if our macro is a forced bracket macro originally written with non-bracket + // delimiters. We need to use the original opener to locate the span after it. + visitor.last_pos = context + .snippet_provider + .span_after(span, original_opener.trim()); for item in items { let item = match item { MacroArg::Item(item) => item, diff --git a/tests/source/issue_5735.rs b/tests/source/issue_5735.rs new file mode 100644 index 00000000000..7708d028bf5 --- /dev/null +++ b/tests/source/issue_5735.rs @@ -0,0 +1,6 @@ +fn find_errors(mut self) { + let errors: Vec<> = vec!{ + #[debug_format = "A({})"] + struct A {} + }; +} diff --git a/tests/target/issue_5735.rs b/tests/target/issue_5735.rs new file mode 100644 index 00000000000..2d1376303f5 --- /dev/null +++ b/tests/target/issue_5735.rs @@ -0,0 +1,6 @@ +fn find_errors(mut self) { + let errors: Vec = vec![ + #[debug_format = "A({})"] + struct A {} + ]; +} -- cgit 1.4.1-3-g733a5 From f89cd3c1f3feffaa960e13c7bec07a6163d18fd3 Mon Sep 17 00:00:00 2001 From: xxchan Date: Tue, 29 Aug 2023 20:46:44 +0800 Subject: Don't treat lines starting with `.` or `)` as ordered markdown lists (#5839) Fixes 5835 Ordered markdown lists start with 0-9 digits followed by a `.` or a `)`. Now, rustfmt ensure that the `.` or `)` is only preceded by numeric characters before deciding that it's reached an `ItemizedBlock` --- src/comment.rs | 7 ++++++- tests/source/issue-5835.rs | 8 ++++++++ tests/target/issue-5835.rs | 8 ++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 tests/source/issue-5835.rs create mode 100644 tests/target/issue-5835.rs (limited to 'src') diff --git a/src/comment.rs b/src/comment.rs index a000d110daa..dec925e14c0 100644 --- a/src/comment.rs +++ b/src/comment.rs @@ -482,7 +482,9 @@ impl ItemizedBlock { // allowed. for suffix in [". ", ") "] { if let Some((prefix, _)) = trimmed.split_once(suffix) { - if prefix.len() <= 2 && prefix.chars().all(|c| char::is_ascii_digit(&c)) { + let has_leading_digits = (1..=2).contains(&prefix.len()) + && prefix.chars().all(|c| char::is_ascii_digit(&c)); + if has_leading_digits { return Some(prefix.len() + suffix.len()); } } @@ -2126,6 +2128,9 @@ fn main() { // https://spec.commonmark.org/0.30 says: "A start number may not be negative": "-1. Not a list item.", "-1 Not a list item.", + // Marker without prefix are not recognized as item markers: + ". Not a list item.", + ") Not a list item.", ]; for line in test_inputs.iter() { let maybe_block = ItemizedBlock::new(line); diff --git a/tests/source/issue-5835.rs b/tests/source/issue-5835.rs new file mode 100644 index 00000000000..3e4da3492ce --- /dev/null +++ b/tests/source/issue-5835.rs @@ -0,0 +1,8 @@ +// rustfmt-wrap_comments: true + +/// . a +pub fn foo() {} + +pub fn main() { + // . a +} diff --git a/tests/target/issue-5835.rs b/tests/target/issue-5835.rs new file mode 100644 index 00000000000..3e4da3492ce --- /dev/null +++ b/tests/target/issue-5835.rs @@ -0,0 +1,8 @@ +// rustfmt-wrap_comments: true + +/// . a +pub fn foo() {} + +pub fn main() { + // . a +} -- cgit 1.4.1-3-g733a5 From 1340fc412a0c902aa6b07b8c475c5126ab4d81c7 Mon Sep 17 00:00:00 2001 From: Robert Sammelson Date: Fri, 21 Jul 2023 00:02:15 -0400 Subject: Fix issues with formatting imports with comments --- src/imports.rs | 6 ++- tests/source/issue-5852.rs | 104 +++++++++++++++++++++++++++++++++++++++++++++ tests/target/issue-5852.rs | 97 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 205 insertions(+), 2 deletions(-) create mode 100644 tests/source/issue-5852.rs create mode 100644 tests/target/issue-5852.rs (limited to 'src') diff --git a/src/imports.rs b/src/imports.rs index 6f0050647dc..f8e7fa62890 100644 --- a/src/imports.rs +++ b/src/imports.rs @@ -589,7 +589,7 @@ impl UseTree { // Normalise foo::{bar} -> foo::bar if let UseSegmentKind::List(ref list) = last.kind { - if list.len() == 1 && list[0].to_string() != "self" { + if list.len() == 1 && list[0].to_string() != "self" && !list[0].has_comment() { normalize_sole_list = true; } } @@ -1032,7 +1032,9 @@ fn rewrite_nested_use_tree( let list_str = write_list(&list_items, &fmt)?; - let result = if (list_str.contains('\n') || list_str.len() > remaining_width) + let result = if (list_str.contains('\n') + || list_str.len() > remaining_width + || tactic == DefinitiveListTactic::Vertical) && context.config.imports_indent() == IndentStyle::Block { format!( diff --git a/tests/source/issue-5852.rs b/tests/source/issue-5852.rs new file mode 100644 index 00000000000..df84f8f58e1 --- /dev/null +++ b/tests/source/issue-5852.rs @@ -0,0 +1,104 @@ +use std::{ + fs, + // (temporarily commented, we'll need this again in a second) io, +}; + +use foo::{ + self // this is important +}; + +use foo :: bar +; + +use foo::{bar}; + +use foo::{ + bar + // abc +}; + +use foo::{ + bar, + // abc +}; + +use foo::{ + // 345 + bar +}; + +use foo::{ + self + // abc +}; + +use foo::{ + self, + // abc +}; + +use foo::{ + // 345 + self +}; + +use foo::{ + self // a + , +}; + +use foo::{ self /* a */ }; + +use foo::{ self /* a */, }; + +use foo::{ + // abc + abc::{ + xyz + // 123 + } +}; + +use foo::{ + // abc + bar, + abc +}; + +use foo::{ + bar, + // abc + abc +}; + +use foo::{ + bar, + abc + // abc +}; + +use foo::{ + bar, + abc, + // abc +}; + +use foo::{ + self, + // abc + abc::{ + xyz + // 123 + } +}; + +use foo::{ + self, + // abc + abc::{ + // 123 + xyz + } +}; + +use path::{self /*comment*/,}; diff --git a/tests/target/issue-5852.rs b/tests/target/issue-5852.rs new file mode 100644 index 00000000000..a86872a68bf --- /dev/null +++ b/tests/target/issue-5852.rs @@ -0,0 +1,97 @@ +use std::{ + fs, + // (temporarily commented, we'll need this again in a second) io, +}; + +use foo::{ + self, // this is important +}; + +use foo::bar; + +use foo::bar; + +use foo::{ + bar, // abc +}; + +use foo::{ + bar, + // abc +}; + +use foo::{ + // 345 + bar, +}; + +use foo::{ + self, // abc +}; + +use foo::{ + self, + // abc +}; + +use foo::{ + // 345 + self, +}; + +use foo::{ + self, // a +}; + +use foo::{self /* a */}; + +use foo::{self /* a */}; + +use foo::{ + // abc + abc::{ + xyz, // 123 + }, +}; + +use foo::{ + abc, + // abc + bar, +}; + +use foo::{ + // abc + abc, + bar, +}; + +use foo::{ + abc, // abc + bar, +}; + +use foo::{ + abc, + // abc + bar, +}; + +use foo::{ + self, + // abc + abc::{ + xyz, // 123 + }, +}; + +use foo::{ + self, + // abc + abc::{ + // 123 + xyz, + }, +}; + +use path::{self /*comment*/}; -- cgit 1.4.1-3-g733a5 From c7c57f8a161f3ed2a561d237ec285de8cd8e7a96 Mon Sep 17 00:00:00 2001 From: David Bar-On Date: Wed, 17 Mar 2021 11:55:51 +0200 Subject: Fix issue with extra semicolon when import comment preceeds semicolon --- src/lists.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/lists.rs b/src/lists.rs index a878e6cf9b2..41afef279e9 100644 --- a/src/lists.rs +++ b/src/lists.rs @@ -637,7 +637,7 @@ pub(crate) fn extract_post_comment( post_snippet.trim_matches(white_space) } // not comment or over two lines - else if post_snippet.ends_with(',') + else if post_snippet.ends_with(separator) && (!post_snippet.trim().starts_with("//") || post_snippet.trim().contains('\n')) { post_snippet[..(post_snippet.len() - 1)].trim_matches(white_space) -- cgit 1.4.1-3-g733a5 From 262feb33373b2d6b909f00e86be635c6e19886b6 Mon Sep 17 00:00:00 2001 From: Linda_pp Date: Sat, 9 Sep 2023 10:05:07 +0900 Subject: Fix checking if newline is needed before `else` in let-else statement Fixes 5901 Take leading attributes and comments into consideration when determining if we need to wrap the `else` keyword onto the next line. --- src/items.rs | 19 ++++++++++-- tests/source/let_else.rs | 20 +++++++++++++ tests/source/let_else_v2.rs | 56 ++++++++++++++++++++++++++++++++++ tests/target/let_else.rs | 31 +++++++++++++++++++ tests/target/let_else_v2.rs | 73 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 196 insertions(+), 3 deletions(-) create mode 100644 tests/source/let_else_v2.rs create mode 100644 tests/target/let_else_v2.rs (limited to 'src') diff --git a/src/items.rs b/src/items.rs index 4d82e192b7d..48c37df812c 100644 --- a/src/items.rs +++ b/src/items.rs @@ -75,6 +75,7 @@ impl Rewrite for ast::Local { false, )? }; + let let_kw_offset = result.len() - "let ".len(); // 4 = "let ".len() let pat_shape = shape.offset_left(4)?; @@ -127,8 +128,15 @@ impl Rewrite for ast::Local { if let Some(block) = else_block { let else_kw_span = init.span.between(block.span); + // Strip attributes and comments to check if newline is needed before the else + // keyword from the initializer part. (#5901) + let init_str = if context.config.version() == Version::Two { + &result[let_kw_offset..] + } else { + result.as_str() + }; let force_newline_else = pat_str.contains('\n') - || !same_line_else_kw_and_brace(&result, context, else_kw_span, nested_shape); + || !same_line_else_kw_and_brace(init_str, context, else_kw_span, nested_shape); let else_kw = rewrite_else_kw_with_comments( force_newline_else, true, @@ -146,11 +154,16 @@ impl Rewrite for ast::Local { std::cmp::min(shape.width, context.config.single_line_let_else_max_width()); // If available_space hits zero we know for sure this will be a multi-lined block - let available_space = max_width.saturating_sub(result.len()); + let assign_str_with_else_kw = if context.config.version() == Version::Two { + &result[let_kw_offset..] + } else { + result.as_str() + }; + let available_space = max_width.saturating_sub(assign_str_with_else_kw.len()); let allow_single_line = !force_newline_else && available_space > 0 - && allow_single_line_let_else_block(&result, block); + && allow_single_line_let_else_block(assign_str_with_else_kw, block); let mut rw_else_block = rewrite_let_else_block(block, allow_single_line, context, shape)?; diff --git a/tests/source/let_else.rs b/tests/source/let_else.rs index 85b3604ad3c..cb2859e805d 100644 --- a/tests/source/let_else.rs +++ b/tests/source/let_else.rs @@ -160,3 +160,23 @@ fn with_trailing_try_operator() { // Maybe this is a workaround? let Ok(Some(next_bucket)) = ranking_rules[cur_ranking_rule_index].next_bucket(ctx, logger, &ranking_rule_universes[cur_ranking_rule_index]) else { return }; } + +fn issue5901() { + #[cfg(target_os = "linux")] + let Some(x) = foo else { todo!() }; + + #[cfg(target_os = "linux")] + // Some comments between attributes and let-else statement + let Some(x) = foo else { todo!() }; + + #[cfg(target_os = "linux")] + #[cfg(target_arch = "x86_64")] + let Some(x) = foo else { todo!() }; + + // The else block will be multi-lined because attributes and comments before `let` + // are included when calculating max width + #[cfg(target_os = "linux")] + #[cfg(target_arch = "x86_64")] + // Some comments between attributes and let-else statement + let Some(x) = foo() else { todo!() }; +} diff --git a/tests/source/let_else_v2.rs b/tests/source/let_else_v2.rs new file mode 100644 index 00000000000..a420fbcf95b --- /dev/null +++ b/tests/source/let_else_v2.rs @@ -0,0 +1,56 @@ +// rustfmt-version: Two +// rustfmt-single_line_let_else_max_width: 100 + +fn issue5901() { + #[cfg(target_os = "linux")] + let Some(x) = foo else { todo!() }; + + #[cfg(target_os = "linux")] + // Some comments between attributes and let-else statement + let Some(x) = foo else { todo!() }; + + #[cfg(target_os = "linux")] + #[cfg(target_arch = "x86_64")] + let Some(x) = foo else { todo!() }; + + // The else block is multi-lined + #[cfg(target_os = "linux")] + let Some(x) = foo else { return; }; + + // The else block will be single-lined because attributes and comments before `let` + // are no longer included when calculating max width + #[cfg(target_os = "linux")] + #[cfg(target_arch = "x86_64")] + // Some comments between attributes and let-else statement + let Some(x) = foo else { todo!() }; + + // Some more test cases for v2 formatting with attributes + + #[cfg(target_os = "linux")] + #[cfg(target_arch = "x86_64")] + let Some(x) = opt + // pre else keyword line-comment + else { return; }; + + #[cfg(target_os = "linux")] + #[cfg(target_arch = "x86_64")] + let Some(x) = opt else + // post else keyword line-comment + { return; }; + + #[cfg(target_os = "linux")] + #[cfg(target_arch = "x86_64")] + let Foo {x: Bar(..), y: FooBar(..), z: Baz(..)} = opt else { + return; + }; + + #[cfg(target_os = "linux")] + #[cfg(target_arch = "x86_64")] + let Some(Ok((Message::ChangeColor(super::color::Color::Rgb(r, g, b)), Point { x, y, z }))) = opt else { + return; + }; + + #[cfg(target_os = "linux")] + #[cfg(target_arch = "x86_64")] + let Some(x) = very_very_very_very_very_very_very_very_very_very_very_very_long_expression_in_assign_rhs() else { return; }; +} diff --git a/tests/target/let_else.rs b/tests/target/let_else.rs index 6554a0961c0..f6560e85462 100644 --- a/tests/target/let_else.rs +++ b/tests/target/let_else.rs @@ -252,3 +252,34 @@ fn with_trailing_try_operator() { return; }; } + +fn issue5901() { + #[cfg(target_os = "linux")] + let Some(x) = foo + else { + todo!() + }; + + #[cfg(target_os = "linux")] + // Some comments between attributes and let-else statement + let Some(x) = foo + else { + todo!() + }; + + #[cfg(target_os = "linux")] + #[cfg(target_arch = "x86_64")] + let Some(x) = foo + else { + todo!() + }; + + // The else block will be multi-lined because attributes and comments before `let` + // are included when calculating max width + #[cfg(target_os = "linux")] + #[cfg(target_arch = "x86_64")] + // Some comments between attributes and let-else statement + let Some(x) = foo() else { + todo!() + }; +} diff --git a/tests/target/let_else_v2.rs b/tests/target/let_else_v2.rs new file mode 100644 index 00000000000..b25ac1609d8 --- /dev/null +++ b/tests/target/let_else_v2.rs @@ -0,0 +1,73 @@ +// rustfmt-version: Two +// rustfmt-single_line_let_else_max_width: 100 + +fn issue5901() { + #[cfg(target_os = "linux")] + let Some(x) = foo else { todo!() }; + + #[cfg(target_os = "linux")] + // Some comments between attributes and let-else statement + let Some(x) = foo else { todo!() }; + + #[cfg(target_os = "linux")] + #[cfg(target_arch = "x86_64")] + let Some(x) = foo else { todo!() }; + + // The else block is multi-lined + #[cfg(target_os = "linux")] + let Some(x) = foo else { + return; + }; + + // The else block will be single-lined because attributes and comments before `let` + // are no longer included when calculating max width + #[cfg(target_os = "linux")] + #[cfg(target_arch = "x86_64")] + // Some comments between attributes and let-else statement + let Some(x) = foo else { todo!() }; + + // Some more test cases for v2 formatting with attributes + + #[cfg(target_os = "linux")] + #[cfg(target_arch = "x86_64")] + let Some(x) = opt + // pre else keyword line-comment + else { + return; + }; + + #[cfg(target_os = "linux")] + #[cfg(target_arch = "x86_64")] + let Some(x) = opt else + // post else keyword line-comment + { + return; + }; + + #[cfg(target_os = "linux")] + #[cfg(target_arch = "x86_64")] + let Foo { + x: Bar(..), + y: FooBar(..), + z: Baz(..), + } = opt + else { + return; + }; + + #[cfg(target_os = "linux")] + #[cfg(target_arch = "x86_64")] + let Some(Ok((Message::ChangeColor(super::color::Color::Rgb(r, g, b)), Point { x, y, z }))) = + opt + else { + return; + }; + + #[cfg(target_os = "linux")] + #[cfg(target_arch = "x86_64")] + let Some(x) = + very_very_very_very_very_very_very_very_very_very_very_very_long_expression_in_assign_rhs() + else { + return; + }; +} -- cgit 1.4.1-3-g733a5 From 18737ddc7299fa6fa6e9e5d079a543afff277011 Mon Sep 17 00:00:00 2001 From: pan93412 Date: Tue, 12 Sep 2023 02:15:59 +0800 Subject: Prefer light_rewrite_comment if it is not a doccomment (#5536) Fixes 5533, 5568, 5907 Prevent `format_code_in_doc_comments=true` from affecting how non-doc comments are formatted. --------- Co-authored-by: Yacin Tmimi --- src/comment.rs | 6 +++++- tests/target/issue-5568.rs | 14 ++++++++++++++ tests/target/issue_5533.rs | 6 ++++++ tests/target/issue_5907.rs | 6 ++++++ 4 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 tests/target/issue-5568.rs create mode 100644 tests/target/issue_5533.rs create mode 100644 tests/target/issue_5907.rs (limited to 'src') diff --git a/src/comment.rs b/src/comment.rs index dec925e14c0..7da0f79bd09 100644 --- a/src/comment.rs +++ b/src/comment.rs @@ -365,7 +365,11 @@ fn identify_comment( trim_left_preserve_layout(first_group, shape.indent, config)? } else if !config.normalize_comments() && !config.wrap_comments() - && !config.format_code_in_doc_comments() + && !( + // `format_code_in_doc_comments` should only take effect on doc comments, + // so we only consider it when this comment block is a doc comment block. + is_doc_comment && config.format_code_in_doc_comments() + ) { light_rewrite_comment(first_group, shape.indent, config, is_doc_comment) } else { diff --git a/tests/target/issue-5568.rs b/tests/target/issue-5568.rs new file mode 100644 index 00000000000..03ca3a4523c --- /dev/null +++ b/tests/target/issue-5568.rs @@ -0,0 +1,14 @@ +// rustfmt-max_width: 119 +// rustfmt-format_code_in_doc_comments: true + +mod libs { + fn mrbgems_sources() { + [ + "mrbgems/mruby-compiler/core/codegen.c", // Ruby parser and bytecode generation + "mrbgems/mruby-compiler/core/y.tab.c", // Ruby parser and bytecode generation + "mrbgems/mruby-metaprog/src/metaprog.c", // APIs on Kernel and Module for accessing classes and variables + "mrbgems/mruby-method/src/method.c", // `Method`, `UnboundMethod`, and method APIs on Kernel and Module + "mrbgems/mruby-pack/src/pack.c", // Array#pack and String#unpack + ] + } +} diff --git a/tests/target/issue_5533.rs b/tests/target/issue_5533.rs new file mode 100644 index 00000000000..c3095a44022 --- /dev/null +++ b/tests/target/issue_5533.rs @@ -0,0 +1,6 @@ +// rustfmt-format_code_in_doc_comments: true + +struct TestStruct { + position_currency: String, // Currency for position of this contract. If not null, 1 contract = 1 positionCurrency. + pu: Option, // Previous event update sequense ("u" of previous message), -1 also means None +} diff --git a/tests/target/issue_5907.rs b/tests/target/issue_5907.rs new file mode 100644 index 00000000000..144de636b9b --- /dev/null +++ b/tests/target/issue_5907.rs @@ -0,0 +1,6 @@ +// rustfmt-format_code_in_doc_comments: true + +// ``` +// [ +// ] +// ``` -- cgit 1.4.1-3-g733a5 From da7f67810f263351f61f5618c250f7396a5f9bbc Mon Sep 17 00:00:00 2001 From: Ed Page Date: Mon, 11 Sep 2023 21:12:58 -0500 Subject: feat(cargo): Style --help like cargo nightly (#5908) * chore: Update clap * refactor(cargo): Update style of derive * feat(cargo): Style help like cargo nightly --- Cargo.lock | 232 +++++++++++--------------------------------------- Cargo.toml | 3 +- src/cargo-fmt/main.rs | 21 ++--- 3 files changed, 62 insertions(+), 194 deletions(-) (limited to 'src') diff --git a/Cargo.lock b/Cargo.lock index 2cefec09589..76adbb1119f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -23,42 +23,50 @@ dependencies = [ [[package]] name = "anstream" -version = "0.2.6" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "342258dd14006105c2b75ab1bd7543a03bdf0cfc94383303ac212a04939dff6f" +checksum = "b1f58811cfac344940f1a400b6e6231ce35171f614f26439e80f8c1465c5cc0c" dependencies = [ "anstyle", "anstyle-parse", + "anstyle-query", "anstyle-wincon", - "concolor-override", - "concolor-query", - "is-terminal", + "colorchoice", "utf8parse", ] [[package]] name = "anstyle" -version = "0.3.5" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23ea9e81bd02e310c216d080f6223c179012256e5151c41db88d12c88a1684d2" +checksum = "b84bf0a05bbb2a83e5eb6fa36bb6e87baa08193c35ff52bbf6b38d8af2890e46" [[package]] name = "anstyle-parse" -version = "0.1.1" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7d1bb534e9efed14f3e5f44e7dd1a4f709384023a4165199a4241e18dff0116" +checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" dependencies = [ "utf8parse", ] +[[package]] +name = "anstyle-query" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +dependencies = [ + "windows-sys", +] + [[package]] name = "anstyle-wincon" -version = "0.2.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3127af6145b149f3287bb9a0d10ad9c5692dba8c53ad48285e5bec4063834fa" +checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd" dependencies = [ "anstyle", - "windows-sys 0.45.0", + "windows-sys", ] [[package]] @@ -129,12 +137,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "cc" -version = "1.0.79" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" - [[package]] name = "cfg-if" version = "1.0.0" @@ -143,33 +145,41 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.2.1" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "046ae530c528f252094e4a77886ee1374437744b2bff1497aa898bbddbbb29b3" +checksum = "6a13b88d2c62ff462f88e4a121f17a82c1af05693a2f192b5c38d14de73c19f6" dependencies = [ "clap_builder", "clap_derive", - "once_cell", +] + +[[package]] +name = "clap-cargo" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "383f21342a464d4af96e9a4cad22a0b4f2880d4a5b3bbf5c9654dd1d9a224ee4" +dependencies = [ + "anstyle", + "clap", ] [[package]] name = "clap_builder" -version = "4.2.1" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "223163f58c9a40c3b0a43e1c4b50a9ce09f007ea2cb1ec258a687945b4b7929f" +checksum = "2bb9faaa7c2ef94b2743a21f5a29e6f0010dff4caa69ac8e9d6cf8b6fa74da08" dependencies = [ "anstream", "anstyle", - "bitflags", "clap_lex", "strsim", ] [[package]] name = "clap_derive" -version = "4.2.0" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9644cd56d6b87dbe899ef8b053e331c0637664e9e21a33dfcdc36093f5c5c4" +checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" dependencies = [ "heck", "proc-macro2", @@ -179,24 +189,15 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.4.1" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1" +checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" [[package]] -name = "concolor-override" +name = "colorchoice" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a855d4a1978dc52fb0536a04d384c2c0c1aa273597f08b77c8c4d3b2eec6037f" - -[[package]] -name = "concolor-query" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d11d52c3d7ca2e6d0040212be9e4dbbcd78b6447f535b6b561f449427944cf" -dependencies = [ - "windows-sys 0.45.0", -] +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "crossbeam-utils" @@ -261,27 +262,6 @@ version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" -[[package]] -name = "errno" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" -dependencies = [ - "errno-dragonfly", - "libc", - "windows-sys 0.48.0", -] - -[[package]] -name = "errno-dragonfly" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" -dependencies = [ - "cc", - "libc", -] - [[package]] name = "fnv" version = "1.0.7" @@ -333,12 +313,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" -[[package]] -name = "hermit-abi" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" - [[package]] name = "ignore" version = "0.4.18" @@ -367,29 +341,6 @@ dependencies = [ "hashbrown", ] -[[package]] -name = "io-lifetimes" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" -dependencies = [ - "hermit-abi", - "libc", - "windows-sys 0.48.0", -] - -[[package]] -name = "is-terminal" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" -dependencies = [ - "hermit-abi", - "io-lifetimes", - "rustix", - "windows-sys 0.48.0", -] - [[package]] name = "itertools" version = "0.10.3" @@ -423,12 +374,6 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a" -[[package]] -name = "linux-raw-sys" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59d8c75012853d2e872fb56bc8a2e53718e2cafe1a4c823143141c6d90c322f" - [[package]] name = "log" version = "0.4.16" @@ -573,6 +518,7 @@ dependencies = [ "bytecount", "cargo_metadata", "clap", + "clap-cargo", "diff", "dirs", "getopts", @@ -593,20 +539,6 @@ dependencies = [ "unicode-width", ] -[[package]] -name = "rustix" -version = "0.37.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85597d61f83914ddeba6a47b3b8ffe7365107221c2e557ed94426489fefb5f77" -dependencies = [ - "bitflags", - "errno", - "io-lifetimes", - "libc", - "linux-raw-sys", - "windows-sys 0.48.0", -] - [[package]] name = "rustversion" version = "1.0.6" @@ -929,37 +861,13 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows-sys" -version = "0.45.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" -dependencies = [ - "windows-targets 0.42.2", -] - [[package]] name = "windows-sys" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets 0.48.0", -] - -[[package]] -name = "windows-targets" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", + "windows-targets", ] [[package]] @@ -968,93 +876,51 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" dependencies = [ - "windows_aarch64_gnullvm 0.48.0", - "windows_aarch64_msvc 0.48.0", - "windows_i686_gnu 0.48.0", - "windows_i686_msvc 0.48.0", - "windows_x86_64_gnu 0.48.0", - "windows_x86_64_gnullvm 0.48.0", - "windows_x86_64_msvc 0.48.0", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" - [[package]] name = "windows_aarch64_msvc" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" -[[package]] -name = "windows_i686_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" - [[package]] name = "windows_i686_gnu" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" -[[package]] -name = "windows_i686_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" - [[package]] name = "windows_i686_msvc" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" - [[package]] name = "windows_x86_64_gnu" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" - [[package]] name = "windows_x86_64_gnullvm" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" - [[package]] name = "windows_x86_64_msvc" version = "0.48.0" diff --git a/Cargo.toml b/Cargo.toml index 051c60fca11..ce7cfec9ba0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,7 +37,8 @@ annotate-snippets = { version = "0.9", features = ["color"] } anyhow = "1.0" bytecount = "0.6.3" cargo_metadata = "0.15.4" -clap = { version = "4.2.1", features = ["derive"] } +clap = { version = "4.4.2", features = ["derive"] } +clap-cargo = "0.12.0" diff = "0.1" dirs = "4.0" getopts = "0.2" diff --git a/src/cargo-fmt/main.rs b/src/cargo-fmt/main.rs index 3d399c12978..a1ad1aafac4 100644 --- a/src/cargo-fmt/main.rs +++ b/src/cargo-fmt/main.rs @@ -22,27 +22,28 @@ use clap::{CommandFactory, Parser}; mod cargo_fmt_tests; #[derive(Parser)] -#[clap( +#[command( disable_version_flag = true, bin_name = "cargo fmt", about = "This utility formats all bin and lib files of \ the current crate using rustfmt." )] +#[command(styles = clap_cargo::style::CLAP_STYLING)] pub struct Opts { /// No output printed to stdout - #[clap(short = 'q', long = "quiet")] + #[arg(short = 'q', long = "quiet")] quiet: bool, /// Use verbose output - #[clap(short = 'v', long = "verbose")] + #[arg(short = 'v', long = "verbose")] verbose: bool, /// Print rustfmt version and exit - #[clap(long = "version")] + #[arg(long = "version")] version: bool, /// Specify package to format - #[clap( + #[arg( short = 'p', long = "package", value_name = "package", @@ -51,24 +52,24 @@ pub struct Opts { packages: Vec, /// Specify path to Cargo.toml - #[clap(long = "manifest-path", value_name = "manifest-path")] + #[arg(long = "manifest-path", value_name = "manifest-path")] manifest_path: Option, /// Specify message-format: short|json|human - #[clap(long = "message-format", value_name = "message-format")] + #[arg(long = "message-format", value_name = "message-format")] message_format: Option, /// Options passed to rustfmt // 'raw = true' to make `--` explicit. - #[clap(name = "rustfmt_options", raw(true))] + #[arg(name = "rustfmt_options", raw = true)] rustfmt_options: Vec, /// Format all packages, and also their local path-based dependencies - #[clap(long = "all")] + #[arg(long = "all")] format_all: bool, /// Run rustfmt in check mode - #[clap(long = "check")] + #[arg(long = "check")] check: bool, } -- cgit 1.4.1-3-g733a5 From a1fabbf3865c1044c7e96e8ac337131ebdf411b6 Mon Sep 17 00:00:00 2001 From: GambitingMan <68272188+GambitingMan@users.noreply.github.com> Date: Wed, 20 Sep 2023 21:29:02 +0200 Subject: Bugfix/comment duplication (#5913) * Fix #5871 * Only idempotence test is necessary * Update src/expr.rs Co-authored-by: Caleb Cartwright --------- Co-authored-by: Caleb Cartwright --- src/expr.rs | 2 +- tests/target/issue-5871.rs | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 tests/target/issue-5871.rs (limited to 'src') diff --git a/src/expr.rs b/src/expr.rs index 450f1476db0..2f230ecc3b4 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -1453,7 +1453,7 @@ pub(crate) fn rewrite_paren( let remove_nested_parens = context.config.remove_nested_parens(); loop { // 1 = "(" or ")" - pre_span = mk_sp(span.lo() + BytePos(1), subexpr.span.lo()); + pre_span = mk_sp(span.lo() + BytePos(1), subexpr.span().lo()); post_span = mk_sp(subexpr.span.hi(), span.hi() - BytePos(1)); pre_comment = rewrite_missing_comment(pre_span, shape, context)?; post_comment = rewrite_missing_comment(post_span, shape, context)?; diff --git a/tests/target/issue-5871.rs b/tests/target/issue-5871.rs new file mode 100644 index 00000000000..3116533bcb8 --- /dev/null +++ b/tests/target/issue-5871.rs @@ -0,0 +1,8 @@ +#![feature(stmt_expr_attributes)] +fn okay() -> u32 { + ( + // Comments in parentheses-expressions caused attributes to be duplicated. + #[allow(unused_variables)] + 0 + ) +} -- cgit 1.4.1-3-g733a5 From 27071031543908ba594560bda58cf86ac2e33f1e Mon Sep 17 00:00:00 2001 From: Caleb Cartwright Date: Sun, 8 Oct 2023 17:24:25 -0500 Subject: fix: adjust span derivation for const generics --- src/items.rs | 2 +- tests/source/issue-5935.rs | 9 +++++++++ tests/target/issue-5935.rs | 8 ++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 tests/source/issue-5935.rs create mode 100644 tests/target/issue-5935.rs (limited to 'src') diff --git a/src/items.rs b/src/items.rs index 48c37df812c..c31d425af52 100644 --- a/src/items.rs +++ b/src/items.rs @@ -3244,7 +3244,7 @@ fn format_generics( if brace_pos == BracePos::None { span.hi() } else { - context.snippet_provider.span_before(span, "{") + context.snippet_provider.span_before_last(span, "{") }, ), shape, diff --git a/tests/source/issue-5935.rs b/tests/source/issue-5935.rs new file mode 100644 index 00000000000..a1aac05627a --- /dev/null +++ b/tests/source/issue-5935.rs @@ -0,0 +1,9 @@ +struct Regs< + const BEGIN: u64, + const END: u64, + const DIM: usize, + const N: usize = { (END - BEGIN) as usize / (8 * DIM) + 1 }, +> +{ + _foo: u64, +} \ No newline at end of file diff --git a/tests/target/issue-5935.rs b/tests/target/issue-5935.rs new file mode 100644 index 00000000000..ebc62c46466 --- /dev/null +++ b/tests/target/issue-5935.rs @@ -0,0 +1,8 @@ +struct Regs< + const BEGIN: u64, + const END: u64, + const DIM: usize, + const N: usize = { (END - BEGIN) as usize / (8 * DIM) + 1 }, +> { + _foo: u64, +} -- cgit 1.4.1-3-g733a5 From 457dc79a35242826860f40ee4d6e5623a4071a5b Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Sat, 29 Jan 2022 22:15:30 -0600 Subject: Add support for ExprKind::Let --- src/expr.rs | 33 ++++++++++++++++++++++++++++++++- tests/source/let_chains.rs | 16 ++++++++++++++++ tests/source/match.rs | 3 +++ tests/target/let_chains.rs | 41 +++++++++++++++++++++++++++++++++++++++++ tests/target/match.rs | 8 ++++++++ 5 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 tests/source/let_chains.rs create mode 100644 tests/target/let_chains.rs (limited to 'src') diff --git a/src/expr.rs b/src/expr.rs index 2f230ecc3b4..c15e680333b 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -132,7 +132,7 @@ pub(crate) fn format_expr( ast::ExprKind::Tup(ref items) => { rewrite_tuple(context, items.iter(), expr.span, shape, items.len() == 1) } - ast::ExprKind::Let(..) => None, + ast::ExprKind::Let(ref pat, ref expr, _span) => rewrite_let(context, shape, pat, expr), ast::ExprKind::If(..) | ast::ExprKind::ForLoop(..) | ast::ExprKind::Loop(..) @@ -1834,6 +1834,37 @@ fn rewrite_tuple_in_visual_indent_style<'a, T: 'a + IntoOverflowableItem<'a>>( Some(format!("({list_str})")) } +fn rewrite_let( + context: &RewriteContext<'_>, + shape: Shape, + pat: &ast::Pat, + expr: &ast::Expr, +) -> Option { + let mut result = "let ".to_owned(); + + // 4 = "let ".len() + let pat_shape = shape.offset_left(4)?; + let pat_str = pat.rewrite(context, pat_shape)?; + result.push_str(&pat_str); + + result.push_str(" ="); + + let comments_lo = context + .snippet_provider + .span_after(expr.span.with_lo(pat.span.hi()), "="); + let comments_span = mk_sp(comments_lo, expr.span.lo()); + rewrite_assign_rhs_with_comments( + context, + result, + expr, + shape, + &RhsAssignKind::Expr(&expr.kind, expr.span), + RhsTactics::Default, + comments_span, + true, + ) +} + pub(crate) fn rewrite_tuple<'a, T: 'a + IntoOverflowableItem<'a>>( context: &'a RewriteContext<'_>, items: impl Iterator, diff --git a/tests/source/let_chains.rs b/tests/source/let_chains.rs new file mode 100644 index 00000000000..f5f8285aa10 --- /dev/null +++ b/tests/source/let_chains.rs @@ -0,0 +1,16 @@ +fn main() { + if let x = x && x {} + + if xxx && let x = x {} + + if aaaaaaaaaaaaaaaaaaaaa && aaaaaaaaaaaaaaa && aaaaaaaaa && let Some(x) = xxxxxxxxxxxx && aaaaaaa && let None = aaaaaaaaaa {} + + if aaaaaaaaaaaaaaaaaaaaa && aaaaaaaaaaaaaaa || aaaaaaaaa && let Some(x) = xxxxxxxxxxxx && aaaaaaa && let None = aaaaaaaaaa {} + + if let Some(Struct { x:TS(1,2) }) = path::to::<_>(hehe) + && let [Simple, people] = /* get ready */ create_universe(/* hi */ GreatPowers).initialize_badminton().populate_swamps() && + let everybody = (Loops { hi /*hi*/ , ..loopy() }) || summons::triumphantly() { todo!() } + + if let XXXXXXXXX { xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, yyyyyyyyyyyyy, zzzzzzzzzzzzz} = xxxxxxx() + && let Foo = bar() { todo!() } +} \ No newline at end of file diff --git a/tests/source/match.rs b/tests/source/match.rs index b5dc9957a2c..d1d8d7f2c36 100644 --- a/tests/source/match.rs +++ b/tests/source/match.rs @@ -292,6 +292,9 @@ fn guards() { aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa if fooooooooooooooooooooo && (bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb || cccccccccccccccccccccccccccccccccccccccc) => {} + Hi { friend } if let None = friend => {} + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa if let Some(foooooooooooooo) = hiiiiiiiiiiiiiii => {} + aaaaaaaaaaaaaaaaa if let Superman { powers: Some(goteem), .. } = all::get_random_being::() => {} } } diff --git a/tests/target/let_chains.rs b/tests/target/let_chains.rs new file mode 100644 index 00000000000..36fd0ba1590 --- /dev/null +++ b/tests/target/let_chains.rs @@ -0,0 +1,41 @@ +fn main() { + if let x = x && x {} + + if xxx && let x = x {} + + if aaaaaaaaaaaaaaaaaaaaa + && aaaaaaaaaaaaaaa + && aaaaaaaaa + && let Some(x) = xxxxxxxxxxxx + && aaaaaaa + && let None = aaaaaaaaaa + {} + + if aaaaaaaaaaaaaaaaaaaaa && aaaaaaaaaaaaaaa + || aaaaaaaaa && let Some(x) = xxxxxxxxxxxx && aaaaaaa && let None = aaaaaaaaaa + {} + + if let Some(Struct { x: TS(1, 2) }) = path::to::<_>(hehe) + && let [Simple, people] = /* get ready */ + create_universe(/* hi */ GreatPowers) + .initialize_badminton() + .populate_swamps() + && let everybody = (Loops { + hi, /*hi*/ + ..loopy() + }) + || summons::triumphantly() + { + todo!() + } + + if let XXXXXXXXX { + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, + yyyyyyyyyyyyy, + zzzzzzzzzzzzz, + } = xxxxxxx() + && let Foo = bar() + { + todo!() + } +} diff --git a/tests/target/match.rs b/tests/target/match.rs index 1bf3fb758ee..0e7815a814d 100644 --- a/tests/target/match.rs +++ b/tests/target/match.rs @@ -317,6 +317,14 @@ fn guards() { if fooooooooooooooooooooo && (bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb || cccccccccccccccccccccccccccccccccccccccc) => {} + Hi { friend } if let None = friend => {} + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + if let Some(foooooooooooooo) = hiiiiiiiiiiiiiii => {} + aaaaaaaaaaaaaaaaa + if let Superman { + powers: Some(goteem), + .. + } = all::get_random_being::() => {} } } -- cgit 1.4.1-3-g733a5 From 547577fa5d309d90292ca3a58fef1bf0d9325cc0 Mon Sep 17 00:00:00 2001 From: Yacin Tmimi Date: Mon, 7 Aug 2023 12:57:20 -0400 Subject: implement sinlge line let-chain rules for now, let-chains can only be formatted on a single line if the chain consits of 2 expressions where the first is an identifier proceeded by any number of unary operators and the second is a let-expr. --- src/expr.rs | 3 ++ src/pairs.rs | 41 +++++++++++++++-- tests/source/let_chains.rs | 107 ++++++++++++++++++++++++++++++++++++++++++++- tests/target/let_chains.rs | 91 +++++++++++++++++++++++++++++++++++++- 4 files changed, 236 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/expr.rs b/src/expr.rs index c15e680333b..25226991fbc 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -1842,11 +1842,14 @@ fn rewrite_let( ) -> Option { let mut result = "let ".to_owned(); + // TODO(ytmimi) comments could appear between `let` and the `pat` + // 4 = "let ".len() let pat_shape = shape.offset_left(4)?; let pat_str = pat.rewrite(context, pat_shape)?; result.push_str(&pat_str); + // TODO(ytmimi) comments could appear between `pat` and `=` result.push_str(" ="); let comments_lo = context diff --git a/src/pairs.rs b/src/pairs.rs index 96f023b3b0e..9dac20d3699 100644 --- a/src/pairs.rs +++ b/src/pairs.rs @@ -42,9 +42,13 @@ pub(crate) fn rewrite_all_pairs( context: &RewriteContext<'_>, ) -> Option { expr.flatten(context, shape).and_then(|list| { - // First we try formatting on one line. - rewrite_pairs_one_line(&list, shape, context) - .or_else(|| rewrite_pairs_multiline(&list, shape, context)) + if list.let_chain_count() > 0 && !list.can_rewrite_let_chain_single_line() { + rewrite_pairs_multiline(&list, shape, context) + } else { + // First we try formatting on one line. + rewrite_pairs_one_line(&list, shape, context) + .or_else(|| rewrite_pairs_multiline(&list, shape, context)) + } }) } @@ -255,6 +259,37 @@ struct PairList<'a, 'b, T: Rewrite> { separators: Vec<&'a str>, } +fn is_ident(expr: &ast::Expr) -> bool { + match &expr.kind { + ast::ExprKind::Path(None, path) if path.segments.len() == 1 => true, + ast::ExprKind::Unary(_, expr) + | ast::ExprKind::AddrOf(_, _, expr) + | ast::ExprKind::Paren(expr) + | ast::ExprKind::Try(expr) => is_ident(expr), + _ => false, + } +} + +impl<'a, 'b> PairList<'a, 'b, ast::Expr> { + fn let_chain_count(&self) -> usize { + self.list + .iter() + .filter(|(expr, _)| matches!(expr.kind, ast::ExprKind::Let(_, _, _))) + .count() + } + + fn can_rewrite_let_chain_single_line(&self) -> bool { + if self.list.len() != 2 { + return false; + } + + let fist_item_is_ident = is_ident(self.list[0].0); + let second_item_is_let_chain = matches!(self.list[1].0.kind, ast::ExprKind::Let(_, _, _)); + + fist_item_is_ident && second_item_is_let_chain + } +} + impl FlattenPair for ast::Expr { fn flatten( &self, diff --git a/tests/source/let_chains.rs b/tests/source/let_chains.rs index f5f8285aa10..88ee126bfbd 100644 --- a/tests/source/let_chains.rs +++ b/tests/source/let_chains.rs @@ -13,4 +13,109 @@ fn main() { if let XXXXXXXXX { xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, yyyyyyyyyyyyy, zzzzzzzzzzzzz} = xxxxxxx() && let Foo = bar() { todo!() } -} \ No newline at end of file +} + +fn test_single_line_let_chain() { + // first item in let-chain is an ident + if a && let Some(b) = foo() { + } + + // first item in let-chain is a unary ! with an ident + let unary_not = if !from_hir_call + && let Some(p) = parent + { + }; + + // first item in let-chain is a unary * with an ident + let unary_deref = if *some_deref + && let Some(p) = parent + { + }; + + // first item in let-chain is a unary - (neg) with an ident + let unary_neg = if -some_ident + && let Some(p) = parent + { + }; + + // first item in let-chain is a try (?) with an ident + let try_ = if some_try? + && let Some(p) = parent + { + }; + + // first item in let-chain is an ident wrapped in parens + let in_parens = if (some_ident) + && let Some(p) = parent + { + }; + + // first item in let-chain is a ref & with an ident + let _ref = if &some_ref + && let Some(p) = parent + { + }; + + // first item in let-chain is a ref &mut with an ident + let mut_ref = if &mut some_ref + && let Some(p) = parent + { + }; + + // chain unary ref and try + let chain_of_unary_ref_and_try = if !&*some_ref? + && let Some(p) = parent { + }; +} + +fn test_multi_line_let_chain() { + // Can only single line the let-chain if the first item is an ident + if let Some(x) = y && a { + + } + + // More than one let-chain must be formatted on multiple lines + if let Some(x) = y && let Some(a) = b { + + } + + // The ident isn't long enough so we don't wrap the first let-chain + if a && let Some(x) = y && let Some(a) = b { + + } + + // The ident is long enough so both let-chains are wrapped + if aaa && let Some(x) = y && let Some(a) = b { + + } + + // function call + if a() && let Some(x) = y { + + } + + // bool literal + if true && let Some(x) = y { + + } + + // cast to a bool + if 1 as bool && let Some(x) = y { + + } + + // matches! macro call + if matches!(a, some_type) && let Some(x) = y { + + } + + // block expression returning bool + if { true } && let Some(x) = y { + + } + + // field access + if a.x && let Some(x) = y { + + } +} diff --git a/tests/target/let_chains.rs b/tests/target/let_chains.rs index 36fd0ba1590..165641521cf 100644 --- a/tests/target/let_chains.rs +++ b/tests/target/let_chains.rs @@ -1,5 +1,7 @@ fn main() { - if let x = x && x {} + if let x = x + && x + {} if xxx && let x = x {} @@ -12,7 +14,10 @@ fn main() { {} if aaaaaaaaaaaaaaaaaaaaa && aaaaaaaaaaaaaaa - || aaaaaaaaa && let Some(x) = xxxxxxxxxxxx && aaaaaaa && let None = aaaaaaaaaa + || aaaaaaaaa + && let Some(x) = xxxxxxxxxxxx + && aaaaaaa + && let None = aaaaaaaaaa {} if let Some(Struct { x: TS(1, 2) }) = path::to::<_>(hehe) @@ -39,3 +44,85 @@ fn main() { todo!() } } + +fn test_single_line_let_chain() { + // first item in let-chain is an ident + if a && let Some(b) = foo() {} + + // first item in let-chain is a unary ! with an ident + let unary_not = if !from_hir_call && let Some(p) = parent {}; + + // first item in let-chain is a unary * with an ident + let unary_deref = if *some_deref && let Some(p) = parent {}; + + // first item in let-chain is a unary - (neg) with an ident + let unary_neg = if -some_ident && let Some(p) = parent {}; + + // first item in let-chain is a try (?) with an ident + let try_ = if some_try? && let Some(p) = parent {}; + + // first item in let-chain is an ident wrapped in parens + let in_parens = if (some_ident) && let Some(p) = parent {}; + + // first item in let-chain is a ref & with an ident + let _ref = if &some_ref && let Some(p) = parent {}; + + // first item in let-chain is a ref &mut with an ident + let mut_ref = if &mut some_ref && let Some(p) = parent {}; + + // chain unary ref and try + let chain_of_unary_ref_and_try = if !&*some_ref? && let Some(p) = parent {}; +} + +fn test_multi_line_let_chain() { + // Can only single line the let-chain if the first item is an ident + if let Some(x) = y + && a + {} + + // More than one let-chain must be formatted on multiple lines + if let Some(x) = y + && let Some(a) = b + {} + + // The ident isn't long enough so we don't wrap the first let-chain + if a && let Some(x) = y + && let Some(a) = b + {} + + // The ident is long enough so both let-chains are wrapped + if aaa + && let Some(x) = y + && let Some(a) = b + {} + + // function call + if a() + && let Some(x) = y + {} + + // bool literal + if true + && let Some(x) = y + {} + + // cast to a bool + if 1 as bool + && let Some(x) = y + {} + + // matches! macro call + if matches!(a, some_type) + && let Some(x) = y + {} + + // block expression returning bool + if { true } + && let Some(x) = y + {} + + // field access + if a.x + && let Some(x) = y + {} +} -- cgit 1.4.1-3-g733a5