diff options
-rw-r--r-- | crates/ra_parser/src/grammar/type_params.rs | 45 |
1 files changed, 26 insertions, 19 deletions
diff --git a/crates/ra_parser/src/grammar/type_params.rs b/crates/ra_parser/src/grammar/type_params.rs index e28c124cd..01175c0a3 100644 --- a/crates/ra_parser/src/grammar/type_params.rs +++ b/crates/ra_parser/src/grammar/type_params.rs | |||
@@ -80,29 +80,36 @@ fn lifetime_bounds(p: &mut Parser) { | |||
80 | } | 80 | } |
81 | 81 | ||
82 | pub(super) fn bounds_without_colon(p: &mut Parser) { | 82 | pub(super) fn bounds_without_colon(p: &mut Parser) { |
83 | let outer = p.start(); | 83 | let m = p.start(); |
84 | loop { | 84 | |
85 | let inner = p.start(); | 85 | while type_bound(p) { |
86 | let has_paren = p.eat(L_PAREN); | ||
87 | p.eat(QUESTION); | ||
88 | match p.current() { | ||
89 | LIFETIME => p.bump(), | ||
90 | FOR_KW => types::for_type(p), | ||
91 | _ if paths::is_path_start(p) => types::path_type_(p, false), | ||
92 | _ => { | ||
93 | inner.abandon(p); | ||
94 | break; | ||
95 | } | ||
96 | } | ||
97 | if has_paren { | ||
98 | p.expect(R_PAREN); | ||
99 | } | ||
100 | inner.complete(p, TYPE_BOUND); | ||
101 | if !p.eat(PLUS) { | 86 | if !p.eat(PLUS) { |
102 | break; | 87 | break; |
103 | } | 88 | } |
104 | } | 89 | } |
105 | outer.complete(p, TYPE_BOUND_LIST); | 90 | |
91 | m.complete(p, TYPE_BOUND_LIST); | ||
92 | } | ||
93 | |||
94 | fn type_bound(p: &mut Parser) -> bool { | ||
95 | let m = p.start(); | ||
96 | let has_paren = p.eat(L_PAREN); | ||
97 | p.eat(QUESTION); | ||
98 | match p.current() { | ||
99 | LIFETIME => p.bump(), | ||
100 | FOR_KW => types::for_type(p), | ||
101 | _ if paths::is_path_start(p) => types::path_type_(p, false), | ||
102 | _ => { | ||
103 | m.abandon(p); | ||
104 | return false; | ||
105 | } | ||
106 | } | ||
107 | if has_paren { | ||
108 | p.expect(R_PAREN); | ||
109 | } | ||
110 | m.complete(p, TYPE_BOUND); | ||
111 | |||
112 | true | ||
106 | } | 113 | } |
107 | 114 | ||
108 | // test where_clause | 115 | // test where_clause |