// let _ = b"e";
// let _ = br"f";
// }
-pub(crate) const LITERAL_FIRST: TokenSet =
- TokenSet::new(&[TRUE_KW, FALSE_KW, INT_NUMBER, FLOAT_NUMBER, BYTE, CHAR, STRING, BYTE_STRING]);
+pub(crate) const LITERAL_FIRST: TokenSet = TokenSet::new(&[
+ T![true],
+ T![false],
+ INT_NUMBER,
+ FLOAT_NUMBER,
+ BYTE,
+ CHAR,
+ STRING,
+ BYTE_STRING,
+]);
pub(crate) fn literal(p: &mut Parser) -> Option<CompletedMarker> {
if !p.at_ts(LITERAL_FIRST) {
T![continue],
T![async],
T![try],
+ T![const],
T![loop],
T![for],
LIFETIME_IDENT,
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![,]);