aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--grammar.ron3
-rw-r--r--src/parser/grammar/items/mod.rs80
-rw-r--r--src/parser/grammar/type_params.rs5
-rw-r--r--src/parser/grammar/types.rs11
-rw-r--r--src/syntax_kinds.rs7
-rw-r--r--tests/data/lexer/0011_keywords.rs2
-rw-r--r--tests/data/lexer/0011_keywords.txt2
-rw-r--r--tests/data/parser/inline/0014_type_item_type_params.rs1
-rw-r--r--tests/data/parser/inline/0014_type_item_type_params.txt17
-rw-r--r--tests/data/parser/inline/0015_type_item.rs1
-rw-r--r--tests/data/parser/inline/0015_type_item.txt11
-rw-r--r--tests/data/parser/inline/0016_type_item_where_clause.rs1
-rw-r--r--tests/data/parser/inline/0016_type_item_where_clause.txt20
-rw-r--r--tests/testutils/src/lib.rs7
14 files changed, 134 insertions, 34 deletions
diff --git a/grammar.ron b/grammar.ron
index e97ef0c2c..c38bf654d 100644
--- a/grammar.ron
+++ b/grammar.ron
@@ -26,6 +26,7 @@ Grammar(
26 "static", 26 "static",
27 "mut", 27 "mut",
28 "unsafe", 28 "unsafe",
29 "type",
29 ], 30 ],
30 contextual_keywords: [ 31 contextual_keywords: [
31 "auto", 32 "auto",
@@ -98,6 +99,7 @@ Grammar(
98 "CONST_ITEM", 99 "CONST_ITEM",
99 "TRAIT_ITEM", 100 "TRAIT_ITEM",
100 "IMPL_ITEM", 101 "IMPL_ITEM",
102 "TYPE_ITEM",
101 103
102 "EXTERN_BLOCK", 104 "EXTERN_BLOCK",
103 "ENUM_VARIANT", 105 "ENUM_VARIANT",
@@ -112,6 +114,7 @@ Grammar(
112 "ALIAS", 114 "ALIAS",
113 "VISIBILITY", 115 "VISIBILITY",
114 "TYPE_PARAM_LIST", 116 "TYPE_PARAM_LIST",
117 "WHERE_CLAUSE",
115 "LIFETIME_PARAM", 118 "LIFETIME_PARAM",
116 "TYPE_PARAM", 119 "TYPE_PARAM",
117 "ABI", 120 "ABI",
diff --git a/src/parser/grammar/items/mod.rs b/src/parser/grammar/items/mod.rs
index b73628ec0..ffe86fa97 100644
--- a/src/parser/grammar/items/mod.rs
+++ b/src/parser/grammar/items/mod.rs
@@ -150,7 +150,14 @@ fn item(p: &mut Parser) {
150 } 150 }
151 } 151 }
152 } 152 }
153 153 FN_KW => {
154 fn_item(p);
155 FN_ITEM
156 }
157 TYPE_KW => {
158 type_item(p);
159 TYPE_ITEM
160 }
154 MOD_KW => { 161 MOD_KW => {
155 mod_item(p); 162 mod_item(p);
156 MOD_ITEM 163 MOD_ITEM
@@ -163,10 +170,6 @@ fn item(p: &mut Parser) {
163 structs::enum_item(p); 170 structs::enum_item(p);
164 ENUM_ITEM 171 ENUM_ITEM
165 } 172 }
166 FN_KW => {
167 fn_item(p);
168 FN_ITEM
169 }
170 L_CURLY => { 173 L_CURLY => {
171 item.abandon(p); 174 item.abandon(p);
172 error_block(p, "expected item"); 175 error_block(p, "expected item");
@@ -203,29 +206,6 @@ fn extern_block(p: &mut Parser) {
203 p.expect(R_CURLY); 206 p.expect(R_CURLY);
204} 207}
205 208
206fn mod_item(p: &mut Parser) {
207 assert!(p.at(MOD_KW));
208 p.bump();
209
210 if p.expect(IDENT) && !p.eat(SEMI) {
211 if p.expect(L_CURLY) {
212 mod_contents(p, true);
213 p.expect(R_CURLY);
214 }
215 }
216}
217
218fn abi(p: &mut Parser) {
219 assert!(p.at(EXTERN_KW));
220 let abi = p.start();
221 p.bump();
222 match p.current() {
223 STRING | RAW_STRING => p.bump(),
224 _ => (),
225 }
226 abi.complete(p, ABI);
227}
228
229fn fn_item(p: &mut Parser) { 209fn fn_item(p: &mut Parser) {
230 assert!(p.at(FN_KW)); 210 assert!(p.at(FN_KW));
231 p.bump(); 211 p.bump();
@@ -248,3 +228,47 @@ fn fn_item(p: &mut Parser) {
248 p.expect(R_PAREN); 228 p.expect(R_PAREN);
249 } 229 }
250} 230}
231
232// test type_item
233// type Foo = Bar;
234fn type_item(p: &mut Parser) {
235 assert!(p.at(TYPE_KW));
236 p.bump();
237
238 p.expect(IDENT);
239
240 // test type_item_type_params
241 // type Result<T> = ();
242 type_params::list(p);
243
244 // test type_item_where_clause
245 // type Foo where Foo: Copy = ();
246 type_params::where_clause(p);
247
248 p.expect(EQ);
249 types::type_ref(p);
250 p.expect(SEMI);
251}
252
253fn mod_item(p: &mut Parser) {
254 assert!(p.at(MOD_KW));
255 p.bump();
256
257 if p.expect(IDENT) && !p.eat(SEMI) {
258 if p.expect(L_CURLY) {
259 mod_contents(p, true);
260 p.expect(R_CURLY);
261 }
262 }
263}
264
265fn abi(p: &mut Parser) {
266 assert!(p.at(EXTERN_KW));
267 let abi = p.start();
268 p.bump();
269 match p.current() {
270 STRING | RAW_STRING => p.bump(),
271 _ => (),
272 }
273 abi.complete(p, ABI);
274}
diff --git a/src/parser/grammar/type_params.rs b/src/parser/grammar/type_params.rs
index 12c9a5362..8f62a471c 100644
--- a/src/parser/grammar/type_params.rs
+++ b/src/parser/grammar/type_params.rs
@@ -70,6 +70,11 @@ pub(super) fn list(p: &mut Parser) {
70 70
71pub(super) fn where_clause(p: &mut Parser) { 71pub(super) fn where_clause(p: &mut Parser) {
72 if p.at(WHERE_KW) { 72 if p.at(WHERE_KW) {
73 let m = p.start();
73 p.bump(); 74 p.bump();
75 p.expect(IDENT);
76 p.expect(COLON);
77 p.expect(IDENT);
78 m.complete(p, WHERE_CLAUSE);
74 } 79 }
75} 80}
diff --git a/src/parser/grammar/types.rs b/src/parser/grammar/types.rs
index 1a3d44a0a..c798edd08 100644
--- a/src/parser/grammar/types.rs
+++ b/src/parser/grammar/types.rs
@@ -1,5 +1,14 @@
1use super::*; 1use super::*;
2 2
3pub(super) fn type_ref(p: &mut Parser) { 3pub(super) fn type_ref(p: &mut Parser) {
4 p.expect(IDENT); 4 match p.current() {
5 IDENT => p.bump(),
6 L_PAREN => {
7 p.bump();
8 p.expect(R_PAREN);
9 }
10 _ => {
11 p.error("expected type");
12 }
13 }
5} 14}
diff --git a/src/syntax_kinds.rs b/src/syntax_kinds.rs
index 27bc1cafa..dc287f0f4 100644
--- a/src/syntax_kinds.rs
+++ b/src/syntax_kinds.rs
@@ -83,6 +83,7 @@ pub enum SyntaxKind {
83 STATIC_KW, 83 STATIC_KW,
84 MUT_KW, 84 MUT_KW,
85 UNSAFE_KW, 85 UNSAFE_KW,
86 TYPE_KW,
86 AUTO_KW, 87 AUTO_KW,
87 DEFAULT_KW, 88 DEFAULT_KW,
88 UNION_KW, 89 UNION_KW,
@@ -97,6 +98,7 @@ pub enum SyntaxKind {
97 CONST_ITEM, 98 CONST_ITEM,
98 TRAIT_ITEM, 99 TRAIT_ITEM,
99 IMPL_ITEM, 100 IMPL_ITEM,
101 TYPE_ITEM,
100 EXTERN_BLOCK, 102 EXTERN_BLOCK,
101 ENUM_VARIANT, 103 ENUM_VARIANT,
102 NAMED_FIELD, 104 NAMED_FIELD,
@@ -110,6 +112,7 @@ pub enum SyntaxKind {
110 ALIAS, 112 ALIAS,
111 VISIBILITY, 113 VISIBILITY,
112 TYPE_PARAM_LIST, 114 TYPE_PARAM_LIST,
115 WHERE_CLAUSE,
113 LIFETIME_PARAM, 116 LIFETIME_PARAM,
114 TYPE_PARAM, 117 TYPE_PARAM,
115 ABI, 118 ABI,
@@ -203,6 +206,7 @@ impl SyntaxKind {
203 STATIC_KW => &SyntaxInfo { name: "STATIC_KW" }, 206 STATIC_KW => &SyntaxInfo { name: "STATIC_KW" },
204 MUT_KW => &SyntaxInfo { name: "MUT_KW" }, 207 MUT_KW => &SyntaxInfo { name: "MUT_KW" },
205 UNSAFE_KW => &SyntaxInfo { name: "UNSAFE_KW" }, 208 UNSAFE_KW => &SyntaxInfo { name: "UNSAFE_KW" },
209 TYPE_KW => &SyntaxInfo { name: "TYPE_KW" },
206 AUTO_KW => &SyntaxInfo { name: "AUTO_KW" }, 210 AUTO_KW => &SyntaxInfo { name: "AUTO_KW" },
207 DEFAULT_KW => &SyntaxInfo { name: "DEFAULT_KW" }, 211 DEFAULT_KW => &SyntaxInfo { name: "DEFAULT_KW" },
208 UNION_KW => &SyntaxInfo { name: "UNION_KW" }, 212 UNION_KW => &SyntaxInfo { name: "UNION_KW" },
@@ -217,6 +221,7 @@ impl SyntaxKind {
217 CONST_ITEM => &SyntaxInfo { name: "CONST_ITEM" }, 221 CONST_ITEM => &SyntaxInfo { name: "CONST_ITEM" },
218 TRAIT_ITEM => &SyntaxInfo { name: "TRAIT_ITEM" }, 222 TRAIT_ITEM => &SyntaxInfo { name: "TRAIT_ITEM" },
219 IMPL_ITEM => &SyntaxInfo { name: "IMPL_ITEM" }, 223 IMPL_ITEM => &SyntaxInfo { name: "IMPL_ITEM" },
224 TYPE_ITEM => &SyntaxInfo { name: "TYPE_ITEM" },
220 EXTERN_BLOCK => &SyntaxInfo { name: "EXTERN_BLOCK" }, 225 EXTERN_BLOCK => &SyntaxInfo { name: "EXTERN_BLOCK" },
221 ENUM_VARIANT => &SyntaxInfo { name: "ENUM_VARIANT" }, 226 ENUM_VARIANT => &SyntaxInfo { name: "ENUM_VARIANT" },
222 NAMED_FIELD => &SyntaxInfo { name: "NAMED_FIELD" }, 227 NAMED_FIELD => &SyntaxInfo { name: "NAMED_FIELD" },
@@ -230,6 +235,7 @@ impl SyntaxKind {
230 ALIAS => &SyntaxInfo { name: "ALIAS" }, 235 ALIAS => &SyntaxInfo { name: "ALIAS" },
231 VISIBILITY => &SyntaxInfo { name: "VISIBILITY" }, 236 VISIBILITY => &SyntaxInfo { name: "VISIBILITY" },
232 TYPE_PARAM_LIST => &SyntaxInfo { name: "TYPE_PARAM_LIST" }, 237 TYPE_PARAM_LIST => &SyntaxInfo { name: "TYPE_PARAM_LIST" },
238 WHERE_CLAUSE => &SyntaxInfo { name: "WHERE_CLAUSE" },
233 LIFETIME_PARAM => &SyntaxInfo { name: "LIFETIME_PARAM" }, 239 LIFETIME_PARAM => &SyntaxInfo { name: "LIFETIME_PARAM" },
234 TYPE_PARAM => &SyntaxInfo { name: "TYPE_PARAM" }, 240 TYPE_PARAM => &SyntaxInfo { name: "TYPE_PARAM" },
235 ABI => &SyntaxInfo { name: "ABI" }, 241 ABI => &SyntaxInfo { name: "ABI" },
@@ -268,6 +274,7 @@ pub(crate) fn ident_to_keyword(ident: &str) -> Option<SyntaxKind> {
268 "static" => Some(STATIC_KW), 274 "static" => Some(STATIC_KW),
269 "mut" => Some(MUT_KW), 275 "mut" => Some(MUT_KW),
270 "unsafe" => Some(UNSAFE_KW), 276 "unsafe" => Some(UNSAFE_KW),
277 "type" => Some(TYPE_KW),
271 _ => None, 278 _ => None,
272 } 279 }
273} 280}
diff --git a/tests/data/lexer/0011_keywords.rs b/tests/data/lexer/0011_keywords.rs
index b74fc606e..7a9509f3c 100644
--- a/tests/data/lexer/0011_keywords.rs
+++ b/tests/data/lexer/0011_keywords.rs
@@ -1,3 +1,3 @@
1fn use struct trait enum impl true false as extern crate 1fn use struct trait enum impl true false as extern crate
2mod pub self super in where for loop while if match const 2mod pub self super in where for loop while if match const
3static mut 3static mut type
diff --git a/tests/data/lexer/0011_keywords.txt b/tests/data/lexer/0011_keywords.txt
index 05b1f0995..96528952b 100644
--- a/tests/data/lexer/0011_keywords.txt
+++ b/tests/data/lexer/0011_keywords.txt
@@ -47,4 +47,6 @@ WHITESPACE 1 "\n"
47STATIC_KW 6 "static" 47STATIC_KW 6 "static"
48WHITESPACE 1 " " 48WHITESPACE 1 " "
49MUT_KW 3 "mut" 49MUT_KW 3 "mut"
50WHITESPACE 1 " "
51TYPE_KW 4 "type"
50WHITESPACE 1 "\n" 52WHITESPACE 1 "\n"
diff --git a/tests/data/parser/inline/0014_type_item_type_params.rs b/tests/data/parser/inline/0014_type_item_type_params.rs
new file mode 100644
index 000000000..defd110c4
--- /dev/null
+++ b/tests/data/parser/inline/0014_type_item_type_params.rs
@@ -0,0 +1 @@
type Result<T> = ();
diff --git a/tests/data/parser/inline/0014_type_item_type_params.txt b/tests/data/parser/inline/0014_type_item_type_params.txt
new file mode 100644
index 000000000..b0f0f8337
--- /dev/null
+++ b/tests/data/parser/inline/0014_type_item_type_params.txt
@@ -0,0 +1,17 @@
1FILE@[0; 21)
2 TYPE_ITEM@[0; 21)
3 TYPE_KW@[0; 4)
4 WHITESPACE@[4; 5)
5 IDENT@[5; 11) "Result"
6 TYPE_PARAM_LIST@[11; 15)
7 L_ANGLE@[11; 12)
8 TYPE_PARAM@[12; 13)
9 IDENT@[12; 13) "T"
10 R_ANGLE@[13; 14)
11 WHITESPACE@[14; 15)
12 EQ@[15; 16)
13 WHITESPACE@[16; 17)
14 L_PAREN@[17; 18)
15 R_PAREN@[18; 19)
16 SEMI@[19; 20)
17 WHITESPACE@[20; 21)
diff --git a/tests/data/parser/inline/0015_type_item.rs b/tests/data/parser/inline/0015_type_item.rs
new file mode 100644
index 000000000..04c0344fa
--- /dev/null
+++ b/tests/data/parser/inline/0015_type_item.rs
@@ -0,0 +1 @@
type Foo = Bar;
diff --git a/tests/data/parser/inline/0015_type_item.txt b/tests/data/parser/inline/0015_type_item.txt
new file mode 100644
index 000000000..382d7ece0
--- /dev/null
+++ b/tests/data/parser/inline/0015_type_item.txt
@@ -0,0 +1,11 @@
1FILE@[0; 16)
2 TYPE_ITEM@[0; 16)
3 TYPE_KW@[0; 4)
4 WHITESPACE@[4; 5)
5 IDENT@[5; 8) "Foo"
6 WHITESPACE@[8; 9)
7 EQ@[9; 10)
8 WHITESPACE@[10; 11)
9 IDENT@[11; 14) "Bar"
10 SEMI@[14; 15)
11 WHITESPACE@[15; 16)
diff --git a/tests/data/parser/inline/0016_type_item_where_clause.rs b/tests/data/parser/inline/0016_type_item_where_clause.rs
new file mode 100644
index 000000000..a602d07f0
--- /dev/null
+++ b/tests/data/parser/inline/0016_type_item_where_clause.rs
@@ -0,0 +1 @@
type Foo where Foo: Copy = ();
diff --git a/tests/data/parser/inline/0016_type_item_where_clause.txt b/tests/data/parser/inline/0016_type_item_where_clause.txt
new file mode 100644
index 000000000..ddd335870
--- /dev/null
+++ b/tests/data/parser/inline/0016_type_item_where_clause.txt
@@ -0,0 +1,20 @@
1FILE@[0; 31)
2 TYPE_ITEM@[0; 31)
3 TYPE_KW@[0; 4)
4 WHITESPACE@[4; 5)
5 IDENT@[5; 8) "Foo"
6 WHERE_CLAUSE@[8; 25)
7 WHITESPACE@[8; 9)
8 WHERE_KW@[9; 14)
9 WHITESPACE@[14; 15)
10 IDENT@[15; 18) "Foo"
11 COLON@[18; 19)
12 WHITESPACE@[19; 20)
13 IDENT@[20; 24) "Copy"
14 WHITESPACE@[24; 25)
15 EQ@[25; 26)
16 WHITESPACE@[26; 27)
17 L_PAREN@[27; 28)
18 R_PAREN@[28; 29)
19 SEMI@[29; 30)
20 WHITESPACE@[30; 31)
diff --git a/tests/testutils/src/lib.rs b/tests/testutils/src/lib.rs
index f829b243b..d181e455b 100644
--- a/tests/testutils/src/lib.rs
+++ b/tests/testutils/src/lib.rs
@@ -76,15 +76,14 @@ fn test_from_dir(dir: &Path) -> Vec<PathBuf> {
76fn print_difference(expected: &str, actual: &str, path: &Path) { 76fn print_difference(expected: &str, actual: &str, path: &Path) {
77 let dir = project_dir(); 77 let dir = project_dir();
78 let path = path.strip_prefix(&dir).unwrap_or_else(|_| path); 78 let path = path.strip_prefix(&dir).unwrap_or_else(|_| path);
79 println!("\nfile: {}", path.display());
80 if expected.trim() == actual.trim() { 79 if expected.trim() == actual.trim() {
81 println!("whitespace difference"); 80 println!("whitespace difference, rewriting");
82 println!("rewriting the file");
83 file::put_text(path, actual).unwrap(); 81 file::put_text(path, actual).unwrap();
84 } else { 82 } else {
85 let changeset = Changeset::new(actual, expected, "\n"); 83 let changeset = Changeset::new(actual, expected, "\n");
86 println!("{}", changeset); 84 print!("{}", changeset);
87 } 85 }
86 println!("file: {}\n", path.display());
88 panic!("Comparison failed") 87 panic!("Comparison failed")
89} 88}
90 89