@@ -19,6 +19,7 @@ pub mod paths;
19
19
pub mod ptr;
20
20
pub mod sugg;
21
21
pub mod usage;
22
+
22
23
pub use self :: attrs:: * ;
23
24
pub use self :: diagnostics:: * ;
24
25
pub use self :: hir_utils:: { both, eq_expr_value, over, SpanlessEq , SpanlessHash } ;
@@ -108,6 +109,7 @@ pub fn in_macro(span: Span) -> bool {
108
109
false
109
110
}
110
111
}
112
+
111
113
// If the snippet is empty, it's an attribute that was inserted during macro
112
114
// expansion and we want to ignore those, because they could come from external
113
115
// sources that the user has no control over.
@@ -571,7 +573,7 @@ pub fn snippet_block<'a, T: LintContext>(
571
573
) -> Cow < ' a , str > {
572
574
let snip = snippet ( cx, span, default) ;
573
575
let indent = indent_relative_to. and_then ( |s| indent_of ( cx, s) ) ;
574
- trim_multiline ( snip, true , indent)
576
+ reindent_multiline ( snip, true , indent)
575
577
}
576
578
577
579
/// 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>(
585
587
) -> Cow < ' a , str > {
586
588
let snip = snippet_with_applicability ( cx, span, default, applicability) ;
587
589
let indent = indent_relative_to. and_then ( |s| indent_of ( cx, s) ) ;
588
- trim_multiline ( snip, true , indent)
590
+ reindent_multiline ( snip, true , indent)
589
591
}
590
592
591
593
/// 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>(
661
663
}
662
664
}
663
665
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 ( )
670
672
}
671
673
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
674
676
. lines ( )
675
677
. skip ( ignore_first as usize )
676
678
. filter_map ( |l| {
@@ -683,26 +685,20 @@ fn trim_multiline_inner(s: Cow<'_, str>, ignore_first: bool, indent: Option<usiz
683
685
} )
684
686
. min ( )
685
687
. 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 " )
706
702
}
707
703
708
704
/// Gets the parent expression, if any –- this is useful to constrain a lint.
@@ -1475,26 +1471,26 @@ macro_rules! unwrap_cargo_metadata {
1475
1471
1476
1472
#[ cfg( test) ]
1477
1473
mod test {
1478
- use super :: { trim_multiline , without_block_comments} ;
1474
+ use super :: { reindent_multiline , without_block_comments} ;
1479
1475
1480
1476
#[ 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 ) ) ;
1487
1483
}
1488
1484
1489
1485
#[ test]
1490
1486
#[ rustfmt:: skip]
1491
- fn test_trim_multiline_block ( ) {
1487
+ fn test_reindent_multiline_block ( ) {
1492
1488
assert_eq ! ( "\
1493
1489
if x {
1494
1490
y
1495
1491
} else {
1496
1492
z
1497
- }" , trim_multiline ( " if x {
1493
+ }" , reindent_multiline ( " if x {
1498
1494
y
1499
1495
} else {
1500
1496
z
@@ -1504,7 +1500,7 @@ mod test {
1504
1500
\t y
1505
1501
} else {
1506
1502
\t z
1507
- }" , trim_multiline ( " if x {
1503
+ }" , reindent_multiline ( " if x {
1508
1504
\t y
1509
1505
} else {
1510
1506
\t z
@@ -1513,21 +1509,37 @@ mod test {
1513
1509
1514
1510
#[ test]
1515
1511
#[ rustfmt:: skip]
1516
- fn test_trim_multiline_empty_line ( ) {
1512
+ fn test_reindent_multiline_empty_line ( ) {
1517
1513
assert_eq ! ( "\
1518
1514
if x {
1519
1515
y
1520
1516
1521
1517
} else {
1522
1518
z
1523
- }" , trim_multiline ( " if x {
1519
+ }" , reindent_multiline ( " if x {
1524
1520
y
1525
1521
1526
1522
} else {
1527
1523
z
1528
1524
}" . into( ) , false , None ) ) ;
1529
1525
}
1530
1526
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
+
1531
1543
#[ test]
1532
1544
fn test_without_block_comments_lines_without_block_comments ( ) {
1533
1545
let result = without_block_comments ( vec ! [ "/*" , "" , "*/" ] ) ;
0 commit comments