Skip to content

Commit

Permalink
Auto merge of #11021 - y21:issue9493, r=llogiq
Browse files Browse the repository at this point in the history
[`format_push_string`]: look through `match` and `if` expressions

Closes #9493.

changelog: [`format_push_string`]: look through `match` and `if` expressions
  • Loading branch information
bors committed Jun 24, 2023
2 parents 3cee98d + fe856d3 commit 1b4c423
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 6 deletions.
23 changes: 18 additions & 5 deletions clippy_lints/src/format_push_string.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::ty::is_type_lang_item;
use clippy_utils::{match_def_path, paths, peel_hir_expr_refs};
use rustc_hir::{BinOpKind, Expr, ExprKind, LangItem};
use clippy_utils::{higher, match_def_path, paths};
use rustc_hir::{BinOpKind, Expr, ExprKind, LangItem, MatchSource};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::sym;
Expand Down Expand Up @@ -44,10 +44,24 @@ fn is_string(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
is_type_lang_item(cx, cx.typeck_results().expr_ty(e).peel_refs(), LangItem::String)
}
fn is_format(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
if let Some(macro_def_id) = e.span.ctxt().outer_expn_data().macro_def_id {
let e = e.peel_blocks().peel_borrows();

if e.span.from_expansion()
&& let Some(macro_def_id) = e.span.ctxt().outer_expn_data().macro_def_id
{
cx.tcx.get_diagnostic_name(macro_def_id) == Some(sym::format_macro)
} else if let Some(higher::If { then, r#else, .. }) = higher::If::hir(e) {
is_format(cx, then) || r#else.is_some_and(|e| is_format(cx, e))
} else {
false
match higher::IfLetOrMatch::parse(cx, e) {
Some(higher::IfLetOrMatch::Match(_, arms, MatchSource::Normal)) => {
arms.iter().any(|arm| is_format(cx, arm.body))
},
Some(higher::IfLetOrMatch::IfLet(_, _, then, r#else)) => {
is_format(cx, then) ||r#else.is_some_and(|e| is_format(cx, e))
},
_ => false,
}
}
}

Expand All @@ -68,7 +82,6 @@ impl<'tcx> LateLintPass<'tcx> for FormatPushString {
},
_ => return,
};
let (arg, _) = peel_hir_expr_refs(arg);
if is_format(cx, arg) {
span_lint_and_help(
cx,
Expand Down
29 changes: 29 additions & 0 deletions tests/ui/format_push_string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,32 @@ fn main() {
string += &format!("{:?}", 1234);
string.push_str(&format!("{:?}", 5678));
}

mod issue9493 {
pub fn u8vec_to_hex(vector: &Vec<u8>, upper: bool) -> String {
let mut hex = String::with_capacity(vector.len() * 2);
for byte in vector {
hex += &(if upper {
format!("{byte:02X}")
} else {
format!("{byte:02x}")
});
}
hex
}

pub fn other_cases() {
let mut s = String::new();
// if let
s += &(if let Some(_a) = Some(1234) {
format!("{}", 1234)
} else {
format!("{}", 1234)
});
// match
s += &(match Some(1234) {
Some(_) => format!("{}", 1234),
None => format!("{}", 1234),
});
}
}
37 changes: 36 additions & 1 deletion tests/ui/format_push_string.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,40 @@ LL | string.push_str(&format!("{:?}", 5678));
|
= help: consider using `write!` to avoid the extra allocation

error: aborting due to 2 previous errors
error: `format!(..)` appended to existing `String`
--> $DIR/format_push_string.rs:13:13
|
LL | / hex += &(if upper {
LL | | format!("{byte:02X}")
LL | | } else {
LL | | format!("{byte:02x}")
LL | | });
| |______________^
|
= help: consider using `write!` to avoid the extra allocation

error: `format!(..)` appended to existing `String`
--> $DIR/format_push_string.rs:25:9
|
LL | / s += &(if let Some(_a) = Some(1234) {
LL | | format!("{}", 1234)
LL | | } else {
LL | | format!("{}", 1234)
LL | | });
| |__________^
|
= help: consider using `write!` to avoid the extra allocation

error: `format!(..)` appended to existing `String`
--> $DIR/format_push_string.rs:31:9
|
LL | / s += &(match Some(1234) {
LL | | Some(_) => format!("{}", 1234),
LL | | None => format!("{}", 1234),
LL | | });
| |__________^
|
= help: consider using `write!` to avoid the extra allocation

error: aborting due to 5 previous errors

0 comments on commit 1b4c423

Please sign in to comment.