[PATCH v2] rust: doctest: add source map script
From: Gary Guo
Date: Thu Sep 03 2026 - 15:42:01 EST
Quite often when updating abstractions there will be some documentation
that needs updating, but the build process is not very developer friendly
as it just gives out something like
"rust/doctests_kernel_generated.rs:12345:42" and it is a hassle to find
where the documentation actually is.
Add a script as rustc wrapper, which translates the error message by
appending a "(generated from original_file:original_line:col)" message to
the original source info emitted by rustc.
This is the result of an example diagnostics:
error: test
--> rust/doctests_kernel_generated.rs:4490:1 (generated from rust/kernel/build_assert.rs:96:1)
|
4490 | compile_error!("test");
| ^^^^^^^^^^^^^^^^^^^^^^
Signed-off-by: Gary Guo <gary@xxxxxxxxxxx>
---
Changes in v2:
- Fixed SPDX header.
- Detect tty with stderr instead of stdout.
- Match doctest anchors more loosely without hardcoding i32.
- Link to v1: https://patch.msgid.link/20260612160523.3083792-1-gary@xxxxxxxxxx
---
rust/Makefile | 6 ++++
scripts/rustdoc_test_map_source.py | 73 ++++++++++++++++++++++++++++++++++++++
2 files changed, 79 insertions(+)
diff --git a/rust/Makefile b/rust/Makefile
index da1a7409d984..23f603d1356e 100644
--- a/rust/Makefile
+++ b/rust/Makefile
@@ -406,6 +406,12 @@ quiet_cmd_rustdoc_test_kernel = RUSTDOC TK $<
$(objtree)/scripts/rustdoc_test_gen FORCE
+$(call if_changed,rustdoc_test_kernel)
+# When building rustdoc tests, instead of using the actual RUSTC_OR_CLIPPY, use a wrapper to build
+# so we can convert line number in diagnostics.
+ACTUAL_RUSTC := $(RUSTC_OR_CLIPPY)
+%/doctests_kernel_generated.o: private RUSTC_OR_CLIPPY = \
+ PYTHONDONTWRITEBYTECODE=1 ACTUAL_RUSTC=$(ACTUAL_RUSTC) $(PYTHON3) $(srctree)/scripts/rustdoc_test_map_source.py
+
# We cannot use `-Zpanic-abort-tests` because some tests are dynamic,
# so for the moment we skip `-Cpanic=abort`.
quiet_cmd_rustc_test = $(RUSTC_OR_CLIPPY_QUIET) T $<
diff --git a/scripts/rustdoc_test_map_source.py b/scripts/rustdoc_test_map_source.py
new file mode 100644
index 000000000000..673021bedf4c
--- /dev/null
+++ b/scripts/rustdoc_test_map_source.py
@@ -0,0 +1,73 @@
+# SPDX-License-Identifier: GPL-2.0
+
+import sys
+import re
+import os
+import subprocess
+
+LOCATION_REGEX = re.compile(r"\.location: (.*):(\d+)")
+ANCHOR_REGEX = re.compile(r"static __DOCTEST_ANCHOR: .+ = .* \+ (\d+) \+ (\d+);")
+SOURCE_INFO_REGEX = re.compile(r"(rust/[\w/.-]+\.rs):(\d+):(\d+)")
+
+
+def transform(file, line):
+ with open(file, "r") as f:
+ lines = f.readlines()
+
+ line_idx = line - 1
+
+ # Find the last location and anchor before the erroring line
+ real_path = None
+ orig_line = None
+ anchor_line = None
+
+ for i in range(line_idx, -1, -1):
+ if real_path is None:
+ match = LOCATION_REGEX.search(lines[i])
+ if match:
+ real_path = match.group(1)
+ orig_line = int(match.group(2))
+
+ if anchor_line is None:
+ match = ANCHOR_REGEX.search(lines[i])
+ if match:
+ anchor_line = i + int(match.group(1)) + int(match.group(2))
+
+ if real_path is not None and anchor_line is not None:
+ break
+
+ new_line = orig_line + (line_idx - anchor_line)
+ return real_path, new_line
+
+
+def main():
+ actual_rustc = os.environ.get("ACTUAL_RUSTC")
+ args = sys.argv[1:]
+
+ # We redirected Rust output so it is not TTY anymore.
+ # Add `--color=always` back to preserve the color behaviour.
+ if sys.stderr.isatty() and not any(arg.startswith("--color") for arg in args):
+ args.append("--color=always")
+
+ result = subprocess.run([actual_rustc] + args, stderr=subprocess.PIPE, text=True)
+
+ def replacer(match):
+ orig = match.group(0)
+ file = match.group(1)
+ line = int(match.group(2))
+ col = int(match.group(3))
+
+ if file != "rust/doctests_kernel_generated.rs":
+ return orig
+
+ new_file, new_line = transform(file, line)
+ return f"{orig} (generated from {new_file}:{new_line}:{col})"
+
+ if result.stderr:
+ sys.stderr.write(SOURCE_INFO_REGEX.sub(replacer, result.stderr))
+
+ sys.exit(result.returncode)
+
+
+if __name__ == "__main__":
+ main()
---
base-commit: cee9395acd8043be0644b25c34bfa86623f2b935
change-id: 20260903-rustdoc-sourcemap-160f904fe78f
Best regards,
--
Gary Guo <gary@xxxxxxxxxxx>