@@ -19,6 +19,7 @@ pub mod paths;
1919pub mod ptr;
2020pub mod sugg;
2121pub mod usage;
22+
2223pub use self :: attrs:: * ;
2324pub use self :: diagnostics:: * ;
2425pub use self :: hir_utils:: { both, eq_expr_value, over, SpanlessEq , SpanlessHash } ;
@@ -108,6 +109,7 @@ pub fn in_macro(span: Span) -> bool {
108109 false
109110 }
110111}
112+
111113// If the snippet is empty, it's an attribute that was inserted during macro
112114// expansion and we want to ignore those, because they could come from external
113115// sources that the user has no control over.
@@ -571,7 +573,7 @@ pub fn snippet_block<'a, T: LintContext>(
571573) -> Cow < ' a , str > {
572574 let snip = snippet ( cx, span, default) ;
573575 let indent = indent_relative_to. and_then ( |s| indent_of ( cx, s) ) ;
574- trim_multiline ( snip, true , indent)
576+ reindent_multiline ( snip, true , indent)
575577}
576578
577579/// Same as `snippet_block`, but adapts the applicability level by the rules of
@@ -585,7 +587,7 @@ pub fn snippet_block_with_applicability<'a, T: LintContext>(
585587) -> Cow < ' a , str > {
586588 let snip = snippet_with_applicability ( cx, span, default, applicability) ;
587589 let indent = indent_relative_to. and_then ( |s| indent_of ( cx, s) ) ;
588- trim_multiline ( snip, true , indent)
590+ reindent_multiline ( snip, true , indent)
589591}
590592
591593/// Returns a new Span that extends the original Span to the first non-whitespace char of the first
@@ -661,16 +663,16 @@ pub fn expr_block<'a, T: LintContext>(
661663 }
662664}
663665
664- /// Trim indentation from a multiline string with possibility of ignoring the
665- /// first line.
666- pub fn trim_multiline ( s : Cow < ' _ , str > , ignore_first : bool , indent : Option < usize > ) -> Cow < ' _ , str > {
667- let s_space = trim_multiline_inner ( s, ignore_first, indent, ' ' ) ;
668- let s_tab = trim_multiline_inner ( s_space, ignore_first, indent, '\t' ) ;
669- trim_multiline_inner ( s_tab, ignore_first, indent, ' ' )
666+ /// Reindent a multiline string with possibility of ignoring the first line.
667+ # [ allow ( clippy :: needless_pass_by_value ) ]
668+ pub fn reindent_multiline ( s : Cow < ' _ , str > , ignore_first : bool , indent : Option < usize > ) -> Cow < ' _ , str > {
669+ let s_space = reindent_multiline_inner ( & s, ignore_first, indent, ' ' ) ;
670+ let s_tab = reindent_multiline_inner ( & s_space, ignore_first, indent, '\t' ) ;
671+ reindent_multiline_inner ( & s_tab, ignore_first, indent, ' ' ) . into ( )
670672}
671673
672- fn trim_multiline_inner ( s : Cow < ' _ , str > , ignore_first : bool , indent : Option < usize > , ch : char ) -> Cow < ' _ , str > {
673- let mut x = s
674+ fn reindent_multiline_inner ( s : & str , ignore_first : bool , indent : Option < usize > , ch : char ) -> String {
675+ let x = s
674676 . lines ( )
675677 . skip ( ignore_first as usize )
676678 . filter_map ( |l| {
@@ -683,26 +685,20 @@ fn trim_multiline_inner(s: Cow<'_, str>, ignore_first: bool, indent: Option<usiz
683685 } )
684686 . min ( )
685687 . unwrap_or ( 0 ) ;
686- if let Some ( indent) = indent {
687- x = x. saturating_sub ( indent) ;
688- }
689- if x > 0 {
690- Cow :: Owned (
691- s. lines ( )
692- . enumerate ( )
693- . map ( |( i, l) | {
694- if ( ignore_first && i == 0 ) || l. is_empty ( ) {
695- l
696- } else {
697- l. split_at ( x) . 1
698- }
699- } )
700- . collect :: < Vec < _ > > ( )
701- . join ( "\n " ) ,
702- )
703- } else {
704- s
705- }
688+ let indent = indent. unwrap_or ( 0 ) ;
689+ s. lines ( )
690+ . enumerate ( )
691+ . map ( |( i, l) | {
692+ if ( ignore_first && i == 0 ) || l. is_empty ( ) {
693+ l. to_owned ( )
694+ } else if x > indent {
695+ l. split_at ( x - indent) . 1 . to_owned ( )
696+ } else {
697+ " " . repeat ( indent - x) + l
698+ }
699+ } )
700+ . collect :: < Vec < String > > ( )
701+ . join ( "\n " )
706702}
707703
708704/// Gets the parent expression, if any –- this is useful to constrain a lint.
@@ -1475,26 +1471,26 @@ macro_rules! unwrap_cargo_metadata {
14751471
14761472#[ cfg( test) ]
14771473mod test {
1478- use super :: { trim_multiline , without_block_comments} ;
1474+ use super :: { reindent_multiline , without_block_comments} ;
14791475
14801476 #[ test]
1481- fn test_trim_multiline_single_line ( ) {
1482- assert_eq ! ( "" , trim_multiline ( "" . into( ) , false , None ) ) ;
1483- assert_eq ! ( "..." , trim_multiline ( "..." . into( ) , false , None ) ) ;
1484- assert_eq ! ( "..." , trim_multiline ( " ..." . into( ) , false , None ) ) ;
1485- assert_eq ! ( "..." , trim_multiline ( "\t ..." . into( ) , false , None ) ) ;
1486- assert_eq ! ( "..." , trim_multiline ( "\t \t ..." . into( ) , false , None ) ) ;
1477+ fn test_reindent_multiline_single_line ( ) {
1478+ assert_eq ! ( "" , reindent_multiline ( "" . into( ) , false , None ) ) ;
1479+ assert_eq ! ( "..." , reindent_multiline ( "..." . into( ) , false , None ) ) ;
1480+ assert_eq ! ( "..." , reindent_multiline ( " ..." . into( ) , false , None ) ) ;
1481+ assert_eq ! ( "..." , reindent_multiline ( "\t ..." . into( ) , false , None ) ) ;
1482+ assert_eq ! ( "..." , reindent_multiline ( "\t \t ..." . into( ) , false , None ) ) ;
14871483 }
14881484
14891485 #[ test]
14901486 #[ rustfmt:: skip]
1491- fn test_trim_multiline_block ( ) {
1487+ fn test_reindent_multiline_block ( ) {
14921488 assert_eq ! ( "\
14931489 if x {
14941490 y
14951491 } else {
14961492 z
1497- }" , trim_multiline ( " if x {
1493+ }" , reindent_multiline ( " if x {
14981494 y
14991495 } else {
15001496 z
@@ -1504,7 +1500,7 @@ mod test {
15041500 \t y
15051501 } else {
15061502 \t z
1507- }" , trim_multiline ( " if x {
1503+ }" , reindent_multiline ( " if x {
15081504 \t y
15091505 } else {
15101506 \t z
@@ -1513,21 +1509,37 @@ mod test {
15131509
15141510 #[ test]
15151511 #[ rustfmt:: skip]
1516- fn test_trim_multiline_empty_line ( ) {
1512+ fn test_reindent_multiline_empty_line ( ) {
15171513 assert_eq ! ( "\
15181514 if x {
15191515 y
15201516
15211517 } else {
15221518 z
1523- }" , trim_multiline ( " if x {
1519+ }" , reindent_multiline ( " if x {
15241520 y
15251521
15261522 } else {
15271523 z
15281524 }" . into( ) , false , None ) ) ;
15291525 }
15301526
1527+ #[ test]
1528+ #[ rustfmt:: skip]
1529+ fn test_reindent_multiline_lines_deeper ( ) {
1530+ assert_eq ! ( "\
1531+ if x {
1532+ y
1533+ } else {
1534+ z
1535+ }" , reindent_multiline( "\
1536+ if x {
1537+ y
1538+ } else {
1539+ z
1540+ }" . into( ) , true , Some ( 8 ) ) ) ;
1541+ }
1542+
15311543 #[ test]
15321544 fn test_without_block_comments_lines_without_block_comments ( ) {
15331545 let result = without_block_comments ( vec ! [ "/*" , "" , "*/" ] ) ;
0 commit comments