Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/parser/src/grammar/type_params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ fn type_bound(p: &mut Parser) -> bool {
p.eat(T![?]);
match p.current() {
LIFETIME_IDENT => lifetime(p),
T![for] => types::for_type(p),
T![for] => types::for_type(p, false),
_ if paths::is_use_path_start(p) => types::path_type_(p, false),
_ => {
m.abandon(p);
Expand Down
26 changes: 18 additions & 8 deletions crates/parser/src/grammar/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ fn type_with_bounds_cond(p: &mut Parser, allow_bounds: bool) {
T![&] => ref_type(p),
T![_] => infer_type(p),
T![fn] | T![unsafe] | T![extern] => fn_ptr_type(p),
T![for] => for_type(p),
T![for] => for_type(p, allow_bounds),
T![impl] => impl_trait_type(p),
T![dyn] => dyn_trait_type(p),
// Some path types are not allowed to have bounds (no plus)
Expand Down Expand Up @@ -227,7 +227,7 @@ pub(super) fn for_binder(p: &mut Parser) {
// type A = for<'a> fn() -> ();
// type B = for<'a> unsafe extern "C" fn(&'a ()) -> ();
// type Obj = for<'a> PartialEq<&'a i32>;
pub(super) fn for_type(p: &mut Parser) {
pub(super) fn for_type(p: &mut Parser, allow_bounds: bool) {
assert!(p.at(T![for]));
let m = p.start();
for_binder(p);
Expand All @@ -240,7 +240,13 @@ pub(super) fn for_type(p: &mut Parser) {
}
}
type_no_bounds(p);
m.complete(p, FOR_TYPE);
let completed = m.complete(p, FOR_TYPE);

// test no_dyn_trait_leading_for
// type A = for<'a> Test<'a> + Send;
if allow_bounds {
opt_type_bounds_as_dyn_trait_type(p, completed);
}
}

// test impl_trait_type
Expand Down Expand Up @@ -290,7 +296,7 @@ fn path_or_macro_type_(p: &mut Parser, allow_bounds: bool) {
let path = m.complete(p, kind);

if allow_bounds {
opt_path_type_bounds_as_dyn_trait_type(p, path);
opt_type_bounds_as_dyn_trait_type(p, path);
}
}

Expand All @@ -304,19 +310,23 @@ pub(super) fn path_type_(p: &mut Parser, allow_bounds: bool) {
// 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);
opt_type_bounds_as_dyn_trait_type(p, path);
}
}

/// This turns a parsed PATH_TYPE optionally into a DYN_TRAIT_TYPE
/// This turns a parsed PATH_TYPE or FOR_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) {
fn opt_type_bounds_as_dyn_trait_type(p: &mut Parser, type_marker: CompletedMarker) {
assert!(matches!(
type_marker.kind(),
SyntaxKind::PATH_TYPE | SyntaxKind::FOR_TYPE | SyntaxKind::MACRO_CALL
));
if !p.at(T![+]) {
return;
}

// First create a TYPE_BOUND from the completed PATH_TYPE
let m = path_type_marker.precede(p).complete(p, TYPE_BOUND);
let m = type_marker.precede(p).complete(p, TYPE_BOUND);

// Next setup a marker for the TYPE_BOUND_LIST
let m = m.precede(p);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
SOURCE_FILE@0..34
TYPE_ALIAS@0..33
TYPE_KW@0..4 "type"
WHITESPACE@4..5 " "
NAME@5..6
IDENT@5..6 "A"
WHITESPACE@6..7 " "
EQ@7..8 "="
WHITESPACE@8..9 " "
DYN_TRAIT_TYPE@9..32
TYPE_BOUND_LIST@9..32
TYPE_BOUND@9..25
FOR_TYPE@9..25
FOR_KW@9..12 "for"
GENERIC_PARAM_LIST@12..16
L_ANGLE@12..13 "<"
LIFETIME_PARAM@13..15
LIFETIME@13..15
LIFETIME_IDENT@13..15 "\'a"
R_ANGLE@15..16 ">"
WHITESPACE@16..17 " "
PATH_TYPE@17..25
PATH@17..25
PATH_SEGMENT@17..25
NAME_REF@17..21
IDENT@17..21 "Test"
GENERIC_ARG_LIST@21..25
L_ANGLE@21..22 "<"
LIFETIME_ARG@22..24
LIFETIME@22..24
LIFETIME_IDENT@22..24 "\'a"
R_ANGLE@24..25 ">"
WHITESPACE@25..26 " "
PLUS@26..27 "+"
WHITESPACE@27..28 " "
TYPE_BOUND@28..32
PATH_TYPE@28..32
PATH@28..32
PATH_SEGMENT@28..32
NAME_REF@28..32
IDENT@28..32 "Send"
SEMICOLON@32..33 ";"
WHITESPACE@33..34 "\n"
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
type A = for<'a> Test<'a> + Send;