From dd168838b9d353229dc6c9dfb25f3caa66a1d5b2 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Wed, 11 Jan 2023 21:42:08 +0100 Subject: [PATCH 1/2] Make clippy compile. --- clippy_utils/src/sugg.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/clippy_utils/src/sugg.rs b/clippy_utils/src/sugg.rs index e7879bb196e..2d1044af17e 100644 --- a/clippy_utils/src/sugg.rs +++ b/clippy_utils/src/sugg.rs @@ -219,6 +219,7 @@ pub fn ast( | ast::ExprKind::Repeat(..) | ast::ExprKind::Ret(..) | ast::ExprKind::Yeet(..) + | ast::ExprKind::FormatArgs(..) | ast::ExprKind::Struct(..) | ast::ExprKind::Try(..) | ast::ExprKind::TryBlock(..) From 2bcd697e2d89d0f9f80682fdaaf5bbdd5adbb0ba Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Thu, 12 Jan 2023 00:25:09 +0100 Subject: [PATCH 2/2] Update clippy for new format_args!() lang items. --- clippy_lints/src/format_args.rs | 6 ++-- clippy_utils/src/macros.rs | 54 +++++++++++++++++++-------------- 2 files changed, 35 insertions(+), 25 deletions(-) diff --git a/clippy_lints/src/format_args.rs b/clippy_lints/src/format_args.rs index 043112bbc95..70a80d40f46 100644 --- a/clippy_lints/src/format_args.rs +++ b/clippy_lints/src/format_args.rs @@ -7,14 +7,14 @@ }; use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_opt; -use clippy_utils::ty::{implements_trait, is_type_diagnostic_item}; +use clippy_utils::ty::{implements_trait, is_type_lang_item}; use if_chain::if_chain; use itertools::Itertools; use rustc_errors::{ Applicability, SuggestionStyle::{CompletelyHidden, ShowCode}, }; -use rustc_hir::{Expr, ExprKind, HirId, QPath}; +use rustc_hir::{Expr, ExprKind, HirId, LangItem, QPath}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::ty::adjustment::{Adjust, Adjustment}; use rustc_middle::ty::Ty; @@ -237,7 +237,7 @@ fn check_unused_format_specifier(cx: &LateContext<'_>, arg: &FormatArg<'_>) { ); } - if is_type_diagnostic_item(cx, param_ty, sym::Arguments) && !arg.format.is_default_for_trait() { + if is_type_lang_item(cx, param_ty, LangItem::FormatArguments) && !arg.format.is_default_for_trait() { span_lint_and_then( cx, UNUSED_FORMAT_SPECS, diff --git a/clippy_utils/src/macros.rs b/clippy_utils/src/macros.rs index 77c5f115542..a8f8da67b51 100644 --- a/clippy_utils/src/macros.rs +++ b/clippy_utils/src/macros.rs @@ -1,6 +1,5 @@ #![allow(clippy::similar_names)] // `expr` and `expn` -use crate::is_path_diagnostic_item; use crate::source::snippet_opt; use crate::visitors::{for_each_expr, Descend}; @@ -8,7 +7,7 @@ use itertools::{izip, Either, Itertools}; use rustc_ast::ast::LitKind; use rustc_hir::intravisit::{walk_expr, Visitor}; -use rustc_hir::{self as hir, Expr, ExprField, ExprKind, HirId, Node, QPath}; +use rustc_hir::{self as hir, Expr, ExprField, ExprKind, HirId, LangItem, Node, QPath, TyKind}; use rustc_lexer::unescape::unescape_literal; use rustc_lexer::{tokenize, unescape, LiteralKind, TokenKind}; use rustc_lint::LateContext; @@ -439,8 +438,7 @@ fn new(args: &'tcx Expr<'tcx>, format_string_span: SpanData) -> Self { // ArgumentV1::from_usize() if let ExprKind::Call(callee, [val]) = expr.kind && let ExprKind::Path(QPath::TypeRelative(ty, _)) = callee.kind - && let hir::TyKind::Path(QPath::Resolved(_, path)) = ty.kind - && path.segments.last().unwrap().ident.name == sym::ArgumentV1 + && let TyKind::Path(QPath::LangItem(LangItem::FormatArgument, _, _)) = ty.kind { let val_idx = if val.span.ctxt() == expr.span.ctxt() && let ExprKind::Field(_, field) = val.kind @@ -486,20 +484,6 @@ struct ParamPosition { impl<'tcx> Visitor<'tcx> for ParamPosition { fn visit_expr_field(&mut self, field: &'tcx ExprField<'tcx>) { - fn parse_count(expr: &Expr<'_>) -> Option { - // ::core::fmt::rt::v1::Count::Param(1usize), - if let ExprKind::Call(ctor, [val]) = expr.kind - && let ExprKind::Path(QPath::Resolved(_, path)) = ctor.kind - && path.segments.last()?.ident.name == sym::Param - && let ExprKind::Lit(lit) = &val.kind - && let LitKind::Int(pos, _) = lit.node - { - Some(pos as usize) - } else { - None - } - } - match field.ident.name { sym::position => { if let ExprKind::Lit(lit) = &field.expr.kind @@ -519,15 +503,41 @@ fn parse_count(expr: &Expr<'_>) -> Option { } } +fn parse_count(expr: &Expr<'_>) -> Option { + // <::core::fmt::rt::v1::Count>::Param(1usize), + if let ExprKind::Call(ctor, [val]) = expr.kind + && let ExprKind::Path(QPath::TypeRelative(_, path)) = ctor.kind + && path.ident.name == sym::Param + && let ExprKind::Lit(lit) = &val.kind + && let LitKind::Int(pos, _) = lit.node + { + Some(pos as usize) + } else { + None + } +} + /// Parses the `fmt` arg of `Arguments::new_v1_formatted(pieces, args, fmt, _)` fn parse_rt_fmt<'tcx>(fmt_arg: &'tcx Expr<'tcx>) -> Option + 'tcx> { if let ExprKind::AddrOf(.., array) = fmt_arg.kind && let ExprKind::Array(specs) = array.kind { Some(specs.iter().map(|spec| { - let mut position = ParamPosition::default(); - position.visit_expr(spec); - position + if let ExprKind::Call(f, args) = spec.kind + && let ExprKind::Path(QPath::TypeRelative(ty, f)) = f.kind + && let TyKind::Path(QPath::LangItem(LangItem::FormatPlaceholder, _, _)) = ty.kind + && f.ident.name == sym::new + && let [position, _fill, _align, _flags, precision, width] = args + && let ExprKind::Lit(position) = &position.kind + && let LitKind::Int(position, _) = position.node { + ParamPosition { + value: position as usize, + width: parse_count(width), + precision: parse_count(precision), + } + } else { + ParamPosition::default() + } })) } else { None @@ -890,7 +900,7 @@ pub fn parse(cx: &LateContext<'_>, expr: &'tcx Expr<'tcx>) -> Option { // ::core::fmt::Arguments::new_v1_formatted(pieces, args, fmt, _unsafe_arg) if let ExprKind::Call(callee, [pieces, args, rest @ ..]) = expr.kind && let ExprKind::Path(QPath::TypeRelative(ty, seg)) = callee.kind - && is_path_diagnostic_item(cx, ty, sym::Arguments) + && let TyKind::Path(QPath::LangItem(LangItem::FormatArguments, _, _)) = ty.kind && matches!(seg.ident.as_str(), "new_v1" | "new_v1_formatted") { let format_string = FormatString::new(cx, pieces)?;