|
1 |
| -use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg}; |
| 1 | +use clippy_utils::diagnostics::span_lint_and_sugg; |
2 | 2 | use clippy_utils::macros::{root_macro_call, FormatArgsExpn};
|
3 |
| -use clippy_utils::source::snippet_with_applicability; |
| 3 | +use clippy_utils::sugg::Sugg; |
4 | 4 | use clippy_utils::ty::is_type_diagnostic_item;
|
5 | 5 | use rustc_errors::Applicability;
|
6 | 6 | use rustc_hir::{Expr, ExprKind};
|
@@ -45,46 +45,44 @@ impl<'tcx> LateLintPass<'tcx> for PathFromFormat {
|
45 | 45 | if let Some(macro_call) = root_macro_call(args[0].span);
|
46 | 46 | if cx.tcx.item_name(macro_call.def_id) == sym::format;
|
47 | 47 | if let Some(format_args) = FormatArgsExpn::find_nested(cx, &args[0], macro_call.expn);
|
48 |
| - let mut applicability = Applicability::MachineApplicable; |
49 |
| - let format_args_snip = snippet_with_applicability(cx, format_args.inputs_span(), "..", &mut applicability); |
50 |
| - if let Some(end_of_literal) = format_args_snip.find("\","); |
| 48 | + let format_string_parts = format_args.format_string_parts; |
| 49 | + let format_value_args = format_args.value_args; |
51 | 50 | then {
|
52 |
| - let (literal, vars) = format_args_snip.split_at(end_of_literal); |
53 |
| - let mut literal = literal.to_string(); |
54 |
| - literal.remove(0); |
55 |
| - let v: Vec<&str> = literal.split("{}").collect(); |
56 |
| - let real_vars = vars.strip_prefix("\", ").unwrap_or(vars); |
57 |
| - if v.len() != 2 || real_vars.contains(',') { |
58 |
| - span_lint_and_help( |
59 |
| - cx, |
60 |
| - PATH_FROM_FORMAT, |
61 |
| - expr.span, |
62 |
| - "`format!(..)` used to form `PathBuf`", |
63 |
| - None, |
64 |
| - "consider using `.join()` to avoid the extra allocation", |
65 |
| - ); |
66 |
| - return; |
67 |
| - } |
68 |
| - let sugg = { |
69 |
| - if v[0].is_empty() { |
70 |
| - let mut str1 = v[1].to_string(); |
71 |
| - if str1.starts_with('\\') || str1.starts_with('/') { |
72 |
| - str1.remove(0); |
| 51 | + let mut string_parts: Vec<&str> = format_string_parts.iter().map(|x| x.as_str()).collect(); |
| 52 | + string_parts.push(""); |
| 53 | + let mut applicability = Applicability::MachineApplicable; |
| 54 | + let real_vars: Vec<Sugg<'_>> = format_value_args.iter().map(|x| Sugg::hir_with_applicability(cx, x, "..", &mut applicability)).collect(); |
| 55 | + let order_of_real_vars: Vec<usize> = format_args.formatters.iter().map(|(x, _)| x.clone()).collect(); |
| 56 | + let mut sugg = String::new(); |
| 57 | + for n in 0..real_vars.len() { |
| 58 | + if n == 0 { |
| 59 | + if string_parts[0].is_empty() { |
| 60 | + sugg = format!("Path::new({})", real_vars[order_of_real_vars[0]]); |
| 61 | + } |
| 62 | + else { |
| 63 | + sugg = format!("Path::new(\"{}\").join({y})", string_parts[0], y = real_vars[order_of_real_vars[0]]); |
73 | 64 | }
|
74 |
| - format!("Path::new({real_vars}).join(\"{str1}\")") |
75 |
| - } |
76 |
| - else if v[1].is_empty() { |
77 |
| - let str1 = v[0].to_string(); |
78 |
| - format!("Path::new(\"{str1}\").join({real_vars})") |
79 | 65 | }
|
80 | 66 | else {
|
81 |
| - let (str1, mut str2) = (v[0].to_string(), v[1].to_string()); |
82 |
| - if str2.starts_with('\\') || str2.starts_with('/') { |
83 |
| - str2.remove(0); |
| 67 | + if string_parts[n].is_empty() { |
| 68 | + sugg = format!("{sugg}.join({})", real_vars[order_of_real_vars[n]]); |
| 69 | + } |
| 70 | + else { |
| 71 | + let mut string = String::from(string_parts[n]); |
| 72 | + if string.starts_with('/') || string.starts_with('\\') { |
| 73 | + string.remove(0); |
| 74 | + } |
| 75 | + sugg = format!("{sugg}.join(\"{}\").join({y})", string, y = real_vars[order_of_real_vars[n]]); |
84 | 76 | }
|
85 |
| - format!("Path::new(\"{str1}\").join({real_vars}).join(\"{str2}\")") |
86 | 77 | }
|
87 |
| - }; |
| 78 | + } |
| 79 | + if !string_parts[real_vars.len()].is_empty() { |
| 80 | + let mut string = String::from(string_parts[real_vars.len()]); |
| 81 | + if string.starts_with('/') || string.starts_with('\\') { |
| 82 | + string.remove(0); |
| 83 | + } |
| 84 | + sugg = format!("{sugg}.join(\"{}\")", string); |
| 85 | + } |
88 | 86 | span_lint_and_sugg(
|
89 | 87 | cx,
|
90 | 88 | PATH_FROM_FORMAT,
|
|
0 commit comments