Skip to content

Commit e5889c9

Browse files
committed
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.
2 parents b85d38f + 91d181f commit e5889c9

File tree

3 files changed

+109
-2
lines changed

3 files changed

+109
-2
lines changed

crates/parser/src/shortcuts.rs

+16-2
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ impl Builder<'_, '_> {
190190

191191
fn do_float_split(&mut self, has_pseudo_dot: bool) {
192192
let text = &self.lexed.range_text(self.pos..self.pos + 1);
193-
self.pos += 1;
193+
194194
match text.split_once('.') {
195195
Some((left, right)) => {
196196
assert!(!left.is_empty());
@@ -216,8 +216,22 @@ impl Builder<'_, '_> {
216216
self.state = State::PendingExit;
217217
}
218218
}
219-
None => unreachable!(),
219+
None => {
220+
// illegal float literal which doesn't have dot in form (like 1e0)
221+
// we should emit an error node here
222+
(self.sink)(StrStep::Error { msg: "illegal float literal", pos: self.pos });
223+
(self.sink)(StrStep::Enter { kind: SyntaxKind::ERROR });
224+
(self.sink)(StrStep::Token { kind: SyntaxKind::FLOAT_NUMBER, text });
225+
(self.sink)(StrStep::Exit);
226+
227+
// move up
228+
(self.sink)(StrStep::Exit);
229+
230+
self.state = if has_pseudo_dot { State::Normal } else { State::PendingExit };
231+
}
220232
}
233+
234+
self.pos += 1;
221235
}
222236
}
223237

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
SOURCE_FILE
2+
STRUCT
3+
STRUCT_KW "struct"
4+
WHITESPACE " "
5+
NAME
6+
IDENT "S"
7+
TUPLE_FIELD_LIST
8+
L_PAREN "("
9+
TUPLE_FIELD
10+
PATH_TYPE
11+
PATH
12+
PATH_SEGMENT
13+
NAME_REF
14+
IDENT "i32"
15+
COMMA ","
16+
WHITESPACE " "
17+
TUPLE_FIELD
18+
PATH_TYPE
19+
PATH
20+
PATH_SEGMENT
21+
NAME_REF
22+
IDENT "i32"
23+
R_PAREN ")"
24+
SEMICOLON ";"
25+
WHITESPACE "\n"
26+
FN
27+
FN_KW "fn"
28+
WHITESPACE " "
29+
NAME
30+
IDENT "f"
31+
PARAM_LIST
32+
L_PAREN "("
33+
R_PAREN ")"
34+
WHITESPACE " "
35+
BLOCK_EXPR
36+
STMT_LIST
37+
L_CURLY "{"
38+
WHITESPACE "\n "
39+
LET_STMT
40+
LET_KW "let"
41+
WHITESPACE " "
42+
IDENT_PAT
43+
NAME
44+
IDENT "s"
45+
WHITESPACE " "
46+
EQ "="
47+
WHITESPACE " "
48+
CALL_EXPR
49+
PATH_EXPR
50+
PATH
51+
PATH_SEGMENT
52+
NAME_REF
53+
IDENT "S"
54+
ARG_LIST
55+
L_PAREN "("
56+
LITERAL
57+
INT_NUMBER "1"
58+
COMMA ","
59+
WHITESPACE " "
60+
LITERAL
61+
INT_NUMBER "2"
62+
R_PAREN ")"
63+
SEMICOLON ";"
64+
WHITESPACE "\n "
65+
LET_STMT
66+
LET_KW "let"
67+
WHITESPACE " "
68+
IDENT_PAT
69+
NAME
70+
IDENT "a"
71+
WHITESPACE " "
72+
EQ "="
73+
WHITESPACE " "
74+
FIELD_EXPR
75+
FIELD_EXPR
76+
PATH_EXPR
77+
PATH
78+
PATH_SEGMENT
79+
NAME_REF
80+
IDENT "s"
81+
DOT "."
82+
ERROR
83+
FLOAT_NUMBER "1e0"
84+
SEMICOLON ";"
85+
WHITESPACE "\n"
86+
R_CURLY "}"
87+
WHITESPACE "\n"
88+
error 42: illegal float literal
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
struct S(i32, i32);
2+
fn f() {
3+
let s = S(1, 2);
4+
let a = s.1e0;
5+
}

0 commit comments

Comments
 (0)