diff options
Diffstat (limited to 'crates/ra_parser/src/grammar/types.rs')
-rw-r--r-- | crates/ra_parser/src/grammar/types.rs | 40 |
1 files changed, 33 insertions, 7 deletions
diff --git a/crates/ra_parser/src/grammar/types.rs b/crates/ra_parser/src/grammar/types.rs index fdd4f2c52..a46da9b44 100644 --- a/crates/ra_parser/src/grammar/types.rs +++ b/crates/ra_parser/src/grammar/types.rs | |||
@@ -261,21 +261,47 @@ fn path_or_macro_type_(p: &mut Parser, allow_bounds: bool) { | |||
261 | PATH_TYPE | 261 | PATH_TYPE |
262 | }; | 262 | }; |
263 | 263 | ||
264 | if allow_bounds && p.eat(PLUS) { | 264 | let path = m.complete(p, kind); |
265 | type_params::bounds_without_colon(p); | ||
266 | } | ||
267 | 265 | ||
268 | m.complete(p, kind); | 266 | if allow_bounds { |
267 | opt_path_type_bounds_as_dyn_trait_type(p, path); | ||
268 | } | ||
269 | } | 269 | } |
270 | 270 | ||
271 | pub(super) fn path_type_(p: &mut Parser, allow_bounds: bool) { | 271 | pub(super) fn path_type_(p: &mut Parser, allow_bounds: bool) { |
272 | assert!(paths::is_path_start(p) || p.at(L_ANGLE)); | 272 | assert!(paths::is_path_start(p) || p.at(L_ANGLE)); |
273 | let m = p.start(); | 273 | let m = p.start(); |
274 | paths::type_path(p); | 274 | paths::type_path(p); |
275 | |||
275 | // test path_type_with_bounds | 276 | // test path_type_with_bounds |
276 | // fn foo() -> Box<T + 'f> {} | 277 | // fn foo() -> Box<T + 'f> {} |
277 | if allow_bounds && p.eat(PLUS) { | 278 | // fn foo() -> Box<dyn T + 'f> {} |
278 | type_params::bounds_without_colon(p); | 279 | let path = m.complete(p, PATH_TYPE); |
280 | if allow_bounds { | ||
281 | opt_path_type_bounds_as_dyn_trait_type(p, path); | ||
279 | } | 282 | } |
280 | m.complete(p, PATH_TYPE); | 283 | } |
284 | |||
285 | /// This turns a parsed PATH_TYPE optionally into a DYN_TRAIT_TYPE | ||
286 | /// with a TYPE_BOUND_LIST | ||
287 | fn opt_path_type_bounds_as_dyn_trait_type(p: &mut Parser, path_type_marker: CompletedMarker) { | ||
288 | if !p.at(PLUS) { | ||
289 | return; | ||
290 | } | ||
291 | |||
292 | // First create a TYPE_BOUND from the completed PATH_TYPE | ||
293 | let m = path_type_marker.precede(p).complete(p, TYPE_BOUND); | ||
294 | |||
295 | // Next setup a marker for the TYPE_BOUND_LIST | ||
296 | let m = m.precede(p); | ||
297 | |||
298 | // This gets consumed here so it gets properly set | ||
299 | // in the TYPE_BOUND_LIST | ||
300 | p.eat(PLUS); | ||
301 | |||
302 | // Parse rest of the bounds into the TYPE_BOUND_LIST | ||
303 | let m = type_params::bounds_without_colon_m(p, m); | ||
304 | |||
305 | // Finally precede everything with DYN_TRAIT_TYPE | ||
306 | m.precede(p).complete(p, DYN_TRAIT_TYPE); | ||
281 | } | 307 | } |