Re: [PATCH v3 1/2] scripts: generate_rust_analyzer.py: add versioning infrastructure

From: Tamir Duberstein

Date: Mon Mar 09 2026 - 14:36:07 EST


On Sun, 08 Mar 2026 08:30:34 +0900, Jesung Yang <y.j3ms.n@xxxxxxxxx> wrote:
> diff --git a/scripts/generate_rust_analyzer.py b/scripts/generate_rust_analyzer.py
> index b4a55344688d..a4d25bb8b602 100755
> --- a/scripts/generate_rust_analyzer.py
> +++ b/scripts/generate_rust_analyzer.py
> @@ -49,7 +52,41 @@ class CrateWithGenerated(Crate):
> source: Source
>
>
> +class RustProject(TypedDict):
> + crates: List[Crate]
> + sysroot: str
> +
> +
> +Version = tuple[int, int, int]
> +
> +
> +class RaVersionInfo(TypedDict):
> + release_date: date
> + ra_version: Version
> + rust_version: Version
> +

Unlike other types that are intended to be serialized to JSON, this type is
strictly for internal use. Could we make it a `@dataclass` instead of a
`TypedDict`? That produces more pleasant syntax and clarifies the intended use.

> +
> +class RaVersionCtx(TypedDict):
> + manual_sysroot_crates: bool
> + use_crate_attrs: bool
> +
> +
> +# Represents rust-analyzer compatibility baselines. Concrete versions are mapped to the most

Same here.

> +# recent baseline they have reached. Must be in release order.
> +BASELINES: List[RaVersionInfo] = [
> + # v0.3.1877, released on 2024-03-11; shipped with the rustup 1.78 toolchain.
> + {
> + "release_date": datetime.strptime("2024-03-11", "%Y-%m-%d"),
> + "ra_version": (0, 3, 1877),
> + "rust_version": (1, 78, 0),
> + },
> +]
> +
> +DEFAULT_BASELINE: RaVersionInfo = BASELINES[0]
> +
> +
> def generate_crates(
> + ctx: RaVersionCtx,
> srctree: pathlib.Path,

Could we define these constants closer to their point of use? I understand the
custom of keeping these things near the top of the file but this 400-line
separation makes it hard to see that there is quite tight coupling between the
two sites.

> @@ -200,67 +245,72 @@ def generate_crates(
> edition=core_edition,
> )
>
> - # NB: sysroot crates reexport items from one another so setting up our transitive dependencies
> - # here is important for ensuring that rust-analyzer can resolve symbols. The sources of truth
> - # for this dependency graph are `(sysroot_src / crate / "Cargo.toml" for crate in crates)`.
> - core = append_sysroot_crate("core", [])
> - alloc = append_sysroot_crate("alloc", [core])
> - std = append_sysroot_crate("std", [alloc, core])
> - proc_macro = append_sysroot_crate("proc_macro", [core, std])
> + core = alloc = std = proc_macro = None
> + if ctx["manual_sysroot_crates"]:
> + # NB: sysroot crates reexport items from one another so setting up our transitive dependencies
> + # here is important for ensuring that rust-analyzer can resolve symbols. The sources of truth
> + # for this dependency graph are `(sysroot_src / crate / "Cargo.toml" for crate in crates)`.
> + core = append_sysroot_crate("core", [])
> + alloc = append_sysroot_crate("alloc", [core])
> + std = append_sysroot_crate("std", [alloc, core])
> + proc_macro = append_sysroot_crate("proc_macro", [core, std])
> +

Should this logic (inspecting `manual_sysroot_crates`) be in
`append_sysroot_crate`?

> @@ -335,12 +390,90 @@ def generate_crates(
> append_crate(
> name,
> path,
> - [core, kernel, pin_init],
> + sysroot_deps(core) + [kernel, pin_init],
> cfg=generated_cfg,
> + crate_attrs=["no_std"],
> )

Can you help me understand this addition? It's not mentioned except in the
cover letter as a diff from v2.

>
> return crates
>
> +def generate_rust_project(
> + version_info: RaVersionInfo,
> + srctree: pathlib.Path,
> + objtree: pathlib.Path,
> + sysroot: pathlib.Path,
> + sysroot_src: pathlib.Path,
> + external_src: Optional[pathlib.Path],
> + cfgs: List[str],
> + core_edition: str,
> +) -> RustProject:
> + assert len(BASELINES) == 1, "Exhaustiveness check: update if branches!"
> +
> + ctx: RaVersionCtx
> +

Could we make RaVersionInfo an enum? That would allow mypy to do this check
(using `match`) rather than relying on this.


--
Tamir Duberstein <tamird@xxxxxxxxxx>