rust-for-linux.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/7] rust: generate_rust_analyzer.py: define host crates
@ 2025-03-20  0:07 Tamir Duberstein
  2025-03-20  0:07 ` [PATCH v3 1/7] scripts: generate_rust_analyzer.py: add missing whitespace Tamir Duberstein
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Tamir Duberstein @ 2025-03-20  0:07 UTC (permalink / raw)
  To: Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Danilo Krummrich, Boris-Chengbiao Zhou, Kees Cook,
	Fiona Behrens
  Cc: rust-for-linux, linux-kernel, Lukas Wirth, Tamir Duberstein

This series updates rust-project.json to differentiate between host and
target crates, where the former are used as dependencies of the `macros`
crate. Please see individual commit messages for details.

The first 3 commits contain mechanical formatting changes and are
optional. The series can be taken without them.

I avoided more significant formatting or changes where possible to
reduce the diff. Unfortunately `scripts/generate_rust_analyzer.py` is
not consistently formatted before nor after this series.

The 5th commit ("scripts: generate_rust_analyzer.py: use
str(pathlib.Path)") can also be considered optional. It removes an
inconsistency I noticed while working on this series and which occurs on
a line which churns in this series anyway.

Signed-off-by: Tamir Duberstein <tamird@gmail.com>
---
Changes in v3:
- Rebase on linux-next. This is needed to pick up all the conflicts from
  both rust-next and rust-fixes.
- Drop `uv` from `mypy` command. (Trevor Gross)
- Add `--python-version 3.8` to `mypy` command. (Trevor Gross)
- `from typings import ...` directly. (Trevor Gross)
- Extract `build_crate` and `register_crate` to avoid peeking into
  `crates[-1]`. (Trevor Gross)
- Link to v2: https://lore.kernel.org/r/20250311-rust-analyzer-host-v2-0-30220e116511@gmail.com

Changes in v2:
- Rebased on "rust: fix rust-analyzer configuration for generated files" [1]
  Link: https://lore.kernel.org/all/CANiq72nv7nQ+1BinCHe2qsvwdUb-y9t7x=RGSppi_n9TBXNHpw@mail.gmail.com/ [1]
- Link to v1: https://lore.kernel.org/r/20250209-rust-analyzer-host-v1-0-a2286a2a2fa3@gmail.com

---
Tamir Duberstein (7):
      scripts: generate_rust_analyzer.py: add missing whitespace
      scripts: generate_rust_analyzer.py: use double quotes
      scripts: generate_rust_analyzer.py: add trailing comma
      scripts: generate_rust_analyzer.py: add type hints
      scripts: generate_rust_analyzer.py: use str(pathlib.Path)
      scripts: generate_rust_analyzer.py: identify crates explicitly
      scripts: generate_rust_analyzer.py: define host crates

 scripts/generate_rust_analyzer.py | 210 ++++++++++++++++++++++++++------------
 1 file changed, 144 insertions(+), 66 deletions(-)
---
base-commit: 57e79e4281c114dc06f6aaf3369d863025e706b4
change-id: 20250209-rust-analyzer-host-43b108655578

Best regards,
-- 
Tamir Duberstein <tamird@gmail.com>


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v3 1/7] scripts: generate_rust_analyzer.py: add missing whitespace
  2025-03-20  0:07 [PATCH v3 0/7] rust: generate_rust_analyzer.py: define host crates Tamir Duberstein
@ 2025-03-20  0:07 ` Tamir Duberstein
  2025-03-20  0:07 ` [PATCH v3 2/7] scripts: generate_rust_analyzer.py: use double quotes Tamir Duberstein
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Tamir Duberstein @ 2025-03-20  0:07 UTC (permalink / raw)
  To: Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Danilo Krummrich, Boris-Chengbiao Zhou, Kees Cook,
	Fiona Behrens
  Cc: rust-for-linux, linux-kernel, Lukas Wirth, Tamir Duberstein

Add a space before the `/` operator for consistency with surrounding
code and code formatting tools. Add a second newline between top-level
items in accordance with PEP 8[1]:

> Surround top-level function and class definitions with two blank
lines.

This change was made by a code formatting tool.

Link: https://peps.python.org/pep-0008/ [1]
Reviewed-by: Fiona Behrens <me@kloenk.dev>
Signed-off-by: Tamir Duberstein <tamird@gmail.com>
---
 scripts/generate_rust_analyzer.py | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/scripts/generate_rust_analyzer.py b/scripts/generate_rust_analyzer.py
index a0e5a0aef444..fc1788764b31 100755
--- a/scripts/generate_rust_analyzer.py
+++ b/scripts/generate_rust_analyzer.py
@@ -118,7 +118,7 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs):
     ):
         append_crate(
             display_name,
-            srctree / "rust"/ display_name / "lib.rs",
+            srctree / "rust" / display_name / "lib.rs",
             deps,
             cfg=cfg,
         )
@@ -193,5 +193,6 @@ def main():
 
     json.dump(rust_project, sys.stdout, sort_keys=True, indent=4)
 
+
 if __name__ == "__main__":
     main()

-- 
2.48.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v3 2/7] scripts: generate_rust_analyzer.py: use double quotes
  2025-03-20  0:07 [PATCH v3 0/7] rust: generate_rust_analyzer.py: define host crates Tamir Duberstein
  2025-03-20  0:07 ` [PATCH v3 1/7] scripts: generate_rust_analyzer.py: add missing whitespace Tamir Duberstein
