Don't allocate the format_args template string as an expression
This commit is contained in:
parent
3fa0bf0dd3
commit
5046889f43
@ -32,7 +32,7 @@
|
|||||||
hir::{
|
hir::{
|
||||||
dummy_expr_id,
|
dummy_expr_id,
|
||||||
format_args::{
|
format_args::{
|
||||||
self, FormatAlignment, FormatArgsPiece, FormatArgument, FormatArgumentKind,
|
self, FormatAlignment, FormatArgs, FormatArgsPiece, FormatArgument, FormatArgumentKind,
|
||||||
FormatArgumentsCollector, FormatCount, FormatDebugHex, FormatOptions,
|
FormatArgumentsCollector, FormatCount, FormatDebugHex, FormatOptions,
|
||||||
FormatPlaceholder, FormatSign, FormatTrait,
|
FormatPlaceholder, FormatSign, FormatTrait,
|
||||||
},
|
},
|
||||||
@ -1568,6 +1568,24 @@ fn with_opt_labeled_rib<T>(
|
|||||||
// endregion: labels
|
// endregion: labels
|
||||||
|
|
||||||
// region: format
|
// region: format
|
||||||
|
fn expand_macros_to_string(&mut self, expr: ast::Expr) -> Option<(ast::String, bool)> {
|
||||||
|
let m = match expr {
|
||||||
|
ast::Expr::MacroExpr(m) => m,
|
||||||
|
ast::Expr::Literal(l) => {
|
||||||
|
return match l.kind() {
|
||||||
|
ast::LiteralKind::String(s) => Some((s, true)),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => return None,
|
||||||
|
};
|
||||||
|
let e = m.macro_call()?;
|
||||||
|
let macro_ptr = AstPtr::new(&e);
|
||||||
|
let (exp, _) = self.collect_macro_call(e, macro_ptr, true, |this, expansion| {
|
||||||
|
expansion.and_then(|it| this.expand_macros_to_string(it))
|
||||||
|
})?;
|
||||||
|
Some((exp, false))
|
||||||
|
}
|
||||||
|
|
||||||
fn collect_format_args(
|
fn collect_format_args(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -1586,31 +1604,13 @@ fn collect_format_args(
|
|||||||
});
|
});
|
||||||
let template = f.template();
|
let template = f.template();
|
||||||
let fmt_snippet = template.as_ref().map(ToString::to_string);
|
let fmt_snippet = template.as_ref().map(ToString::to_string);
|
||||||
|
let fmt = match template.and_then(|it| self.expand_macros_to_string(it)) {
|
||||||
// FIXME: We shouldn't allocate this one, just resolve and expand the macros to fetch the
|
Some((s, is_direct_literal)) => {
|
||||||
// string literal!
|
format_args::parse(&s, fmt_snippet, args, is_direct_literal, |name| {
|
||||||
let expr = self.collect_expr_opt(template);
|
self.alloc_expr_desugared(Expr::Path(Path::from(name)))
|
||||||
|
})
|
||||||
let fmt = 'b: {
|
|
||||||
if let Expr::Literal(Literal::String(_)) = self.body[expr] {
|
|
||||||
let source = self.source_map.expr_map_back[expr].clone();
|
|
||||||
let is_direct_literal = source.file_id == self.expander.current_file_id;
|
|
||||||
if let ast::Expr::Literal(l) =
|
|
||||||
source.value.to_node(&self.db.parse_or_expand(source.file_id))
|
|
||||||
{
|
|
||||||
if let ast::LiteralKind::String(s) = l.kind() {
|
|
||||||
break 'b format_args::parse(
|
|
||||||
expr,
|
|
||||||
&s,
|
|
||||||
fmt_snippet,
|
|
||||||
args,
|
|
||||||
is_direct_literal,
|
|
||||||
|name| self.alloc_expr_desugared(Expr::Path(Path::from(name))),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return self.missing_expr();
|
None => FormatArgs { template: Default::default(), arguments: args.finish() },
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create a list of all _unique_ (argument, format trait) combinations.
|
// Create a list of all _unique_ (argument, format trait) combinations.
|
||||||
|
@ -161,7 +161,7 @@ fn main() {
|
|||||||
let count = 10;
|
let count = 10;
|
||||||
builtin#lang(Arguments::new_v1_formatted)(
|
builtin#lang(Arguments::new_v1_formatted)(
|
||||||
&[
|
&[
|
||||||
"\"hello ", " ", " friends, we ", " ", "", "\"",
|
"\"hello ", " ", " friends, we ", " ", "", "\"",
|
||||||
],
|
],
|
||||||
&[
|
&[
|
||||||
builtin#lang(Argument::new_display)(
|
builtin#lang(Argument::new_display)(
|
||||||
@ -172,7 +172,7 @@ fn main() {
|
|||||||
&are,
|
&are,
|
||||||
), builtin#lang(Argument::new_display)(
|
), builtin#lang(Argument::new_display)(
|
||||||
&"!",
|
&"!",
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
&[
|
&[
|
||||||
builtin#lang(Placeholder::new)(
|
builtin#lang(Placeholder::new)(
|
||||||
@ -212,7 +212,7 @@ fn main() {
|
|||||||
0u32,
|
0u32,
|
||||||
builtin#lang(Count::Implied),
|
builtin#lang(Count::Implied),
|
||||||
builtin#lang(Count::Implied),
|
builtin#lang(Count::Implied),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
unsafe {
|
unsafe {
|
||||||
builtin#lang(UnsafeArg::new)()
|
builtin#lang(UnsafeArg::new)()
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
//! Parses `format_args` input.
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
use hir_expand::name::Name;
|
use hir_expand::name::Name;
|
||||||
@ -12,7 +13,6 @@
|
|||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct FormatArgs {
|
pub struct FormatArgs {
|
||||||
pub template_expr: ExprId,
|
|
||||||
pub template: Box<[FormatArgsPiece]>,
|
pub template: Box<[FormatArgsPiece]>,
|
||||||
pub arguments: FormatArguments,
|
pub arguments: FormatArguments,
|
||||||
}
|
}
|
||||||
@ -166,7 +166,6 @@ enum PositionUsedAs {
|
|||||||
use PositionUsedAs::*;
|
use PositionUsedAs::*;
|
||||||
|
|
||||||
pub(crate) fn parse(
|
pub(crate) fn parse(
|
||||||
expr: ExprId,
|
|
||||||
s: &ast::String,
|
s: &ast::String,
|
||||||
fmt_snippet: Option<String>,
|
fmt_snippet: Option<String>,
|
||||||
mut args: FormatArgumentsCollector,
|
mut args: FormatArgumentsCollector,
|
||||||
@ -195,11 +194,7 @@ pub(crate) fn parse(
|
|||||||
let is_source_literal = parser.is_source_literal;
|
let is_source_literal = parser.is_source_literal;
|
||||||
if !parser.errors.is_empty() {
|
if !parser.errors.is_empty() {
|
||||||
// FIXME: Diagnose
|
// FIXME: Diagnose
|
||||||
return FormatArgs {
|
return FormatArgs { template: Default::default(), arguments: args.finish() };
|
||||||
template_expr: expr,
|
|
||||||
template: Default::default(),
|
|
||||||
arguments: args.finish(),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let to_span = |inner_span: parse::InnerSpan| {
|
let to_span = |inner_span: parse::InnerSpan| {
|
||||||
@ -419,11 +414,7 @@ enum ArgRef<'a> {
|
|||||||
// FIXME: Diagnose
|
// FIXME: Diagnose
|
||||||
}
|
}
|
||||||
|
|
||||||
FormatArgs {
|
FormatArgs { template: template.into_boxed_slice(), arguments: args.finish() }
|
||||||
template_expr: expr,
|
|
||||||
template: template.into_boxed_slice(),
|
|
||||||
arguments: args.finish(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
@ -34,23 +34,17 @@ pub(crate) fn extract_expressions_from_format_string(
|
|||||||
let fmt_string = ctx.find_token_at_offset::<ast::String>()?;
|
let fmt_string = ctx.find_token_at_offset::<ast::String>()?;
|
||||||
let tt = fmt_string.syntax().parent().and_then(ast::TokenTree::cast)?;
|
let tt = fmt_string.syntax().parent().and_then(ast::TokenTree::cast)?;
|
||||||
|
|
||||||
dbg!();
|
|
||||||
let expanded_t = ast::String::cast(
|
let expanded_t = ast::String::cast(
|
||||||
ctx.sema.descend_into_macros_with_kind_preference(fmt_string.syntax().clone(), 0.into()),
|
ctx.sema.descend_into_macros_with_kind_preference(fmt_string.syntax().clone(), 0.into()),
|
||||||
)?;
|
)?;
|
||||||
dbg!();
|
|
||||||
if !is_format_string(&expanded_t) {
|
if !is_format_string(&expanded_t) {
|
||||||
dbg!();
|
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
dbg!();
|
|
||||||
let (new_fmt, extracted_args) = parse_format_exprs(fmt_string.text()).ok()?;
|
let (new_fmt, extracted_args) = parse_format_exprs(fmt_string.text()).ok()?;
|
||||||
dbg!();
|
|
||||||
if extracted_args.is_empty() {
|
if extracted_args.is_empty() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
dbg!();
|
|
||||||
|
|
||||||
acc.add(
|
acc.add(
|
||||||
AssistId(
|
AssistId(
|
||||||
|
Loading…
Reference in New Issue
Block a user