about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-01-24 01:18:58 +0000
committerGitHub <noreply@github.com>2021-01-24 01:18:58 +0000
commit3ab8d7a9ae1b8c5e421a4666f6693ae7278a7a3c (patch)
treef1ce0582f85b1612e369681dc981df7ec575ae9a
parenta7a1bb444d59732e3973b7b2d5b27413c5a1ca81 (diff)
parent70d43c3faf6cc4e6fe4833c6375d05e54874ca0d (diff)
downloadrust-3ab8d7a9ae1b8c5e421a4666f6693ae7278a7a3c.tar.gz
rust-3ab8d7a9ae1b8c5e421a4666f6693ae7278a7a3c.zip
Merge #7414
7414: Add validation for mutable const items r=Veykril a=Veykril

bors r+

Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
-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 eb7d1f8281d..12130df40db 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) {
 fn const_or_static(p: &mut Parser, m: Marker, kw: SyntaxKind, def: SyntaxKind) {
     assert!(p.at(kw));
     p.bump(kw);
-    p.eat(T![mut]); // FIXME: validator to forbid const mut
+    p.eat(T![mut]);
 
     // Allow `_` in place of an identifier in a `const`.
     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 7694e883432..3e216fb70b8 100644
--- a/crates/syntax/src/validation.rs
+++ b/crates/syntax/src/validation.rs
@@ -1,4 +1,6 @@
-//! FIXME: write short doc here
+//! This module implements syntax validation that the parser doesn't handle.
+//!
+//! A failed validation emits a diagnostic.
 
 mod block;
 
@@ -92,6 +94,7 @@ pub(crate) fn validate(root: &SyntaxNode) -> Vec<SyntaxError> {
         match_ast! {
             match node {
                 ast::Literal(it) => validate_literal(it, &mut errors),
+                ast::Const(it) => validate_const(it, &mut errors),
                 ast::BlockExpr(it) => block::validate_block_expr(it, &mut errors),
                 ast::FieldExpr(it) => validate_numeric_name(it.name_ref(), &mut errors),
                 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>) {
         ));
     }
 }
+
+fn validate_const(const_: ast::Const, errors: &mut Vec<SyntaxError>) {
+    if let Some(mut_token) = const_
+        .const_token()
+        .and_then(|t| t.next_token())
+        .and_then(|t| algo::skip_trivia_token(t, Direction::Next))
+        .filter(|t| t.kind() == T![mut])
+    {
+        errors.push(SyntaxError::new("const globals cannot be mutable", mut_token.text_range()));
+    }
+}
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 00000000000..c7eb312c92c
--- /dev/null
+++ b/crates/syntax/test_data/parser/err/0047_mutable_const_item.rast
@@ -0,0 +1,22 @@
+SOURCE_FILE@0..24
+  CONST@0..23
+    CONST_KW@0..5 "const"
+    WHITESPACE@5..6 " "
+    MUT_KW@6..9 "mut"
+    WHITESPACE@9..10 " "
+    NAME@10..13
+      IDENT@10..13 "FOO"
+    COLON@13..14 ":"
+    WHITESPACE@14..15 " "
+    TUPLE_TYPE@15..17
+      L_PAREN@15..16 "("
+      R_PAREN@16..17 ")"
+    WHITESPACE@17..18 " "
+    EQ@18..19 "="
+    WHITESPACE@19..20 " "
+    TUPLE_EXPR@20..22
+      L_PAREN@20..21 "("
+      R_PAREN@21..22 ")"
+    SEMICOLON@22..23 ";"
+  WHITESPACE@23..24 "\n"
+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 00000000000..b34336f3f15
--- /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 dd1b9c9a0a4..b89ed6f98e0 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 @@
-SOURCE_FILE@0..64
+SOURCE_FILE@0..39
   CONST@0..17
     CONST_KW@0..5 "const"
     WHITESPACE@5..6 " "
@@ -36,24 +36,3 @@ SOURCE_FILE@0..64
       INT_NUMBER@35..37 "92"
     SEMICOLON@37..38 ";"
   WHITESPACE@38..39 "\n"
-  CONST@39..63
-    CONST_KW@39..44 "const"
-    WHITESPACE@44..45 " "
-    MUT_KW@45..48 "mut"
-    WHITESPACE@48..49 " "
-    NAME@49..52
-      IDENT@49..52 "BAR"
-    COLON@52..53 ":"
-    WHITESPACE@53..54 " "
-    PATH_TYPE@54..57
-      PATH@54..57
-        PATH_SEGMENT@54..57
-          NAME_REF@54..57
-            IDENT@54..57 "u32"
-    WHITESPACE@57..58 " "
-    EQ@58..59 "="
-    WHITESPACE@59..60 " "
-    LITERAL@60..62
-      INT_NUMBER@60..62 "62"
-    SEMICOLON@62..63 ";"
-  WHITESPACE@63..64 "\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 a806a209dc1..1f2ffa0da38 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 @@
 const _: u32 = 0;
 const FOO: u32 = 92;
-const mut BAR: u32 = 62;