1//! Compiler intrinsics.
2//!
3//! The corresponding definitions are in <https://github.com/rust-lang/rust/blob/master/compiler/rustc_codegen_llvm/src/intrinsic.rs>.
4//! The corresponding const implementations are in <https://github.com/rust-lang/rust/blob/master/compiler/rustc_const_eval/src/interpret/intrinsics.rs>.
5//!
6//! # Const intrinsics
7//!
8//! Note: any changes to the constness of intrinsics should be discussed with the language team.
9//! This includes changes in the stability of the constness.
10//!
11//! In order to make an intrinsic usable at compile-time, one needs to copy the implementation
12//! from <https://github.com/rust-lang/miri/blob/master/src/shims/intrinsics> to
13//! <https://github.com/rust-lang/rust/blob/master/compiler/rustc_const_eval/src/interpret/intrinsics.rs> and add a
14//! `#[rustc_const_unstable(feature = "const_such_and_such", issue = "01234")]` to the intrinsic declaration.
15//!
16//! If an intrinsic is supposed to be used from a `const fn` with a `rustc_const_stable` attribute,
17//! the intrinsic's attribute must be `rustc_const_stable`, too. Such a change should not be done
18//! without T-lang consultation, because it bakes a feature into the language that cannot be
19//! replicated in user code without compiler support.
20//!
21//! # Volatiles
22//!
23//! The volatile intrinsics provide operations intended to act on I/O
24//! memory, which are guaranteed to not be reordered by the compiler
25//! across other volatile intrinsics. See the LLVM documentation on
26//! [[volatile]].
27//!
28//! [volatile]: https://llvm.org/docs/LangRef.html#volatile-memory-accesses
29//!
30//! # Atomics
31//!
32//! The atomic intrinsics provide common atomic operations on machine
33//! words, with multiple possible memory orderings. They obey the same
34//! semantics as C++11. See the LLVM documentation on [[atomics]].
35//!
36//! [atomics]: https://llvm.org/docs/Atomics.html
37//!
38//! A quick refresher on memory ordering:
39//!
40//! * Acquire - a barrier for acquiring a lock. Subsequent reads and writes
41//! take place after the barrier.
42//! * Release - a barrier for releasing a lock. Preceding reads and writes
43//! take place before the barrier.
44//! * Sequentially consistent - sequentially consistent operations are
45//! guaranteed to happen in order. This is the standard mode for working
46//! with atomic types and is equivalent to Java's `volatile`.
47
48#![unstable(
49 feature = "core_intrinsics",
50 reason = "intrinsics are unlikely to ever be stabilized, instead \
51 they should be used through stabilized interfaces \
52 in the rest of the standard library",
53 issue = "none"
54)]
55#![allow(missing_docs)]
56
57use crate::marker::DiscriminantKind;
58use crate::marker::Tuple;
59use crate::mem;
60
61pub mod mir;
62pub mod simd;
63
64// These imports are used for simplifying intra-doc links
65#[allow(unused_imports)]
66#[cfg(all(target_has_atomic = "8", target_has_atomic = "32", target_has_atomic = "ptr"))]
67use crate::sync::atomic::{self, AtomicBool, AtomicI32, AtomicIsize, AtomicU32, Ordering};
68
69#[stable(feature = "drop_in_place", since = "1.8.0")]
70#[rustc_allowed_through_unstable_modules]
71#[deprecated(note = "no longer an intrinsic - use `ptr::drop_in_place` directly", since = "1.52.0")]
72#[inline]
73pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
74 // SAFETY: see `ptr::drop_in_place`
75 unsafe { crate::ptr::drop_in_place(to_drop) }
76}
77
78extern "rust-intrinsic" {
79 // N.B., these intrinsics take raw pointers because they mutate aliased
80 // memory, which is not valid for either `&` or `&mut`.
81
82 /// Stores a value if the current value is the same as the `old` value.
83 ///
84 /// The stabilized version of this intrinsic is available on the
85 /// [`atomic`] types via the `compare_exchange` method by passing
86 /// [`Ordering::Relaxed`] as both the success and failure parameters.
87 /// For example, [`AtomicBool::compare_exchange`].
88 #[rustc_nounwind]
89 pub fn atomic_cxchg_relaxed_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
90 /// Stores a value if the current value is the same as the `old` value.
91 ///
92 /// The stabilized version of this intrinsic is available on the
93 /// [`atomic`] types via the `compare_exchange` method by passing
94 /// [`Ordering::Relaxed`] and [`Ordering::Acquire`] as the success and failure parameters.
95 /// For example, [`AtomicBool::compare_exchange`].
96 #[rustc_nounwind]
97 pub fn atomic_cxchg_relaxed_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
98 /// Stores a value if the current value is the same as the `old` value.
99 ///
100 /// The stabilized version of this intrinsic is available on the
101 /// [`atomic`] types via the `compare_exchange` method by passing
102 /// [`Ordering::Relaxed`] and [`Ordering::SeqCst`] as the success and failure parameters.
103 /// For example, [`AtomicBool::compare_exchange`].
104 #[rustc_nounwind]
105 pub fn atomic_cxchg_relaxed_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
106 /// Stores a value if the current value is the same as the `old` value.
107 ///
108 /// The stabilized version of this intrinsic is available on the
109 /// [`atomic`] types via the `compare_exchange` method by passing
110 /// [`Ordering::Acquire`] and [`Ordering::Relaxed`] as the success and failure parameters.
111 /// For example, [`AtomicBool::compare_exchange`].
112 #[rustc_nounwind]
113 pub fn atomic_cxchg_acquire_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
114 /// Stores a value if the current value is the same as the `old` value.
115 ///
116 /// The stabilized version of this intrinsic is available on the
117 /// [`atomic`] types via the `compare_exchange` method by passing
118 /// [`Ordering::Acquire`] as both the success and failure parameters.
119 /// For example, [`AtomicBool::compare_exchange`].
120 #[rustc_nounwind]
121 pub fn atomic_cxchg_acquire_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
122 /// Stores a value if the current value is the same as the `old` value.
123 ///
124 /// The stabilized version of this intrinsic is available on the
125 /// [`atomic`] types via the `compare_exchange` method by passing
126 /// [`Ordering::Acquire`] and [`Ordering::SeqCst`] as the success and failure parameters.
127 /// For example, [`AtomicBool::compare_exchange`].
128 #[rustc_nounwind]
129 pub fn atomic_cxchg_acquire_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
130 /// Stores a value if the current value is the same as the `old` value.
131 ///
132 /// The stabilized version of this intrinsic is available on the
133 /// [`atomic`] types via the `compare_exchange` method by passing
134 /// [`Ordering::Release`] and [`Ordering::Relaxed`] as the success and failure parameters.
135 /// For example, [`AtomicBool::compare_exchange`].
136 #[rustc_nounwind]
137 pub fn atomic_cxchg_release_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
138 /// Stores a value if the current value is the same as the `old` value.
139 ///
140 /// The stabilized version of this intrinsic is available on the
141 /// [`atomic`] types via the `compare_exchange` method by passing
142 /// [`Ordering::Release`] and [`Ordering::Acquire`] as the success and failure parameters.
143 /// For example, [`AtomicBool::compare_exchange`].
144 #[rustc_nounwind]
145 pub fn atomic_cxchg_release_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
146 /// Stores a value if the current value is the same as the `old` value.
147 ///
148 /// The stabilized version of this intrinsic is available on the
149 /// [`atomic`] types via the `compare_exchange` method by passing
150 /// [`Ordering::Release`] and [`Ordering::SeqCst`] as the success and failure parameters.
151 /// For example, [`AtomicBool::compare_exchange`].
152 #[rustc_nounwind]
153 pub fn atomic_cxchg_release_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
154 /// Stores a value if the current value is the same as the `old` value.
155 ///
156 /// The stabilized version of this intrinsic is available on the
157 /// [`atomic`] types via the `compare_exchange` method by passing
158 /// [`Ordering::AcqRel`] and [`Ordering::Relaxed`] as the success and failure parameters.
159 /// For example, [`AtomicBool::compare_exchange`].
160 #[rustc_nounwind]
161 pub fn atomic_cxchg_acqrel_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
162 /// Stores a value if the current value is the same as the `old` value.
163 ///
164 /// The stabilized version of this intrinsic is available on the
165 /// [`atomic`] types via the `compare_exchange` method by passing
166 /// [`Ordering::AcqRel`] and [`Ordering::Acquire`] as the success and failure parameters.
167 /// For example, [`AtomicBool::compare_exchange`].
168 #[rustc_nounwind]
169 pub fn atomic_cxchg_acqrel_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
170 /// Stores a value if the current value is the same as the `old` value.
171 ///
172 /// The stabilized version of this intrinsic is available on the
173 /// [`atomic`] types via the `compare_exchange` method by passing
174 /// [`Ordering::AcqRel`] and [`Ordering::SeqCst`] as the success and failure parameters.
175 /// For example, [`AtomicBool::compare_exchange`].
176 #[rustc_nounwind]
177 pub fn atomic_cxchg_acqrel_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
178 /// Stores a value if the current value is the same as the `old` value.
179 ///
180 /// The stabilized version of this intrinsic is available on the
181 /// [`atomic`] types via the `compare_exchange` method by passing
182 /// [`Ordering::SeqCst`] and [`Ordering::Relaxed`] as the success and failure parameters.
183 /// For example, [`AtomicBool::compare_exchange`].
184 #[rustc_nounwind]
185 pub fn atomic_cxchg_seqcst_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
186 /// Stores a value if the current value is the same as the `old` value.
187 ///
188 /// The stabilized version of this intrinsic is available on the
189 /// [`atomic`] types via the `compare_exchange` method by passing
190 /// [`Ordering::SeqCst`] and [`Ordering::Acquire`] as the success and failure parameters.
191 /// For example, [`AtomicBool::compare_exchange`].
192 #[rustc_nounwind]
193 pub fn atomic_cxchg_seqcst_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
194 /// Stores a value if the current value is the same as the `old` value.
195 ///
196 /// The stabilized version of this intrinsic is available on the
197 /// [`atomic`] types via the `compare_exchange` method by passing
198 /// [`Ordering::SeqCst`] as both the success and failure parameters.
199 /// For example, [`AtomicBool::compare_exchange`].
200 #[rustc_nounwind]
201 pub fn atomic_cxchg_seqcst_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
202
203 /// Stores a value if the current value is the same as the `old` value.
204 ///
205 /// The stabilized version of this intrinsic is available on the
206 /// [`atomic`] types via the `compare_exchange_weak` method by passing
207 /// [`Ordering::Relaxed`] as both the success and failure parameters.
208 /// For example, [`AtomicBool::compare_exchange_weak`].
209 #[rustc_nounwind]
210 pub fn atomic_cxchgweak_relaxed_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
211 /// Stores a value if the current value is the same as the `old` value.
212 ///
213 /// The stabilized version of this intrinsic is available on the
214 /// [`atomic`] types via the `compare_exchange_weak` method by passing
215 /// [`Ordering::Relaxed`] and [`Ordering::Acquire`] as the success and failure parameters.
216 /// For example, [`AtomicBool::compare_exchange_weak`].
217 #[rustc_nounwind]
218 pub fn atomic_cxchgweak_relaxed_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
219 /// Stores a value if the current value is the same as the `old` value.
220 ///
221 /// The stabilized version of this intrinsic is available on the
222 /// [`atomic`] types via the `compare_exchange_weak` method by passing
223 /// [`Ordering::Relaxed`] and [`Ordering::SeqCst`] as the success and failure parameters.
224 /// For example, [`AtomicBool::compare_exchange_weak`].
225 #[rustc_nounwind]
226 pub fn atomic_cxchgweak_relaxed_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
227 /// Stores a value if the current value is the same as the `old` value.
228 ///
229 /// The stabilized version of this intrinsic is available on the
230 /// [`atomic`] types via the `compare_exchange_weak` method by passing
231 /// [`Ordering::Acquire`] and [`Ordering::Relaxed`] as the success and failure parameters.
232 /// For example, [`AtomicBool::compare_exchange_weak`].
233 #[rustc_nounwind]
234 pub fn atomic_cxchgweak_acquire_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
235 /// Stores a value if the current value is the same as the `old` value.
236 ///
237 /// The stabilized version of this intrinsic is available on the
238 /// [`atomic`] types via the `compare_exchange_weak` method by passing
239 /// [`Ordering::Acquire`] as both the success and failure parameters.
240 /// For example, [`AtomicBool::compare_exchange_weak`].
241 #[rustc_nounwind]
242 pub fn atomic_cxchgweak_acquire_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
243 /// Stores a value if the current value is the same as the `old` value.
244 ///
245 /// The stabilized version of this intrinsic is available on the
246 /// [`atomic`] types via the `compare_exchange_weak` method by passing
247 /// [`Ordering::Acquire`] and [`Ordering::SeqCst`] as the success and failure parameters.
248 /// For example, [`AtomicBool::compare_exchange_weak`].
249 #[rustc_nounwind]
250 pub fn atomic_cxchgweak_acquire_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
251 /// Stores a value if the current value is the same as the `old` value.
252 ///
253 /// The stabilized version of this intrinsic is available on the
254 /// [`atomic`] types via the `compare_exchange_weak` method by passing
255 /// [`Ordering::Release`] and [`Ordering::Relaxed`] as the success and failure parameters.
256 /// For example, [`AtomicBool::compare_exchange_weak`].
257 #[rustc_nounwind]
258 pub fn atomic_cxchgweak_release_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
259 /// Stores a value if the current value is the same as the `old` value.
260 ///
261 /// The stabilized version of this intrinsic is available on the
262 /// [`atomic`] types via the `compare_exchange_weak` method by passing
263 /// [`Ordering::Release`] and [`Ordering::Acquire`] as the success and failure parameters.
264 /// For example, [`AtomicBool::compare_exchange_weak`].
265 #[rustc_nounwind]
266 pub fn atomic_cxchgweak_release_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
267 /// Stores a value if the current value is the same as the `old` value.
268 ///
269 /// The stabilized version of this intrinsic is available on the
270 /// [`atomic`] types via the `compare_exchange_weak` method by passing
271 /// [`Ordering::Release`] and [`Ordering::SeqCst`] as the success and failure parameters.
272 /// For example, [`AtomicBool::compare_exchange_weak`].
273 #[rustc_nounwind]
274 pub fn atomic_cxchgweak_release_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
275 /// Stores a value if the current value is the same as the `old` value.
276 ///
277 /// The stabilized version of this intrinsic is available on the
278 /// [`atomic`] types via the `compare_exchange_weak` method by passing
279 /// [`Ordering::AcqRel`] and [`Ordering::Relaxed`] as the success and failure parameters.
280 /// For example, [`AtomicBool::compare_exchange_weak`].
281 #[rustc_nounwind]
282 pub fn atomic_cxchgweak_acqrel_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
283 /// Stores a value if the current value is the same as the `old` value.
284 ///
285 /// The stabilized version of this intrinsic is available on the
286 /// [`atomic`] types via the `compare_exchange_weak` method by passing
287 /// [`Ordering::AcqRel`] and [`Ordering::Acquire`] as the success and failure parameters.
288 /// For example, [`AtomicBool::compare_exchange_weak`].
289 #[rustc_nounwind]
290 pub fn atomic_cxchgweak_acqrel_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
291 /// Stores a value if the current value is the same as the `old` value.
292 ///
293 /// The stabilized version of this intrinsic is available on the
294 /// [`atomic`] types via the `compare_exchange_weak` method by passing
295 /// [`Ordering::AcqRel`] and [`Ordering::SeqCst`] as the success and failure parameters.
296 /// For example, [`AtomicBool::compare_exchange_weak`].
297 #[rustc_nounwind]
298 pub fn atomic_cxchgweak_acqrel_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
299 /// Stores a value if the current value is the same as the `old` value.
300 ///
301 /// The stabilized version of this intrinsic is available on the
302 /// [`atomic`] types via the `compare_exchange_weak` method by passing
303 /// [`Ordering::SeqCst`] and [`Ordering::Relaxed`] as the success and failure parameters.
304 /// For example, [`AtomicBool::compare_exchange_weak`].
305 #[rustc_nounwind]
306 pub fn atomic_cxchgweak_seqcst_relaxed<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
307 /// Stores a value if the current value is the same as the `old` value.
308 ///
309 /// The stabilized version of this intrinsic is available on the
310 /// [`atomic`] types via the `compare_exchange_weak` method by passing
311 /// [`Ordering::SeqCst`] and [`Ordering::Acquire`] as the success and failure parameters.
312 /// For example, [`AtomicBool::compare_exchange_weak`].
313 #[rustc_nounwind]
314 pub fn atomic_cxchgweak_seqcst_acquire<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
315 /// Stores a value if the current value is the same as the `old` value.
316 ///
317 /// The stabilized version of this intrinsic is available on the
318 /// [`atomic`] types via the `compare_exchange_weak` method by passing
319 /// [`Ordering::SeqCst`] as both the success and failure parameters.
320 /// For example, [`AtomicBool::compare_exchange_weak`].
321 #[rustc_nounwind]
322 pub fn atomic_cxchgweak_seqcst_seqcst<T: Copy>(dst: *mut T, old: T, src: T) -> (T, bool);
323
324 /// Loads the current value of the pointer.
325 ///
326 /// The stabilized version of this intrinsic is available on the
327 /// [`atomic`] types via the `load` method by passing
328 /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::load`].
329 #[rustc_nounwind]
330 pub fn atomic_load_seqcst<T: Copy>(src: *const T) -> T;
331 /// Loads the current value of the pointer.
332 ///
333 /// The stabilized version of this intrinsic is available on the
334 /// [`atomic`] types via the `load` method by passing
335 /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::load`].
336 #[rustc_nounwind]
337 pub fn atomic_load_acquire<T: Copy>(src: *const T) -> T;
338 /// Loads the current value of the pointer.
339 ///
340 /// The stabilized version of this intrinsic is available on the
341 /// [`atomic`] types via the `load` method by passing
342 /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::load`].
343 #[rustc_nounwind]
344 pub fn atomic_load_relaxed<T: Copy>(src: *const T) -> T;
345 /// Do NOT use this intrinsic; "unordered" operations do not exist in our memory model!
346 /// In terms of the Rust Abstract Machine, this operation is equivalent to `src.read()`,
347 /// i.e., it performs a non-atomic read.
348 #[rustc_nounwind]
349 pub fn atomic_load_unordered<T: Copy>(src: *const T) -> T;
350
351 /// Stores the value at the specified memory location.
352 ///
353 /// The stabilized version of this intrinsic is available on the
354 /// [`atomic`] types via the `store` method by passing
355 /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::store`].
356 #[rustc_nounwind]
357 pub fn atomic_store_seqcst<T: Copy>(dst: *mut T, val: T);
358 /// Stores the value at the specified memory location.
359 ///
360 /// The stabilized version of this intrinsic is available on the
361 /// [`atomic`] types via the `store` method by passing
362 /// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::store`].
363 #[rustc_nounwind]
364 pub fn atomic_store_release<T: Copy>(dst: *mut T, val: T);
365 /// Stores the value at the specified memory location.
366 ///
367 /// The stabilized version of this intrinsic is available on the
368 /// [`atomic`] types via the `store` method by passing
369 /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::store`].
370 #[rustc_nounwind]
371 pub fn atomic_store_relaxed<T: Copy>(dst: *mut T, val: T);
372 /// Do NOT use this intrinsic; "unordered" operations do not exist in our memory model!
373 /// In terms of the Rust Abstract Machine, this operation is equivalent to `dst.write(val)`,
374 /// i.e., it performs a non-atomic write.
375 #[rustc_nounwind]
376 pub fn atomic_store_unordered<T: Copy>(dst: *mut T, val: T);
377
378 /// Stores the value at the specified memory location, returning the old value.
379 ///
380 /// The stabilized version of this intrinsic is available on the
381 /// [`atomic`] types via the `swap` method by passing
382 /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::swap`].
383 #[rustc_nounwind]
384 pub fn atomic_xchg_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
385 /// Stores the value at the specified memory location, returning the old value.
386 ///
387 /// The stabilized version of this intrinsic is available on the
388 /// [`atomic`] types via the `swap` method by passing
389 /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::swap`].
390 #[rustc_nounwind]
391 pub fn atomic_xchg_acquire<T: Copy>(dst: *mut T, src: T) -> T;
392 /// Stores the value at the specified memory location, returning the old value.
393 ///
394 /// The stabilized version of this intrinsic is available on the
395 /// [`atomic`] types via the `swap` method by passing
396 /// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::swap`].
397 #[rustc_nounwind]
398 pub fn atomic_xchg_release<T: Copy>(dst: *mut T, src: T) -> T;
399 /// Stores the value at the specified memory location, returning the old value.
400 ///
401 /// The stabilized version of this intrinsic is available on the
402 /// [`atomic`] types via the `swap` method by passing
403 /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicBool::swap`].
404 #[rustc_nounwind]
405 pub fn atomic_xchg_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
406 /// Stores the value at the specified memory location, returning the old value.
407 ///
408 /// The stabilized version of this intrinsic is available on the
409 /// [`atomic`] types via the `swap` method by passing
410 /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::swap`].
411 #[rustc_nounwind]
412 pub fn atomic_xchg_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
413
414 /// Adds to the current value, returning the previous value.
415 ///
416 /// The stabilized version of this intrinsic is available on the
417 /// [`atomic`] types via the `fetch_add` method by passing
418 /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicIsize::fetch_add`].
419 #[rustc_nounwind]
420 pub fn atomic_xadd_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
421 /// Adds to the current value, returning the previous value.
422 ///
423 /// The stabilized version of this intrinsic is available on the
424 /// [`atomic`] types via the `fetch_add` method by passing
425 /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicIsize::fetch_add`].
426 #[rustc_nounwind]
427 pub fn atomic_xadd_acquire<T: Copy>(dst: *mut T, src: T) -> T;
428 /// Adds to the current value, returning the previous value.
429 ///
430 /// The stabilized version of this intrinsic is available on the
431 /// [`atomic`] types via the `fetch_add` method by passing
432 /// [`Ordering::Release`] as the `order`. For example, [`AtomicIsize::fetch_add`].
433 #[rustc_nounwind]
434 pub fn atomic_xadd_release<T: Copy>(dst: *mut T, src: T) -> T;
435 /// Adds to the current value, returning the previous value.
436 ///
437 /// The stabilized version of this intrinsic is available on the
438 /// [`atomic`] types via the `fetch_add` method by passing
439 /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicIsize::fetch_add`].
440 #[rustc_nounwind]
441 pub fn atomic_xadd_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
442 /// Adds to the current value, returning the previous value.
443 ///
444 /// The stabilized version of this intrinsic is available on the
445 /// [`atomic`] types via the `fetch_add` method by passing
446 /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicIsize::fetch_add`].
447 #[rustc_nounwind]
448 pub fn atomic_xadd_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
449
450 /// Subtract from the current value, returning the previous value.
451 ///
452 /// The stabilized version of this intrinsic is available on the
453 /// [`atomic`] types via the `fetch_sub` method by passing
454 /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicIsize::fetch_sub`].
455 #[rustc_nounwind]
456 pub fn atomic_xsub_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
457 /// Subtract from the current value, returning the previous value.
458 ///
459 /// The stabilized version of this intrinsic is available on the
460 /// [`atomic`] types via the `fetch_sub` method by passing
461 /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicIsize::fetch_sub`].
462 #[rustc_nounwind]
463 pub fn atomic_xsub_acquire<T: Copy>(dst: *mut T, src: T) -> T;
464 /// Subtract from the current value, returning the previous value.
465 ///
466 /// The stabilized version of this intrinsic is available on the
467 /// [`atomic`] types via the `fetch_sub` method by passing
468 /// [`Ordering::Release`] as the `order`. For example, [`AtomicIsize::fetch_sub`].
469 #[rustc_nounwind]
470 pub fn atomic_xsub_release<T: Copy>(dst: *mut T, src: T) -> T;
471 /// Subtract from the current value, returning the previous value.
472 ///
473 /// The stabilized version of this intrinsic is available on the
474 /// [`atomic`] types via the `fetch_sub` method by passing
475 /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicIsize::fetch_sub`].
476 #[rustc_nounwind]
477 pub fn atomic_xsub_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
478 /// Subtract from the current value, returning the previous value.
479 ///
480 /// The stabilized version of this intrinsic is available on the
481 /// [`atomic`] types via the `fetch_sub` method by passing
482 /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicIsize::fetch_sub`].
483 #[rustc_nounwind]
484 pub fn atomic_xsub_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
485
486 /// Bitwise and with the current value, returning the previous value.
487 ///
488 /// The stabilized version of this intrinsic is available on the
489 /// [`atomic`] types via the `fetch_and` method by passing
490 /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::fetch_and`].
491 #[rustc_nounwind]
492 pub fn atomic_and_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
493 /// Bitwise and with the current value, returning the previous value.
494 ///
495 /// The stabilized version of this intrinsic is available on the
496 /// [`atomic`] types via the `fetch_and` method by passing
497 /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::fetch_and`].
498 #[rustc_nounwind]
499 pub fn atomic_and_acquire<T: Copy>(dst: *mut T, src: T) -> T;
500 /// Bitwise and with the current value, returning the previous value.
501 ///
502 /// The stabilized version of this intrinsic is available on the
503 /// [`atomic`] types via the `fetch_and` method by passing
504 /// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::fetch_and`].
505 #[rustc_nounwind]
506 pub fn atomic_and_release<T: Copy>(dst: *mut T, src: T) -> T;
507 /// Bitwise and with the current value, returning the previous value.
508 ///
509 /// The stabilized version of this intrinsic is available on the
510 /// [`atomic`] types via the `fetch_and` method by passing
511 /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicBool::fetch_and`].
512 #[rustc_nounwind]
513 pub fn atomic_and_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
514 /// Bitwise and with the current value, returning the previous value.
515 ///
516 /// The stabilized version of this intrinsic is available on the
517 /// [`atomic`] types via the `fetch_and` method by passing
518 /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::fetch_and`].
519 #[rustc_nounwind]
520 pub fn atomic_and_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
521
522 /// Bitwise nand with the current value, returning the previous value.
523 ///
524 /// The stabilized version of this intrinsic is available on the
525 /// [`AtomicBool`] type via the `fetch_nand` method by passing
526 /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::fetch_nand`].
527 #[rustc_nounwind]
528 pub fn atomic_nand_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
529 /// Bitwise nand with the current value, returning the previous value.
530 ///
531 /// The stabilized version of this intrinsic is available on the
532 /// [`AtomicBool`] type via the `fetch_nand` method by passing
533 /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::fetch_nand`].
534 #[rustc_nounwind]
535 pub fn atomic_nand_acquire<T: Copy>(dst: *mut T, src: T) -> T;
536 /// Bitwise nand with the current value, returning the previous value.
537 ///
538 /// The stabilized version of this intrinsic is available on the
539 /// [`AtomicBool`] type via the `fetch_nand` method by passing
540 /// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::fetch_nand`].
541 #[rustc_nounwind]
542 pub fn atomic_nand_release<T: Copy>(dst: *mut T, src: T) -> T;
543 /// Bitwise nand with the current value, returning the previous value.
544 ///
545 /// The stabilized version of this intrinsic is available on the
546 /// [`AtomicBool`] type via the `fetch_nand` method by passing
547 /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicBool::fetch_nand`].
548 #[rustc_nounwind]
549 pub fn atomic_nand_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
550 /// Bitwise nand with the current value, returning the previous value.
551 ///
552 /// The stabilized version of this intrinsic is available on the
553 /// [`AtomicBool`] type via the `fetch_nand` method by passing
554 /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::fetch_nand`].
555 #[rustc_nounwind]
556 pub fn atomic_nand_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
557
558 /// Bitwise or with the current value, returning the previous value.
559 ///
560 /// The stabilized version of this intrinsic is available on the
561 /// [`atomic`] types via the `fetch_or` method by passing
562 /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::fetch_or`].
563 #[rustc_nounwind]
564 pub fn atomic_or_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
565 /// Bitwise or with the current value, returning the previous value.
566 ///
567 /// The stabilized version of this intrinsic is available on the
568 /// [`atomic`] types via the `fetch_or` method by passing
569 /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::fetch_or`].
570 #[rustc_nounwind]
571 pub fn atomic_or_acquire<T: Copy>(dst: *mut T, src: T) -> T;
572 /// Bitwise or with the current value, returning the previous value.
573 ///
574 /// The stabilized version of this intrinsic is available on the
575 /// [`atomic`] types via the `fetch_or` method by passing
576 /// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::fetch_or`].
577 #[rustc_nounwind]
578 pub fn atomic_or_release<T: Copy>(dst: *mut T, src: T) -> T;
579 /// Bitwise or with the current value, returning the previous value.
580 ///
581 /// The stabilized version of this intrinsic is available on the
582 /// [`atomic`] types via the `fetch_or` method by passing
583 /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicBool::fetch_or`].
584 #[rustc_nounwind]
585 pub fn atomic_or_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
586 /// Bitwise or with the current value, returning the previous value.
587 ///
588 /// The stabilized version of this intrinsic is available on the
589 /// [`atomic`] types via the `fetch_or` method by passing
590 /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::fetch_or`].
591 #[rustc_nounwind]
592 pub fn atomic_or_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
593
594 /// Bitwise xor with the current value, returning the previous value.
595 ///
596 /// The stabilized version of this intrinsic is available on the
597 /// [`atomic`] types via the `fetch_xor` method by passing
598 /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::fetch_xor`].
599 #[rustc_nounwind]
600 pub fn atomic_xor_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
601 /// Bitwise xor with the current value, returning the previous value.
602 ///
603 /// The stabilized version of this intrinsic is available on the
604 /// [`atomic`] types via the `fetch_xor` method by passing
605 /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::fetch_xor`].
606 #[rustc_nounwind]
607 pub fn atomic_xor_acquire<T: Copy>(dst: *mut T, src: T) -> T;
608 /// Bitwise xor with the current value, returning the previous value.
609 ///
610 /// The stabilized version of this intrinsic is available on the
611 /// [`atomic`] types via the `fetch_xor` method by passing
612 /// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::fetch_xor`].
613 #[rustc_nounwind]
614 pub fn atomic_xor_release<T: Copy>(dst: *mut T, src: T) -> T;
615 /// Bitwise xor with the current value, returning the previous value.
616 ///
617 /// The stabilized version of this intrinsic is available on the
618 /// [`atomic`] types via the `fetch_xor` method by passing
619 /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicBool::fetch_xor`].
620 #[rustc_nounwind]
621 pub fn atomic_xor_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
622 /// Bitwise xor with the current value, returning the previous value.
623 ///
624 /// The stabilized version of this intrinsic is available on the
625 /// [`atomic`] types via the `fetch_xor` method by passing
626 /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::fetch_xor`].
627 #[rustc_nounwind]
628 pub fn atomic_xor_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
629
630 /// Maximum with the current value using a signed comparison.
631 ///
632 /// The stabilized version of this intrinsic is available on the
633 /// [`atomic`] signed integer types via the `fetch_max` method by passing
634 /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicI32::fetch_max`].
635 #[rustc_nounwind]
636 pub fn atomic_max_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
637 /// Maximum with the current value using a signed comparison.
638 ///
639 /// The stabilized version of this intrinsic is available on the
640 /// [`atomic`] signed integer types via the `fetch_max` method by passing
641 /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicI32::fetch_max`].
642 #[rustc_nounwind]
643 pub fn atomic_max_acquire<T: Copy>(dst: *mut T, src: T) -> T;
644 /// Maximum with the current value using a signed comparison.
645 ///
646 /// The stabilized version of this intrinsic is available on the
647 /// [`atomic`] signed integer types via the `fetch_max` method by passing
648 /// [`Ordering::Release`] as the `order`. For example, [`AtomicI32::fetch_max`].
649 #[rustc_nounwind]
650 pub fn atomic_max_release<T: Copy>(dst: *mut T, src: T) -> T;
651 /// Maximum with the current value using a signed comparison.
652 ///
653 /// The stabilized version of this intrinsic is available on the
654 /// [`atomic`] signed integer types via the `fetch_max` method by passing
655 /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicI32::fetch_max`].
656 #[rustc_nounwind]
657 pub fn atomic_max_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
658 /// Maximum with the current value.
659 ///
660 /// The stabilized version of this intrinsic is available on the
661 /// [`atomic`] signed integer types via the `fetch_max` method by passing
662 /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicI32::fetch_max`].
663 #[rustc_nounwind]
664 pub fn atomic_max_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
665
666 /// Minimum with the current value using a signed comparison.
667 ///
668 /// The stabilized version of this intrinsic is available on the
669 /// [`atomic`] signed integer types via the `fetch_min` method by passing
670 /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicI32::fetch_min`].
671 #[rustc_nounwind]
672 pub fn atomic_min_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
673 /// Minimum with the current value using a signed comparison.
674 ///
675 /// The stabilized version of this intrinsic is available on the
676 /// [`atomic`] signed integer types via the `fetch_min` method by passing
677 /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicI32::fetch_min`].
678 #[rustc_nounwind]
679 pub fn atomic_min_acquire<T: Copy>(dst: *mut T, src: T) -> T;
680 /// Minimum with the current value using a signed comparison.
681 ///
682 /// The stabilized version of this intrinsic is available on the
683 /// [`atomic`] signed integer types via the `fetch_min` method by passing
684 /// [`Ordering::Release`] as the `order`. For example, [`AtomicI32::fetch_min`].
685 #[rustc_nounwind]
686 pub fn atomic_min_release<T: Copy>(dst: *mut T, src: T) -> T;
687 /// Minimum with the current value using a signed comparison.
688 ///
689 /// The stabilized version of this intrinsic is available on the
690 /// [`atomic`] signed integer types via the `fetch_min` method by passing
691 /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicI32::fetch_min`].
692 pub fn atomic_min_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
693 /// Minimum with the current value using a signed comparison.
694 ///
695 /// The stabilized version of this intrinsic is available on the
696 /// [`atomic`] signed integer types via the `fetch_min` method by passing
697 /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicI32::fetch_min`].
698 #[rustc_nounwind]
699 pub fn atomic_min_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
700
701 /// Minimum with the current value using an unsigned comparison.
702 ///
703 /// The stabilized version of this intrinsic is available on the
704 /// [`atomic`] unsigned integer types via the `fetch_min` method by passing
705 /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicU32::fetch_min`].
706 #[rustc_nounwind]
707 pub fn atomic_umin_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
708 /// Minimum with the current value using an unsigned comparison.
709 ///
710 /// The stabilized version of this intrinsic is available on the
711 /// [`atomic`] unsigned integer types via the `fetch_min` method by passing
712 /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicU32::fetch_min`].
713 #[rustc_nounwind]
714 pub fn atomic_umin_acquire<T: Copy>(dst: *mut T, src: T) -> T;
715 /// Minimum with the current value using an unsigned comparison.
716 ///
717 /// The stabilized version of this intrinsic is available on the
718 /// [`atomic`] unsigned integer types via the `fetch_min` method by passing
719 /// [`Ordering::Release`] as the `order`. For example, [`AtomicU32::fetch_min`].
720 #[rustc_nounwind]
721 pub fn atomic_umin_release<T: Copy>(dst: *mut T, src: T) -> T;
722 /// Minimum with the current value using an unsigned comparison.
723 ///
724 /// The stabilized version of this intrinsic is available on the
725 /// [`atomic`] unsigned integer types via the `fetch_min` method by passing
726 /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicU32::fetch_min`].
727 #[rustc_nounwind]
728 pub fn atomic_umin_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
729 /// Minimum with the current value using an unsigned comparison.
730 ///
731 /// The stabilized version of this intrinsic is available on the
732 /// [`atomic`] unsigned integer types via the `fetch_min` method by passing
733 /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicU32::fetch_min`].
734 #[rustc_nounwind]
735 pub fn atomic_umin_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
736
737 /// Maximum with the current value using an unsigned comparison.
738 ///
739 /// The stabilized version of this intrinsic is available on the
740 /// [`atomic`] unsigned integer types via the `fetch_max` method by passing
741 /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicU32::fetch_max`].
742 #[rustc_nounwind]
743 pub fn atomic_umax_seqcst<T: Copy>(dst: *mut T, src: T) -> T;
744 /// Maximum with the current value using an unsigned comparison.
745 ///
746 /// The stabilized version of this intrinsic is available on the
747 /// [`atomic`] unsigned integer types via the `fetch_max` method by passing
748 /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicU32::fetch_max`].
749 #[rustc_nounwind]
750 pub fn atomic_umax_acquire<T: Copy>(dst: *mut T, src: T) -> T;
751 /// Maximum with the current value using an unsigned comparison.
752 ///
753 /// The stabilized version of this intrinsic is available on the
754 /// [`atomic`] unsigned integer types via the `fetch_max` method by passing
755 /// [`Ordering::Release`] as the `order`. For example, [`AtomicU32::fetch_max`].
756 #[rustc_nounwind]
757 pub fn atomic_umax_release<T: Copy>(dst: *mut T, src: T) -> T;
758 /// Maximum with the current value using an unsigned comparison.
759 ///
760 /// The stabilized version of this intrinsic is available on the
761 /// [`atomic`] unsigned integer types via the `fetch_max` method by passing
762 /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicU32::fetch_max`].
763 #[rustc_nounwind]
764 pub fn atomic_umax_acqrel<T: Copy>(dst: *mut T, src: T) -> T;
765 /// Maximum with the current value using an unsigned comparison.
766 ///
767 /// The stabilized version of this intrinsic is available on the
768 /// [`atomic`] unsigned integer types via the `fetch_max` method by passing
769 /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicU32::fetch_max`].
770 #[rustc_nounwind]
771 pub fn atomic_umax_relaxed<T: Copy>(dst: *mut T, src: T) -> T;
772
773 /// An atomic fence.
774 ///
775 /// The stabilized version of this intrinsic is available in
776 /// [`atomic::fence`] by passing [`Ordering::SeqCst`]
777 /// as the `order`.
778 #[rustc_nounwind]
779 pub fn atomic_fence_seqcst();
780 /// An atomic fence.
781 ///
782 /// The stabilized version of this intrinsic is available in
783 /// [`atomic::fence`] by passing [`Ordering::Acquire`]
784 /// as the `order`.
785 #[rustc_nounwind]
786 pub fn atomic_fence_acquire();
787 /// An atomic fence.
788 ///
789 /// The stabilized version of this intrinsic is available in
790 /// [`atomic::fence`] by passing [`Ordering::Release`]
791 /// as the `order`.
792 #[rustc_nounwind]
793 pub fn atomic_fence_release();
794 /// An atomic fence.
795 ///
796 /// The stabilized version of this intrinsic is available in
797 /// [`atomic::fence`] by passing [`Ordering::AcqRel`]
798 /// as the `order`.
799 #[rustc_nounwind]
800 pub fn atomic_fence_acqrel();
801
802 /// A compiler-only memory barrier.
803 ///
804 /// Memory accesses will never be reordered across this barrier by the
805 /// compiler, but no instructions will be emitted for it. This is
806 /// appropriate for operations on the same thread that may be preempted,
807 /// such as when interacting with signal handlers.
808 ///
809 /// The stabilized version of this intrinsic is available in
810 /// [`atomic::compiler_fence`] by passing [`Ordering::SeqCst`]
811 /// as the `order`.
812 #[rustc_nounwind]
813 pub fn atomic_singlethreadfence_seqcst();
814 /// A compiler-only memory barrier.
815 ///
816 /// Memory accesses will never be reordered across this barrier by the
817 /// compiler, but no instructions will be emitted for it. This is
818 /// appropriate for operations on the same thread that may be preempted,
819 /// such as when interacting with signal handlers.
820 ///
821 /// The stabilized version of this intrinsic is available in
822 /// [`atomic::compiler_fence`] by passing [`Ordering::Acquire`]
823 /// as the `order`.
824 #[rustc_nounwind]
825 pub fn atomic_singlethreadfence_acquire();
826 /// A compiler-only memory barrier.
827 ///
828 /// Memory accesses will never be reordered across this barrier by the
829 /// compiler, but no instructions will be emitted for it. This is
830 /// appropriate for operations on the same thread that may be preempted,
831 /// such as when interacting with signal handlers.
832 ///
833 /// The stabilized version of this intrinsic is available in
834 /// [`atomic::compiler_fence`] by passing [`Ordering::Release`]
835 /// as the `order`.
836 #[rustc_nounwind]
837 pub fn atomic_singlethreadfence_release();
838 /// A compiler-only memory barrier.
839 ///
840 /// Memory accesses will never be reordered across this barrier by the
841 /// compiler, but no instructions will be emitted for it. This is
842 /// appropriate for operations on the same thread that may be preempted,
843 /// such as when interacting with signal handlers.
844 ///
845 /// The stabilized version of this intrinsic is available in
846 /// [`atomic::compiler_fence`] by passing [`Ordering::AcqRel`]
847 /// as the `order`.
848 #[rustc_nounwind]
849 pub fn atomic_singlethreadfence_acqrel();
850
851 /// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction
852 /// if supported; otherwise, it is a no-op.
853 /// Prefetches have no effect on the behavior of the program but can change its performance
854 /// characteristics.
855 ///
856 /// The `locality` argument must be a constant integer and is a temporal locality specifier
857 /// ranging from (0) - no locality, to (3) - extremely local keep in cache.
858 ///
859 /// This intrinsic does not have a stable counterpart.
860 #[rustc_nounwind]
861 pub fn prefetch_read_data<T>(data: *const T, locality: i32);
862 /// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction
863 /// if supported; otherwise, it is a no-op.
864 /// Prefetches have no effect on the behavior of the program but can change its performance
865 /// characteristics.
866 ///
867 /// The `locality` argument must be a constant integer and is a temporal locality specifier
868 /// ranging from (0) - no locality, to (3) - extremely local keep in cache.
869 ///
870 /// This intrinsic does not have a stable counterpart.
871 #[rustc_nounwind]
872 pub fn prefetch_write_data<T>(data: *const T, locality: i32);
873 /// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction
874 /// if supported; otherwise, it is a no-op.
875 /// Prefetches have no effect on the behavior of the program but can change its performance
876 /// characteristics.
877 ///
878 /// The `locality` argument must be a constant integer and is a temporal locality specifier
879 /// ranging from (0) - no locality, to (3) - extremely local keep in cache.
880 ///
881 /// This intrinsic does not have a stable counterpart.
882 #[rustc_nounwind]
883 pub fn prefetch_read_instruction<T>(data: *const T, locality: i32);
884 /// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction
885 /// if supported; otherwise, it is a no-op.
886 /// Prefetches have no effect on the behavior of the program but can change its performance
887 /// characteristics.
888 ///
889 /// The `locality` argument must be a constant integer and is a temporal locality specifier
890 /// ranging from (0) - no locality, to (3) - extremely local keep in cache.
891 ///
892 /// This intrinsic does not have a stable counterpart.
893 #[rustc_nounwind]
894 pub fn prefetch_write_instruction<T>(data: *const T, locality: i32);
895
896 /// Magic intrinsic that derives its meaning from attributes
897 /// attached to the function.
898 ///
899 /// For example, dataflow uses this to inject static assertions so
900 /// that `rustc_peek(potentially_uninitialized)` would actually
901 /// double-check that dataflow did indeed compute that it is
902 /// uninitialized at that point in the control flow.
903 ///
904 /// This intrinsic should not be used outside of the compiler.
905 #[rustc_safe_intrinsic]
906 #[rustc_nounwind]
907 pub fn rustc_peek<T>(_: T) -> T;
908
909 /// Aborts the execution of the process.
910 ///
911 /// Note that, unlike most intrinsics, this is safe to call;
912 /// it does not require an `unsafe` block.
913 /// Therefore, implementations must not require the user to uphold
914 /// any safety invariants.
915 ///
916 /// [`std::process::abort`](../../std/process/fn.abort.html) is to be preferred if possible,
917 /// as its behavior is more user-friendly and more stable.
918 ///
919 /// The current implementation of `intrinsics::abort` is to invoke an invalid instruction,
920 /// on most platforms.
921 /// On Unix, the
922 /// process will probably terminate with a signal like `SIGABRT`, `SIGILL`, `SIGTRAP`, `SIGSEGV` or
923 /// `SIGBUS`. The precise behaviour is not guaranteed and not stable.
924 #[rustc_safe_intrinsic]
925 #[rustc_nounwind]
926 pub fn abort() -> !;
927
928 /// Informs the optimizer that this point in the code is not reachable,
929 /// enabling further optimizations.
930 ///
931 /// N.B., this is very different from the `unreachable!()` macro: Unlike the
932 /// macro, which panics when it is executed, it is *undefined behavior* to
933 /// reach code marked with this function.
934 ///
935 /// The stabilized version of this intrinsic is [`core::hint::unreachable_unchecked`].
936 #[rustc_const_stable(feature = "const_unreachable_unchecked", since = "1.57.0")]
937 #[rustc_nounwind]
938 pub fn unreachable() -> !;
939
940 /// Informs the optimizer that a condition is always true.
941 /// If the condition is false, the behavior is undefined.
942 ///
943 /// No code is generated for this intrinsic, but the optimizer will try
944 /// to preserve it (and its condition) between passes, which may interfere
945 /// with optimization of surrounding code and reduce performance. It should
946 /// not be used if the invariant can be discovered by the optimizer on its
947 /// own, or if it does not enable any significant optimizations.
948 ///
949 /// This intrinsic does not have a stable counterpart.
950 #[rustc_const_stable(feature = "const_assume", since = "1.77.0")]
951 #[rustc_nounwind]
952 pub fn assume(b: bool);
953
954 /// Hints to the compiler that branch condition is likely to be true.
955 /// Returns the value passed to it.
956 ///
957 /// Any use other than with `if` statements will probably not have an effect.
958 ///
959 /// Note that, unlike most intrinsics, this is safe to call;
960 /// it does not require an `unsafe` block.
961 /// Therefore, implementations must not require the user to uphold
962 /// any safety invariants.
963 ///
964 /// This intrinsic does not have a stable counterpart.
965 #[rustc_const_unstable(feature = "const_likely", issue = "none")]
966 #[rustc_safe_intrinsic]
967 #[rustc_nounwind]
968 pub fn likely(b: bool) -> bool;
969
970 /// Hints to the compiler that branch condition is likely to be false.
971 /// Returns the value passed to it.
972 ///
973 /// Any use other than with `if` statements will probably not have an effect.
974 ///
975 /// Note that, unlike most intrinsics, this is safe to call;
976 /// it does not require an `unsafe` block.
977 /// Therefore, implementations must not require the user to uphold
978 /// any safety invariants.
979 ///
980 /// This intrinsic does not have a stable counterpart.
981 #[rustc_const_unstable(feature = "const_likely", issue = "none")]
982 #[rustc_safe_intrinsic]
983 #[rustc_nounwind]
984 pub fn unlikely(b: bool) -> bool;
985
986 /// Executes a breakpoint trap, for inspection by a debugger.
987 ///
988 /// This intrinsic does not have a stable counterpart.
989 #[rustc_nounwind]
990 pub fn breakpoint();
991
992 /// The size of a type in bytes.
993 ///
994 /// Note that, unlike most intrinsics, this is safe to call;
995 /// it does not require an `unsafe` block.
996 /// Therefore, implementations must not require the user to uphold
997 /// any safety invariants.
998 ///
999 /// More specifically, this is the offset in bytes between successive
1000 /// items of the same type, including alignment padding.
1001 ///
1002 /// The stabilized version of this intrinsic is [`core::mem::size_of`].
1003 #[rustc_const_stable(feature = "const_size_of", since = "1.40.0")]
1004 #[rustc_safe_intrinsic]
1005 #[rustc_nounwind]
1006 pub fn size_of<T>() -> usize;
1007
1008 /// The minimum alignment of a type.
1009 ///
1010 /// Note that, unlike most intrinsics, this is safe to call;
1011 /// it does not require an `unsafe` block.
1012 /// Therefore, implementations must not require the user to uphold
1013 /// any safety invariants.
1014 ///
1015 /// The stabilized version of this intrinsic is [`core::mem::align_of`].
1016 #[rustc_const_stable(feature = "const_min_align_of", since = "1.40.0")]
1017 #[rustc_safe_intrinsic]
1018 #[rustc_nounwind]
1019 pub fn min_align_of<T>() -> usize;
1020 /// The preferred alignment of a type.
1021 ///
1022 /// This intrinsic does not have a stable counterpart.
1023 /// It's "tracking issue" is [#91971](https://github.com/rust-lang/rust/issues/91971).
1024 #[rustc_const_unstable(feature = "const_pref_align_of", issue = "91971")]
1025 #[rustc_nounwind]
1026 pub fn pref_align_of<T>() -> usize;
1027
1028 /// The size of the referenced value in bytes.
1029 ///
1030 /// The stabilized version of this intrinsic is [`mem::size_of_val`].
1031 #[rustc_const_unstable(feature = "const_size_of_val", issue = "46571")]
1032 #[rustc_nounwind]
1033 pub fn size_of_val<T: ?Sized>(_: *const T) -> usize;
1034 /// The required alignment of the referenced value.
1035 ///
1036 /// The stabilized version of this intrinsic is [`core::mem::align_of_val`].
1037 #[rustc_const_unstable(feature = "const_align_of_val", issue = "46571")]
1038 #[rustc_nounwind]
1039 pub fn min_align_of_val<T: ?Sized>(_: *const T) -> usize;
1040
1041 /// Gets a static string slice containing the name of a type.
1042 ///
1043 /// Note that, unlike most intrinsics, this is safe to call;
1044 /// it does not require an `unsafe` block.
1045 /// Therefore, implementations must not require the user to uphold
1046 /// any safety invariants.
1047 ///
1048 /// The stabilized version of this intrinsic is [`core::any::type_name`].
1049 #[rustc_const_unstable(feature = "const_type_name", issue = "63084")]
1050 #[rustc_safe_intrinsic]
1051 #[rustc_nounwind]
1052 pub fn type_name<T: ?Sized>() -> &'static str;
1053
1054 /// Gets an identifier which is globally unique to the specified type. This
1055 /// function will return the same value for a type regardless of whichever
1056 /// crate it is invoked in.
1057 ///
1058 /// Note that, unlike most intrinsics, this is safe to call;
1059 /// it does not require an `unsafe` block.
1060 /// Therefore, implementations must not require the user to uphold
1061 /// any safety invariants.
1062 ///
1063 /// The stabilized version of this intrinsic is [`core::any::TypeId::of`].
1064 #[rustc_const_unstable(feature = "const_type_id", issue = "77125")]
1065 #[rustc_safe_intrinsic]
1066 #[rustc_nounwind]
1067 pub fn type_id<T: ?Sized + 'static>() -> u128;
1068
1069 /// A guard for unsafe functions that cannot ever be executed if `T` is uninhabited:
1070 /// This will statically either panic, or do nothing.
1071 ///
1072 /// This intrinsic does not have a stable counterpart.
1073 #[rustc_const_stable(feature = "const_assert_type", since = "1.59.0")]
1074 #[rustc_safe_intrinsic]
1075 #[rustc_nounwind]
1076 pub fn assert_inhabited<T>();
1077
1078 /// A guard for unsafe functions that cannot ever be executed if `T` does not permit
1079 /// zero-initialization: This will statically either panic, or do nothing.
1080 ///
1081 /// This intrinsic does not have a stable counterpart.
1082 #[rustc_const_stable(feature = "const_assert_type2", since = "1.75.0")]
1083 #[rustc_safe_intrinsic]
1084 #[rustc_nounwind]
1085 pub fn assert_zero_valid<T>();
1086
1087 /// A guard for `std::mem::uninitialized`. This will statically either panic, or do nothing.
1088 ///
1089 /// This intrinsic does not have a stable counterpart.
1090 #[rustc_const_stable(feature = "const_assert_type2", since = "1.75.0")]
1091 #[rustc_safe_intrinsic]
1092 #[rustc_nounwind]
1093 pub fn assert_mem_uninitialized_valid<T>();
1094
1095 /// Gets a reference to a static `Location` indicating where it was called.
1096 ///
1097 /// Note that, unlike most intrinsics, this is safe to call;
1098 /// it does not require an `unsafe` block.
1099 /// Therefore, implementations must not require the user to uphold
1100 /// any safety invariants.
1101 ///
1102 /// Consider using [`core::panic::Location::caller`] instead.
1103 #[rustc_const_unstable(feature = "const_caller_location", issue = "76156")]
1104 #[rustc_safe_intrinsic]
1105 #[rustc_nounwind]
1106 pub fn caller_location() -> &'static crate::panic::Location<'static>;
1107
1108 /// Moves a value out of scope without running drop glue.
1109 ///
1110 /// This exists solely for [`mem::forget_unsized`]; normal `forget` uses
1111 /// `ManuallyDrop` instead.
1112 ///
1113 /// Note that, unlike most intrinsics, this is safe to call;
1114 /// it does not require an `unsafe` block.
1115 /// Therefore, implementations must not require the user to uphold
1116 /// any safety invariants.
1117 #[rustc_const_unstable(feature = "const_intrinsic_forget", issue = "none")]
1118 #[rustc_safe_intrinsic]
1119 #[rustc_nounwind]
1120 pub fn forget<T: ?Sized>(_: T);
1121
1122 /// Reinterprets the bits of a value of one type as another type.
1123 ///
1124 /// Both types must have the same size. Compilation will fail if this is not guaranteed.
1125 ///
1126 /// `transmute` is semantically equivalent to a bitwise move of one type
1127 /// into another. It copies the bits from the source value into the
1128 /// destination value, then forgets the original. Note that source and destination
1129 /// are passed by-value, which means if `Src` or `Dst` contain padding, that padding
1130 /// is *not* guaranteed to be preserved by `transmute`.
1131 ///
1132 /// Both the argument and the result must be [valid](../../nomicon/what-unsafe-does.html) at
1133 /// their given type. Violating this condition leads to [undefined behavior][ub]. The compiler
1134 /// will generate code *assuming that you, the programmer, ensure that there will never be
1135 /// undefined behavior*. It is therefore your responsibility to guarantee that every value
1136 /// passed to `transmute` is valid at both types `Src` and `Dst`. Failing to uphold this condition
1137 /// may lead to unexpected and unstable compilation results. This makes `transmute` **incredibly
1138 /// unsafe**. `transmute` should be the absolute last resort.
1139 ///
1140 /// Transmuting pointers *to* integers in a `const` context is [undefined behavior][ub],
1141 /// unless the pointer was originally created *from* an integer.
1142 /// (That includes this function specifically, integer-to-pointer casts, and helpers like [`invalid`][crate::ptr::invalid],
1143 /// but also semantically-equivalent conversions such as punning through `repr(C)` union fields.)
1144 /// Any attempt to use the resulting value for integer operations will abort const-evaluation.
1145 /// (And even outside `const`, such transmutation is touching on many unspecified aspects of the
1146 /// Rust memory model and should be avoided. See below for alternatives.)
1147 ///
1148 /// Because `transmute` is a by-value operation, alignment of the *transmuted values
1149 /// themselves* is not a concern. As with any other function, the compiler already ensures
1150 /// both `Src` and `Dst` are properly aligned. However, when transmuting values that *point
1151 /// elsewhere* (such as pointers, references, boxes…), the caller has to ensure proper
1152 /// alignment of the pointed-to values.
1153 ///
1154 /// The [nomicon](../../nomicon/transmutes.html) has additional documentation.
1155 ///
1156 /// [ub]: ../../reference/behavior-considered-undefined.html
1157 ///
1158 /// # Examples
1159 ///
1160 /// There are a few things that `transmute` is really useful for.
1161 ///
1162 /// Turning a pointer into a function pointer. This is *not* portable to
1163 /// machines where function pointers and data pointers have different sizes.
1164 ///
1165 /// ```
1166 /// fn foo() -> i32 {
1167 /// 0
1168 /// }
1169 /// // Crucially, we `as`-cast to a raw pointer before `transmute`ing to a function pointer.
1170 /// // This avoids an integer-to-pointer `transmute`, which can be problematic.
1171 /// // Transmuting between raw pointers and function pointers (i.e., two pointer types) is fine.
1172 /// let pointer = foo as *const ();
1173 /// let function = unsafe {
1174 /// std::mem::transmute::<*const (), fn() -> i32>(pointer)
1175 /// };
1176 /// assert_eq!(function(), 0);
1177 /// ```
1178 ///
1179 /// Extending a lifetime, or shortening an invariant lifetime. This is
1180 /// advanced, very unsafe Rust!
1181 ///
1182 /// ```
1183 /// struct R<'a>(&'a i32);
1184 /// unsafe fn extend_lifetime<'b>(r: R<'b>) -> R<'static> {
1185 /// std::mem::transmute::<R<'b>, R<'static>>(r)
1186 /// }
1187 ///
1188 /// unsafe fn shorten_invariant_lifetime<'b, 'c>(r: &'b mut R<'static>)
1189 /// -> &'b mut R<'c> {
1190 /// std::mem::transmute::<&'b mut R<'static>, &'b mut R<'c>>(r)
1191 /// }
1192 /// ```
1193 ///
1194 /// # Alternatives
1195 ///
1196 /// Don't despair: many uses of `transmute` can be achieved through other means.
1197 /// Below are common applications of `transmute` which can be replaced with safer
1198 /// constructs.
1199 ///
1200 /// Turning raw bytes (`[u8; SZ]`) into `u32`, `f64`, etc.:
1201 ///
1202 /// ```
1203 /// let raw_bytes = [0x78, 0x56, 0x34, 0x12];
1204 ///
1205 /// let num = unsafe {
1206 /// std::mem::transmute::<[u8; 4], u32>(raw_bytes)
1207 /// };
1208 ///
1209 /// // use `u32::from_ne_bytes` instead
1210 /// let num = u32::from_ne_bytes(raw_bytes);
1211 /// // or use `u32::from_le_bytes` or `u32::from_be_bytes` to specify the endianness
1212 /// let num = u32::from_le_bytes(raw_bytes);
1213 /// assert_eq!(num, 0x12345678);
1214 /// let num = u32::from_be_bytes(raw_bytes);
1215 /// assert_eq!(num, 0x78563412);
1216 /// ```
1217 ///
1218 /// Turning a pointer into a `usize`:
1219 ///
1220 /// ```no_run
1221 /// let ptr = &0;
1222 /// let ptr_num_transmute = unsafe {
1223 /// std::mem::transmute::<&i32, usize>(ptr)
1224 /// };
1225 ///
1226 /// // Use an `as` cast instead
1227 /// let ptr_num_cast = ptr as *const i32 as usize;
1228 /// ```
1229 ///
1230 /// Note that using `transmute` to turn a pointer to a `usize` is (as noted above) [undefined
1231 /// behavior][ub] in `const` contexts. Also outside of consts, this operation might not behave
1232 /// as expected -- this is touching on many unspecified aspects of the Rust memory model.
1233 /// Depending on what the code is doing, the following alternatives are preferable to
1234 /// pointer-to-integer transmutation:
1235 /// - If the code just wants to store data of arbitrary type in some buffer and needs to pick a
1236 /// type for that buffer, it can use [`MaybeUninit`][mem::MaybeUninit].
1237 /// - If the code actually wants to work on the address the pointer points to, it can use `as`
1238 /// casts or [`ptr.addr()`][pointer::addr].
1239 ///
1240 /// Turning a `*mut T` into an `&mut T`:
1241 ///
1242 /// ```
1243 /// let ptr: *mut i32 = &mut 0;
1244 /// let ref_transmuted = unsafe {
1245 /// std::mem::transmute::<*mut i32, &mut i32>(ptr)
1246 /// };
1247 ///
1248 /// // Use a reborrow instead
1249 /// let ref_casted = unsafe { &mut *ptr };
1250 /// ```
1251 ///
1252 /// Turning an `&mut T` into an `&mut U`:
1253 ///
1254 /// ```
1255 /// let ptr = &mut 0;
1256 /// let val_transmuted = unsafe {
1257 /// std::mem::transmute::<&mut i32, &mut u32>(ptr)
1258 /// };
1259 ///
1260 /// // Now, put together `as` and reborrowing - note the chaining of `as`
1261 /// // `as` is not transitive
1262 /// let val_casts = unsafe { &mut *(ptr as *mut i32 as *mut u32) };
1263 /// ```
1264 ///
1265 /// Turning an `&str` into a `&[u8]`:
1266 ///
1267 /// ```
1268 /// // this is not a good way to do this.
1269 /// let slice = unsafe { std::mem::transmute::<&str, &[u8]>("Rust") };
1270 /// assert_eq!(slice, &[82, 117, 115, 116]);
1271 ///
1272 /// // You could use `str::as_bytes`
1273 /// let slice = "Rust".as_bytes();
1274 /// assert_eq!(slice, &[82, 117, 115, 116]);
1275 ///
1276 /// // Or, just use a byte string, if you have control over the string
1277 /// // literal
1278 /// assert_eq!(b"Rust", &[82, 117, 115, 116]);
1279 /// ```
1280 ///
1281 /// Turning a `Vec<&T>` into a `Vec<Option<&T>>`.
1282 ///
1283 /// To transmute the inner type of the contents of a container, you must make sure to not
1284 /// violate any of the container's invariants. For `Vec`, this means that both the size
1285 /// *and alignment* of the inner types have to match. Other containers might rely on the
1286 /// size of the type, alignment, or even the `TypeId`, in which case transmuting wouldn't
1287 /// be possible at all without violating the container invariants.
1288 ///
1289 /// ```
1290 /// let store = [0, 1, 2, 3];
1291 /// let v_orig = store.iter().collect::<Vec<&i32>>();
1292 ///
1293 /// // clone the vector as we will reuse them later
1294 /// let v_clone = v_orig.clone();
1295 ///
1296 /// // Using transmute: this relies on the unspecified data layout of `Vec`, which is a
1297 /// // bad idea and could cause Undefined Behavior.
1298 /// // However, it is no-copy.
1299 /// let v_transmuted = unsafe {
1300 /// std::mem::transmute::<Vec<&i32>, Vec<Option<&i32>>>(v_clone)
1301 /// };
1302 ///
1303 /// let v_clone = v_orig.clone();
1304 ///
1305 /// // This is the suggested, safe way.
1306 /// // It does copy the entire vector, though, into a new array.
1307 /// let v_collected = v_clone.into_iter()
1308 /// .map(Some)
1309 /// .collect::<Vec<Option<&i32>>>();
1310 ///
1311 /// let v_clone = v_orig.clone();
1312 ///
1313 /// // This is the proper no-copy, unsafe way of "transmuting" a `Vec`, without relying on the
1314 /// // data layout. Instead of literally calling `transmute`, we perform a pointer cast, but
1315 /// // in terms of converting the original inner type (`&i32`) to the new one (`Option<&i32>`),
1316 /// // this has all the same caveats. Besides the information provided above, also consult the
1317 /// // [`from_raw_parts`] documentation.
1318 /// let v_from_raw = unsafe {
1319 // FIXME Update this when vec_into_raw_parts is stabilized
1320 /// // Ensure the original vector is not dropped.
1321 /// let mut v_clone = std::mem::ManuallyDrop::new(v_clone);
1322 /// Vec::from_raw_parts(v_clone.as_mut_ptr() as *mut Option<&i32>,
1323 /// v_clone.len(),
1324 /// v_clone.capacity())
1325 /// };
1326 /// ```
1327 ///
1328 /// [`from_raw_parts`]: ../../std/vec/struct.Vec.html#method.from_raw_parts
1329 ///
1330 /// Implementing `split_at_mut`:
1331 ///
1332 /// ```
1333 /// use std::{slice, mem};
1334 ///
1335 /// // There are multiple ways to do this, and there are multiple problems
1336 /// // with the following (transmute) way.
1337 /// fn split_at_mut_transmute<T>(slice: &mut [T], mid: usize)
1338 /// -> (&mut [T], &mut [T]) {
1339 /// let len = slice.len();
1340 /// assert!(mid <= len);
1341 /// unsafe {
1342 /// let slice2 = mem::transmute::<&mut [T], &mut [T]>(slice);
1343 /// // first: transmute is not type safe; all it checks is that T and
1344 /// // U are of the same size. Second, right here, you have two
1345 /// // mutable references pointing to the same memory.
1346 /// (&mut slice[0..mid], &mut slice2[mid..len])
1347 /// }
1348 /// }
1349 ///
1350 /// // This gets rid of the type safety problems; `&mut *` will *only* give
1351 /// // you an `&mut T` from an `&mut T` or `*mut T`.
1352 /// fn split_at_mut_casts<T>(slice: &mut [T], mid: usize)
1353 /// -> (&mut [T], &mut [T]) {
1354 /// let len = slice.len();
1355 /// assert!(mid <= len);
1356 /// unsafe {
1357 /// let slice2 = &mut *(slice as *mut [T]);
1358 /// // however, you still have two mutable references pointing to
1359 /// // the same memory.
1360 /// (&mut slice[0..mid], &mut slice2[mid..len])
1361 /// }
1362 /// }
1363 ///
1364 /// // This is how the standard library does it. This is the best method, if
1365 /// // you need to do something like this
1366 /// fn split_at_stdlib<T>(slice: &mut [T], mid: usize)
1367 /// -> (&mut [T], &mut [T]) {
1368 /// let len = slice.len();
1369 /// assert!(mid <= len);
1370 /// unsafe {
1371 /// let ptr = slice.as_mut_ptr();
1372 /// // This now has three mutable references pointing at the same
1373 /// // memory. `slice`, the rvalue ret.0, and the rvalue ret.1.
1374 /// // `slice` is never used after `let ptr = ...`, and so one can
1375 /// // treat it as "dead", and therefore, you only have two real
1376 /// // mutable slices.
1377 /// (slice::from_raw_parts_mut(ptr, mid),
1378 /// slice::from_raw_parts_mut(ptr.add(mid), len - mid))
1379 /// }
1380 /// }
1381 /// ```
1382 #[stable(feature = "rust1", since = "1.0.0")]
1383 #[rustc_allowed_through_unstable_modules]
1384 #[rustc_const_stable(feature = "const_transmute", since = "1.56.0")]
1385 #[rustc_diagnostic_item = "transmute"]
1386 #[rustc_nounwind]
1387 pub fn transmute<Src, Dst>(src: Src) -> Dst;
1388
1389 /// Like [`transmute`], but even less checked at compile-time: rather than
1390 /// giving an error for `size_of::<Src>() != size_of::<Dst>()`, it's
1391 /// **Undefined Behaviour** at runtime.
1392 ///
1393 /// Prefer normal `transmute` where possible, for the extra checking, since
1394 /// both do exactly the same thing at runtime, if they both compile.
1395 ///
1396 /// This is not expected to ever be exposed directly to users, rather it
1397 /// may eventually be exposed through some more-constrained API.
1398 #[rustc_const_stable(feature = "const_transmute", since = "1.56.0")]
1399 #[rustc_nounwind]
1400 pub fn transmute_unchecked<Src, Dst>(src: Src) -> Dst;
1401
1402 /// Returns `true` if the actual type given as `T` requires drop
1403 /// glue; returns `false` if the actual type provided for `T`
1404 /// implements `Copy`.
1405 ///
1406 /// If the actual type neither requires drop glue nor implements
1407 /// `Copy`, then the return value of this function is unspecified.
1408 ///
1409 /// Note that, unlike most intrinsics, this is safe to call;
1410 /// it does not require an `unsafe` block.
1411 /// Therefore, implementations must not require the user to uphold
1412 /// any safety invariants.
1413 ///
1414 /// The stabilized version of this intrinsic is [`mem::needs_drop`](crate::mem::needs_drop).
1415 #[rustc_const_stable(feature = "const_needs_drop", since = "1.40.0")]
1416 #[rustc_safe_intrinsic]
1417 #[rustc_nounwind]
1418 pub fn needs_drop<T: ?Sized>() -> bool;
1419
1420 /// Calculates the offset from a pointer.
1421 ///
1422 /// This is implemented as an intrinsic to avoid converting to and from an
1423 /// integer, since the conversion would throw away aliasing information.
1424 ///
1425 /// This can only be used with `Ptr` as a raw pointer type (`*mut` or `*const`)
1426 /// to a `Sized` pointee and with `Delta` as `usize` or `isize`. Any other
1427 /// instantiations may arbitrarily misbehave, and that's *not* a compiler bug.
1428 ///
1429 /// # Safety
1430 ///
1431 /// Both the starting and resulting pointer must be either in bounds or one
1432 /// byte past the end of an allocated object. If either pointer is out of
1433 /// bounds or arithmetic overflow occurs then any further use of the
1434 /// returned value will result in undefined behavior.
1435 ///
1436 /// The stabilized version of this intrinsic is [`pointer::offset`].
1437 #[must_use = "returns a new pointer rather than modifying its argument"]
1438 #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
1439 #[rustc_nounwind]
1440 pub fn offset<Ptr, Delta>(dst: Ptr, offset: Delta) -> Ptr;
1441
1442 /// Calculates the offset from a pointer, potentially wrapping.
1443 ///
1444 /// This is implemented as an intrinsic to avoid converting to and from an
1445 /// integer, since the conversion inhibits certain optimizations.
1446 ///
1447 /// # Safety
1448 ///
1449 /// Unlike the `offset` intrinsic, this intrinsic does not restrict the
1450 /// resulting pointer to point into or one byte past the end of an allocated
1451 /// object, and it wraps with two's complement arithmetic. The resulting
1452 /// value is not necessarily valid to be used to actually access memory.
1453 ///
1454 /// The stabilized version of this intrinsic is [`pointer::wrapping_offset`].
1455 #[must_use = "returns a new pointer rather than modifying its argument"]
1456 #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
1457 #[rustc_nounwind]
1458 pub fn arith_offset<T>(dst: *const T, offset: isize) -> *const T;
1459
1460 /// Masks out bits of the pointer according to a mask.
1461 ///
1462 /// Note that, unlike most intrinsics, this is safe to call;
1463 /// it does not require an `unsafe` block.
1464 /// Therefore, implementations must not require the user to uphold
1465 /// any safety invariants.
1466 ///
1467 /// Consider using [`pointer::mask`] instead.
1468 #[rustc_safe_intrinsic]
1469 #[rustc_nounwind]
1470 pub fn ptr_mask<T>(ptr: *const T, mask: usize) -> *const T;
1471
1472 /// Equivalent to the appropriate `llvm.memcpy.p0i8.0i8.*` intrinsic, with
1473 /// a size of `count` * `size_of::<T>()` and an alignment of
1474 /// `min_align_of::<T>()`
1475 ///
1476 /// The volatile parameter is set to `true`, so it will not be optimized out
1477 /// unless size is equal to zero.
1478 ///
1479 /// This intrinsic does not have a stable counterpart.
1480 #[rustc_nounwind]
1481 pub fn volatile_copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: usize);
1482 /// Equivalent to the appropriate `llvm.memmove.p0i8.0i8.*` intrinsic, with
1483 /// a size of `count * size_of::<T>()` and an alignment of
1484 /// `min_align_of::<T>()`
1485 ///
1486 /// The volatile parameter is set to `true`, so it will not be optimized out
1487 /// unless size is equal to zero.
1488 ///
1489 /// This intrinsic does not have a stable counterpart.
1490 #[rustc_nounwind]
1491 pub fn volatile_copy_memory<T>(dst: *mut T, src: *const T, count: usize);
1492 /// Equivalent to the appropriate `llvm.memset.p0i8.*` intrinsic, with a
1493 /// size of `count * size_of::<T>()` and an alignment of
1494 /// `min_align_of::<T>()`.
1495 ///
1496 /// The volatile parameter is set to `true`, so it will not be optimized out
1497 /// unless size is equal to zero.
1498 ///
1499 /// This intrinsic does not have a stable counterpart.
1500 #[rustc_nounwind]
1501 pub fn volatile_set_memory<T>(dst: *mut T, val: u8, count: usize);
1502
1503 /// Performs a volatile load from the `src` pointer.
1504 ///
1505 /// The stabilized version of this intrinsic is [`core::ptr::read_volatile`].
1506 #[rustc_nounwind]
1507 pub fn volatile_load<T>(src: *const T) -> T;
1508 /// Performs a volatile store to the `dst` pointer.
1509 ///
1510 /// The stabilized version of this intrinsic is [`core::ptr::write_volatile`].
1511 #[rustc_nounwind]
1512 pub fn volatile_store<T>(dst: *mut T, val: T);
1513
1514 /// Performs a volatile load from the `src` pointer
1515 /// The pointer is not required to be aligned.
1516 ///
1517 /// This intrinsic does not have a stable counterpart.
1518 #[rustc_nounwind]
1519 #[rustc_diagnostic_item = "intrinsics_unaligned_volatile_load"]
1520 pub fn unaligned_volatile_load<T>(src: *const T) -> T;
1521 /// Performs a volatile store to the `dst` pointer.
1522 /// The pointer is not required to be aligned.
1523 ///
1524 /// This intrinsic does not have a stable counterpart.
1525 #[rustc_nounwind]
1526 #[rustc_diagnostic_item = "intrinsics_unaligned_volatile_store"]
1527 pub fn unaligned_volatile_store<T>(dst: *mut T, val: T);
1528
1529 /// Returns the square root of an `f32`
1530 ///
1531 /// The stabilized version of this intrinsic is
1532 /// [`f32::sqrt`](../../std/primitive.f32.html#method.sqrt)
1533 #[rustc_nounwind]
1534 pub fn sqrtf32(x: f32) -> f32;
1535 /// Returns the square root of an `f64`
1536 ///
1537 /// The stabilized version of this intrinsic is
1538 /// [`f64::sqrt`](../../std/primitive.f64.html#method.sqrt)
1539 #[rustc_nounwind]
1540 pub fn sqrtf64(x: f64) -> f64;
1541
1542 /// Raises an `f32` to an integer power.
1543 ///
1544 /// The stabilized version of this intrinsic is
1545 /// [`f32::powi`](../../std/primitive.f32.html#method.powi)
1546 #[rustc_nounwind]
1547 pub fn powif32(a: f32, x: i32) -> f32;
1548 /// Raises an `f64` to an integer power.
1549 ///
1550 /// The stabilized version of this intrinsic is
1551 /// [`f64::powi`](../../std/primitive.f64.html#method.powi)
1552 #[rustc_nounwind]
1553 pub fn powif64(a: f64, x: i32) -> f64;
1554
1555 /// Returns the sine of an `f32`.
1556 ///
1557 /// The stabilized version of this intrinsic is
1558 /// [`f32::sin`](../../std/primitive.f32.html#method.sin)
1559 #[rustc_nounwind]
1560 pub fn sinf32(x: f32) -> f32;
1561 /// Returns the sine of an `f64`.
1562 ///
1563 /// The stabilized version of this intrinsic is
1564 /// [`f64::sin`](../../std/primitive.f64.html#method.sin)
1565 #[rustc_nounwind]
1566 pub fn sinf64(x: f64) -> f64;
1567
1568 /// Returns the cosine of an `f32`.
1569 ///
1570 /// The stabilized version of this intrinsic is
1571 /// [`f32::cos`](../../std/primitive.f32.html#method.cos)
1572 #[rustc_nounwind]
1573 pub fn cosf32(x: f32) -> f32;
1574 /// Returns the cosine of an `f64`.
1575 ///
1576 /// The stabilized version of this intrinsic is
1577 /// [`f64::cos`](../../std/primitive.f64.html#method.cos)
1578 #[rustc_nounwind]
1579 pub fn cosf64(x: f64) -> f64;
1580
1581 /// Raises an `f32` to an `f32` power.
1582 ///
1583 /// The stabilized version of this intrinsic is
1584 /// [`f32::powf`](../../std/primitive.f32.html#method.powf)
1585 #[rustc_nounwind]
1586 pub fn powf32(a: f32, x: f32) -> f32;
1587 /// Raises an `f64` to an `f64` power.
1588 ///
1589 /// The stabilized version of this intrinsic is
1590 /// [`f64::powf`](../../std/primitive.f64.html#method.powf)
1591 #[rustc_nounwind]
1592 pub fn powf64(a: f64, x: f64) -> f64;
1593
1594 /// Returns the exponential of an `f32`.
1595 ///
1596 /// The stabilized version of this intrinsic is
1597 /// [`f32::exp`](../../std/primitive.f32.html#method.exp)
1598 #[rustc_nounwind]
1599 pub fn expf32(x: f32) -> f32;
1600 /// Returns the exponential of an `f64`.
1601 ///
1602 /// The stabilized version of this intrinsic is
1603 /// [`f64::exp`](../../std/primitive.f64.html#method.exp)
1604 #[rustc_nounwind]
1605 pub fn expf64(x: f64) -> f64;
1606
1607 /// Returns 2 raised to the power of an `f32`.
1608 ///
1609 /// The stabilized version of this intrinsic is
1610 /// [`f32::exp2`](../../std/primitive.f32.html#method.exp2)
1611 #[rustc_nounwind]
1612 pub fn exp2f32(x: f32) -> f32;
1613 /// Returns 2 raised to the power of an `f64`.
1614 ///
1615 /// The stabilized version of this intrinsic is
1616 /// [`f64::exp2`](../../std/primitive.f64.html#method.exp2)
1617 #[rustc_nounwind]
1618 pub fn exp2f64(x: f64) -> f64;
1619
1620 /// Returns the natural logarithm of an `f32`.
1621 ///
1622 /// The stabilized version of this intrinsic is
1623 /// [`f32::ln`](../../std/primitive.f32.html#method.ln)
1624 #[rustc_nounwind]
1625 pub fn logf32(x: f32) -> f32;
1626 /// Returns the natural logarithm of an `f64`.
1627 ///
1628 /// The stabilized version of this intrinsic is
1629 /// [`f64::ln`](../../std/primitive.f64.html#method.ln)
1630 #[rustc_nounwind]
1631 pub fn logf64(x: f64) -> f64;
1632
1633 /// Returns the base 10 logarithm of an `f32`.
1634 ///
1635 /// The stabilized version of this intrinsic is
1636 /// [`f32::log10`](../../std/primitive.f32.html#method.log10)
1637 #[rustc_nounwind]
1638 pub fn log10f32(x: f32) -> f32;
1639 /// Returns the base 10 logarithm of an `f64`.
1640 ///
1641 /// The stabilized version of this intrinsic is
1642 /// [`f64::log10`](../../std/primitive.f64.html#method.log10)
1643 #[rustc_nounwind]
1644 pub fn log10f64(x: f64) -> f64;
1645
1646 /// Returns the base 2 logarithm of an `f32`.
1647 ///
1648 /// The stabilized version of this intrinsic is
1649 /// [`f32::log2`](../../std/primitive.f32.html#method.log2)
1650 #[rustc_nounwind]
1651 pub fn log2f32(x: f32) -> f32;
1652 /// Returns the base 2 logarithm of an `f64`.
1653 ///
1654 /// The stabilized version of this intrinsic is
1655 /// [`f64::log2`](../../std/primitive.f64.html#method.log2)
1656 #[rustc_nounwind]
1657 pub fn log2f64(x: f64) -> f64;
1658
1659 /// Returns `a * b + c` for `f32` values.
1660 ///
1661 /// The stabilized version of this intrinsic is
1662 /// [`f32::mul_add`](../../std/primitive.f32.html#method.mul_add)
1663 #[rustc_nounwind]
1664 pub fn fmaf32(a: f32, b: f32, c: f32) -> f32;
1665 /// Returns `a * b + c` for `f64` values.
1666 ///
1667 /// The stabilized version of this intrinsic is
1668 /// [`f64::mul_add`](../../std/primitive.f64.html#method.mul_add)
1669 #[rustc_nounwind]
1670 pub fn fmaf64(a: f64, b: f64, c: f64) -> f64;
1671
1672 /// Returns the absolute value of an `f32`.
1673 ///
1674 /// The stabilized version of this intrinsic is
1675 /// [`f32::abs`](../../std/primitive.f32.html#method.abs)
1676 #[rustc_nounwind]
1677 pub fn fabsf32(x: f32) -> f32;
1678 /// Returns the absolute value of an `f64`.
1679 ///
1680 /// The stabilized version of this intrinsic is
1681 /// [`f64::abs`](../../std/primitive.f64.html#method.abs)
1682 #[rustc_nounwind]
1683 pub fn fabsf64(x: f64) -> f64;
1684
1685 /// Returns the minimum of two `f32` values.
1686 ///
1687 /// Note that, unlike most intrinsics, this is safe to call;
1688 /// it does not require an `unsafe` block.
1689 /// Therefore, implementations must not require the user to uphold
1690 /// any safety invariants.
1691 ///
1692 /// The stabilized version of this intrinsic is
1693 /// [`f32::min`]
1694 #[rustc_safe_intrinsic]
1695 #[rustc_nounwind]
1696 pub fn minnumf32(x: f32, y: f32) -> f32;
1697 /// Returns the minimum of two `f64` values.
1698 ///
1699 /// Note that, unlike most intrinsics, this is safe to call;
1700 /// it does not require an `unsafe` block.
1701 /// Therefore, implementations must not require the user to uphold
1702 /// any safety invariants.
1703 ///
1704 /// The stabilized version of this intrinsic is
1705 /// [`f64::min`]
1706 #[rustc_safe_intrinsic]
1707 #[rustc_nounwind]
1708 pub fn minnumf64(x: f64, y: f64) -> f64;
1709 /// Returns the maximum of two `f32` values.
1710 ///
1711 /// Note that, unlike most intrinsics, this is safe to call;
1712 /// it does not require an `unsafe` block.
1713 /// Therefore, implementations must not require the user to uphold
1714 /// any safety invariants.
1715 ///
1716 /// The stabilized version of this intrinsic is
1717 /// [`f32::max`]
1718 #[rustc_safe_intrinsic]
1719 #[rustc_nounwind]
1720 pub fn maxnumf32(x: f32, y: f32) -> f32;
1721 /// Returns the maximum of two `f64` values.
1722 ///
1723 /// Note that, unlike most intrinsics, this is safe to call;
1724 /// it does not require an `unsafe` block.
1725 /// Therefore, implementations must not require the user to uphold
1726 /// any safety invariants.
1727 ///
1728 /// The stabilized version of this intrinsic is
1729 /// [`f64::max`]
1730 #[rustc_safe_intrinsic]
1731 #[rustc_nounwind]
1732 pub fn maxnumf64(x: f64, y: f64) -> f64;
1733
1734 /// Copies the sign from `y` to `x` for `f32` values.
1735 ///
1736 /// The stabilized version of this intrinsic is
1737 /// [`f32::copysign`](../../std/primitive.f32.html#method.copysign)
1738 #[rustc_nounwind]
1739 pub fn copysignf32(x: f32, y: f32) -> f32;
1740 /// Copies the sign from `y` to `x` for `f64` values.
1741 ///
1742 /// The stabilized version of this intrinsic is
1743 /// [`f64::copysign`](../../std/primitive.f64.html#method.copysign)
1744 #[rustc_nounwind]
1745 pub fn copysignf64(x: f64, y: f64) -> f64;
1746
1747 /// Returns the largest integer less than or equal to an `f32`.
1748 ///
1749 /// The stabilized version of this intrinsic is
1750 /// [`f32::floor`](../../std/primitive.f32.html#method.floor)
1751 #[rustc_nounwind]
1752 pub fn floorf32(x: f32) -> f32;
1753 /// Returns the largest integer less than or equal to an `f64`.
1754 ///
1755 /// The stabilized version of this intrinsic is
1756 /// [`f64::floor`](../../std/primitive.f64.html#method.floor)
1757 #[rustc_nounwind]
1758 pub fn floorf64(x: f64) -> f64;
1759
1760 /// Returns the smallest integer greater than or equal to an `f32`.
1761 ///
1762 /// The stabilized version of this intrinsic is
1763 /// [`f32::ceil`](../../std/primitive.f32.html#method.ceil)
1764 #[rustc_nounwind]
1765 pub fn ceilf32(x: f32) -> f32;
1766 /// Returns the smallest integer greater than or equal to an `f64`.
1767 ///
1768 /// The stabilized version of this intrinsic is
1769 /// [`f64::ceil`](../../std/primitive.f64.html#method.ceil)
1770 #[rustc_nounwind]
1771 pub fn ceilf64(x: f64) -> f64;
1772
1773 /// Returns the integer part of an `f32`.
1774 ///
1775 /// The stabilized version of this intrinsic is
1776 /// [`f32::trunc`](../../std/primitive.f32.html#method.trunc)
1777 #[rustc_nounwind]
1778 pub fn truncf32(x: f32) -> f32;
1779 /// Returns the integer part of an `f64`.
1780 ///
1781 /// The stabilized version of this intrinsic is
1782 /// [`f64::trunc`](../../std/primitive.f64.html#method.trunc)
1783 #[rustc_nounwind]
1784 pub fn truncf64(x: f64) -> f64;
1785
1786 /// Returns the nearest integer to an `f32`. Changing the rounding mode is not possible in Rust,
1787 /// so this rounds half-way cases to the number with an even least significant digit.
1788 ///
1789 /// May raise an inexact floating-point exception if the argument is not an integer.
1790 /// However, Rust assumes floating-point exceptions cannot be observed, so these exceptions
1791 /// cannot actually be utilized from Rust code.
1792 /// In other words, this intrinsic is equivalent in behavior to `nearbyintf32` and `roundevenf32`.
1793 ///
1794 /// The stabilized version of this intrinsic is
1795 /// [`f32::round_ties_even`](../../std/primitive.f32.html#method.round_ties_even)
1796 #[rustc_nounwind]
1797 pub fn rintf32(x: f32) -> f32;
1798 /// Returns the nearest integer to an `f64`. Changing the rounding mode is not possible in Rust,
1799 /// so this rounds half-way cases to the number with an even least significant digit.
1800 ///
1801 /// May raise an inexact floating-point exception if the argument is not an integer.
1802 /// However, Rust assumes floating-point exceptions cannot be observed, so these exceptions
1803 /// cannot actually be utilized from Rust code.
1804 /// In other words, this intrinsic is equivalent in behavior to `nearbyintf64` and `roundevenf64`.
1805 ///
1806 /// The stabilized version of this intrinsic is
1807 /// [`f64::round_ties_even`](../../std/primitive.f64.html#method.round_ties_even)
1808 #[rustc_nounwind]
1809 pub fn rintf64(x: f64) -> f64;
1810
1811 /// Returns the nearest integer to an `f32`. Changing the rounding mode is not possible in Rust,
1812 /// so this rounds half-way cases to the number with an even least significant digit.
1813 ///
1814 /// This intrinsic does not have a stable counterpart.
1815 #[rustc_nounwind]
1816 pub fn nearbyintf32(x: f32) -> f32;
1817 /// Returns the nearest integer to an `f64`. Changing the rounding mode is not possible in Rust,
1818 /// so this rounds half-way cases to the number with an even least significant digit.
1819 ///
1820 /// This intrinsic does not have a stable counterpart.
1821 #[rustc_nounwind]
1822 pub fn nearbyintf64(x: f64) -> f64;
1823
1824 /// Returns the nearest integer to an `f32`. Rounds half-way cases away from zero.
1825 ///
1826 /// The stabilized version of this intrinsic is
1827 /// [`f32::round`](../../std/primitive.f32.html#method.round)
1828 #[rustc_nounwind]
1829 pub fn roundf32(x: f32) -> f32;
1830 /// Returns the nearest integer to an `f64`. Rounds half-way cases away from zero.
1831 ///
1832 /// The stabilized version of this intrinsic is
1833 /// [`f64::round`](../../std/primitive.f64.html#method.round)
1834 #[rustc_nounwind]
1835 pub fn roundf64(x: f64) -> f64;
1836
1837 /// Returns the nearest integer to an `f32`. Rounds half-way cases to the number
1838 /// with an even least significant digit.
1839 ///
1840 /// This intrinsic does not have a stable counterpart.
1841 #[rustc_nounwind]
1842 pub fn roundevenf32(x: f32) -> f32;
1843 /// Returns the nearest integer to an `f64`. Rounds half-way cases to the number
1844 /// with an even least significant digit.
1845 ///
1846 /// This intrinsic does not have a stable counterpart.
1847 #[rustc_nounwind]
1848 pub fn roundevenf64(x: f64) -> f64;
1849
1850 /// Float addition that allows optimizations based on algebraic rules.
1851 /// May assume inputs are finite.
1852 ///
1853 /// This intrinsic does not have a stable counterpart.
1854 #[rustc_nounwind]
1855 pub fn fadd_fast<T: Copy>(a: T, b: T) -> T;
1856
1857 /// Float subtraction that allows optimizations based on algebraic rules.
1858 /// May assume inputs are finite.
1859 ///
1860 /// This intrinsic does not have a stable counterpart.
1861 #[rustc_nounwind]
1862 pub fn fsub_fast<T: Copy>(a: T, b: T) -> T;
1863
1864 /// Float multiplication that allows optimizations based on algebraic rules.
1865 /// May assume inputs are finite.
1866 ///
1867 /// This intrinsic does not have a stable counterpart.
1868 #[rustc_nounwind]
1869 pub fn fmul_fast<T: Copy>(a: T, b: T) -> T;
1870
1871 /// Float division that allows optimizations based on algebraic rules.
1872 /// May assume inputs are finite.
1873 ///
1874 /// This intrinsic does not have a stable counterpart.
1875 #[rustc_nounwind]
1876 pub fn fdiv_fast<T: Copy>(a: T, b: T) -> T;
1877
1878 /// Float remainder that allows optimizations based on algebraic rules.
1879 /// May assume inputs are finite.
1880 ///
1881 /// This intrinsic does not have a stable counterpart.
1882 #[rustc_nounwind]
1883 pub fn frem_fast<T: Copy>(a: T, b: T) -> T;
1884
1885 /// Convert with LLVM’s fptoui/fptosi, which may return undef for values out of range
1886 /// (<https://github.com/rust-lang/rust/issues/10184>)
1887 ///
1888 /// Stabilized as [`f32::to_int_unchecked`] and [`f64::to_int_unchecked`].
1889 #[rustc_nounwind]
1890 pub fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int;
1891
1892 /// Returns the number of bits set in an integer type `T`
1893 ///
1894 /// Note that, unlike most intrinsics, this is safe to call;
1895 /// it does not require an `unsafe` block.
1896 /// Therefore, implementations must not require the user to uphold
1897 /// any safety invariants.
1898 ///
1899 /// The stabilized versions of this intrinsic are available on the integer
1900 /// primitives via the `count_ones` method. For example,
1901 /// [`u32::count_ones`]
1902 #[rustc_const_stable(feature = "const_ctpop", since = "1.40.0")]
1903 #[rustc_safe_intrinsic]
1904 #[rustc_nounwind]
1905 pub fn ctpop<T: Copy>(x: T) -> T;
1906
1907 /// Returns the number of leading unset bits (zeroes) in an integer type `T`.
1908 ///
1909 /// Note that, unlike most intrinsics, this is safe to call;
1910 /// it does not require an `unsafe` block.
1911 /// Therefore, implementations must not require the user to uphold
1912 /// any safety invariants.
1913 ///
1914 /// The stabilized versions of this intrinsic are available on the integer
1915 /// primitives via the `leading_zeros` method. For example,
1916 /// [`u32::leading_zeros`]
1917 ///
1918 /// # Examples
1919 ///
1920 /// ```
1921 /// #![feature(core_intrinsics)]
1922 /// # #![allow(internal_features)]
1923 ///
1924 /// use std::intrinsics::ctlz;
1925 ///
1926 /// let x = 0b0001_1100_u8;
1927 /// let num_leading = ctlz(x);
1928 /// assert_eq!(num_leading, 3);
1929 /// ```
1930 ///
1931 /// An `x` with value `0` will return the bit width of `T`.
1932 ///
1933 /// ```
1934 /// #![feature(core_intrinsics)]
1935 /// # #![allow(internal_features)]
1936 ///
1937 /// use std::intrinsics::ctlz;
1938 ///
1939 /// let x = 0u16;
1940 /// let num_leading = ctlz(x);
1941 /// assert_eq!(num_leading, 16);
1942 /// ```
1943 #[rustc_const_stable(feature = "const_ctlz", since = "1.40.0")]
1944 #[rustc_safe_intrinsic]
1945 #[rustc_nounwind]
1946 pub fn ctlz<T: Copy>(x: T) -> T;
1947
1948 /// Like `ctlz`, but extra-unsafe as it returns `undef` when
1949 /// given an `x` with value `0`.
1950 ///
1951 /// This intrinsic does not have a stable counterpart.
1952 ///
1953 /// # Examples
1954 ///
1955 /// ```
1956 /// #![feature(core_intrinsics)]
1957 /// # #![allow(internal_features)]
1958 ///
1959 /// use std::intrinsics::ctlz_nonzero;
1960 ///
1961 /// let x = 0b0001_1100_u8;
1962 /// let num_leading = unsafe { ctlz_nonzero(x) };
1963 /// assert_eq!(num_leading, 3);
1964 /// ```
1965 #[rustc_const_stable(feature = "constctlz", since = "1.50.0")]
1966 #[rustc_nounwind]
1967 pub fn ctlz_nonzero<T: Copy>(x: T) -> T;
1968
1969 /// Returns the number of trailing unset bits (zeroes) in an integer type `T`.
1970 ///
1971 /// Note that, unlike most intrinsics, this is safe to call;
1972 /// it does not require an `unsafe` block.
1973 /// Therefore, implementations must not require the user to uphold
1974 /// any safety invariants.
1975 ///
1976 /// The stabilized versions of this intrinsic are available on the integer
1977 /// primitives via the `trailing_zeros` method. For example,
1978 /// [`u32::trailing_zeros`]
1979 ///
1980 /// # Examples
1981 ///
1982 /// ```
1983 /// #![feature(core_intrinsics)]
1984 /// # #![allow(internal_features)]
1985 ///
1986 /// use std::intrinsics::cttz;
1987 ///
1988 /// let x = 0b0011_1000_u8;
1989 /// let num_trailing = cttz(x);
1990 /// assert_eq!(num_trailing, 3);
1991 /// ```
1992 ///
1993 /// An `x` with value `0` will return the bit width of `T`:
1994 ///
1995 /// ```
1996 /// #![feature(core_intrinsics)]
1997 /// # #![allow(internal_features)]
1998 ///
1999 /// use std::intrinsics::cttz;
2000 ///
2001 /// let x = 0u16;
2002 /// let num_trailing = cttz(x);
2003 /// assert_eq!(num_trailing, 16);
2004 /// ```
2005 #[rustc_const_stable(feature = "const_cttz", since = "1.40.0")]
2006 #[rustc_safe_intrinsic]
2007 #[rustc_nounwind]
2008 pub fn cttz<T: Copy>(x: T) -> T;
2009
2010 /// Like `cttz`, but extra-unsafe as it returns `undef` when
2011 /// given an `x` with value `0`.
2012 ///
2013 /// This intrinsic does not have a stable counterpart.
2014 ///
2015 /// # Examples
2016 ///
2017 /// ```
2018 /// #![feature(core_intrinsics)]
2019 /// # #![allow(internal_features)]
2020 ///
2021 /// use std::intrinsics::cttz_nonzero;
2022 ///
2023 /// let x = 0b0011_1000_u8;
2024 /// let num_trailing = unsafe { cttz_nonzero(x) };
2025 /// assert_eq!(num_trailing, 3);
2026 /// ```
2027 #[rustc_const_stable(feature = "const_cttz_nonzero", since = "1.53.0")]
2028 #[rustc_nounwind]
2029 pub fn cttz_nonzero<T: Copy>(x: T) -> T;
2030
2031 /// Reverses the bytes in an integer type `T`.
2032 ///
2033 /// Note that, unlike most intrinsics, this is safe to call;
2034 /// it does not require an `unsafe` block.
2035 /// Therefore, implementations must not require the user to uphold
2036 /// any safety invariants.
2037 ///
2038 /// The stabilized versions of this intrinsic are available on the integer
2039 /// primitives via the `swap_bytes` method. For example,
2040 /// [`u32::swap_bytes`]
2041 #[rustc_const_stable(feature = "const_bswap", since = "1.40.0")]
2042 #[rustc_safe_intrinsic]
2043 #[rustc_nounwind]
2044 pub fn bswap<T: Copy>(x: T) -> T;
2045
2046 /// Reverses the bits in an integer type `T`.
2047 ///
2048 /// Note that, unlike most intrinsics, this is safe to call;
2049 /// it does not require an `unsafe` block.
2050 /// Therefore, implementations must not require the user to uphold
2051 /// any safety invariants.
2052 ///
2053 /// The stabilized versions of this intrinsic are available on the integer
2054 /// primitives via the `reverse_bits` method. For example,
2055 /// [`u32::reverse_bits`]
2056 #[rustc_const_stable(feature = "const_bitreverse", since = "1.40.0")]
2057 #[rustc_safe_intrinsic]
2058 #[rustc_nounwind]
2059 pub fn bitreverse<T: Copy>(x: T) -> T;
2060
2061 /// Performs checked integer addition.
2062 ///
2063 /// Note that, unlike most intrinsics, this is safe to call;
2064 /// it does not require an `unsafe` block.
2065 /// Therefore, implementations must not require the user to uphold
2066 /// any safety invariants.
2067 ///
2068 /// The stabilized versions of this intrinsic are available on the integer
2069 /// primitives via the `overflowing_add` method. For example,
2070 /// [`u32::overflowing_add`]
2071 #[rustc_const_stable(feature = "const_int_overflow", since = "1.40.0")]
2072 #[rustc_safe_intrinsic]
2073 #[rustc_nounwind]
2074 pub fn add_with_overflow<T: Copy>(x: T, y: T) -> (T, bool);
2075
2076 /// Performs checked integer subtraction
2077 ///
2078 /// Note that, unlike most intrinsics, this is safe to call;
2079 /// it does not require an `unsafe` block.
2080 /// Therefore, implementations must not require the user to uphold
2081 /// any safety invariants.
2082 ///
2083 /// The stabilized versions of this intrinsic are available on the integer
2084 /// primitives via the `overflowing_sub` method. For example,
2085 /// [`u32::overflowing_sub`]
2086 #[rustc_const_stable(feature = "const_int_overflow", since = "1.40.0")]
2087 #[rustc_safe_intrinsic]
2088 #[rustc_nounwind]
2089 pub fn sub_with_overflow<T: Copy>(x: T, y: T) -> (T, bool);
2090
2091 /// Performs checked integer multiplication
2092 ///
2093 /// Note that, unlike most intrinsics, this is safe to call;
2094 /// it does not require an `unsafe` block.
2095 /// Therefore, implementations must not require the user to uphold
2096 /// any safety invariants.
2097 ///
2098 /// The stabilized versions of this intrinsic are available on the integer
2099 /// primitives via the `overflowing_mul` method. For example,
2100 /// [`u32::overflowing_mul`]
2101 #[rustc_const_stable(feature = "const_int_overflow", since = "1.40.0")]
2102 #[rustc_safe_intrinsic]
2103 #[rustc_nounwind]
2104 pub fn mul_with_overflow<T: Copy>(x: T, y: T) -> (T, bool);
2105
2106 /// Performs an exact division, resulting in undefined behavior where
2107 /// `x % y != 0` or `y == 0` or `x == T::MIN && y == -1`
2108 ///
2109 /// This intrinsic does not have a stable counterpart.
2110 #[rustc_const_unstable(feature = "const_exact_div", issue = "none")]
2111 #[rustc_nounwind]
2112 pub fn exact_div<T: Copy>(x: T, y: T) -> T;
2113
2114 /// Performs an unchecked division, resulting in undefined behavior
2115 /// where `y == 0` or `x == T::MIN && y == -1`
2116 ///
2117 /// Safe wrappers for this intrinsic are available on the integer
2118 /// primitives via the `checked_div` method. For example,
2119 /// [`u32::checked_div`]
2120 #[rustc_const_stable(feature = "const_int_unchecked_div", since = "1.52.0")]
2121 #[rustc_nounwind]
2122 pub fn unchecked_div<T: Copy>(x: T, y: T) -> T;
2123 /// Returns the remainder of an unchecked division, resulting in
2124 /// undefined behavior when `y == 0` or `x == T::MIN && y == -1`
2125 ///
2126 /// Safe wrappers for this intrinsic are available on the integer
2127 /// primitives via the `checked_rem` method. For example,
2128 /// [`u32::checked_rem`]
2129 #[rustc_const_stable(feature = "const_int_unchecked_rem", since = "1.52.0")]
2130 #[rustc_nounwind]
2131 pub fn unchecked_rem<T: Copy>(x: T, y: T) -> T;
2132
2133 /// Performs an unchecked left shift, resulting in undefined behavior when
2134 /// `y < 0` or `y >= N`, where N is the width of T in bits.
2135 ///
2136 /// Safe wrappers for this intrinsic are available on the integer
2137 /// primitives via the `checked_shl` method. For example,
2138 /// [`u32::checked_shl`]
2139 #[rustc_const_stable(feature = "const_int_unchecked", since = "1.40.0")]
2140 #[rustc_nounwind]
2141 pub fn unchecked_shl<T: Copy>(x: T, y: T) -> T;
2142 /// Performs an unchecked right shift, resulting in undefined behavior when
2143 /// `y < 0` or `y >= N`, where N is the width of T in bits.
2144 ///
2145 /// Safe wrappers for this intrinsic are available on the integer
2146 /// primitives via the `checked_shr` method. For example,
2147 /// [`u32::checked_shr`]
2148 #[rustc_const_stable(feature = "const_int_unchecked", since = "1.40.0")]
2149 #[rustc_nounwind]
2150 pub fn unchecked_shr<T: Copy>(x: T, y: T) -> T;
2151
2152 /// Returns the result of an unchecked addition, resulting in
2153 /// undefined behavior when `x + y > T::MAX` or `x + y < T::MIN`.
2154 ///
2155 /// This intrinsic does not have a stable counterpart.
2156 #[rustc_const_unstable(feature = "const_int_unchecked_arith", issue = "none")]
2157 #[rustc_nounwind]
2158 pub fn unchecked_add<T: Copy>(x: T, y: T) -> T;
2159
2160 /// Returns the result of an unchecked subtraction, resulting in
2161 /// undefined behavior when `x - y > T::MAX` or `x - y < T::MIN`.
2162 ///
2163 /// This intrinsic does not have a stable counterpart.
2164 #[rustc_const_unstable(feature = "const_int_unchecked_arith", issue = "none")]
2165 #[rustc_nounwind]
2166 pub fn unchecked_sub<T: Copy>(x: T, y: T) -> T;
2167
2168 /// Returns the result of an unchecked multiplication, resulting in
2169 /// undefined behavior when `x * y > T::MAX` or `x * y < T::MIN`.
2170 ///
2171 /// This intrinsic does not have a stable counterpart.
2172 #[rustc_const_unstable(feature = "const_int_unchecked_arith", issue = "none")]
2173 #[rustc_nounwind]
2174 pub fn unchecked_mul<T: Copy>(x: T, y: T) -> T;
2175
2176 /// Performs rotate left.
2177 ///
2178 /// Note that, unlike most intrinsics, this is safe to call;
2179 /// it does not require an `unsafe` block.
2180 /// Therefore, implementations must not require the user to uphold
2181 /// any safety invariants.
2182 ///
2183 /// The stabilized versions of this intrinsic are available on the integer
2184 /// primitives via the `rotate_left` method. For example,
2185 /// [`u32::rotate_left`]
2186 #[rustc_const_stable(feature = "const_int_rotate", since = "1.40.0")]
2187 #[rustc_safe_intrinsic]
2188 #[rustc_nounwind]
2189 pub fn rotate_left<T: Copy>(x: T, y: T) -> T;
2190
2191 /// Performs rotate right.
2192 ///
2193 /// Note that, unlike most intrinsics, this is safe to call;
2194 /// it does not require an `unsafe` block.
2195 /// Therefore, implementations must not require the user to uphold
2196 /// any safety invariants.
2197 ///
2198 /// The stabilized versions of this intrinsic are available on the integer
2199 /// primitives via the `rotate_right` method. For example,
2200 /// [`u32::rotate_right`]
2201 #[rustc_const_stable(feature = "const_int_rotate", since = "1.40.0")]
2202 #[rustc_safe_intrinsic]
2203 #[rustc_nounwind]
2204 pub fn rotate_right<T: Copy>(x: T, y: T) -> T;
2205
2206 /// Returns (a + b) mod 2<sup>N</sup>, where N is the width of T in bits.
2207 ///
2208 /// Note that, unlike most intrinsics, this is safe to call;
2209 /// it does not require an `unsafe` block.
2210 /// Therefore, implementations must not require the user to uphold
2211 /// any safety invariants.
2212 ///
2213 /// The stabilized versions of this intrinsic are available on the integer
2214 /// primitives via the `wrapping_add` method. For example,
2215 /// [`u32::wrapping_add`]
2216 #[rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0")]
2217 #[rustc_safe_intrinsic]
2218 #[rustc_nounwind]
2219 pub fn wrapping_add<T: Copy>(a: T, b: T) -> T;
2220 /// Returns (a - b) mod 2<sup>N</sup>, where N is the width of T in bits.
2221 ///
2222 /// Note that, unlike most intrinsics, this is safe to call;
2223 /// it does not require an `unsafe` block.
2224 /// Therefore, implementations must not require the user to uphold
2225 /// any safety invariants.
2226 ///
2227 /// The stabilized versions of this intrinsic are available on the integer
2228 /// primitives via the `wrapping_sub` method. For example,
2229 /// [`u32::wrapping_sub`]
2230 #[rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0")]
2231 #[rustc_safe_intrinsic]
2232 #[rustc_nounwind]
2233 pub fn wrapping_sub<T: Copy>(a: T, b: T) -> T;
2234 /// Returns (a * b) mod 2<sup>N</sup>, where N is the width of T in bits.
2235 ///
2236 /// Note that, unlike most intrinsics, this is safe to call;
2237 /// it does not require an `unsafe` block.
2238 /// Therefore, implementations must not require the user to uphold
2239 /// any safety invariants.
2240 ///
2241 /// The stabilized versions of this intrinsic are available on the integer
2242 /// primitives via the `wrapping_mul` method. For example,
2243 /// [`u32::wrapping_mul`]
2244 #[rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0")]
2245 #[rustc_safe_intrinsic]
2246 #[rustc_nounwind]
2247 pub fn wrapping_mul<T: Copy>(a: T, b: T) -> T;
2248
2249 /// Computes `a + b`, saturating at numeric bounds.
2250 ///
2251 /// Note that, unlike most intrinsics, this is safe to call;
2252 /// it does not require an `unsafe` block.
2253 /// Therefore, implementations must not require the user to uphold
2254 /// any safety invariants.
2255 ///
2256 /// The stabilized versions of this intrinsic are available on the integer
2257 /// primitives via the `saturating_add` method. For example,
2258 /// [`u32::saturating_add`]
2259 #[rustc_const_stable(feature = "const_int_saturating", since = "1.40.0")]
2260 #[rustc_safe_intrinsic]
2261 #[rustc_nounwind]
2262 pub fn saturating_add<T: Copy>(a: T, b: T) -> T;
2263 /// Computes `a - b`, saturating at numeric bounds.
2264 ///
2265 /// Note that, unlike most intrinsics, this is safe to call;
2266 /// it does not require an `unsafe` block.
2267 /// Therefore, implementations must not require the user to uphold
2268 /// any safety invariants.
2269 ///
2270 /// The stabilized versions of this intrinsic are available on the integer
2271 /// primitives via the `saturating_sub` method. For example,
2272 /// [`u32::saturating_sub`]
2273 #[rustc_const_stable(feature = "const_int_saturating", since = "1.40.0")]
2274 #[rustc_safe_intrinsic]
2275 #[rustc_nounwind]
2276 pub fn saturating_sub<T: Copy>(a: T, b: T) -> T;
2277
2278 /// This is an implementation detail of [`crate::ptr::read`] and should
2279 /// not be used anywhere else. See its comments for why this exists.
2280 ///
2281 /// This intrinsic can *only* be called where the pointer is a local without
2282 /// projections (`read_via_copy(ptr)`, not `read_via_copy(*ptr)`) so that it
2283 /// trivially obeys runtime-MIR rules about derefs in operands.
2284 #[rustc_const_stable(feature = "const_ptr_read", since = "1.71.0")]
2285 #[rustc_nounwind]
2286 pub fn read_via_copy<T>(ptr: *const T) -> T;
2287
2288 /// This is an implementation detail of [`crate::ptr::write`] and should
2289 /// not be used anywhere else. See its comments for why this exists.
2290 ///
2291 /// This intrinsic can *only* be called where the pointer is a local without
2292 /// projections (`write_via_move(ptr, x)`, not `write_via_move(*ptr, x)`) so
2293 /// that it trivially obeys runtime-MIR rules about derefs in operands.
2294 #[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
2295 #[rustc_nounwind]
2296 pub fn write_via_move<T>(ptr: *mut T, value: T);
2297
2298 /// Returns the value of the discriminant for the variant in 'v';
2299 /// if `T` has no discriminant, returns `0`.
2300 ///
2301 /// Note that, unlike most intrinsics, this is safe to call;
2302 /// it does not require an `unsafe` block.
2303 /// Therefore, implementations must not require the user to uphold
2304 /// any safety invariants.
2305 ///
2306 /// The stabilized version of this intrinsic is [`core::mem::discriminant`].
2307 #[rustc_const_stable(feature = "const_discriminant", since = "1.75.0")]
2308 #[rustc_safe_intrinsic]
2309 #[rustc_nounwind]
2310 pub fn discriminant_value<T>(v: &T) -> <T as DiscriminantKind>::Discriminant;
2311
2312 /// Returns the number of variants of the type `T` cast to a `usize`;
2313 /// if `T` has no variants, returns `0`. Uninhabited variants will be counted.
2314 ///
2315 /// Note that, unlike most intrinsics, this is safe to call;
2316 /// it does not require an `unsafe` block.
2317 /// Therefore, implementations must not require the user to uphold
2318 /// any safety invariants.
2319 ///
2320 /// The to-be-stabilized version of this intrinsic is [`mem::variant_count`].
2321 #[rustc_const_unstable(feature = "variant_count", issue = "73662")]
2322 #[rustc_safe_intrinsic]
2323 #[rustc_nounwind]
2324 pub fn variant_count<T>() -> usize;
2325
2326 /// Rust's "try catch" construct which invokes the function pointer `try_fn`
2327 /// with the data pointer `data`.
2328 ///
2329 /// The third argument is a function called if a panic occurs. This function
2330 /// takes the data pointer and a pointer to the target-specific exception
2331 /// object that was caught. For more information see the compiler's
2332 /// source as well as std's catch implementation.
2333 ///
2334 /// `catch_fn` must not unwind.
2335 #[rustc_nounwind]
2336 pub fn r#try(try_fn: fn(*mut u8), data: *mut u8, catch_fn: fn(*mut u8, *mut u8)) -> i32;
2337
2338 /// Emits a `!nontemporal` store according to LLVM (see their docs).
2339 /// Probably will never become stable.
2340 ///
2341 /// Do NOT use this intrinsic; "nontemporal" operations do not exist in our memory model!
2342 /// It exists to support current stdarch, but the plan is to change stdarch and remove this intrinsic.
2343 /// See <https://github.com/rust-lang/rust/issues/114582> for some more discussion.
2344 #[rustc_nounwind]
2345 pub fn nontemporal_store<T>(ptr: *mut T, val: T);
2346
2347 /// See documentation of `<*const T>::offset_from` for details.
2348 #[rustc_const_stable(feature = "const_ptr_offset_from", since = "1.65.0")]
2349 #[rustc_nounwind]
2350 pub fn ptr_offset_from<T>(ptr: *const T, base: *const T) -> isize;
2351
2352 /// See documentation of `<*const T>::sub_ptr` for details.
2353 #[rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892")]
2354 #[rustc_nounwind]
2355 pub fn ptr_offset_from_unsigned<T>(ptr: *const T, base: *const T) -> usize;
2356
2357 /// See documentation of `<*const T>::guaranteed_eq` for details.
2358 /// Returns `2` if the result is unknown.
2359 /// Returns `1` if the pointers are guaranteed equal
2360 /// Returns `0` if the pointers are guaranteed inequal
2361 ///
2362 /// Note that, unlike most intrinsics, this is safe to call;
2363 /// it does not require an `unsafe` block.
2364 /// Therefore, implementations must not require the user to uphold
2365 /// any safety invariants.
2366 #[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
2367 #[rustc_safe_intrinsic]
2368 #[rustc_nounwind]
2369 pub fn ptr_guaranteed_cmp<T>(ptr: *const T, other: *const T) -> u8;
2370
2371 /// Allocates a block of memory at compile time.
2372 /// At runtime, just returns a null pointer.
2373 ///
2374 /// # Safety
2375 ///
2376 /// - The `align` argument must be a power of two.
2377 /// - At compile time, a compile error occurs if this constraint is violated.
2378 /// - At runtime, it is not checked.
2379 #[rustc_const_unstable(feature = "const_heap", issue = "79597")]
2380 #[rustc_nounwind]
2381 pub fn const_allocate(size: usize, align: usize) -> *mut u8;
2382
2383 /// Deallocates a memory which allocated by `intrinsics::const_allocate` at compile time.
2384 /// At runtime, does nothing.
2385 ///
2386 /// # Safety
2387 ///
2388 /// - The `align` argument must be a power of two.
2389 /// - At compile time, a compile error occurs if this constraint is violated.
2390 /// - At runtime, it is not checked.
2391 /// - If the `ptr` is created in an another const, this intrinsic doesn't deallocate it.
2392 /// - If the `ptr` is pointing to a local variable, this intrinsic doesn't deallocate it.
2393 #[rustc_const_unstable(feature = "const_heap", issue = "79597")]
2394 #[rustc_nounwind]
2395 pub fn const_deallocate(ptr: *mut u8, size: usize, align: usize);
2396
2397 /// Determines whether the raw bytes of the two values are equal.
2398 ///
2399 /// This is particularly handy for arrays, since it allows things like just
2400 /// comparing `i96`s instead of forcing `alloca`s for `[6 x i16]`.
2401 ///
2402 /// Above some backend-decided threshold this will emit calls to `memcmp`,
2403 /// like slice equality does, instead of causing massive code size.
2404 ///
2405 /// Since this works by comparing the underlying bytes, the actual `T` is
2406 /// not particularly important. It will be used for its size and alignment,
2407 /// but any validity restrictions will be ignored, not enforced.
2408 ///
2409 /// # Safety
2410 ///
2411 /// It's UB to call this if any of the *bytes* in `*a` or `*b` are uninitialized or carry a
2412 /// pointer value.
2413 /// Note that this is a stricter criterion than just the *values* being
2414 /// fully-initialized: if `T` has padding, it's UB to call this intrinsic.
2415 ///
2416 /// (The implementation is allowed to branch on the results of comparisons,
2417 /// which is UB if any of their inputs are `undef`.)
2418 #[rustc_const_unstable(feature = "const_intrinsic_raw_eq", issue = "none")]
2419 #[rustc_nounwind]
2420 pub fn raw_eq<T>(a: &T, b: &T) -> bool;
2421
2422 /// Lexicographically compare `[left, left + bytes)` and `[right, right + bytes)`
2423 /// as unsigned bytes, returning negative if `left` is less, zero if all the
2424 /// bytes match, or positive if `right` is greater.
2425 ///
2426 /// This underlies things like `<[u8]>::cmp`, and will usually lower to `memcmp`.
2427 ///
2428 /// # Safety
2429 ///
2430 /// `left` and `right` must each be [valid] for reads of `bytes` bytes.
2431 ///
2432 /// Note that this applies to the whole range, not just until the first byte
2433 /// that differs. That allows optimizations that can read in large chunks.
2434 ///
2435 /// [valid]: crate::ptr#safety
2436 #[rustc_const_unstable(feature = "const_intrinsic_compare_bytes", issue = "none")]
2437 #[rustc_nounwind]
2438 pub fn compare_bytes(left: *const u8, right: *const u8, bytes: usize) -> i32;
2439
2440 /// See documentation of [`std::hint::black_box`] for details.
2441 ///
2442 /// [`std::hint::black_box`]: crate::hint::black_box
2443 #[rustc_const_unstable(feature = "const_black_box", issue = "none")]
2444 #[rustc_safe_intrinsic]
2445 #[rustc_nounwind]
2446 pub fn black_box<T>(dummy: T) -> T;
2447
2448 /// `ptr` must point to a vtable.
2449 /// The intrinsic will return the size stored in that vtable.
2450 #[rustc_nounwind]
2451 pub fn vtable_size(ptr: *const ()) -> usize;
2452
2453 /// `ptr` must point to a vtable.
2454 /// The intrinsic will return the alignment stored in that vtable.
2455 #[rustc_nounwind]
2456 pub fn vtable_align(ptr: *const ()) -> usize;
2457
2458 /// Selects which function to call depending on the context.
2459 ///
2460 /// If this function is evaluated at compile-time, then a call to this
2461 /// intrinsic will be replaced with a call to `called_in_const`. It gets
2462 /// replaced with a call to `called_at_rt` otherwise.
2463 ///
2464 /// # Type Requirements
2465 ///
2466 /// The two functions must be both function items. They cannot be function
2467 /// pointers or closures. The first function must be a `const fn`.
2468 ///
2469 /// `arg` will be the tupled arguments that will be passed to either one of
2470 /// the two functions, therefore, both functions must accept the same type of
2471 /// arguments. Both functions must return RET.
2472 ///
2473 /// # Safety
2474 ///
2475 /// The two functions must behave observably equivalent. Safe code in other
2476 /// crates may assume that calling a `const fn` at compile-time and at run-time
2477 /// produces the same result. A function that produces a different result when
2478 /// evaluated at run-time, or has any other observable side-effects, is
2479 /// *unsound*.
2480 ///
2481 /// Here is an example of how this could cause a problem:
2482 /// ```no_run
2483 /// #![feature(const_eval_select)]
2484 /// #![feature(core_intrinsics)]
2485 /// # #![allow(internal_features)]
2486 /// use std::hint::unreachable_unchecked;
2487 /// use std::intrinsics::const_eval_select;
2488 ///
2489 /// // Crate A
2490 /// pub const fn inconsistent() -> i32 {
2491 /// fn runtime() -> i32 { 1 }
2492 /// const fn compiletime() -> i32 { 2 }
2493 ///
2494 /// unsafe {
2495 // // ⚠ This code violates the required equivalence of `compiletime`
2496 /// // and `runtime`.
2497 /// const_eval_select((), compiletime, runtime)
2498 /// }
2499 /// }
2500 ///
2501 /// // Crate B
2502 /// const X: i32 = inconsistent();
2503 /// let x = inconsistent();
2504 /// if x != X { unsafe { unreachable_unchecked(); }}
2505 /// ```
2506 ///
2507 /// This code causes Undefined Behavior when being run, since the
2508 /// `unreachable_unchecked` is actually being reached. The bug is in *crate A*,
2509 /// which violates the principle that a `const fn` must behave the same at
2510 /// compile-time and at run-time. The unsafe code in crate B is fine.
2511 #[rustc_const_unstable(feature = "const_eval_select", issue = "none")]
2512 pub fn const_eval_select<ARG: Tuple, F, G, RET>(
2513 arg: ARG,
2514 called_in_const: F,
2515 called_at_rt: G,
2516 ) -> RET
2517 where
2518 G: FnOnce<ARG, Output = RET>,
2519 F: FnOnce<ARG, Output = RET>;
2520
2521 /// Returns whether the argument's value is statically known at
2522 /// compile-time.
2523 ///
2524 /// This is useful when there is a way of writing the code that will
2525 /// be *faster* when some variables have known values, but *slower*
2526 /// in the general case: an `if is_val_statically_known(var)` can be used
2527 /// to select between these two variants. The `if` will be optimized away
2528 /// and only the desired branch remains.
2529 ///
2530 /// Formally speaking, this function non-deterministically returns `true`
2531 /// or `false`, and the caller has to ensure sound behavior for both cases.
2532 /// In other words, the following code has *Undefined Behavior*:
2533 ///
2534 /// ```no_run
2535 /// #![feature(is_val_statically_known)]
2536 /// #![feature(core_intrinsics)]
2537 /// # #![allow(internal_features)]
2538 /// use std::hint::unreachable_unchecked;
2539 /// use std::intrinsics::is_val_statically_known;
2540 ///
2541 /// unsafe {
2542 /// if !is_val_statically_known(0) { unreachable_unchecked(); }
2543 /// }
2544 /// ```
2545 ///
2546 /// This also means that the following code's behavior is unspecified; it
2547 /// may panic, or it may not:
2548 ///
2549 /// ```no_run
2550 /// #![feature(is_val_statically_known)]
2551 /// #![feature(core_intrinsics)]
2552 /// # #![allow(internal_features)]
2553 /// use std::intrinsics::is_val_statically_known;
2554 ///
2555 /// unsafe {
2556 /// assert_eq!(is_val_statically_known(0), is_val_statically_known(0));
2557 /// }
2558 /// ```
2559 ///
2560 /// Unsafe code may not rely on `is_val_statically_known` returning any
2561 /// particular value, ever. However, the compiler will generally make it
2562 /// return `true` only if the value of the argument is actually known.
2563 ///
2564 /// When calling this in a `const fn`, both paths must be semantically
2565 /// equivalent, that is, the result of the `true` branch and the `false`
2566 /// branch must return the same value and have the same side-effects *no
2567 /// matter what*.
2568 #[rustc_const_unstable(feature = "is_val_statically_known", issue = "none")]
2569 #[rustc_nounwind]
2570 #[cfg(not(bootstrap))]
2571 pub fn is_val_statically_known<T: Copy>(arg: T) -> bool;
2572}
2573
2574// FIXME: Seems using `unstable` here completely ignores `rustc_allow_const_fn_unstable`
2575// and thus compiling stage0 core doesn't work.
2576#[rustc_const_stable(feature = "is_val_statically_known", since = "0.0.0")]
2577#[cfg(bootstrap)]
2578pub const unsafe fn is_val_statically_known<T: Copy>(_arg: T) -> bool {
2579 false
2580}
2581
2582// Some functions are defined here because they accidentally got made
2583// available in this module on stable. See <https://github.com/rust-lang/rust/issues/15702>.
2584// (`transmute` also falls into this category, but it cannot be wrapped due to the
2585// check that `T` and `U` have the same size.)
2586
2587/// Check that the preconditions of an unsafe function are followed, if debug_assertions are on,
2588/// and only at runtime.
2589///
2590/// This macro should be called as `assert_unsafe_precondition!([Generics](name: Type) => Expression)`
2591/// where the names specified will be moved into the macro as captured variables, and defines an item
2592/// to call `const_eval_select` on. The tokens inside the square brackets are used to denote generics
2593/// for the function declarations and can be omitted if there is no generics.
2594///
2595/// # Safety
2596///
2597/// Invoking this macro is only sound if the following code is already UB when the passed
2598/// expression evaluates to false.
2599///
2600/// This macro expands to a check at runtime if debug_assertions is set. It has no effect at
2601/// compile time, but the semantics of the contained `const_eval_select` must be the same at
2602/// runtime and at compile time. Thus if the expression evaluates to false, this macro produces
2603/// different behavior at compile time and at runtime, and invoking it is incorrect.
2604///
2605/// So in a sense it is UB if this macro is useful, but we expect callers of `unsafe fn` to make
2606/// the occasional mistake, and this check should help them figure things out.
2607#[allow_internal_unstable(const_eval_select)] // permit this to be called in stably-const fn
2608macro_rules! assert_unsafe_precondition {
2609 ($name:expr, $([$($tt:tt)*])?($($i:ident:$ty:ty),*$(,)?) => $e:expr $(,)?) => {
2610 if cfg!(debug_assertions) {
2611 // allow non_snake_case to allow capturing const generics
2612 #[allow(non_snake_case)]
2613 #[inline(always)]
2614 fn runtime$(<$($tt)*>)?($($i:$ty),*) {
2615 if !$e {
2616 // don't unwind to reduce impact on code size
2617 ::core::panicking::panic_nounwind(
2618 concat!("unsafe precondition(s) violated: ", $name)
2619 );
2620 }
2621 }
2622 #[allow(non_snake_case)]
2623 #[inline]
2624 const fn comptime$(<$($tt)*>)?($(_:$ty),*) {}
2625
2626 ::core::intrinsics::const_eval_select(($($i,)*), comptime, runtime);
2627 }
2628 };
2629}
2630pub(crate) use assert_unsafe_precondition;
2631
2632/// Checks whether `ptr` is properly aligned with respect to
2633/// `align_of::<T>()`.
2634#[inline]
2635pub(crate) fn is_aligned_and_not_null<T>(ptr: *const T) -> bool {
2636 !ptr.is_null() && ptr.is_aligned()
2637}
2638
2639/// Checks whether an allocation of `len` instances of `T` exceeds
2640/// the maximum allowed allocation size.
2641#[inline]
2642pub(crate) fn is_valid_allocation_size<T>(len: usize) -> bool {
2643 let max_len: usize = const {
2644 let size: usize = crate::mem::size_of::<T>();
2645 if size == 0 { usize::MAX } else { isize::MAX as usize / size }
2646 };
2647 len <= max_len
2648}
2649
2650/// Checks whether the regions of memory starting at `src` and `dst` of size
2651/// `count * size_of::<T>()` do *not* overlap.
2652#[inline]
2653pub(crate) fn is_nonoverlapping<T>(src: *const T, dst: *const T, count: usize) -> bool {
2654 let src_usize: usize = src.addr();
2655 let dst_usize: usize = dst.addr();
2656 let size: usize = mem::size_of::<T>()
2657 .checked_mul(count)
2658 .expect(msg:"is_nonoverlapping: `size_of::<T>() * count` overflows a usize");
2659 let diff: usize = src_usize.abs_diff(dst_usize);
2660 // If the absolute distance between the ptrs is at least as big as the size of the buffer,
2661 // they do not overlap.
2662 diff >= size
2663}
2664
2665/// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
2666/// and destination must *not* overlap.
2667///
2668/// For regions of memory which might overlap, use [`copy`] instead.
2669///
2670/// `copy_nonoverlapping` is semantically equivalent to C's [`memcpy`], but
2671/// with the argument order swapped.
2672///
2673/// The copy is "untyped" in the sense that data may be uninitialized or otherwise violate the
2674/// requirements of `T`. The initialization state is preserved exactly.
2675///
2676/// [`memcpy`]: https://en.cppreference.com/w/c/string/byte/memcpy
2677///
2678/// # Safety
2679///
2680/// Behavior is undefined if any of the following conditions are violated:
2681///
2682/// * `src` must be [valid] for reads of `count * size_of::<T>()` bytes.
2683///
2684/// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes.
2685///
2686/// * Both `src` and `dst` must be properly aligned.
2687///
2688/// * The region of memory beginning at `src` with a size of `count *
2689/// size_of::<T>()` bytes must *not* overlap with the region of memory
2690/// beginning at `dst` with the same size.
2691///
2692/// Like [`read`], `copy_nonoverlapping` creates a bitwise copy of `T`, regardless of
2693/// whether `T` is [`Copy`]. If `T` is not [`Copy`], using *both* the values
2694/// in the region beginning at `*src` and the region beginning at `*dst` can
2695/// [violate memory safety][read-ownership].
2696///
2697/// Note that even if the effectively copied size (`count * size_of::<T>()`) is
2698/// `0`, the pointers must be non-null and properly aligned.
2699///
2700/// [`read`]: crate::ptr::read
2701/// [read-ownership]: crate::ptr::read#ownership-of-the-returned-value
2702/// [valid]: crate::ptr#safety
2703///
2704/// # Examples
2705///
2706/// Manually implement [`Vec::append`]:
2707///
2708/// ```
2709/// use std::ptr;
2710///
2711/// /// Moves all the elements of `src` into `dst`, leaving `src` empty.
2712/// fn append<T>(dst: &mut Vec<T>, src: &mut Vec<T>) {
2713/// let src_len = src.len();
2714/// let dst_len = dst.len();
2715///
2716/// // Ensure that `dst` has enough capacity to hold all of `src`.
2717/// dst.reserve(src_len);
2718///
2719/// unsafe {
2720/// // The call to add is always safe because `Vec` will never
2721/// // allocate more than `isize::MAX` bytes.
2722/// let dst_ptr = dst.as_mut_ptr().add(dst_len);
2723/// let src_ptr = src.as_ptr();
2724///
2725/// // Truncate `src` without dropping its contents. We do this first,
2726/// // to avoid problems in case something further down panics.
2727/// src.set_len(0);
2728///
2729/// // The two regions cannot overlap because mutable references do
2730/// // not alias, and two different vectors cannot own the same
2731/// // memory.
2732/// ptr::copy_nonoverlapping(src_ptr, dst_ptr, src_len);
2733///
2734/// // Notify `dst` that it now holds the contents of `src`.
2735/// dst.set_len(dst_len + src_len);
2736/// }
2737/// }
2738///
2739/// let mut a = vec!['r'];
2740/// let mut b = vec!['u', 's', 't'];
2741///
2742/// append(&mut a, &mut b);
2743///
2744/// assert_eq!(a, &['r', 'u', 's', 't']);
2745/// assert!(b.is_empty());
2746/// ```
2747///
2748/// [`Vec::append`]: ../../std/vec/struct.Vec.html#method.append
2749#[doc(alias = "memcpy")]
2750#[stable(feature = "rust1", since = "1.0.0")]
2751#[rustc_allowed_through_unstable_modules]
2752#[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")]
2753#[inline(always)]
2754#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2755#[rustc_diagnostic_item = "ptr_copy_nonoverlapping"]
2756pub const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize) {
2757 extern "rust-intrinsic" {
2758 #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")]
2759 #[rustc_nounwind]
2760 pub fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
2761 }
2762
2763 // SAFETY: the safety contract for `copy_nonoverlapping` must be
2764 // upheld by the caller.
2765 unsafe {
2766 assert_unsafe_precondition!(
2767 "ptr::copy_nonoverlapping requires that both pointer arguments are aligned and non-null \
2768 and the specified memory ranges do not overlap",
2769 [T](src: *const T, dst: *mut T, count: usize) =>
2770 is_aligned_and_not_null(src)
2771 && is_aligned_and_not_null(dst)
2772 && is_nonoverlapping(src, dst, count)
2773 );
2774 copy_nonoverlapping(src, dst, count)
2775 }
2776}
2777
2778/// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
2779/// and destination may overlap.
2780///
2781/// If the source and destination will *never* overlap,
2782/// [`copy_nonoverlapping`] can be used instead.
2783///
2784/// `copy` is semantically equivalent to C's [`memmove`], but with the argument
2785/// order swapped. Copying takes place as if the bytes were copied from `src`
2786/// to a temporary array and then copied from the array to `dst`.
2787///
2788/// The copy is "untyped" in the sense that data may be uninitialized or otherwise violate the
2789/// requirements of `T`. The initialization state is preserved exactly.
2790///
2791/// [`memmove`]: https://en.cppreference.com/w/c/string/byte/memmove
2792///
2793/// # Safety
2794///
2795/// Behavior is undefined if any of the following conditions are violated:
2796///
2797/// * `src` must be [valid] for reads of `count * size_of::<T>()` bytes, and must remain valid even
2798/// when `dst` is written for `count * size_of::<T>()` bytes. (This means if the memory ranges
2799/// overlap, the two pointers must not be subject to aliasing restrictions relative to each
2800/// other.)
2801///
2802/// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes, and must remain valid even
2803/// when `src` is read for `count * size_of::<T>()` bytes.
2804///
2805/// * Both `src` and `dst` must be properly aligned.
2806///
2807/// Like [`read`], `copy` creates a bitwise copy of `T`, regardless of
2808/// whether `T` is [`Copy`]. If `T` is not [`Copy`], using both the values
2809/// in the region beginning at `*src` and the region beginning at `*dst` can
2810/// [violate memory safety][read-ownership].
2811///
2812/// Note that even if the effectively copied size (`count * size_of::<T>()`) is
2813/// `0`, the pointers must be non-null and properly aligned.
2814///
2815/// [`read`]: crate::ptr::read
2816/// [read-ownership]: crate::ptr::read#ownership-of-the-returned-value
2817/// [valid]: crate::ptr#safety
2818///
2819/// # Examples
2820///
2821/// Efficiently create a Rust vector from an unsafe buffer:
2822///
2823/// ```
2824/// use std::ptr;
2825///
2826/// /// # Safety
2827/// ///
2828/// /// * `ptr` must be correctly aligned for its type and non-zero.
2829/// /// * `ptr` must be valid for reads of `elts` contiguous elements of type `T`.
2830/// /// * Those elements must not be used after calling this function unless `T: Copy`.
2831/// # #[allow(dead_code)]
2832/// unsafe fn from_buf_raw<T>(ptr: *const T, elts: usize) -> Vec<T> {
2833/// let mut dst = Vec::with_capacity(elts);
2834///
2835/// // SAFETY: Our precondition ensures the source is aligned and valid,
2836/// // and `Vec::with_capacity` ensures that we have usable space to write them.
2837/// ptr::copy(ptr, dst.as_mut_ptr(), elts);
2838///
2839/// // SAFETY: We created it with this much capacity earlier,
2840/// // and the previous `copy` has initialized these elements.
2841/// dst.set_len(elts);
2842/// dst
2843/// }
2844/// ```
2845#[doc(alias = "memmove")]
2846#[stable(feature = "rust1", since = "1.0.0")]
2847#[rustc_allowed_through_unstable_modules]
2848#[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")]
2849#[inline(always)]
2850#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2851#[rustc_diagnostic_item = "ptr_copy"]
2852pub const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
2853 extern "rust-intrinsic" {
2854 #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")]
2855 #[rustc_nounwind]
2856 fn copy<T>(src: *const T, dst: *mut T, count: usize);
2857 }
2858
2859 // SAFETY: the safety contract for `copy` must be upheld by the caller.
2860 unsafe {
2861 assert_unsafe_precondition!(
2862 "ptr::copy requires that both pointer arguments are aligned and non-null",
2863 [T](src: *const T, dst: *mut T) =>
2864 is_aligned_and_not_null(src) && is_aligned_and_not_null(dst)
2865 );
2866 copy(src, dst, count)
2867 }
2868}
2869
2870/// Sets `count * size_of::<T>()` bytes of memory starting at `dst` to
2871/// `val`.
2872///
2873/// `write_bytes` is similar to C's [`memset`], but sets `count *
2874/// size_of::<T>()` bytes to `val`.
2875///
2876/// [`memset`]: https://en.cppreference.com/w/c/string/byte/memset
2877///
2878/// # Safety
2879///
2880/// Behavior is undefined if any of the following conditions are violated:
2881///
2882/// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes.
2883///
2884/// * `dst` must be properly aligned.
2885///
2886/// Note that even if the effectively copied size (`count * size_of::<T>()`) is
2887/// `0`, the pointer must be non-null and properly aligned.
2888///
2889/// Additionally, note that changing `*dst` in this way can easily lead to undefined behavior (UB)
2890/// later if the written bytes are not a valid representation of some `T`. For instance, the
2891/// following is an **incorrect** use of this function:
2892///
2893/// ```rust,no_run
2894/// unsafe {
2895/// let mut value: u8 = 0;
2896/// let ptr: *mut bool = &mut value as *mut u8 as *mut bool;
2897/// let _bool = ptr.read(); // This is fine, `ptr` points to a valid `bool`.
2898/// ptr.write_bytes(42u8, 1); // This function itself does not cause UB...
2899/// let _bool = ptr.read(); // ...but it makes this operation UB! ⚠️
2900/// }
2901/// ```
2902///
2903/// [valid]: crate::ptr#safety
2904///
2905/// # Examples
2906///
2907/// Basic usage:
2908///
2909/// ```
2910/// use std::ptr;
2911///
2912/// let mut vec = vec![0u32; 4];
2913/// unsafe {
2914/// let vec_ptr = vec.as_mut_ptr();
2915/// ptr::write_bytes(vec_ptr, 0xfe, 2);
2916/// }
2917/// assert_eq!(vec, [0xfefefefe, 0xfefefefe, 0, 0]);
2918/// ```
2919#[doc(alias = "memset")]
2920#[stable(feature = "rust1", since = "1.0.0")]
2921#[rustc_allowed_through_unstable_modules]
2922#[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
2923#[inline(always)]
2924#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
2925#[rustc_diagnostic_item = "ptr_write_bytes"]
2926pub const unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize) {
2927 extern "rust-intrinsic" {
2928 #[rustc_const_unstable(feature = "const_ptr_write", issue = "86302")]
2929 #[rustc_nounwind]
2930 fn write_bytes<T>(dst: *mut T, val: u8, count: usize);
2931 }
2932
2933 // SAFETY: the safety contract for `write_bytes` must be upheld by the caller.
2934 unsafe {
2935 assert_unsafe_precondition!(
2936 "ptr::write_bytes requires that the destination pointer is aligned and non-null",
2937 [T](dst: *mut T) => is_aligned_and_not_null(dst)
2938 );
2939 write_bytes(dst, val, count)
2940 }
2941}
2942
2943/// Inform Miri that a given pointer definitely has a certain alignment.
2944#[cfg(miri)]
2945pub(crate) const fn miri_promise_symbolic_alignment(ptr: *const (), align: usize) {
2946 extern "Rust" {
2947 /// Miri-provided extern function to promise that a given pointer is properly aligned for
2948 /// "symbolic" alignment checks. Will fail if the pointer is not actually aligned or `align` is
2949 /// not a power of two. Has no effect when alignment checks are concrete (which is the default).
2950 fn miri_promise_symbolic_alignment(ptr: *const (), align: usize);
2951 }
2952
2953 fn runtime(ptr: *const (), align: usize) {
2954 // SAFETY: this call is always safe.
2955 unsafe {
2956 miri_promise_symbolic_alignment(ptr, align);
2957 }
2958 }
2959
2960 const fn compiletime(_ptr: *const (), _align: usize) {}
2961
2962 // SAFETY: the extra behavior at runtime is for UB checks only.
2963 unsafe {
2964 const_eval_select((ptr, align), called_in_const:compiletime, called_at_rt:runtime);
2965 }
2966}
2967