Fix handling of code that is annotated with rustfmt::skip.
A rustfmt::skip'ed block is indented although original lines are returned. In order to resolve this, the leading whitespaces are trimmed on each line while retaining the layout; this leaves the skipped code to be indented as necessary by the caller.
This commit is contained in:
parent
4789f65041
commit
9c75a15f4c
@ -19,7 +19,7 @@ use config::Config;
|
|||||||
use rewrite::RewriteContext;
|
use rewrite::RewriteContext;
|
||||||
use shape::{Indent, Shape};
|
use shape::{Indent, Shape};
|
||||||
use string::{rewrite_string, StringFormat};
|
use string::{rewrite_string, StringFormat};
|
||||||
use utils::{count_newlines, first_line_width, last_line_width};
|
use utils::{count_newlines, first_line_width, last_line_width, trim_left_preserve_layout};
|
||||||
use {ErrorKind, FormattingError};
|
use {ErrorKind, FormattingError};
|
||||||
|
|
||||||
fn is_custom_comment(comment: &str) -> bool {
|
fn is_custom_comment(comment: &str) -> bool {
|
||||||
@ -332,12 +332,12 @@ fn identify_comment(
|
|||||||
let (first_group, rest) = orig.split_at(first_group_ending);
|
let (first_group, rest) = orig.split_at(first_group_ending);
|
||||||
let rewritten_first_group =
|
let rewritten_first_group =
|
||||||
if !config.normalize_comments() && has_bare_lines && style.is_block_comment() {
|
if !config.normalize_comments() && has_bare_lines && style.is_block_comment() {
|
||||||
light_rewrite_block_comment_with_bare_lines(first_group, shape, config)?
|
trim_left_preserve_layout(first_group, &shape.indent, config)
|
||||||
} else if !config.normalize_comments()
|
} else if !config.normalize_comments()
|
||||||
&& !config.wrap_comments()
|
&& !config.wrap_comments()
|
||||||
&& !config.format_doc_comments()
|
&& !config.format_doc_comments()
|
||||||
{
|
{
|
||||||
light_rewrite_comment(first_group, shape.indent, config, is_doc_comment)?
|
light_rewrite_comment(first_group, shape.indent, config, is_doc_comment)
|
||||||
} else {
|
} else {
|
||||||
rewrite_comment_inner(
|
rewrite_comment_inner(
|
||||||
first_group,
|
first_group,
|
||||||
@ -370,47 +370,6 @@ fn identify_comment(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Trims a minimum of leading whitespaces so that the content layout is kept and aligns to indent.
|
|
||||||
fn light_rewrite_block_comment_with_bare_lines(
|
|
||||||
orig: &str,
|
|
||||||
shape: Shape,
|
|
||||||
config: &Config,
|
|
||||||
) -> Option<String> {
|
|
||||||
let prefix_whitespace_min = orig
|
|
||||||
.lines()
|
|
||||||
// skip the line with the starting sigil since the leading whitespace is removed
|
|
||||||
// otherwise, the minimum would always be zero
|
|
||||||
.skip(1)
|
|
||||||
.filter(|line| !line.is_empty())
|
|
||||||
.map(|line| {
|
|
||||||
let mut width = 0;
|
|
||||||
for c in line.chars() {
|
|
||||||
match c {
|
|
||||||
' ' => width += 1,
|
|
||||||
'\t' => width += config.tab_spaces(),
|
|
||||||
_ => break,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
width
|
|
||||||
})
|
|
||||||
.min()?;
|
|
||||||
|
|
||||||
let indent_str = shape.indent.to_string(config);
|
|
||||||
let mut lines = orig.lines();
|
|
||||||
let first_line = lines.next()?;
|
|
||||||
let rest = lines
|
|
||||||
.map(|line| {
|
|
||||||
if line.is_empty() {
|
|
||||||
line
|
|
||||||
} else {
|
|
||||||
&line[prefix_whitespace_min..]
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect::<Vec<&str>>()
|
|
||||||
.join(&format!("\n{}", indent_str));
|
|
||||||
Some(format!("{}\n{}{}", first_line, indent_str, rest))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Attributes for code blocks in rustdoc.
|
/// Attributes for code blocks in rustdoc.
|
||||||
/// See https://doc.rust-lang.org/rustdoc/print.html#attributes
|
/// See https://doc.rust-lang.org/rustdoc/print.html#attributes
|
||||||
enum CodeBlockAttribute {
|
enum CodeBlockAttribute {
|
||||||
@ -912,7 +871,7 @@ fn light_rewrite_comment(
|
|||||||
offset: Indent,
|
offset: Indent,
|
||||||
config: &Config,
|
config: &Config,
|
||||||
is_doc_comment: bool,
|
is_doc_comment: bool,
|
||||||
) -> Option<String> {
|
) -> String {
|
||||||
let lines: Vec<&str> = orig
|
let lines: Vec<&str> = orig
|
||||||
.lines()
|
.lines()
|
||||||
.map(|l| {
|
.map(|l| {
|
||||||
@ -933,7 +892,7 @@ fn light_rewrite_comment(
|
|||||||
trim_right_unless_two_whitespaces(left_trimmed, is_doc_comment)
|
trim_right_unless_two_whitespaces(left_trimmed, is_doc_comment)
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
Some(lines.join(&format!("\n{}", offset.to_string(config))))
|
lines.join(&format!("\n{}", offset.to_string(config)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Trims comment characters and possibly a single space from the left of a string.
|
/// Trims comment characters and possibly a single space from the left of a string.
|
||||||
|
41
src/utils.rs
41
src/utils.rs
@ -21,8 +21,9 @@ use syntax::ptr;
|
|||||||
use syntax::source_map::{BytePos, Span, NO_EXPANSION};
|
use syntax::source_map::{BytePos, Span, NO_EXPANSION};
|
||||||
|
|
||||||
use comment::{filter_normal_code, CharClasses, FullCodeCharKind};
|
use comment::{filter_normal_code, CharClasses, FullCodeCharKind};
|
||||||
|
use config::Config;
|
||||||
use rewrite::RewriteContext;
|
use rewrite::RewriteContext;
|
||||||
use shape::Shape;
|
use shape::{Indent, Shape};
|
||||||
|
|
||||||
pub const DEPR_SKIP_ANNOTATION: &str = "rustfmt_skip";
|
pub const DEPR_SKIP_ANNOTATION: &str = "rustfmt_skip";
|
||||||
pub const SKIP_ANNOTATION: &str = "rustfmt::skip";
|
pub const SKIP_ANNOTATION: &str = "rustfmt::skip";
|
||||||
@ -482,6 +483,44 @@ pub fn remove_trailing_white_spaces(text: &str) -> String {
|
|||||||
buffer
|
buffer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Trims a minimum of leading whitespaces so that the content layout is kept and aligns to indent.
|
||||||
|
pub fn trim_left_preserve_layout(orig: &str, indent: &Indent, config: &Config) -> String {
|
||||||
|
let prefix_whitespace_min = orig
|
||||||
|
.lines()
|
||||||
|
// skip the line with the starting sigil since the leading whitespace is removed
|
||||||
|
// otherwise, the minimum would always be zero
|
||||||
|
.skip(1)
|
||||||
|
.filter(|line| !line.is_empty())
|
||||||
|
.map(|line| {
|
||||||
|
let mut width = 0;
|
||||||
|
for c in line.chars() {
|
||||||
|
match c {
|
||||||
|
' ' => width += 1,
|
||||||
|
'\t' => width += config.tab_spaces(),
|
||||||
|
_ => break,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
width
|
||||||
|
})
|
||||||
|
.min()
|
||||||
|
.unwrap_or(0);
|
||||||
|
|
||||||
|
let indent_str = indent.to_string(config);
|
||||||
|
let mut lines = orig.lines();
|
||||||
|
let first_line = lines.next().unwrap();
|
||||||
|
let rest = lines
|
||||||
|
.map(|line| {
|
||||||
|
if line.is_empty() {
|
||||||
|
String::from("\n")
|
||||||
|
} else {
|
||||||
|
format!("\n{}{}", indent_str, &line[prefix_whitespace_min..])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
.concat();
|
||||||
|
format!("{}{}", first_line, rest)
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_remove_trailing_white_spaces() {
|
fn test_remove_trailing_white_spaces() {
|
||||||
let s = " r#\"\n test\n \"#";
|
let s = " r#\"\n test\n \"#";
|
||||||
|
@ -29,7 +29,7 @@ use source_map::{LineRangeUtils, SpanUtils};
|
|||||||
use spanned::Spanned;
|
use spanned::Spanned;
|
||||||
use utils::{
|
use utils::{
|
||||||
self, contains_skip, count_newlines, inner_attributes, mk_sp, ptr_vec_to_ref_vec,
|
self, contains_skip, count_newlines, inner_attributes, mk_sp, ptr_vec_to_ref_vec,
|
||||||
rewrite_ident, DEPR_SKIP_ANNOTATION,
|
rewrite_ident, trim_left_preserve_layout, DEPR_SKIP_ANNOTATION,
|
||||||
};
|
};
|
||||||
use {ErrorKind, FormatReport, FormattingError};
|
use {ErrorKind, FormatReport, FormattingError};
|
||||||
|
|
||||||
@ -574,9 +574,16 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::needless_pass_by_value)]
|
#[allow(clippy::needless_pass_by_value)]
|
||||||
fn push_rewrite_inner(&mut self, span: Span, rewrite: Option<String>) {
|
fn push_rewrite_inner(&mut self, span: Span, rewrite: Option<String>, is_skipped: bool) {
|
||||||
if let Some(ref s) = rewrite {
|
if let Some(ref s) = rewrite {
|
||||||
self.push_str(s);
|
self.push_str(s);
|
||||||
|
} else if is_skipped {
|
||||||
|
// in case the code block (e.g., inside a macro or a doc) is skipped a minimum of
|
||||||
|
// leading whitespaces is trimmed so that the code layout is kept but allows it to
|
||||||
|
// be indented as necessary
|
||||||
|
let snippet =
|
||||||
|
trim_left_preserve_layout(self.snippet(span), &self.block_indent, self.config);
|
||||||
|
self.push_str(&snippet);
|
||||||
} else {
|
} else {
|
||||||
let snippet = self.snippet(span);
|
let snippet = self.snippet(span);
|
||||||
self.push_str(snippet);
|
self.push_str(snippet);
|
||||||
@ -586,13 +593,13 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
|
|||||||
|
|
||||||
pub fn push_rewrite(&mut self, span: Span, rewrite: Option<String>) {
|
pub fn push_rewrite(&mut self, span: Span, rewrite: Option<String>) {
|
||||||
self.format_missing_with_indent(source!(self, span).lo());
|
self.format_missing_with_indent(source!(self, span).lo());
|
||||||
self.push_rewrite_inner(span, rewrite);
|
self.push_rewrite_inner(span, rewrite, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push_skipped_with_span(&mut self, span: Span) {
|
pub fn push_skipped_with_span(&mut self, span: Span) {
|
||||||
self.format_missing_with_indent(source!(self, span).lo());
|
self.format_missing_with_indent(source!(self, span).lo());
|
||||||
let lo = self.line_number + 1;
|
let lo = self.line_number + 1;
|
||||||
self.push_rewrite_inner(span, None);
|
self.push_rewrite_inner(span, None, true);
|
||||||
let hi = self.line_number + 1;
|
let hi = self.line_number + 1;
|
||||||
self.skipped_range.push((lo, hi));
|
self.skipped_range.push((lo, hi));
|
||||||
}
|
}
|
||||||
|
30
tests/source/issue-3105.rs
Normal file
30
tests/source/issue-3105.rs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
// rustfmt-wrap_comments: true
|
||||||
|
|
||||||
|
/// ```
|
||||||
|
/// pub unsafe fn _mm256_shufflehi_epi16(a: __m256i, imm8: i32) -> __m256i {
|
||||||
|
/// let imm8 = (imm8 & 0xFF) as u8;
|
||||||
|
/// let a = a.as_i16x16();
|
||||||
|
/// macro_rules! shuffle_done {
|
||||||
|
/// ($x01:expr, $x23:expr, $x45:expr, $x67:expr) => {
|
||||||
|
/// #[cfg_attr(rustfmt, rustfmt_skip)]
|
||||||
|
/// simd_shuffle16(a, a, [
|
||||||
|
/// 0, 1, 2, 3, 4+$x01, 4+$x23, 4+$x45, 4+$x67,
|
||||||
|
/// 8, 9, 10, 11, 12+$x01, 12+$x23, 12+$x45, 12+$x67
|
||||||
|
/// ]);
|
||||||
|
/// };
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
pub unsafe fn _mm256_shufflehi_epi16(a: __m256i, imm8: i32) -> __m256i {
|
||||||
|
let imm8 = (imm8 & 0xFF) as u8;
|
||||||
|
let a = a.as_i16x16();
|
||||||
|
macro_rules! shuffle_done {
|
||||||
|
($x01:expr, $x23:expr, $x45:expr, $x67:expr) => {
|
||||||
|
#[cfg_attr(rustfmt, rustfmt_skip)]
|
||||||
|
simd_shuffle16(a, a, [
|
||||||
|
0, 1, 2, 3, 4+$x01, 4+$x23, 4+$x45, 4+$x67,
|
||||||
|
8, 9, 10, 11, 12+$x01, 12+$x23, 12+$x45, 12+$x67
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
30
tests/target/issue-3105.rs
Normal file
30
tests/target/issue-3105.rs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
// rustfmt-wrap_comments: true
|
||||||
|
|
||||||
|
/// ```
|
||||||
|
/// pub unsafe fn _mm256_shufflehi_epi16(a: __m256i, imm8: i32) -> __m256i {
|
||||||
|
/// let imm8 = (imm8 & 0xFF) as u8;
|
||||||
|
/// let a = a.as_i16x16();
|
||||||
|
/// macro_rules! shuffle_done {
|
||||||
|
/// ($x01:expr, $x23:expr, $x45:expr, $x67:expr) => {
|
||||||
|
/// #[cfg_attr(rustfmt, rustfmt_skip)]
|
||||||
|
/// simd_shuffle16(a, a, [
|
||||||
|
/// 0, 1, 2, 3, 4+$x01, 4+$x23, 4+$x45, 4+$x67,
|
||||||
|
/// 8, 9, 10, 11, 12+$x01, 12+$x23, 12+$x45, 12+$x67
|
||||||
|
/// ]);
|
||||||
|
/// };
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
pub unsafe fn _mm256_shufflehi_epi16(a: __m256i, imm8: i32) -> __m256i {
|
||||||
|
let imm8 = (imm8 & 0xFF) as u8;
|
||||||
|
let a = a.as_i16x16();
|
||||||
|
macro_rules! shuffle_done {
|
||||||
|
($x01:expr, $x23:expr, $x45:expr, $x67:expr) => {
|
||||||
|
#[cfg_attr(rustfmt, rustfmt_skip)]
|
||||||
|
simd_shuffle16(a, a, [
|
||||||
|
0, 1, 2, 3, 4+$x01, 4+$x23, 4+$x45, 4+$x67,
|
||||||
|
8, 9, 10, 11, 12+$x01, 12+$x23, 12+$x45, 12+$x67
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user