1
1
use crate :: { LateContext , LateLintPass , LintContext } ;
2
2
use rustc_ast as ast;
3
- use rustc_errors:: { pluralize , Applicability } ;
3
+ use rustc_errors:: { fluent , Applicability } ;
4
4
use rustc_hir as hir;
5
5
use rustc_infer:: infer:: TyCtxtInferExt ;
6
6
use rustc_middle:: lint:: in_external_macro;
@@ -120,20 +120,21 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
120
120
}
121
121
122
122
cx. struct_span_lint ( NON_FMT_PANICS , arg_span, |lint| {
123
- let mut l = lint. build ( "panic message is not a string literal" ) ;
124
- l. note ( & format ! ( "this usage of {}!() is deprecated; it will be a hard error in Rust 2021" , symbol) ) ;
125
- l. note ( "for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>" ) ;
123
+ let mut l = lint. build ( fluent:: lint:: non_fmt_panic) ;
124
+ l. set_arg ( "name" , symbol) ;
125
+ l. note ( fluent:: lint:: note) ;
126
+ l. note ( fluent:: lint:: more_info_note) ;
126
127
if !is_arg_inside_call ( arg_span, span) {
127
128
// No clue where this argument is coming from.
128
129
l. emit ( ) ;
129
130
return ;
130
131
}
131
132
if arg_macro. map_or ( false , |id| cx. tcx . is_diagnostic_item ( sym:: format_macro, id) ) {
132
133
// A case of `panic!(format!(..))`.
133
- l. note ( format ! ( "the {}!() macro supports formatting, so there's no need for the format!() macro here" , symbol ) . as_str ( ) ) ;
134
+ l. note ( fluent :: lint :: supports_fmt_note ) ;
134
135
if let Some ( ( open, close, _) ) = find_delimiters ( cx, arg_span) {
135
136
l. multipart_suggestion (
136
- "remove the `format!(..)` macro call" ,
137
+ fluent :: lint :: supports_fmt_suggestion ,
137
138
vec ! [
138
139
( arg_span. until( open. shrink_to_hi( ) ) , "" . into( ) ) ,
139
140
( close. until( arg_span. shrink_to_hi( ) ) , "" . into( ) ) ,
@@ -153,12 +154,18 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
153
154
) ;
154
155
155
156
let ( suggest_display, suggest_debug) = cx. tcx . infer_ctxt ( ) . enter ( |infcx| {
156
- let display = is_str || cx. tcx . get_diagnostic_item ( sym:: Display ) . map ( |t| {
157
- infcx. type_implements_trait ( t, ty, InternalSubsts :: empty ( ) , cx. param_env ) . may_apply ( )
158
- } ) == Some ( true ) ;
159
- let debug = !display && cx. tcx . get_diagnostic_item ( sym:: Debug ) . map ( |t| {
160
- infcx. type_implements_trait ( t, ty, InternalSubsts :: empty ( ) , cx. param_env ) . may_apply ( )
161
- } ) == Some ( true ) ;
157
+ let display = is_str
158
+ || cx. tcx . get_diagnostic_item ( sym:: Display ) . map ( |t| {
159
+ infcx
160
+ . type_implements_trait ( t, ty, InternalSubsts :: empty ( ) , cx. param_env )
161
+ . may_apply ( )
162
+ } ) == Some ( true ) ;
163
+ let debug = !display
164
+ && cx. tcx . get_diagnostic_item ( sym:: Debug ) . map ( |t| {
165
+ infcx
166
+ . type_implements_trait ( t, ty, InternalSubsts :: empty ( ) , cx. param_env )
167
+ . may_apply ( )
168
+ } ) == Some ( true ) ;
162
169
( display, debug)
163
170
} ) ;
164
171
@@ -175,33 +182,25 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
175
182
if suggest_display {
176
183
l. span_suggestion_verbose (
177
184
arg_span. shrink_to_lo ( ) ,
178
- "add a \" {} \" format string to Display the message" ,
185
+ fluent :: lint :: display_suggestion ,
179
186
"\" {}\" , " ,
180
187
fmt_applicability,
181
188
) ;
182
189
} else if suggest_debug {
190
+ l. set_arg ( "ty" , ty) ;
183
191
l. span_suggestion_verbose (
184
192
arg_span. shrink_to_lo ( ) ,
185
- & format ! (
186
- "add a \" {{:?}}\" format string to use the Debug implementation of `{}`" ,
187
- ty,
188
- ) ,
193
+ fluent:: lint:: debug_suggestion,
189
194
"\" {:?}\" , " ,
190
195
fmt_applicability,
191
196
) ;
192
197
}
193
198
194
199
if suggest_panic_any {
195
200
if let Some ( ( open, close, del) ) = find_delimiters ( cx, span) {
201
+ l. set_arg ( "already_suggested" , suggest_display || suggest_debug) ;
196
202
l. multipart_suggestion (
197
- & format ! (
198
- "{}use std::panic::panic_any instead" ,
199
- if suggest_display || suggest_debug {
200
- "or "
201
- } else {
202
- ""
203
- } ,
204
- ) ,
203
+ fluent:: lint:: panic_suggestion,
205
204
if del == '(' {
206
205
vec ! [ ( span. until( open) , "std::panic::panic_any" . into( ) ) ]
207
206
} else {
@@ -260,21 +259,19 @@ fn check_panic_str<'tcx>(
260
259
. collect ( ) ,
261
260
} ;
262
261
cx. struct_span_lint ( NON_FMT_PANICS , arg_spans, |lint| {
263
- let mut l = lint. build ( match n_arguments {
264
- 1 => "panic message contains an unused formatting placeholder" ,
265
- _ => "panic message contains unused formatting placeholders" ,
266
- } ) ;
267
- l. note ( "this message is not used as a format string when given without arguments, but will be in Rust 2021" ) ;
262
+ let mut l = lint. build ( fluent:: lint:: non_fmt_panic_unused) ;
263
+ l. set_arg ( "count" , n_arguments) ;
264
+ l. note ( fluent:: lint:: note) ;
268
265
if is_arg_inside_call ( arg. span , span) {
269
266
l. span_suggestion (
270
267
arg. span . shrink_to_hi ( ) ,
271
- & format ! ( "add the missing argument{}" , pluralize! ( n_arguments ) ) ,
268
+ fluent :: lint :: add_args_suggestion ,
272
269
", ..." ,
273
270
Applicability :: HasPlaceholders ,
274
271
) ;
275
272
l. span_suggestion (
276
273
arg. span . shrink_to_lo ( ) ,
277
- "or add a \" {} \" format string to use the message literally" ,
274
+ fluent :: lint :: add_fmt_suggestion ,
278
275
"\" {}\" , " ,
279
276
Applicability :: MachineApplicable ,
280
277
) ;
@@ -289,17 +286,15 @@ fn check_panic_str<'tcx>(
289
286
. map ( |( i, _) | fmt_span. from_inner ( InnerSpan { start : i, end : i + 1 } ) )
290
287
. collect ( )
291
288
} ) ;
292
- let msg = match & brace_spans {
293
- Some ( v) if v. len ( ) == 1 => "panic message contains a brace" ,
294
- _ => "panic message contains braces" ,
295
- } ;
289
+ let count = brace_spans. as_ref ( ) . map ( |v| v. len ( ) ) . unwrap_or ( /* any number >1 */ 2 ) ;
296
290
cx. struct_span_lint ( NON_FMT_PANICS , brace_spans. unwrap_or_else ( || vec ! [ span] ) , |lint| {
297
- let mut l = lint. build ( msg) ;
298
- l. note ( "this message is not used as a format string, but will be in Rust 2021" ) ;
291
+ let mut l = lint. build ( fluent:: lint:: non_fmt_panic_braces) ;
292
+ l. set_arg ( "count" , count) ;
293
+ l. note ( fluent:: lint:: note) ;
299
294
if is_arg_inside_call ( arg. span , span) {
300
295
l. span_suggestion (
301
296
arg. span . shrink_to_lo ( ) ,
302
- "add a \" {} \" format string to use the message literally" ,
297
+ fluent :: lint :: suggestion ,
303
298
"\" {}\" , " ,
304
299
Applicability :: MachineApplicable ,
305
300
) ;
0 commit comments