* [PATCH v2 0/2] rust: take advantage of newer rust-analyzer features
@ 2026-01-09 22:08 Jesung Yang via B4 Relay
2026-01-09 22:09 ` [PATCH v2 1/2] scripts: generate_rust_analyzer: add versioning infrastructure Jesung Yang via B4 Relay
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Jesung Yang via B4 Relay @ 2026-01-09 22:08 UTC (permalink / raw)
To: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
Danilo Krummrich, Tamir Duberstein
Cc: rust-for-linux, linux-kernel, Jesung Yang
As discussed in [1], we need to support multiple versions of
rust-analyzer to take advantage of newer features without breaking
compatibility for users on older toolchains; we must maintain support
for rust-analyzer v0.3.1940 (2024-04-29), which corresponds to our
current MSRV of 1.78.
Hence, this series revises the approach taken in [2] by first adding
multi-version support for rust-analyzer. Specifically, it enables
support for the v0.3.2727 (2025-12-22) release and newer, which is
required to resolve inherent method resolution issues for primitive
types found in recent versions of rust-analyzer.
Thanks to Gary Guo and Miguel Ojeda for their feedback and reviews.
[1] https://lore.kernel.org/rust-for-linux/20260101-rust-project-reduce-size-v1-1-4cd66e9e02d9@gmail.com/
[2] https://lore.kernel.org/r/20260101-ra-fix-primitive-v1-1-def809357b4e@gmail.com/
Signed-off-by: Jesung Yang <y.j3ms.n@gmail.com>
---
Changes in v2:
- Implement multiple rust-analyzer version support.
- Rebase on 9ace4753a520 (Linux 6.19-rc4).
- Remove an unnecessary new line between tags.
- Link to v1: https://lore.kernel.org/r/20260101-ra-fix-primitive-v1-1-def809357b4e@gmail.com
---
Jesung Yang (2):
scripts: generate_rust_analyzer: add versioning infrastructure
scripts: generate_rust_analyzer: fix IDE support for primitive types
scripts/generate_rust_analyzer.py | 196 +++++++++++++++++++++++++++++++++-----
1 file changed, 172 insertions(+), 24 deletions(-)
---
base-commit: 9ace4753a5202b02191d54e9fdf7f9e3d02b85eb
change-id: 20260101-ra-fix-primitive-78154fe8173f
Best regards,
--
Jesung Yang <y.j3ms.n@gmail.com>
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH v2 1/2] scripts: generate_rust_analyzer: add versioning infrastructure 2026-01-09 22:08 [PATCH v2 0/2] rust: take advantage of newer rust-analyzer features Jesung Yang via B4 Relay @ 2026-01-09 22:09 ` Jesung Yang via B4 Relay 2026-01-09 23:07 ` Tamir Duberstein 2026-01-09 22:09 ` [PATCH v2 2/2] scripts: generate_rust_analyzer: fix IDE support for primitive types Jesung Yang via B4 Relay 2026-03-02 16:58 ` [PATCH v2 0/2] rust: take advantage of newer rust-analyzer features Tamir Duberstein 2 siblings, 1 reply; 8+ messages in thread From: Jesung Yang via B4 Relay @ 2026-01-09 22:09 UTC (permalink / raw) To: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich, Tamir Duberstein Cc: rust-for-linux, linux-kernel, Jesung Yang From: Jesung Yang <y.j3ms.n@gmail.com> Introduce multi-version support for rust-analyzer. The script now executes `rust-analyzer --version` to query the version string and generates a `rust-project.json` file compatible with the detected version. This is a preparatory patch to address inherent method resolution failures for primitive types occurring in rust-analyzer v0.3.2693 (2025-11-24) or later when used with our current `rust-project.json` generation logic. Since the actual fix requires a feature only available in rust-analyzer v0.3.2727 (2025-12-22) or later, this infrastructure is necessary to avoid breaking compatibility with rust-analyzer v0.3.1940 (2024-04-29), which corresponds to our MSRV of 1.78. Signed-off-by: Jesung Yang <y.j3ms.n@gmail.com> --- scripts/generate_rust_analyzer.py | 181 +++++++++++++++++++++++++++++++++----- 1 file changed, 157 insertions(+), 24 deletions(-) diff --git a/scripts/generate_rust_analyzer.py b/scripts/generate_rust_analyzer.py index 147d0cc940681426771db865bc2462e7029a6d7d..32b0da99f17549ecc83e9a68911373310a2c9617 100755 --- a/scripts/generate_rust_analyzer.py +++ b/scripts/generate_rust_analyzer.py @@ -4,10 +4,13 @@ """ import argparse +from datetime import datetime +import enum import json import logging import os import pathlib +import re import subprocess import sys @@ -19,7 +22,7 @@ def args_crates_cfgs(cfgs): return crates_cfgs -def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs, core_edition): +def generate_crates(ctx, srctree, objtree, sysroot_src, external_src, cfgs, core_edition): # Generate the configuration list. cfg = [] with open(objtree / "include" / "generated" / "rustc_cfg") as fd: @@ -35,7 +38,7 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs, core_edit crates_indexes = {} crates_cfgs = args_crates_cfgs(cfgs) - def append_crate(display_name, root_module, deps, cfg=[], is_workspace_member=True, is_proc_macro=False, edition="2021"): + def append_crate(display_name, root_module, deps, cfg=[], crate_attrs=[], is_workspace_member=True, is_proc_macro=False, edition="2021"): crate = { "display_name": display_name, "root_module": str(root_module), @@ -48,6 +51,8 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs, core_edit "RUST_MODFILE": "This is only for rust-analyzer" } } + if ctx["use_crate_attrs"] and len(crate_attrs) > 0: + crate["crate_attrs"] = crate_attrs if is_proc_macro: proc_macro_dylib_name = subprocess.check_output( [os.environ["RUSTC"], "--print", "file-names", "--crate-name", display_name, "--crate-type", "proc-macro", "-"], @@ -72,52 +77,58 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs, core_edit edition=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)`. - append_sysroot_crate("core", [], cfg=crates_cfgs.get("core", []), edition=core_edition) - append_sysroot_crate("alloc", ["core"]) - append_sysroot_crate("std", ["alloc", "core"]) - append_sysroot_crate("proc_macro", ["core", "std"]) + def sysroot_deps(*deps): + return list(deps) if ctx["add_sysroot_crates"] else [] + + if ctx["add_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)`. + append_sysroot_crate("core", [], cfg=crates_cfgs.get("core", []), edition=core_edition) + append_sysroot_crate("alloc", ["core"]) + append_sysroot_crate("std", ["alloc", "core"]) + append_sysroot_crate("proc_macro", ["core", "std"]) append_crate( "compiler_builtins", srctree / "rust" / "compiler_builtins.rs", [], + crate_attrs=["no_std"], ) append_crate( "proc_macro2", srctree / "rust" / "proc-macro2" / "lib.rs", - ["core", "alloc", "std", "proc_macro"], + sysroot_deps("core", "alloc", "std", "proc_macro"), cfg=crates_cfgs["proc_macro2"], ) append_crate( "quote", srctree / "rust" / "quote" / "lib.rs", - ["alloc", "proc_macro", "proc_macro2"], + sysroot_deps("alloc", "proc_macro") + ["proc_macro2"], cfg=crates_cfgs["quote"], ) append_crate( "syn", srctree / "rust" / "syn" / "lib.rs", - ["proc_macro", "proc_macro2", "quote"], + sysroot_deps("proc_macro") + ["proc_macro2", "quote"], cfg=crates_cfgs["syn"], ) append_crate( "macros", srctree / "rust" / "macros" / "lib.rs", - ["std", "proc_macro", "proc_macro2", "quote", "syn"], + sysroot_deps("std", "proc_macro") + ["proc_macro2", "quote", "syn"], is_proc_macro=True, ) append_crate( "build_error", srctree / "rust" / "build_error.rs", - ["core", "compiler_builtins"], + sysroot_deps("core") + ["compiler_builtins"], + crate_attrs=["no_std"], ) append_crate( @@ -125,31 +136,36 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs, core_edit srctree / "rust" / "pin-init" / "internal" / "src" / "lib.rs", [], cfg=["kernel"], + crate_attrs=["no_std"], is_proc_macro=True, ) append_crate( "pin_init", srctree / "rust" / "pin-init" / "src" / "lib.rs", - ["core", "pin_init_internal", "macros"], + sysroot_deps("core") + ["pin_init_internal", "macros"], cfg=["kernel"], + crate_attrs=["no_std"], ) append_crate( "ffi", srctree / "rust" / "ffi.rs", - ["core", "compiler_builtins"], + sysroot_deps("core") + ["compiler_builtins"], + crate_attrs=["no_std"], ) def append_crate_with_generated( display_name, deps, + crate_attrs=[] ): append_crate( display_name, srctree / "rust"/ display_name / "lib.rs", deps, cfg=cfg, + crate_attrs=crate_attrs ) crates[-1]["env"]["OBJTREE"] = str(objtree.resolve(True)) crates[-1]["source"] = { @@ -160,9 +176,21 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs, core_edit "exclude_dirs": [], } - append_crate_with_generated("bindings", ["core", "ffi", "pin_init"]) - append_crate_with_generated("uapi", ["core", "ffi", "pin_init"]) - append_crate_with_generated("kernel", ["core", "macros", "build_error", "pin_init", "ffi", "bindings", "uapi"]) + append_crate_with_generated( + "bindings", + sysroot_deps("core") + ["ffi", "pin_init"], + crate_attrs=["no_std"], + ) + append_crate_with_generated( + "uapi", + sysroot_deps("core") + ["ffi", "pin_init"], + crate_attrs=["no_std"], + ) + append_crate_with_generated( + "kernel", + sysroot_deps("core") + ["macros", "build_error", "pin_init", "ffi", "bindings", "uapi"], + crate_attrs=["no_std"], + ) def is_root_crate(build_file, target): try: @@ -190,12 +218,103 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs, core_edit append_crate( name, path, - ["core", "kernel"], + sysroot_deps("core") + ["kernel"], cfg=cfg, + crate_attrs=["no_std"] ) return crates +@enum.unique +class RaVersion(enum.Enum): + """ + Represents rust-analyzer compatibility baselines. Concrete versions are mapped to the most + recent baseline they have reached. Must be in release order. + """ + + # v0.3.1940, released on 2024-04-29; bundled with the rustup 1.78 toolchain. + V20240429 = 0 + + @staticmethod + def baselines(): + assert len(RaVersion) == 1, "Exhaustiveness check: update baseline list!" + + return [ + (datetime.strptime("2024-04-29", "%Y-%m-%d"), (0, 3, 1940), RaVersion.V20240429), + ] + + @staticmethod + def default(): + # The default is the 2024-04-29 release, aligning with our MSRV policy. + return RaVersion.V20240429 + + def __str__(self): + assert len(RaVersion) == 1, "Exhaustiveness check: update if branches!" + + if self == RaVersion.V20240429: + return "v0.3.1940 (2024-04-29)" + else: + assert False, "Unreachable" + +def generate_rust_project( + ra_version, + srctree, + objtree, + sysroot, + sysroot_src, + external_src, + cfgs, + core_edition +): + assert len(RaVersion) == 1, "Exhaustiveness check: update if branches!" + + if ra_version == RaVersion.V20240429: + ctx = { + "use_crate_attrs": False, + "add_sysroot_crates": True, + } + return { + "crates": generate_crates(ctx, srctree, objtree, sysroot_src, external_src, cfgs, core_edition), + "sysroot": str(sysroot), + } + else: + assert False, "Unreachable" + +def query_ra_version(): + try: + # Use the rust-analyzer binary found in $PATH. + ra_version_output = subprocess.check_output( + ["rust-analyzer", "--version"], + stdin=subprocess.DEVNULL, + ).decode('utf-8').strip() + return ra_version_output + except FileNotFoundError: + logging.warning("Failed to find rust-analyzer in $PATH") + return None + +def map_ra_version_baseline(ra_version_output): + checkpoints = reversed(RaVersion.baselines()) + + # First, attempt to resolve to our known checkpoint using the release date. + # This covers patterns like "rust-analyzer 1.78.0 (9b00956e 2024-04-29)". + date_match = re.search(r"\d{4}-\d{2}-\d{2}", ra_version_output) + if date_match: + found_date = datetime.strptime(date_match.group(), "%Y-%m-%d") + for date, ver, enum in checkpoints: + if found_date >= date: + return enum + + # Otherwise, attempt to resolve to our known checkpoint using the rust-analyzer version. + # This covers patterns like "rust-analyzer 0.3.2743-standalone". + version_match = re.search(r"\d+\.\d+\.\d+", ra_version_output) + if version_match: + found_version = tuple(map(int, version_match.group().split("."))) + for date, ver, enum in checkpoints: + if found_version >= ver: + return enum + + return RaVersion.default() + def main(): parser = argparse.ArgumentParser() parser.add_argument('--verbose', '-v', action='store_true') @@ -216,10 +335,24 @@ def main(): # Making sure that the `sysroot` and `sysroot_src` belong to the same toolchain. assert args.sysroot in args.sysroot_src.parents - rust_project = { - "crates": generate_crates(args.srctree, args.objtree, args.sysroot_src, args.exttree, args.cfgs, args.core_edition), - "sysroot": str(args.sysroot), - } + output = query_ra_version() + if output: + compatible_ra_version = map_ra_version_baseline(output) + else: + default = RaVersion.default() + logging.warning("Falling back to `rust-project.json` for rust-analyzer %s", default) + compatible_ra_version = default + + rust_project = generate_rust_project( + compatible_ra_version, + args.srctree, + args.objtree, + args.sysroot, + args.sysroot_src, + args.exttree, + args.cfgs, + args.core_edition, + ) json.dump(rust_project, sys.stdout, sort_keys=True, indent=4) -- 2.47.3 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v2 1/2] scripts: generate_rust_analyzer: add versioning infrastructure 2026-01-09 22:09 ` [PATCH v2 1/2] scripts: generate_rust_analyzer: add versioning infrastructure Jesung Yang via B4 Relay @ 2026-01-09 23:07 ` Tamir Duberstein 2026-01-11 1:21 ` Jesung Yang 0 siblings, 1 reply; 8+ messages in thread From: Tamir Duberstein @ 2026-01-09 23:07 UTC (permalink / raw) To: y.j3ms.n Cc: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich, rust-for-linux, linux-kernel On Fri, Jan 9, 2026 at 5:10 PM Jesung Yang via B4 Relay <devnull+y.j3ms.n.gmail.com@kernel.org> wrote: > > From: Jesung Yang <y.j3ms.n@gmail.com> > > Introduce multi-version support for rust-analyzer. The script now > executes `rust-analyzer --version` to query the version string and > generates a `rust-project.json` file compatible with the detected > version. > > This is a preparatory patch to address inherent method resolution > failures for primitive types occurring in rust-analyzer v0.3.2693 > (2025-11-24) or later when used with our current `rust-project.json` > generation logic. Since the actual fix requires a feature only available > in rust-analyzer v0.3.2727 (2025-12-22) or later, this infrastructure is > necessary to avoid breaking compatibility with rust-analyzer v0.3.1940 > (2024-04-29), which corresponds to our MSRV of 1.78. > > Signed-off-by: Jesung Yang <y.j3ms.n@gmail.com> I think we can get all the information we need about the compiler without shelling out to RA here. In KConfig we already have options like config RUSTC_HAS_COERCE_POINTEE def_bool RUSTC_VERSION >= 108400 and those configs all flow through scripts/generate_rust_analyzer.py. Could we add one to indicate the new version of RA, and then drive the logic from it? > --- > scripts/generate_rust_analyzer.py | 181 +++++++++++++++++++++++++++++++++----- > 1 file changed, 157 insertions(+), 24 deletions(-) > > diff --git a/scripts/generate_rust_analyzer.py b/scripts/generate_rust_analyzer.py > index 147d0cc940681426771db865bc2462e7029a6d7d..32b0da99f17549ecc83e9a68911373310a2c9617 100755 > --- a/scripts/generate_rust_analyzer.py > +++ b/scripts/generate_rust_analyzer.py > @@ -4,10 +4,13 @@ > """ > > import argparse > +from datetime import datetime > +import enum > import json > import logging > import os > import pathlib > +import re > import subprocess > import sys > > @@ -19,7 +22,7 @@ def args_crates_cfgs(cfgs): > > return crates_cfgs > > -def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs, core_edition): > +def generate_crates(ctx, srctree, objtree, sysroot_src, external_src, cfgs, core_edition): > # Generate the configuration list. > cfg = [] > with open(objtree / "include" / "generated" / "rustc_cfg") as fd: > @@ -35,7 +38,7 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs, core_edit > crates_indexes = {} > crates_cfgs = args_crates_cfgs(cfgs) > > - def append_crate(display_name, root_module, deps, cfg=[], is_workspace_member=True, is_proc_macro=False, edition="2021"): > + def append_crate(display_name, root_module, deps, cfg=[], crate_attrs=[], is_workspace_member=True, is_proc_macro=False, edition="2021"): > crate = { > "display_name": display_name, > "root_module": str(root_module), > @@ -48,6 +51,8 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs, core_edit > "RUST_MODFILE": "This is only for rust-analyzer" > } > } > + if ctx["use_crate_attrs"] and len(crate_attrs) > 0: > + crate["crate_attrs"] = crate_attrs > if is_proc_macro: > proc_macro_dylib_name = subprocess.check_output( > [os.environ["RUSTC"], "--print", "file-names", "--crate-name", display_name, "--crate-type", "proc-macro", "-"], > @@ -72,52 +77,58 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs, core_edit > edition=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)`. > - append_sysroot_crate("core", [], cfg=crates_cfgs.get("core", []), edition=core_edition) > - append_sysroot_crate("alloc", ["core"]) > - append_sysroot_crate("std", ["alloc", "core"]) > - append_sysroot_crate("proc_macro", ["core", "std"]) > + def sysroot_deps(*deps): > + return list(deps) if ctx["add_sysroot_crates"] else [] > + > + if ctx["add_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)`. > + append_sysroot_crate("core", [], cfg=crates_cfgs.get("core", []), edition=core_edition) > + append_sysroot_crate("alloc", ["core"]) > + append_sysroot_crate("std", ["alloc", "core"]) > + append_sysroot_crate("proc_macro", ["core", "std"]) > > append_crate( > "compiler_builtins", > srctree / "rust" / "compiler_builtins.rs", > [], > + crate_attrs=["no_std"], > ) > > append_crate( > "proc_macro2", > srctree / "rust" / "proc-macro2" / "lib.rs", > - ["core", "alloc", "std", "proc_macro"], > + sysroot_deps("core", "alloc", "std", "proc_macro"), > cfg=crates_cfgs["proc_macro2"], > ) > > append_crate( > "quote", > srctree / "rust" / "quote" / "lib.rs", > - ["alloc", "proc_macro", "proc_macro2"], > + sysroot_deps("alloc", "proc_macro") + ["proc_macro2"], > cfg=crates_cfgs["quote"], > ) > > append_crate( > "syn", > srctree / "rust" / "syn" / "lib.rs", > - ["proc_macro", "proc_macro2", "quote"], > + sysroot_deps("proc_macro") + ["proc_macro2", "quote"], > cfg=crates_cfgs["syn"], > ) > > append_crate( > "macros", > srctree / "rust" / "macros" / "lib.rs", > - ["std", "proc_macro", "proc_macro2", "quote", "syn"], > + sysroot_deps("std", "proc_macro") + ["proc_macro2", "quote", "syn"], > is_proc_macro=True, > ) > > append_crate( > "build_error", > srctree / "rust" / "build_error.rs", > - ["core", "compiler_builtins"], > + sysroot_deps("core") + ["compiler_builtins"], > + crate_attrs=["no_std"], > ) > > append_crate( > @@ -125,31 +136,36 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs, core_edit > srctree / "rust" / "pin-init" / "internal" / "src" / "lib.rs", > [], > cfg=["kernel"], > + crate_attrs=["no_std"], > is_proc_macro=True, > ) > > append_crate( > "pin_init", > srctree / "rust" / "pin-init" / "src" / "lib.rs", > - ["core", "pin_init_internal", "macros"], > + sysroot_deps("core") + ["pin_init_internal", "macros"], > cfg=["kernel"], > + crate_attrs=["no_std"], > ) > > append_crate( > "ffi", > srctree / "rust" / "ffi.rs", > - ["core", "compiler_builtins"], > + sysroot_deps("core") + ["compiler_builtins"], > + crate_attrs=["no_std"], > ) > > def append_crate_with_generated( > display_name, > deps, > + crate_attrs=[] > ): > append_crate( > display_name, > srctree / "rust"/ display_name / "lib.rs", > deps, > cfg=cfg, > + crate_attrs=crate_attrs > ) > crates[-1]["env"]["OBJTREE"] = str(objtree.resolve(True)) > crates[-1]["source"] = { > @@ -160,9 +176,21 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs, core_edit > "exclude_dirs": [], > } > > - append_crate_with_generated("bindings", ["core", "ffi", "pin_init"]) > - append_crate_with_generated("uapi", ["core", "ffi", "pin_init"]) > - append_crate_with_generated("kernel", ["core", "macros", "build_error", "pin_init", "ffi", "bindings", "uapi"]) > + append_crate_with_generated( > + "bindings", > + sysroot_deps("core") + ["ffi", "pin_init"], > + crate_attrs=["no_std"], > + ) > + append_crate_with_generated( > + "uapi", > + sysroot_deps("core") + ["ffi", "pin_init"], > + crate_attrs=["no_std"], > + ) > + append_crate_with_generated( > + "kernel", > + sysroot_deps("core") + ["macros", "build_error", "pin_init", "ffi", "bindings", "uapi"], > + crate_attrs=["no_std"], > + ) > > def is_root_crate(build_file, target): > try: > @@ -190,12 +218,103 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs, core_edit > append_crate( > name, > path, > - ["core", "kernel"], > + sysroot_deps("core") + ["kernel"], > cfg=cfg, > + crate_attrs=["no_std"] > ) > > return crates > > +@enum.unique > +class RaVersion(enum.Enum): > + """ > + Represents rust-analyzer compatibility baselines. Concrete versions are mapped to the most > + recent baseline they have reached. Must be in release order. > + """ > + > + # v0.3.1940, released on 2024-04-29; bundled with the rustup 1.78 toolchain. > + V20240429 = 0 > + > + @staticmethod > + def baselines(): > + assert len(RaVersion) == 1, "Exhaustiveness check: update baseline list!" > + > + return [ > + (datetime.strptime("2024-04-29", "%Y-%m-%d"), (0, 3, 1940), RaVersion.V20240429), > + ] > + > + @staticmethod > + def default(): > + # The default is the 2024-04-29 release, aligning with our MSRV policy. > + return RaVersion.V20240429 > + > + def __str__(self): > + assert len(RaVersion) == 1, "Exhaustiveness check: update if branches!" > + > + if self == RaVersion.V20240429: > + return "v0.3.1940 (2024-04-29)" > + else: > + assert False, "Unreachable" > + > +def generate_rust_project( > + ra_version, > + srctree, > + objtree, > + sysroot, > + sysroot_src, > + external_src, > + cfgs, > + core_edition > +): > + assert len(RaVersion) == 1, "Exhaustiveness check: update if branches!" > + > + if ra_version == RaVersion.V20240429: > + ctx = { > + "use_crate_attrs": False, > + "add_sysroot_crates": True, > + } > + return { > + "crates": generate_crates(ctx, srctree, objtree, sysroot_src, external_src, cfgs, core_edition), > + "sysroot": str(sysroot), > + } > + else: > + assert False, "Unreachable" > + > +def query_ra_version(): > + try: > + # Use the rust-analyzer binary found in $PATH. > + ra_version_output = subprocess.check_output( > + ["rust-analyzer", "--version"], > + stdin=subprocess.DEVNULL, > + ).decode('utf-8').strip() > + return ra_version_output > + except FileNotFoundError: > + logging.warning("Failed to find rust-analyzer in $PATH") > + return None > + > +def map_ra_version_baseline(ra_version_output): > + checkpoints = reversed(RaVersion.baselines()) > + > + # First, attempt to resolve to our known checkpoint using the release date. > + # This covers patterns like "rust-analyzer 1.78.0 (9b00956e 2024-04-29)". > + date_match = re.search(r"\d{4}-\d{2}-\d{2}", ra_version_output) > + if date_match: > + found_date = datetime.strptime(date_match.group(), "%Y-%m-%d") > + for date, ver, enum in checkpoints: > + if found_date >= date: > + return enum > + > + # Otherwise, attempt to resolve to our known checkpoint using the rust-analyzer version. > + # This covers patterns like "rust-analyzer 0.3.2743-standalone". > + version_match = re.search(r"\d+\.\d+\.\d+", ra_version_output) > + if version_match: > + found_version = tuple(map(int, version_match.group().split("."))) > + for date, ver, enum in checkpoints: > + if found_version >= ver: > + return enum > + > + return RaVersion.default() > + > def main(): > parser = argparse.ArgumentParser() > parser.add_argument('--verbose', '-v', action='store_true') > @@ -216,10 +335,24 @@ def main(): > # Making sure that the `sysroot` and `sysroot_src` belong to the same toolchain. > assert args.sysroot in args.sysroot_src.parents > > - rust_project = { > - "crates": generate_crates(args.srctree, args.objtree, args.sysroot_src, args.exttree, args.cfgs, args.core_edition), > - "sysroot": str(args.sysroot), > - } > + output = query_ra_version() > + if output: > + compatible_ra_version = map_ra_version_baseline(output) > + else: > + default = RaVersion.default() > + logging.warning("Falling back to `rust-project.json` for rust-analyzer %s", default) > + compatible_ra_version = default > + > + rust_project = generate_rust_project( > + compatible_ra_version, > + args.srctree, > + args.objtree, > + args.sysroot, > + args.sysroot_src, > + args.exttree, > + args.cfgs, > + args.core_edition, > + ) > > json.dump(rust_project, sys.stdout, sort_keys=True, indent=4) > > > -- > 2.47.3 > > ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 1/2] scripts: generate_rust_analyzer: add versioning infrastructure 2026-01-09 23:07 ` Tamir Duberstein @ 2026-01-11 1:21 ` Jesung Yang 2026-01-11 2:24 ` Gary Guo 0 siblings, 1 reply; 8+ messages in thread From: Jesung Yang @ 2026-01-11 1:21 UTC (permalink / raw) To: Tamir Duberstein Cc: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich, rust-for-linux, linux-kernel On Sat, Jan 10, 2026 at 8:08 AM Tamir Duberstein <tamird@gmail.com> wrote: > > I think we can get all the information we need about the compiler > without shelling out to RA here. In KConfig we already have options > like > > config RUSTC_HAS_COERCE_POINTEE > def_bool RUSTC_VERSION >= 108400 > > and those configs all flow through scripts/generate_rust_analyzer.py. > Could we add one to indicate the new version of RA, and then drive the > logic from it? This could be an option, but I'm hesitant to use Kconfig soley for tooling enhancements which don't affect the kernel binary. I'd like to get a bit more input on whether this approach aligns with how we want to use Kconfig. Best regards, Jesung ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 1/2] scripts: generate_rust_analyzer: add versioning infrastructure 2026-01-11 1:21 ` Jesung Yang @ 2026-01-11 2:24 ` Gary Guo 0 siblings, 0 replies; 8+ messages in thread From: Gary Guo @ 2026-01-11 2:24 UTC (permalink / raw) To: Jesung Yang, Tamir Duberstein Cc: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich, rust-for-linux, linux-kernel On Sun Jan 11, 2026 at 1:21 AM GMT, Jesung Yang wrote: > On Sat, Jan 10, 2026 at 8:08 AM Tamir Duberstein <tamird@gmail.com> wrote: >> >> I think we can get all the information we need about the compiler >> without shelling out to RA here. In KConfig we already have options >> like >> >> config RUSTC_HAS_COERCE_POINTEE >> def_bool RUSTC_VERSION >= 108400 >> >> and those configs all flow through scripts/generate_rust_analyzer.py. >> Could we add one to indicate the new version of RA, and then drive the >> logic from it? > > This could be an option, but I'm hesitant to use Kconfig soley for > tooling enhancements which don't affect the kernel binary. I'd like to > get a bit more input on whether this approach aligns with how we want > to use Kconfig. Yes, we shouldn't have RA knobs in Kconfig just for this script (the script is just a good-to-have utility but not a requirement to build or even develop the kernel anyway). Best, Gary ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2 2/2] scripts: generate_rust_analyzer: fix IDE support for primitive types 2026-01-09 22:08 [PATCH v2 0/2] rust: take advantage of newer rust-analyzer features Jesung Yang via B4 Relay 2026-01-09 22:09 ` [PATCH v2 1/2] scripts: generate_rust_analyzer: add versioning infrastructure Jesung Yang via B4 Relay @ 2026-01-09 22:09 ` Jesung Yang via B4 Relay 2026-03-02 16:58 ` [PATCH v2 0/2] rust: take advantage of newer rust-analyzer features Tamir Duberstein 2 siblings, 0 replies; 8+ messages in thread From: Jesung Yang via B4 Relay @ 2026-01-09 22:09 UTC (permalink / raw) To: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich, Tamir Duberstein Cc: rust-for-linux, linux-kernel, Jesung Yang From: Jesung Yang <y.j3ms.n@gmail.com> Update `generate_rust_analyzer.py` so that the generated `rust-project.json` contains the `sysroot_src` field with `"crate_attrs": ["no_std"]` specified for relevant crates. This ensures that rust-analyzer provides proper IDE support for inherent methods of primitive types. Since commit 50384460c68f ("Rewrite method resolution to follow rustc more closely") to rust-analyzer, it no longer provides language server features like code completion and go-to-definition for inherent methods of primitive types when sysroot crates (e.g., `core`, `std`) are inlined in `rust-project.json` [1]. As `generate_rust_analyzer.py` currently inlines these crates, our setup is affected by this change. Specifying the `sysroot_src` field restores this functionality by allowing rust-analyzer to locate sysroot crates by itself. However, this causes `std` to be treated as a dependency for all local crates by default. To align with our compilation settings, provide the `no_std` attribute via the `crate_attrs` field, as the `-Zcrate-attr=no_std` compiler flag is not visible to rust-analyzer. This combined approach removes manual manipulation of sysroot dependencies while preventing incorrect symbol resolution against the standard library. Note that this configuration requires rust-analyzer release 2025-12-22 (v0.3.2727) or later, which introduced support for the `crate_attrs` field. Link: https://rust-lang.zulipchat.com/#narrow/channel/x/topic/x/near/561607963 [1] Link: https://rust-for-linux.zulipchat.com/#narrow/channel/x/topic/x/near/561607753 Signed-off-by: Jesung Yang <y.j3ms.n@gmail.com> --- scripts/generate_rust_analyzer.py | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/scripts/generate_rust_analyzer.py b/scripts/generate_rust_analyzer.py index 32b0da99f17549ecc83e9a68911373310a2c9617..6c3cb1d65d97e0ec414192f9fb867700a99c3d57 100755 --- a/scripts/generate_rust_analyzer.py +++ b/scripts/generate_rust_analyzer.py @@ -234,13 +234,16 @@ class RaVersion(enum.Enum): # v0.3.1940, released on 2024-04-29; bundled with the rustup 1.78 toolchain. V20240429 = 0 + # v0.3.2727, released on 2025-12-22. + V20251222 = 1 @staticmethod def baselines(): - assert len(RaVersion) == 1, "Exhaustiveness check: update baseline list!" + assert len(RaVersion) == 2, "Exhaustiveness check: update checkpoint list!" return [ (datetime.strptime("2024-04-29", "%Y-%m-%d"), (0, 3, 1940), RaVersion.V20240429), + (datetime.strptime("2025-12-22", "%Y-%m-%d"), (0, 3, 2727), RaVersion.V20251222), ] @staticmethod @@ -249,10 +252,12 @@ class RaVersion(enum.Enum): return RaVersion.V20240429 def __str__(self): - assert len(RaVersion) == 1, "Exhaustiveness check: update if branches!" + assert len(RaVersion) == 2, "Exhaustiveness check: update if branches!" if self == RaVersion.V20240429: return "v0.3.1940 (2024-04-29)" + elif self == RaVersion.V20251222: + return "v0.3.2727 (2025-12-22)" else: assert False, "Unreachable" @@ -266,7 +271,7 @@ def generate_rust_project( cfgs, core_edition ): - assert len(RaVersion) == 1, "Exhaustiveness check: update if branches!" + assert len(RaVersion) == 2, "Exhaustiveness check: update if branches!" if ra_version == RaVersion.V20240429: ctx = { @@ -277,6 +282,16 @@ def generate_rust_project( "crates": generate_crates(ctx, srctree, objtree, sysroot_src, external_src, cfgs, core_edition), "sysroot": str(sysroot), } + elif ra_version == RaVersion.V20251222: + ctx = { + "use_crate_attrs": True, + "add_sysroot_crates": False, + } + return { + "crates": generate_crates(ctx, srctree, objtree, sysroot_src, external_src, cfgs, core_edition), + "sysroot": str(sysroot), + "sysroot_src": str(sysroot_src), + } else: assert False, "Unreachable" -- 2.47.3 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v2 0/2] rust: take advantage of newer rust-analyzer features 2026-01-09 22:08 [PATCH v2 0/2] rust: take advantage of newer rust-analyzer features Jesung Yang via B4 Relay 2026-01-09 22:09 ` [PATCH v2 1/2] scripts: generate_rust_analyzer: add versioning infrastructure Jesung Yang via B4 Relay 2026-01-09 22:09 ` [PATCH v2 2/2] scripts: generate_rust_analyzer: fix IDE support for primitive types Jesung Yang via B4 Relay @ 2026-03-02 16:58 ` Tamir Duberstein 2026-03-04 9:52 ` Jesung Yang 2 siblings, 1 reply; 8+ messages in thread From: Tamir Duberstein @ 2026-03-02 16:58 UTC (permalink / raw) To: y.j3ms.n Cc: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich, rust-for-linux, linux-kernel On Fri, Jan 9, 2026 at 5:10 PM Jesung Yang via B4 Relay <devnull+y.j3ms.n.gmail.com@kernel.org> wrote: > > As discussed in [1], we need to support multiple versions of > rust-analyzer to take advantage of newer features without breaking > compatibility for users on older toolchains; we must maintain support > for rust-analyzer v0.3.1940 (2024-04-29), which corresponds to our > current MSRV of 1.78. > > Hence, this series revises the approach taken in [2] by first adding > multi-version support for rust-analyzer. Specifically, it enables > support for the v0.3.2727 (2025-12-22) release and newer, which is > required to resolve inherent method resolution issues for primitive > types found in recent versions of rust-analyzer. > > Thanks to Gary Guo and Miguel Ojeda for their feedback and reviews. > > [1] https://lore.kernel.org/rust-for-linux/20260101-rust-project-reduce-size-v1-1-4cd66e9e02d9@gmail.com/ > [2] https://lore.kernel.org/r/20260101-ra-fix-primitive-v1-1-def809357b4e@gmail.com/ > > Signed-off-by: Jesung Yang <y.j3ms.n@gmail.com> > --- > Changes in v2: > - Implement multiple rust-analyzer version support. > - Rebase on 9ace4753a520 (Linux 6.19-rc4). > - Remove an unnecessary new line between tags. > - Link to v1: https://lore.kernel.org/r/20260101-ra-fix-primitive-v1-1-def809357b4e@gmail.com > > --- > Jesung Yang (2): > scripts: generate_rust_analyzer: add versioning infrastructure > scripts: generate_rust_analyzer: fix IDE support for primitive types > > scripts/generate_rust_analyzer.py | 196 +++++++++++++++++++++++++++++++++----- > 1 file changed, 172 insertions(+), 24 deletions(-) > --- > base-commit: 9ace4753a5202b02191d54e9fdf7f9e3d02b85eb > change-id: 20260101-ra-fix-primitive-78154fe8173f > > Best regards, > -- > Jesung Yang <y.j3ms.n@gmail.com> > > Hi Jesung, is this something you'd be interested in updating now that type hints have been staged in rust-analyzer-next? Cheers. Tamir ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2 0/2] rust: take advantage of newer rust-analyzer features 2026-03-02 16:58 ` [PATCH v2 0/2] rust: take advantage of newer rust-analyzer features Tamir Duberstein @ 2026-03-04 9:52 ` Jesung Yang 0 siblings, 0 replies; 8+ messages in thread From: Jesung Yang @ 2026-03-04 9:52 UTC (permalink / raw) To: Tamir Duberstein, y.j3ms.n Cc: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich, rust-for-linux, linux-kernel On Tue Mar 3, 2026 at 1:58 AM KST, Tamir Duberstein wrote: [...] > > Hi Jesung, is this something you'd be interested in updating now that > type hints have been staged in rust-analyzer-next? Yeah, I'll send the next version within a few days. Best regards, Jesung ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-03-04 9:53 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-01-09 22:08 [PATCH v2 0/2] rust: take advantage of newer rust-analyzer features Jesung Yang via B4 Relay 2026-01-09 22:09 ` [PATCH v2 1/2] scripts: generate_rust_analyzer: add versioning infrastructure Jesung Yang via B4 Relay 2026-01-09 23:07 ` Tamir Duberstein 2026-01-11 1:21 ` Jesung Yang 2026-01-11 2:24 ` Gary Guo 2026-01-09 22:09 ` [PATCH v2 2/2] scripts: generate_rust_analyzer: fix IDE support for primitive types Jesung Yang via B4 Relay 2026-03-02 16:58 ` [PATCH v2 0/2] rust: take advantage of newer rust-analyzer features Tamir Duberstein 2026-03-04 9:52 ` Jesung Yang
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox