aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Wirth <[email protected]>2021-01-24 01:17:41 +0000
committerLukas Wirth <[email protected]>2021-01-24 01:17:41 +0000
commit70d43c3faf6cc4e6fe4833c6375d05e54874ca0d (patch)
treef4b06a875d92661bcf5b4080864baa07dabb8914
parent89fef5307e81d5d23bb65677000f35332190661a (diff)
Add validation for mutable const items
-rw-r--r--crates/parser/src/grammar/items/consts.rs2
-rw-r--r--crates/syntax/src/validation.rs16
-rw-r--r--crates/syntax/test_data/parser/err/0047_mutable_const_item.rast22
-rw-r--r--crates/syntax/test_data/parser/err/0047_mutable_const_item.rs1
-rw-r--r--crates/syntax/test_data/parser/ok/0024_const_item.rast23
-rw-r--r--crates/syntax/test_data/parser/ok/0024_const_item.rs1
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) {
13fn const_or_static(p: &mut Parser, m: Marker, kw: SyntaxKind, def: SyntaxKind) { 13fn 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
3mod block; 5mod 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
369fn 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"
22error 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 @@
1SOURCE_FILE@0..64 1SOURCE_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 @@
1const _: u32 = 0; 1const _: u32 = 0;
2const FOO: u32 = 92; 2const FOO: u32 = 92;
3const mut BAR: u32 = 62;