about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlex Macleod <alex@macleod.io>2022-09-10 18:32:05 +0000
committerAlex Macleod <alex@macleod.io>2022-09-10 18:33:04 +0000
commit1b245e7e0e83d387ab9d2cc7a157b081ba5d0ef2 (patch)
tree90b01ea4e856917a3e991fbfa1c6f6f1ff4ea97e
parent5652ccbc0ff4e3895caca34a147db04c40d734c6 (diff)
downloadrust-1b245e7e0e83d387ab9d2cc7a157b081ba5d0ef2.tar.gz
rust-1b245e7e0e83d387ab9d2cc7a157b081ba5d0ef2.zip
Use visit_expr_field for ParamPosition
-rw-r--r--clippy_utils/src/macros.rs87
1 files changed, 36 insertions, 51 deletions
diff --git a/clippy_utils/src/macros.rs b/clippy_utils/src/macros.rs
index bd89ff977f8..058a15590ab 100644
--- a/clippy_utils/src/macros.rs
+++ b/clippy_utils/src/macros.rs
@@ -8,7 +8,7 @@ use arrayvec::ArrayVec;
 use itertools::{izip, Either, Itertools};
 use rustc_ast::ast::LitKind;
 use rustc_hir::intravisit::Visitor;
-use rustc_hir::{self as hir, Expr, ExprKind, HirId, Node, QPath};
+use rustc_hir::{self as hir, Expr, ExprField, ExprKind, HirId, Node, QPath};
 use rustc_lexer::unescape::unescape_literal;
 use rustc_lexer::{tokenize, unescape, LiteralKind, TokenKind};
 use rustc_lint::LateContext;
@@ -485,64 +485,49 @@ struct ParamPosition {
     precision: Option<usize>,
 }
 
-/// Parses the `fmt` arg of `Arguments::new_v1_formatted(pieces, args, fmt, _)`
-fn parse_rt_fmt<'tcx>(fmt_arg: &'tcx Expr<'tcx>) -> Option<impl Iterator<Item = ParamPosition> + 'tcx> {
-    fn parse_count(expr: &Expr<'_>) -> Option<usize> {
-        // ::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
+impl<'tcx> Visitor<'tcx> for ParamPosition {
+    fn visit_expr_field(&mut self, field: &'tcx ExprField<'tcx>) {
+        fn parse_count(expr: &Expr<'_>) -> Option<usize> {
+            // ::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
+                    && let LitKind::Int(pos, _) = lit.node
+                {
+                    self.value = pos as usize;
+                }
+            },
+            sym::precision => {
+                self.precision = parse_count(field.expr);
+            },
+            sym::width => {
+                self.width = parse_count(field.expr);
+            },
+            _ => {},
         }
     }
+}
 
+/// Parses the `fmt` arg of `Arguments::new_v1_formatted(pieces, args, fmt, _)`
+fn parse_rt_fmt<'tcx>(fmt_arg: &'tcx Expr<'tcx>) -> Option<impl Iterator<Item = ParamPosition> + '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();
-
-            // ::core::fmt::rt::v1::Argument {
-            //     position: 0usize,
-            //     format: ::core::fmt::rt::v1::FormatSpec {
-            //         ..
-            //         precision: ::core::fmt::rt::v1::Count::Implied,
-            //         width: ::core::fmt::rt::v1::Count::Implied,
-            //     },
-            // }
-
-            // TODO: this can be made much nicer next sync with `Visitor::visit_expr_field`
-            if let ExprKind::Struct(_, fields, _) = spec.kind {
-                for field in fields {
-                    match (field.ident.name, &field.expr.kind) {
-                        (sym::position, ExprKind::Lit(lit)) => {
-                            if let LitKind::Int(pos, _) = lit.node {
-                                position.value = pos as usize;
-                            }
-                        },
-                        (sym::format, &ExprKind::Struct(_, spec_fields, _)) => {
-                            for spec_field in spec_fields {
-                                match spec_field.ident.name {
-                                    sym::precision => {
-                                        position.precision = parse_count(spec_field.expr);
-                                    },
-                                    sym::width => {
-                                        position.width = parse_count(spec_field.expr);
-                                    },
-                                    _ => {},
-                                }
-                            }
-                        },
-                        _ => {},
-                    }
-                }
-            }
-
+            position.visit_expr(spec);
             position
         }))
     } else {