@@ -93,12 +93,12 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
93
93
if arg_macro. map_or ( false , |id| cx. tcx . is_diagnostic_item ( sym:: format_macro, id) ) {
94
94
// A case of `panic!(format!(..))`.
95
95
l. note ( "the panic!() macro supports formatting, so there's no need for the format!() macro here" ) ;
96
- if let Some ( inner ) = find_inner_span ( cx, arg_span) {
96
+ if let Some ( ( open , close , _ ) ) = find_delimiters ( cx, arg_span) {
97
97
l. multipart_suggestion (
98
98
"remove the `format!(..)` macro call" ,
99
99
vec ! [
100
- ( arg_span. until( inner ) , "" . into( ) ) ,
101
- ( inner . between ( arg_span. shrink_to_hi( ) ) , "" . into( ) ) ,
100
+ ( arg_span. until( open . shrink_to_hi ( ) ) , "" . into( ) ) ,
101
+ ( close . until ( arg_span. shrink_to_hi( ) ) , "" . into( ) ) ,
102
102
] ,
103
103
Applicability :: MachineApplicable ,
104
104
) ;
@@ -111,12 +111,20 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
111
111
Applicability :: MaybeIncorrect ,
112
112
) ;
113
113
if panic == sym:: std_panic_macro {
114
- l. span_suggestion_verbose (
115
- span. until ( arg_span) ,
116
- "or use std::panic::panic_any instead" ,
117
- "std::panic::panic_any(" . into ( ) ,
118
- Applicability :: MachineApplicable ,
119
- ) ;
114
+ if let Some ( ( open, close, del) ) = find_delimiters ( cx, span) {
115
+ l. multipart_suggestion (
116
+ "or use std::panic::panic_any instead" ,
117
+ if del == '(' {
118
+ vec ! [ ( span. until( open) , "std::panic::panic_any" . into( ) ) ]
119
+ } else {
120
+ vec ! [
121
+ ( span. until( open. shrink_to_hi( ) ) , "std::panic::panic_any(" . into( ) ) ,
122
+ ( close, ")" . into( ) ) ,
123
+ ]
124
+ } ,
125
+ Applicability :: MachineApplicable ,
126
+ ) ;
127
+ }
120
128
}
121
129
}
122
130
l. emit ( ) ;
@@ -206,13 +214,23 @@ fn check_panic_str<'tcx>(
206
214
}
207
215
}
208
216
209
- /// Given the span of `some_macro!(args)`, gives the span of `args`.
210
- fn find_inner_span < ' tcx > ( cx : & LateContext < ' tcx > , span : Span ) -> Option < Span > {
217
+ /// Given the span of `some_macro!(args);`, gives the span of `(` and `)`,
218
+ /// and the type of (opening) delimiter used.
219
+ fn find_delimiters < ' tcx > ( cx : & LateContext < ' tcx > , span : Span ) -> Option < ( Span , Span , char ) > {
211
220
let snippet = cx. sess ( ) . parse_sess . source_map ( ) . span_to_snippet ( span) . ok ( ) ?;
212
- Some ( span. from_inner ( InnerSpan {
213
- start : snippet. find ( & [ '(' , '{' , '[' ] [ ..] ) ? + 1 ,
214
- end : snippet. rfind ( & [ ')' , '}' , ']' ] [ ..] ) ?,
215
- } ) )
221
+ let ( open, open_ch) = snippet. char_indices ( ) . find ( |& ( _, c) | "([{" . contains ( c) ) ?;
222
+ let close = snippet. rfind ( |c| ")]}" . contains ( c) ) ?;
223
+ Some ( (
224
+ span. from_inner ( InnerSpan {
225
+ start : open,
226
+ end : open + 1 ,
227
+ } ) ,
228
+ span. from_inner ( InnerSpan {
229
+ start : close,
230
+ end : close + 1 ,
231
+ } ) ,
232
+ open_ch,
233
+ ) )
216
234
}
217
235
218
236
fn panic_call < ' tcx > ( cx : & LateContext < ' tcx > , f : & ' tcx hir:: Expr < ' tcx > ) -> ( Span , Symbol ) {
0 commit comments