Use source callsite in FormatArgsExpn::inputs_span

This commit is contained in:
Alex Macleod 2022-01-28 14:42:19 +00:00
parent 699ee5e31c
commit 4bae06d73c
9 changed files with 98 additions and 32 deletions

View File

@ -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())),
}
}
}

View File

@ -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<i32> = None;
with_none_and_as_str.unwrap_or_else(|| panic!("Error {}: fake error", error_code));
let with_none_and_format_with_macro: Option<i32> = None;
with_none_and_format_with_macro.unwrap_or_else(|| panic!("Error {}: fake error", one!()));
let with_ok: Result<(), ()> = Ok(());
with_ok.expect("error");

View File

@ -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<i32> = None;
with_none_and_as_str.expect(format!("Error {}: fake error", error_code).as_str());
let with_none_and_format_with_macro: Option<i32> = None;
with_none_and_format_with_macro.expect(format!("Error {}: fake error", one!()).as_str());
let with_ok: Result<(), ()> = Ok(());
with_ok.expect("error");

View File

@ -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

View File

@ -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!());
}

View File

@ -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

View File

@ -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!());
}

View File

@ -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

View File

@ -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!())
}
}