Auto merge of #90485 - camsteffen:fmt-args-less-bind, r=m-ou-se
Don't destructure args tuple in format_args! This allows Clippy to parse the HIR more simply since `arg0` is changed to `_args.0`. (cc rust-lang/rust-clippy#7843). From rustc's perspective, I think this is something between a lateral move and a tiny improvement since there are fewer bindings. r? `@m-ou-se`
This commit is contained in:
commit
60952bc3da
@ -760,16 +760,11 @@ impl<'a, 'b> Context<'a, 'b> {
|
|||||||
/// Actually builds the expression which the format_args! block will be
|
/// Actually builds the expression which the format_args! block will be
|
||||||
/// expanded to.
|
/// expanded to.
|
||||||
fn into_expr(self) -> P<ast::Expr> {
|
fn into_expr(self) -> P<ast::Expr> {
|
||||||
let mut locals =
|
let mut args = Vec::with_capacity(
|
||||||
Vec::with_capacity((0..self.args.len()).map(|i| self.arg_unique_types[i].len()).sum());
|
self.arg_unique_types.iter().map(|v| v.len()).sum::<usize>() + self.count_args.len(),
|
||||||
let mut counts = Vec::with_capacity(self.count_args.len());
|
);
|
||||||
let mut pats = Vec::with_capacity(self.args.len());
|
|
||||||
let mut heads = Vec::with_capacity(self.args.len());
|
let mut heads = Vec::with_capacity(self.args.len());
|
||||||
|
|
||||||
let names_pos: Vec<_> = (0..self.args.len())
|
|
||||||
.map(|i| Ident::from_str_and_span(&format!("arg{}", i), self.macsp))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
// First, build up the static array which will become our precompiled
|
// First, build up the static array which will become our precompiled
|
||||||
// format "string"
|
// format "string"
|
||||||
let pieces = self.ecx.expr_vec_slice(self.fmtsp, self.str_pieces);
|
let pieces = self.ecx.expr_vec_slice(self.fmtsp, self.str_pieces);
|
||||||
@ -787,11 +782,8 @@ impl<'a, 'b> Context<'a, 'b> {
|
|||||||
// of each variable because we don't want to move out of the arguments
|
// of each variable because we don't want to move out of the arguments
|
||||||
// passed to this function.
|
// passed to this function.
|
||||||
for (i, e) in self.args.into_iter().enumerate() {
|
for (i, e) in self.args.into_iter().enumerate() {
|
||||||
let name = names_pos[i];
|
|
||||||
let span = self.ecx.with_def_site_ctxt(e.span);
|
|
||||||
pats.push(self.ecx.pat_ident(span, name));
|
|
||||||
for arg_ty in self.arg_unique_types[i].iter() {
|
for arg_ty in self.arg_unique_types[i].iter() {
|
||||||
locals.push(Context::format_arg(self.ecx, self.macsp, e.span, arg_ty, name));
|
args.push(Context::format_arg(self.ecx, self.macsp, e.span, arg_ty, i));
|
||||||
}
|
}
|
||||||
heads.push(self.ecx.expr_addr_of(e.span, e));
|
heads.push(self.ecx.expr_addr_of(e.span, e));
|
||||||
}
|
}
|
||||||
@ -800,15 +792,11 @@ impl<'a, 'b> Context<'a, 'b> {
|
|||||||
Exact(i) => i,
|
Exact(i) => i,
|
||||||
_ => panic!("should never happen"),
|
_ => panic!("should never happen"),
|
||||||
};
|
};
|
||||||
let name = names_pos[index];
|
|
||||||
let span = spans_pos[index];
|
let span = spans_pos[index];
|
||||||
counts.push(Context::format_arg(self.ecx, self.macsp, span, &Count, name));
|
args.push(Context::format_arg(self.ecx, self.macsp, span, &Count, index));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now create a vector containing all the arguments
|
let args_array = self.ecx.expr_vec(self.macsp, args);
|
||||||
let args = locals.into_iter().chain(counts.into_iter());
|
|
||||||
|
|
||||||
let args_array = self.ecx.expr_vec(self.macsp, args.collect());
|
|
||||||
|
|
||||||
// Constructs an AST equivalent to:
|
// Constructs an AST equivalent to:
|
||||||
//
|
//
|
||||||
@ -838,7 +826,7 @@ impl<'a, 'b> Context<'a, 'b> {
|
|||||||
// But the nested match expression is proved to perform not as well
|
// But the nested match expression is proved to perform not as well
|
||||||
// as series of let's; the first approach does.
|
// as series of let's; the first approach does.
|
||||||
let args_match = {
|
let args_match = {
|
||||||
let pat = self.ecx.pat_tuple(self.macsp, pats);
|
let pat = self.ecx.pat_ident(self.macsp, Ident::new(sym::_args, self.macsp));
|
||||||
let arm = self.ecx.arm(self.macsp, pat, args_array);
|
let arm = self.ecx.arm(self.macsp, pat, args_array);
|
||||||
let head = self.ecx.expr(self.macsp, ast::ExprKind::Tup(heads));
|
let head = self.ecx.expr(self.macsp, ast::ExprKind::Tup(heads));
|
||||||
self.ecx.expr_match(self.macsp, head, vec![arm])
|
self.ecx.expr_match(self.macsp, head, vec![arm])
|
||||||
@ -877,10 +865,11 @@ impl<'a, 'b> Context<'a, 'b> {
|
|||||||
macsp: Span,
|
macsp: Span,
|
||||||
mut sp: Span,
|
mut sp: Span,
|
||||||
ty: &ArgumentType,
|
ty: &ArgumentType,
|
||||||
arg: Ident,
|
arg_index: usize,
|
||||||
) -> P<ast::Expr> {
|
) -> P<ast::Expr> {
|
||||||
sp = ecx.with_def_site_ctxt(sp);
|
sp = ecx.with_def_site_ctxt(sp);
|
||||||
let arg = ecx.expr_ident(sp, arg);
|
let arg = ecx.expr_ident(sp, Ident::new(sym::_args, sp));
|
||||||
|
let arg = ecx.expr(sp, ast::ExprKind::Field(arg, Ident::new(sym::integer(arg_index), sp)));
|
||||||
let trait_ = match *ty {
|
let trait_ = match *ty {
|
||||||
Placeholder(trait_) if trait_ == "<invalid>" => return DummyResult::raw_expr(sp, true),
|
Placeholder(trait_) if trait_ == "<invalid>" => return DummyResult::raw_expr(sp, true),
|
||||||
Placeholder(trait_) => trait_,
|
Placeholder(trait_) => trait_,
|
||||||
|
@ -271,6 +271,7 @@ symbols! {
|
|||||||
__S,
|
__S,
|
||||||
__next,
|
__next,
|
||||||
__try_var,
|
__try_var,
|
||||||
|
_args,
|
||||||
_d,
|
_d,
|
||||||
_e,
|
_e,
|
||||||
_task_context,
|
_task_context,
|
||||||
|
@ -12,7 +12,7 @@ fn main() {
|
|||||||
{
|
{
|
||||||
::std::io::_print(::core::fmt::Arguments::new_v1(&["rust\n"],
|
::std::io::_print(::core::fmt::Arguments::new_v1(&["rust\n"],
|
||||||
&match () {
|
&match () {
|
||||||
() => [],
|
_args => [],
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ pub fn bar() ({
|
|||||||
as
|
as
|
||||||
())
|
())
|
||||||
{
|
{
|
||||||
()
|
_args
|
||||||
=>
|
=>
|
||||||
([]
|
([]
|
||||||
as
|
as
|
||||||
|
@ -19,8 +19,8 @@ error: unexpected token: `{
|
|||||||
let res =
|
let res =
|
||||||
::alloc::fmt::format(::core::fmt::Arguments::new_v1(&[""],
|
::alloc::fmt::format(::core::fmt::Arguments::new_v1(&[""],
|
||||||
&match (&"u8",) {
|
&match (&"u8",) {
|
||||||
(arg0,) =>
|
_args =>
|
||||||
[::core::fmt::ArgumentV1::new(arg0,
|
[::core::fmt::ArgumentV1::new(_args.0,
|
||||||
::core::fmt::Display::fmt)],
|
::core::fmt::Display::fmt)],
|
||||||
}));
|
}));
|
||||||
res
|
res
|
||||||
|
@ -9,7 +9,7 @@ LL | let c1 : () = c;
|
|||||||
| expected due to this
|
| expected due to this
|
||||||
|
|
|
|
||||||
= note: expected unit type `()`
|
= note: expected unit type `()`
|
||||||
found closure `[mod1::f<T>::{closure#0} closure_substs=(unavailable) substs=[T, _#25t, extern "rust-call" fn(()), _#26t]]`
|
found closure `[mod1::f<T>::{closure#0} closure_substs=(unavailable) substs=[T, _#22t, extern "rust-call" fn(()), _#23t]]`
|
||||||
help: use parentheses to call this closure
|
help: use parentheses to call this closure
|
||||||
|
|
|
|
||||||
LL | let c1 : () = c();
|
LL | let c1 : () = c();
|
||||||
|
@ -9,7 +9,7 @@ LL | let c1 : () = c;
|
|||||||
| expected due to this
|
| expected due to this
|
||||||
|
|
|
|
||||||
= note: expected unit type `()`
|
= note: expected unit type `()`
|
||||||
found closure `[f<T>::{closure#0} closure_substs=(unavailable) substs=[T, _#25t, extern "rust-call" fn(()), _#26t]]`
|
found closure `[f<T>::{closure#0} closure_substs=(unavailable) substs=[T, _#22t, extern "rust-call" fn(()), _#23t]]`
|
||||||
help: use parentheses to call this closure
|
help: use parentheses to call this closure
|
||||||
|
|
|
|
||||||
LL | let c1 : () = c();
|
LL | let c1 : () = c();
|
||||||
|
@ -3,12 +3,12 @@
|
|||||||
#![deny(clippy::missing_docs_in_private_items)]
|
#![deny(clippy::missing_docs_in_private_items)]
|
||||||
|
|
||||||
use crate::ty::is_type_diagnostic_item;
|
use crate::ty::is_type_diagnostic_item;
|
||||||
use crate::{is_expn_of, last_path_segment, match_def_path, path_to_local_id, paths};
|
use crate::{is_expn_of, last_path_segment, match_def_path, paths};
|
||||||
use if_chain::if_chain;
|
use if_chain::if_chain;
|
||||||
use rustc_ast::ast::{self, LitKind};
|
use rustc_ast::ast::{self, LitKind};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::{
|
use rustc_hir::{
|
||||||
Arm, Block, BorrowKind, Expr, ExprKind, HirId, LoopSource, MatchSource, Node, Pat, PatKind, QPath, StmtKind, UnOp,
|
Arm, Block, BorrowKind, Expr, ExprKind, HirId, LoopSource, MatchSource, Node, Pat, QPath, StmtKind, UnOp,
|
||||||
};
|
};
|
||||||
use rustc_lint::LateContext;
|
use rustc_lint::LateContext;
|
||||||
use rustc_span::{sym, symbol, ExpnKind, Span, Symbol};
|
use rustc_span::{sym, symbol, ExpnKind, Span, Symbol};
|
||||||
@ -513,8 +513,6 @@ pub struct FormatArgsExpn<'tcx> {
|
|||||||
pub format_string_parts: &'tcx [Expr<'tcx>],
|
pub format_string_parts: &'tcx [Expr<'tcx>],
|
||||||
/// Symbols corresponding to [`Self::format_string_parts`]
|
/// Symbols corresponding to [`Self::format_string_parts`]
|
||||||
pub format_string_symbols: Vec<Symbol>,
|
pub format_string_symbols: Vec<Symbol>,
|
||||||
/// Match arm patterns, the `arg0`, etc. from the next field `args`
|
|
||||||
pub arg_names: &'tcx [Pat<'tcx>],
|
|
||||||
/// Expressions like `ArgumentV1::new(arg0, Debug::fmt)`
|
/// Expressions like `ArgumentV1::new(arg0, Debug::fmt)`
|
||||||
pub args: &'tcx [Expr<'tcx>],
|
pub args: &'tcx [Expr<'tcx>],
|
||||||
/// The final argument passed to `Arguments::new_v1_formatted`, if applicable
|
/// The final argument passed to `Arguments::new_v1_formatted`, if applicable
|
||||||
@ -559,7 +557,6 @@ impl FormatArgsExpn<'tcx> {
|
|||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
if let PatKind::Tuple(arg_names, None) = arm.pat.kind;
|
|
||||||
if let ExprKind::Array(args) = arm.body.kind;
|
if let ExprKind::Array(args) = arm.body.kind;
|
||||||
then {
|
then {
|
||||||
Some(FormatArgsExpn {
|
Some(FormatArgsExpn {
|
||||||
@ -567,7 +564,6 @@ impl FormatArgsExpn<'tcx> {
|
|||||||
value_args,
|
value_args,
|
||||||
format_string_parts,
|
format_string_parts,
|
||||||
format_string_symbols,
|
format_string_symbols,
|
||||||
arg_names,
|
|
||||||
args,
|
args,
|
||||||
fmt_expr,
|
fmt_expr,
|
||||||
})
|
})
|
||||||
@ -594,10 +590,8 @@ impl FormatArgsExpn<'tcx> {
|
|||||||
if let Ok(i) = usize::try_from(position);
|
if let Ok(i) = usize::try_from(position);
|
||||||
let arg = &self.args[i];
|
let arg = &self.args[i];
|
||||||
if let ExprKind::Call(_, [arg_name, _]) = arg.kind;
|
if let ExprKind::Call(_, [arg_name, _]) = arg.kind;
|
||||||
if let Some(j) = self
|
if let ExprKind::Field(_, j) = arg_name.kind;
|
||||||
.arg_names
|
if let Ok(j) = j.name.as_str().parse::<usize>();
|
||||||
.iter()
|
|
||||||
.position(|pat| path_to_local_id(arg_name, pat.hir_id));
|
|
||||||
then {
|
then {
|
||||||
Some(FormatArgsArg { value: self.value_args[j], arg, fmt: Some(fmt) })
|
Some(FormatArgsArg { value: self.value_args[j], arg, fmt: Some(fmt) })
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user