@ 2025-03-20  0:07 ` Tamir Duberstein
  2025-03-20  0:07 ` [PATCH v3 3/7] scripts: generate_rust_analyzer.py: add trailing comma Tamir Duberstein
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Tamir Duberstein @ 2025-03-20  0:07 UTC (permalink / raw)
  To: Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Danilo Krummrich, Boris-Chengbiao Zhou, Kees Cook,
	Fiona Behrens
  Cc: rust-for-linux, linux-kernel, Lukas Wirth, Tamir Duberstein

Replace inconsistent use of single quotes with double quotes.

This change was made by a code formatting tool.

Reviewed-by: Fiona Behrens <me@kloenk.dev>
Signed-off-by: Tamir Duberstein <tamird@gmail.com>
---
 scripts/generate_rust_analyzer.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/scripts/generate_rust_analyzer.py b/scripts/generate_rust_analyzer.py
index fc1788764b31..e2bc4a717f87 100755
--- a/scripts/generate_rust_analyzer.py
+++ b/scripts/generate_rust_analyzer.py
@@ -169,8 +169,8 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs):
 
 def main():
     parser = argparse.ArgumentParser()
-    parser.add_argument('--verbose', '-v', action='store_true')
-    parser.add_argument('--cfgs', action='append', default=[])
+    parser.add_argument("--verbose", "-v", action="store_true")
+    parser.add_argument("--cfgs", action="append", default=[])
     parser.add_argument("srctree", type=pathlib.Path)
     parser.add_argument("objtree", type=pathlib.Path)
     parser.add_argument("sysroot", type=pathlib.Path)

-- 
2.48.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v3 3/7] scripts: generate_rust_analyzer.py: add trailing comma
  2025-03-20  0:07 [PATCH v3 0/7] rust: generate_rust_analyzer.py: define host crates Tamir Duberstein
  2025-03-20  0:07 ` [PATCH v3 1/7] scripts: generate_rust_analyzer.py: add missing whitespace Tamir Duberstein
  2025-03-20  0:07 ` [PATCH v3 2/7] scripts: generate_rust_analyzer.py: use double quotes Tamir Duberstein
@ 2025-03-20  0:07 ` Tamir Duberstein
  2025-03-20  0:07 ` [PATCH v3 4/7] scripts: generate_rust_analyzer.py: add type hints Tamir Duberstein
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Tamir Duberstein @ 2025-03-20  0:07 UTC (permalink / raw)
  To: Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Danilo Krummrich, Boris-Chengbiao Zhou, Kees Cook,
	Fiona Behrens
  Cc: rust-for-linux, linux-kernel, Lukas Wirth, Tamir Duberstein

Add missing trailing comma on multi-line function call as suggested by
PEP-8:

> The pattern is to put each value (etc.) on a line by itself, always
> adding a trailing comma, and add the close parenthesis/bracket/brace
> on the next line.

This change was made by a code formatting tool.

Reviewed-by: Fiona Behrens <me@kloenk.dev>
Signed-off-by: Tamir Duberstein <tamird@gmail.com>
---
 scripts/generate_rust_analyzer.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scripts/generate_rust_analyzer.py b/scripts/generate_rust_analyzer.py
index e2bc4a717f87..e997d923268d 100755
--- a/scripts/generate_rust_analyzer.py
+++ b/scripts/generate_rust_analyzer.py
@@ -180,7 +180,7 @@ def main():
 
     logging.basicConfig(
         format="[%(asctime)s] [%(levelname)s] %(message)s",
-        level=logging.INFO if args.verbose else logging.WARNING
+        level=logging.INFO if args.verbose else logging.WARNING,
     )
 
     # Making sure that the `sysroot` and `sysroot_src` belong to the same toolchain.

