aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--grammar.ron1
-rw-r--r--src/parser/grammar/items/mod.rs17
-rw-r--r--src/parser/grammar/mod.rs24
-rw-r--r--src/parser/grammar/types.rs26
-rw-r--r--src/syntax_kinds.rs2
-rw-r--r--tests/data/parser/inline/0028_fn_pointer_type.rs3
-rw-r--r--tests/data/parser/inline/0028_fn_pointer_type.txt52
-rw-r--r--tests/data/parser/inline/0029_fn_pointer_type_missing_fn.rs1
-rw-r--r--tests/data/parser/inline/0029_fn_pointer_type_missing_fn.txt24
-rw-r--r--tests/data/parser/inline/0030_fn_pointer_type_with_ret.rs1
-rw-r--r--tests/data/parser/inline/0030_fn_pointer_type_with_ret.txt21
11 files changed, 155 insertions, 17 deletions
diff --git a/grammar.ron b/grammar.ron
index e3010b009..d5ad59553 100644
--- a/grammar.ron
+++ b/grammar.ron
@@ -110,6 +110,7 @@ Grammar(
110 "SLICE_TYPE", 110 "SLICE_TYPE",
111 "REFERENCE_TYPE", 111 "REFERENCE_TYPE",
112 "PLACEHOLDER_TYPE", 112 "PLACEHOLDER_TYPE",
113 "FN_POINTER_TYPE",
113 114
114 "EXTERN_BLOCK", 115 "EXTERN_BLOCK",
115 "ENUM_VARIANT", 116 "ENUM_VARIANT",
diff --git a/src/parser/grammar/items/mod.rs b/src/parser/grammar/items/mod.rs
index b1edf2f22..18ee8af86 100644
--- a/src/parser/grammar/items/mod.rs
+++ b/src/parser/grammar/items/mod.rs
@@ -222,12 +222,6 @@ fn fn_item(p: &mut Parser) {
222 p.expect(L_CURLY); 222 p.expect(L_CURLY);
223 p.expect(R_CURLY); 223 p.expect(R_CURLY);
224 } 224 }
225
226 fn fn_value_parameters(p: &mut Parser) {
227 assert!(p.at(L_PAREN));
228 p.bump();
229 p.expect(R_PAREN);
230 }
231} 225}
232 226
233// test type_item 227// test type_item
@@ -263,14 +257,3 @@ fn mod_item(p: &mut Parser) {
263 } 257 }
264 } 258 }
265} 259}
266
267fn abi(p: &mut Parser) {
268 assert!(p.at(EXTERN_KW));
269 let abi = p.start();
270 p.bump();
271 match p.current() {
272 STRING | RAW_STRING => p.bump(),
273 _ => (),
274 }
275 abi.complete(p, ABI);
276}
diff --git a/src/parser/grammar/mod.rs b/src/parser/grammar/mod.rs
index abf9fe86c..5266354c1 100644
--- a/src/parser/grammar/mod.rs
+++ b/src/parser/grammar/mod.rs
@@ -50,6 +50,30 @@ fn alias(p: &mut Parser) -> bool {
50 true //FIXME: return false if three are errors 50 true //FIXME: return false if three are errors
51} 51}
52 52
53fn abi(p: &mut Parser) {
54 assert!(p.at(EXTERN_KW));
55 let abi = p.start();
56 p.bump();
57 match p.current() {
58 STRING | RAW_STRING => p.bump(),
59 _ => (),
60 }
61 abi.complete(p, ABI);
62}
63
64fn fn_value_parameters(p: &mut Parser) {
65 assert!(p.at(L_PAREN));
66 p.bump();
67 p.expect(R_PAREN);
68}
69
70fn fn_ret_type(p: &mut Parser) {
71 if p.at(THIN_ARROW) {
72 p.bump();
73 types::type_(p);
74 }
75}
76
53fn name(p: &mut Parser) { 77fn name(p: &mut Parser) {
54 if p.at(IDENT) { 78 if p.at(IDENT) {
55 let m = p.start(); 79 let m = p.start();
diff --git a/src/parser/grammar/types.rs b/src/parser/grammar/types.rs
index 37b74bfe7..ea4df8639 100644
--- a/src/parser/grammar/types.rs
+++ b/src/parser/grammar/types.rs
@@ -8,6 +8,7 @@ pub(super) fn type_(p: &mut Parser) {
8 L_BRACK => array_or_slice_type(p), 8 L_BRACK => array_or_slice_type(p),
9 AMPERSAND => reference_type(p), 9 AMPERSAND => reference_type(p),
10 UNDERSCORE => placeholder_type(p), 10 UNDERSCORE => placeholder_type(p),
11 FN_KW | UNSAFE_KW | EXTERN_KW => fn_pointer_type(p),
11 IDENT => path_type(p), 12 IDENT => path_type(p),
12 _ => { 13 _ => {
13 p.error("expected type"); 14 p.error("expected type");
@@ -140,6 +141,31 @@ fn placeholder_type(p: &mut Parser) {
140 m.complete(p, PLACEHOLDER_TYPE); 141 m.complete(p, PLACEHOLDER_TYPE);
141} 142}
142 143
144// test fn_pointer_type
145// type A = fn();
146// type B = unsafe fn();
147// type C = unsafe extern "C" fn();
148fn fn_pointer_type(p: &mut Parser) {
149 let m = p.start();
150 p.eat(UNSAFE_KW);
151 if p.at(EXTERN_KW) {
152 abi(p);
153 }
154 // test fn_pointer_type_missing_fn
155 // type F = unsafe ();
156 if !p.eat(FN_KW) {
157 m.abandon(p);
158 p.error("expected `fn`");
159 return;
160 }
161
162 fn_value_parameters(p);
163 // test fn_pointer_type_with_ret
164 // type F = fn() -> ();
165 fn_ret_type(p);
166 m.complete(p, FN_POINTER_TYPE);
167}
168
143fn path_type(p: &mut Parser) { 169fn path_type(p: &mut Parser) {
144 assert!(p.at(IDENT)); 170 assert!(p.at(IDENT));
145 let m = p.start(); 171 let m = p.start();
diff --git a/src/syntax_kinds.rs b/src/syntax_kinds.rs
index 73539d6d4..db0f51beb 100644
--- a/src/syntax_kinds.rs
+++ b/src/syntax_kinds.rs
@@ -108,6 +108,7 @@ pub enum SyntaxKind {
108 SLICE_TYPE, 108 SLICE_TYPE,
109 REFERENCE_TYPE, 109 REFERENCE_TYPE,
110 PLACEHOLDER_TYPE, 110 PLACEHOLDER_TYPE,
111 FN_POINTER_TYPE,
111 EXTERN_BLOCK, 112 EXTERN_BLOCK,
112 ENUM_VARIANT, 113 ENUM_VARIANT,
113 NAMED_FIELD, 114 NAMED_FIELD,
@@ -242,6 +243,7 @@ impl SyntaxKind {
242 SLICE_TYPE => &SyntaxInfo { name: "SLICE_TYPE" }, 243 SLICE_TYPE => &SyntaxInfo { name: "SLICE_TYPE" },
243 REFERENCE_TYPE => &SyntaxInfo { name: "REFERENCE_TYPE" }, 244 REFERENCE_TYPE => &SyntaxInfo { name: "REFERENCE_TYPE" },
244 PLACEHOLDER_TYPE => &SyntaxInfo { name: "PLACEHOLDER_TYPE" }, 245 PLACEHOLDER_TYPE => &SyntaxInfo { name: "PLACEHOLDER_TYPE" },
246 FN_POINTER_TYPE => &SyntaxInfo { name: "FN_POINTER_TYPE" },
245 EXTERN_BLOCK => &SyntaxInfo { name: "EXTERN_BLOCK" }, 247 EXTERN_BLOCK => &SyntaxInfo { name: "EXTERN_BLOCK" },
246 ENUM_VARIANT => &SyntaxInfo { name: "ENUM_VARIANT" }, 248 ENUM_VARIANT => &SyntaxInfo { name: "ENUM_VARIANT" },
247 NAMED_FIELD => &SyntaxInfo { name: "NAMED_FIELD" }, 249 NAMED_FIELD => &SyntaxInfo { name: "NAMED_FIELD" },
diff --git a/tests/data/parser/inline/0028_fn_pointer_type.rs b/tests/data/parser/inline/0028_fn_pointer_type.rs
new file mode 100644
index 000000000..c9bf3bdb4
--- /dev/null
+++ b/tests/data/parser/inline/0028_fn_pointer_type.rs
@@ -0,0 +1,3 @@
1type A = fn();
2type B = unsafe fn();
3type C = unsafe extern "C" fn();
diff --git a/tests/data/parser/inline/0028_fn_pointer_type.txt b/tests/data/parser/inline/0028_fn_pointer_type.txt
new file mode 100644
index 000000000..6c62b0051
--- /dev/null
+++ b/tests/data/parser/inline/0028_fn_pointer_type.txt
@@ -0,0 +1,52 @@
1FILE@[0; 70)
2 TYPE_ITEM@[0; 15)
3 TYPE_KW@[0; 4)
4 NAME@[4; 7)
5 WHITESPACE@[4; 5)
6 IDENT@[5; 6) "A"
7 WHITESPACE@[6; 7)
8 EQ@[7; 8)
9 FN_POINTER_TYPE@[8; 13)
10 WHITESPACE@[8; 9)
11 FN_KW@[9; 11)
12 L_PAREN@[11; 12)
13 R_PAREN@[12; 13)
14 SEMI@[13; 14)
15 WHITESPACE@[14; 15)
16 TYPE_ITEM@[15; 37)
17 TYPE_KW@[15; 19)
18 NAME@[19; 22)
19 WHITESPACE@[19; 20)
20 IDENT@[20; 21) "B"
21 WHITESPACE@[21; 22)
22 EQ@[22; 23)
23 FN_POINTER_TYPE@[23; 35)
24 WHITESPACE@[23; 24)
25 UNSAFE_KW@[24; 30)
26 WHITESPACE@[30; 31)
27 FN_KW@[31; 33)
28 L_PAREN@[33; 34)
29 R_PAREN@[34; 35)
30 SEMI@[35; 36)
31 WHITESPACE@[36; 37)
32 TYPE_ITEM@[37; 70)
33 TYPE_KW@[37; 41)
34 NAME@[41; 44)
35 WHITESPACE@[41; 42)
36 IDENT@[42; 43) "C"
37 WHITESPACE@[43; 44)
38 EQ@[44; 45)
39 FN_POINTER_TYPE@[45; 68)
40 WHITESPACE@[45; 46)
41 UNSAFE_KW@[46; 52)
42 ABI@[52; 64)
43 WHITESPACE@[52; 53)
44 EXTERN_KW@[53; 59)
45 WHITESPACE@[59; 60)
46 STRING@[60; 63)
47 WHITESPACE@[63; 64)
48 FN_KW@[64; 66)
49 L_PAREN@[66; 67)
50 R_PAREN@[67; 68)
51 SEMI@[68; 69)
52 WHITESPACE@[69; 70)
diff --git a/tests/data/parser/inline/0029_fn_pointer_type_missing_fn.rs b/tests/data/parser/inline/0029_fn_pointer_type_missing_fn.rs
new file mode 100644
index 000000000..f014914ff
--- /dev/null
+++ b/tests/data/parser/inline/0029_fn_pointer_type_missing_fn.rs
@@ -0,0 +1 @@
type F = unsafe ();
diff --git a/tests/data/parser/inline/0029_fn_pointer_type_missing_fn.txt b/tests/data/parser/inline/0029_fn_pointer_type_missing_fn.txt
new file mode 100644
index 000000000..dd6e24096
--- /dev/null
+++ b/tests/data/parser/inline/0029_fn_pointer_type_missing_fn.txt
@@ -0,0 +1,24 @@
1FILE@[0; 20)
2 TYPE_ITEM@[0; 16)
3 TYPE_KW@[0; 4)
4 NAME@[4; 7)
5 WHITESPACE@[4; 5)
6 IDENT@[5; 6) "F"
7 WHITESPACE@[6; 7)
8 EQ@[7; 8)
9 WHITESPACE@[8; 9)
10 UNSAFE_KW@[9; 15)
11 err: `expected `fn``
12 err: `expected SEMI`
13 WHITESPACE@[15; 16)
14 ERROR@[16; 17)
15 err: `expected item`
16 L_PAREN@[16; 17)
17 ERROR@[17; 18)
18 err: `expected item`
19 R_PAREN@[17; 18)
20 ERROR@[18; 20)
21 err: `expected item, found `;`
22consider removing this semicolon`
23 SEMI@[18; 19)
24 WHITESPACE@[19; 20)
diff --git a/tests/data/parser/inline/0030_fn_pointer_type_with_ret.rs b/tests/data/parser/inline/0030_fn_pointer_type_with_ret.rs
new file mode 100644
index 000000000..e3ba5e87f
--- /dev/null
+++ b/tests/data/parser/inline/0030_fn_pointer_type_with_ret.rs
@@ -0,0 +1 @@
type F = fn() -> ();
diff --git a/tests/data/parser/inline/0030_fn_pointer_type_with_ret.txt b/tests/data/parser/inline/0030_fn_pointer_type_with_ret.txt
new file mode 100644
index 000000000..b41efa368
--- /dev/null
+++ b/tests/data/parser/inline/0030_fn_pointer_type_with_ret.txt
@@ -0,0 +1,21 @@
1FILE@[0; 21)
2 TYPE_ITEM@[0; 21)
3 TYPE_KW@[0; 4)
4 NAME@[4; 7)
5 WHITESPACE@[4; 5)
6 IDENT@[5; 6) "F"
7 WHITESPACE@[6; 7)
8 EQ@[7; 8)
9 FN_POINTER_TYPE@[8; 19)
10 WHITESPACE@[8; 9)
11 FN_KW@[9; 11)
12 L_PAREN@[11; 12)
13 R_PAREN@[12; 13)
14 WHITESPACE@[13; 14)
15 THIN_ARROW@[14; 16)
16 TUPLE_TYPE@[16; 19)
17 WHITESPACE@[16; 17)
18 L_PAREN@[17; 18)
19 R_PAREN@[18; 19)
20 SEMI@[19; 20)
21 WHITESPACE@[20; 21)