@@ -95,7 +95,7 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
95
95
let mut l = lint. build ( "panic message is not a string literal" ) ;
96
96
l. note ( "this usage of panic!() is deprecated; it will be a hard error in Rust 2021" ) ;
97
97
l. note ( "for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>" ) ;
98
- if !span . contains ( arg_span) {
98
+ if !is_arg_inside_call ( arg_span, span ) {
99
99
// No clue where this argument is coming from.
100
100
l. emit ( ) ;
101
101
return ;
@@ -180,7 +180,7 @@ fn check_panic_str<'tcx>(
180
180
_ => "panic message contains unused formatting placeholders" ,
181
181
} ) ;
182
182
l. note ( "this message is not used as a format string when given without arguments, but will be in Rust 2021" ) ;
183
- if span . contains ( arg. span ) {
183
+ if is_arg_inside_call ( arg. span , span) {
184
184
l. span_suggestion (
185
185
arg. span . shrink_to_hi ( ) ,
186
186
& format ! ( "add the missing argument{}" , pluralize!( n_arguments) ) ,
@@ -211,7 +211,7 @@ fn check_panic_str<'tcx>(
211
211
cx. struct_span_lint ( NON_FMT_PANICS , brace_spans. unwrap_or_else ( || vec ! [ span] ) , |lint| {
212
212
let mut l = lint. build ( msg) ;
213
213
l. note ( "this message is not used as a format string, but will be in Rust 2021" ) ;
214
- if span . contains ( arg. span ) {
214
+ if is_arg_inside_call ( arg. span , span) {
215
215
l. span_suggestion (
216
216
arg. span . shrink_to_lo ( ) ,
217
217
"add a \" {}\" format string to use the message literally" ,
@@ -259,3 +259,11 @@ fn panic_call<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>) -> (Span,
259
259
if let hygiene:: ExpnKind :: Macro ( _, symbol) = expn. kind { symbol } else { sym:: panic } ;
260
260
( expn. call_site , panic_macro, macro_symbol. as_str ( ) )
261
261
}
262
+
263
+ fn is_arg_inside_call ( arg : Span , call : Span ) -> bool {
264
+ // We only add suggestions if the argument we're looking at appears inside the
265
+ // panic call in the source file, to avoid invalid suggestions when macros are involved.
266
+ // We specifically check for the spans to not be identical, as that happens sometimes when
267
+ // proc_macros lie about spans and apply the same span to all the tokens they produce.
268
+ call. contains ( arg) && !call. source_equal ( & arg)
269
+ }
0 commit comments