-- 
2.48.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v3 4/7] scripts: generate_rust_analyzer.py: add type hints
  2025-03-20  0:07 [PATCH v3 0/7] rust: generate_rust_analyzer.py: define host crates Tamir Duberstein
                   ` (2 preceding siblings ...)
  2025-03-20  0:07 ` [PATCH v3 3/7] scripts: generate_rust_analyzer.py: add trailing comma Tamir Duberstein
@ 2025-03-20  0:07 ` Tamir Duberstein
  2025-03-20  0:07 ` [PATCH v3 5/7] scripts: generate_rust_analyzer.py: use str(pathlib.Path) Tamir Duberstein
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Tamir Duberstein @ 2025-03-20  0:07 UTC (permalink / raw)
  To: Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Danilo Krummrich, Boris-Chengbiao Zhou, Kees Cook,
	Fiona Behrens
  Cc: rust-for-linux, linux-kernel, Lukas Wirth, Tamir Duberstein

Python type hints allow static analysis tools like mypy to detect type
errors during development, improving the developer experience.

Python type hints have been present in the kernel since 2019 at the
latest; see commit 6ebf5866f2e8 ("kunit: tool: add Python wrappers for
running KUnit tests").

Run `mypy --strict scripts/generate_rust_analyzer.py --python-version
3.8` to verify. Note that `mypy` no longer supports python < 3.8.

This removes `"is_proc_macro": false` from `rust-project.json` in
exchange for stricter types. This field is interpreted as false if
absent[1] so this doesn't change the behavior of rust-analyzer.

Link: https://github.com/rust-lang/rust-analyzer/blob/8d01570b5e812a49daa1f08404269f6ea5dd73a1/crates/project-model/src/project_json.rs#L372-L373 [1]
Signed-off-by: Tamir Duberstein <tamird@gmail.com>
---
 scripts/generate_rust_analyzer.py | 165 ++++++++++++++++++++++++++++----------
 1 file changed, 121 insertions(+), 44 deletions(-)

diff --git a/scripts/generate_rust_analyzer.py b/scripts/generate_rust_analyzer.py
index e997d923268d..c6f8ed9a5bdb 100755
--- a/scripts/generate_rust_analyzer.py
+++ b/scripts/generate_rust_analyzer.py
@@ -10,8 +10,10 @@ import os
 import pathlib
 import subprocess
 import sys
+from typing import Dict, Iterable, List, Literal, Optional, TypedDict
 
-def args_crates_cfgs(cfgs):
+
+def args_crates_cfgs(cfgs: Iterable[str]) -> Dict[str, List[str]]:
     crates_cfgs = {}
     for cfg in cfgs:
         crate, vals = cfg.split("=", 1)
@@ -19,7 +21,45 @@ def args_crates_cfgs(cfgs):
 
     return crates_cfgs
 
-def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs):
+
+class Dependency(TypedDict):
+    crate: int
+    name: str
+
+
+class Source(TypedDict):
+    include_dirs: List[str]
+    exclude_dirs: List[str]
+
+
+class Crate(TypedDict):
+    display_name: str
+    root_module: str
+    is_workspace_member: bool
+    deps: List[Dependency]
+    cfg: List[str]
+    edition: Literal["2021"]
+    env: Dict[str, str]
+
+
+# `NotRequired` fields on `Crate` would be better but `NotRequired` was added in 3.11.
+class ProcMacroCrate(Crate):
+    is_proc_macro: Literal[True]
+    proc_macro_dylib_path: Optional[str]  # `pathlib.Path` is not JSON serializable.
+
+
+# `NotRequired` fields on `Crate` would be better but `NotRequired` was added in 3.11.
+class CrateWithGenerated(Crate):
+    source: Optional[Source]
+
+
+def generate_crates(
+    srctree: pathlib.Path,
+    objtree: pathlib.Path,
+    sysroot_src: pathlib.Path,
+    external_src: pathlib.Path,
+    cfgs: List[str],
+) -> List[Crate]:
     # Generate the configuration list.
     cfg = []
     with open(objtree / "include" / "generated" / "rustc_cfg") as fd:
@@ -31,43 +71,75 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs):
     # Now fill the crates list -- dependencies need to come first.
     #
     # Avoid O(n^2) iterations by keeping a map of indexes.
