aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_parser/src/grammar
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_parser/src/grammar')
-rw-r--r--crates/ra_parser/src/grammar/expressions.rs6
-rw-r--r--crates/ra_parser/src/grammar/items.rs20
-rw-r--r--crates/ra_parser/src/grammar/paths.rs15
-rw-r--r--crates/ra_parser/src/grammar/patterns.rs8
-rw-r--r--crates/ra_parser/src/grammar/type_params.rs11
-rw-r--r--crates/ra_parser/src/grammar/types.rs16
6 files changed, 51 insertions, 25 deletions
diff --git a/crates/ra_parser/src/grammar/expressions.rs b/crates/ra_parser/src/grammar/expressions.rs
index d6e8df32a..6e72eea66 100644
--- a/crates/ra_parser/src/grammar/expressions.rs
+++ b/crates/ra_parser/src/grammar/expressions.rs
@@ -50,10 +50,8 @@ fn expr_no_struct(p: &mut Parser) {
50} 50}
51 51
52fn is_expr_stmt_attr_allowed(kind: SyntaxKind) -> bool { 52fn is_expr_stmt_attr_allowed(kind: SyntaxKind) -> bool {
53 match kind { 53 let forbid = matches!(kind, BIN_EXPR | RANGE_EXPR);
54 BIN_EXPR | RANGE_EXPR | IF_EXPR => false, 54 !forbid
55 _ => true,
56 }
57} 55}
58 56
59pub(super) fn stmt(p: &mut Parser, with_semi: StmtWithSemi) { 57pub(super) fn stmt(p: &mut Parser, with_semi: StmtWithSemi) {
diff --git a/crates/ra_parser/src/grammar/items.rs b/crates/ra_parser/src/grammar/items.rs
index 67a924de5..97642bc24 100644
--- a/crates/ra_parser/src/grammar/items.rs
+++ b/crates/ra_parser/src/grammar/items.rs
@@ -118,7 +118,22 @@ pub(super) fn maybe_item(p: &mut Parser, m: Marker, flavor: ItemFlavor) -> Resul
118 && p.at_contextual_kw("default") 118 && p.at_contextual_kw("default")
119 && (match p.nth(1) { 119 && (match p.nth(1) {
120 T![impl] => true, 120 T![impl] => true,
121 T![fn] | T![type] => { 121 T![unsafe] => {
122 // test default_unsafe_impl
123 // default unsafe impl Foo {}
124
125 // test default_unsafe_fn
126 // impl T for Foo {
127 // default unsafe fn foo() {}
128 // }
129 if p.nth(2) == T![impl] || p.nth(2) == T![fn] {
130 p.bump_remap(T![default]);
131 p.bump(T![unsafe]);
132 has_mods = true;
133 }
134 false
135 }
136 T![fn] | T![type] | T![const] => {
122 if let ItemFlavor::Mod = flavor { 137 if let ItemFlavor::Mod = flavor {
123 true 138 true
124 } else { 139 } else {
@@ -198,6 +213,9 @@ pub(super) fn maybe_item(p: &mut Parser, m: Marker, flavor: ItemFlavor) -> Resul
198 // default type T = Bar; 213 // default type T = Bar;
199 // default fn foo() {} 214 // default fn foo() {}
200 // } 215 // }
216 T![const] => {
217 consts::const_def(p, m);
218 }
201 219
202 // test unsafe_default_impl 220 // test unsafe_default_impl
203 // unsafe default impl Foo {} 221 // unsafe default impl Foo {}
diff --git a/crates/ra_parser/src/grammar/paths.rs b/crates/ra_parser/src/grammar/paths.rs
index 332acc1a0..b503af1dc 100644
--- a/crates/ra_parser/src/grammar/paths.rs
+++ b/crates/ra_parser/src/grammar/paths.rs
@@ -3,7 +3,7 @@
3use super::*; 3use super::*;
4 4
5pub(super) const PATH_FIRST: TokenSet = 5pub(super) const PATH_FIRST: TokenSet =
6 token_set![IDENT, SELF_KW, SUPER_KW, CRATE_KW, COLON, L_ANGLE]; 6 token_set![IDENT, T![self], T![super], T![crate], T![:], T![<]];
7 7
8pub(super) fn is_path_start(p: &Parser) -> bool { 8pub(super) fn is_path_start(p: &Parser) -> bool {
9 is_use_path_start(p) || p.at(T![<]) 9 is_use_path_start(p) || p.at(T![<])
@@ -41,10 +41,7 @@ fn path(p: &mut Parser, mode: Mode) {
41 path_segment(p, mode, true); 41 path_segment(p, mode, true);
42 let mut qual = path.complete(p, PATH); 42 let mut qual = path.complete(p, PATH);
43 loop { 43 loop {
44 let use_tree = match p.nth(2) { 44 let use_tree = matches!(p.nth(2), T![*] | T!['{']);
45 T![*] | T!['{'] => true,
46 _ => false,
47 };
48 if p.at(T![::]) && !use_tree { 45 if p.at(T![::]) && !use_tree {
49 let path = qual.precede(p); 46 let path = qual.precede(p);
50 p.bump(T![::]); 47 p.bump(T![::]);
@@ -73,8 +70,10 @@ fn path_segment(p: &mut Parser, mode: Mode, first: bool) {
73 } 70 }
74 p.expect(T![>]); 71 p.expect(T![>]);
75 } else { 72 } else {
73 let mut empty = true;
76 if first { 74 if first {
77 p.eat(T![::]); 75 p.eat(T![::]);
76 empty = false;
78 } 77 }
79 match p.current() { 78 match p.current() {
80 IDENT => { 79 IDENT => {
@@ -86,6 +85,12 @@ fn path_segment(p: &mut Parser, mode: Mode, first: bool) {
86 T![self] | T![super] | T![crate] => p.bump_any(), 85 T![self] | T![super] | T![crate] => p.bump_any(),
87 _ => { 86 _ => {
88 p.err_recover("expected identifier", items::ITEM_RECOVERY_SET); 87 p.err_recover("expected identifier", items::ITEM_RECOVERY_SET);
88 if empty {
89 // test_err empty_segment
90 // use crate::;
91 m.abandon(p);
92 return;
93 }
89 } 94 }
90 }; 95 };
91 } 96 }
diff --git a/crates/ra_parser/src/grammar/patterns.rs b/crates/ra_parser/src/grammar/patterns.rs
index 68fb2fc73..427c0eb49 100644
--- a/crates/ra_parser/src/grammar/patterns.rs
+++ b/crates/ra_parser/src/grammar/patterns.rs
@@ -4,7 +4,7 @@ use super::*;
4 4
5pub(super) const PATTERN_FIRST: TokenSet = expressions::LITERAL_FIRST 5pub(super) const PATTERN_FIRST: TokenSet = expressions::LITERAL_FIRST
6 .union(paths::PATH_FIRST) 6 .union(paths::PATH_FIRST)
7 .union(token_set![BOX_KW, REF_KW, MUT_KW, L_PAREN, L_BRACK, AMP, UNDERSCORE, MINUS, DOT]); 7 .union(token_set![T![box], T![ref], T![mut], T!['('], T!['['], T![&], T![_], T![-], T![.]]);
8 8
9pub(crate) fn pattern(p: &mut Parser) { 9pub(crate) fn pattern(p: &mut Parser) {
10 pattern_r(p, PAT_RECOVERY_SET); 10 pattern_r(p, PAT_RECOVERY_SET);
@@ -88,7 +88,9 @@ fn atom_pat(p: &mut Parser, recovery_set: TokenSet) -> Option<CompletedMarker> {
88 _ => bind_pat(p, true), 88 _ => bind_pat(p, true),
89 }, 89 },
90 90
91 _ if paths::is_use_path_start(p) => path_or_macro_pat(p), 91 // test type_path_in_pattern
92 // fn main() { let <_>::Foo = (); }
93 _ if paths::is_path_start(p) => path_or_macro_pat(p),
92 _ if is_literal_pat_start(p) => literal_pat(p), 94 _ if is_literal_pat_start(p) => literal_pat(p),
93 95
94 T![.] if p.at(T![..]) => dot_dot_pat(p), 96 T![.] if p.at(T![..]) => dot_dot_pat(p),
@@ -138,7 +140,7 @@ fn literal_pat(p: &mut Parser) -> CompletedMarker {
138// let Bar(..) = (); 140// let Bar(..) = ();
139// } 141// }
140fn path_or_macro_pat(p: &mut Parser) -> CompletedMarker { 142fn path_or_macro_pat(p: &mut Parser) -> CompletedMarker {
141 assert!(paths::is_use_path_start(p)); 143 assert!(paths::is_path_start(p));
142 let m = p.start(); 144 let m = p.start();
143 paths::expr_path(p); 145 paths::expr_path(p);
144 let kind = match p.current() { 146 let kind = match p.current() {
diff --git a/crates/ra_parser/src/grammar/type_params.rs b/crates/ra_parser/src/grammar/type_params.rs
index 50e4900c3..d1330d4b9 100644
--- a/crates/ra_parser/src/grammar/type_params.rs
+++ b/crates/ra_parser/src/grammar/type_params.rs
@@ -169,10 +169,7 @@ fn is_where_predicate(p: &mut Parser) -> bool {
169} 169}
170 170
171fn is_where_clause_end(p: &mut Parser) -> bool { 171fn is_where_clause_end(p: &mut Parser) -> bool {
172 match p.current() { 172 matches!(p.current(), T!['{'] | T![;] | T![=])
173 T!['{'] | T![;] | T![=] => true,
174 _ => false,
175 }
176} 173}
177 174
178fn where_predicate(p: &mut Parser) { 175fn where_predicate(p: &mut Parser) {
@@ -191,10 +188,14 @@ fn where_predicate(p: &mut Parser) {
191 } 188 }
192 _ => { 189 _ => {
193 // test where_pred_for 190 // test where_pred_for
194 // fn test<F>() 191 // fn for_trait<F>()
195 // where 192 // where
196 // for<'a> F: Fn(&'a str) 193 // for<'a> F: Fn(&'a str)
197 // { } 194 // { }
195 if p.at(T![for]) {
196 types::for_binder(p);
197 }
198
198 types::type_(p); 199 types::type_(p);
199 200
200 if p.at(T![:]) { 201 if p.at(T![:]) {
diff --git a/crates/ra_parser/src/grammar/types.rs b/crates/ra_parser/src/grammar/types.rs
index fe1a039cb..9e8e3bd97 100644
--- a/crates/ra_parser/src/grammar/types.rs
+++ b/crates/ra_parser/src/grammar/types.rs
@@ -216,19 +216,21 @@ pub(super) fn for_binder(p: &mut Parser) {
216 216
217// test for_type 217// test for_type
218// type A = for<'a> fn() -> (); 218// type A = for<'a> fn() -> ();
219// fn foo<T>(_t: &T) where for<'a> &'a T: Iterator {} 219// type B = for<'a> unsafe extern "C" fn(&'a ()) -> ();
220// fn bar<T>(_t: &T) where for<'a> &'a mut T: Iterator {} 220// type Obj = for<'a> PartialEq<&'a i32>;
221// fn baz<T>(_t: &T) where for<'a> <&'a T as Baz>::Foo: Iterator {}
222pub(super) fn for_type(p: &mut Parser) { 221pub(super) fn for_type(p: &mut Parser) {
223 assert!(p.at(T![for])); 222 assert!(p.at(T![for]));
224 let m = p.start(); 223 let m = p.start();
225 for_binder(p); 224 for_binder(p);
226 match p.current() { 225 match p.current() {
227 T![fn] | T![unsafe] | T![extern] => fn_pointer_type(p), 226 T![fn] | T![unsafe] | T![extern] => {}
228 T![&] => reference_type(p), 227 // OK: legacy trait object format
229 _ if paths::is_path_start(p) => path_type_(p, false), 228 _ if paths::is_use_path_start(p) => {}
230 _ => p.error("expected a path"), 229 _ => {
230 p.error("expected a function pointer or path");
231 }
231 } 232 }
233 type_no_bounds(p);
232 m.complete(p, FOR_TYPE); 234 m.complete(p, FOR_TYPE);
233} 235}
234 236