mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-10 15:14:29 +00:00
Catch up with format_args
change
Catches up with a change in rust-lang/rust#57537 Happened to fix a bug in `expect_fun_call`, that is the lint ignores more than one arguments to `format`.
This commit is contained in:
parent
235f96005c
commit
2ee713dc7b
5 changed files with 31 additions and 18 deletions
|
@ -53,12 +53,17 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
|
|||
ExprKind::Call(ref fun, ref args) => {
|
||||
if_chain! {
|
||||
if let ExprKind::Path(ref qpath) = fun.node;
|
||||
if args.len() == 3;
|
||||
if let Some(fun_def_id) = opt_def_id(resolve_node(cx, qpath, fun.hir_id));
|
||||
if match_def_path(cx.tcx, fun_def_id, &paths::FMT_ARGUMENTS_NEWV1FORMATTED);
|
||||
let new_v1 = match_def_path(cx.tcx, fun_def_id, &paths::FMT_ARGUMENTS_NEWV1);
|
||||
let new_v1_fmt = match_def_path(
|
||||
cx.tcx,
|
||||
fun_def_id,
|
||||
&paths::FMT_ARGUMENTS_NEWV1FORMATTED
|
||||
);
|
||||
if new_v1 || new_v1_fmt;
|
||||
if check_single_piece(&args[0]);
|
||||
if let Some(format_arg) = get_single_string_arg(cx, &args[1]);
|
||||
if check_unformatted(&args[2]);
|
||||
if new_v1 || check_unformatted(&args[2]);
|
||||
if let ExprKind::AddrOf(_, ref format_arg) = format_arg.node;
|
||||
then {
|
||||
let (message, sugg) = if_chain! {
|
||||
|
|
|
@ -1148,7 +1148,7 @@ fn lint_or_fun_call(cx: &LateContext<'_, '_>, expr: &hir::Expr, method_span: Spa
|
|||
|
||||
/// Checks for the `EXPECT_FUN_CALL` lint.
|
||||
fn lint_expect_fun_call(cx: &LateContext<'_, '_>, expr: &hir::Expr, method_span: Span, name: &str, args: &[hir::Expr]) {
|
||||
fn extract_format_args(arg: &hir::Expr) -> Option<&hir::HirVec<hir::Expr>> {
|
||||
fn extract_format_args(arg: &hir::Expr) -> Option<(&hir::Expr, &hir::Expr)> {
|
||||
let arg = match &arg.node {
|
||||
hir::ExprKind::AddrOf(_, expr) => expr,
|
||||
hir::ExprKind::MethodCall(method_name, _, args)
|
||||
|
@ -1161,8 +1161,8 @@ fn lint_expect_fun_call(cx: &LateContext<'_, '_>, expr: &hir::Expr, method_span:
|
|||
|
||||
if let hir::ExprKind::Call(ref inner_fun, ref inner_args) = arg.node {
|
||||
if is_expn_of(inner_fun.span, "format").is_some() && inner_args.len() == 1 {
|
||||
if let hir::ExprKind::Call(_, ref format_args) = inner_args[0].node {
|
||||
return Some(format_args);
|
||||
if let hir::ExprKind::Call(_, format_args) = &inner_args[0].node {
|
||||
return Some((&format_args[0], &format_args[1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1174,17 +1174,19 @@ fn lint_expect_fun_call(cx: &LateContext<'_, '_>, expr: &hir::Expr, method_span:
|
|||
cx: &LateContext<'_, '_>,
|
||||
a: &hir::Expr,
|
||||
applicability: &mut Applicability,
|
||||
) -> String {
|
||||
) -> Vec<String> {
|
||||
if let hir::ExprKind::AddrOf(_, ref format_arg) = a.node {
|
||||
if let hir::ExprKind::Match(ref format_arg_expr, _, _) = format_arg.node {
|
||||
if let hir::ExprKind::Tup(ref format_arg_expr_tup) = format_arg_expr.node {
|
||||
return snippet_with_applicability(cx, format_arg_expr_tup[0].span, "..", applicability)
|
||||
.into_owned();
|
||||
return format_arg_expr_tup
|
||||
.iter()
|
||||
.map(|a| snippet_with_applicability(cx, a.span, "..", applicability).into_owned())
|
||||
.collect();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
snippet(cx, a.span, "..").into_owned()
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
fn check_general_case(
|
||||
|
@ -1233,14 +1235,11 @@ fn lint_expect_fun_call(cx: &LateContext<'_, '_>, expr: &hir::Expr, method_span:
|
|||
};
|
||||
let span_replace_word = method_span.with_hi(span.hi());
|
||||
|
||||
if let Some(format_args) = extract_format_args(arg) {
|
||||
if let Some((fmt_spec, fmt_args)) = extract_format_args(arg) {
|
||||
let mut applicability = Applicability::MachineApplicable;
|
||||
let args_len = format_args.len();
|
||||
let args: Vec<String> = format_args
|
||||
.into_iter()
|
||||
.take(args_len - 1)
|
||||
.map(|a| generate_format_arg_snippet(cx, a, &mut applicability))
|
||||
.collect();
|
||||
let mut args = vec![snippet(cx, fmt_spec.span, "..").into_owned()];
|
||||
|
||||
args.extend(generate_format_arg_snippet(cx, fmt_args, &mut applicability));
|
||||
|
||||
let sugg = args.join(", ");
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ pub const DOUBLE_ENDED_ITERATOR: [&str; 4] = ["core", "iter", "traits", "DoubleE
|
|||
pub const DROP: [&str; 3] = ["core", "mem", "drop"];
|
||||
pub const DURATION: [&str; 3] = ["core", "time", "Duration"];
|
||||
pub const EARLY_CONTEXT: [&str; 4] = ["rustc", "lint", "context", "EarlyContext"];
|
||||
pub const FMT_ARGUMENTS_NEWV1: [&str; 4] = ["core", "fmt", "Arguments", "new_v1"];
|
||||
pub const FMT_ARGUMENTS_NEWV1FORMATTED: [&str; 4] = ["core", "fmt", "Arguments", "new_v1_formatted"];
|
||||
pub const FROM_FROM: [&str; 4] = ["core", "convert", "From", "from"];
|
||||
pub const FROM_TRAIT: [&str; 3] = ["core", "convert", "From"];
|
||||
|
|
|
@ -57,6 +57,8 @@ fn expect_fun_call() {
|
|||
|
||||
Some("foo").expect({ &format!("error") });
|
||||
Some("foo").expect(format!("error").as_ref());
|
||||
|
||||
Some("foo").expect(format!("{} {}", 1, 2).as_ref());
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -36,5 +36,11 @@ error: use of `expect` followed by a function call
|
|||
LL | Some("foo").expect(format!("error").as_ref());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| panic!("error"))`
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
error: use of `expect` followed by a function call
|
||||
--> $DIR/expect_fun_call.rs:61:17
|
||||
|
|
||||
LL | Some("foo").expect(format!("{} {}", 1, 2).as_ref());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| panic!("{} {}", 1, 2))`
|
||||
|
||||
error: aborting due to 7 previous errors
|
||||
|
||||
|
|
Loading…
Reference in a new issue