safety_tag/lib.rs
1pub mod invariants {
2 #![allow(private_interfaces, unused_variables, non_snake_case)]
3
4 pub trait SafetyProperty {
5 /// A tuple of SP arguments.
6 type Args: SafetyPropertyArg;
7
8 /// Single ident name of an SP.
9 fn name() -> &'static str;
10
11 /// Static string, or dynamic interpolated string based on tag arguments.
12 fn description(args: Self::Args) -> String;
13
14 /// Kani macros for the SP.
15 fn kani(args: Self::Args) -> Option<String> {
16 None
17 }
18 }
19
20 pub trait SafetyPropertyArg {
21 fn name() -> &'static str;
22 }
23
24 macro_rules! sp_arg {
25 ($name:ident) => {
26 enum $name {}
27 impl SafetyPropertyArg for $name {
28 fn name() -> &'static str { stringify!($name) }
29 }
30 };
31 ($( $name:ident)+ ) => {
32 $( sp_arg!{ $name } )+
33 }
34 }
35
36 sp_arg! { Pointer Type Len Num Allocator }
37
38 /// Official ptr safety doc: <https://doc.rust-lang.org/std/ptr/index.html#safety>.
39 ///
40 /// Formal: `Size(T, 0) || (!Size(T,0) && Deref(p, T, len) )`
41 ///
42 /// where
43 /// - [Size]
44 /// - [Deref]
45 ///
46 /// # Unsafe Function directly requiring this SP
47 ///
48 /// - [crate::foo]
49 pub fn ValidPtr(p: Pointer, T: Type, len: Len) {}
50
51 /// Formal: `sizeof(T) = c, c ∈ {num, unknown, any}`
52 ///
53 /// # Unsafe Function indirectly requiring this SP
54 ///
55 /// - [crate::foo]
56 pub fn Size(T: Type, c: Num) {}
57
58 /// Formal: `Deref(p, T, len) = Allocated(p, T, len, *) && InBound(p, T, len)`
59 ///
60 /// where
61 /// - [Allocated]
62 /// - [InBound]
63 ///
64 /// # Unsafe Function indirectly requiring this SP
65 ///
66 /// - [crate::foo]
67 pub fn Deref(p: Pointer, T: Type, len: Len) {}
68
69 /// Formal: `Allocated(p, T, len, A): ∀ i ∈ 0..sizeof(T)*len, allocator(p+i) = A`
70 ///
71 /// # Unsafe Function indirectly requiring this SP
72 ///
73 /// - [crate::foo]
74 pub fn Allocated(p: Pointer, T: Type, len: Len, A: Allocator) {}
75
76 /// Formal: `InBound(p, T, len): mem(p, p+ sizeof(T) * len) ∈ single allocated object`
77 ///
78 /// # Unsafe Function indirectly requiring this SP
79 ///
80 /// - [crate::foo]
81 pub fn InBound(p: Pointer, T: Type, len: Len) {}
82}
83
84#[cfg(doc)]
85use invariants::*;
86
87// #[safety { ValidPtr(ptr) }] expands to:
88/// # Safety
89///
90/// - [ValidPtr] : ptr must be [valid](https://doc.rust-lang.org/std/ptr/index.html#safety)
91pub unsafe fn foo(ptr: *const ()) {}