-    crates = []
-    crates_indexes = {}
+    crates: List[Crate] = []
+    crates_indexes: Dict[str, int] = {}
     crates_cfgs = args_crates_cfgs(cfgs)
 
-    def append_crate(display_name, root_module, deps, cfg=[], is_workspace_member=True, is_proc_macro=False):
-        crate = {
+    def register_crate(crate: Crate) -> None:
+        crates_indexes[crate["display_name"]] = len(crates)
+        crates.append(crate)
+
+    def build_crate(
+        display_name: str,
+        root_module: pathlib.Path,
+        deps: List[str],
+        cfg: List[str] = [],
+        is_workspace_member: bool = True,
+    ) -> Crate:
+        return {
             "display_name": display_name,
             "root_module": str(root_module),
             "is_workspace_member": is_workspace_member,
-            "is_proc_macro": is_proc_macro,
             "deps": [{"crate": crates_indexes[dep], "name": dep} for dep in deps],
             "cfg": cfg,
             "edition": "2021",
             "env": {
                 "RUST_MODFILE": "This is only for rust-analyzer"
-            }
+            },
         }
-        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", "-"],
-                stdin=subprocess.DEVNULL,
-            ).decode('utf-8').strip()
-            crate["proc_macro_dylib_path"] = f"{objtree}/rust/{proc_macro_dylib_name}"
-        crates_indexes[display_name] = len(crates)
-        crates.append(crate)
+
+    def append_crate(
+        display_name: str,
+        root_module: pathlib.Path,
+        deps: List[str],
+        cfg: List[str] = [],
+        is_workspace_member: bool = True,
+    ) -> None:
+        register_crate(
+            build_crate(display_name, root_module, deps, cfg, is_workspace_member)
+        )
+
+    def append_proc_macro_crate(
+        display_name: str,
+        root_module: pathlib.Path,
+        deps: List[str],
+        cfg: List[str] = [],
+    ) -> None:
+        crate = build_crate(display_name, root_module, deps, cfg)
+        proc_macro_dylib_name = subprocess.check_output(
+            [os.environ["RUSTC"], "--print", "file-names", "--crate-name", display_name, "--crate-type", "proc-macro", "-"],
+            stdin=subprocess.DEVNULL,
+        ).decode('utf-8').strip()
+        proc_macro_crate: ProcMacroCrate = {
+            **crate,
+            "is_proc_macro": True,
+            "proc_macro_dylib_path": f"{objtree}/rust/{proc_macro_dylib_name}",
+        }
+        register_crate(proc_macro_crate)
 
     def append_sysroot_crate(
-        display_name,
-        deps,
-        cfg=[],
-    ):
-        append_crate(
-            display_name,
-            sysroot_src / display_name / "src" / "lib.rs",
-            deps,
-            cfg,
-            is_workspace_member=False,
+        display_name: str,
+        deps: List[str],
+        cfg: List[str] = [],
+    ) -> None:
+        register_crate(
+            build_crate(
+                display_name,
+                sysroot_src / display_name / "src" / "lib.rs",
+                deps,
+                cfg,
+                is_workspace_member=False,
+            )
         )
 
     # NB: sysroot crates reexport items from one another so setting up our transitive dependencies
@@ -84,11 +156,10 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs):
         [],
     )
 
-    append_crate(
+    append_proc_macro_crate(
         "macros",
         srctree / "rust" / "macros" / "lib.rs",
         ["std", "proc_macro"],
-        is_proc_macro=True,
     )
 
     append_crate(
@@ -97,12 +168,11 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs):
         ["core", "compiler_builtins"],
     )
 
-    append_crate(
+    append_proc_macro_crate(
         "pin_init_internal",
         srctree / "rust" / "pin-init" / "internal" / "src" / "lib.rs",
         [],
         cfg=["kernel"],
-        is_proc_macro=True,
     )
 
     append_crate(
@@ -113,29 +183,33 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs):
     )
 
     def append_crate_with_generated(
-        display_name,
-        deps,
-    ):
-        append_crate(
+        display_name: str,
+        deps: List[str],
+    ) -> None:
+        crate = build_crate(
             display_name,
             srctree / "rust" / display_name / "lib.rs",
             deps,
             cfg=cfg,
         )
