diff options
6 files changed, 40 insertions, 25 deletions
diff --git a/crates/parser/src/grammar/items/consts.rs b/crates/parser/src/grammar/items/consts.rs index eb7d1f828..12130df40 100644 --- a/crates/parser/src/grammar/items/consts.rs +++ b/crates/parser/src/grammar/items/consts.rs | |||
@@ -13,7 +13,7 @@ pub(super) fn konst(p: &mut Parser, m: Marker) { | |||
13 | fn const_or_static(p: &mut Parser, m: Marker, kw: SyntaxKind, def: SyntaxKind) { | 13 | fn const_or_static(p: &mut Parser, m: Marker, kw: SyntaxKind, def: SyntaxKind) { |
14 | assert!(p.at(kw)); | 14 | assert!(p.at(kw)); |
15 | p.bump(kw); | 15 | p.bump(kw); |
16 | p.eat(T![mut]); // FIXME: validator to forbid const mut | 16 | p.eat(T![mut]); |
17 | 17 | ||
18 | // Allow `_` in place of an identifier in a `const`. | 18 | // Allow `_` in place of an identifier in a `const`. |
19 | let is_const_underscore = kw == T![const] && p.eat(T![_]); | 19 | let is_const_underscore = kw == T![const] && p.eat(T![_]); |
diff --git a/crates/syntax/src/validation.rs b/crates/syntax/src/validation.rs index 7694e8834..3e216fb70 100644 --- a/crates/syntax/src/validation.rs +++ b/crates/syntax/src/validation.rs | |||
@@ -1,4 +1,6 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! This module implements syntax validation that the parser doesn't handle. |
2 | //! | ||
3 | //! A failed validation emits a diagnostic. | ||
2 | 4 | ||
3 | mod block; | 5 | mod block; |
4 | 6 | ||
@@ -92,6 +94,7 @@ pub(crate) fn validate(root: &SyntaxNode) -> Vec<SyntaxError> { | |||
92 | match_ast! { | 94 | match_ast! { |
93 | match node { | 95 | match node { |
94 | ast::Literal(it) => validate_literal(it, &mut errors), | 96 | ast::Literal(it) => validate_literal(it, &mut errors), |
97 | ast::Const(it) => validate_const(it, &mut errors), | ||
95 | ast::BlockExpr(it) => block::validate_block_expr(it, &mut errors), | 98 | ast::BlockExpr(it) => block::validate_block_expr(it, &mut errors), |
96 | ast::FieldExpr(it) => validate_numeric_name(it.name_ref(), &mut errors), | 99 | ast::FieldExpr(it) => validate_numeric_name(it.name_ref(), &mut errors), |
97 | ast::RecordExprField(it) => validate_numeric_name(it.name_ref(), &mut errors), | 100 | ast::RecordExprField(it) => validate_numeric_name(it.name_ref(), &mut errors), |
@@ -362,3 +365,14 @@ fn validate_macro_rules(mac: ast::MacroRules, errors: &mut Vec<SyntaxError>) { | |||
362 | )); | 365 | )); |
363 | } | 366 | } |
364 | } | 367 | } |
368 | |||
369 | fn validate_const(const_: ast::Const, errors: &mut Vec<SyntaxError>) { | ||
370 | if let Some(mut_token) = const_ | ||
371 | .const_token() | ||
372 | .and_then(|t| t.next_token()) | ||
373 | .and_then(|t| algo::skip_trivia_token(t, Direction::Next)) | ||
374 | .filter(|t| t.kind() == T![mut]) | ||
375 | { | ||
376 | errors.push(SyntaxError::new("const globals cannot be mutable", mut_token.text_range())); | ||
377 | } | ||
378 | } | ||
diff --git a/crates/syntax/test_data/parser/err/0047_mutable_const_item.rast b/crates/syntax/test_data/parser/err/0047_mutable_const_item.rast new file mode 100644 index 000000000..c7eb312c9 --- /dev/null +++ b/crates/syntax/test_data/parser/err/0047_mutable_const_item.rast | |||
@@ -0,0 +1,22 @@ | |||
1 | [email protected] | ||
2 | [email protected] | ||
3 | [email protected] "const" | ||
4 | [email protected] " " | ||
5 | [email protected] "mut" | ||
6 | [email protected] " " | ||
7 | [email protected] | ||
8 | [email protected] "FOO" | ||
9 | [email protected] ":" | ||
10 | [email protected] " " | ||
11 | [email protected] | ||
12 | [email protected] "(" | ||
13 | [email protected] ")" | ||
14 | [email protected] " " | ||
15 | [email protected] "=" | ||
16 | [email protected] " " | ||
17 | [email protected] | ||
18 | [email protected] "(" | ||
19 | [email protected] ")" | ||
20 | [email protected] ";" | ||
21 | [email protected] "\n" | ||
22 | error 6..9: const globals cannot be mutable | ||
diff --git a/crates/syntax/test_data/parser/err/0047_mutable_const_item.rs b/crates/syntax/test_data/parser/err/0047_mutable_const_item.rs new file mode 100644 index 000000000..b34336f3f --- /dev/null +++ b/crates/syntax/test_data/parser/err/0047_mutable_const_item.rs | |||
@@ -0,0 +1 @@ | |||
const mut FOO: () = (); | |||
diff --git a/crates/syntax/test_data/parser/ok/0024_const_item.rast b/crates/syntax/test_data/parser/ok/0024_const_item.rast index dd1b9c9a0..b89ed6f98 100644 --- a/crates/syntax/test_data/parser/ok/0024_const_item.rast +++ b/crates/syntax/test_data/parser/ok/0024_const_item.rast | |||
@@ -1,4 +1,4 @@ | |||
1 | SOURCE_FILE@0..64 | 1 | SOURCE_FILE@0..39 |
2 | [email protected] | 2 | [email protected] |
3 | [email protected] "const" | 3 | [email protected] "const" |
4 | [email protected] " " | 4 | [email protected] " " |
@@ -36,24 +36,3 @@ [email protected] | |||
36 | [email protected] "92" | 36 | [email protected] "92" |
37 | [email protected] ";" | 37 | [email protected] ";" |
38 | [email protected] "\n" | 38 | [email protected] "\n" |
39 | [email protected] | ||
40 | [email protected] "const" | ||
41 | [email protected] " " | ||
42 | [email protected] "mut" | ||
43 | [email protected] " " | ||
44 | [email protected] | ||
45 | [email protected] "BAR" | ||
46 | [email protected] ":" | ||
47 | [email protected] " " | ||
48 | [email protected] | ||
49 | [email protected] | ||
50 | [email protected] | ||
51 | [email protected] | ||
52 | [email protected] "u32" | ||
53 | [email protected] " " | ||
54 | [email protected] "=" | ||
55 | [email protected] " " | ||
56 | [email protected] | ||
57 | [email protected] "62" | ||
58 | [email protected] ";" | ||
59 | [email protected] "\n" | ||
diff --git a/crates/syntax/test_data/parser/ok/0024_const_item.rs b/crates/syntax/test_data/parser/ok/0024_const_item.rs index a806a209d..1f2ffa0da 100644 --- a/crates/syntax/test_data/parser/ok/0024_const_item.rs +++ b/crates/syntax/test_data/parser/ok/0024_const_item.rs | |||
@@ -1,3 +1,2 @@ | |||
1 | const _: u32 = 0; | 1 | const _: u32 = 0; |
2 | const FOO: u32 = 92; | 2 | const FOO: u32 = 92; |
3 | const mut BAR: u32 = 62; | ||