Skip to content

Commit 7b9df10

Browse files
bors[bot]mchesser
andauthored
Merge #2724
2724: Improve const generic parsing r=matklad a=mchesser Add support for generic arguments in: `impl` type parameters: ```rust impl<const N: u32> Bar<N> {} ``` type args: ```rust type A = B<1, { 2 }>; test::<10>(); ``` Co-authored-by: Michael Chesser <michaelchesser@outlook.com>
2 parents c92a090 + ce1b34f commit 7b9df10

File tree

9 files changed

+123
-21
lines changed

9 files changed

+123
-21
lines changed

crates/ra_parser/src/grammar/items/traits.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,13 +100,16 @@ pub(crate) fn impl_item_list(p: &mut Parser) {
100100
m.complete(p, ITEM_LIST);
101101
}
102102

103+
// test impl_type_params
104+
// impl<const N: u32> Bar<N> {}
103105
fn choose_type_params_over_qpath(p: &Parser) -> bool {
104106
// There's an ambiguity between generic parameters and qualified paths in impls.
105107
// If we see `<` it may start both, so we have to inspect some following tokens.
106108
// The following combinations can only start generics,
107109
// but not qualified paths (with one exception):
108110
// `<` `>` - empty generic parameters
109111
// `<` `#` - generic parameters with attributes
112+
// `<` `const` - const generic parameters
110113
// `<` (LIFETIME|IDENT) `>` - single generic parameter
111114
// `<` (LIFETIME|IDENT) `,` - first generic parameter in a list
112115
// `<` (LIFETIME|IDENT) `:` - generic parameter with bounds
@@ -119,7 +122,7 @@ fn choose_type_params_over_qpath(p: &Parser) -> bool {
119122
if !p.at(T![<]) {
120123
return false;
121124
}
122-
if p.nth(1) == T![#] || p.nth(1) == T![>] {
125+
if p.nth(1) == T![#] || p.nth(1) == T![>] || p.nth(1) == CONST_KW {
123126
return true;
124127
}
125128
(p.nth(1) == LIFETIME || p.nth(1) == IDENT)

crates/ra_parser/src/grammar/type_args.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ pub(super) fn opt_type_arg_list(p: &mut Parser, colon_colon_required: bool) {
2626
}
2727

2828
// test type_arg
29-
// type A = B<'static, i32, Item=u64>;
29+
// type A = B<'static, i32, 1, { 2 }, Item=u64>;
3030
fn type_arg(p: &mut Parser) {
3131
let m = p.start();
3232
match p.current() {
@@ -47,6 +47,14 @@ fn type_arg(p: &mut Parser) {
4747
types::type_(p);
4848
m.complete(p, ASSOC_TYPE_ARG);
4949
}
50+
T!['{'] => {
51+
expressions::block(p);
52+
m.complete(p, CONST_ARG);
53+
}
54+
k if k.is_literal() => {
55+
p.bump(k);
56+
m.complete(p, CONST_ARG);
57+
}
5058
_ => {
5159
types::type_(p);
5260
m.complete(p, TYPE_ARG);

crates/ra_parser/src/syntax_kind/generated.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ pub enum SyntaxKind {
234234
LIFETIME_ARG,
235235
TYPE_ARG,
236236
ASSOC_TYPE_ARG,
237+
CONST_ARG,
237238
PARAM_LIST,
238239
PARAM,
239240
SELF_PARAM,

crates/ra_syntax/src/ast/generated.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3114,6 +3114,9 @@ impl TypeArgList {
31143114
pub fn assoc_type_args(&self) -> AstChildren<AssocTypeArg> {
31153115
AstChildren::new(&self.syntax)
31163116
}
3117+
pub fn const_arg(&self) -> AstChildren<ConstArg> {
3118+
AstChildren::new(&self.syntax)
3119+
}
31173120
}
31183121
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
31193122
pub struct TypeArg {
@@ -3196,6 +3199,36 @@ impl AstNode for LifetimeArg {
31963199
}
31973200
impl LifetimeArg {}
31983201
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3202+
pub struct ConstArg {
3203+
pub(crate) syntax: SyntaxNode,
3204+
}
3205+
impl AstNode for ConstArg {
3206+
fn can_cast(kind: SyntaxKind) -> bool {
3207+
match kind {
3208+
CONST_ARG => true,
3209+
_ => false,
3210+
}
3211+
}
3212+
fn cast(syntax: SyntaxNode) -> Option<Self> {
3213+
if Self::can_cast(syntax.kind()) {
3214+
Some(Self { syntax })
3215+
} else {
3216+
None
3217+
}
3218+
}
3219+
fn syntax(&self) -> &SyntaxNode {
3220+
&self.syntax
3221+
}
3222+
}
3223+
impl ConstArg {
3224+
pub fn literal(&self) -> Option<Literal> {
3225+
AstChildren::new(&self.syntax).next()
3226+
}
3227+
pub fn block_expr(&self) -> Option<BlockExpr> {
3228+
AstChildren::new(&self.syntax).next()
3229+
}
3230+
}
3231+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
31993232
pub struct MacroItems {
32003233
pub(crate) syntax: SyntaxNode,
32013234
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
type A = B<'static, i32, Item=u64>;
1+
type A = B<'static, i32, 1, { 2 }, Item=u64>;
Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
1-
SOURCE_FILE@[0; 36)
2-
TYPE_ALIAS_DEF@[0; 35)
1+
SOURCE_FILE@[0; 46)
2+
TYPE_ALIAS_DEF@[0; 45)
33
TYPE_KW@[0; 4) "type"
44
WHITESPACE@[4; 5) " "
55
NAME@[5; 6)
66
IDENT@[5; 6) "A"
77
WHITESPACE@[6; 7) " "
88
EQ@[7; 8) "="
99
WHITESPACE@[8; 9) " "
10-
PATH_TYPE@[9; 34)
11-
PATH@[9; 34)
12-
PATH_SEGMENT@[9; 34)
10+
PATH_TYPE@[9; 44)
11+
PATH@[9; 44)
12+
PATH_SEGMENT@[9; 44)
1313
NAME_REF@[9; 10)
1414
IDENT@[9; 10) "B"
15-
TYPE_ARG_LIST@[10; 34)
15+
TYPE_ARG_LIST@[10; 44)
1616
L_ANGLE@[10; 11) "<"
1717
LIFETIME_ARG@[11; 18)
1818
LIFETIME@[11; 18) "\'static"
@@ -26,15 +26,30 @@ SOURCE_FILE@[0; 36)
2626
IDENT@[20; 23) "i32"
2727
COMMA@[23; 24) ","
2828
WHITESPACE@[24; 25) " "
29-
ASSOC_TYPE_ARG@[25; 33)
30-
NAME_REF@[25; 29)
31-
IDENT@[25; 29) "Item"
32-
EQ@[29; 30) "="
33-
PATH_TYPE@[30; 33)
34-
PATH@[30; 33)
35-
PATH_SEGMENT@[30; 33)
36-
NAME_REF@[30; 33)
37-
IDENT@[30; 33) "u64"
38-
R_ANGLE@[33; 34) ">"
39-
SEMI@[34; 35) ";"
40-
WHITESPACE@[35; 36) "\n"
29+
CONST_ARG@[25; 26)
30+
INT_NUMBER@[25; 26) "1"
31+
COMMA@[26; 27) ","
32+
WHITESPACE@[27; 28) " "
33+
CONST_ARG@[28; 33)
34+
BLOCK_EXPR@[28; 33)
35+
BLOCK@[28; 33)
36+
L_CURLY@[28; 29) "{"
37+
WHITESPACE@[29; 30) " "
38+
LITERAL@[30; 31)
39+
INT_NUMBER@[30; 31) "2"
40+
WHITESPACE@[31; 32) " "
41+
R_CURLY@[32; 33) "}"
42+
COMMA@[33; 34) ","
43+
WHITESPACE@[34; 35) " "
44+
ASSOC_TYPE_ARG@[35; 43)
45+
NAME_REF@[35; 39)
46+
IDENT@[35; 39) "Item"
47+
EQ@[39; 40) "="
48+
PATH_TYPE@[40; 43)
49+
PATH@[40; 43)
50+
PATH_SEGMENT@[40; 43)
51+
NAME_REF@[40; 43)
52+
IDENT@[40; 43) "u64"
53+
R_ANGLE@[43; 44) ">"
54+
SEMI@[44; 45) ";"
55+
WHITESPACE@[45; 46) "\n"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
impl<const N: u32> Bar<N> {}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
SOURCE_FILE@[0; 29)
2+
IMPL_BLOCK@[0; 28)
3+
IMPL_KW@[0; 4) "impl"
4+
TYPE_PARAM_LIST@[4; 18)
5+
L_ANGLE@[4; 5) "<"
6+
CONST_PARAM@[5; 17)
7+
CONST_KW@[5; 10) "const"
8+
WHITESPACE@[10; 11) " "
9+
NAME@[11; 12)
10+
IDENT@[11; 12) "N"
11+
COLON@[12; 13) ":"
12+
WHITESPACE@[13; 14) " "
13+
PATH_TYPE@[14; 17)
14+
PATH@[14; 17)
15+
PATH_SEGMENT@[14; 17)
16+
NAME_REF@[14; 17)
17+
IDENT@[14; 17) "u32"
18+
R_ANGLE@[17; 18) ">"
19+
WHITESPACE@[18; 19) " "
20+
PATH_TYPE@[19; 25)
21+
PATH@[19; 25)
22+
PATH_SEGMENT@[19; 25)
23+
NAME_REF@[19; 22)
24+
IDENT@[19; 22) "Bar"
25+
TYPE_ARG_LIST@[22; 25)
26+
L_ANGLE@[22; 23) "<"
27+
TYPE_ARG@[23; 24)
28+
PATH_TYPE@[23; 24)
29+
PATH@[23; 24)
30+
PATH_SEGMENT@[23; 24)
31+
NAME_REF@[23; 24)
32+
IDENT@[23; 24) "N"
33+
R_ANGLE@[24; 25) ">"
34+
WHITESPACE@[25; 26) " "
35+
ITEM_LIST@[26; 28)
36+
L_CURLY@[26; 27) "{"
37+
R_CURLY@[27; 28) "}"
38+
WHITESPACE@[28; 29) "\n"

xtask/src/ast_src.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ pub(crate) const KINDS_SRC: KindsSrc = KindsSrc {
206206
"LIFETIME_ARG",
207207
"TYPE_ARG",
208208
"ASSOC_TYPE_ARG",
209+
"CONST_ARG",
209210
"PARAM_LIST",
210211
"PARAM",
211212
"SELF_PARAM",
@@ -511,10 +512,12 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
511512
type_args: [TypeArg],
512513
lifetime_args: [LifetimeArg],
513514
assoc_type_args: [AssocTypeArg],
515+
const_arg: [ConstArg],
514516
}
515517
struct TypeArg { TypeRef }
516518
struct AssocTypeArg { NameRef, TypeRef }
517519
struct LifetimeArg {}
520+
struct ConstArg { Literal, BlockExpr }
518521

519522
struct MacroItems: ModuleItemOwner, FnDefOwner { }
520523

0 commit comments

Comments
 (0)