diff --git a/src/chains.rs b/src/chains.rs index ac14ec9e110..ae6fc659539 100644 --- a/src/chains.rs +++ b/src/chains.rs @@ -442,7 +442,7 @@ impl Rewrite for Chain { formatter.format_root(&self.parent, context, shape)?; if let Some(result) = formatter.pure_root() { - return wrap_str(result, context.config.max_width(), shape); + return wrap_str(result, context.config, shape); } // Decide how to layout the rest of the chain. @@ -452,7 +452,7 @@ impl Rewrite for Chain { formatter.format_last_child(context, shape, child_shape)?; let result = formatter.join_rewrites(context, child_shape)?; - wrap_str(result, context.config.max_width(), shape) + wrap_str(result, context.config, shape) } } @@ -813,7 +813,7 @@ 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) { + match wrap_str(rewrite, context.config, shape) { Some(rewrite) => root_rewrite.push_str(&rewrite), None => { // We couldn't fit in at the visual indent, try the last diff --git a/src/comment.rs b/src/comment.rs index 0264a90c7d0..743f87f51ab 100644 --- a/src/comment.rs +++ b/src/comment.rs @@ -5,7 +5,7 @@ use std::{self, borrow::Cow, iter}; use itertools::{multipeek, MultiPeek}; use rustc_span::Span; -use crate::config::Config; +use crate::config::{Config, Version}; use crate::rewrite::RewriteContext; use crate::shape::{Indent, Shape}; use crate::string::{rewrite_string, StringFormat}; @@ -1364,13 +1364,15 @@ where pub(crate) struct LineClasses<'a> { base: iter::Peekable>>, kind: FullCodeCharKind, + config_version: Version, } impl<'a> LineClasses<'a> { - pub(crate) fn new(s: &'a str) -> Self { + pub(crate) fn new(s: &'a str, config_version: Version) -> Self { LineClasses { base: CharClasses::new(s.chars()).peekable(), kind: FullCodeCharKind::Normal, + config_version, } } } @@ -1388,7 +1390,9 @@ impl<'a> Iterator for LineClasses<'a> { None => unreachable!(), }; + let mut prev_kind = FullCodeCharKind::Normal; while let Some((kind, c)) = self.base.next() { + prev_kind = self.kind; // needed to set the kind of the ending character on the last line self.kind = kind; if c == '\n' { @@ -1405,6 +1409,12 @@ impl<'a> Iterator for LineClasses<'a> { (FullCodeCharKind::InStringCommented, FullCodeCharKind::InComment) => { FullCodeCharKind::EndStringCommented } + (_, FullCodeCharKind::Normal) + if prev_kind == FullCodeCharKind::EndComment + && self.config_version == Version::Two => + { + FullCodeCharKind::EndComment + } _ => kind, }; break; @@ -1585,9 +1595,9 @@ pub(crate) fn recover_comment_removed( } } -pub(crate) fn filter_normal_code(code: &str) -> String { +pub(crate) fn filter_normal_code(code: &str, config_version: Version) -> String { let mut buffer = String::with_capacity(code.len()); - LineClasses::new(code).for_each(|(kind, line)| match kind { + LineClasses::new(code, config_version).for_each(|(kind, line)| match kind { FullCodeCharKind::Normal | FullCodeCharKind::StartString | FullCodeCharKind::InString @@ -1905,13 +1915,32 @@ fn main() { println!("hello, world"); } "#; - assert_eq!(s, filter_normal_code(s)); - let s_with_comment = r#" + assert_eq!(s, filter_normal_code(s, Version::Two)); + let s_with_line_comment = r#" fn main() { // hello, world println!("hello, world"); } "#; - assert_eq!(s, filter_normal_code(s_with_comment)); + assert_eq!(s, filter_normal_code(s_with_line_comment, Version::Two)); + let s_with_block_comment = r#" +fn main() { + /* hello, world */ + println!("hello, world"); +} +"#; + assert_eq!(s, filter_normal_code(s_with_block_comment, Version::Two)); + let s_with_multi_line_comment = r#" +fn main() { + /* hello, + * world + */ + println!("hello, world"); +} +"#; + assert_eq!( + s, + filter_normal_code(s_with_multi_line_comment, Version::Two) + ); } } diff --git a/src/expr.rs b/src/expr.rs index d3fd22653b4..6c3a67d630f 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -198,13 +198,8 @@ pub(crate) fn format_expr( rewrite_chain(expr, context, shape) } ast::ExprKind::MacCall(ref mac) => { - rewrite_macro(mac, None, context, shape, MacroPosition::Expression).or_else(|| { - wrap_str( - context.snippet(expr.span).to_owned(), - context.config.max_width(), - shape, - ) - }) + rewrite_macro(mac, None, context, shape, MacroPosition::Expression) + .or_else(|| wrap_str(context.snippet(expr.span).to_owned(), context.config, shape)) } ast::ExprKind::Ret(None) => Some("return".to_owned()), ast::ExprKind::Ret(Some(ref expr)) => { @@ -1187,11 +1182,7 @@ pub(crate) fn rewrite_literal( ) -> Option { match l.kind { ast::LitKind::Str(_, ast::StrStyle::Cooked) => rewrite_string_lit(context, l.span, shape), - _ => wrap_str( - context.snippet(l.span).to_owned(), - context.config.max_width(), - shape, - ), + _ => wrap_str(context.snippet(l.span).to_owned(), context.config, shape), } } @@ -1207,7 +1198,7 @@ fn rewrite_string_lit(context: &RewriteContext<'_>, span: Span, shape: Shape) -> { return Some(string_lit.to_owned()); } else { - return wrap_str(string_lit.to_owned(), context.config.max_width(), shape); + return wrap_str(string_lit.to_owned(), context.config, shape); } } @@ -1971,8 +1962,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 wrap_str(new_rhs.clone(), context.config, new_shape).is_none() => { Some(format!("{}{}", before_space_str, orig_rhs)) } diff --git a/src/lib.rs b/src/lib.rs index db48b52f440..b72535cef56 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -348,7 +348,7 @@ fn format_code_block( let mut result = String::with_capacity(s.len() * 2); result.push_str(FN_MAIN_PREFIX); let mut need_indent = true; - for (kind, line) in LineClasses::new(s) { + for (kind, line) in LineClasses::new(s, config.version()) { if need_indent { result.push_str(&indent.to_string(config)); } @@ -385,7 +385,10 @@ fn format_code_block( .unwrap_or_else(|| formatted.snippet.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[FN_MAIN_PREFIX.len()..block_len], + config.version(), + ) { if !is_first { result.push('\n'); } else { diff --git a/src/macros.rs b/src/macros.rs index 190f4b599b0..bcce577bc4d 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -1372,15 +1372,11 @@ impl MacroBranch { } } }; - let new_body = wrap_str( - new_body_snippet.snippet.to_string(), - config.max_width(), - shape, - )?; + let new_body = wrap_str(new_body_snippet.snippet.to_string(), &config, shape)?; // 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.trim_end(), config.version()) .enumerate() .fold( (String::new(), true), diff --git a/src/pairs.rs b/src/pairs.rs index 0f3d5e8f878..55ad1a7400a 100644 --- a/src/pairs.rs +++ b/src/pairs.rs @@ -86,7 +86,7 @@ fn rewrite_pairs_one_line( return None; } - wrap_str(result, context.config.max_width(), shape) + wrap_str(result, context.config, shape) } fn rewrite_pairs_multiline( diff --git a/src/string.rs b/src/string.rs index 080c4f17788..c9bda5b8af7 100644 --- a/src/string.rs +++ b/src/string.rs @@ -150,7 +150,7 @@ pub(crate) fn rewrite_string<'a>( } result.push_str(fmt.closer); - wrap_str(result, fmt.config.max_width(), fmt.shape) + wrap_str(result, fmt.config, fmt.shape) } /// Returns the index to the end of the URL if the split at index of the given string includes an diff --git a/src/utils.rs b/src/utils.rs index d3c349fb701..3562ce902b0 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -394,8 +394,12 @@ 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) { +pub(crate) fn wrap_str(s: String, config: &Config, shape: Shape) -> Option { + if is_valid_str( + &filter_normal_code(&s, config.version()), + config.max_width(), + shape, + ) { Some(s) } else { None @@ -583,7 +587,7 @@ pub(crate) fn trim_left_preserve_layout( indent: Indent, config: &Config, ) -> Option { - let mut lines = LineClasses::new(orig); + let mut lines = LineClasses::new(orig, config.version()); let first_line = lines.next().map(|(_, s)| s.trim_end().to_owned())?; let mut trimmed_lines = Vec::with_capacity(16); diff --git a/tests/source/issue-4668.rs b/tests/source/issue-4668.rs new file mode 100644 index 00000000000..45f53afc7df --- /dev/null +++ b/tests/source/issue-4668.rs @@ -0,0 +1,46 @@ +// rustfmt-version: Two + +const C: usize = 0_usize; +const U: usize = /* A long block-style comment A long block-style comment A long block-style comment A long block-style comment */ if C > 0 { 4 } else { 3 }; + +fn f() { + fn g() -> int { + let foo = 12; + match foo { + 0..=10 => { + /* Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin urna felis, molestie ex. */ + } + _ => { + let st = None; + let res = st.unwrap_or( + /* Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin urna felis, molestie ex. */ "abc" + ); + } + } + } +} + +fn h() { + let mut y = 0; + while let x = vec![1, 2, 3] + .iter() + /* Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin urna felis, molestie ex... */ + .take(3) + .skip(1) + .to_owned() + .next() + { + y += x.unwrap_or_else(|/* Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin urna felis, molestie ex... */_| &0) * 2; + } +} + +pub fn t(x: int) { + if x == 3 { + let y = match context { + True => { + |x| /* Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin urna felis, molestie ex... */ x+2 + } + False => |x| x, + }; + } else {} +} diff --git a/tests/target/issue-4668.rs b/tests/target/issue-4668.rs new file mode 100644 index 00000000000..75d67c933d5 --- /dev/null +++ b/tests/target/issue-4668.rs @@ -0,0 +1,53 @@ +// rustfmt-version: Two + +const C: usize = 0_usize; +const U: usize = + /* A long block-style comment A long block-style comment A long block-style comment A long block-style comment */ + if C > 0 { 4 } else { 3 }; + +fn f() { + fn g() -> int { + let foo = 12; + match foo { + 0..=10 => { + /* Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin urna felis, molestie ex. */ + } + _ => { + let st = None; + let res = st.unwrap_or( + /* Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin urna felis, molestie ex. */ + "abc", + ); + } + } + } +} + +fn h() { + let mut y = 0; + while let x = vec![1, 2, 3] + .iter() + /* Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin urna felis, molestie ex... */ + .take(3) + .skip(1) + .to_owned() + .next() + { + y += x.unwrap_or_else( + |/* Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin urna felis, molestie ex... */ + _| &0, + ) * 2; + } +} + +pub fn t(x: int) { + if x == 3 { + let y = match context { + True => { + |x| /* Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin urna felis, molestie ex... */ x+2 + } + False => |x| x, + }; + } else { + } +}