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.
This commit is contained in:
Ville Penttinen 2019-03-31 10:35:55 +03:00
parent e3f9d6555b
commit 98cff6ecec
2 changed files with 40 additions and 11 deletions

View File

@ -79,16 +79,19 @@ fn lifetime_bounds(p: &mut Parser) {
}
}
pub(super) fn bounds_without_colon(p: &mut Parser) {
let m = p.start();
pub(super) fn bounds_without_colon_m(p: &mut Parser, marker: Marker) -> CompletedMarker {
while type_bound(p) {
if !p.eat(PLUS) {
break;
}
}
m.complete(p, TYPE_BOUND_LIST);
marker.complete(p, TYPE_BOUND_LIST)
}
pub(super) fn bounds_without_colon(p: &mut Parser) {
let m = p.start();
bounds_without_colon_m(p, m);
}
fn type_bound(p: &mut Parser) -> bool {

View File

@ -261,21 +261,47 @@ fn path_or_macro_type_(p: &mut Parser, allow_bounds: bool) {
PATH_TYPE
};
if allow_bounds && p.eat(PLUS) {
type_params::bounds_without_colon(p);
}
let path = m.complete(p, kind);
m.complete(p, kind);
if allow_bounds {
opt_path_type_bounds_as_dyn_trait_type(p, path);
}
}
pub(super) fn path_type_(p: &mut Parser, allow_bounds: bool) {
assert!(paths::is_path_start(p) || p.at(L_ANGLE));
let m = p.start();
paths::type_path(p);
// test path_type_with_bounds
// fn foo() -> Box<T + 'f> {}
if allow_bounds && p.eat(PLUS) {
type_params::bounds_without_colon(p);
// fn foo() -> Box<dyn T + 'f> {}
let path = m.complete(p, PATH_TYPE);
if allow_bounds {
opt_path_type_bounds_as_dyn_trait_type(p, path);
}
m.complete(p, PATH_TYPE);
}
/// This turns a parsed PATH_TYPE optionally into a DYN_TRAIT_TYPE
/// with a TYPE_BOUND_LIST
fn opt_path_type_bounds_as_dyn_trait_type(p: &mut Parser, path_type_marker: CompletedMarker) {
if !p.at(PLUS) {
return;
}
// First create a TYPE_BOUND from the completed PATH_TYPE
let m = path_type_marker.precede(p).complete(p, TYPE_BOUND);
// Next setup a marker for the TYPE_BOUND_LIST
let m = m.precede(p);
// This gets consumed here so it gets properly set
// in the TYPE_BOUND_LIST
p.eat(PLUS);
// Parse rest of the bounds into the TYPE_BOUND_LIST
let m = type_params::bounds_without_colon_m(p, m);
// Finally precede everything with DYN_TRAIT_TYPE
m.precede(p).complete(p, DYN_TRAIT_TYPE);
}