std: add safety comments · model-checking/verify-rust-std@d6fadf5 (original) (raw)
`@@ -50,6 +50,7 @@ unsafe impl Sync for Storage {}
`
50
50
``
51
51
`struct Value<T: 'static> {
`
52
52
`value: T,
`
``
53
`` +
// INVARIANT: if this value is stored under a TLS key, key
must be that key
.
``
53
54
`key: Key,
`
54
55
`}
`
55
56
``
`@@ -73,10 +74,14 @@ impl<T: 'static> Storage {
`
73
74
`// is not running) + it is coming from a trusted source (self).
`
74
75
`unsafe { &(*ptr).value }
`
75
76
`} else {
`
``
77
`+
// SAFETY: trivially correct.
`
76
78
`unsafe { Self::try_initialize(key, ptr, i, f) }
`
77
79
`}
`
78
80
`}
`
79
81
``
``
82
`+
/// # Safety
`
``
83
`` +
/// * key
must be the result of calling self.key.force()
``
``
84
`` +
/// * ptr
must be the current value associated with key
.
``
80
85
`unsafe fn try_initialize(
`
81
86
`key: Key,
`
82
87
`ptr: *mut Value,
`
`@@ -91,11 +96,16 @@ impl<T: 'static> Storage {
`
91
96
`let value = Box::new(Value { value: i.and_then(Option::take).unwrap_or_else(f), key });
`
92
97
`let ptr = Box::into_raw(value);
`
93
98
``
94
``
`-
let old = unsafe { get(key) as *mut Value };
`
95
``
`` -
// SAFETY: ptr
is a correct pointer that can be destroyed by the key destructor.
``
96
``
`-
unsafe {
`
``
99
`+
// SAFETY:
`
``
100
`` +
// * key came from a LazyKey
and is thus correct.
``
``
101
`` +
// * ptr
is a correct pointer that can be destroyed by the key destructor.
``
``
102
`+
// * the value is stored under the key that it contains.
`
``
103
`+
let old = unsafe {
`
``
104
`+
let old = get(key) as *mut Value;
`
97
105
`set(key, ptr as *mut u8);
`
98
``
`-
}
`
``
106
`+
old
`
``
107
`+
};
`
``
108
+
99
109
`if !old.is_null() {
`
100
110
`// If the variable was recursively initialized, drop the old value.
`
101
111
`` // SAFETY: We cannot be inside a LocalKey::with
scope, as the
``
`@@ -123,8 +133,10 @@ unsafe extern "C" fn destroy_value<T: 'static>(ptr: *mut u8) {
`
123
133
`abort_on_dtor_unwind(|| {
`
124
134
`let ptr = unsafe { Box::from_raw(ptr as *mut Value) };
`
125
135
`let key = ptr.key;
`
``
136
`` +
// SAFETY: key
is the TLS key ptr
was stored under.
``
126
137
`unsafe { set(key, ptr::without_provenance_mut(1)) };
`
127
138
`drop(ptr);
`
``
139
`` +
// SAFETY: key
is the TLS key ptr
was stored under.
``
128
140
`unsafe { set(key, ptr::null_mut()) };
`
129
141
`});
`
130
142
`}
`