Auto merge of #15415 - Veykril:eager-parser-input, r=Veykril

fix: Fix float parser hack creating empty NameRef tokens

Fixes https://github.com/rust-lang/rust-analyzer/issues/15403
This commit is contained in:
bors 2023-08-08 12:46:32 +00:00
commit 44eeaea68b
4 changed files with 46 additions and 7 deletions

View file

@ -909,3 +909,30 @@ macro_rules! with_std {
"##]],
)
}
#[test]
fn eager_regression_15403() {
check(
r#"
#[rustc_builtin_macro]
#[macro_export]
macro_rules! format_args {}
fn main() {
format_args /* +errors */ !("{}", line.1.);
}
"#,
expect![[r##"
#[rustc_builtin_macro]
#[macro_export]
macro_rules! format_args {}
fn main() {
/* error: expected field name or number *//* parse error: expected field name or number */
::core::fmt::Arguments::new_v1(&["", ], &[::core::fmt::ArgumentV1::new(&(line.1.), ::core::fmt::Display::fmt), ]);
}
"##]],
);
}

View file

@ -961,6 +961,7 @@ impl TtTreeSink<'_> {
if has_pseudo_dot {
assert!(right.is_empty(), "{left}.{right}");
} else {
assert!(!right.is_empty(), "{left}.{right}");
self.inner.start_node(SyntaxKind::NAME_REF);
self.inner.token(SyntaxKind::INT_NUMBER, right);
self.inner.finish_node();

View file

@ -46,12 +46,16 @@ impl LexedStr<'_> {
// Tag the token as joint if it is float with a fractional part
// we use this jointness to inform the parser about what token split
// event to emit when we encounter a float literal in a field access
if kind == SyntaxKind::FLOAT_NUMBER && !self.text(i).ends_with('.') {
res.was_joint();
if kind == SyntaxKind::FLOAT_NUMBER {
if !self.text(i).ends_with('.') {
res.was_joint();
} else {
was_joint = false;
}
} else {
was_joint = true;
}
}
was_joint = true;
}
}
res
@ -204,6 +208,7 @@ impl Builder<'_, '_> {
assert!(right.is_empty(), "{left}.{right}");
self.state = State::Normal;
} else {
assert!(!right.is_empty(), "{left}.{right}");
(self.sink)(StrStep::Enter { kind: SyntaxKind::NAME_REF });
(self.sink)(StrStep::Token { kind: SyntaxKind::INT_NUMBER, text: right });
(self.sink)(StrStep::Exit);

View file

@ -195,11 +195,16 @@ impl ast::TokenTree {
// Tag the token as joint if it is float with a fractional part
// we use this jointness to inform the parser about what token split
// event to emit when we encounter a float literal in a field access
if kind == SyntaxKind::FLOAT_NUMBER && !t.text().ends_with('.') {
parser_input.was_joint();
if kind == SyntaxKind::FLOAT_NUMBER {
if !t.text().ends_with('.') {
parser_input.was_joint();
} else {
was_joint = false;
}
} else {
was_joint = true;
}
}
was_joint = true;
}
}
@ -250,6 +255,7 @@ impl ast::TokenTree {
if has_pseudo_dot {
assert!(right.is_empty(), "{left}.{right}");
} else {
assert!(!right.is_empty(), "{left}.{right}");
builder.start_node(SyntaxKind::NAME_REF);
builder.token(SyntaxKind::INT_NUMBER, right);
builder.finish_node();