-        crates[-1]["env"]["OBJTREE"] = str(objtree.resolve(True))
-        crates[-1]["source"] = {
-            "include_dirs": [
-                str(srctree / "rust" / display_name),
-                str(objtree / "rust")
-            ],
-            "exclude_dirs": [],
+        crate["env"]["OBJTREE"] = str(objtree.resolve(True))
+        crate_with_generate: CrateWithGenerated = {
+            **crate,
+            "source": {
+                "include_dirs": [
+                    str(srctree / "rust" / display_name),
+                    str(objtree / "rust")
+                ],
+                "exclude_dirs": [],
+            }
         }
+        register_crate(crate_with_generate)
 
     append_crate_with_generated("bindings", ["core"])
     append_crate_with_generated("uapi", ["core"])
     append_crate_with_generated("kernel", ["core", "macros", "build_error", "bindings", "pin_init", "uapi"])
 
-    def is_root_crate(build_file, target):
+    def is_root_crate(build_file: pathlib.Path, target: str) -> bool:
         try:
             return f"{target}.o" in open(build_file).read()
         except FileNotFoundError:
@@ -144,7 +218,9 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs):
     # Then, the rest outside of `rust/`.
     #
     # We explicitly mention the top-level folders we want to cover.
-    extra_dirs = map(lambda dir: srctree / dir, ("samples", "drivers"))
+    extra_dirs: Iterable[pathlib.Path] = map(
+        lambda dir: srctree / dir, ("samples", "drivers")
+    )
     if external_src is not None:
         extra_dirs = [external_src]
     for folder in extra_dirs:
@@ -167,7 +243,8 @@ def generate_crates(srctree, objtree, sysroot_src, external_src, cfgs):
 
     return crates
 
-def main():
+
+def main() -> None:
     parser = argparse.ArgumentParser()
     parser.add_argument("--verbose", "-v", action="store_true")
     parser.add_argument("--cfgs", action="append", default=[])

-- 
2.48.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v3 5/7] scripts: generate_rust_analyzer.py: use str(pathlib.Path)
  2025-03-20  0:07 [PATCH v3 0/7] rust: generate_rust_analyzer.py: define host crates Tamir Duberstein
                   ` (3 preceding siblings ...)
  2025-03-20  0:07 ` [PATCH v3 4/7] scripts: generate_rust_analyzer.py: add type hints Tamir Duberstein
@ 2025-03-20  0:07 ` Tamir Duberstein
  2025-03-20  0:07 ` [PATCH v3 6/7] scripts: generate_rust_analyzer.py: identify crates explicitly Tamir Duberstein
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Tamir Duberstein @ 2025-03-20  0:07 UTC (permalink / raw)
  To: Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Danilo Krummrich, Boris-Chengbiao Zhou, Kees Cook,
	Fiona Behrens
  Cc: rust-for-linux, linux-kernel, Lukas Wirth, Tamir Duberstein

Use the `/` operator on `pathlib.Path` rather than directly crafting a
string. This is consistent with all other path manipulation in this
script.

Reviewed-by: Fiona Behrens <me@kloenk.dev>
Signed-off-by: Tamir Duberstein <tamird@gmail.com>
---
 scripts/generate_rust_analyzer.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scripts/generate_rust_analyzer.py b/scripts/generate_rust_analyzer.py
index c6f8ed9a5bdb..21224fc9be8f 100755
--- a/scripts/generate_rust_analyzer.py
+++ b/scripts/generate_rust_analyzer.py
@@ -123,7 +123,7 @@ def generate_crates(
         proc_macro_crate: ProcMacroCrate = {
             **crate,
             "is_proc_macro": True,
-            "proc_macro_dylib_path": f"{objtree}/rust/{proc_macro_dylib_name}",
+            "proc_macro_dylib_path": str(objtree / "rust" / proc_macro_dylib_name),
         }
         register_crate(proc_macro_crate)
 

-- 
2.48.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v3 6/7] scripts: generate_rust_analyzer.py: identify crates explicitly
  2025-03-20  0:07 [PATCH v3 0/7] rust: generate_rust_analyzer.py: define host crates Tamir Duberstein
                   ` (4 preceding siblings ...)
  2025-03-20  0:07 ` [PATCH v3 5/7] scripts: generate_rust_analyzer.py: use str(pathlib.Path) Tamir Duberstein
