rust-analyzer icon indicating copy to clipboard operation
rust-analyzer copied to clipboard

Parsing issues around inline consts in match arms

Open fmease opened this issue 3 years ago • 9 comments

Syntax support for #![feature(inline_const)] was added in #7010 (rust-analyzer/ungrammar#17). However, r-a fails to parse the following code whereas rustc accepts it:

fn f() {
    match () {
        () => const { &["--release"] }[..],
        //    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Syntax Error: expected FAT_ARROW
    }
}

rust-analyzer version: 0.3.1131-standalone (897a7ec4b 2022-07-17)

rustc version: rustc 1.64.0-nightly (f8588549c 2022-07-18)

fmease avatar Jul 20 '22 11:07 fmease

Oh this is a funny one, we parse the block expression, then due to a bug here we consider the expression finished and since its a block there is no need for a comma, so we parse the slice expression as the pattern of the next arm

Veykril avatar Jul 20 '22 12:07 Veykril

Interesting, so const blocks behave differently from normal blocks and unsafe blocks ...

Veykril avatar Jul 20 '22 12:07 Veykril

Interesting, so const blocks behave differently from normal blocks and unsafe blocks ...

I see what you mean (replacing const with an empty string or with unsafe leads to an error with rustc, too). Might be worth asking T-lang or whoever if this is intentional. Not sure.

fmease avatar Jul 20 '22 12:07 fmease

Though these errors aren't parsing errors in rustc, but type inference so I think this is overall a bug in the parser for us. I can see the const blocks being special in regards to their return value here to make them more useful I guess.

Veykril avatar Jul 20 '22 12:07 Veykril

Though these errors aren't parsing errors in rustc

I beg to differ:

#[cfg(FALSE)]
fn f () {
    match () {
        () => { [0] }[..],
    }
}
error: unexpected `,` in pattern
 --> src/lib.rs:4:27
  |
4 |         () =>  { [0] }[..],
  |                           ^
  |
help: try adding parentheses to match on a tuple...
  |
4 |         () =>  { [0] }([..],)
  |                       +     +
help: ...or a vertical bar to match on multiple alternatives
  |
4 |         () =>  { [0] }[..] |
  | 

#[cfg(FALSE)]
fn f () {
    match () {
        () => unsafe { [0] }[..],
    }
}
error: unexpected `,` in pattern
 --> src/lib.rs:4:33
  |
4 |         () => unsafe { [0] }[..],
  |                                 ^
  |
help: try adding parentheses to match on a tuple...
  |
4 |         () => unsafe { [0] }([..],)
  |                             +     +
help: ...or a vertical bar to match on multiple alternatives
  |
4 |         () => unsafe { [0] }[..] |
  |                             ~~~~~~

Edit: Apart from #[cfg(FALSE)], you can also pass -Zparse-only to rustc to double-check.

fmease avatar Jul 20 '22 12:07 fmease

Ah whoops I was testing it differently by accident

Veykril avatar Jul 20 '22 12:07 Veykril

Okay, so should I ask T-lang on Zulip or would you like to do the favor? Either one is fine for me.

Edit: Zulip stream.

fmease avatar Jul 20 '22 12:07 fmease

You can go ahead and ask if you'd like

Veykril avatar Jul 20 '22 12:07 Veykril

The discussion didn't lead to anything we could immediately act on. scottmcm added this issue to the list of unresolved questions on the tracking issue for inline consts (rust-lang/rust#76001). Seems like this r-a issue turns out to be S-unactionable?

fmease avatar Jul 23 '22 14:07 fmease

Since rust-lang/rust#105142, rustc now correctly parses inline consts as ExpressionWithBlock instead of ExpressionWithoutBlock making the behavior of rustc & rust-analyzer equal & fixing this issue.

fmease avatar Dec 04 '22 18:12 fmease