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) => {
|
ExprKind::Call(ref fun, ref args) => {
|
||||||
if_chain! {
|
if_chain! {
|
||||||
if let ExprKind::Path(ref qpath) = fun.node;
|
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 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 check_single_piece(&args[0]);
|
||||||
if let Some(format_arg) = get_single_string_arg(cx, &args[1]);
|
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;
|
if let ExprKind::AddrOf(_, ref format_arg) = format_arg.node;
|
||||||
then {
|
then {
|
||||||
let (message, sugg) = if_chain! {
|
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.
|
/// 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 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 {
|
let arg = match &arg.node {
|
||||||
hir::ExprKind::AddrOf(_, expr) => expr,
|
hir::ExprKind::AddrOf(_, expr) => expr,
|
||||||
hir::ExprKind::MethodCall(method_name, _, args)
|
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 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 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 {
|
if let hir::ExprKind::Call(_, format_args) = &inner_args[0].node {
|
||||||
return Some(format_args);
|
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<'_, '_>,
|
cx: &LateContext<'_, '_>,
|
||||||
a: &hir::Expr,
|
a: &hir::Expr,
|
||||||
applicability: &mut Applicability,
|
applicability: &mut Applicability,
|
||||||
) -> String {
|
) -> Vec<String> {
|
||||||
if let hir::ExprKind::AddrOf(_, ref format_arg) = a.node {
|
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::Match(ref format_arg_expr, _, _) = format_arg.node {
|
||||||
if let hir::ExprKind::Tup(ref format_arg_expr_tup) = format_arg_expr.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)
|
return format_arg_expr_tup
|
||||||
.into_owned();
|
.iter()
|
||||||
|
.map(|a| snippet_with_applicability(cx, a.span, "..", applicability).into_owned())
|
||||||
|
.collect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
snippet(cx, a.span, "..").into_owned()
|
unreachable!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_general_case(
|
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());
|
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 mut applicability = Applicability::MachineApplicable;
|
||||||
let args_len = format_args.len();
|
let mut args = vec![snippet(cx, fmt_spec.span, "..").into_owned()];
|
||||||
let args: Vec<String> = format_args
|
|
||||||
.into_iter()
|
args.extend(generate_format_arg_snippet(cx, fmt_args, &mut applicability));
|
||||||
.take(args_len - 1)
|
|
||||||
.map(|a| generate_format_arg_snippet(cx, a, &mut applicability))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let sugg = args.join(", ");
|
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 DROP: [&str; 3] = ["core", "mem", "drop"];
|
||||||
pub const DURATION: [&str; 3] = ["core", "time", "Duration"];
|
pub const DURATION: [&str; 3] = ["core", "time", "Duration"];
|
||||||
pub const EARLY_CONTEXT: [&str; 4] = ["rustc", "lint", "context", "EarlyContext"];
|
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 FMT_ARGUMENTS_NEWV1FORMATTED: [&str; 4] = ["core", "fmt", "Arguments", "new_v1_formatted"];
|
||||||
pub const FROM_FROM: [&str; 4] = ["core", "convert", "From", "from"];
|
pub const FROM_FROM: [&str; 4] = ["core", "convert", "From", "from"];
|
||||||
pub const FROM_TRAIT: [&str; 3] = ["core", "convert", "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") });
|
||||||
Some("foo").expect(format!("error").as_ref());
|
Some("foo").expect(format!("error").as_ref());
|
||||||
|
|
||||||
|
Some("foo").expect(format!("{} {}", 1, 2).as_ref());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -36,5 +36,11 @@ error: use of `expect` followed by a function call
|
||||||
LL | Some("foo").expect(format!("error").as_ref());
|
LL | Some("foo").expect(format!("error").as_ref());
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| panic!("error"))`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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…
Add table
Add a link
Reference in a new issue