1
1
use clippy_utils:: diagnostics:: span_lint_and_sugg;
2
- use clippy_utils:: source:: snippet_with_context;
2
+ use clippy_utils:: source:: { snippet_with_applicability, snippet_with_context} ;
3
+ use clippy_utils:: sugg:: Sugg ;
3
4
use clippy_utils:: ty:: { is_type_diagnostic_item, is_type_lang_item, match_type} ;
4
5
use clippy_utils:: { is_expr_path_def_path, paths} ;
5
6
use if_chain:: if_chain;
6
- use rustc_ast:: util:: parser:: PREC_POSTFIX ;
7
7
use rustc_ast:: LitKind ;
8
8
use rustc_errors:: Applicability ;
9
9
use rustc_hir:: { Expr , ExprKind , LangItem } ;
10
10
use rustc_lint:: LateContext ;
11
11
use rustc_middle:: ty:: { self , Ty , TyS } ;
12
12
use rustc_span:: symbol:: { sym, Symbol } ;
13
+ use std:: borrow:: Cow ;
13
14
14
15
use super :: MANUAL_STR_REPEAT ;
15
16
16
17
enum RepeatKind {
17
- Str ,
18
18
String ,
19
- Char ,
19
+ Char ( char ) ,
20
20
}
21
21
22
22
fn get_ty_param ( ty : Ty < ' _ > ) -> Option < Ty < ' _ > > {
@@ -30,8 +30,8 @@ fn get_ty_param(ty: Ty<'_>) -> Option<Ty<'_>> {
30
30
fn parse_repeat_arg ( cx : & LateContext < ' _ > , e : & Expr < ' _ > ) -> Option < RepeatKind > {
31
31
if let ExprKind :: Lit ( lit) = & e. kind {
32
32
match lit. node {
33
- LitKind :: Str ( ..) => Some ( RepeatKind :: Str ) ,
34
- LitKind :: Char ( _ ) => Some ( RepeatKind :: Char ) ,
33
+ LitKind :: Str ( ..) => Some ( RepeatKind :: String ) ,
34
+ LitKind :: Char ( c ) => Some ( RepeatKind :: Char ( c ) ) ,
35
35
_ => None ,
36
36
}
37
37
} else {
@@ -43,7 +43,7 @@ fn parse_repeat_arg(cx: &LateContext<'_>, e: &Expr<'_>) -> Option<RepeatKind> {
43
43
Some ( RepeatKind :: String )
44
44
} else {
45
45
let ty = ty. peel_refs ( ) ;
46
- ( ty. is_str ( ) || is_type_diagnostic_item ( cx, ty, sym:: string_type) ) . then ( || RepeatKind :: Str )
46
+ ( ty. is_str ( ) || is_type_diagnostic_item ( cx, ty, sym:: string_type) ) . then ( || RepeatKind :: String )
47
47
}
48
48
}
49
49
}
@@ -68,17 +68,19 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, method_name: Symbol,
68
68
if ctxt == repeat_expr. span. ctxt( ) ;
69
69
then {
70
70
let mut app = Applicability :: MachineApplicable ;
71
- let ( val_snip, val_is_mac) = snippet_with_context( cx, repeat_arg. span, ctxt, ".." , & mut app) ;
72
71
let count_snip = snippet_with_context( cx, take_arg. span, ctxt, ".." , & mut app) . 0 ;
73
72
74
73
let val_str = match repeat_kind {
75
- RepeatKind :: Str if !val_is_mac && repeat_arg. precedence( ) . order( ) < PREC_POSTFIX => {
76
- format!( "({})" , val_snip)
77
- } ,
78
- RepeatKind :: Str | RepeatKind :: String => val_snip. into( ) ,
79
- RepeatKind :: Char if val_snip == r#"'"'"# => r#""\"""# . into( ) ,
80
- RepeatKind :: Char if val_snip == r#"'\''"# => r#""'""# . into( ) ,
81
- RepeatKind :: Char => format!( "\" {}\" " , & val_snip[ 1 ..val_snip. len( ) - 1 ] ) ,
74
+ RepeatKind :: Char ( _) if repeat_arg. span. ctxt( ) != ctxt => return ,
75
+ RepeatKind :: Char ( '\'' ) => r#""'""# . into( ) ,
76
+ RepeatKind :: Char ( '"' ) => r#""\"""# . into( ) ,
77
+ RepeatKind :: Char ( _) =>
78
+ match snippet_with_applicability( cx, repeat_arg. span, ".." , & mut app) {
79
+ Cow :: Owned ( s) => Cow :: Owned ( format!( "\" {}\" " , & s[ 1 ..s. len( ) - 1 ] ) ) ,
80
+ s @ Cow :: Borrowed ( _) => s,
81
+ } ,
82
+ RepeatKind :: String =>
83
+ Sugg :: hir_with_context( cx, repeat_arg, ctxt, ".." , & mut app) . maybe_par( ) . to_string( ) . into( ) ,
82
84
} ;
83
85
84
86
span_lint_and_sugg(
0 commit comments