Unnamed repository; edit this file 'description' to name the repository.
fix: Fix format_args lowering passing incorrect parameters to rustc_parse_format
Lukas Wirth 2024-05-22
parent 21ec8f5 · commit 4f17d07
-rw-r--r--crates/hir-def/src/body/lower.rs10
-rw-r--r--crates/hir-def/src/body/tests.rs4
-rw-r--r--crates/hir-def/src/hir/format_args.rs10
3 files changed, 18 insertions, 6 deletions
diff --git a/crates/hir-def/src/body/lower.rs b/crates/hir-def/src/body/lower.rs
index 82f89393ad..c6d9ba6cfe 100644
--- a/crates/hir-def/src/body/lower.rs
+++ b/crates/hir-def/src/body/lower.rs
@@ -17,7 +17,7 @@ use syntax::{
self, ArrayExprKind, AstChildren, BlockExpr, HasArgList, HasAttrs, HasLoopBody, HasName,
RangeItem, SlicePatComponents,
},
- AstNode, AstPtr, SyntaxNodePtr,
+ AstNode, AstPtr, AstToken as _, SyntaxNodePtr,
};
use triomphe::Arc;
@@ -1577,7 +1577,13 @@ impl ExprCollector<'_> {
});
});
let template = f.template();
- let fmt_snippet = template.as_ref().map(ToString::to_string);
+ let fmt_snippet = template.as_ref().and_then(|it| match it {
+ ast::Expr::Literal(literal) => match literal.kind() {
+ ast::LiteralKind::String(s) => Some(s.text().to_owned()),
+ _ => None,
+ },
+ _ => None,
+ });
let mut mappings = vec![];
let fmt = match template.and_then(|it| self.expand_macros_to_string(it)) {
Some((s, is_direct_literal)) => format_args::parse(
diff --git a/crates/hir-def/src/body/tests.rs b/crates/hir-def/src/body/tests.rs
index 4c8a54f7c8..e8b26d5373 100644
--- a/crates/hir-def/src/body/tests.rs
+++ b/crates/hir-def/src/body/tests.rs
@@ -150,7 +150,7 @@ fn desugar_builtin_format_args() {
fn main() {
let are = "are";
let count = 10;
- builtin#format_args("hello {count:02} {} friends, we {are:?} {0}{last}", "fancy", last = "!");
+ builtin#format_args("\u{1b}hello {count:02} {} friends, we {are:?} {0}{last}", "fancy", last = "!");
}
"#,
);
@@ -161,7 +161,7 @@ fn main() {
let count = 10;
builtin#lang(Arguments::new_v1_formatted)(
&[
- "hello ", " ", " friends, we ", " ", "",
+ "\u{1b}hello ", " ", " friends, we ", " ", "",
],
&[
builtin#lang(Argument::new_display)(
diff --git a/crates/hir-def/src/hir/format_args.rs b/crates/hir-def/src/hir/format_args.rs
index b097a721c7..de0fa982c8 100644
--- a/crates/hir-def/src/hir/format_args.rs
+++ b/crates/hir-def/src/hir/format_args.rs
@@ -175,7 +175,13 @@ pub(crate) fn parse(
mut synth: impl FnMut(Name) -> ExprId,
mut record_usage: impl FnMut(Name, Option<TextRange>),
) -> FormatArgs {
- let text = s.text_without_quotes();
+ let Ok(text) = s.value() else {
+ return FormatArgs {
+ template: Default::default(),
+ arguments: args.finish(),
+ orphans: vec![],
+ };
+ };
let str_style = match s.quote_offsets() {
Some(offsets) => {
let raw = usize::from(offsets.quotes.0.len()) - 1;
@@ -186,7 +192,7 @@ pub(crate) fn parse(
};
let mut parser =
- parse::Parser::new(text, str_style, fmt_snippet, false, parse::ParseMode::Format);
+ parse::Parser::new(&text, str_style, fmt_snippet, false, parse::ParseMode::Format);
let mut pieces = Vec::new();
while let Some(piece) = parser.next() {