Node-ify lifetimes

This commit is contained in:
Lukas Wirth 2020-12-15 19:23:51 +01:00
parent d34611633b
commit dd496223f5
63 changed files with 420 additions and 274 deletions

View file

@ -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 {}

View file

@ -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<T> ::absolute::Path<T> { ... }`)
@ -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![=])
}

View file

@ -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();
}
}

View file

@ -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

View file

@ -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 {

View file

@ -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);