// let _ = b"e";
// let _ = br"f";
// }
-pub(crate) const LITERAL_FIRST: TokenSet = token_set![
- TRUE_KW,
- FALSE_KW,
+pub(crate) const LITERAL_FIRST: TokenSet = TokenSet::new(&[
+ T![true],
+ T![false],
INT_NUMBER,
FLOAT_NUMBER,
BYTE,
CHAR,
STRING,
- RAW_STRING,
BYTE_STRING,
- RAW_BYTE_STRING
-];
+]);
pub(crate) fn literal(p: &mut Parser) -> Option<CompletedMarker> {
if !p.at_ts(LITERAL_FIRST) {
// E.g. for after the break in `if break {}`, this should not match
pub(super) const ATOM_EXPR_FIRST: TokenSet =
- LITERAL_FIRST.union(paths::PATH_FIRST).union(token_set![
+ LITERAL_FIRST.union(paths::PATH_FIRST).union(TokenSet::new(&[
T!['('],
T!['{'],
T!['['],
T![continue],
T![async],
T![try],
+ T![const],
T![loop],
T![for],
- LIFETIME,
- ]);
+ LIFETIME_IDENT,
+ ]));
-const EXPR_RECOVERY_SET: TokenSet = token_set![LET_KW, R_DOLLAR];
+const EXPR_RECOVERY_SET: TokenSet = TokenSet::new(&[LET_KW, R_DOLLAR]);
pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMarker, BlockLike)> {
if let Some(m) = literal(p) {
T!['('] => tuple_expr(p),
T!['['] => array_expr(p),
L_DOLLAR => meta_var_expr(p),
- T![|] => lambda_expr(p),
- T![move] if la == T![|] => lambda_expr(p),
- T![async] if la == T![|] || (la == T![move] && p.nth(2) == T![|]) => lambda_expr(p),
+ T![|] => closure_expr(p),
+ T![move] if la == T![|] => closure_expr(p),
+ T![async] if la == T![|] || (la == T![move] && p.nth(2) == T![|]) => closure_expr(p),
T![if] => if_expr(p),
T![loop] => loop_expr(p, None),
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() {
block_expr(p);
m.complete(p, EFFECT_EXPR)
}
+ // test const_block
+ // fn f() { const { } }
+ T![const] if la == T!['{'] => {
+ let m = p.start();
+ p.bump(T![const]);
+ block_expr(p);
+ m.complete(p, EFFECT_EXPR)
+ }
T!['{'] => {
// test for_range_from
// fn foo() {
let mut saw_expr = false;
while !p.at(EOF) && !p.at(T![')']) {
saw_expr = true;
- if !p.at_ts(EXPR_FIRST) {
- p.error("expected expression");
+
+ // test tuple_attrs
+ // const A: (i64, i64) = (1, #[cfg(test)] 2);
+ if !expr_with_attrs(p) {
break;
}
- expr(p);
+
if !p.at(T![')']) {
saw_comma = true;
p.expect(T![,]);
// move || {};
// async move || {};
// }
-fn lambda_expr(p: &mut Parser) -> CompletedMarker {
+fn closure_expr(p: &mut Parser) -> CompletedMarker {
assert!(
p.at(T![|])
|| (p.at(T![move]) && p.nth(1) == T![|])
p.eat(T![async]);
p.eat(T![move]);
params::param_list_closure(p);
- if opt_fn_ret_type(p) {
+ if opt_ret_type(p) {
// test lambda_ret_block
// fn main() { || -> i32 { 92 }(); }
block_expr(p);
assert!(p.at(T![if]));
let m = p.start();
p.bump(T![if]);
- cond(p);
+ condition(p);
block_expr(p);
if p.at(T![else]) {
p.bump(T![else]);
// '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);
}
assert!(p.at(T![while]));
let m = m.unwrap_or_else(|| p.start());
p.bump(T![while]);
- cond(p);
+ condition(p);
block_expr(p);
m.complete(p, WHILE_EXPR)
}
// while let Some(_) | Some(_) = None {}
// while let | Some(_) = None {}
// }
-fn cond(p: &mut Parser) {
+fn condition(p: &mut Parser) {
let m = p.start();
if p.eat(T![let]) {
patterns::pattern_top(p);
// _ => (),
// }
// }
- attributes::inner_attributes(p);
+ attributes::inner_attrs(p);
while !p.at(EOF) && !p.at(T!['}']) {
if p.at(T!['{']) {
// _ => (),
// }
// }
- attributes::outer_attributes(p);
+ attributes::outer_attrs(p);
patterns::pattern_top_r(p, TokenSet::EMPTY);
if p.at(T![if]) {
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)
}
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 {}