rust-lang / rust-lang/rust-analyzer

Erroneous right paren when annotating closure with tuple return type

Open
#16,084 6 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

A-ide C-bug
Dominant language
Rust
Stars
16.9k
Forks
2.2k
Avg merge
1d 12h
Merged PRs (30d)
72

Description

Reproduction Steps

  1. Create a new project with cargo new temp.
  2. In bin.rs, define the following function:
fn func() {
    let closure = |a: i64| {
        let b = 2 * a;
        (a, b)
    };
}
  1. Place the cursor after |a: i64|, just before the opening {.
  2. Type -> (i64, i64)

Expected behavior
After adding the return type annotation to the closure, the editor should have the following text:

fn func() {
    let closure = |a: i64| -> (i64, i64) {
        let b = 2 * a;
        (a, b)
    };
}

Observed behavior
After adding the return type annotation to the closure, the editor has the following text.

fn func() {
    let closure = |a: i64| -> (i64, i64) {
        let b = 2 * a;
        (a, b)
    });
}

The extra closing ) occurs at the end of the closure definition, causing a compilation error due to unmatched parentheses. Because the insertion of the extra ) may be several lines away from the point where the user is typing, this is difficult to spot as it occurs.

Suspected Mechanism

  1. The opening ( in (i64, i64) triggers the on_char_typed, which then delegates to on_opening_bracket_typed
  2. on_opening_bracket_typed calls bracket_expr, to determine if the ( occurred just prior to an expression that should be parenthesized.
  3. bracket_expr recognizes the body of the lambda as a block expression, and inserts a closing ) between the closing } of the lambda and the ;

rust-analyzer version:

  • First noticed in rust-analyzer 1.74.1 (a28077b 2023-12-04)
  • Last nightly build without the error: rust-analyzer 1.74.0-nightly (203c57d 2023-09-17)
  • First nightly build with the error: rust-analyzer 1.74.0-nightly (65ea825 2023-09-18)

The list of rustc commits, starting at the first known bad commit is here. The subtree updates for rust-analyzer in this window are from this PR. This PR included commit 0f1cde70, which was an upstreaming of the rust-analyzer PR https://github.com/rust-lang/rust-analyzer/pull/15532, and seems the most likely commit to have introduced this error.

rustc version: rustc 1.74.1 (a28077b28 2023-12-04)

relevant settings: (eg. client settings, or environment variables like CARGO, RUSTC, RUSTUP_HOME or CARGO_HOME)

  • emacs version 27.1
  • rust-mode version 20230805.1558 (latest version on melpa)
  • lsp-mode version 20231124.833 (~1 week away from latest version on melpa)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the closure annotation case, then inspect crates/ide/src/typing.rs, especially on_char_typed, on_opening_bracket_typed, and bracket_expr. Trace why the tuple return type causes a closing parenthesis to be inserted after the closure body. Done means the reproduction produces no extra closing parenthesis and the resulting Rust code compiles.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.