@ 2025-03-20  0:07 ` Tamir Duberstein
  2025-03-20  0:07 ` [PATCH v3 7/7] scripts: generate_rust_analyzer.py: define host crates Tamir Duberstein
  2025-03-21  9:41 ` [PATCH v3 0/7] rust: " Tamir Duberstein
  7 siblings, 0 replies; 9+ messages in thread
From: Tamir Duberstein @ 2025-03-20  0:07 UTC (permalink / raw)
  To: Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Danilo Krummrich, Boris-Chengbiao Zhou, Kees Cook,
	Fiona Behrens
  Cc: rust-for-linux, linux-kernel, Lukas Wirth, Tamir Duberstein

Use the return of `append_crate` to declare dependency on that crate.
This allows multiple crates with the same display_name be defined, which
we'll use to define host crates separately from target crates.

Reviewed-by: Fiona Behrens <me@kloenk.dev>
Signed-off-by: Tamir Duberstein <tamird@gmail.com>
---
 scripts/generate_rust_analyzer.py | 70 +++++++++++++++++++--------------------
 1 file changed, 34 insertions(+), 36 deletions(-)

diff --git a/scripts/generate_rust_analyzer.py b/scripts/generate_rust_analyzer.py
index 21224fc9be8f..adba72eb1910 100755
--- a/scripts/generate_rust_analyzer.py
+++ b/scripts/generate_rust_analyzer.py
@@ -68,21 +68,19 @@ def generate_crates(
             line = line.replace("\n", "")
             cfg.append(line)
 
-    # Now fill the crates list -- dependencies need to come first.
-    #
-    # Avoid O(n^2) iterations by keeping a map of indexes.
+    # Now fill the crates list.
     crates: List[Crate] = []
-    crates_indexes: Dict[str, int] = {}
     crates_cfgs = args_crates_cfgs(cfgs)
 
-    def register_crate(crate: Crate) -> None:
-        crates_indexes[crate["display_name"]] = len(crates)
+    def register_crate(crate: Crate) -> Dependency:
+        index = len(crates)
         crates.append(crate)
+        return {"crate": index, "name": crate["display_name"]}
 
     def build_crate(
         display_name: str,
         root_module: pathlib.Path,
-        deps: List[str],
+        deps: List[Dependency],
         cfg: List[str] = [],
         is_workspace_member: bool = True,
     ) -> Crate:
@@ -90,7 +88,7 @@ def generate_crates(
             "display_name": display_name,
             "root_module": str(root_module),
             "is_workspace_member": is_workspace_member,
-            "deps": [{"crate": crates_indexes[dep], "name": dep} for dep in deps],
+            "deps": deps,
             "cfg": cfg,
             "edition": "2021",
             "env": {
@@ -101,20 +99,20 @@ def generate_crates(
     def append_crate(
         display_name: str,
         root_module: pathlib.Path,
-        deps: List[str],
+        deps: List[Dependency],
         cfg: List[str] = [],
         is_workspace_member: bool = True,
-    ) -> None:
-        register_crate(
+    ) -> Dependency:
+        return register_crate(
             build_crate(display_name, root_module, deps, cfg, is_workspace_member)
         )
 
     def append_proc_macro_crate(
         display_name: str,
         root_module: pathlib.Path,
-        deps: List[str],
+        deps: List[Dependency],
         cfg: List[str] = [],
-    ) -> None:
+    ) -> Dependency:
         crate = build_crate(display_name, root_module, deps, cfg)
         proc_macro_dylib_name = subprocess.check_output(
             [os.environ["RUSTC"], "--print", "file-names", "--crate-name", display_name, "--crate-type", "proc-macro", "-"],
@@ -125,14 +123,14 @@ def generate_crates(
             "is_proc_macro": True,
             "proc_macro_dylib_path": str(objtree / "rust" / proc_macro_dylib_name),
         }
-        register_crate(proc_macro_crate)
+        return register_crate(proc_macro_crate)
 
     def append_sysroot_crate(
         display_name: str,
-        deps: List[str],
+        deps: List[Dependency],
         cfg: List[str] = [],
-    ) -> None:
-        register_crate(
+    ) -> Dependency:
+        return register_crate(
             build_crate(
                 display_name,
                 sysroot_src / display_name / "src" / "lib.rs",
@@ -145,47 +143,47 @@ def generate_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", []))
-    append_sysroot_crate("alloc", ["core"])
-    append_sysroot_crate("std", ["alloc", "core"])
-    append_sysroot_crate("proc_macro", ["core", "std"])
+    core = append_sysroot_crate("core", [], cfg=crates_cfgs.get("core", []))
+    alloc = append_sysroot_crate("alloc", [core])
+    std = append_sysroot_crate("std", [alloc, core])
+    proc_macro = append_sysroot_crate("proc_macro", [core, std])
 
-    append_crate(
+    compiler_builtins = append_crate(
         "compiler_builtins",
         srctree / "rust" / "compiler_builtins.rs",
         [],
     )
 
-    append_proc_macro_crate(
+    macros = append_proc_macro_crate(
         "macros",
         srctree / "rust" / "macros" / "lib.rs",
-        ["std", "proc_macro"],
+        [std, proc_macro],
     )
 
-    append_crate(
+    build_error = append_crate(
         "build_error",
         srctree / "rust" / "build_error.rs",
-        ["core", "compiler_builtins"],
+        [core, compiler_builtins],
     )
 
-    append_proc_macro_crate(
+    pin_init_internal = append_proc_macro_crate(
         "pin_init_internal",
         srctree / "rust" / "pin-init" / "internal" / "src" / "lib.rs",
         [],
         cfg=["kernel"],
     )
 
-    append_crate(
+    pin_init = append_crate(
         "pin_init",
         srctree / "rust" / "pin-init" / "src" / "lib.rs",
-        ["core", "pin_init_internal", "macros"],
+        [core, pin_init_internal, macros],
         cfg=["kernel"],
     )
 
     def append_crate_with_generated(
         display_name: str,
-        deps: List[str],
-    ) -> None:
+        deps: List[Dependency],
+    ) -> Dependency:
         crate = build_crate(
             display_name,
             srctree / "rust" / display_name / "lib.rs",
@@ -203,11 +201,11 @@ def generate_crates(
                 "exclude_dirs": [],
             }
         }
-        register_crate(crate_with_generate)
+        return register_crate(crate_with_generate)
 
-    append_crate_with_generated("bindings", ["core"])
-    append_crate_with_generated("uapi", ["core"])
-    append_crate_with_generated("kernel", ["core", "macros", "build_error", "bindings", "pin_init", "uapi"])
+    bindings = append_crate_with_generated("bindings", [core])
+    uapi = append_crate_with_generated("uapi", [core])
+    kernel = append_crate_with_generated("kernel", [core, macros, build_error, bindings, pin_init, uapi])
 
     def is_root_crate(build_file: pathlib.Path, target: str) -> bool:
         try:
@@ -237,7 +235,7 @@ def generate_crates(
             append_crate(
                 name,
                 path,
-                ["core", "kernel"],
+                [core, kernel],
                 cfg=cfg,
             )
 

-- 
2.48.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v3 7/7] scripts: generate_rust_analyzer.py: define host crates
  2025-03-20  0:07 [PATCH v3 0/7] rust: generate_rust_analyzer.py: define host crates Tamir Duberstein
                   ` (5 preceding siblings ...)
  2025-03-20  0:07 ` [PATCH v3 6/7] scripts: generate_rust_analyzer.py: identify crates explicitly Tamir Duberstein
@ 2025-03-20  0:07 ` Tamir Duberstein
  2025-03-21  9:41 ` [PATCH v3 0/7] rust: " Tamir Duberstein
  7 siblings, 0 replies; 9+ messages in thread
From: Tamir Duberstein @ 2025-03-20  0:07 UTC (permalink / raw)
  To: Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Danilo Krummrich, Boris-Chengbiao Zhou, Kees Cook,
	Fiona Behrens
  Cc: rust-for-linux, linux-kernel, Lukas Wirth, Tamir Duberstein

Define host crates used by the `macros` crate separately from target
crates, now that we can uniquely identify crates with the same name.

This avoids rust-analyzer thinking the host `core` crate has our target
configs applied to it.

Suggested-by: Miguel Ojeda <ojeda@kernel.org>
Link: https://lore.kernel.org/all/CANiq72mw83RmLYeFFoJW6mUUygoyiA_f1ievSC2pmBESsQew+w@mail.gmail.com/
Reviewed-by: Fiona Behrens <me@kloenk.dev>
Signed-off-by: Tamir Duberstein <tamird@gmail.com>
---
 scripts/generate_rust_analyzer.py | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/scripts/generate_rust_analyzer.py b/scripts/generate_rust_analyzer.py
index adba72eb1910..cb497a492155 100755
--- a/scripts/generate_rust_analyzer.py
+++ b/scripts/generate_rust_analyzer.py
@@ -143,10 +143,12 @@ def generate_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)`.
+    host_core = append_sysroot_crate("core", [])
+    host_alloc = append_sysroot_crate("alloc", [host_core])
+    host_std = append_sysroot_crate("std", [host_alloc, host_core])
+    host_proc_macro = append_sysroot_crate("proc_macro", [host_core, host_std])
+
     core = append_sysroot_crate("core", [], cfg=crates_cfgs.get("core", []))
