mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-28 14:03:35 +00:00
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:
commit
44eeaea68b
4 changed files with 46 additions and 7 deletions
|
@ -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), ]);
|
||||||
|
}
|
||||||
|
|
||||||
|
"##]],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
@ -961,6 +961,7 @@ impl TtTreeSink<'_> {
|
||||||
if has_pseudo_dot {
|
if has_pseudo_dot {
|
||||||
assert!(right.is_empty(), "{left}.{right}");
|
assert!(right.is_empty(), "{left}.{right}");
|
||||||
} else {
|
} else {
|
||||||
|
assert!(!right.is_empty(), "{left}.{right}");
|
||||||
self.inner.start_node(SyntaxKind::NAME_REF);
|
self.inner.start_node(SyntaxKind::NAME_REF);
|
||||||
self.inner.token(SyntaxKind::INT_NUMBER, right);
|
self.inner.token(SyntaxKind::INT_NUMBER, right);
|
||||||
self.inner.finish_node();
|
self.inner.finish_node();
|
||||||
|
|
|
@ -46,12 +46,16 @@ impl LexedStr<'_> {
|
||||||
// Tag the token as joint if it is float with a fractional part
|
// 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
|
// 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
|
// event to emit when we encounter a float literal in a field access
|
||||||
if kind == SyntaxKind::FLOAT_NUMBER && !self.text(i).ends_with('.') {
|
if kind == SyntaxKind::FLOAT_NUMBER {
|
||||||
res.was_joint();
|
if !self.text(i).ends_with('.') {
|
||||||
|
res.was_joint();
|
||||||
|
} else {
|
||||||
|
was_joint = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
was_joint = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
was_joint = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
res
|
res
|
||||||
|
@ -204,6 +208,7 @@ impl Builder<'_, '_> {
|
||||||
assert!(right.is_empty(), "{left}.{right}");
|
assert!(right.is_empty(), "{left}.{right}");
|
||||||
self.state = State::Normal;
|
self.state = State::Normal;
|
||||||
} else {
|
} else {
|
||||||
|
assert!(!right.is_empty(), "{left}.{right}");
|
||||||
(self.sink)(StrStep::Enter { kind: SyntaxKind::NAME_REF });
|
(self.sink)(StrStep::Enter { kind: SyntaxKind::NAME_REF });
|
||||||
(self.sink)(StrStep::Token { kind: SyntaxKind::INT_NUMBER, text: right });
|
(self.sink)(StrStep::Token { kind: SyntaxKind::INT_NUMBER, text: right });
|
||||||
(self.sink)(StrStep::Exit);
|
(self.sink)(StrStep::Exit);
|
||||||
|
|
|
@ -195,11 +195,16 @@ impl ast::TokenTree {
|
||||||
// Tag the token as joint if it is float with a fractional part
|
// 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
|
// 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
|
// event to emit when we encounter a float literal in a field access
|
||||||
if kind == SyntaxKind::FLOAT_NUMBER && !t.text().ends_with('.') {
|
if kind == SyntaxKind::FLOAT_NUMBER {
|
||||||
parser_input.was_joint();
|
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 {
|
if has_pseudo_dot {
|
||||||
assert!(right.is_empty(), "{left}.{right}");
|
assert!(right.is_empty(), "{left}.{right}");
|
||||||
} else {
|
} else {
|
||||||
|
assert!(!right.is_empty(), "{left}.{right}");
|
||||||
builder.start_node(SyntaxKind::NAME_REF);
|
builder.start_node(SyntaxKind::NAME_REF);
|
||||||
builder.token(SyntaxKind::INT_NUMBER, right);
|
builder.token(SyntaxKind::INT_NUMBER, right);
|
||||||
builder.finish_node();
|
builder.finish_node();
|
||||||
|
|
Loading…
Reference in a new issue