mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-06-08 00:07:34 +09:00
rust: use absolute paths in macros referencing core and kernel
Macros and auto-generated code should use absolute paths, `::core::...` and `::kernel::...`, for core and kernel references. This prevents issues where user-defined modules named `core` or `kernel` could be picked up instead of the `core` or `kernel` crates. Thus clean some references up. Suggested-by: Benno Lossin <benno.lossin@proton.me> Closes: https://github.com/Rust-for-Linux/linux/issues/1150 Signed-off-by: Igor Korotin <igor.korotin.linux@gmail.com> Reviewed-by: Benno Lossin <lossin@kernel.org> Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Link: https://lore.kernel.org/r/20250519164615.3310844-1-igor.korotin.linux@gmail.com [ Applied `rustfmt`. Reworded slightly. - Miguel ] Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
This commit is contained in:
parent
977c4308ee
commit
de7cd3e4d6
11 changed files with 56 additions and 49 deletions
|
@ -17,7 +17,7 @@ macro_rules! alias {
|
||||||
|
|
||||||
// Check size compatibility with `core`.
|
// Check size compatibility with `core`.
|
||||||
const _: () = assert!(
|
const _: () = assert!(
|
||||||
core::mem::size_of::<$name>() == core::mem::size_of::<core::ffi::$name>()
|
::core::mem::size_of::<$name>() == ::core::mem::size_of::<::core::ffi::$name>()
|
||||||
);
|
);
|
||||||
)*}
|
)*}
|
||||||
}
|
}
|
||||||
|
|
|
@ -240,7 +240,7 @@ impl DeviceContext for Normal {}
|
||||||
macro_rules! dev_printk {
|
macro_rules! dev_printk {
|
||||||
($method:ident, $dev:expr, $($f:tt)*) => {
|
($method:ident, $dev:expr, $($f:tt)*) => {
|
||||||
{
|
{
|
||||||
($dev).$method(core::format_args!($($f)*));
|
($dev).$method(::core::format_args!($($f)*));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -159,7 +159,7 @@ macro_rules! module_device_table {
|
||||||
"_", line!(),
|
"_", line!(),
|
||||||
"_", stringify!($table_name))
|
"_", stringify!($table_name))
|
||||||
]
|
]
|
||||||
static $module_table_name: [core::mem::MaybeUninit<u8>; $table_name.raw_ids().size()] =
|
static $module_table_name: [::core::mem::MaybeUninit<u8>; $table_name.raw_ids().size()] =
|
||||||
unsafe { core::mem::transmute_copy($table_name.raw_ids()) };
|
unsafe { ::core::mem::transmute_copy($table_name.raw_ids()) };
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ macro_rules! kunit_assert {
|
||||||
}
|
}
|
||||||
|
|
||||||
static FILE: &'static $crate::str::CStr = $crate::c_str!($file);
|
static FILE: &'static $crate::str::CStr = $crate::c_str!($file);
|
||||||
static LINE: i32 = core::line!() as i32 - $diff;
|
static LINE: i32 = ::core::line!() as i32 - $diff;
|
||||||
static CONDITION: &'static $crate::str::CStr = $crate::c_str!(stringify!($condition));
|
static CONDITION: &'static $crate::str::CStr = $crate::c_str!(stringify!($condition));
|
||||||
|
|
||||||
// SAFETY: FFI call without safety requirements.
|
// SAFETY: FFI call without safety requirements.
|
||||||
|
@ -130,11 +130,11 @@ macro_rules! kunit_assert {
|
||||||
unsafe {
|
unsafe {
|
||||||
$crate::bindings::__kunit_do_failed_assertion(
|
$crate::bindings::__kunit_do_failed_assertion(
|
||||||
kunit_test,
|
kunit_test,
|
||||||
core::ptr::addr_of!(LOCATION.0),
|
::core::ptr::addr_of!(LOCATION.0),
|
||||||
$crate::bindings::kunit_assert_type_KUNIT_ASSERTION,
|
$crate::bindings::kunit_assert_type_KUNIT_ASSERTION,
|
||||||
core::ptr::addr_of!(ASSERTION.0.assert),
|
::core::ptr::addr_of!(ASSERTION.0.assert),
|
||||||
Some($crate::bindings::kunit_unary_assert_format),
|
Some($crate::bindings::kunit_unary_assert_format),
|
||||||
core::ptr::null(),
|
::core::ptr::null(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,6 @@
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! static_assert {
|
macro_rules! static_assert {
|
||||||
($condition:expr $(,$arg:literal)?) => {
|
($condition:expr $(,$arg:literal)?) => {
|
||||||
const _: () = core::assert!($condition $(,$arg)?);
|
const _: () = ::core::assert!($condition $(,$arg)?);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -595,7 +595,7 @@ mod tests {
|
||||||
|
|
||||||
macro_rules! format {
|
macro_rules! format {
|
||||||
($($f:tt)*) => ({
|
($($f:tt)*) => ({
|
||||||
&*String::from_fmt(kernel::fmt!($($f)*))
|
&*String::from_fmt(::kernel::fmt!($($f)*))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -944,5 +944,5 @@ impl fmt::Debug for CString {
|
||||||
/// A convenience alias for [`core::format_args`].
|
/// A convenience alias for [`core::format_args`].
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! fmt {
|
macro_rules! fmt {
|
||||||
($($f:tt)*) => ( core::format_args!($($f)*) )
|
($($f:tt)*) => ( ::core::format_args!($($f)*) )
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,28 +85,28 @@ pub(crate) fn kunit_tests(attr: TokenStream, ts: TokenStream) -> TokenStream {
|
||||||
// Looks like:
|
// Looks like:
|
||||||
//
|
//
|
||||||
// ```
|
// ```
|
||||||
// unsafe extern "C" fn kunit_rust_wrapper_foo(_test: *mut kernel::bindings::kunit) { foo(); }
|
// unsafe extern "C" fn kunit_rust_wrapper_foo(_test: *mut ::kernel::bindings::kunit) { foo(); }
|
||||||
// unsafe extern "C" fn kunit_rust_wrapper_bar(_test: *mut kernel::bindings::kunit) { bar(); }
|
// unsafe extern "C" fn kunit_rust_wrapper_bar(_test: *mut ::kernel::bindings::kunit) { bar(); }
|
||||||
//
|
//
|
||||||
// static mut TEST_CASES: [kernel::bindings::kunit_case; 3] = [
|
// static mut TEST_CASES: [::kernel::bindings::kunit_case; 3] = [
|
||||||
// kernel::kunit::kunit_case(kernel::c_str!("foo"), kunit_rust_wrapper_foo),
|
// ::kernel::kunit::kunit_case(::kernel::c_str!("foo"), kunit_rust_wrapper_foo),
|
||||||
// kernel::kunit::kunit_case(kernel::c_str!("bar"), kunit_rust_wrapper_bar),
|
// ::kernel::kunit::kunit_case(::kernel::c_str!("bar"), kunit_rust_wrapper_bar),
|
||||||
// kernel::kunit::kunit_case_null(),
|
// ::kernel::kunit::kunit_case_null(),
|
||||||
// ];
|
// ];
|
||||||
//
|
//
|
||||||
// kernel::kunit_unsafe_test_suite!(kunit_test_suit_name, TEST_CASES);
|
// ::kernel::kunit_unsafe_test_suite!(kunit_test_suit_name, TEST_CASES);
|
||||||
// ```
|
// ```
|
||||||
let mut kunit_macros = "".to_owned();
|
let mut kunit_macros = "".to_owned();
|
||||||
let mut test_cases = "".to_owned();
|
let mut test_cases = "".to_owned();
|
||||||
for test in &tests {
|
for test in &tests {
|
||||||
let kunit_wrapper_fn_name = format!("kunit_rust_wrapper_{test}");
|
let kunit_wrapper_fn_name = format!("kunit_rust_wrapper_{test}");
|
||||||
let kunit_wrapper = format!(
|
let kunit_wrapper = format!(
|
||||||
"unsafe extern \"C\" fn {kunit_wrapper_fn_name}(_test: *mut kernel::bindings::kunit) {{ {test}(); }}"
|
"unsafe extern \"C\" fn {kunit_wrapper_fn_name}(_test: *mut ::kernel::bindings::kunit) {{ {test}(); }}"
|
||||||
);
|
);
|
||||||
writeln!(kunit_macros, "{kunit_wrapper}").unwrap();
|
writeln!(kunit_macros, "{kunit_wrapper}").unwrap();
|
||||||
writeln!(
|
writeln!(
|
||||||
test_cases,
|
test_cases,
|
||||||
" kernel::kunit::kunit_case(kernel::c_str!(\"{test}\"), {kunit_wrapper_fn_name}),"
|
" ::kernel::kunit::kunit_case(::kernel::c_str!(\"{test}\"), {kunit_wrapper_fn_name}),"
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
@ -114,14 +114,14 @@ pub(crate) fn kunit_tests(attr: TokenStream, ts: TokenStream) -> TokenStream {
|
||||||
writeln!(kunit_macros).unwrap();
|
writeln!(kunit_macros).unwrap();
|
||||||
writeln!(
|
writeln!(
|
||||||
kunit_macros,
|
kunit_macros,
|
||||||
"static mut TEST_CASES: [kernel::bindings::kunit_case; {}] = [\n{test_cases} kernel::kunit::kunit_case_null(),\n];",
|
"static mut TEST_CASES: [::kernel::bindings::kunit_case; {}] = [\n{test_cases} ::kernel::kunit::kunit_case_null(),\n];",
|
||||||
tests.len() + 1
|
tests.len() + 1
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
writeln!(
|
writeln!(
|
||||||
kunit_macros,
|
kunit_macros,
|
||||||
"kernel::kunit_unsafe_test_suite!({attr}, TEST_CASES);"
|
"::kernel::kunit_unsafe_test_suite!({attr}, TEST_CASES);"
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
|
|
@ -283,7 +283,7 @@ pub fn concat_idents(ts: TokenStream) -> TokenStream {
|
||||||
/// # const binder_driver_return_protocol_BR_FAILED_REPLY: u32 = 14;
|
/// # const binder_driver_return_protocol_BR_FAILED_REPLY: u32 = 14;
|
||||||
/// macro_rules! pub_no_prefix {
|
/// macro_rules! pub_no_prefix {
|
||||||
/// ($prefix:ident, $($newname:ident),+) => {
|
/// ($prefix:ident, $($newname:ident),+) => {
|
||||||
/// kernel::macros::paste! {
|
/// ::kernel::macros::paste! {
|
||||||
/// $(pub(crate) const $newname: u32 = [<$prefix $newname>];)+
|
/// $(pub(crate) const $newname: u32 = [<$prefix $newname>];)+
|
||||||
/// }
|
/// }
|
||||||
/// };
|
/// };
|
||||||
|
@ -340,7 +340,7 @@ pub fn concat_idents(ts: TokenStream) -> TokenStream {
|
||||||
/// # const binder_driver_return_protocol_BR_FAILED_REPLY: u32 = 14;
|
/// # const binder_driver_return_protocol_BR_FAILED_REPLY: u32 = 14;
|
||||||
/// macro_rules! pub_no_prefix {
|
/// macro_rules! pub_no_prefix {
|
||||||
/// ($prefix:ident, $($newname:ident),+) => {
|
/// ($prefix:ident, $($newname:ident),+) => {
|
||||||
/// kernel::macros::paste! {
|
/// ::kernel::macros::paste! {
|
||||||
/// $(pub(crate) const fn [<$newname:lower:span>]() -> u32 { [<$prefix $newname:span>] })+
|
/// $(pub(crate) const fn [<$newname:lower:span>]() -> u32 { [<$prefix $newname:span>] })+
|
||||||
/// }
|
/// }
|
||||||
/// };
|
/// };
|
||||||
|
@ -375,7 +375,7 @@ pub fn concat_idents(ts: TokenStream) -> TokenStream {
|
||||||
/// ```
|
/// ```
|
||||||
/// macro_rules! create_numbered_fn {
|
/// macro_rules! create_numbered_fn {
|
||||||
/// ($name:literal, $val:literal) => {
|
/// ($name:literal, $val:literal) => {
|
||||||
/// kernel::macros::paste! {
|
/// ::kernel::macros::paste! {
|
||||||
/// fn [<some_ $name _fn $val>]() -> u32 { $val }
|
/// fn [<some_ $name _fn $val>]() -> u32 { $val }
|
||||||
/// }
|
/// }
|
||||||
/// };
|
/// };
|
||||||
|
|
|
@ -215,24 +215,24 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream {
|
||||||
// SAFETY: `__this_module` is constructed by the kernel at load time and will not be
|
// SAFETY: `__this_module` is constructed by the kernel at load time and will not be
|
||||||
// freed until the module is unloaded.
|
// freed until the module is unloaded.
|
||||||
#[cfg(MODULE)]
|
#[cfg(MODULE)]
|
||||||
static THIS_MODULE: kernel::ThisModule = unsafe {{
|
static THIS_MODULE: ::kernel::ThisModule = unsafe {{
|
||||||
extern \"C\" {{
|
extern \"C\" {{
|
||||||
static __this_module: kernel::types::Opaque<kernel::bindings::module>;
|
static __this_module: ::kernel::types::Opaque<::kernel::bindings::module>;
|
||||||
}}
|
}}
|
||||||
|
|
||||||
kernel::ThisModule::from_ptr(__this_module.get())
|
::kernel::ThisModule::from_ptr(__this_module.get())
|
||||||
}};
|
}};
|
||||||
#[cfg(not(MODULE))]
|
#[cfg(not(MODULE))]
|
||||||
static THIS_MODULE: kernel::ThisModule = unsafe {{
|
static THIS_MODULE: ::kernel::ThisModule = unsafe {{
|
||||||
kernel::ThisModule::from_ptr(core::ptr::null_mut())
|
::kernel::ThisModule::from_ptr(::core::ptr::null_mut())
|
||||||
}};
|
}};
|
||||||
|
|
||||||
/// The `LocalModule` type is the type of the module created by `module!`,
|
/// The `LocalModule` type is the type of the module created by `module!`,
|
||||||
/// `module_pci_driver!`, `module_platform_driver!`, etc.
|
/// `module_pci_driver!`, `module_platform_driver!`, etc.
|
||||||
type LocalModule = {type_};
|
type LocalModule = {type_};
|
||||||
|
|
||||||
impl kernel::ModuleMetadata for {type_} {{
|
impl ::kernel::ModuleMetadata for {type_} {{
|
||||||
const NAME: &'static kernel::str::CStr = kernel::c_str!(\"{name}\");
|
const NAME: &'static ::kernel::str::CStr = ::kernel::c_str!(\"{name}\");
|
||||||
}}
|
}}
|
||||||
|
|
||||||
// Double nested modules, since then nobody can access the public items inside.
|
// Double nested modules, since then nobody can access the public items inside.
|
||||||
|
@ -250,8 +250,8 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream {
|
||||||
#[used]
|
#[used]
|
||||||
static __IS_RUST_MODULE: () = ();
|
static __IS_RUST_MODULE: () = ();
|
||||||
|
|
||||||
static mut __MOD: core::mem::MaybeUninit<{type_}> =
|
static mut __MOD: ::core::mem::MaybeUninit<{type_}> =
|
||||||
core::mem::MaybeUninit::uninit();
|
::core::mem::MaybeUninit::uninit();
|
||||||
|
|
||||||
// Loadable modules need to export the `{{init,cleanup}}_module` identifiers.
|
// Loadable modules need to export the `{{init,cleanup}}_module` identifiers.
|
||||||
/// # Safety
|
/// # Safety
|
||||||
|
@ -262,7 +262,7 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream {
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
#[link_section = \".init.text\"]
|
#[link_section = \".init.text\"]
|
||||||
pub unsafe extern \"C\" fn init_module() -> kernel::ffi::c_int {{
|
pub unsafe extern \"C\" fn init_module() -> ::kernel::ffi::c_int {{
|
||||||
// SAFETY: This function is inaccessible to the outside due to the double
|
// SAFETY: This function is inaccessible to the outside due to the double
|
||||||
// module wrapping it. It is called exactly once by the C side via its
|
// module wrapping it. It is called exactly once by the C side via its
|
||||||
// unique name.
|
// unique name.
|
||||||
|
@ -302,11 +302,12 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream {
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[link_section = \"{initcall_section}\"]
|
#[link_section = \"{initcall_section}\"]
|
||||||
#[used]
|
#[used]
|
||||||
pub static __{name}_initcall: extern \"C\" fn() -> kernel::ffi::c_int = __{name}_init;
|
pub static __{name}_initcall: extern \"C\" fn() -> ::kernel::ffi::c_int =
|
||||||
|
__{name}_init;
|
||||||
|
|
||||||
#[cfg(not(MODULE))]
|
#[cfg(not(MODULE))]
|
||||||
#[cfg(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS)]
|
#[cfg(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS)]
|
||||||
core::arch::global_asm!(
|
::core::arch::global_asm!(
|
||||||
r#\".section \"{initcall_section}\", \"a\"
|
r#\".section \"{initcall_section}\", \"a\"
|
||||||
__{name}_initcall:
|
__{name}_initcall:
|
||||||
.long __{name}_init - .
|
.long __{name}_init - .
|
||||||
|
@ -317,7 +318,7 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream {
|
||||||
#[cfg(not(MODULE))]
|
#[cfg(not(MODULE))]
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern \"C\" fn __{name}_init() -> kernel::ffi::c_int {{
|
pub extern \"C\" fn __{name}_init() -> ::kernel::ffi::c_int {{
|
||||||
// SAFETY: This function is inaccessible to the outside due to the double
|
// SAFETY: This function is inaccessible to the outside due to the double
|
||||||
// module wrapping it. It is called exactly once by the C side via its
|
// module wrapping it. It is called exactly once by the C side via its
|
||||||
// placement above in the initcall section.
|
// placement above in the initcall section.
|
||||||
|
@ -340,9 +341,9 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream {
|
||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// This function must only be called once.
|
/// This function must only be called once.
|
||||||
unsafe fn __init() -> kernel::ffi::c_int {{
|
unsafe fn __init() -> ::kernel::ffi::c_int {{
|
||||||
let initer =
|
let initer =
|
||||||
<{type_} as kernel::InPlaceModule>::init(&super::super::THIS_MODULE);
|
<{type_} as ::kernel::InPlaceModule>::init(&super::super::THIS_MODULE);
|
||||||
// SAFETY: No data race, since `__MOD` can only be accessed by this module
|
// SAFETY: No data race, since `__MOD` can only be accessed by this module
|
||||||
// and there only `__init` and `__exit` access it. These functions are only
|
// and there only `__init` and `__exit` access it. These functions are only
|
||||||
// called once and `__exit` cannot be called before or during `__init`.
|
// called once and `__exit` cannot be called before or during `__init`.
|
||||||
|
|
|
@ -28,7 +28,7 @@ fn main() {
|
||||||
//
|
//
|
||||||
// ```
|
// ```
|
||||||
// fn main() { #[allow(non_snake_case)] fn _doctest_main_rust_kernel_file_rs_28_0() {
|
// fn main() { #[allow(non_snake_case)] fn _doctest_main_rust_kernel_file_rs_28_0() {
|
||||||
// fn main() { #[allow(non_snake_case)] fn _doctest_main_rust_kernel_file_rs_37_0() -> Result<(), impl core::fmt::Debug> {
|
// fn main() { #[allow(non_snake_case)] fn _doctest_main_rust_kernel_file_rs_37_0() -> Result<(), impl ::core::fmt::Debug> {
|
||||||
// ```
|
// ```
|
||||||
//
|
//
|
||||||
// It should be unlikely that doctest code matches such lines (when code is formatted properly).
|
// It should be unlikely that doctest code matches such lines (when code is formatted properly).
|
||||||
|
@ -49,8 +49,10 @@ fn main() {
|
||||||
|
|
||||||
// Qualify `Result` to avoid the collision with our own `Result` coming from the prelude.
|
// Qualify `Result` to avoid the collision with our own `Result` coming from the prelude.
|
||||||
let body = body.replace(
|
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> {{"),
|
&format!(
|
||||||
|
"{rustdoc_function_name}() -> ::core::result::Result<(), impl ::core::fmt::Debug> {{"
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
// For tests that get generated with `Result`, like above, `rustdoc` generates an `unwrap()` on
|
// For tests that get generated with `Result`, like above, `rustdoc` generates an `unwrap()` on
|
||||||
|
|
|
@ -167,12 +167,14 @@ fn main() {
|
||||||
rust_tests,
|
rust_tests,
|
||||||
r#"/// Generated `{name}` KUnit test case from a Rust documentation test.
|
r#"/// Generated `{name}` KUnit test case from a Rust documentation test.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn {kunit_name}(__kunit_test: *mut kernel::bindings::kunit) {{
|
pub extern "C" fn {kunit_name}(__kunit_test: *mut ::kernel::bindings::kunit) {{
|
||||||
/// Overrides the usual [`assert!`] macro with one that calls KUnit instead.
|
/// Overrides the usual [`assert!`] macro with one that calls KUnit instead.
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
macro_rules! assert {{
|
macro_rules! assert {{
|
||||||
($cond:expr $(,)?) => {{{{
|
($cond:expr $(,)?) => {{{{
|
||||||
kernel::kunit_assert!("{kunit_name}", "{real_path}", __DOCTEST_ANCHOR - {line}, $cond);
|
::kernel::kunit_assert!(
|
||||||
|
"{kunit_name}", "{real_path}", __DOCTEST_ANCHOR - {line}, $cond
|
||||||
|
);
|
||||||
}}}}
|
}}}}
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
@ -180,13 +182,15 @@ pub extern "C" fn {kunit_name}(__kunit_test: *mut kernel::bindings::kunit) {{
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
macro_rules! assert_eq {{
|
macro_rules! assert_eq {{
|
||||||
($left:expr, $right:expr $(,)?) => {{{{
|
($left:expr, $right:expr $(,)?) => {{{{
|
||||||
kernel::kunit_assert_eq!("{kunit_name}", "{real_path}", __DOCTEST_ANCHOR - {line}, $left, $right);
|
::kernel::kunit_assert_eq!(
|
||||||
|
"{kunit_name}", "{real_path}", __DOCTEST_ANCHOR - {line}, $left, $right
|
||||||
|
);
|
||||||
}}}}
|
}}}}
|
||||||
}}
|
}}
|
||||||
|
|
||||||
// Many tests need the prelude, so provide it by default.
|
// Many tests need the prelude, so provide it by default.
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
use kernel::prelude::*;
|
use ::kernel::prelude::*;
|
||||||
|
|
||||||
// Unconditionally print the location of the original doctest (i.e. rather than the location in
|
// Unconditionally print the location of the original doctest (i.e. rather than the location in
|
||||||
// the generated file) so that developers can easily map the test back to the source code.
|
// the generated file) so that developers can easily map the test back to the source code.
|
||||||
|
@ -197,11 +201,11 @@ pub extern "C" fn {kunit_name}(__kunit_test: *mut kernel::bindings::kunit) {{
|
||||||
// This follows the syntax for declaring test metadata in the proposed KTAP v2 spec, which may
|
// This follows the syntax for declaring test metadata in the proposed KTAP v2 spec, which may
|
||||||
// be used for the proposed KUnit test attributes API. Thus hopefully this will make migration
|
// be used for the proposed KUnit test attributes API. Thus hopefully this will make migration
|
||||||
// easier later on.
|
// easier later on.
|
||||||
kernel::kunit::info(format_args!(" # {kunit_name}.location: {real_path}:{line}\n"));
|
::kernel::kunit::info(format_args!(" # {kunit_name}.location: {real_path}:{line}\n"));
|
||||||
|
|
||||||
/// The anchor where the test code body starts.
|
/// The anchor where the test code body starts.
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
static __DOCTEST_ANCHOR: i32 = core::line!() as i32 + {body_offset} + 1;
|
static __DOCTEST_ANCHOR: i32 = ::core::line!() as i32 + {body_offset} + 1;
|
||||||
{{
|
{{
|
||||||
{body}
|
{body}
|
||||||
main();
|
main();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue