* [PATCH v5 0/2] rust: take advantage of newer rust-analyzer features
@ 2026-04-30 12:15 Jesung Yang via B4 Relay
2026-04-30 12:15 ` [PATCH v5 1/2] scripts: generate_rust_analyzer.py: add versioning infrastructure Jesung Yang via B4 Relay
2026-04-30 12:15 ` [PATCH v5 2/2] scripts: generate_rust_analyzer.py: fix IDE support for primitive types Jesung Yang via B4 Relay
0 siblings, 2 replies; 12+ messages in thread
From: Jesung Yang via B4 Relay @ 2026-04-30 12:15 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: Eliot Courtney, 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.
In this specific patch series addressing IDE support for inherent methods
of primitive types, the main compatibility issue arises from using
`sysroot_src`, which brings `std` as a dependency for crates in
`drivers/` and `samples/` (please see PATCH [2/2] for more details). This
causes rust-analyzer to incorrectly resolve symbols from `std` in those
crates.
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.
As Eliot mentioned in [3], we might also want to do the `include_dirs`
trick on top of this series to support rust-analyzer releases older than
v0.3.2727, but it should be handled in a dedicated patch series.
----- [QUICK TEST INSTRUCTIONS] -----
[Example 1]
1) Apply this patch series.
2) Run `mypy --strict scripts/generate_rust_analyzer.py` against
different Python versions (e.g., `--python-version 3.9`,
`--python-version 3.11`)
3) Verify that there is no type errors.
[Example 2]
1) Make rust-analyzer>=v0.3.2727 (2025-12-22) available in `$PATH`.
2) Compile one of the crates under `driver/` or `samples/rust`.
3) Run `make LLVM=1 rust-analyzer`.
4) Check that autocompletion for inherent methods does not work for
primitive types (e.g., `0i32.rotate_left()`).
5) Apply this patch series.
6) Re-run `make LLVM=1 rust-analyzer`.
7) Verify that autocompletion works properly now.
8) Verify that no autocompletion is provided for `std`.
[Example 3]
1) Make rust-analyzer<v0.3.2727 (2025-12-22) available in `$PATH`.
2) Compile one of the crates under `driver/` or `samples/rust`.
3) Run `make LLVM=1 rust-analyzer`.
4) Run `mv rust-project.json rust-project.json.old`.
5) Apply this patch series.
6) Re-run `make LLVM=1 rust-analyzer`.
7) Run `diff -s rust-project.json rust-project.json.old` to verify that
they are identical.
[Example 4]
1) Apply this patch series.
2) Ensure `rust-analyzer` is not available in `$PATH`.
3) Run `make V=1 LLVM=1 rust-analyzer`.
4) Verify that the fallback warning message appears.
[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/
[3] https://lore.kernel.org/rust-for-linux/DFVQBFD54CJO.2D3VQ091URH2B@nvidia.com/
Signed-off-by: Jesung Yang <y.j3ms.n@gmail.com>
---
Changes in v5:
- Document how to retrieve rust-analyzer version information.
- Rename `RaVersionInfo.DEFAULT` to `RaVersionInfo.MSRV`.
- Move the introduction of `RaVersionCtx` to the second patch.
- Embed `RaVersionCtx` into `RaVersionInfo`.
- Conditionally add `sysroot_src` field depending on
`manual_sysroot_crates`.
- Conditionally add `crate_attrs` field depending on `use_crate_attrs`.
- Conditionally define `RustProject` and `Crate` for stricter type
checking in newer Python versions.
- Move the dependency filtering logic to `build_crate`.
- Move `RustProject` closer to its point of use.
- Fix grammar.
- Link to v4: https://lore.kernel.org/r/20260317-ra-fix-primitive-v4-0-bc06709c8243@gmail.com
Changes in v4:
- Use `dataclass` for internal data structures.
- Change `RaVersionInfo` to an enum.
- Move `RaVersionInfo` closer to its point of use.
- Statically check if all `RaVersionInfo` variants are properly handled
(using mypy).
- Relocate `ctx.manual_sysroot_crates` check in `append_sysroot_crate`.
- Move `crate_attrs=["no_std"]` addition to `scripts:
generate_rust_analyzer.py: fix IDE support for primitive types`.
- Move `typing.NotRequired` closer to the relevant field.
- Link to v3: https://lore.kernel.org/r/20260308-ra-fix-primitive-v3-0-598017bcefd8@gmail.com
Changes in v3:
- Remove extra `crate_attrs=["no_std"]` for crates that specify
`#![no_std]` by themselves.
- Fix rust-analyzer version for Rust 1.78.
- Tweak `map_ra_version_baseline` to distinguish between Rust version
and rust-analyzer version.
- Simplify overall structure.
- Rebase on 6c02871d258 ("scripts: generate_rust_analyzer.py: reduce cfg
plumbing")
- Link to v2: https://lore.kernel.org/r/20260109-ra-fix-primitive-v2-0-249852a4145a@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.py: add versioning infrastructure
scripts: generate_rust_analyzer.py: fix IDE support for primitive types
scripts/generate_rust_analyzer.py | 268 +++++++++++++++++++++++++++++++++++---
1 file changed, 248 insertions(+), 20 deletions(-)
---
base-commit: b4e07588e743c989499ca24d49e752c074924a9a
change-id: 20260101-ra-fix-primitive-78154fe8173f
Best regards,
--
Jesung Yang <y.j3ms.n@gmail.com>
^ permalink raw reply [flat|nested] 12+ messages in thread* [PATCH v5 1/2] scripts: generate_rust_analyzer.py: add versioning infrastructure 2026-04-30 12:15 [PATCH v5 0/2] rust: take advantage of newer rust-analyzer features Jesung Yang via B4 Relay @ 2026-04-30 12:15 ` Jesung Yang via B4 Relay 2026-04-30 14:13 ` Tamir Duberstein 2026-04-30 12:15 ` [PATCH v5 2/2] scripts: generate_rust_analyzer.py: fix IDE support for primitive types Jesung Yang via B4 Relay 1 sibling, 1 reply; 12+ messages in thread From: Jesung Yang via B4 Relay @ 2026-04-30 12:15 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: Eliot Courtney, 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. 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 using the `sysroot_src` field with a feature only available in rust-analyzer v0.3.2727 (2025-12-22) or later, this infrastructure is necessary to maintain compatibility with older rust-analyzer releases. Signed-off-by: Jesung Yang <y.j3ms.n@gmail.com> --- scripts/generate_rust_analyzer.py | 171 +++++++++++++++++++++++++++++++++++++- 1 file changed, 167 insertions(+), 4 deletions(-) diff --git a/scripts/generate_rust_analyzer.py b/scripts/generate_rust_analyzer.py index d5f9a0ca742c..f1828620bbbf 100755 --- a/scripts/generate_rust_analyzer.py +++ b/scripts/generate_rust_analyzer.py @@ -4,6 +4,9 @@ """ import argparse +from datetime import datetime, date +import enum +import re import json import logging import os @@ -343,6 +346,148 @@ def generate_crates( return crates + +Version = tuple[int, int, int] + + +@enum.unique +class RaVersionInfo(enum.Enum): + """ + Represents rust-analyzer compatibility baselines. Concrete versions are mapped to the most + recent baseline they have reached. Must be in release order. + """ + + # NOTE: + # This rust-analyzer release should be kept in sync with our MSRV (currently 1.85.0). + # When the MSRV is bumped, follow the steps below to retrieve the information needed + # to update this: + # + # 1) Clone both Rust and rust-analyzer repositories. + # ```console + # $ git clone https://github.com/rust-lang/rust.git + # $ git clone https://github.com/rust-lang/rust-analyzer.git + # ``` + # 2) Run the following script, providing the new MSRV as an argument. + # It uses `xdg-open` to open the matching [1] rust-analyzer release page. + # ```bash + # #!/usr/bin/env bash + # + # RUST_VERSION=$1 + # LOOKAHEAD=50 + # + # subject_string=$( + # git -C ./rust log -n "$LOOKAHEAD" --format='%s' "$RUST_VERSION" \ + # -- src/tools/rust-analyzer | grep 'Merge pull request #' + # ) + # readarray -t subject_array <<< "$subject_string" + # + # hash=$( + # git -C ./rust-analyzer log -n 1 --format='%H' --fixed-strings \ + # "${subject_array[@]/#/--grep=}" + # ) + # + # tag_predates=$(git -C ./rust-analyzer describe --tags --abbrev=0 "$hash") + # + # link_prefix="https://github.com/rust-lang/rust-analyzer/releases/tag" + # xdg-open "$link_prefix/$tag_predates" + # ``` + # 3) Grab the release date and the version string. + # + # [1] Note that rust-analyzer releases may not perfectly align with those shipped + # in upstream Rust. We take a conservative approach here: use the tag that + # directly predates the latest merge commit found upstream. + # + # v0.3.2228, released on 2024-12-23; shipped with the rustup 1.85.0 toolchain. + MSRV = ( + datetime.strptime("2024-12-23", "%Y-%m-%d"), + (0, 3, 2228), + (1, 85, 0), + ) + + def __init__( + self, + release_date: date, + ra_version: Version, + rust_version: Version, + ) -> None: + self.release_date = release_date + self.ra_version = ra_version + self.rust_version = rust_version + + +class RustProject(TypedDict): + crates: List[Crate] + sysroot: str + + +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: + rust_project: RustProject = { + "crates": generate_crates( + srctree, objtree, sysroot_src, external_src, cfgs, core_edition + ), + "sysroot": str(sysroot), + } + + return rust_project + +def query_ra_version() -> Optional[str]: + 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: str) -> RaVersionInfo: + baselines = reversed(RaVersionInfo) + + version_match = re.search(r"\d+\.\d+\.\d+", ra_version_output) + if version_match: + version_string = version_match.group() + found_version = tuple(map(int, version_string.split("."))) + + # `rust-analyzer --version` shows a different version string depending on how the binary + # is built: it may print either the Rust version or the rust-analyzer version itself. + # To distinguish between them, we leverage rust-analyzer's versioning convention. + # + # See: + # - https://github.com/rust-lang/rust-analyzer/blob/fad5c3d2d642/xtask/src/dist.rs#L19-L21 + is_ra_version = version_string.startswith(("0.3", "0.4", "0.5")) + if is_ra_version: + for info in baselines: + if found_version >= info.ra_version: + return info + else: + for info in baselines: + if found_version >= info.rust_version: + return info + + 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 info in baselines: + if found_date >= info.release_date: + return info + + return RaVersionInfo.MSRV + def main() -> None: parser = argparse.ArgumentParser() parser.add_argument('--verbose', '-v', action='store_true') @@ -371,10 +516,28 @@ def main() -> None: level=logging.INFO if args.verbose else logging.WARNING ) - rust_project = { - "crates": generate_crates(args.srctree, args.objtree, args.sysroot_src, args.exttree, args.cfgs, args.core_edition), - "sysroot": str(args.sysroot), - } + ra_version_output = query_ra_version() + if ra_version_output: + compatible_ra_version = map_ra_version_baseline(ra_version_output) + else: + logging.warning( + "Falling back to `rust-project.json` for rust-analyzer %s, %s (shipped with Rust %s)", + ".".join(map(str, RaVersionInfo.MSRV.ra_version)), + datetime.strftime(RaVersionInfo.MSRV.release_date, "%Y-%m-%d"), + ".".join(map(str, RaVersionInfo.MSRV.rust_version)), + ) + compatible_ra_version = RaVersionInfo.MSRV + + 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.53.0 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v5 1/2] scripts: generate_rust_analyzer.py: add versioning infrastructure 2026-04-30 12:15 ` [PATCH v5 1/2] scripts: generate_rust_analyzer.py: add versioning infrastructure Jesung Yang via B4 Relay @ 2026-04-30 14:13 ` Tamir Duberstein 2026-05-01 14:27 ` Jesung Yang 2026-05-02 7:40 ` Jesung Yang 0 siblings, 2 replies; 12+ messages in thread From: Tamir Duberstein @ 2026-04-30 14:13 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, Eliot Courtney, rust-for-linux, linux-kernel On Thu, Apr 30, 2026 at 8:15 AM 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. > > 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 using the `sysroot_src` > field with a feature only available in rust-analyzer v0.3.2727 > (2025-12-22) or later, this infrastructure is necessary to maintain > compatibility with older rust-analyzer releases. > > Signed-off-by: Jesung Yang <y.j3ms.n@gmail.com> > --- > scripts/generate_rust_analyzer.py | 171 +++++++++++++++++++++++++++++++++++++- > 1 file changed, 167 insertions(+), 4 deletions(-) > > diff --git a/scripts/generate_rust_analyzer.py b/scripts/generate_rust_analyzer.py > index d5f9a0ca742c..f1828620bbbf 100755 > --- a/scripts/generate_rust_analyzer.py > +++ b/scripts/generate_rust_analyzer.py > @@ -4,6 +4,9 @@ > """ > > import argparse > +from datetime import datetime, date > +import enum > +import re > import json > import logging > import os > @@ -343,6 +346,148 @@ def generate_crates( > > return crates > > + > +Version = tuple[int, int, int] > + > + > +@enum.unique > +class RaVersionInfo(enum.Enum): > + """ > + Represents rust-analyzer compatibility baselines. Concrete versions are mapped to the most > + recent baseline they have reached. Must be in release order. > + """ Until this patch this file wrapped at 80 columns. > + > + # NOTE: > + # This rust-analyzer release should be kept in sync with our MSRV (currently 1.85.0). > + # When the MSRV is bumped, follow the steps below to retrieve the information needed > + # to update this: > + # > + # 1) Clone both Rust and rust-analyzer repositories. > + # ```console > + # $ git clone https://github.com/rust-lang/rust.git > + # $ git clone https://github.com/rust-lang/rust-analyzer.git > + # ``` > + # 2) Run the following script, providing the new MSRV as an argument. > + # It uses `xdg-open` to open the matching [1] rust-analyzer release page. > + # ```bash > + # #!/usr/bin/env bash > + # > + # RUST_VERSION=$1 > + # LOOKAHEAD=50 > + # > + # subject_string=$( > + # git -C ./rust log -n "$LOOKAHEAD" --format='%s' "$RUST_VERSION" \ > + # -- src/tools/rust-analyzer | grep 'Merge pull request #' This grep can be replaced with `--merges` and then you can just use `-n 1` instead of `-n $LOOKAHEAD`, right? > + # ) > + # readarray -t subject_array <<< "$subject_string" > + # > + # hash=$( > + # git -C ./rust-analyzer log -n 1 --format='%H' --fixed-strings \ > + # "${subject_array[@]/#/--grep=}" > + # ) > + # > + # tag_predates=$(git -C ./rust-analyzer describe --tags --abbrev=0 "$hash") > + # > + # link_prefix="https://github.com/rust-lang/rust-analyzer/releases/tag" > + # xdg-open "$link_prefix/$tag_predates" > + # ``` With or without the `--merges` change, this always takes me to a very recent tag. It seems like `git log -- src/tools/rust-analyzer` in the rust repo never shows merge commits? > + # 3) Grab the release date and the version string. > + # > + # [1] Note that rust-analyzer releases may not perfectly align with those shipped > + # in upstream Rust. We take a conservative approach here: use the tag that > + # directly predates the latest merge commit found upstream. > + # > + # v0.3.2228, released on 2024-12-23; shipped with the rustup 1.85.0 toolchain. > + MSRV = ( > + datetime.strptime("2024-12-23", "%Y-%m-%d"), Could we use date everywhere? Why datetime? https://docs.python.org/3/library/datetime.html#datetime.date.strptime > + (0, 3, 2228), > + (1, 85, 0), > + ) > + > + def __init__( > + self, > + release_date: date, > + ra_version: Version, > + rust_version: Version, > + ) -> None: > + self.release_date = release_date > + self.ra_version = ra_version > + self.rust_version = rust_version > + > + > +class RustProject(TypedDict): > + crates: List[Crate] > + sysroot: str > + > + > +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: > + rust_project: RustProject = { > + "crates": generate_crates( > + srctree, objtree, sysroot_src, external_src, cfgs, core_edition > + ), > + "sysroot": str(sysroot), > + } > + > + return rust_project > + > +def query_ra_version() -> Optional[str]: > + 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: str) -> RaVersionInfo: > + baselines = reversed(RaVersionInfo) > + > + version_match = re.search(r"\d+\.\d+\.\d+", ra_version_output) > + if version_match: > + version_string = version_match.group() > + found_version = tuple(map(int, version_string.split("."))) > + > + # `rust-analyzer --version` shows a different version string depending on how the binary > + # is built: it may print either the Rust version or the rust-analyzer version itself. > + # To distinguish between them, we leverage rust-analyzer's versioning convention. > + # > + # See: > + # - https://github.com/rust-lang/rust-analyzer/blob/fad5c3d2d642/xtask/src/dist.rs#L19-L21 > + is_ra_version = version_string.startswith(("0.3", "0.4", "0.5")) > + if is_ra_version: > + for info in baselines: > + if found_version >= info.ra_version: > + return info > + else: > + for info in baselines: > + if found_version >= info.rust_version: > + return info > + > + 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") datetime.strptime throws ValueError on invalid input; perhaps we can catch that instead of using a regex match. > + for info in baselines: > + if found_date >= info.release_date: > + return info > + > + return RaVersionInfo.MSRV > + > def main() -> None: > parser = argparse.ArgumentParser() > parser.add_argument('--verbose', '-v', action='store_true') > @@ -371,10 +516,28 @@ def main() -> None: > level=logging.INFO if args.verbose else logging.WARNING > ) > > - rust_project = { > - "crates": generate_crates(args.srctree, args.objtree, args.sysroot_src, args.exttree, args.cfgs, args.core_edition), > - "sysroot": str(args.sysroot), > - } > + ra_version_output = query_ra_version() > + if ra_version_output: > + compatible_ra_version = map_ra_version_baseline(ra_version_output) > + else: > + logging.warning( > + "Falling back to `rust-project.json` for rust-analyzer %s, %s (shipped with Rust %s)", > + ".".join(map(str, RaVersionInfo.MSRV.ra_version)), > + datetime.strftime(RaVersionInfo.MSRV.release_date, "%Y-%m-%d"), > + ".".join(map(str, RaVersionInfo.MSRV.rust_version)), > + ) I think I mentioned this in an earlier review: this warning is logged under the exact same circumstances as the warning in `query_ra_version`. It should be one warning, not two. > + compatible_ra_version = RaVersionInfo.MSRV > + > + 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.53.0 > > ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v5 1/2] scripts: generate_rust_analyzer.py: add versioning infrastructure 2026-04-30 14:13 ` Tamir Duberstein @ 2026-05-01 14:27 ` Jesung Yang 2026-05-01 15:38 ` Tamir Duberstein 2026-05-02 7:40 ` Jesung Yang 1 sibling, 1 reply; 12+ messages in thread From: Jesung Yang @ 2026-05-01 14:27 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, Eliot Courtney, rust-for-linux, linux-kernel On Thu, Apr 30, 2026 at 11:14 PM Tamir Duberstein <tamird@kernel.org> wrote: > On Thu, Apr 30, 2026 at 8:15 AM Jesung Yang via B4 Relay > <devnull+y.j3ms.n.gmail.com@kernel.org> wrote: [...] > > + # NOTE: > > + # This rust-analyzer release should be kept in sync with our MSRV (currently 1.85.0). > > + # When the MSRV is bumped, follow the steps below to retrieve the information needed > > + # to update this: > > + # > > + # 1) Clone both Rust and rust-analyzer repositories. > > + # ```console > > + # $ git clone https://github.com/rust-lang/rust.git > > + # $ git clone https://github.com/rust-lang/rust-analyzer.git > > + # ``` > > + # 2) Run the following script, providing the new MSRV as an argument. > > + # It uses `xdg-open` to open the matching [1] rust-analyzer release page. > > + # ```bash > > + # #!/usr/bin/env bash > > + # > > + # RUST_VERSION=$1 > > + # LOOKAHEAD=50 > > + # > > + # subject_string=$( > > + # git -C ./rust log -n "$LOOKAHEAD" --format='%s' "$RUST_VERSION" \ > > + # -- src/tools/rust-analyzer | grep 'Merge pull request #' > > This grep can be replaced with `--merges` and then you can just use > `-n 1` instead of `-n $LOOKAHEAD`, right? No, because of commits like "Merge from rust-lang/rust." Sometimes those are more recent than the downstream PR merges we're looking for. An example using 1.86.0: $ git -C ./rust log --merges -n 1 --format='%s' 1.86.0 \ -- src/tools/rust-analyzer Merge from rust-lang/rust $ git -C ./rust-analyzer log -n 1 --fixed-strings \ --grep='Merge from rust-lang/rust' commit 99894ccbccd63cd7480ac282ba636e84004427bc Merge: d105b7e0d1 f13fe5a4dc Author: Laurențiu Nicola <lnicola@dend.ro> Date: Mon Jul 21 09:18:22 2025 +0300 Merge from rust-lang/rust Since "Merge from rust-lang/rust" is a common subject name for downstream synchronizations, we've picked up a more recent one here (1.86.0 was released on Apr 3 2025, which predates the Jul 21 2025 commit shown above). > > + # ) > > + # readarray -t subject_array <<< "$subject_string" > > + # > > + # hash=$( > > + # git -C ./rust-analyzer log -n 1 --format='%H' --fixed-strings \ > > + # "${subject_array[@]/#/--grep=}" > > + # ) > > + # > > + # tag_predates=$(git -C ./rust-analyzer describe --tags --abbrev=0 "$hash") > > + # > > + # link_prefix="https://github.com/rust-lang/rust-analyzer/releases/tag" > > + # xdg-open "$link_prefix/$tag_predates" > > + # ``` > > With or without the `--merges` change, this always takes me to a very > recent tag. It seems like `git log -- src/tools/rust-analyzer` in the > rust repo never shows merge commits? Perhaps the MSRV wasn't provided as an argument? I see the nightly release page if the version is missing or unknown. $ ./check.sh 1.85.0 # This opens: # https://github.com/rust-lang/rust-analyzer/releases/tag/2024-12-23 $ ./check.sh 1.94.0 # This opens: # https://github.com/rust-lang/rust-analyzer/releases/tag/2026-01-05 $ ./check.sh 1.85 # This opens: # https://github.com/rust-lang/rust-analyzer/releases/tag/nightly $ ./check.sh # This opens: # https://github.com/rust-lang/rust-analyzer/releases/tag/nightly I'll add `set -e` and a check to make the argument mandatory to prevent this confusion. As for the rest of your comments, I'll incorporate them in the next version. Best regards, Jesung ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v5 1/2] scripts: generate_rust_analyzer.py: add versioning infrastructure 2026-05-01 14:27 ` Jesung Yang @ 2026-05-01 15:38 ` Tamir Duberstein 2026-05-02 6:25 ` Jesung Yang 0 siblings, 1 reply; 12+ messages in thread From: Tamir Duberstein @ 2026-05-01 15:38 UTC (permalink / raw) To: Jesung Yang Cc: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich, Eliot Courtney, rust-for-linux, linux-kernel On Fri, May 1, 2026 at 10:27 AM Jesung Yang <y.j3ms.n@gmail.com> wrote: > > On Thu, Apr 30, 2026 at 11:14 PM Tamir Duberstein <tamird@kernel.org> wrote: > > [...] > > With or without the `--merges` change, this always takes me to a very > > recent tag. It seems like `git log -- src/tools/rust-analyzer` in the > > rust repo never shows merge commits? > > Perhaps the MSRV wasn't provided as an argument? I see the nightly > release page if the version is missing or unknown. > > $ ./check.sh 1.85.0 > # This opens: > # https://github.com/rust-lang/rust-analyzer/releases/tag/2024-12-23 > > $ ./check.sh 1.94.0 > # This opens: > # https://github.com/rust-lang/rust-analyzer/releases/tag/2026-01-05 > > $ ./check.sh 1.85 > # This opens: > # https://github.com/rust-lang/rust-analyzer/releases/tag/nightly > > $ ./check.sh > # This opens: > # https://github.com/rust-lang/rust-analyzer/releases/tag/nightly > > I'll add `set -e` and a check to make the argument mandatory to prevent > this confusion. Here's what I see locally: % cat check.sh #!/usr/bin/env bash set -eux RUST_VERSION=$1 LOOKAHEAD=50 subject_string=$( git -C ./rust log -n "$LOOKAHEAD" --format='%s' "$RUST_VERSION" \ -- src/tools/rust-analyzer | grep 'Merge pull request #' ) readarray -t subject_array <<< "$subject_string" hash=$( git -C ./rust-analyzer log -n 1 --format='%H' --fixed-strings \ "${subject_array[@]/#/--grep=}" ) tag_predates=$(git -C ./rust-analyzer describe --tags --abbrev=0 "$hash") link_prefix="https://github.com/rust-lang/rust-analyzer/releases/tag" open "$link_prefix/$tag_predates" % bash check.sh 1.85.0 + RUST_VERSION=1.85.0 + LOOKAHEAD=50 ++ git -C ./rust log -n 50 --format=%s 1.85.0 -- src/tools/rust-analyzer ++ grep 'Merge pull request #' + subject_string= % echo $? 1 So it seems to never get past `git log` in the rust repo. When I run that git log manually I see nothing containing "Merge pull request ...": % git -C ./rust log -n 50 --format=%s 1.85.0 -- src/tools/rust-analyzer Disable some incorrect rust-analyzer diagnostics on beta Backport rust-lang/rust-analyzer#18760: internal: Workaround salsa cycles leaking Bump rustc crates Preparing for merge from rust-lang/rust Revert "Auto merge of #130766 - clarfonthey:stable-coverage-attribute, r=wesleywiser" fix: Fix flycheck workspace when requested but package was found fix: Delay initial flycheck until after build scripts fix: Fix empty check diagnostics not marking files as changed fix: Properly check if workspace flychecking is allowed fix: Don't trigger paren wrapping typing handler after idents minor: Tell the server to stop prior to restarting it fix: Set `result_id` for `RelatedFullDocumentDiagnosticReport` everywhere fix: only show debug lens with a valid root fix: remove always! check for file_id in runnables Revert "internal: Drop proc-macro server support for ~1.66.0 and older toolchains" Clear all check diagnostics when the workspace changes Arc the package ids coming from flycheck Arc the workspace root flycheck Clear flycheck diagnostics more granularly Fix a case where completion was unable to expand a macro internal: Split serde derive feature into `serde_derive` usage fix: Reduce applicability of unnecessary_async assist internal: Set `result_id` for pull diagnostics fix: Consider both completion detail fields in to_proto Fix AsmOption rule in rust.ungram fix: Do not ask the client ro resolve for non existing label details internal: Cleanup label structure of `CompletionItem` Taking a raw ref of a deref is always safe make no-variant types a dedicated Variants variant Variants::Single: do not use invalid VariantIdx for uninhabited enums Remove salsa from proc-macro server dep tree Fix pretty-printing of `@` patterns Stabilize #[coverage] attribute Use a record struct instead of a tuple for each namespace in `PerNs` Fix a panic with a diagnostics fix when a keyword is used as a field fix: Fix path qualified auto-importing completions not working with re-exports internal: Don't serialize empty fields in completions and resolve payloads internal: Simplify ratoml testdir usage Report unresolved idents for implicit captures in `format_args!()` refactor: simplify `edit_tuple_usages` in destructure_tuple_binding fix: Fix proc-macro dylib names on windows internal: Show mir eval errors on hover with debug env var set feat: Use string literal contents as a name when extracting into variable fix: Revert changes to client capabilities in `bac0ed5` feat: improve name generation in destructure_tuple_binding Bump typos Fix a few typos Show expansion errors in expand_macro feature Do not require a special env var to be set for the proc-macro-srv internal: Implement `naked_asm!` builtin What's also interesting is that when I use `--merges` I get no commits at all: % git -C ./rust log -n1 --merges --format=%s 1.85.0 -- src/tools/rust-analyzer % Something strange is happening; my git is not behaving the same as your git. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v5 1/2] scripts: generate_rust_analyzer.py: add versioning infrastructure 2026-05-01 15:38 ` Tamir Duberstein @ 2026-05-02 6:25 ` Jesung Yang 2026-05-03 13:21 ` Tamir Duberstein 0 siblings, 1 reply; 12+ messages in thread From: Jesung Yang @ 2026-05-02 6:25 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, Eliot Courtney, rust-for-linux, linux-kernel On Sat, May 2, 2026 at 12:39 AM Tamir Duberstein <tamird@kernel.org> wrote: > > Here's what I see locally: > > % bash check.sh 1.85.0 > + RUST_VERSION=1.85.0 > + LOOKAHEAD=50 > ++ git -C ./rust log -n 50 --format=%s 1.85.0 -- src/tools/rust-analyzer > ++ grep 'Merge pull request #' > + subject_string= > % echo $? > 1 > > So it seems to never get past `git log` in the rust repo. When I run > that git log manually I see nothing containing "Merge pull request > ...": > > % git -C ./rust log -n 50 --format=%s 1.85.0 -- src/tools/rust-analyzer > Disable some incorrect rust-analyzer diagnostics on beta > Backport rust-lang/rust-analyzer#18760: internal: Workaround salsa > cycles leaking > Bump rustc crates > Preparing for merge from rust-lang/rust [...] > > What's also interesting is that when I use `--merges` I get no commits at all: > > % git -C ./rust log -n1 --merges --format=%s 1.85.0 -- src/tools/rust-analyzer > % > > Something strange is happening; my git is not behaving the same as your git. I tested the procedure on a fresh Ubuntu 24.04 container using git 2.43.0, and it works as expected: merge commits are not lost, and the script provides the matching release page link. What does your git configuration look like? Perhaps some local settings are preventing merge commits from being displayed? Best regards, Jesung ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v5 1/2] scripts: generate_rust_analyzer.py: add versioning infrastructure 2026-05-02 6:25 ` Jesung Yang @ 2026-05-03 13:21 ` Tamir Duberstein 2026-05-04 13:11 ` Jesung Yang 0 siblings, 1 reply; 12+ messages in thread From: Tamir Duberstein @ 2026-05-03 13:21 UTC (permalink / raw) To: Jesung Yang Cc: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich, Eliot Courtney, rust-for-linux, linux-kernel On Sat, May 2, 2026 at 2:26 AM Jesung Yang <y.j3ms.n@gmail.com> wrote: > > On Sat, May 2, 2026 at 12:39 AM Tamir Duberstein <tamird@kernel.org> wrote: > > > > Here's what I see locally: > > > > % bash check.sh 1.85.0 > > + RUST_VERSION=1.85.0 > > + LOOKAHEAD=50 > > ++ git -C ./rust log -n 50 --format=%s 1.85.0 -- src/tools/rust-analyzer > > ++ grep 'Merge pull request #' > > + subject_string= > > % echo $? > > 1 > > > > So it seems to never get past `git log` in the rust repo. When I run > > that git log manually I see nothing containing "Merge pull request > > ...": > > > > % git -C ./rust log -n 50 --format=%s 1.85.0 -- src/tools/rust-analyzer > > Disable some incorrect rust-analyzer diagnostics on beta > > Backport rust-lang/rust-analyzer#18760: internal: Workaround salsa > > cycles leaking > > Bump rustc crates > > Preparing for merge from rust-lang/rust > [...] > > > > What's also interesting is that when I use `--merges` I get no commits at all: > > > > % git -C ./rust log -n1 --merges --format=%s 1.85.0 -- src/tools/rust-analyzer > > % > > > > Something strange is happening; my git is not behaving the same as your git. > > I tested the procedure on a fresh Ubuntu 24.04 container using git > 2.43.0, and it works as expected: merge commits are not lost, and the > script provides the matching release page link. What does your git > configuration look like? Perhaps some local settings are preventing > merge commits from being displayed? Indeed. Codex figured it out: The cause is your global Git config. You have: git config --show-origin --get log.follow # file:/Users/tamird/.gitconfig true That affects /Users/tamird/code/check.sh:9: with a single pathspec, git log ... -- src/tools/rust-analyzer behaves as if --follow was passed. In this non-linear subtree history, --follow drops the merge commits, so the grep for Merge pull request # finds nothing. Best script fix: make that command immune to user config, e.g. add --no-follow or use git -c log.follow=false -C ./rust log .... Secondary issue: after this is fixed, macOS /bin/bash here is 3.2 and does not have readarray, so /Users/tamird/code/check.sh:12 will hit another portability failure on this machine. Mind incorporating these fixes in the next version? ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v5 1/2] scripts: generate_rust_analyzer.py: add versioning infrastructure 2026-05-03 13:21 ` Tamir Duberstein @ 2026-05-04 13:11 ` Jesung Yang 0 siblings, 0 replies; 12+ messages in thread From: Jesung Yang @ 2026-05-04 13:11 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, Eliot Courtney, rust-for-linux, linux-kernel On Sun, May 3, 2026 at 10:21 PM Tamir Duberstein <tamird@kernel.org> wrote: > > Indeed. Codex figured it out: > > The cause is your global Git config. You have: > > git config --show-origin --get log.follow > # file:/Users/tamird/.gitconfig true > > That affects /Users/tamird/code/check.sh:9: with a single pathspec, > git log ... -- src/tools/rust-analyzer behaves as if --follow was > passed. In this non-linear subtree history, --follow drops the merge > commits, so the grep for Merge pull request # finds nothing. > > Best script fix: make that command immune to user config, e.g. add > --no-follow or use git -c log.follow=false -C ./rust log .... > > Secondary issue: after this is fixed, macOS /bin/bash here is 3.2 and > does not have readarray, so /Users/tamird/code/check.sh:12 will hit > another portability failure on this machine. > > Mind incorporating these fixes in the next version? Happy to :) (Surprised macOS is still on bash from 2006... I suppose it has something to do with the GPLv3 transition.) Best regards, Jesung ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v5 1/2] scripts: generate_rust_analyzer.py: add versioning infrastructure 2026-04-30 14:13 ` Tamir Duberstein 2026-05-01 14:27 ` Jesung Yang @ 2026-05-02 7:40 ` Jesung Yang 2026-05-03 13:22 ` Tamir Duberstein 1 sibling, 1 reply; 12+ messages in thread From: Jesung Yang @ 2026-05-02 7:40 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, Eliot Courtney, rust-for-linux, linux-kernel On Thu, Apr 30, 2026 at 11:14 PM Tamir Duberstein <tamird@kernel.org> wrote: > On Thu, Apr 30, 2026 at 8:15 AM Jesung Yang via B4 Relay > <devnull+y.j3ms.n.gmail.com@kernel.org> wrote: > > > > +def map_ra_version_baseline(ra_version_output: str) -> RaVersionInfo: > > + baselines = reversed(RaVersionInfo) > > + > > + version_match = re.search(r"\d+\.\d+\.\d+", ra_version_output) > > + if version_match: > > + version_string = version_match.group() > > + found_version = tuple(map(int, version_string.split("."))) > > + > > + # `rust-analyzer --version` shows a different version string depending on how the binary > > + # is built: it may print either the Rust version or the rust-analyzer version itself. > > + # To distinguish between them, we leverage rust-analyzer's versioning convention. > > + # > > + # See: > > + # - https://github.com/rust-lang/rust-analyzer/blob/fad5c3d2d642/xtask/src/dist.rs#L19-L21 > > + is_ra_version = version_string.startswith(("0.3", "0.4", "0.5")) > > + if is_ra_version: > > + for info in baselines: > > + if found_version >= info.ra_version: > > + return info > > + else: > > + for info in baselines: > > + if found_version >= info.rust_version: > > + return info > > + > > + 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") > > datetime.strptime throws ValueError on invalid input; perhaps we can > catch that instead of using a regex match. I think we still need to use regex to extract the date substring, right? Since `ra_version_output` is the uncleaned CLI output, `date.strptime` would always fail if passed the whole string. Best regards, Jesung ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v5 1/2] scripts: generate_rust_analyzer.py: add versioning infrastructure 2026-05-02 7:40 ` Jesung Yang @ 2026-05-03 13:22 ` Tamir Duberstein 0 siblings, 0 replies; 12+ messages in thread From: Tamir Duberstein @ 2026-05-03 13:22 UTC (permalink / raw) To: Jesung Yang Cc: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich, Eliot Courtney, rust-for-linux, linux-kernel On Sat, May 2, 2026 at 3:40 AM Jesung Yang <y.j3ms.n@gmail.com> wrote: > > On Thu, Apr 30, 2026 at 11:14 PM Tamir Duberstein <tamird@kernel.org> wrote: > > On Thu, Apr 30, 2026 at 8:15 AM Jesung Yang via B4 Relay > > <devnull+y.j3ms.n.gmail.com@kernel.org> wrote: > > > > > > +def map_ra_version_baseline(ra_version_output: str) -> RaVersionInfo: > > > + baselines = reversed(RaVersionInfo) > > > + > > > + version_match = re.search(r"\d+\.\d+\.\d+", ra_version_output) > > > + if version_match: > > > + version_string = version_match.group() > > > + found_version = tuple(map(int, version_string.split("."))) > > > + > > > + # `rust-analyzer --version` shows a different version string depending on how the binary > > > + # is built: it may print either the Rust version or the rust-analyzer version itself. > > > + # To distinguish between them, we leverage rust-analyzer's versioning convention. > > > + # > > > + # See: > > > + # - https://github.com/rust-lang/rust-analyzer/blob/fad5c3d2d642/xtask/src/dist.rs#L19-L21 > > > + is_ra_version = version_string.startswith(("0.3", "0.4", "0.5")) > > > + if is_ra_version: > > > + for info in baselines: > > > + if found_version >= info.ra_version: > > > + return info > > > + else: > > > + for info in baselines: > > > + if found_version >= info.rust_version: > > > + return info > > > + > > > + 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") > > > > datetime.strptime throws ValueError on invalid input; perhaps we can > > catch that instead of using a regex match. > > I think we still need to use regex to extract the date substring, right? > Since `ra_version_output` is the uncleaned CLI output, `date.strptime` > would always fail if passed the whole string. Ah yes, good point. ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v5 2/2] scripts: generate_rust_analyzer.py: fix IDE support for primitive types 2026-04-30 12:15 [PATCH v5 0/2] rust: take advantage of newer rust-analyzer features Jesung Yang via B4 Relay 2026-04-30 12:15 ` [PATCH v5 1/2] scripts: generate_rust_analyzer.py: add versioning infrastructure Jesung Yang via B4 Relay @ 2026-04-30 12:15 ` Jesung Yang via B4 Relay 2026-04-30 14:18 ` Tamir Duberstein 1 sibling, 1 reply; 12+ messages in thread From: Jesung Yang via B4 Relay @ 2026-04-30 12:15 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: Eliot Courtney, 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 | 107 ++++++++++++++++++++++++++++++-------- 1 file changed, 86 insertions(+), 21 deletions(-) diff --git a/scripts/generate_rust_analyzer.py b/scripts/generate_rust_analyzer.py index f1828620bbbf..f335cbd30fcf 100755 --- a/scripts/generate_rust_analyzer.py +++ b/scripts/generate_rust_analyzer.py @@ -4,6 +4,7 @@ """ import argparse +from dataclasses import dataclass from datetime import datetime, date import enum import re @@ -39,14 +40,28 @@ class Source(TypedDict): exclude_dirs: List[str] -class Crate(TypedDict): - display_name: str - root_module: str - is_workspace_member: bool - deps: List[Dependency] - cfg: List[str] - edition: str - env: Dict[str, str] +# TODO: clean up once Python 3.11 is adopted. +if sys.version_info < (3, 11): + class Crate(TypedDict, total=False): + display_name: str + root_module: str + is_workspace_member: bool + deps: List[Dependency] + cfg: List[str] + crate_attrs: List[str] + edition: str + env: Dict[str, str] +else: + from typing import NotRequired + class Crate(TypedDict): + display_name: str + root_module: str + is_workspace_member: bool + deps: List[Dependency] + cfg: List[str] + crate_attrs: NotRequired[List[str]] + edition: str + env: Dict[str, str] class ProcMacroCrate(Crate): @@ -58,7 +73,14 @@ class CrateWithGenerated(Crate): source: Source +@dataclass(frozen=True) +class RaVersionCtx: + manual_sysroot_crates: bool + use_crate_attrs: bool + + def generate_crates( + ctx: RaVersionCtx, srctree: pathlib.Path, objtree: pathlib.Path, sysroot_src: pathlib.Path, @@ -84,22 +106,24 @@ def generate_crates( def build_crate( display_name: str, root_module: pathlib.Path, - deps: List[Dependency], + deps: List[Optional[Dependency]], *, cfg: Optional[List[str]], + crate_attrs: Optional[List[str]], is_workspace_member: Optional[bool], edition: Optional[str], ) -> Crate: + filtered_deps = [dep for dep in deps if dep is not None] cfg = cfg if cfg is not None else crates_cfgs.get(display_name, []) is_workspace_member = ( is_workspace_member if is_workspace_member is not None else True ) edition = edition if edition is not None else "2021" - return { + crate: Crate = { "display_name": display_name, "root_module": str(root_module), "is_workspace_member": is_workspace_member, - "deps": deps, + "deps": filtered_deps, "cfg": cfg, "edition": edition, "env": { @@ -107,10 +131,15 @@ def generate_crates( } } + if ctx.use_crate_attrs and crate_attrs is not None: + crate["crate_attrs"] = crate_attrs + + return crate + def append_proc_macro_crate( display_name: str, root_module: pathlib.Path, - deps: List[Dependency], + deps: List[Optional[Dependency]], *, cfg: Optional[List[str]] = None, is_workspace_member: Optional[bool] = None, @@ -121,6 +150,7 @@ def generate_crates( root_module, deps, cfg=cfg, + crate_attrs=None, is_workspace_member=is_workspace_member, edition=edition, ) @@ -148,9 +178,10 @@ def generate_crates( def append_crate( display_name: str, root_module: pathlib.Path, - deps: List[Dependency], + deps: List[Optional[Dependency]], *, cfg: Optional[List[str]] = None, + crate_attrs: Optional[List[str]] = None, is_workspace_member: Optional[bool] = None, edition: Optional[str] = None, ) -> Dependency: @@ -160,6 +191,7 @@ def generate_crates( root_module, deps, cfg=cfg, + crate_attrs=crate_attrs, is_workspace_member=is_workspace_member, edition=edition, ) @@ -167,10 +199,12 @@ def generate_crates( def append_sysroot_crate( display_name: str, - deps: List[Dependency], + deps: List[Optional[Dependency]], *, cfg: Optional[List[str]] = None, - ) -> Dependency: + ) -> Optional[Dependency]: + if not ctx.manual_sysroot_crates: + return None return append_crate( display_name, sysroot_src / display_name / "src" / "lib.rs", @@ -269,13 +303,14 @@ def generate_crates( def append_crate_with_generated( display_name: str, - deps: List[Dependency], + deps: List[Optional[Dependency]], ) -> Dependency: crate = build_crate( display_name, srctree / "rust"/ display_name / "lib.rs", deps, cfg=generated_cfg, + crate_attrs=None, is_workspace_member=True, edition=None, ) @@ -342,6 +377,7 @@ def generate_crates( path, [core, kernel, pin_init], cfg=generated_cfg, + crate_attrs=["no_std"], ) return crates @@ -402,6 +438,20 @@ class RaVersionInfo(enum.Enum): datetime.strptime("2024-12-23", "%Y-%m-%d"), (0, 3, 2228), (1, 85, 0), + RaVersionCtx( + use_crate_attrs=False, + manual_sysroot_crates=True, + ), + ) + # v0.3.2727, released on 2025-12-22; v0.3.2743 is shipped with the rustup 1.94.0 toolchain. + SUPPROTS_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__( @@ -409,19 +459,30 @@ class RaVersionInfo(enum.Enum): 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 -class RustProject(TypedDict): - crates: List[Crate] - sysroot: str +# TODO: clean up once Python 3.11 is adopted. +if sys.version_info < (3, 11): + class RustProject(TypedDict, total=False): + crates: List[Crate] + sysroot: str + sysroot_src: str +else: + from typing import NotRequired + class RustProject(TypedDict): + crates: List[Crate] + sysroot: str + sysroot_src: NotRequired[str] def generate_rust_project( - _version_info: RaVersionInfo, + version_info: RaVersionInfo, srctree: pathlib.Path, objtree: pathlib.Path, sysroot: pathlib.Path, @@ -430,13 +491,17 @@ def generate_rust_project( cfgs: List[str], core_edition: str, ) -> RustProject: + ctx = version_info.ctx rust_project: RustProject = { "crates": generate_crates( - srctree, objtree, sysroot_src, external_src, cfgs, core_edition + ctx, srctree, objtree, sysroot_src, external_src, cfgs, core_edition ), "sysroot": str(sysroot), } + if not ctx.manual_sysroot_crates: + rust_project["sysroot_src"] = str(sysroot_src) + return rust_project def query_ra_version() -> Optional[str]: -- 2.53.0 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v5 2/2] scripts: generate_rust_analyzer.py: fix IDE support for primitive types 2026-04-30 12:15 ` [PATCH v5 2/2] scripts: generate_rust_analyzer.py: fix IDE support for primitive types Jesung Yang via B4 Relay @ 2026-04-30 14:18 ` Tamir Duberstein 0 siblings, 0 replies; 12+ messages in thread From: Tamir Duberstein @ 2026-04-30 14:18 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, Eliot Courtney, rust-for-linux, linux-kernel On Thu, Apr 30, 2026 at 8:15 AM Jesung Yang via B4 Relay <devnull+y.j3ms.n.gmail.com@kernel.org> wrote: > > 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 | 107 ++++++++++++++++++++++++++++++-------- > 1 file changed, 86 insertions(+), 21 deletions(-) > > diff --git a/scripts/generate_rust_analyzer.py b/scripts/generate_rust_analyzer.py > index f1828620bbbf..f335cbd30fcf 100755 > --- a/scripts/generate_rust_analyzer.py > +++ b/scripts/generate_rust_analyzer.py > @@ -4,6 +4,7 @@ > """ > > import argparse > +from dataclasses import dataclass > from datetime import datetime, date > import enum > import re > @@ -39,14 +40,28 @@ class Source(TypedDict): > exclude_dirs: List[str] > > > -class Crate(TypedDict): > - display_name: str > - root_module: str > - is_workspace_member: bool > - deps: List[Dependency] > - cfg: List[str] > - edition: str > - env: Dict[str, str] > +# TODO: clean up once Python 3.11 is adopted. > +if sys.version_info < (3, 11): > + class Crate(TypedDict, total=False): > + display_name: str > + root_module: str > + is_workspace_member: bool > + deps: List[Dependency] > + cfg: List[str] > + crate_attrs: List[str] > + edition: str > + env: Dict[str, str] > +else: > + from typing import NotRequired > + class Crate(TypedDict): > + display_name: str > + root_module: str > + is_workspace_member: bool > + deps: List[Dependency] > + cfg: List[str] > + crate_attrs: NotRequired[List[str]] > + edition: str > + env: Dict[str, str] > > > class ProcMacroCrate(Crate): > @@ -58,7 +73,14 @@ class CrateWithGenerated(Crate): > source: Source > > > +@dataclass(frozen=True) > +class RaVersionCtx: > + manual_sysroot_crates: bool > + use_crate_attrs: bool > + > + > def generate_crates( > + ctx: RaVersionCtx, > srctree: pathlib.Path, > objtree: pathlib.Path, > sysroot_src: pathlib.Path, > @@ -84,22 +106,24 @@ def generate_crates( > def build_crate( > display_name: str, > root_module: pathlib.Path, > - deps: List[Dependency], > + deps: List[Optional[Dependency]], > *, > cfg: Optional[List[str]], > + crate_attrs: Optional[List[str]], > is_workspace_member: Optional[bool], > edition: Optional[str], > ) -> Crate: > + filtered_deps = [dep for dep in deps if dep is not None] > cfg = cfg if cfg is not None else crates_cfgs.get(display_name, []) > is_workspace_member = ( > is_workspace_member if is_workspace_member is not None else True > ) > edition = edition if edition is not None else "2021" > - return { > + crate: Crate = { > "display_name": display_name, > "root_module": str(root_module), > "is_workspace_member": is_workspace_member, > - "deps": deps, > + "deps": filtered_deps, > "cfg": cfg, > "edition": edition, > "env": { > @@ -107,10 +131,15 @@ def generate_crates( > } > } > > + if ctx.use_crate_attrs and crate_attrs is not None: > + crate["crate_attrs"] = crate_attrs > + > + return crate > + > def append_proc_macro_crate( > display_name: str, > root_module: pathlib.Path, > - deps: List[Dependency], > + deps: List[Optional[Dependency]], > *, > cfg: Optional[List[str]] = None, > is_workspace_member: Optional[bool] = None, > @@ -121,6 +150,7 @@ def generate_crates( > root_module, > deps, > cfg=cfg, > + crate_attrs=None, > is_workspace_member=is_workspace_member, > edition=edition, > ) > @@ -148,9 +178,10 @@ def generate_crates( > def append_crate( > display_name: str, > root_module: pathlib.Path, > - deps: List[Dependency], > + deps: List[Optional[Dependency]], > *, > cfg: Optional[List[str]] = None, > + crate_attrs: Optional[List[str]] = None, > is_workspace_member: Optional[bool] = None, > edition: Optional[str] = None, > ) -> Dependency: > @@ -160,6 +191,7 @@ def generate_crates( > root_module, > deps, > cfg=cfg, > + crate_attrs=crate_attrs, > is_workspace_member=is_workspace_member, > edition=edition, > ) > @@ -167,10 +199,12 @@ def generate_crates( > > def append_sysroot_crate( > display_name: str, > - deps: List[Dependency], > + deps: List[Optional[Dependency]], > *, > cfg: Optional[List[str]] = None, > - ) -> Dependency: > + ) -> Optional[Dependency]: > + if not ctx.manual_sysroot_crates: > + return None > return append_crate( > display_name, > sysroot_src / display_name / "src" / "lib.rs", > @@ -269,13 +303,14 @@ def generate_crates( > > def append_crate_with_generated( > display_name: str, > - deps: List[Dependency], > + deps: List[Optional[Dependency]], > ) -> Dependency: > crate = build_crate( > display_name, > srctree / "rust"/ display_name / "lib.rs", > deps, > cfg=generated_cfg, > + crate_attrs=None, > is_workspace_member=True, > edition=None, > ) > @@ -342,6 +377,7 @@ def generate_crates( > path, > [core, kernel, pin_init], > cfg=generated_cfg, > + crate_attrs=["no_std"], > ) > > return crates > @@ -402,6 +438,20 @@ class RaVersionInfo(enum.Enum): > datetime.strptime("2024-12-23", "%Y-%m-%d"), > (0, 3, 2228), > (1, 85, 0), > + RaVersionCtx( > + use_crate_attrs=False, > + manual_sysroot_crates=True, > + ), > + ) > + # v0.3.2727, released on 2025-12-22; v0.3.2743 is shipped with the rustup 1.94.0 toolchain. > + SUPPROTS_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__( > @@ -409,19 +459,30 @@ class RaVersionInfo(enum.Enum): > 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 > > > -class RustProject(TypedDict): > - crates: List[Crate] > - sysroot: str > +# TODO: clean up once Python 3.11 is adopted. > +if sys.version_info < (3, 11): > + class RustProject(TypedDict, total=False): > + crates: List[Crate] > + sysroot: str > + sysroot_src: str > +else: > + from typing import NotRequired > + class RustProject(TypedDict): > + crates: List[Crate] > + sysroot: str > + sysroot_src: NotRequired[str] > > > def generate_rust_project( > - _version_info: RaVersionInfo, > + version_info: RaVersionInfo, > srctree: pathlib.Path, > objtree: pathlib.Path, > sysroot: pathlib.Path, > @@ -430,13 +491,17 @@ def generate_rust_project( > cfgs: List[str], > core_edition: str, > ) -> RustProject: > + ctx = version_info.ctx > rust_project: RustProject = { > "crates": generate_crates( > - srctree, objtree, sysroot_src, external_src, cfgs, core_edition > + ctx, srctree, objtree, sysroot_src, external_src, cfgs, core_edition > ), > "sysroot": str(sysroot), > } > > + if not ctx.manual_sysroot_crates: > + rust_project["sysroot_src"] = str(sysroot_src) > + > return rust_project > > def query_ra_version() -> Optional[str]: > > -- > 2.53.0 > > Reviewed-by: Tamir Duberstein <tamird@kernel.org> ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2026-05-04 13:12 UTC | newest] Thread overview: 12+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-04-30 12:15 [PATCH v5 0/2] rust: take advantage of newer rust-analyzer features Jesung Yang via B4 Relay 2026-04-30 12:15 ` [PATCH v5 1/2] scripts: generate_rust_analyzer.py: add versioning infrastructure Jesung Yang via B4 Relay 2026-04-30 14:13 ` Tamir Duberstein 2026-05-01 14:27 ` Jesung Yang 2026-05-01 15:38 ` Tamir Duberstein 2026-05-02 6:25 ` Jesung Yang 2026-05-03 13:21 ` Tamir Duberstein 2026-05-04 13:11 ` Jesung Yang 2026-05-02 7:40 ` Jesung Yang 2026-05-03 13:22 ` Tamir Duberstein 2026-04-30 12:15 ` [PATCH v5 2/2] scripts: generate_rust_analyzer.py: fix IDE support for primitive types Jesung Yang via B4 Relay 2026-04-30 14:18 ` Tamir Duberstein
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox