rust: doctest: fix incorrect pattern in replacement
PATCH 1/2 rust: doctest: fix incorrect pattern in replacement
From: Gary Guo <[email protected]>
The -> Result<(), impl core::fmt::Debug> string is generated by rustdoc and by adding "::" into the string it no longer finds anything, and making the line useless. Remove the "::" in the pattern (but keep it in the replacement result).
--- scripts/rustdoc_test_builder.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
scripts/rustdoc_test_builder.rs +1 -1
@@ -49,7 +49,7 @@ fn main() {// Qualify `Result` to avoid the collision with our own `Result` coming from the prelude. let body = body.replace ( - &format! ("{rustdoc_function_name}() -> Result<(), impl ::core::fmt::Debug> {{" ), + &format! ("{rustdoc_function_name}() -> Result<(), impl core::fmt::Debug> {{" ), &format! ("{rustdoc_function_name}() -> ::core::result::Result<(), impl ::core::fmt::Debug> {{" ),
base-commit: abe651837cb394f76d738a7a747322fca3bf17ba
Signature · 1 line
2.54.0
PATCH 2/2 rust: doctest: trim function name for reproducbility
From: Gary Guo <[email protected]>
Currently rustdoc will generate function names like "_doctest_main__home_gary_Projects_linux_rust_kernel_io_rs_824_0" for a doctest located at rust/kernel/io.rs:824, when building with separate outdir using O=. This creates overlong symbol names and is also not reproducible.
Fix it by doing a custom remapping to trim it to something like _doctest_main_rust_kernel_io_rs_824_0.
--- scripts/rustdoc_test_builder.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)
scripts/rustdoc_test_builder.rs +9 -5
@@ -47,11 +47,18 @@ fn main() { }) .expect ("No test function found in `rustdoc`'s output." ); +// Figure out a smaller test name based on the generated function name. +let name = rustdoc_function_name.split_once ("_rust_kernel_" ).unwrap ().1 ; + +// The rustdoc function name can include the absolute path when building with `O=` which is +// undesireable and create overlong symbol names. Remap it to relative path. +let trimmed_function_name =format! ("_doctest_main_rust_kernel_{name}" ); +// Qualify `Result` to avoid the collision with our own `Result` coming from the prelude. let body = body.replace ( &format! ("{rustdoc_function_name}() -> Result<(), impl core::fmt::Debug> {{" ), &format! ( -"{rustdoc_function_name}() -> ::core::result::Result<(), impl ::core::fmt::Debug> {{" +"{trimmed_function_name}() -> ::core::result::Result<(), impl ::core::fmt::Debug> {{" ), );
@@ -62,12 +69,9 @@ fn main() {// We save the result in a variable so that the failed assertion message looks nicer. let body = body.replace ( &format! ("}} {rustdoc_function_name}().unwrap() }}" ), - &format! ("}} let test_return_value = {rustdoc_function_name}(); assert!(test_return_value.is_ok()); }}" ), + &format! ("}} let test_return_value = {trimmed_function_name}(); assert!(test_return_value.is_ok()); }}" ), ); -// Figure out a smaller test name based on the generated function name. -let name = rustdoc_function_name.split_once ("_rust_kernel_" ).unwrap ().1 ; -let path =format! ("rust/test/doctests/kernel/{name}" ); std::fs::write (path, body.as_bytes ()).unwrap ();
Signature · 1 line
2.54.0
David Gow
maintainerRe: [PATCH 2/2] rust: doctest: trim function name for reproducbility
Le 13/06/2026 à 10:04 PM, Gary Guo a écrit :
Quoted 8 lines
From: Gary Guo <[email protected]>
Currently rustdoc will generate function names like "
_doctest_main__home_gary_Projects_linux_rust_kernel_io_rs_824_0" for a doctest located atrust/kernel/io.rs:824, when building with separate outdir usingO=. This creates overlong symbol names and is also not reproducible.
Quoted 5 lines
Fix it by doing a custom remapping to trim it to something like
_doctest_main_rust_kernel_io_rs_824_0.Signed-off-by Gary Guo <[email protected]>---
Hi Gary,
This seems to break older versions of rustc. For example, with rust 1.93.1, the build now fails with errors like:
ERROR:root:error[E0425]: cannot find function _doctest_main_rust_kernel_alloc_allocator_rs_176_0 in this scope
--> rust/doctests_kernel_generated.rs:74:27
| 74 | } let test_return_value = _doctest_main_rust_kernel_alloc_allocator_rs_176_0(); assert!(test_return_value.is_ok()); } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope
Am I missing something? I'm using kunit.py to build:./tools/testing/kunit/kunit.py run --kconfig_add CONFIG_RUST=y rust_doctests_kernel
Seems to be working okay with 1.96, though.
Cheers,
-- David
Quoted 41 lines
scripts/rustdoc_test_builder.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)scripts/rustdoc_test_builder.rs +9
-5@@ -47,11 +47,18 @@ fn main() { }) .expect ("No test function found in `rustdoc`'s output." ); +// Figure out a smaller test name based on the generated function name. +let name = rustdoc_function_name.split_once ("_rust_kernel_" ).unwrap ().1 ; + +// The rustdoc function name can include the absolute path when building with `O=` which is +// undesireable and create overlong symbol names. Remap it to relative path. +let trimmed_function_name =format! ("_doctest_main_rust_kernel_{name}" ); +// Qualify `Result` to avoid the collision with our own `Result` coming from the prelude. let body = body.replace ( &format! ("{rustdoc_function_name}() -> Result<(), impl core::fmt::Debug> {{" ), &format! ( -"{rustdoc_function_name}() -> ::core::result::Result<(), impl ::core::fmt::Debug> {{" +"{trimmed_function_name}() -> ::core::result::Result<(), impl ::core::fmt::Debug> {{" ), );@@ -62,12 +69,9 @@ fn main() {// We save the result in a variable so that the failed assertion message looks nicer. let body = body.replace ( &format! ("}} {rustdoc_function_name}().unwrap() }}" ), - &format! ("}} let test_return_value = {rustdoc_function_name}(); assert!(test_return_value.is_ok()); }}" ), + &format! ("}} let test_return_value = {trimmed_function_name}(); assert!(test_return_value.is_ok()); }}" ), ); -// Figure out a smaller test name based on the generated function name. -let name = rustdoc_function_name.split_once ("_rust_kernel_" ).unwrap ().1 ; -let path =format! ("rust/test/doctests/kernel/{name}" ); std::fs::write (path, body.as_bytes ()).unwrap ();
Gary Guo
reviewerRe: [PATCH 2/2] rust: doctest: trim function name for reproducbility
Quoted 27 lines · David Gow
Le 13/06/2026 à 10:04 PM, Gary Guo a écrit :
Quoted 8 lines
From: Gary Guo <[email protected]>
Currently rustdoc will generate function names like "
_doctest_main__home_gary_Projects_linux_rust_kernel_io_rs_824_0" for a doctest located atrust/kernel/io.rs:824, when building with separate outdir usingO=. This creates overlong symbol names and is also not reproducible.Quoted 5 lines
Fix it by doing a custom remapping to trim it to something like
_doctest_main_rust_kernel_io_rs_824_0.Signed-off-by Gary Guo <[email protected]>---
Hi Gary,
This seems to break older versions of rustc. For example, with rust 1.93.1, the build now fails with errors like:
ERROR:root:error[E0425]: cannot find function
_doctest_main_rust_kernel_alloc_allocator_rs_176_0in this scope
-->rust/doctests_kernel_generated.rs:74:27| 74 | } let test_return_value = _doctest_main_rust_kernel_alloc_allocator_rs_176_0(); assert!(test_return_value.is_ok()); } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope
Quoted 4 lines
Am I missing something? I'm using
kunit.pyto build:./tools/testing/kunit/kunit.pyrun --kconfig_addCONFIG_RUST=yrust_doctests_kernelSeems to be working okay with 1.96, though.
It looks like upstream rustdoc is using fully qualified path from 1.87+, so the replacement doesn't find it anymore. Not sure why it works in 1.96, though.
Sashiko suggested doing a full text replacement which I think makes more sense anyway and would work for all versions (and also for unit-returning functions). Will do it for the next version.
Best,
Gary
Quoted 45 lines
Cheers,
-- DavidQuoted 41 lines
scripts/rustdoc_test_builder.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)scripts/rustdoc_test_builder.rs +9
-5@@ -47,11 +47,18 @@ fn main() { }) .expect ("No test function found in `rustdoc`'s output." ); +// Figure out a smaller test name based on the generated function name. +let name = rustdoc_function_name.split_once ("_rust_kernel_" ).unwrap ().1 ; + +// The rustdoc function name can include the absolute path when building with `O=` which is +// undesireable and create overlong symbol names. Remap it to relative path. +let trimmed_function_name =format! ("_doctest_main_rust_kernel_{name}" ); +// Qualify `Result` to avoid the collision with our own `Result` coming from the prelude. let body = body.replace ( &format! ("{rustdoc_function_name}() -> Result<(), impl core::fmt::Debug> {{" ), &format! ( -"{rustdoc_function_name}() -> ::core::result::Result<(), impl ::core::fmt::Debug> {{" +"{trimmed_function_name}() -> ::core::result::Result<(), impl ::core::fmt::Debug> {{" ), );@@ -62,12 +69,9 @@ fn main() {// We save the result in a variable so that the failed assertion message looks nicer. let body = body.replace ( &format! ("}} {rustdoc_function_name}().unwrap() }}" ), - &format! ("}} let test_return_value = {rustdoc_function_name}(); assert!(test_return_value.is_ok()); }}" ), + &format! ("}} let test_return_value = {trimmed_function_name}(); assert!(test_return_value.is_ok()); }}" ), ); -// Figure out a smaller test name based on the generated function name. -let name = rustdoc_function_name.split_once ("_rust_kernel_" ).unwrap ().1 ; -let path =format! ("rust/test/doctests/kernel/{name}" ); std::fs::write (path, body.as_bytes ()).unwrap ();