From dd496223f50232fe98312ee8edc89eb4b5ee3d85 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Tue, 15 Dec 2020 19:23:51 +0100 Subject: Node-ify lifetimes --- crates/parser/src/grammar/expressions/atom.rs | 16 ++++++++++------ crates/parser/src/grammar/items/traits.rs | 10 +++++----- crates/parser/src/grammar/params.rs | 13 +++++++++---- crates/parser/src/grammar/type_args.rs | 4 ++-- crates/parser/src/grammar/type_params.rs | 18 +++++++++--------- crates/parser/src/grammar/types.rs | 4 +++- 6 files changed, 38 insertions(+), 27 deletions(-) (limited to 'crates/parser/src/grammar') diff --git a/crates/parser/src/grammar/expressions/atom.rs b/crates/parser/src/grammar/expressions/atom.rs index 31f42f161..18b63feb7 100644 --- a/crates/parser/src/grammar/expressions/atom.rs +++ b/crates/parser/src/grammar/expressions/atom.rs @@ -48,7 +48,7 @@ pub(super) const ATOM_EXPR_FIRST: TokenSet = T![try], T![loop], T![for], - LIFETIME, + LIFETIME_IDENT, ])); const EXPR_RECOVERY_SET: TokenSet = TokenSet::new(&[LET_KW, R_DOLLAR]); @@ -75,7 +75,7 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar T![for] => for_expr(p, None), T![while] => while_expr(p, None), T![try] => try_block_expr(p, None), - LIFETIME if la == T![:] => { + LIFETIME_IDENT if la == T![:] => { let m = p.start(); label(p); match p.current() { @@ -275,9 +275,9 @@ fn if_expr(p: &mut Parser) -> CompletedMarker { // 'c: for x in () {} // } fn label(p: &mut Parser) { - assert!(p.at(LIFETIME) && p.nth(1) == T![:]); + assert!(p.at(LIFETIME_IDENT) && p.nth(1) == T![:]); let m = p.start(); - p.bump(LIFETIME); + lifetime(p); p.bump_any(); m.complete(p, LABEL); } @@ -501,7 +501,9 @@ fn continue_expr(p: &mut Parser) -> CompletedMarker { assert!(p.at(T![continue])); let m = p.start(); p.bump(T![continue]); - p.eat(LIFETIME); + if p.at(LIFETIME_IDENT) { + lifetime(p); + } m.complete(p, CONTINUE_EXPR) } @@ -518,7 +520,9 @@ fn break_expr(p: &mut Parser, r: Restrictions) -> CompletedMarker { assert!(p.at(T![break])); let m = p.start(); p.bump(T![break]); - p.eat(LIFETIME); + if p.at(LIFETIME_IDENT) { + lifetime(p); + } // test break_ambiguity // fn foo(){ // if break {} diff --git a/crates/parser/src/grammar/items/traits.rs b/crates/parser/src/grammar/items/traits.rs index 8394020da..ab9a12b4d 100644 --- a/crates/parser/src/grammar/items/traits.rs +++ b/crates/parser/src/grammar/items/traits.rs @@ -98,10 +98,10 @@ fn choose_type_params_over_qpath(p: &Parser) -> bool { // `<` `>` - empty generic parameters // `<` `#` - generic parameters with attributes // `<` `const` - const generic parameters - // `<` (LIFETIME|IDENT) `>` - single generic parameter - // `<` (LIFETIME|IDENT) `,` - first generic parameter in a list - // `<` (LIFETIME|IDENT) `:` - generic parameter with bounds - // `<` (LIFETIME|IDENT) `=` - generic parameter with a default + // `<` (LIFETIME_IDENT|IDENT) `>` - single generic parameter + // `<` (LIFETIME_IDENT|IDENT) `,` - first generic parameter in a list + // `<` (LIFETIME_IDENT|IDENT) `:` - generic parameter with bounds + // `<` (LIFETIME_IDENT|IDENT) `=` - generic parameter with a default // The only truly ambiguous case is // `<` IDENT `>` `::` IDENT ... // we disambiguate it in favor of generics (`impl ::absolute::Path { ... }`) @@ -113,7 +113,7 @@ fn choose_type_params_over_qpath(p: &Parser) -> bool { if p.nth(1) == T![#] || p.nth(1) == T![>] || p.nth(1) == CONST_KW { return true; } - (p.nth(1) == LIFETIME || p.nth(1) == IDENT) + (p.nth(1) == LIFETIME_IDENT || p.nth(1) == IDENT) && (p.nth(2) == T![>] || p.nth(2) == T![,] || p.nth(2) == T![:] || p.nth(2) == T![=]) } diff --git a/crates/parser/src/grammar/params.rs b/crates/parser/src/grammar/params.rs index a665ffc13..3ee4e4fca 100644 --- a/crates/parser/src/grammar/params.rs +++ b/crates/parser/src/grammar/params.rs @@ -169,15 +169,20 @@ fn opt_self_param(p: &mut Parser) { let la1 = p.nth(1); let la2 = p.nth(2); let la3 = p.nth(3); - let n_toks = match (p.current(), la1, la2, la3) { + let mut n_toks = match (p.current(), la1, la2, la3) { (T![&], T![self], _, _) => 2, (T![&], T![mut], T![self], _) => 3, - (T![&], LIFETIME, T![self], _) => 3, - (T![&], LIFETIME, T![mut], T![self]) => 4, + (T![&], LIFETIME_IDENT, T![self], _) => 3, + (T![&], LIFETIME_IDENT, T![mut], T![self]) => 4, _ => return, }; m = p.start(); - for _ in 0..n_toks { + p.bump_any(); + if p.at(LIFETIME_IDENT) { + lifetime(p); + n_toks -= 1; + } + for _ in 1..n_toks { p.bump_any(); } } diff --git a/crates/parser/src/grammar/type_args.rs b/crates/parser/src/grammar/type_args.rs index f2d34a749..a013c49b9 100644 --- a/crates/parser/src/grammar/type_args.rs +++ b/crates/parser/src/grammar/type_args.rs @@ -30,8 +30,8 @@ pub(super) fn opt_generic_arg_list(p: &mut Parser, colon_colon_required: bool) { fn generic_arg(p: &mut Parser) { let m = p.start(); match p.current() { - LIFETIME => { - p.bump(LIFETIME); + LIFETIME_IDENT => { + lifetime(p); m.complete(p, LIFETIME_ARG); } // test associated_type_bounds diff --git a/crates/parser/src/grammar/type_params.rs b/crates/parser/src/grammar/type_params.rs index bc7d8d724..9c3f7c28a 100644 --- a/crates/parser/src/grammar/type_params.rs +++ b/crates/parser/src/grammar/type_params.rs @@ -23,7 +23,7 @@ fn generic_param_list(p: &mut Parser) { attributes::outer_attrs(p); match p.current() { - LIFETIME => lifetime_param(p, m), + LIFETIME_IDENT => lifetime_param(p, m), IDENT => type_param(p, m), CONST_KW => const_param(p, m), _ => { @@ -40,8 +40,8 @@ fn generic_param_list(p: &mut Parser) { } fn lifetime_param(p: &mut Parser, m: Marker) { - assert!(p.at(LIFETIME)); - p.bump(LIFETIME); + assert!(p.at(LIFETIME_IDENT)); + lifetime(p); if p.at(T![:]) { lifetime_bounds(p); } @@ -84,8 +84,8 @@ pub(super) fn bounds(p: &mut Parser) { fn lifetime_bounds(p: &mut Parser) { assert!(p.at(T![:])); p.bump(T![:]); - while p.at(LIFETIME) { - p.bump(LIFETIME); + while p.at(LIFETIME_IDENT) { + lifetime(p); if !p.eat(T![+]) { break; } @@ -112,7 +112,7 @@ fn type_bound(p: &mut Parser) -> bool { let has_paren = p.eat(T!['(']); p.eat(T![?]); match p.current() { - LIFETIME => p.bump(LIFETIME), + LIFETIME_IDENT => lifetime(p), T![for] => types::for_type(p), _ if paths::is_use_path_start(p) => types::path_type_(p, false), _ => { @@ -162,7 +162,7 @@ pub(super) fn opt_where_clause(p: &mut Parser) { fn is_where_predicate(p: &mut Parser) -> bool { match p.current() { - LIFETIME => true, + LIFETIME_IDENT => true, T![impl] => false, token => types::TYPE_FIRST.contains(token), } @@ -175,8 +175,8 @@ fn is_where_clause_end(p: &mut Parser) -> bool { fn where_predicate(p: &mut Parser) { let m = p.start(); match p.current() { - LIFETIME => { - p.bump(LIFETIME); + LIFETIME_IDENT => { + lifetime(p); if p.at(T![:]) { bounds(p); } else { diff --git a/crates/parser/src/grammar/types.rs b/crates/parser/src/grammar/types.rs index 1ea130ac5..36a15eace 100644 --- a/crates/parser/src/grammar/types.rs +++ b/crates/parser/src/grammar/types.rs @@ -167,7 +167,9 @@ fn ref_type(p: &mut Parser) { assert!(p.at(T![&])); let m = p.start(); p.bump(T![&]); - p.eat(LIFETIME); + if p.at(LIFETIME_IDENT) { + lifetime(p); + } p.eat(T![mut]); type_no_bounds(p); m.complete(p, REF_TYPE); -- cgit v1.2.3