aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_parser/src/grammar/types.rs
diff options
context:
space:
mode:
authorVille Penttinen <[email protected]>2019-03-31 08:35:55 +0100
committerVille Penttinen <[email protected]>2019-03-31 08:38:36 +0100
commit98cff6ecec1b0af2cb9cead544526a0dbf2760f5 (patch)
tree511188639f3fca256f1b4a319973fd20108e1680 /crates/ra_parser/src/grammar/types.rs
parente3f9d6555beec6fb4bebf6aef3e983149f7aee3a (diff)
Change parsing bounds in path_types
Now bounds inside a path are parsed as DYN_TRAIT_TYPE, previously they would be parsed as `PATH_TYPE` followed by `TYPE_BOUND_LIST`. Basically this means `Box<T + 'f>` is now parsed almost the same as `Box<dyn T + 'f>` with the exception of not having the `dyn` keyword.
Diffstat (limited to 'crates/ra_parser/src/grammar/types.rs')
-rw-r--r--crates/ra_parser/src/grammar/types.rs40
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
271pub(super) fn path_type_(p: &mut Parser, allow_bounds: bool) { 271pub(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
287fn 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}