Re: [PATCH v4 2/2] scripts: generate_rust_analyzer.py: fix IDE support for primitive types

From: Jesung Yang

Date: Sat Apr 25 2026 - 08:17:34 EST


On Thu, Mar 19, 2026 at 3:02 PM Tamir Duberstein <tamird@xxxxxxxxxx> wrote:
>
> On Tue, 17 Mar 2026 18:29:55 +0900, Jesung Yang <y.j3ms.n@xxxxxxxxx> wrote:
> > diff --git a/scripts/generate_rust_analyzer.py b/scripts/generate_rust_analyzer.py
> > index 21832763c5be..bf5a0f16995a 100755
> > --- a/scripts/generate_rust_analyzer.py
> > +++ b/scripts/generate_rust_analyzer.py
> > @@ -372,6 +374,7 @@ def generate_crates(
> > path,
> > sysroot_deps(core) + [kernel, pin_init],
> > cfg=generated_cfg,
> > + crate_attrs=["no_std"],
> > )
>
> This seems to be independent of the RA version. Is this broken today? Should it
> be a separate patch? Maybe that patch need not be in this series.

The primary motivation for the versioning infrastructure was to
incorporate the `crate_attrs` feature introduced in the recent
rust-analyzer release (denoted as `RaVersionInfo.SUPPORTS_CRATE_ATTRS`
in our case).
This solves the side effect of enabling `sysroot_src`: `sysroot_src`
implicitly brings in `std` as a dependency, which is undesirable for
driver crates. Setting `crate_attrs=["no_std"]` is a direct fix for
this.

I could split this series into two separate patches, but I prefer to
keep them in the same series. I think a standalone versioning
infrastructure patch would be unjustified in isolation without an actual
consumer of that logic.

> Is this broken today?

If we enable `sysroot_src` without `crate_attrs=["no_std"]`, users with
a fairly new rust-analyzer release would see, for example, auto-complete
suggestions for `std`.

To provide full context, here is the sequence of issues:

1) Inherent impls for primitive type have been broken in recent
rust-analyzer releases.
2) To fix 1), we need to enable `sysroot_src`. There are also other
reasons reported by Eliot to enable it, as we know.
3) A new problem emerges: rust-analyzer thinks we have `std` in the
kernel driver crates.
4) To fix 3), we need to use `crate_attrs=["no_std"]` alongside
`sysroot_src`.
5) However, `crate_attrs` is only available in rust-analyzer>=0.3.2727.
6) This means rust-analyzer<0.3.2727 would still suffer from 3) if we
just use `sysroot_src` + `crate_attrs=["no_std"]`.
7) We need an infrastructure to conditionally include both
`sysroot_src` and `crate_attrs["no_std"]` based on the user's
rust-analyzer version.

I hope this clarifies the intent.

> > @@ -432,6 +435,18 @@ def generate_rust_project(
> > ),
> > "sysroot": str(sysroot),
> > }
> > + elif version_info == RaVersionInfo.SUPPORTS_CRATE_ATTRS:
> > + ctx = RaVersionCtx(
>
> I think you forgot to define RaVersionInfo.SUPPORTS_CRATE_ATTRS?

Yeah, interestingly, mypy didn't complain about this. I'll fix it in
v5.

> > [ ... skip 7 lines ... ]
> > + "sysroot": str(sysroot),
> > + "sysroot_src": str(sysroot_src),
> > + }
> > else:
> > assert_never(version_info)
> >
>
> This bifurcates the handling of RA version differences: half of it is encoded
> in RaVersionCtx, and the other half is here in the presence or absence of
> "sysroot_src". Can we keep it somehow more contained?

Fair point. Actually, the presence or absence of `sysroot_src` should
depend on `manual_sysroot_crates`. To keep things more self-contained,
I think it would be better to embed `RaVersionCtx` directly into
`RaVersionInfo`, since the values in `RaVersionCtx` are solely
determined by the version.

I'm thinking of something like this:

-------------------------------------------------
@enum.unique
class RaVersionInfo(enum.Enum):
DEFAULT = (
datetime.strptime("2024-03-11", "%Y-%m-%d"),
(0, 3, 1877),
(1, 78, 0),
RaVersionCtx(
use_crate_attrs=False,
manual_sysroot_crates=True,
),
)
SUPPORTS_CRATE_ATTRS = (
datetime.strptime("2025-12-22", "%Y-%m-%d"),
(0, 3, 2727),
(1, 94, 0),
RaVersionCtx(
use_crate_attrs=True,
manual_sysroot_crates=False,
),
)

def __init__(
self,
release_date: date,
ra_version: Version,
rust_version: Version,
ctx: RaVersionCtx,
) -> None:
self.release_date = release_date
self.ra_version = ra_version
self.rust_version = rust_version
self.ctx = ctx

# ...

def generate_rust_project(version_info: RaVersionInfo, ...) -> RustProject:
ctx = version_info
rust_project = {
"crates": generate_crates(ctx, ...),
"sysroot": str(sysroot),
}

if not ctx.manual_sysroot_crates:
rust_project["sysroot_src"] = str(sysroot_src)

return rust_project

-------------------------------------------------

This allows us to remove the if-else branches and the `assert_never`
check altogether.

Best regards,
Jesung