Skip to content

Commit e3f7d18

Browse files
authored
Merge pull request #19643 from ChayimFriedman2/generic-const-items
feat: Parse generic consts
2 parents 5195f9d + 812a035 commit e3f7d18

File tree

12 files changed

+305
-3
lines changed

12 files changed

+305
-3
lines changed

crates/parser/src/grammar/items/consts.rs

+26
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,18 @@ fn const_or_static(p: &mut Parser<'_>, m: Marker, is_const: bool) {
2424
name(p);
2525
}
2626

27+
// FIXME: Recover on statics with generic params/where clause.
28+
if is_const {
29+
// test generic_const
30+
// const C<i32>: u32 = 0;
31+
// impl Foo {
32+
// const C<'a>: &'a () = &();
33+
// }
34+
generic_params::opt_generic_param_list(p);
35+
}
36+
// test_err generic_static
37+
// static C<i32>: u32 = 0;
38+
2739
if p.at(T![:]) {
2840
types::ascription(p);
2941
} else {
@@ -32,6 +44,20 @@ fn const_or_static(p: &mut Parser<'_>, m: Marker, is_const: bool) {
3244
if p.eat(T![=]) {
3345
expressions::expr(p);
3446
}
47+
48+
if is_const {
49+
// test const_where_clause
50+
// const C<i32>: u32 = 0
51+
// where i32: Copy;
52+
// trait Foo {
53+
// const C: i32 where i32: Copy;
54+
// }
55+
generic_params::opt_where_clause(p);
56+
}
57+
// test_err static_where_clause
58+
// static C: u32 = 0
59+
// where i32: Copy;
60+
3561
p.expect(T![;]);
3662
m.complete(p, if is_const { CONST } else { STATIC });
3763
}

crates/parser/test_data/generated/runner.rs

+12
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,10 @@ mod ok {
139139
run_and_expect_no_errors("test_data/parser/inline/ok/const_trait_bound.rs");
140140
}
141141
#[test]
142+
fn const_where_clause() {
143+
run_and_expect_no_errors("test_data/parser/inline/ok/const_where_clause.rs");
144+
}
145+
#[test]
142146
fn continue_expr() { run_and_expect_no_errors("test_data/parser/inline/ok/continue_expr.rs"); }
143147
#[test]
144148
fn crate_path() { run_and_expect_no_errors("test_data/parser/inline/ok/crate_path.rs"); }
@@ -278,6 +282,8 @@ mod ok {
278282
run_and_expect_no_errors("test_data/parser/inline/ok/generic_arg_bounds.rs");
279283
}
280284
#[test]
285+
fn generic_const() { run_and_expect_no_errors("test_data/parser/inline/ok/generic_const.rs"); }
286+
#[test]
281287
fn generic_param_attribute() {
282288
run_and_expect_no_errors("test_data/parser/inline/ok/generic_param_attribute.rs");
283289
}
@@ -764,6 +770,8 @@ mod err {
764770
run_and_expect_errors("test_data/parser/inline/err/generic_param_list_recover.rs");
765771
}
766772
#[test]
773+
fn generic_static() { run_and_expect_errors("test_data/parser/inline/err/generic_static.rs"); }
774+
#[test]
767775
fn impl_type() { run_and_expect_errors("test_data/parser/inline/err/impl_type.rs"); }
768776
#[test]
769777
fn let_else_right_curly_brace() {
@@ -836,6 +844,10 @@ mod err {
836844
run_and_expect_errors("test_data/parser/inline/err/recover_from_missing_const_default.rs");
837845
}
838846
#[test]
847+
fn static_where_clause() {
848+
run_and_expect_errors("test_data/parser/inline/err/static_where_clause.rs");
849+
}
850+
#[test]
839851
fn struct_field_recover() {
840852
run_and_expect_errors("test_data/parser/inline/err/struct_field_recover.rs");
841853
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
SOURCE_FILE
2+
STATIC
3+
STATIC_KW "static"
4+
WHITESPACE " "
5+
NAME
6+
IDENT "C"
7+
ERROR
8+
L_ANGLE "<"
9+
ERROR
10+
PATH
11+
PATH_SEGMENT
12+
NAME_REF
13+
IDENT "i32"
14+
ERROR
15+
R_ANGLE ">"
16+
ERROR
17+
COLON ":"
18+
WHITESPACE " "
19+
ERROR
20+
PATH
21+
PATH_SEGMENT
22+
NAME_REF
23+
IDENT "u32"
24+
WHITESPACE " "
25+
ERROR
26+
EQ "="
27+
WHITESPACE " "
28+
ERROR
29+
INT_NUMBER "0"
30+
ERROR
31+
SEMICOLON ";"
32+
WHITESPACE "\n"
33+
error 8: missing type for `const` or `static`
34+
error 8: expected SEMICOLON
35+
error 8: expected an item
36+
error 12: expected an item
37+
error 12: expected an item
38+
error 13: expected an item
39+
error 18: expected an item
40+
error 19: expected an item
41+
error 21: expected an item
42+
error 22: expected an item
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
static C<i32>: u32 = 0;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
SOURCE_FILE
2+
STATIC
3+
STATIC_KW "static"
4+
WHITESPACE " "
5+
NAME
6+
IDENT "C"
7+
COLON ":"
8+
WHITESPACE " "
9+
PATH_TYPE
10+
PATH
11+
PATH_SEGMENT
12+
NAME_REF
13+
IDENT "u32"
14+
WHITESPACE " "
15+
EQ "="
16+
WHITESPACE " "
17+
LITERAL
18+
INT_NUMBER "0"
19+
WHITESPACE "\n"
20+
ERROR
21+
WHERE_KW "where"
22+
WHITESPACE " "
23+
ERROR
24+
PATH
25+
PATH_SEGMENT
26+
NAME_REF
27+
IDENT "i32"
28+
ERROR
29+
COLON ":"
30+
WHITESPACE " "
31+
ERROR
32+
PATH
33+
PATH_SEGMENT
34+
NAME_REF
35+
IDENT "Copy"
36+
ERROR
37+
SEMICOLON ";"
38+
WHITESPACE "\n"
39+
error 17: expected SEMICOLON
40+
error 18: expected an item
41+
error 27: expected an item
42+
error 27: expected an item
43+
error 33: expected an item
44+
error 33: expected an item
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
static C: u32 = 0
2+
where i32: Copy;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
SOURCE_FILE
2+
CONST
3+
CONST_KW "const"
4+
WHITESPACE " "
5+
NAME
6+
IDENT "C"
7+
GENERIC_PARAM_LIST
8+
L_ANGLE "<"
9+
TYPE_PARAM
10+
NAME
11+
IDENT "i32"
12+
R_ANGLE ">"
13+
COLON ":"
14+
WHITESPACE " "
15+
PATH_TYPE
16+
PATH
17+
PATH_SEGMENT
18+
NAME_REF
19+
IDENT "u32"
20+
WHITESPACE " "
21+
EQ "="
22+
WHITESPACE " "
23+
LITERAL
24+
INT_NUMBER "0"
25+
WHITESPACE "\n"
26+
WHERE_CLAUSE
27+
WHERE_KW "where"
28+
WHITESPACE " "
29+
WHERE_PRED
30+
PATH_TYPE
31+
PATH
32+
PATH_SEGMENT
33+
NAME_REF
34+
IDENT "i32"
35+
COLON ":"
36+
WHITESPACE " "
37+
TYPE_BOUND_LIST
38+
TYPE_BOUND
39+
PATH_TYPE
40+
PATH
41+
PATH_SEGMENT
42+
NAME_REF
43+
IDENT "Copy"
44+
SEMICOLON ";"
45+
WHITESPACE "\n"
46+
TRAIT
47+
TRAIT_KW "trait"
48+
WHITESPACE " "
49+
NAME
50+
IDENT "Foo"
51+
WHITESPACE " "
52+
ASSOC_ITEM_LIST
53+
L_CURLY "{"
54+
WHITESPACE "\n "
55+
CONST
56+
CONST_KW "const"
57+
WHITESPACE " "
58+
NAME
59+
IDENT "C"
60+
COLON ":"
61+
WHITESPACE " "
62+
PATH_TYPE
63+
PATH
64+
PATH_SEGMENT
65+
NAME_REF
66+
IDENT "i32"
67+
WHITESPACE " "
68+
WHERE_CLAUSE
69+
WHERE_KW "where"
70+
WHITESPACE " "
71+
WHERE_PRED
72+
PATH_TYPE
73+
PATH
74+
PATH_SEGMENT
75+
NAME_REF
76+
IDENT "i32"
77+
COLON ":"
78+
WHITESPACE " "
79+
TYPE_BOUND_LIST
80+
TYPE_BOUND
81+
PATH_TYPE
82+
PATH
83+
PATH_SEGMENT
84+
NAME_REF
85+
IDENT "Copy"
86+
SEMICOLON ";"
87+
WHITESPACE "\n"
88+
R_CURLY "}"
89+
WHITESPACE "\n"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
const C<i32>: u32 = 0
2+
where i32: Copy;
3+
trait Foo {
4+
const C: i32 where i32: Copy;
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
SOURCE_FILE
2+
CONST
3+
CONST_KW "const"
4+
WHITESPACE " "
5+
NAME
6+
IDENT "C"
7+
GENERIC_PARAM_LIST
8+
L_ANGLE "<"
9+
TYPE_PARAM
10+
NAME
11+
IDENT "i32"
12+
R_ANGLE ">"
13+
COLON ":"
14+
WHITESPACE " "
15+
PATH_TYPE
16+
PATH
17+
PATH_SEGMENT
18+
NAME_REF
19+
IDENT "u32"
20+
WHITESPACE " "
21+
EQ "="
22+
WHITESPACE " "
23+
LITERAL
24+
INT_NUMBER "0"
25+
SEMICOLON ";"
26+
WHITESPACE "\n"
27+
IMPL
28+
IMPL_KW "impl"
29+
WHITESPACE " "
30+
PATH_TYPE
31+
PATH
32+
PATH_SEGMENT
33+
NAME_REF
34+
IDENT "Foo"
35+
WHITESPACE " "
36+
ASSOC_ITEM_LIST
37+
L_CURLY "{"
38+
WHITESPACE "\n "
39+
CONST
40+
CONST_KW "const"
41+
WHITESPACE " "
42+
NAME
43+
IDENT "C"
44+
GENERIC_PARAM_LIST
45+
L_ANGLE "<"
46+
LIFETIME_PARAM
47+
LIFETIME
48+
LIFETIME_IDENT "'a"
49+
R_ANGLE ">"
50+
COLON ":"
51+
WHITESPACE " "
52+
REF_TYPE
53+
AMP "&"
54+
LIFETIME
55+
LIFETIME_IDENT "'a"
56+
WHITESPACE " "
57+
TUPLE_TYPE
58+
L_PAREN "("
59+
R_PAREN ")"
60+
WHITESPACE " "
61+
EQ "="
62+
WHITESPACE " "
63+
REF_EXPR
64+
AMP "&"
65+
TUPLE_EXPR
66+
L_PAREN "("
67+
R_PAREN ")"
68+
SEMICOLON ";"
69+
WHITESPACE "\n"
70+
R_CURLY "}"
71+
WHITESPACE "\n"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
const C<i32>: u32 = 0;
2+
impl Foo {
3+
const C<'a>: &'a () = &();
4+
}

crates/syntax/rust.ungram

+3-2
Original file line numberDiff line numberDiff line change
@@ -287,8 +287,9 @@ VariantDef =
287287
Const =
288288
Attr* Visibility?
289289
'default'?
290-
'const' (Name | '_') ':' Type
291-
('=' body:Expr)? ';'
290+
'const' (Name | '_') GenericParamList? ':' Type
291+
('=' body:Expr)?
292+
WhereClause? ';'
292293

293294
Static =
294295
Attr* Visibility?

crates/syntax/src/ast/generated/nodes.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,7 @@ pub struct Const {
405405
}
406406
impl ast::HasAttrs for Const {}
407407
impl ast::HasDocComments for Const {}
408+
impl ast::HasGenericParams for Const {}
408409
impl ast::HasName for Const {}
409410
impl ast::HasVisibility for Const {}
410411
impl Const {
@@ -9423,7 +9424,7 @@ impl ast::HasGenericParams for AnyHasGenericParams {}
94239424
impl AstNode for AnyHasGenericParams {
94249425
#[inline]
94259426
fn can_cast(kind: SyntaxKind) -> bool {
9426-
matches!(kind, ENUM | FN | IMPL | STRUCT | TRAIT | TRAIT_ALIAS | TYPE_ALIAS | UNION)
9427+
matches!(kind, CONST | ENUM | FN | IMPL | STRUCT | TRAIT | TRAIT_ALIAS | TYPE_ALIAS | UNION)
94279428
}
94289429
#[inline]
94299430
fn cast(syntax: SyntaxNode) -> Option<Self> {
@@ -9447,6 +9448,10 @@ impl fmt::Debug for AnyHasGenericParams {
94479448
f.debug_struct("AnyHasGenericParams").field("syntax", &self.syntax).finish()
94489449
}
94499450
}
9451+
impl From<Const> for AnyHasGenericParams {
9452+
#[inline]
9453+
fn from(node: Const) -> AnyHasGenericParams { AnyHasGenericParams { syntax: node.syntax } }
9454+
}
94509455
impl From<Enum> for AnyHasGenericParams {
94519456
#[inline]
94529457
fn from(node: Enum) -> AnyHasGenericParams { AnyHasGenericParams { syntax: node.syntax } }

0 commit comments

Comments
 (0)