Support flattening/inlining format_args through & and ().
E.g. format_args!("{}", &(format_args!("abc"))).
This commit is contained in:
parent
85ef2f0cfe
commit
caa6ba9e86
@ -1184,6 +1184,15 @@ impl Expr {
|
|||||||
expr
|
expr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn peel_parens_and_refs(&self) -> &Expr {
|
||||||
|
let mut expr = self;
|
||||||
|
while let ExprKind::Paren(inner) | ExprKind::AddrOf(BorrowKind::Ref, _, inner) = &expr.kind
|
||||||
|
{
|
||||||
|
expr = inner;
|
||||||
|
}
|
||||||
|
expr
|
||||||
|
}
|
||||||
|
|
||||||
/// Attempts to reparse as `Ty` (for diagnostic purposes).
|
/// Attempts to reparse as `Ty` (for diagnostic purposes).
|
||||||
pub fn to_ty(&self) -> Option<P<Ty>> {
|
pub fn to_ty(&self) -> Option<P<Ty>> {
|
||||||
let kind = match &self.kind {
|
let kind = match &self.kind {
|
||||||
|
@ -34,7 +34,7 @@ fn flatten_format_args(mut fmt: Cow<'_, FormatArgs>) -> Cow<'_, FormatArgs> {
|
|||||||
if let FormatArgsPiece::Placeholder(placeholder) = &fmt.template[i]
|
if let FormatArgsPiece::Placeholder(placeholder) = &fmt.template[i]
|
||||||
&& let FormatTrait::Display | FormatTrait::Debug = &placeholder.format_trait
|
&& let FormatTrait::Display | FormatTrait::Debug = &placeholder.format_trait
|
||||||
&& let Ok(arg_index) = placeholder.argument.index
|
&& let Ok(arg_index) = placeholder.argument.index
|
||||||
&& let arg = &fmt.arguments.all_args()[arg_index].expr
|
&& let arg = fmt.arguments.all_args()[arg_index].expr.peel_parens_and_refs()
|
||||||
&& let ExprKind::FormatArgs(_) = &arg.kind
|
&& let ExprKind::FormatArgs(_) = &arg.kind
|
||||||
// Check that this argument is not used by any other placeholders.
|
// Check that this argument is not used by any other placeholders.
|
||||||
&& fmt.template.iter().enumerate().all(|(j, p)|
|
&& fmt.template.iter().enumerate().all(|(j, p)|
|
||||||
@ -54,9 +54,14 @@ fn flatten_format_args(mut fmt: Cow<'_, FormatArgs>) -> Cow<'_, FormatArgs> {
|
|||||||
let args = fmt.arguments.all_args_mut();
|
let args = fmt.arguments.all_args_mut();
|
||||||
let remaining_args = args.split_off(arg_index + 1);
|
let remaining_args = args.split_off(arg_index + 1);
|
||||||
let old_arg_offset = args.len();
|
let old_arg_offset = args.len();
|
||||||
let fmt2 = args.pop().unwrap().expr.into_inner(); // The inner FormatArgs.
|
let mut fmt2 = &mut args.pop().unwrap().expr; // The inner FormatArgs.
|
||||||
let ExprKind::FormatArgs(fmt2) = fmt2.kind else { unreachable!() };
|
let fmt2 = loop { // Unwrap the Expr to get to the FormatArgs.
|
||||||
let mut fmt2 = fmt2.into_inner();
|
match &mut fmt2.kind {
|
||||||
|
ExprKind::Paren(inner) | ExprKind::AddrOf(BorrowKind::Ref, _, inner) => fmt2 = inner,
|
||||||
|
ExprKind::FormatArgs(fmt2) => break fmt2,
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
args.append(fmt2.arguments.all_args_mut());
|
args.append(fmt2.arguments.all_args_mut());
|
||||||
let new_arg_offset = args.len();
|
let new_arg_offset = args.len();
|
||||||
@ -78,7 +83,7 @@ fn flatten_format_args(mut fmt: Cow<'_, FormatArgs>) -> Cow<'_, FormatArgs> {
|
|||||||
let rest = fmt.template.split_off(i + 1);
|
let rest = fmt.template.split_off(i + 1);
|
||||||
fmt.template.pop(); // remove the placeholder for the nested fmt args.
|
fmt.template.pop(); // remove the placeholder for the nested fmt args.
|
||||||
|
|
||||||
for piece in fmt2.template {
|
for piece in fmt2.template.drain(..) {
|
||||||
match piece {
|
match piece {
|
||||||
FormatArgsPiece::Literal(s) => fmt.template.push(FormatArgsPiece::Literal(s)),
|
FormatArgsPiece::Literal(s) => fmt.template.push(FormatArgsPiece::Literal(s)),
|
||||||
FormatArgsPiece::Placeholder(mut p) => {
|
FormatArgsPiece::Placeholder(mut p) => {
|
||||||
@ -119,7 +124,8 @@ fn inline_literals(mut fmt: Cow<'_, FormatArgs>) -> Cow<'_, FormatArgs> {
|
|||||||
let FormatArgsPiece::Placeholder(placeholder) = &fmt.template[i] else { continue };
|
let FormatArgsPiece::Placeholder(placeholder) = &fmt.template[i] else { continue };
|
||||||
let Ok(arg_index) = placeholder.argument.index else { continue };
|
let Ok(arg_index) = placeholder.argument.index else { continue };
|
||||||
if let FormatTrait::Display = placeholder.format_trait
|
if let FormatTrait::Display = placeholder.format_trait
|
||||||
&& let ExprKind::Lit(lit) = fmt.arguments.all_args()[arg_index].expr.kind
|
&& let arg = fmt.arguments.all_args()[arg_index].expr.peel_parens_and_refs()
|
||||||
|
&& let ExprKind::Lit(lit) = arg.kind
|
||||||
&& let token::LitKind::Str | token::LitKind::StrRaw(_) = lit.kind
|
&& let token::LitKind::Str | token::LitKind::StrRaw(_) = lit.kind
|
||||||
&& let Ok(LitKind::Str(s, _)) = LitKind::from_token_lit(lit)
|
&& let Ok(LitKind::Str(s, _)) = LitKind::from_token_lit(lit)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user