Skip to content

Commit cec2f3f

Browse files
committed
Implement link-time panic and assertion
Signed-off-by: Gary Guo <[email protected]>
1 parent caa9a60 commit cec2f3f

File tree

3 files changed

+62
-1
lines changed

3 files changed

+62
-1
lines changed

rust/Makefile

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ rustdoc-compiler_builtins: $(srctree)/rust/compiler_builtins.rs FORCE
3232
$(call if_changed,rustdoc)
3333

3434
rustdoc-kernel: private rustdoc_target_flags = --extern alloc \
35+
--extern link_time_panic \
3536
--extern module=$(objtree)/rust/libmodule.so
3637
rustdoc-kernel: $(srctree)/rust/kernel/lib.rs rustdoc-module \
3738
$(objtree)/rust/libmodule.so $(objtree)/rust/bindings_generated.rs FORCE
@@ -147,9 +148,17 @@ $(objtree)/rust/alloc.o: $$(RUST_LIB_SRC)/alloc/src/lib.rs \
147148
$(objtree)/rust/compiler_builtins.o FORCE
148149
$(call if_changed_dep,rustc_library)
149150

151+
# link_time_panic.o is deliberately only compiled as a dependency but not
152+
# included in obj-y.
153+
$(objtree)/rust/link_time_panic.o: $(srctree)/rust/link_time_panic.rs \
154+
$(objtree)/rust/compiler_builtins.o FORCE
155+
$(call if_changed_dep,rustc_library)
156+
150157
# ICE on `--extern module`: https://github.com/rust-lang/rust/issues/56935
151158
$(objtree)/rust/kernel.o: private rustc_target_flags = --extern alloc \
159+
--extern link_time_panic \
152160
--extern module=$(objtree)/rust/libmodule.so
153161
$(objtree)/rust/kernel.o: $(srctree)/rust/kernel/lib.rs $(objtree)/rust/alloc.o \
162+
$(objtree)/rust/link_time_panic.o \
154163
$(objtree)/rust/libmodule.so $(objtree)/rust/bindings_generated.rs FORCE
155164
$(call if_changed_dep,rustc_library)

rust/link_time_panic.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
3+
//! Link-time panicking.
4+
//!
5+
//! In Rust it is very common to use assertions extensively and defensively.
6+
//! Sometimes we know a condition could be checked statically, but it could not
7+
//! be enforced in Rust (e.g. perform some checks in const functions, but those
8+
//! functions could still be called in the runtime).
9+
//!
10+
//! This crate provides a method `link_time_panic`, which will panic in
11+
//! compile-time if executed in const context, and will trigger a link error
12+
//! if not executed in compile time and optimizer does not optimise away the
13+
//! call.
14+
15+
#![no_std]
16+
#![feature(const_panic, core_panic)]
17+
18+
/// Panics if executed in const context, or triggers a link error if not.
19+
#[inline(never)]
20+
#[no_mangle]
21+
pub const fn link_time_panic(msg: &'static str) {
22+
// Could also be panic!(msg) to avoid using unstable feature `core_panic`,
23+
// but it is not allowed in Rust 2021, while panic!("{}", msg) could not
24+
// yet be used in const context.
25+
core::panicking::panic(msg);
26+
}
27+
28+
/// Asserts that a boolean expression is `true` at compile time.
29+
///
30+
/// This will invoke the [`link_time_panic`] function if the compiler or optimizer
31+
/// cannot guarantee the condition will be evaluated to `true`.
32+
#[macro_export]
33+
macro_rules! link_time_assert {
34+
($cond:expr $(,)?) => {{
35+
if !$cond {
36+
$crate::link_time_panic(concat!("assertion failed: ", stringify!($cond)));
37+
}
38+
}};
39+
($cond:expr, $msg:expr) => {{
40+
if !$cond {
41+
$crate::link_time_panic($msg);
42+
}
43+
}};
44+
}

scripts/generate_rust_analyzer.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,19 @@ def append_crate(display_name, root_module, is_workspace_member, deps, cfg):
7171
)
7272
crates[-1]["proc_macro_dylib_path"] = "rust/libmodule.so"
7373

74+
append_crate(
75+
"link_time_panic",
76+
srctree / "rust" / "link_time_panic.rs",
77+
True,
78+
["core", "compiler_builtins"],
79+
[],
80+
)
81+
7482
append_crate(
7583
"kernel",
7684
srctree / "rust" / "kernel" / "lib.rs",
7785
True,
78-
["core", "alloc", "module"],
86+
["core", "alloc", "module", "link_time_panic"],
7987
cfg,
8088
)
8189
crates[-1]["env"]["RUST_BINDINGS_FILE"] = str(bindings_file.resolve(True))

0 commit comments

Comments
 (0)