rust-lang / rust-lang/rust-analyzer

Rust-analyzer as library: potential overlap between `expr()/tail_expr()` and `statements()` in `ast::MacroStmts` and `ast::StmtList`

Open
#20,485 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

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

Description

rust-analyzer version: 0.0.300

As far as I understand generated getters in ast classes take the first child that matches the required type. However since AsmExpr is now also an Item (and therefore a Stmt), this can lead to overlaps where the last element of ast::MacroStmts::statements() will be a duplicate of ast::MacroStmts::expr(). This can be reproduced by any use of asm!, for example this one coming from https://doc.rust-lang.org/reference/inline-assembly.html

code snippet to reproduce:

use std::arch::asm;

let mut x: u64 = 4;
unsafe {
    asm!(
        "mov {tmp}, {x}",
        "shl {tmp}, 1",
        "shl {x}, 2",
        "add {x}, {tmp}",
        x = inout(reg) x,
        tmp = out(reg) _,
    );
}

When expanding macros, this will result in a MacroStmts instance that exhibits this duplication. I don't know if this could cause any issues elsewhere in the library.

Theoretically this problem could also appear in StmtList, which is

  '{'
    Attr*
    statements:Stmt*
    tail_expr:Expr?
  '}'

but I think that can't happen in practice yet, as there's no other way to produce an AsmExpr (and therefore something that is both an Expr and a Stmt) than by asm! or similar inline assembly macros, so an AsmExpr won't show up as a tail_expr in any StmtList instance.

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

Start with the generated getters for ast::MacroStmts and ast::StmtList, then reproduce the overlap using the inline-assembly example in the issue. Trace how expr(), tail_expr(), and statements() select children, and verify that the relevant AST accessors no longer return the same node twice for asm! input.

Written by the indexing model from the issue text.

Assessment

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.