From 4bae06d73c8c53e5b0aabc90203f808932d2b021 Mon Sep 17 00:00:00 2001 From: Alex Macleod Date: Fri, 28 Jan 2022 14:42:19 +0000 Subject: [PATCH] Use source callsite in FormatArgsExpn::inputs_span --- clippy_utils/src/macros.rs | 9 ++++--- tests/ui/expect_fun_call.fixed | 9 +++++++ tests/ui/expect_fun_call.rs | 9 +++++++ tests/ui/expect_fun_call.stderr | 32 ++++++++++++++--------- tests/ui/manual_assert.edition2018.fixed | 7 +++++ tests/ui/manual_assert.edition2018.stderr | 24 +++++++++++------ tests/ui/manual_assert.edition2021.fixed | 7 +++++ tests/ui/manual_assert.edition2021.stderr | 24 +++++++++++------ tests/ui/manual_assert.rs | 9 +++++++ 9 files changed, 98 insertions(+), 32 deletions(-) diff --git a/clippy_utils/src/macros.rs b/clippy_utils/src/macros.rs index 5bc353bdd89..76478c74e21 100644 --- a/clippy_utils/src/macros.rs +++ b/clippy_utils/src/macros.rs @@ -9,7 +9,7 @@ use rustc_hir::intravisit::Visitor; use rustc_hir::{self as hir, Expr, ExprKind, HirId, Node, QPath}; use rustc_lint::LateContext; use rustc_span::def_id::DefId; -use rustc_span::hygiene::{MacroKind, SyntaxContext}; +use rustc_span::hygiene::{self, MacroKind, SyntaxContext}; use rustc_span::{sym, ExpnData, ExpnId, ExpnKind, Span, Symbol}; use std::ops::ControlFlow; @@ -306,6 +306,7 @@ fn is_assert_arg(cx: &LateContext<'_>, expr: &Expr<'_>, assert_expn: ExpnId) -> } /// A parsed `format_args!` expansion +#[derive(Debug)] pub struct FormatArgsExpn<'tcx> { /// Span of the first argument, the format string pub format_string_span: Span, @@ -465,11 +466,13 @@ impl<'tcx> FormatArgsExpn<'tcx> { .collect() } - /// Span of all inputs + /// Source callsite span of all inputs pub fn inputs_span(&self) -> Span { match *self.value_args { [] => self.format_string_span, - [.., last] => self.format_string_span.to(last.span), + [.., last] => self + .format_string_span + .to(hygiene::walk_chain(last.span, self.format_string_span.ctxt())), } } } diff --git a/tests/ui/expect_fun_call.fixed b/tests/ui/expect_fun_call.fixed index cf923a6a594..53e45d28bde 100644 --- a/tests/ui/expect_fun_call.fixed +++ b/tests/ui/expect_fun_call.fixed @@ -5,6 +5,12 @@ /// Checks implementation of the `EXPECT_FUN_CALL` lint +macro_rules! one { + () => { + 1 + }; +} + fn main() { struct Foo; @@ -31,6 +37,9 @@ fn main() { let with_none_and_as_str: Option = None; with_none_and_as_str.unwrap_or_else(|| panic!("Error {}: fake error", error_code)); + let with_none_and_format_with_macro: Option = None; + with_none_and_format_with_macro.unwrap_or_else(|| panic!("Error {}: fake error", one!())); + let with_ok: Result<(), ()> = Ok(()); with_ok.expect("error"); diff --git a/tests/ui/expect_fun_call.rs b/tests/ui/expect_fun_call.rs index e6f252259df..22e530b8034 100644 --- a/tests/ui/expect_fun_call.rs +++ b/tests/ui/expect_fun_call.rs @@ -5,6 +5,12 @@ /// Checks implementation of the `EXPECT_FUN_CALL` lint +macro_rules! one { + () => { + 1 + }; +} + fn main() { struct Foo; @@ -31,6 +37,9 @@ fn main() { let with_none_and_as_str: Option = None; with_none_and_as_str.expect(format!("Error {}: fake error", error_code).as_str()); + let with_none_and_format_with_macro: Option = None; + with_none_and_format_with_macro.expect(format!("Error {}: fake error", one!()).as_str()); + let with_ok: Result<(), ()> = Ok(()); with_ok.expect("error"); diff --git a/tests/ui/expect_fun_call.stderr b/tests/ui/expect_fun_call.stderr index ac48a06671c..aca15935fca 100644 --- a/tests/ui/expect_fun_call.stderr +++ b/tests/ui/expect_fun_call.stderr @@ -1,5 +1,5 @@ error: use of `expect` followed by a function call - --> $DIR/expect_fun_call.rs:29:26 + --> $DIR/expect_fun_call.rs:35:26 | LL | with_none_and_format.expect(&format!("Error {}: fake error", error_code)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| panic!("Error {}: fake error", error_code))` @@ -7,70 +7,76 @@ LL | with_none_and_format.expect(&format!("Error {}: fake error", error_code = note: `-D clippy::expect-fun-call` implied by `-D warnings` error: use of `expect` followed by a function call - --> $DIR/expect_fun_call.rs:32:26 + --> $DIR/expect_fun_call.rs:38:26 | LL | with_none_and_as_str.expect(format!("Error {}: fake error", error_code).as_str()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| panic!("Error {}: fake error", error_code))` error: use of `expect` followed by a function call - --> $DIR/expect_fun_call.rs:42:25 + --> $DIR/expect_fun_call.rs:41:37 + | +LL | with_none_and_format_with_macro.expect(format!("Error {}: fake error", one!()).as_str()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| panic!("Error {}: fake error", one!()))` + +error: use of `expect` followed by a function call + --> $DIR/expect_fun_call.rs:51:25 | LL | with_err_and_format.expect(&format!("Error {}: fake error", error_code)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|_| panic!("Error {}: fake error", error_code))` error: use of `expect` followed by a function call - --> $DIR/expect_fun_call.rs:45:25 + --> $DIR/expect_fun_call.rs:54:25 | LL | with_err_and_as_str.expect(format!("Error {}: fake error", error_code).as_str()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|_| panic!("Error {}: fake error", error_code))` error: use of `expect` followed by a function call - --> $DIR/expect_fun_call.rs:57:17 + --> $DIR/expect_fun_call.rs:66:17 | LL | Some("foo").expect(format!("{} {}", 1, 2).as_ref()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| panic!("{} {}", 1, 2))` error: use of `expect` followed by a function call - --> $DIR/expect_fun_call.rs:78:21 + --> $DIR/expect_fun_call.rs:87:21 | LL | Some("foo").expect(&get_string()); | ^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| { panic!("{}", get_string()) })` error: use of `expect` followed by a function call - --> $DIR/expect_fun_call.rs:79:21 + --> $DIR/expect_fun_call.rs:88:21 | LL | Some("foo").expect(get_string().as_ref()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| { panic!("{}", get_string()) })` error: use of `expect` followed by a function call - --> $DIR/expect_fun_call.rs:80:21 + --> $DIR/expect_fun_call.rs:89:21 | LL | Some("foo").expect(get_string().as_str()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| { panic!("{}", get_string()) })` error: use of `expect` followed by a function call - --> $DIR/expect_fun_call.rs:82:21 + --> $DIR/expect_fun_call.rs:91:21 | LL | Some("foo").expect(get_static_str()); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| { panic!("{}", get_static_str()) })` error: use of `expect` followed by a function call - --> $DIR/expect_fun_call.rs:83:21 + --> $DIR/expect_fun_call.rs:92:21 | LL | Some("foo").expect(get_non_static_str(&0)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| { panic!("{}", get_non_static_str(&0).to_string()) })` error: use of `expect` followed by a function call - --> $DIR/expect_fun_call.rs:87:16 + --> $DIR/expect_fun_call.rs:96:16 | LL | Some(true).expect(&format!("key {}, {}", 1, 2)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| panic!("key {}, {}", 1, 2))` error: use of `expect` followed by a function call - --> $DIR/expect_fun_call.rs:93:17 + --> $DIR/expect_fun_call.rs:102:17 | LL | opt_ref.expect(&format!("{:?}", opt_ref)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| panic!("{:?}", opt_ref))` -error: aborting due to 12 previous errors +error: aborting due to 13 previous errors diff --git a/tests/ui/manual_assert.edition2018.fixed b/tests/ui/manual_assert.edition2018.fixed index 6c2a25c37d8..d0bc640db88 100644 --- a/tests/ui/manual_assert.edition2018.fixed +++ b/tests/ui/manual_assert.edition2018.fixed @@ -6,6 +6,12 @@ #![warn(clippy::manual_assert)] #![allow(clippy::nonminimal_bool)] +macro_rules! one { + () => { + 1 + }; +} + fn main() { let a = vec![1, 2, 3]; let c = Some(2); @@ -42,4 +48,5 @@ fn main() { assert!(!(a.is_empty() && !b.is_empty()), "panic3"); assert!(!(b.is_empty() || a.is_empty()), "panic4"); assert!(!(a.is_empty() || !b.is_empty()), "panic5"); + assert!(!a.is_empty(), "with expansion {}", one!()); } diff --git a/tests/ui/manual_assert.edition2018.stderr b/tests/ui/manual_assert.edition2018.stderr index 77511631e44..a0f31afd6eb 100644 --- a/tests/ui/manual_assert.edition2018.stderr +++ b/tests/ui/manual_assert.edition2018.stderr @@ -1,5 +1,5 @@ error: only a `panic!` in `if`-then statement - --> $DIR/manual_assert.rs:24:5 + --> $DIR/manual_assert.rs:30:5 | LL | / if !a.is_empty() { LL | | panic!("qaqaq{:?}", a); @@ -9,7 +9,7 @@ LL | | } = note: `-D clippy::manual-assert` implied by `-D warnings` error: only a `panic!` in `if`-then statement - --> $DIR/manual_assert.rs:27:5 + --> $DIR/manual_assert.rs:33:5 | LL | / if !a.is_empty() { LL | | panic!("qwqwq"); @@ -17,7 +17,7 @@ LL | | } | |_____^ help: try: `assert!(a.is_empty(), "qwqwq");` error: only a `panic!` in `if`-then statement - --> $DIR/manual_assert.rs:44:5 + --> $DIR/manual_assert.rs:50:5 | LL | / if b.is_empty() { LL | | panic!("panic1"); @@ -25,7 +25,7 @@ LL | | } | |_____^ help: try: `assert!(!b.is_empty(), "panic1");` error: only a `panic!` in `if`-then statement - --> $DIR/manual_assert.rs:47:5 + --> $DIR/manual_assert.rs:53:5 | LL | / if b.is_empty() && a.is_empty() { LL | | panic!("panic2"); @@ -33,7 +33,7 @@ LL | | } | |_____^ help: try: `assert!(!(b.is_empty() && a.is_empty()), "panic2");` error: only a `panic!` in `if`-then statement - --> $DIR/manual_assert.rs:50:5 + --> $DIR/manual_assert.rs:56:5 | LL | / if a.is_empty() && !b.is_empty() { LL | | panic!("panic3"); @@ -41,7 +41,7 @@ LL | | } | |_____^ help: try: `assert!(!(a.is_empty() && !b.is_empty()), "panic3");` error: only a `panic!` in `if`-then statement - --> $DIR/manual_assert.rs:53:5 + --> $DIR/manual_assert.rs:59:5 | LL | / if b.is_empty() || a.is_empty() { LL | | panic!("panic4"); @@ -49,12 +49,20 @@ LL | | } | |_____^ help: try: `assert!(!(b.is_empty() || a.is_empty()), "panic4");` error: only a `panic!` in `if`-then statement - --> $DIR/manual_assert.rs:56:5 + --> $DIR/manual_assert.rs:62:5 | LL | / if a.is_empty() || !b.is_empty() { LL | | panic!("panic5"); LL | | } | |_____^ help: try: `assert!(!(a.is_empty() || !b.is_empty()), "panic5");` -error: aborting due to 7 previous errors +error: only a `panic!` in `if`-then statement + --> $DIR/manual_assert.rs:65:5 + | +LL | / if a.is_empty() { +LL | | panic!("with expansion {}", one!()) +LL | | } + | |_____^ help: try: `assert!(!a.is_empty(), "with expansion {}", one!());` + +error: aborting due to 8 previous errors diff --git a/tests/ui/manual_assert.edition2021.fixed b/tests/ui/manual_assert.edition2021.fixed index 6c2a25c37d8..d0bc640db88 100644 --- a/tests/ui/manual_assert.edition2021.fixed +++ b/tests/ui/manual_assert.edition2021.fixed @@ -6,6 +6,12 @@ #![warn(clippy::manual_assert)] #![allow(clippy::nonminimal_bool)] +macro_rules! one { + () => { + 1 + }; +} + fn main() { let a = vec![1, 2, 3]; let c = Some(2); @@ -42,4 +48,5 @@ fn main() { assert!(!(a.is_empty() && !b.is_empty()), "panic3"); assert!(!(b.is_empty() || a.is_empty()), "panic4"); assert!(!(a.is_empty() || !b.is_empty()), "panic5"); + assert!(!a.is_empty(), "with expansion {}", one!()); } diff --git a/tests/ui/manual_assert.edition2021.stderr b/tests/ui/manual_assert.edition2021.stderr index 77511631e44..a0f31afd6eb 100644 --- a/tests/ui/manual_assert.edition2021.stderr +++ b/tests/ui/manual_assert.edition2021.stderr @@ -1,5 +1,5 @@ error: only a `panic!` in `if`-then statement - --> $DIR/manual_assert.rs:24:5 + --> $DIR/manual_assert.rs:30:5 | LL | / if !a.is_empty() { LL | | panic!("qaqaq{:?}", a); @@ -9,7 +9,7 @@ LL | | } = note: `-D clippy::manual-assert` implied by `-D warnings` error: only a `panic!` in `if`-then statement - --> $DIR/manual_assert.rs:27:5 + --> $DIR/manual_assert.rs:33:5 | LL | / if !a.is_empty() { LL | | panic!("qwqwq"); @@ -17,7 +17,7 @@ LL | | } | |_____^ help: try: `assert!(a.is_empty(), "qwqwq");` error: only a `panic!` in `if`-then statement - --> $DIR/manual_assert.rs:44:5 + --> $DIR/manual_assert.rs:50:5 | LL | / if b.is_empty() { LL | | panic!("panic1"); @@ -25,7 +25,7 @@ LL | | } | |_____^ help: try: `assert!(!b.is_empty(), "panic1");` error: only a `panic!` in `if`-then statement - --> $DIR/manual_assert.rs:47:5 + --> $DIR/manual_assert.rs:53:5 | LL | / if b.is_empty() && a.is_empty() { LL | | panic!("panic2"); @@ -33,7 +33,7 @@ LL | | } | |_____^ help: try: `assert!(!(b.is_empty() && a.is_empty()), "panic2");` error: only a `panic!` in `if`-then statement - --> $DIR/manual_assert.rs:50:5 + --> $DIR/manual_assert.rs:56:5 | LL | / if a.is_empty() && !b.is_empty() { LL | | panic!("panic3"); @@ -41,7 +41,7 @@ LL | | } | |_____^ help: try: `assert!(!(a.is_empty() && !b.is_empty()), "panic3");` error: only a `panic!` in `if`-then statement - --> $DIR/manual_assert.rs:53:5 + --> $DIR/manual_assert.rs:59:5 | LL | / if b.is_empty() || a.is_empty() { LL | | panic!("panic4"); @@ -49,12 +49,20 @@ LL | | } | |_____^ help: try: `assert!(!(b.is_empty() || a.is_empty()), "panic4");` error: only a `panic!` in `if`-then statement - --> $DIR/manual_assert.rs:56:5 + --> $DIR/manual_assert.rs:62:5 | LL | / if a.is_empty() || !b.is_empty() { LL | | panic!("panic5"); LL | | } | |_____^ help: try: `assert!(!(a.is_empty() || !b.is_empty()), "panic5");` -error: aborting due to 7 previous errors +error: only a `panic!` in `if`-then statement + --> $DIR/manual_assert.rs:65:5 + | +LL | / if a.is_empty() { +LL | | panic!("with expansion {}", one!()) +LL | | } + | |_____^ help: try: `assert!(!a.is_empty(), "with expansion {}", one!());` + +error: aborting due to 8 previous errors diff --git a/tests/ui/manual_assert.rs b/tests/ui/manual_assert.rs index d3e0897488f..027747d8386 100644 --- a/tests/ui/manual_assert.rs +++ b/tests/ui/manual_assert.rs @@ -6,6 +6,12 @@ #![warn(clippy::manual_assert)] #![allow(clippy::nonminimal_bool)] +macro_rules! one { + () => { + 1 + }; +} + fn main() { let a = vec![1, 2, 3]; let c = Some(2); @@ -56,4 +62,7 @@ fn main() { if a.is_empty() || !b.is_empty() { panic!("panic5"); } + if a.is_empty() { + panic!("with expansion {}", one!()) + } }