-    alloc = append_sysroot_crate("alloc", [core])
-    std = append_sysroot_crate("std", [alloc, core])
-    proc_macro = append_sysroot_crate("proc_macro", [core, std])
 
     compiler_builtins = append_crate(
         "compiler_builtins",
@@ -157,7 +159,7 @@ def generate_crates(
     macros = append_proc_macro_crate(
         "macros",
         srctree / "rust" / "macros" / "lib.rs",
-        [std, proc_macro],
+        [host_std, host_proc_macro],
     )
 
     build_error = append_crate(

-- 
2.48.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v3 0/7] rust: generate_rust_analyzer.py: define host crates
  2025-03-20  0:07 [PATCH v3 0/7] rust: generate_rust_analyzer.py: define host crates Tamir Duberstein
                   ` (6 preceding siblings ...)
  2025-03-20  0:07 ` [PATCH v3 7/7] scripts: generate_rust_analyzer.py: define host crates Tamir Duberstein
@ 2025-03-21  9:41 ` Tamir Duberstein
  7 siblings, 0 replies; 9+ messages in thread
From: Tamir Duberstein @ 2025-03-21  9:41 UTC (permalink / raw)
  To: Miguel Ojeda, Alex Gaynor, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Danilo Krummrich, Boris-Chengbiao Zhou, Kees Cook,
	Fiona Behrens
  Cc: rust-for-linux, linux-kernel, Lukas Wirth

On Wed, Mar 19, 2025 at 8:07 PM Tamir Duberstein <tamird@gmail.com> wrote:
>
> This series updates rust-project.json to differentiate between host and
> target crates, where the former are used as dependencies of the `macros`
> crate. Please see individual commit messages for details.
>
> The first 3 commits contain mechanical formatting changes and are
> optional. The series can be taken without them.
>
> I avoided more significant formatting or changes where possible to
> reduce the diff. Unfortunately `scripts/generate_rust_analyzer.py` is
> not consistently formatted before nor after this series.
>
> The 5th commit ("scripts: generate_rust_analyzer.py: use
> str(pathlib.Path)") can also be considered optional. It removes an
> inconsistency I noticed while working on this series and which occurs on
> a line which churns in this series anyway.
>
> Signed-off-by: Tamir Duberstein <tamird@gmail.com>
> ---
> Changes in v3:
> - Rebase on linux-next. This is needed to pick up all the conflicts from
>   both rust-next and rust-fixes.
> - Drop `uv` from `mypy` command. (Trevor Gross)
> - Add `--python-version 3.8` to `mypy` command. (Trevor Gross)
> - `from typings import ...` directly. (Trevor Gross)
> - Extract `build_crate` and `register_crate` to avoid peeking into
>   `crates[-1]`. (Trevor Gross)

I decided to put this in its own patch in v4, will respin later today.

> - Link to v2: https://lore.kernel.org/r/20250311-rust-analyzer-host-v2-0-30220e116511@gmail.com

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2025-03-21  9:42 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-03-20  0:07 [PATCH v3 0/7] rust: generate_rust_analyzer.py: define host crates Tamir Duberstein
2025-03-20  0:07 ` [PATCH v3 1/7] scripts: generate_rust_analyzer.py: add missing whitespace Tamir Duberstein
2025-03-20  0:07 ` [PATCH v3 2/7] scripts: generate_rust_analyzer.py: use double quotes Tamir Duberstein
2025-03-20  0:07 ` [PATCH v3 3/7] scripts: generate_rust_analyzer.py: add trailing comma Tamir Duberstein
2025-03-20  0:07 ` [PATCH v3 4/7] scripts: generate_rust_analyzer.py: add type hints Tamir Duberstein
2025-03-20  0:07 ` [PATCH v3 5/7] scripts: generate_rust_analyzer.py: use str(pathlib.Path) Tamir Duberstein
2025-03-20  0:07 ` [PATCH v3 6/7] scripts: generate_rust_analyzer.py: identify crates explicitly Tamir Duberstein
2025-03-20  0:07 ` [PATCH v3 7/7] scripts: generate_rust_analyzer.py: define host crates Tamir Duberstein
2025-03-21  9:41 ` [PATCH v3 0/7] rust: " Tamir Duberstein

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).