├── .gitignore ├── .rustfmt.toml ├── Cargo.toml ├── README.md └── src └── lib.rs /.gitignore: -------------------------------------------------------------------------------- 1 | *db 2 | *conf 3 | *snap.* 4 | *grind.out* 5 | vgcore* 6 | *.bk 7 | *orig 8 | tags 9 | perf* 10 | *folded 11 | *out 12 | *perf 13 | *svg 14 | *txt 15 | experiments 16 | target 17 | Cargo.lock 18 | *swp 19 | *swo 20 | *.proptest-regressions 21 | corpus 22 | artifacts 23 | .idea 24 | cargo-timing* 25 | -------------------------------------------------------------------------------- /.rustfmt.toml: -------------------------------------------------------------------------------- 1 | version = "Two" 2 | use_small_heuristics = "Max" 3 | reorder_imports = true 4 | max_width = 80 5 | wrap_comments = true 6 | combine_control_expr = true 7 | report_todo = "Always" 8 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "assert_panic_free" 3 | version = "1.0.2" 4 | authors = ["Tyler Neely "] 5 | description = "Assert that some code is panic-free. Fast to compile, no syn or macros etc..." 6 | license = "MIT/Apache-2.0" 7 | homepage = "https://github.com/spacejam/assert_panic_free" 8 | repository = "https://github.com/spacejam/assert_panic_free" 9 | keywords = ["panic", "debugging", "safety", "correctness", "nostd"] 10 | categories = ["no-std", "development-tools", "development-tools::testing"] 11 | documentation = "https://docs.rs/assert_panic_free/" 12 | edition = "2018" 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # assert_panic_free 2 | 3 | A lightweight higher-order-function that doesn't compile 4 | if a function you pass to it might panic. This probably 5 | wont' work unless you're compiling your code with optimizations 6 | enabled. 7 | 8 | # Example 9 | 10 | works when built with optimizations / release: 11 | 12 | ```no_build 13 | assert_panic_free::assert_panic_free(|| 32); 14 | ``` 15 | 16 | doesn't work: 17 | 18 | ```compile_fail 19 | assert_panic_free(|| panic!(":(")); 20 | ``` 21 | 22 | Inspired by [no_panic](https://github.com/dtolnay/no-panic) and [panic_never](https://github.com/japaric/panic-never) but I wanted something that allowed for fine-grained panic reduction (like no_panic) but also something that compiled fast (like panic_never). 23 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | #![no_std] 2 | 3 | struct NoPanic; 4 | 5 | extern "C" { 6 | #[link_name = "\n\nHEY! ACTUAL ERROR DOWN HERE!!! (sorry for that big mess up there) \ 7 | the compiler was unable to prove that some code passed to assert_panic_free is \ 8 | actually panic-free. Please ensure that optimizations are enabled."] 9 | fn trigger() -> !; 10 | } 11 | 12 | impl Drop for NoPanic { 13 | fn drop(&mut self) { 14 | unsafe { 15 | trigger(); 16 | } 17 | } 18 | } 19 | 20 | /// A lightweight higher-order-function that doesn't compile 21 | /// if a function you pass to it might panic. This probably 22 | /// wont' work unless you're compiling your code with optimizations 23 | /// enabled. 24 | /// 25 | /// # Example 26 | /// 27 | /// works when built with optimizations / release: 28 | /// 29 | /// ```no_build 30 | /// assert_panic_free::assert_panic_free(|| 32); 31 | /// ``` 32 | /// 33 | /// doesn't work: 34 | /// 35 | /// ```compile_fail 36 | /// assert_panic_free(|| panic!(":(")); 37 | /// ``` 38 | pub fn assert_panic_free R>(f: F) -> R { 39 | let guard = NoPanic; 40 | let result = f(); 41 | core::mem::forget(guard); 42 | result 43 | } 44 | --------------------------------------------------------------------------------