Stream: t-compiler/rust-analyzer

Topic: RecordExprField parse vs ungrammar definition


Lukas Wirth (Jan 17 2021 at 01:15, on Zulip):

The ungrammar def for RecordExpreField states
https://github.com/Veykril/ungrammar/blob/master/rust.ungram#L410-L411

RecordExprField =
  Attr* NameRef (':' Expr)?

Note the Expr being the optional part here,
but the parser in RA parses this with the assumption that the Expr is always there instead:
https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/parser/src/grammar/expressions.rs#L619-L630

            IDENT | INT_NUMBER => {
                // test_err record_literal_before_ellipsis_recovery
                // fn main() {
                //     S { field ..S::default() }
                // }
                if p.nth_at(1, T![:]) || p.nth_at(1, T![..]) {
                    name_ref_or_index(p);
                    p.expect(T![:]);
                }
                expr(p);
                m.complete(p, RECORD_EXPR_FIELD);
            }

Unless I'm missing something the parser should instead always parse the NameRef, but the expression optionally only no?

Lukas Wirth (Jan 17 2021 at 01:17, on Zulip):

I noticed this because I was expecting the init shorthand to just be the NameRef but it was an Expr instead.

matklad (Jan 17 2021 at 08:03, on Zulip):

yeah, the ungrammar is wrong

matklad (Jan 17 2021 at 08:04, on Zulip):

label is optional, expression is always there. It is a bit mind bending way to look at it, but it actually simplifies things with the impl

matklad (Jan 17 2021 at 08:05, on Zulip):

and forward compatible with lang team deciding that let foo = Foo { spam, &eggs } is ok

Last update: Jul 26 2021 at 13:00UTC