Unnamed repository; edit this file 'description' to name the repository.
Auto merge of #16770 - roife:fix-issue-16278, r=Veykril
fix: panic when using float numbers without dots in chain calls Fix #16278. This PR fixes the panic caused by using floating-point numbers without a dot (such as `1e2`) in chain calls. ------------- Although this syntax is very odd 🤣, r-a should not panic.
bors 2024-03-06
parent b85d38f · parent 91d181f · commit e5889c9
-rw-r--r--crates/parser/src/shortcuts.rs18
-rw-r--r--crates/parser/test_data/parser/err/0054_float_split_scientific_notation.rast88
-rw-r--r--crates/parser/test_data/parser/err/0054_float_split_scientific_notation.rs5
3 files changed, 109 insertions, 2 deletions
diff --git a/crates/parser/src/shortcuts.rs b/crates/parser/src/shortcuts.rs
index 680a70997d..cc2b63d1e6 100644
--- a/crates/parser/src/shortcuts.rs
+++ b/crates/parser/src/shortcuts.rs
@@ -190,7 +190,7 @@ impl Builder<'_, '_> {
fn do_float_split(&mut self, has_pseudo_dot: bool) {
let text = &self.lexed.range_text(self.pos..self.pos + 1);
- self.pos += 1;
+
match text.split_once('.') {
Some((left, right)) => {
assert!(!left.is_empty());
@@ -216,8 +216,22 @@ impl Builder<'_, '_> {
self.state = State::PendingExit;
}
}
- None => unreachable!(),
+ None => {
+ // illegal float literal which doesn't have dot in form (like 1e0)
+ // we should emit an error node here
+ (self.sink)(StrStep::Error { msg: "illegal float literal", pos: self.pos });
+ (self.sink)(StrStep::Enter { kind: SyntaxKind::ERROR });
+ (self.sink)(StrStep::Token { kind: SyntaxKind::FLOAT_NUMBER, text });
+ (self.sink)(StrStep::Exit);
+
+ // move up
+ (self.sink)(StrStep::Exit);
+
+ self.state = if has_pseudo_dot { State::Normal } else { State::PendingExit };
+ }
}
+
+ self.pos += 1;
}
}
diff --git a/crates/parser/test_data/parser/err/0054_float_split_scientific_notation.rast b/crates/parser/test_data/parser/err/0054_float_split_scientific_notation.rast
new file mode 100644
index 0000000000..d6ad733483
--- /dev/null
+++ b/crates/parser/test_data/parser/err/0054_float_split_scientific_notation.rast
@@ -0,0 +1,88 @@
+SOURCE_FILE
+ STRUCT
+ STRUCT_KW "struct"
+ WHITESPACE " "
+ NAME
+ IDENT "S"
+ TUPLE_FIELD_LIST
+ L_PAREN "("
+ TUPLE_FIELD
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "i32"
+ COMMA ","
+ WHITESPACE " "
+ TUPLE_FIELD
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "i32"
+ R_PAREN ")"
+ SEMICOLON ";"
+ WHITESPACE "\n"
+ FN
+ FN_KW "fn"
+ WHITESPACE " "
+ NAME
+ IDENT "f"
+ PARAM_LIST
+ L_PAREN "("
+ R_PAREN ")"
+ WHITESPACE " "
+ BLOCK_EXPR
+ STMT_LIST
+ L_CURLY "{"
+ WHITESPACE "\n "
+ LET_STMT
+ LET_KW "let"
+ WHITESPACE " "
+ IDENT_PAT
+ NAME
+ IDENT "s"
+ WHITESPACE " "
+ EQ "="
+ WHITESPACE " "
+ CALL_EXPR
+ PATH_EXPR
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "S"
+ ARG_LIST
+ L_PAREN "("
+ LITERAL
+ INT_NUMBER "1"
+ COMMA ","
+ WHITESPACE " "
+ LITERAL
+ INT_NUMBER "2"
+ R_PAREN ")"
+ SEMICOLON ";"
+ WHITESPACE "\n "
+ LET_STMT
+ LET_KW "let"
+ WHITESPACE " "
+ IDENT_PAT
+ NAME
+ IDENT "a"
+ WHITESPACE " "
+ EQ "="
+ WHITESPACE " "
+ FIELD_EXPR
+ FIELD_EXPR
+ PATH_EXPR
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "s"
+ DOT "."
+ ERROR
+ FLOAT_NUMBER "1e0"
+ SEMICOLON ";"
+ WHITESPACE "\n"
+ R_CURLY "}"
+ WHITESPACE "\n"
+error 42: illegal float literal
diff --git a/crates/parser/test_data/parser/err/0054_float_split_scientific_notation.rs b/crates/parser/test_data/parser/err/0054_float_split_scientific_notation.rs
new file mode 100644
index 0000000000..648ef5e043
--- /dev/null
+++ b/crates/parser/test_data/parser/err/0054_float_split_scientific_notation.rs
@@ -0,0 +1,5 @@
+struct S(i32, i32);
+fn f() {
+ let s = S(1, 2);
+ let a = s.1e0;
+}