aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax
diff options
context:
space:
mode:
authorErlend Tobiassen <[email protected]>2019-01-25 22:56:31 +0000
committerErlend Tobiassen <[email protected]>2019-01-25 22:56:31 +0000
commite28bd099d68ee124280eeadefe48c1f2e0ff6c17 (patch)
treebc5e32c652d50a439fa8f2d7e8872c947f3de2f6 /crates/ra_syntax
parentdc5ecf446991c65359cf49d52098fcec5f1a1f68 (diff)
Support macro calls in type position
Diffstat (limited to 'crates/ra_syntax')
-rw-r--r--crates/ra_syntax/src/grammar/types.rs24
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/ok/0117_macro_call_type.rs2
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/ok/0117_macro_call_type.txt43
3 files changed, 68 insertions, 1 deletions
diff --git a/crates/ra_syntax/src/grammar/types.rs b/crates/ra_syntax/src/grammar/types.rs
index 21d89d83b..adc189a29 100644
--- a/crates/ra_syntax/src/grammar/types.rs
+++ b/crates/ra_syntax/src/grammar/types.rs
@@ -29,7 +29,7 @@ fn type_with_bounds_cond(p: &mut Parser, allow_bounds: bool) {
29 DYN_KW => dyn_trait_type(p), 29 DYN_KW => dyn_trait_type(p),
30 // Some path types are not allowed to have bounds (no plus) 30 // Some path types are not allowed to have bounds (no plus)
31 L_ANGLE => path_type_(p, allow_bounds), 31 L_ANGLE => path_type_(p, allow_bounds),
32 _ if paths::is_path_start(p) => path_type_(p, allow_bounds), 32 _ if paths::is_path_start(p) => path_or_macro_type_(p, allow_bounds),
33 _ => { 33 _ => {
34 p.err_recover("expected type", TYPE_RECOVERY_SET); 34 p.err_recover("expected type", TYPE_RECOVERY_SET);
35 } 35 }
@@ -243,6 +243,28 @@ pub(super) fn path_type(p: &mut Parser) {
243 path_type_(p, true) 243 path_type_(p, true)
244} 244}
245 245
246// test macro_call_type
247// type A = foo!();
248// type B = crate::foo!();
249fn path_or_macro_type_(p: &mut Parser, allow_bounds: bool) {
250 assert!(paths::is_path_start(p) || p.at(L_ANGLE));
251 let m = p.start();
252 paths::type_path(p);
253
254 let kind = if p.at(EXCL) {
255 items::macro_call_after_excl(p);
256 MACRO_CALL
257 } else {
258 PATH_TYPE
259 };
260
261 if allow_bounds && p.eat(PLUS) {
262 type_params::bounds_without_colon(p);
263 }
264
265 m.complete(p, kind);
266}
267
246pub(super) fn path_type_(p: &mut Parser, allow_bounds: bool) { 268pub(super) fn path_type_(p: &mut Parser, allow_bounds: bool) {
247 assert!(paths::is_path_start(p) || p.at(L_ANGLE)); 269 assert!(paths::is_path_start(p) || p.at(L_ANGLE));
248 let m = p.start(); 270 let m = p.start();
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0117_macro_call_type.rs b/crates/ra_syntax/tests/data/parser/inline/ok/0117_macro_call_type.rs
new file mode 100644
index 000000000..edb470c89
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/ok/0117_macro_call_type.rs
@@ -0,0 +1,2 @@
1type A = foo!();
2type B = crate::foo!();
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0117_macro_call_type.txt b/crates/ra_syntax/tests/data/parser/inline/ok/0117_macro_call_type.txt
new file mode 100644
index 000000000..b2d95451c
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/ok/0117_macro_call_type.txt
@@ -0,0 +1,43 @@
1SOURCE_FILE@[0; 41)
2 TYPE_DEF@[0; 16)
3 TYPE_KW@[0; 4)
4 WHITESPACE@[4; 5)
5 NAME@[5; 6)
6 IDENT@[5; 6) "A"
7 WHITESPACE@[6; 7)
8 EQ@[7; 8)
9 WHITESPACE@[8; 9)
10 MACRO_CALL@[9; 15)
11 PATH@[9; 12)
12 PATH_SEGMENT@[9; 12)
13 NAME_REF@[9; 12)
14 IDENT@[9; 12) "foo"
15 EXCL@[12; 13)
16 TOKEN_TREE@[13; 15)
17 L_PAREN@[13; 14)
18 R_PAREN@[14; 15)
19 SEMI@[15; 16)
20 WHITESPACE@[16; 17)
21 TYPE_DEF@[17; 40)
22 TYPE_KW@[17; 21)
23 WHITESPACE@[21; 22)
24 NAME@[22; 23)
25 IDENT@[22; 23) "B"
26 WHITESPACE@[23; 24)
27 EQ@[24; 25)
28 WHITESPACE@[25; 26)
29 MACRO_CALL@[26; 39)
30 PATH@[26; 36)
31 PATH@[26; 31)
32 PATH_SEGMENT@[26; 31)
33 CRATE_KW@[26; 31)
34 COLONCOLON@[31; 33)
35 PATH_SEGMENT@[33; 36)
36 NAME_REF@[33; 36)
37 IDENT@[33; 36) "foo"
38 EXCL@[36; 37)
39 TOKEN_TREE@[37; 39)
40 L_PAREN@[37; 38)
41 R_PAREN@[38; 39)
42 SEMI@[39; 40)
43 WHITESPACE@[40; 41)