mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-24 05:33:27 +00:00
Use visit_expr_field for ParamPosition
This commit is contained in:
parent
5652ccbc0f
commit
1b245e7e0e
1 changed files with 36 additions and 51 deletions
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue