use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::higher::FormatExpn;
-use clippy_utils::last_path_segment;
use clippy_utils::source::{snippet_opt, snippet_with_applicability};
use clippy_utils::sugg::Sugg;
use if_chain::if_chain;
use rustc_errors::Applicability;
-use rustc_hir::{BorrowKind, Expr, ExprKind, QPath};
+use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty;
use rustc_session::{declare_lint_pass, declare_tool_lint};
ty::Str => true,
_ => false,
};
- if format_args.args.iter().all(is_display_arg);
- if format_args.fmt_expr.map_or(true, check_unformatted);
+ if let Some(args) = format_args.args();
+ if args.iter().all(|arg| arg.is_display() && !arg.has_string_formatting());
then {
let is_new_string = match value.kind {
ExprKind::Binary(..) => true,
applicability,
);
}
-
-fn is_display_arg(expr: &Expr<'_>) -> bool {
- if_chain! {
- if let ExprKind::Call(_, [_, fmt]) = expr.kind;
- if let ExprKind::Path(QPath::Resolved(_, path)) = fmt.kind;
- if let [.., t, _] = path.segments;
- if t.ident.name == sym::Display;
- then { true } else { false }
- }
-}
-
-/// Checks if the expression matches
-/// ```rust,ignore
-/// &[_ {
-/// format: _ {
-/// width: _::Implied,
-/// precision: _::Implied,
-/// ...
-/// },
-/// ...,
-/// }]
-/// ```
-fn check_unformatted(expr: &Expr<'_>) -> bool {
- if_chain! {
- if let ExprKind::AddrOf(BorrowKind::Ref, _, expr) = expr.kind;
- if let ExprKind::Array([expr]) = expr.kind;
- // struct `core::fmt::rt::v1::Argument`
- if let ExprKind::Struct(_, fields, _) = expr.kind;
- if let Some(format_field) = fields.iter().find(|f| f.ident.name == sym::format);
- // struct `core::fmt::rt::v1::FormatSpec`
- if let ExprKind::Struct(_, fields, _) = format_field.expr.kind;
- if let Some(precision_field) = fields.iter().find(|f| f.ident.name == sym::precision);
- if let ExprKind::Path(ref precision_path) = precision_field.expr.kind;
- if last_path_segment(precision_path).ident.name == sym::Implied;
- if let Some(width_field) = fields.iter().find(|f| f.ident.name == sym::width);
- if let ExprKind::Path(ref width_qpath) = width_field.expr.kind;
- if last_path_segment(width_qpath).ident.name == sym::Implied;
- then {
- return true;
- }
- }
-
- false
-}