1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
//! A custom attribute for declaring why an `unsafe` block is correct.
//!
//! # Examples
//!
//! The most basic way this attribute can be used is by annotating an `unsafe`
//! block and providing a `reason` for why it is valid.
//!
//! ```rust
//! # #![feature(stmt_expr_attributes, proc_macro_hygiene)]
//! # use safe::safe;
//! let mut x: u32 = 42;
//! let x_ptr = &mut x as *mut u32;
//!
//! #[safe(reason = "This is the only reference to x")]
//! unsafe {
//! x_ptr.write(7);
//! }
//! ```
//!
//! Unsafe code often has constraints that must be valid before or after the
//! code is run.
//!
//! You can provide an assertion which will be executed with `debug_assert!()`
//! immediately before the block executes by adding a `requires = "..."` to
//! the attribute.
//!
//! ```rust
//! # #![feature(stmt_expr_attributes, proc_macro_hygiene)]
//! # use safe::safe;
//! let x: u32 = 42;
//! let x_ptr = &x as *const u32;
//!
//! #[safe(
//! reason = "The pointer points to a valid integer",
//! requires = "!x_ptr.is_null()"
//! )]
//! unsafe {
//! assert_eq!(42, x_ptr.read());
//! }
//! ```
//!
//! Likewise, for conditions which must be upheld after the `unsafe` block, you
//! can provide an `ensures` assertion.
//!
//! ```rust
//! # #![feature(stmt_expr_attributes, proc_macro_hygiene)]
//! # use safe::safe;
//! let mut allocated: *mut u32;
//!
//! #[safe(
//! reason = "Malloc will always return a non-null pointer unless there is an out-of-memory error",
//! ensures = "!allocated.is_null()"
//! )]
//! unsafe {
//! allocated = libc::malloc(std::mem::size_of::<u32>()) as *mut u32;
//! }
//! ```
//!
//! # Nightly Feature Flags
//!
//! Applying custom attributes to `unsafe` blocks currently requires two
//! `nightly` features:
//!
//! - `stmt_expr_attributes` - because `unsafe {}` is technically an expression
//! ([tracking issue](https://github.com/rust-lang/rust/issues/15701))
//! - `proc_macro_hygiene` - the result of expanding the `#[safe]` macro is an
//! expression which, in general (but not in our case), can result in possible
//! hygiene issues
//! ([tracking issue](https://github.com/rust-lang/rust/issues/54727))
extern crate proc_macro;
use FromMeta;
use TokenStream;
use quote;
use ;
/// A custom attribute for explaining why an `unsafe` block is valid and any
/// invariants which must be upheld.
///
/// See crate-level docs for example usage.