about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crates/parser/src/grammar/type_args.rs32
-rw-r--r--crates/parser/src/grammar/type_params.rs10
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0165_const_param_defaults.rast96
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0165_const_param_defaults.rs3
4 files changed, 141 insertions, 0 deletions
diff --git a/crates/parser/src/grammar/type_args.rs b/crates/parser/src/grammar/type_args.rs
index 56266b8d479..be36cad172d 100644
--- a/crates/parser/src/grammar/type_args.rs
+++ b/crates/parser/src/grammar/type_args.rs
@@ -25,6 +25,38 @@ pub(super) fn opt_generic_arg_list(p: &mut Parser, colon_colon_required: bool) {
     m.complete(p, GENERIC_ARG_LIST);
 }
 
+pub(super) fn const_arg(p: &mut Parser) {
+    let m = p.start();
+    // FIXME: duplicates the code below
+    match p.current() {
+        T!['{'] => {
+            expressions::block_expr(p);
+            m.complete(p, CONST_ARG);
+        }
+        k if k.is_literal() => {
+            expressions::literal(p);
+            m.complete(p, CONST_ARG);
+        }
+        T![true] | T![false] => {
+            expressions::literal(p);
+            m.complete(p, CONST_ARG);
+        }
+        T![-] => {
+            let lm = p.start();
+            p.bump(T![-]);
+            expressions::literal(p);
+            lm.complete(p, PREFIX_EXPR);
+            m.complete(p, CONST_ARG);
+        }
+        _ => {
+            let lm = p.start();
+            paths::use_path(p);
+            lm.complete(p, PATH_EXPR);
+            m.complete(p, CONST_ARG);
+        }
+    }
+}
+
 // test type_arg
 // type A = B<'static, i32, 1, { 2 }, Item=u64, true, false>;
 fn generic_arg(p: &mut Parser) {
diff --git a/crates/parser/src/grammar/type_params.rs b/crates/parser/src/grammar/type_params.rs
index 3de5248da14..b1f97928143 100644
--- a/crates/parser/src/grammar/type_params.rs
+++ b/crates/parser/src/grammar/type_params.rs
@@ -70,6 +70,16 @@ fn const_param(p: &mut Parser, m: Marker) {
     p.bump(T![const]);
     name(p);
     types::ascription(p);
+
+    // test const_param_defaults
+    // struct A<const N: i32 = -1>;
+    // struct B<const N: i32 = {}>;
+    // struct C<const N: i32 = some::CONST>;
+    if p.at(T![=]) {
+        p.bump(T![=]);
+        type_args::const_arg(p);
+    }
+
     m.complete(p, CONST_PARAM);
 }
 
diff --git a/crates/syntax/test_data/parser/inline/ok/0165_const_param_defaults.rast b/crates/syntax/test_data/parser/inline/ok/0165_const_param_defaults.rast
new file mode 100644
index 00000000000..e8f40a4cd70
--- /dev/null
+++ b/crates/syntax/test_data/parser/inline/ok/0165_const_param_defaults.rast
@@ -0,0 +1,96 @@
+SOURCE_FILE@0..96
+  STRUCT@0..28
+    STRUCT_KW@0..6 "struct"
+    WHITESPACE@6..7 " "
+    NAME@7..8
+      IDENT@7..8 "A"
+    GENERIC_PARAM_LIST@8..27
+      L_ANGLE@8..9 "<"
+      CONST_PARAM@9..26
+        CONST_KW@9..14 "const"
+        WHITESPACE@14..15 " "
+        NAME@15..16
+          IDENT@15..16 "N"
+        COLON@16..17 ":"
+        WHITESPACE@17..18 " "
+        PATH_TYPE@18..21
+          PATH@18..21
+            PATH_SEGMENT@18..21
+              NAME_REF@18..21
+                IDENT@18..21 "i32"
+        WHITESPACE@21..22 " "
+        EQ@22..23 "="
+        WHITESPACE@23..24 " "
+        CONST_ARG@24..26
+          PREFIX_EXPR@24..26
+            MINUS@24..25 "-"
+            LITERAL@25..26
+              INT_NUMBER@25..26 "1"
+      R_ANGLE@26..27 ">"
+    SEMICOLON@27..28 ";"
+  WHITESPACE@28..29 "\n"
+  STRUCT@29..57
+    STRUCT_KW@29..35 "struct"
+    WHITESPACE@35..36 " "
+    NAME@36..37
+      IDENT@36..37 "B"
+    GENERIC_PARAM_LIST@37..56
+      L_ANGLE@37..38 "<"
+      CONST_PARAM@38..55
+        CONST_KW@38..43 "const"
+        WHITESPACE@43..44 " "
+        NAME@44..45
+          IDENT@44..45 "N"
+        COLON@45..46 ":"
+        WHITESPACE@46..47 " "
+        PATH_TYPE@47..50
+          PATH@47..50
+            PATH_SEGMENT@47..50
+              NAME_REF@47..50
+                IDENT@47..50 "i32"
+        WHITESPACE@50..51 " "
+        EQ@51..52 "="
+        WHITESPACE@52..53 " "
+        CONST_ARG@53..55
+          BLOCK_EXPR@53..55
+            L_CURLY@53..54 "{"
+            R_CURLY@54..55 "}"
+      R_ANGLE@55..56 ">"
+    SEMICOLON@56..57 ";"
+  WHITESPACE@57..58 "\n"
+  STRUCT@58..95
+    STRUCT_KW@58..64 "struct"
+    WHITESPACE@64..65 " "
+    NAME@65..66
+      IDENT@65..66 "C"
+    GENERIC_PARAM_LIST@66..94
+      L_ANGLE@66..67 "<"
+      CONST_PARAM@67..93
+        CONST_KW@67..72 "const"
+        WHITESPACE@72..73 " "
+        NAME@73..74
+          IDENT@73..74 "N"
+        COLON@74..75 ":"
+        WHITESPACE@75..76 " "
+        PATH_TYPE@76..79
+          PATH@76..79
+            PATH_SEGMENT@76..79
+              NAME_REF@76..79
+                IDENT@76..79 "i32"
+        WHITESPACE@79..80 " "
+        EQ@80..81 "="
+        WHITESPACE@81..82 " "
+        CONST_ARG@82..93
+          PATH_EXPR@82..93
+            PATH@82..93
+              PATH@82..86
+                PATH_SEGMENT@82..86
+                  NAME_REF@82..86
+                    IDENT@82..86 "some"
+              COLON2@86..88 "::"
+              PATH_SEGMENT@88..93
+                NAME_REF@88..93
+                  IDENT@88..93 "CONST"
+      R_ANGLE@93..94 ">"
+    SEMICOLON@94..95 ";"
+  WHITESPACE@95..96 "\n"
diff --git a/crates/syntax/test_data/parser/inline/ok/0165_const_param_defaults.rs b/crates/syntax/test_data/parser/inline/ok/0165_const_param_defaults.rs
new file mode 100644
index 00000000000..68388c8fbdf
--- /dev/null
+++ b/crates/syntax/test_data/parser/inline/ok/0165_const_param_defaults.rs
@@ -0,0 +1,3 @@
+struct A<const N: i32 = -1>;
+struct B<const N: i32 = {}>;
+struct C<const N: i32 = some::CONST>;