aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_db/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide_db/src')
-rw-r--r--crates/ide_db/src/helpers.rs1
-rw-r--r--crates/ide_db/src/helpers/generated_lints.rs6891
2 files changed, 6892 insertions, 0 deletions
diff --git a/crates/ide_db/src/helpers.rs b/crates/ide_db/src/helpers.rs
index 21b48237a..00900cdc2 100644
--- a/crates/ide_db/src/helpers.rs
+++ b/crates/ide_db/src/helpers.rs
@@ -3,6 +3,7 @@ pub mod import_assets;
3pub mod insert_use; 3pub mod insert_use;
4pub mod merge_imports; 4pub mod merge_imports;
5pub mod rust_doc; 5pub mod rust_doc;
6pub mod generated_lints;
6 7
7use std::collections::VecDeque; 8use std::collections::VecDeque;
8 9
diff --git a/crates/ide_db/src/helpers/generated_lints.rs b/crates/ide_db/src/helpers/generated_lints.rs
new file mode 100644
index 000000000..77021bae0
--- /dev/null
+++ b/crates/ide_db/src/helpers/generated_lints.rs
@@ -0,0 +1,6891 @@
1//! Generated file, do not edit by hand, see `xtask/src/codegen`
2
3pub struct Lint {
4 pub label: &'static str,
5 pub description: &'static str,
6}
7
8pub const DEFAULT_LINTS: &[Lint] = &[
9 Lint { label: "----", description: r##"-------"## },
10 Lint {
11 label: "absolute-paths-not-starting-with-crate",
12 description: r##"fully qualified paths that start with a module name instead of `crate`, `self`, or an extern crate name"##,
13 },
14 Lint { label: "ambiguous-associated-items", description: r##"ambiguous associated items"## },
15 Lint { label: "anonymous-parameters", description: r##"detects anonymous parameters"## },
16 Lint { label: "arithmetic-overflow", description: r##"arithmetic operation overflows"## },
17 Lint { label: "array-into-iter", description: r##"detects calling `into_iter` on arrays"## },
18 Lint {
19 label: "asm-sub-register",
20 description: r##"using only a subset of a register for inline asm inputs"##,
21 },
22 Lint { label: "bad-asm-style", description: r##"incorrect use of inline assembly"## },
23 Lint {
24 label: "bare-trait-objects",
25 description: r##"suggest using `dyn Trait` for trait objects"##,
26 },
27 Lint {
28 label: "bindings-with-variant-name",
29 description: r##"detects pattern bindings with the same name as one of the matched variants"##,
30 },
31 Lint { label: "box-pointers", description: r##"use of owned (Box type) heap memory"## },
32 Lint {
33 label: "cenum-impl-drop-cast",
34 description: r##"a C-like enum implementing Drop is cast"##,
35 },
36 Lint {
37 label: "clashing-extern-declarations",
38 description: r##"detects when an extern fn has been declared with the same name but different types"##,
39 },
40 Lint {
41 label: "coherence-leak-check",
42 description: r##"distinct impls distinguished only by the leak-check code"##,
43 },
44 Lint {
45 label: "conflicting-repr-hints",
46 description: r##"conflicts between `#[repr(..)]` hints that were previously accepted and used in practice"##,
47 },
48 Lint {
49 label: "confusable-idents",
50 description: r##"detects visually confusable pairs between identifiers"##,
51 },
52 Lint {
53 label: "const-err",
54 description: r##"constant evaluation encountered erroneous expression"##,
55 },
56 Lint {
57 label: "const-evaluatable-unchecked",
58 description: r##"detects a generic constant is used in a type without a emitting a warning"##,
59 },
60 Lint {
61 label: "const-item-mutation",
62 description: r##"detects attempts to mutate a `const` item"##,
63 },
64 Lint { label: "dead-code", description: r##"detect unused, unexported items"## },
65 Lint { label: "deprecated", description: r##"detects use of deprecated items"## },
66 Lint {
67 label: "deprecated-in-future",
68 description: r##"detects use of items that will be deprecated in a future version"##,
69 },
70 Lint {
71 label: "deref-nullptr",
72 description: r##"detects when an null pointer is dereferenced"##,
73 },
74 Lint {
75 label: "disjoint-capture-migration",
76 description: r##"Drop reorder and auto traits error because of `capture_disjoint_fields`"##,
77 },
78 Lint { label: "drop-bounds", description: r##"bounds of the form `T: Drop` are useless"## },
79 Lint {
80 label: "elided-lifetimes-in-paths",
81 description: r##"hidden lifetime parameters in types are deprecated"##,
82 },
83 Lint {
84 label: "ellipsis-inclusive-range-patterns",
85 description: r##"`...` range patterns are deprecated"##,
86 },
87 Lint {
88 label: "explicit-outlives-requirements",
89 description: r##"outlives requirements can be inferred"##,
90 },
91 Lint {
92 label: "exported-private-dependencies",
93 description: r##"public interface leaks type from a private dependency"##,
94 },
95 Lint { label: "forbidden-lint-groups", description: r##"applying forbid to lint-groups"## },
96 Lint {
97 label: "function-item-references",
98 description: r##"suggest casting to a function pointer when attempting to take references to function items"##,
99 },
100 Lint {
101 label: "ill-formed-attribute-input",
102 description: r##"ill-formed attribute inputs that were previously accepted and used in practice"##,
103 },
104 Lint {
105 label: "illegal-floating-point-literal-pattern",
106 description: r##"floating-point literals cannot be used in patterns"##,
107 },
108 Lint {
109 label: "improper-ctypes",
110 description: r##"proper use of libc types in foreign modules"##,
111 },
112 Lint {
113 label: "improper-ctypes-definitions",
114 description: r##"proper use of libc types in foreign item definitions"##,
115 },
116 Lint {
117 label: "incomplete-features",
118 description: r##"incomplete features that may function improperly in some or all cases"##,
119 },
120 Lint { label: "incomplete-include", description: r##"trailing content in included file"## },
121 Lint {
122 label: "indirect-structural-match",
123 description: r##"constant used in pattern contains value of non-structural-match type in a field or a variant"##,
124 },
125 Lint {
126 label: "ineffective-unstable-trait-impl",
127 description: r##"detects `#[unstable]` on stable trait implementations for stable types"##,
128 },
129 Lint {
130 label: "inline-no-sanitize",
131 description: r##"detects incompatible use of `#[inline(always)]` and `#[no_sanitize(...)]`"##,
132 },
133 Lint {
134 label: "invalid-type-param-default",
135 description: r##"type parameter default erroneously allowed in invalid location"##,
136 },
137 Lint {
138 label: "invalid-value",
139 description: r##"an invalid value is being created (such as a null reference)"##,
140 },
141 Lint {
142 label: "irrefutable-let-patterns",
143 description: r##"detects irrefutable patterns in `if let` and `while let` statements"##,
144 },
145 Lint {
146 label: "keyword-idents",
147 description: r##"detects edition keywords being used as an identifier"##,
148 },
149 Lint { label: "large-assignments", description: r##"detects large moves or copies"## },
150 Lint {
151 label: "late-bound-lifetime-arguments",
152 description: r##"detects generic lifetime arguments in path segments with late bound lifetime parameters"##,
153 },
154 Lint {
155 label: "legacy-derive-helpers",
156 description: r##"detects derive helper attributes that are used before they are introduced"##,
157 },
158 Lint {
159 label: "macro-expanded-macro-exports-accessed-by-absolute-paths",
160 description: r##"macro-expanded `macro_export` macros from the current crate cannot be referred to by absolute paths"##,
161 },
162 Lint {
163 label: "macro-use-extern-crate",
164 description: r##"the `#[macro_use]` attribute is now deprecated in favor of using macros via the module system"##,
165 },
166 Lint {
167 label: "meta-variable-misuse",
168 description: r##"possible meta-variable misuse at macro definition"##,
169 },
170 Lint { label: "missing-abi", description: r##"No declared ABI for extern declaration"## },
171 Lint {
172 label: "missing-copy-implementations",
173 description: r##"detects potentially-forgotten implementations of `Copy`"##,
174 },
175 Lint {
176 label: "missing-debug-implementations",
177 description: r##"detects missing implementations of Debug"##,
178 },
179 Lint {
180 label: "missing-docs",
181 description: r##"detects missing documentation for public members"##,
182 },
183 Lint {
184 label: "missing-fragment-specifier",
185 description: r##"detects missing fragment specifiers in unused `macro_rules!` patterns"##,
186 },
187 Lint {
188 label: "mixed-script-confusables",
189 description: r##"detects Unicode scripts whose mixed script confusables codepoints are solely used"##,
190 },
191 Lint {
192 label: "mutable-borrow-reservation-conflict",
193 description: r##"reservation of a two-phased borrow conflicts with other shared borrows"##,
194 },
195 Lint {
196 label: "mutable-transmutes",
197 description: r##"mutating transmuted &mut T from &T may cause undefined behavior"##,
198 },
199 Lint {
200 label: "no-mangle-const-items",
201 description: r##"const items will not have their symbols exported"##,
202 },
203 Lint { label: "no-mangle-generic-items", description: r##"generic items must be mangled"## },
204 Lint { label: "non-ascii-idents", description: r##"detects non-ASCII identifiers"## },
205 Lint {
206 label: "non-camel-case-types",
207 description: r##"types, variants, traits and type parameters should have camel case names"##,
208 },
209 Lint {
210 label: "non-fmt-panic",
211 description: r##"detect single-argument panic!() invocations in which the argument is not a format string"##,
212 },
213 Lint {
214 label: "non-shorthand-field-patterns",
215 description: r##"using `Struct { x: x }` instead of `Struct { x }` in a pattern"##,
216 },
217 Lint {
218 label: "non-snake-case",
219 description: r##"variables, methods, functions, lifetime parameters and modules should have snake case names"##,
220 },
221 Lint {
222 label: "non-upper-case-globals",
223 description: r##"static constants should have uppercase identifiers"##,
224 },
225 Lint {
226 label: "nontrivial-structural-match",
227 description: r##"constant used in pattern of non-structural-match type and the constant's initializer expression contains values of non-structural-match types"##,
228 },
229 Lint {
230 label: "noop-method-call",
231 description: r##"detects the use of well-known noop methods"##,
232 },
233 Lint {
234 label: "or-patterns-back-compat",
235 description: r##"detects usage of old versions of or-patterns"##,
236 },
237 Lint {
238 label: "order-dependent-trait-objects",
239 description: r##"trait-object types were treated as different depending on marker-trait order"##,
240 },
241 Lint { label: "overflowing-literals", description: r##"literal out of range for its type"## },
242 Lint {
243 label: "overlapping-range-endpoints",
244 description: r##"detects range patterns with overlapping endpoints"##,
245 },
246 Lint { label: "path-statements", description: r##"path statements with no effect"## },
247 Lint {
248 label: "patterns-in-fns-without-body",
249 description: r##"patterns in functions without body were erroneously allowed"##,
250 },
251 Lint {
252 label: "pointer-structural-match",
253 description: r##"pointers are not structural-match"##,
254 },
255 Lint {
256 label: "private-in-public",
257 description: r##"detect private items in public interfaces not caught by the old implementation"##,
258 },
259 Lint {
260 label: "proc-macro-back-compat",
261 description: r##"detects usage of old versions of certain proc-macro crates"##,
262 },
263 Lint {
264 label: "proc-macro-derive-resolution-fallback",
265 description: r##"detects proc macro derives using inaccessible names from parent modules"##,
266 },
267 Lint {
268 label: "pub-use-of-private-extern-crate",
269 description: r##"detect public re-exports of private extern crates"##,
270 },
271 Lint {
272 label: "redundant-semicolons",
273 description: r##"detects unnecessary trailing semicolons"##,
274 },
275 Lint {
276 label: "renamed-and-removed-lints",
277 description: r##"lints that have been renamed or removed"##,
278 },
279 Lint {
280 label: "semicolon-in-expressions-from-macros",
281 description: r##"trailing semicolon in macro body used as expression"##,
282 },
283 Lint {
284 label: "single-use-lifetimes",
285 description: r##"detects lifetime parameters that are only used once"##,
286 },
287 Lint {
288 label: "soft-unstable",
289 description: r##"a feature gate that doesn't break dependent crates"##,
290 },
291 Lint {
292 label: "stable-features",
293 description: r##"stable features found in `#[feature]` directive"##,
294 },
295 Lint {
296 label: "temporary-cstring-as-ptr",
297 description: r##"detects getting the inner pointer of a temporary `CString`"##,
298 },
299 Lint {
300 label: "trivial-bounds",
301 description: r##"these bounds don't depend on an type parameters"##,
302 },
303 Lint {
304 label: "trivial-casts",
305 description: r##"detects trivial casts which could be removed"##,
306 },
307 Lint {
308 label: "trivial-numeric-casts",
309 description: r##"detects trivial casts of numeric types which could be removed"##,
310 },
311 Lint {
312 label: "type-alias-bounds",
313 description: r##"bounds in type aliases are not enforced"##,
314 },
315 Lint {
316 label: "tyvar-behind-raw-pointer",
317 description: r##"raw pointer to an inference variable"##,
318 },
319 Lint {
320 label: "unaligned-references",
321 description: r##"detects unaligned references to fields of packed structs"##,
322 },
323 Lint {
324 label: "uncommon-codepoints",
325 description: r##"detects uncommon Unicode codepoints in identifiers"##,
326 },
327 Lint {
328 label: "unconditional-panic",
329 description: r##"operation will cause a panic at runtime"##,
330 },
331 Lint {
332 label: "unconditional-recursion",
333 description: r##"functions that cannot return without calling themselves"##,
334 },
335 Lint { label: "uninhabited-static", description: r##"uninhabited static"## },
336 Lint {
337 label: "unknown-crate-types",
338 description: r##"unknown crate type found in `#[crate_type]` directive"##,
339 },
340 Lint { label: "unknown-lints", description: r##"unrecognized lint attribute"## },
341 Lint {
342 label: "unnameable-test-items",
343 description: r##"detects an item that cannot be named being marked as `#[test_case]`"##,
344 },
345 Lint { label: "unreachable-code", description: r##"detects unreachable code paths"## },
346 Lint { label: "unreachable-patterns", description: r##"detects unreachable patterns"## },
347 Lint {
348 label: "unreachable-pub",
349 description: r##"`pub` items not reachable from crate root"##,
350 },
351 Lint { label: "unsafe-code", description: r##"usage of `unsafe` code"## },
352 Lint {
353 label: "unsafe-op-in-unsafe-fn",
354 description: r##"unsafe operations in unsafe functions without an explicit unsafe block are deprecated"##,
355 },
356 Lint {
357 label: "unstable-features",
358 description: r##"enabling unstable features (deprecated. do not use)"##,
359 },
360 Lint {
361 label: "unstable-name-collisions",
362 description: r##"detects name collision with an existing but unstable method"##,
363 },
364 Lint {
365 label: "unsupported-naked-functions",
366 description: r##"unsupported naked function definitions"##,
367 },
368 Lint {
369 label: "unused-allocation",
370 description: r##"detects unnecessary allocations that can be eliminated"##,
371 },
372 Lint {
373 label: "unused-assignments",
374 description: r##"detect assignments that will never be read"##,
375 },
376 Lint {
377 label: "unused-attributes",
378 description: r##"detects attributes that were not used by the compiler"##,
379 },
380 Lint { label: "unused-braces", description: r##"unnecessary braces around an expression"## },
381 Lint {
382 label: "unused-comparisons",
383 description: r##"comparisons made useless by limits of the types involved"##,
384 },
385 Lint {
386 label: "unused-crate-dependencies",
387 description: r##"crate dependencies that are never used"##,
388 },
389 Lint {
390 label: "unused-doc-comments",
391 description: r##"detects doc comments that aren't used by rustdoc"##,
392 },
393 Lint { label: "unused-extern-crates", description: r##"extern crates that are never used"## },
394 Lint {
395 label: "unused-features",
396 description: r##"unused features found in crate-level `#[feature]` directives"##,
397 },
398 Lint {
399 label: "unused-import-braces",
400 description: r##"unnecessary braces around an imported item"##,
401 },
402 Lint { label: "unused-imports", description: r##"imports that are never used"## },
403 Lint { label: "unused-labels", description: r##"detects labels that are never used"## },
404 Lint {
405 label: "unused-lifetimes",
406 description: r##"detects lifetime parameters that are never used"##,
407 },
408 Lint { label: "unused-macros", description: r##"detects macros that were not used"## },
409 Lint {
410 label: "unused-must-use",
411 description: r##"unused result of a type flagged as `#[must_use]`"##,
412 },
413 Lint {
414 label: "unused-mut",
415 description: r##"detect mut variables which don't need to be mutable"##,
416 },
417 Lint {
418 label: "unused-parens",
419 description: r##"`if`, `match`, `while` and `return` do not need parentheses"##,
420 },
421 Lint {
422 label: "unused-qualifications",
423 description: r##"detects unnecessarily qualified names"##,
424 },
425 Lint {
426 label: "unused-results",
427 description: r##"unused result of an expression in a statement"##,
428 },
429 Lint { label: "unused-unsafe", description: r##"unnecessary use of an `unsafe` block"## },
430 Lint {
431 label: "unused-variables",
432 description: r##"detect variables which are not used in any way"##,
433 },
434 Lint {
435 label: "useless-deprecated",
436 description: r##"detects deprecation attributes with no effect"##,
437 },
438 Lint {
439 label: "variant-size-differences",
440 description: r##"detects enums with widely varying variant sizes"##,
441 },
442 Lint {
443 label: "warnings",
444 description: r##"mass-change the level for lints which produce warnings"##,
445 },
446 Lint {
447 label: "where-clauses-object-safety",
448 description: r##"checks the object safety of where clauses"##,
449 },
450 Lint {
451 label: "while-true",
452 description: r##"suggest using `loop { }` instead of `while true { }`"##,
453 },
454];
455
456pub const FEATURES: &[Lint] = &[
457 Lint {
458 label: "abi_c_cmse_nonsecure_call",
459 description: r##"# `abi_c_cmse_nonsecure_call`
460
461The tracking issue for this feature is: [#81391]
462
463[#81391]: https://github.com/rust-lang/rust/issues/81391
464
465------------------------
466
467The [TrustZone-M
468feature](https://developer.arm.com/documentation/100690/latest/) is available
469for targets with the Armv8-M architecture profile (`thumbv8m` in their target
470name).
471LLVM, the Rust compiler and the linker are providing
472[support](https://developer.arm.com/documentation/ecm0359818/latest/) for the
473TrustZone-M feature.
474
475One of the things provided, with this unstable feature, is the
476`C-cmse-nonsecure-call` function ABI. This ABI is used on function pointers to
477non-secure code to mark a non-secure function call (see [section
4785.5](https://developer.arm.com/documentation/ecm0359818/latest/) for details).
479
480With this ABI, the compiler will do the following to perform the call:
481* save registers needed after the call to Secure memory
482* clear all registers that might contain confidential information
483* clear the Least Significant Bit of the function address
484* branches using the BLXNS instruction
485
486To avoid using the non-secure stack, the compiler will constrain the number and
487type of parameters/return value.
488
489The `extern "C-cmse-nonsecure-call"` ABI is otherwise equivalent to the
490`extern "C"` ABI.
491
492<!-- NOTE(ignore) this example is specific to thumbv8m targets -->
493
494``` rust,ignore
495#![no_std]
496#![feature(abi_c_cmse_nonsecure_call)]
497
498#[no_mangle]
499pub fn call_nonsecure_function(addr: usize) -> u32 {
500 let non_secure_function =
501 unsafe { core::mem::transmute::<usize, extern "C-cmse-nonsecure-call" fn() -> u32>(addr) };
502 non_secure_function()
503}
504```
505
506``` text
507$ rustc --emit asm --crate-type lib --target thumbv8m.main-none-eabi function.rs
508
509call_nonsecure_function:
510 .fnstart
511 .save {r7, lr}
512 push {r7, lr}
513 .setfp r7, sp
514 mov r7, sp
515 .pad #16
516 sub sp, #16
517 str r0, [sp, #12]
518 ldr r0, [sp, #12]
519 str r0, [sp, #8]
520 b .LBB0_1
521.LBB0_1:
522 ldr r0, [sp, #8]
523 push.w {r4, r5, r6, r7, r8, r9, r10, r11}
524 bic r0, r0, #1
525 mov r1, r0
526 mov r2, r0
527 mov r3, r0
528 mov r4, r0
529 mov r5, r0
530 mov r6, r0
531 mov r7, r0
532 mov r8, r0
533 mov r9, r0
534 mov r10, r0
535 mov r11, r0
536 mov r12, r0
537 msr apsr_nzcvq, r0
538 blxns r0
539 pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
540 str r0, [sp, #4]
541 b .LBB0_2
542.LBB0_2:
543 ldr r0, [sp, #4]
544 add sp, #16
545 pop {r7, pc}
546```
547"##,
548 },
549 Lint {
550 label: "abi_msp430_interrupt",
551 description: r##"# `abi_msp430_interrupt`
552
553The tracking issue for this feature is: [#38487]
554
555[#38487]: https://github.com/rust-lang/rust/issues/38487
556
557------------------------
558
559In the MSP430 architecture, interrupt handlers have a special calling
560convention. You can use the `"msp430-interrupt"` ABI to make the compiler apply
561the right calling convention to the interrupt handlers you define.
562
563<!-- NOTE(ignore) this example is specific to the msp430 target -->
564
565``` rust,ignore
566#![feature(abi_msp430_interrupt)]
567#![no_std]
568
569// Place the interrupt handler at the appropriate memory address
570// (Alternatively, you can use `#[used]` and remove `pub` and `#[no_mangle]`)
571#[link_section = "__interrupt_vector_10"]
572#[no_mangle]
573pub static TIM0_VECTOR: extern "msp430-interrupt" fn() = tim0;
574
575// The interrupt handler
576extern "msp430-interrupt" fn tim0() {
577 // ..
578}
579```
580
581``` text
582$ msp430-elf-objdump -CD ./target/msp430/release/app
583Disassembly of section __interrupt_vector_10:
584
5850000fff2 <TIM0_VECTOR>:
586 fff2: 00 c0 interrupt service routine at 0xc000
587
588Disassembly of section .text:
589
5900000c000 <int::tim0>:
591 c000: 00 13 reti
592```
593"##,
594 },
595 Lint {
596 label: "abi_ptx",
597 description: r##"# `abi_ptx`
598
599The tracking issue for this feature is: [#38788]
600
601[#38788]: https://github.com/rust-lang/rust/issues/38788
602
603------------------------
604
605When emitting PTX code, all vanilla Rust functions (`fn`) get translated to
606"device" functions. These functions are *not* callable from the host via the
607CUDA API so a crate with only device functions is not too useful!
608
609OTOH, "global" functions *can* be called by the host; you can think of them
610as the real public API of your crate. To produce a global function use the
611`"ptx-kernel"` ABI.
612
613<!-- NOTE(ignore) this example is specific to the nvptx targets -->
614
615``` rust,ignore
616#![feature(abi_ptx)]
617#![no_std]
618
619pub unsafe extern "ptx-kernel" fn global_function() {
620 device_function();
621}
622
623pub fn device_function() {
624 // ..
625}
626```
627
628``` text
629$ xargo rustc --target nvptx64-nvidia-cuda --release -- --emit=asm
630
631$ cat $(find -name '*.s')
632//
633// Generated by LLVM NVPTX Back-End
634//
635
636.version 3.2
637.target sm_20
638.address_size 64
639
640 // .globl _ZN6kernel15global_function17h46111ebe6516b382E
641
642.visible .entry _ZN6kernel15global_function17h46111ebe6516b382E()
643{
644
645
646 ret;
647}
648
649 // .globl _ZN6kernel15device_function17hd6a0e4993bbf3f78E
650.visible .func _ZN6kernel15device_function17hd6a0e4993bbf3f78E()
651{
652
653
654 ret;
655}
656```
657"##,
658 },
659 Lint {
660 label: "abi_thiscall",
661 description: r##"# `abi_thiscall`
662
663The tracking issue for this feature is: [#42202]
664
665[#42202]: https://github.com/rust-lang/rust/issues/42202
666
667------------------------
668
669The MSVC ABI on x86 Windows uses the `thiscall` calling convention for C++
670instance methods by default; it is identical to the usual (C) calling
671convention on x86 Windows except that the first parameter of the method,
672the `this` pointer, is passed in the ECX register.
673"##,
674 },
675 Lint {
676 label: "allocator_api",
677 description: r##"# `allocator_api`
678
679The tracking issue for this feature is [#32838]
680
681[#32838]: https://github.com/rust-lang/rust/issues/32838
682
683------------------------
684
685Sometimes you want the memory for one collection to use a different
686allocator than the memory for another collection. In this case,
687replacing the global allocator is not a workable option. Instead,
688you need to pass in an instance of an `AllocRef` to each collection
689for which you want a custom allocator.
690
691TBD
692"##,
693 },
694 Lint {
695 label: "allocator_internals",
696 description: r##"# `allocator_internals`
697
698This feature does not have a tracking issue, it is an unstable implementation
699detail of the `global_allocator` feature not intended for use outside the
700compiler.
701
702------------------------
703"##,
704 },
705 Lint {
706 label: "arbitrary_enum_discriminant",
707 description: r##"# `arbitrary_enum_discriminant`
708
709The tracking issue for this feature is: [#60553]
710
711[#60553]: https://github.com/rust-lang/rust/issues/60553
712
713------------------------
714
715The `arbitrary_enum_discriminant` feature permits tuple-like and
716struct-like enum variants with `#[repr(<int-type>)]` to have explicit discriminants.
717
718## Examples
719
720```rust
721#![feature(arbitrary_enum_discriminant)]
722
723#[allow(dead_code)]
724#[repr(u8)]
725enum Enum {
726 Unit = 3,
727 Tuple(u16) = 2,
728 Struct {
729 a: u8,
730 b: u16,
731 } = 1,
732}
733
734impl Enum {
735 fn tag(&self) -> u8 {
736 unsafe { *(self as *const Self as *const u8) }
737 }
738}
739
740assert_eq!(3, Enum::Unit.tag());
741assert_eq!(2, Enum::Tuple(5).tag());
742assert_eq!(1, Enum::Struct{a: 7, b: 11}.tag());
743```
744"##,
745 },
746 Lint {
747 label: "asm",
748 description: r##"# `asm`
749
750The tracking issue for this feature is: [#72016]
751
752[#72016]: https://github.com/rust-lang/rust/issues/72016
753
754------------------------
755
756For extremely low-level manipulations and performance reasons, one
757might wish to control the CPU directly. Rust supports using inline
758assembly to do this via the `asm!` macro.
759
760# Guide-level explanation
761[guide-level-explanation]: #guide-level-explanation
762
763Rust provides support for inline assembly via the `asm!` macro.
764It can be used to embed handwritten assembly in the assembly output generated by the compiler.
765Generally this should not be necessary, but might be where the required performance or timing
766cannot be otherwise achieved. Accessing low level hardware primitives, e.g. in kernel code, may also demand this functionality.
767
768> **Note**: the examples here are given in x86/x86-64 assembly, but other architectures are also supported.
769
770Inline assembly is currently supported on the following architectures:
771- x86 and x86-64
772- ARM
773- AArch64
774- RISC-V
775- NVPTX
776- PowerPC
777- Hexagon
778- MIPS32r2 and MIPS64r2
779- wasm32
780
781## Basic usage
782
783Let us start with the simplest possible example:
784
785```rust,allow_fail
786#![feature(asm)]
787unsafe {
788 asm!("nop");
789}
790```
791
792This will insert a NOP (no operation) instruction into the assembly generated by the compiler.
793Note that all `asm!` invocations have to be inside an `unsafe` block, as they could insert
794arbitrary instructions and break various invariants. The instructions to be inserted are listed
795in the first argument of the `asm!` macro as a string literal.
796
797## Inputs and outputs
798
799Now inserting an instruction that does nothing is rather boring. Let us do something that
800actually acts on data:
801
802```rust,allow_fail
803#![feature(asm)]
804let x: u64;
805unsafe {
806 asm!("mov {}, 5", out(reg) x);
807}
808assert_eq!(x, 5);
809```
810
811This will write the value `5` into the `u64` variable `x`.
812You can see that the string literal we use to specify instructions is actually a template string.
813It is governed by the same rules as Rust [format strings][format-syntax].
814The arguments that are inserted into the template however look a bit different then you may
815be familiar with. First we need to specify if the variable is an input or an output of the
816inline assembly. In this case it is an output. We declared this by writing `out`.
817We also need to specify in what kind of register the assembly expects the variable.
818In this case we put it in an arbitrary general purpose register by specifying `reg`.
819The compiler will choose an appropriate register to insert into
820the template and will read the variable from there after the inline assembly finishes executing.
821
822Let us see another example that also uses an input:
823
824```rust,allow_fail
825#![feature(asm)]
826let i: u64 = 3;
827let o: u64;
828unsafe {
829 asm!(
830 "mov {0}, {1}",
831 "add {0}, {number}",
832 out(reg) o,
833 in(reg) i,
834 number = const 5,
835 );
836}
837assert_eq!(o, 8);
838```
839
840This will add `5` to the input in variable `i` and write the result to variable `o`.
841The particular way this assembly does this is first copying the value from `i` to the output,
842and then adding `5` to it.
843
844The example shows a few things:
845
846First, we can see that `asm!` allows multiple template string arguments; each
847one is treated as a separate line of assembly code, as if they were all joined
848together with newlines between them. This makes it easy to format assembly
849code.
850
851Second, we can see that inputs are declared by writing `in` instead of `out`.
852
853Third, one of our operands has a type we haven't seen yet, `const`.
854This tells the compiler to expand this argument to value directly inside the assembly template.
855This is only possible for constants and literals.
856
857Fourth, we can see that we can specify an argument number, or name as in any format string.
858For inline assembly templates this is particularly useful as arguments are often used more than once.
859For more complex inline assembly using this facility is generally recommended, as it improves
860readability, and allows reordering instructions without changing the argument order.
861
862We can further refine the above example to avoid the `mov` instruction:
863
864```rust,allow_fail
865#![feature(asm)]
866let mut x: u64 = 3;
867unsafe {
868 asm!("add {0}, {number}", inout(reg) x, number = const 5);
869}
870assert_eq!(x, 8);
871```
872
873We can see that `inout` is used to specify an argument that is both input and output.
874This is different from specifying an input and output separately in that it is guaranteed to assign both to the same register.
875
876It is also possible to specify different variables for the input and output parts of an `inout` operand:
877
878```rust,allow_fail
879#![feature(asm)]
880let x: u64 = 3;
881let y: u64;
882unsafe {
883 asm!("add {0}, {number}", inout(reg) x => y, number = const 5);
884}
885assert_eq!(y, 8);
886```
887
888## Late output operands
889
890The Rust compiler is conservative with its allocation of operands. It is assumed that an `out`
891can be written at any time, and can therefore not share its location with any other argument.
892However, to guarantee optimal performance it is important to use as few registers as possible,
893so they won't have to be saved and reloaded around the inline assembly block.
894To achieve this Rust provides a `lateout` specifier. This can be used on any output that is
895written only after all inputs have been consumed.
896There is also a `inlateout` variant of this specifier.
897
898Here is an example where `inlateout` *cannot* be used:
899
900```rust,allow_fail
901#![feature(asm)]
902let mut a: u64 = 4;
903let b: u64 = 4;
904let c: u64 = 4;
905unsafe {
906 asm!(
907 "add {0}, {1}",
908 "add {0}, {2}",
909 inout(reg) a,
910 in(reg) b,
911 in(reg) c,
912 );
913}
914assert_eq!(a, 12);
915```
916
917Here the compiler is free to allocate the same register for inputs `b` and `c` since it knows they have the same value. However it must allocate a separate register for `a` since it uses `inout` and not `inlateout`. If `inlateout` was used, then `a` and `c` could be allocated to the same register, in which case the first instruction to overwrite the value of `c` and cause the assembly code to produce the wrong result.
918
919However the following example can use `inlateout` since the output is only modified after all input registers have been read:
920
921```rust,allow_fail
922#![feature(asm)]
923let mut a: u64 = 4;
924let b: u64 = 4;
925unsafe {
926 asm!("add {0}, {1}", inlateout(reg) a, in(reg) b);
927}
928assert_eq!(a, 8);
929```
930
931As you can see, this assembly fragment will still work correctly if `a` and `b` are assigned to the same register.
932
933## Explicit register operands
934
935Some instructions require that the operands be in a specific register.
936Therefore, Rust inline assembly provides some more specific constraint specifiers.
937While `reg` is generally available on any architecture, these are highly architecture specific. E.g. for x86 the general purpose registers `eax`, `ebx`, `ecx`, `edx`, `ebp`, `esi`, and `edi`
938among others can be addressed by their name.
939
940```rust,allow_fail,no_run
941#![feature(asm)]
942let cmd = 0xd1;
943unsafe {
944 asm!("out 0x64, eax", in("eax") cmd);
945}
946```
947
948In this example we call the `out` instruction to output the content of the `cmd` variable
949to port `0x64`. Since the `out` instruction only accepts `eax` (and its sub registers) as operand
950we had to use the `eax` constraint specifier.
951
952Note that unlike other operand types, explicit register operands cannot be used in the template string: you can't use `{}` and should write the register name directly instead. Also, they must appear at the end of the operand list after all other operand types.
953
954Consider this example which uses the x86 `mul` instruction:
955
956```rust,allow_fail
957#![feature(asm)]
958fn mul(a: u64, b: u64) -> u128 {
959 let lo: u64;
960 let hi: u64;
961
962 unsafe {
963 asm!(
964 // The x86 mul instruction takes rax as an implicit input and writes
965 // the 128-bit result of the multiplication to rax:rdx.
966 "mul {}",
967 in(reg) a,
968 inlateout("rax") b => lo,
969 lateout("rdx") hi
970 );
971 }
972
973 ((hi as u128) << 64) + lo as u128
974}
975```
976
977This uses the `mul` instruction to multiply two 64-bit inputs with a 128-bit result.
978The only explicit operand is a register, that we fill from the variable `a`.
979The second operand is implicit, and must be the `rax` register, which we fill from the variable `b`.
980The lower 64 bits of the result are stored in `rax` from which we fill the variable `lo`.
981The higher 64 bits are stored in `rdx` from which we fill the variable `hi`.
982
983## Clobbered registers
984
985In many cases inline assembly will modify state that is not needed as an output.
986Usually this is either because we have to use a scratch register in the assembly,
987or instructions modify state that we don't need to further examine.
988This state is generally referred to as being "clobbered".
989We need to tell the compiler about this since it may need to save and restore this state
990around the inline assembly block.
991
992```rust,allow_fail
993#![feature(asm)]
994let ebx: u32;
995let ecx: u32;
996
997unsafe {
998 asm!(
999 "cpuid",
1000 // EAX 4 selects the "Deterministic Cache Parameters" CPUID leaf
1001 inout("eax") 4 => _,
1002 // ECX 0 selects the L0 cache information.
1003 inout("ecx") 0 => ecx,
1004 lateout("ebx") ebx,
1005 lateout("edx") _,
1006 );
1007}
1008
1009println!(
1010 "L1 Cache: {}",
1011 ((ebx >> 22) + 1) * (((ebx >> 12) & 0x3ff) + 1) * ((ebx & 0xfff) + 1) * (ecx + 1)
1012);
1013```
1014
1015In the example above we use the `cpuid` instruction to get the L1 cache size.
1016This instruction writes to `eax`, `ebx`, `ecx`, and `edx`, but for the cache size we only care about the contents of `ebx` and `ecx`.
1017
1018However we still need to tell the compiler that `eax` and `edx` have been modified so that it can save any values that were in these registers before the asm. This is done by declaring these as outputs but with `_` instead of a variable name, which indicates that the output value is to be discarded.
1019
1020This can also be used with a general register class (e.g. `reg`) to obtain a scratch register for use inside the asm code:
1021
1022```rust,allow_fail
1023#![feature(asm)]
1024// Multiply x by 6 using shifts and adds
1025let mut x: u64 = 4;
1026unsafe {
1027 asm!(
1028 "mov {tmp}, {x}",
1029 "shl {tmp}, 1",
1030 "shl {x}, 2",
1031 "add {x}, {tmp}",
1032 x = inout(reg) x,
1033 tmp = out(reg) _,
1034 );
1035}
1036assert_eq!(x, 4 * 6);
1037```
1038
1039## Symbol operands
1040
1041A special operand type, `sym`, allows you to use the symbol name of a `fn` or `static` in inline assembly code.
1042This allows you to call a function or access a global variable without needing to keep its address in a register.
1043
1044```rust,allow_fail
1045#![feature(asm)]
1046extern "C" fn foo(arg: i32) {
1047 println!("arg = {}", arg);
1048}
1049
1050fn call_foo(arg: i32) {
1051 unsafe {
1052 asm!(
1053 "call {}",
1054 sym foo,
1055 // 1st argument in rdi, which is caller-saved
1056 inout("rdi") arg => _,
1057 // All caller-saved registers must be marked as clobbered
1058 out("rax") _, out("rcx") _, out("rdx") _, out("rsi") _,
1059 out("r8") _, out("r9") _, out("r10") _, out("r11") _,
1060 out("xmm0") _, out("xmm1") _, out("xmm2") _, out("xmm3") _,
1061 out("xmm4") _, out("xmm5") _, out("xmm6") _, out("xmm7") _,
1062 out("xmm8") _, out("xmm9") _, out("xmm10") _, out("xmm11") _,
1063 out("xmm12") _, out("xmm13") _, out("xmm14") _, out("xmm15") _,
1064 // Also mark AVX-512 registers as clobbered. This is accepted by the
1065 // compiler even if AVX-512 is not enabled on the current target.
1066 out("xmm16") _, out("xmm17") _, out("xmm18") _, out("xmm19") _,
1067 out("xmm20") _, out("xmm21") _, out("xmm22") _, out("xmm23") _,
1068 out("xmm24") _, out("xmm25") _, out("xmm26") _, out("xmm27") _,
1069 out("xmm28") _, out("xmm29") _, out("xmm30") _, out("xmm31") _,
1070 )
1071 }
1072}
1073```
1074
1075Note that the `fn` or `static` item does not need to be public or `#[no_mangle]`:
1076the compiler will automatically insert the appropriate mangled symbol name into the assembly code.
1077
1078## Register template modifiers
1079
1080In some cases, fine control is needed over the way a register name is formatted when inserted into the template string. This is needed when an architecture's assembly language has several names for the same register, each typically being a "view" over a subset of the register (e.g. the low 32 bits of a 64-bit register).
1081
1082By default the compiler will always choose the name that refers to the full register size (e.g. `rax` on x86-64, `eax` on x86, etc).
1083
1084This default can be overriden by using modifiers on the template string operands, just like you would with format strings:
1085
1086```rust,allow_fail
1087#![feature(asm)]
1088let mut x: u16 = 0xab;
1089
1090unsafe {
1091 asm!("mov {0:h}, {0:l}", inout(reg_abcd) x);
1092}
1093
1094assert_eq!(x, 0xabab);
1095```
1096
1097In this example, we use the `reg_abcd` register class to restrict the register allocator to the 4 legacy x86 register (`ax`, `bx`, `cx`, `dx`) of which the first two bytes can be addressed independently.
1098
1099Let us assume that the register allocator has chosen to allocate `x` in the `ax` register.
1100The `h` modifier will emit the register name for the high byte of that register and the `l` modifier will emit the register name for the low byte. The asm code will therefore be expanded as `mov ah, al` which copies the low byte of the value into the high byte.
1101
1102If you use a smaller data type (e.g. `u16`) with an operand and forget the use template modifiers, the compiler will emit a warning and suggest the correct modifier to use.
1103
1104## Memory address operands
1105
1106Sometimes assembly instructions require operands passed via memory addresses/memory locations.
1107You have to manually use the memory address syntax specified by the respectively architectures.
1108For example, in x86/x86_64 and intel assembly syntax, you should wrap inputs/outputs in `[]`
1109to indicate they are memory operands:
1110
1111```rust,allow_fail
1112#![feature(asm, llvm_asm)]
1113# fn load_fpu_control_word(control: u16) {
1114unsafe {
1115 asm!("fldcw [{}]", in(reg) &control, options(nostack));
1116
1117 // Previously this would have been written with the deprecated `llvm_asm!` like this
1118 llvm_asm!("fldcw $0" :: "m" (control) :: "volatile");
1119}
1120# }
1121```
1122
1123## Labels
1124
1125The compiler is allowed to instantiate multiple copies an `asm!` block, for example when the function containing it is inlined in multiple places. As a consequence, you should only use GNU assembler [local labels] inside inline assembly code. Defining symbols in assembly code may lead to assembler and/or linker errors due to duplicate symbol definitions.
1126
1127Moreover, due to [an llvm bug], you shouldn't use labels exclusively made of `0` and `1` digits, e.g. `0`, `11` or `101010`, as they may end up being interpreted as binary values.
1128
1129```rust,allow_fail
1130#![feature(asm)]
1131
1132let mut a = 0;
1133unsafe {
1134 asm!(
1135 "mov {0}, 10",
1136 "2:",
1137 "sub {0}, 1",
1138 "cmp {0}, 3",
1139 "jle 2f",
1140 "jmp 2b",
1141 "2:",
1142 "add {0}, 2",
1143 out(reg) a
1144 );
1145}
1146assert_eq!(a, 5);
1147```
1148
1149This will decrement the `{0}` register value from 10 to 3, then add 2 and store it in `a`.
1150
1151This example show a few thing:
1152
1153First that the same number can be used as a label multiple times in the same inline block.
1154
1155Second, that when a numeric label is used as a reference (as an instruction operand, for example), the suffixes b (“backward”) or f (“forward”) should be added to the numeric label. It will then refer to the nearest label defined by this number in this direction.
1156
1157[local labels]: https://sourceware.org/binutils/docs/as/Symbol-Names.html#Local-Labels
1158[an llvm bug]: https://bugs.llvm.org/show_bug.cgi?id=36144
1159
1160## Options
1161
1162By default, an inline assembly block is treated the same way as an external FFI function call with a custom calling convention: it may read/write memory, have observable side effects, etc. However in many cases, it is desirable to give the compiler more information about what the assembly code is actually doing so that it can optimize better.
1163
1164Let's take our previous example of an `add` instruction:
1165
1166```rust,allow_fail
1167#![feature(asm)]
1168let mut a: u64 = 4;
1169let b: u64 = 4;
1170unsafe {
1171 asm!(
1172 "add {0}, {1}",
1173 inlateout(reg) a, in(reg) b,
1174 options(pure, nomem, nostack),
1175 );
1176}
1177assert_eq!(a, 8);
1178```
1179
1180Options can be provided as an optional final argument to the `asm!` macro. We specified three options here:
1181- `pure` means that the asm code has no observable side effects and that its output depends only on its inputs. This allows the compiler optimizer to call the inline asm fewer times or even eliminate it entirely.
1182- `nomem` means that the asm code does not read or write to memory. By default the compiler will assume that inline assembly can read or write any memory address that is accessible to it (e.g. through a pointer passed as an operand, or a global).
1183- `nostack` means that the asm code does not push any data onto the stack. This allows the compiler to use optimizations such as the stack red zone on x86-64 to avoid stack pointer adjustments.
1184
1185These allow the compiler to better optimize code using `asm!`, for example by eliminating pure `asm!` blocks whose outputs are not needed.
1186
1187See the reference for the full list of available options and their effects.
1188
1189# Reference-level explanation
1190[reference-level-explanation]: #reference-level-explanation
1191
1192Inline assembler is implemented as an unsafe macro `asm!()`.
1193The first argument to this macro is a template string literal used to build the final assembly.
1194The following arguments specify input and output operands.
1195When required, options are specified as the final argument.
1196
1197The following ABNF specifies the general syntax:
1198
1199```text
1200dir_spec := "in" / "out" / "lateout" / "inout" / "inlateout"
1201reg_spec := <register class> / "<explicit register>"
1202operand_expr := expr / "_" / expr "=>" expr / expr "=>" "_"
1203reg_operand := dir_spec "(" reg_spec ")" operand_expr
1204operand := reg_operand / "const" const_expr / "sym" path
1205option := "pure" / "nomem" / "readonly" / "preserves_flags" / "noreturn" / "nostack" / "att_syntax"
1206options := "options(" option *["," option] [","] ")"
1207asm := "asm!(" format_string *("," format_string) *("," [ident "="] operand) ["," options] [","] ")"
1208```
1209
1210The macro will initially be supported only on ARM, AArch64, Hexagon, PowerPC, x86, x86-64 and RISC-V targets. Support for more targets may be added in the future. The compiler will emit an error if `asm!` is used on an unsupported target.
1211
1212[format-syntax]: https://doc.rust-lang.org/std/fmt/#syntax
1213
1214## Template string arguments
1215
1216The assembler template uses the same syntax as [format strings][format-syntax] (i.e. placeholders are specified by curly braces). The corresponding arguments are accessed in order, by index, or by name. However, implicit named arguments (introduced by [RFC #2795][rfc-2795]) are not supported.
1217
1218An `asm!` invocation may have one or more template string arguments; an `asm!` with multiple template string arguments is treated as if all the strings were concatenated with a `\n` between them. The expected usage is for each template string argument to correspond to a line of assembly code. All template string arguments must appear before any other arguments.
1219
1220As with format strings, named arguments must appear after positional arguments. Explicit register operands must appear at the end of the operand list, after named arguments if any.
1221
1222Explicit register operands cannot be used by placeholders in the template string. All other named and positional operands must appear at least once in the template string, otherwise a compiler error is generated.
1223
1224The exact assembly code syntax is target-specific and opaque to the compiler except for the way operands are substituted into the template string to form the code passed to the assembler.
1225
1226The 5 targets specified in this RFC (x86, ARM, AArch64, RISC-V, Hexagon) all use the assembly code syntax of the GNU assembler (GAS). On x86, the `.intel_syntax noprefix` mode of GAS is used by default. On ARM, the `.syntax unified` mode is used. These targets impose an additional restriction on the assembly code: any assembler state (e.g. the current section which can be changed with `.section`) must be restored to its original value at the end of the asm string. Assembly code that does not conform to the GAS syntax will result in assembler-specific behavior.
1227
1228[rfc-2795]: https://github.com/rust-lang/rfcs/pull/2795
1229
1230## Operand type
1231
1232Several types of operands are supported:
1233
1234* `in(<reg>) <expr>`
1235 - `<reg>` can refer to a register class or an explicit register. The allocated register name is substituted into the asm template string.
1236 - The allocated register will contain the value of `<expr>` at the start of the asm code.
1237 - The allocated register must contain the same value at the end of the asm code (except if a `lateout` is allocated to the same register).
1238* `out(<reg>) <expr>`
1239 - `<reg>` can refer to a register class or an explicit register. The allocated register name is substituted into the asm template string.
1240 - The allocated register will contain an undefined value at the start of the asm code.
1241 - `<expr>` must be a (possibly uninitialized) place expression, to which the contents of the allocated register is written to at the end of the asm code.
1242 - An underscore (`_`) may be specified instead of an expression, which will cause the contents of the register to be discarded at the end of the asm code (effectively acting as a clobber).
1243* `lateout(<reg>) <expr>`
1244 - Identical to `out` except that the register allocator can reuse a register allocated to an `in`.
1245 - You should only write to the register after all inputs are read, otherwise you may clobber an input.
1246* `inout(<reg>) <expr>`
1247 - `<reg>` can refer to a register class or an explicit register. The allocated register name is substituted into the asm template string.
1248 - The allocated register will contain the value of `<expr>` at the start of the asm code.
1249 - `<expr>` must be a mutable initialized place expression, to which the contents of the allocated register is written to at the end of the asm code.
1250* `inout(<reg>) <in expr> => <out expr>`
1251 - Same as `inout` except that the initial value of the register is taken from the value of `<in expr>`.
1252 - `<out expr>` must be a (possibly uninitialized) place expression, to which the contents of the allocated register is written to at the end of the asm code.
1253 - An underscore (`_`) may be specified instead of an expression for `<out expr>`, which will cause the contents of the register to be discarded at the end of the asm code (effectively acting as a clobber).
1254 - `<in expr>` and `<out expr>` may have different types.
1255* `inlateout(<reg>) <expr>` / `inlateout(<reg>) <in expr> => <out expr>`
1256 - Identical to `inout` except that the register allocator can reuse a register allocated to an `in` (this can happen if the compiler knows the `in` has the same initial value as the `inlateout`).
1257 - You should only write to the register after all inputs are read, otherwise you may clobber an input.
1258* `const <expr>`
1259 - `<expr>` must be an integer constant expression.
1260 - The value of the expression is formatted as a string and substituted directly into the asm template string.
1261* `sym <path>`
1262 - `<path>` must refer to a `fn` or `static`.
1263 - A mangled symbol name referring to the item is substituted into the asm template string.
1264 - The substituted string does not include any modifiers (e.g. GOT, PLT, relocations, etc).
1265 - `<path>` is allowed to point to a `#[thread_local]` static, in which case the asm code can combine the symbol with relocations (e.g. `@plt`, `@TPOFF`) to read from thread-local data.
1266
1267Operand expressions are evaluated from left to right, just like function call arguments. After the `asm!` has executed, outputs are written to in left to right order. This is significant if two outputs point to the same place: that place will contain the value of the rightmost output.
1268
1269## Register operands
1270
1271Input and output operands can be specified either as an explicit register or as a register class from which the register allocator can select a register. Explicit registers are specified as string literals (e.g. `"eax"`) while register classes are specified as identifiers (e.g. `reg`). Using string literals for register names enables support for architectures that use special characters in register names, such as MIPS (`$0`, `$1`, etc).
1272
1273Note that explicit registers treat register aliases (e.g. `r14` vs `lr` on ARM) and smaller views of a register (e.g. `eax` vs `rax`) as equivalent to the base register. It is a compile-time error to use the same explicit register for two input operands or two output operands. Additionally, it is also a compile-time error to use overlapping registers (e.g. ARM VFP) in input operands or in output operands.
1274
1275Only the following types are allowed as operands for inline assembly:
1276- Integers (signed and unsigned)
1277- Floating-point numbers
1278- Pointers (thin only)
1279- Function pointers
1280- SIMD vectors (structs defined with `#[repr(simd)]` and which implement `Copy`). This includes architecture-specific vector types defined in `std::arch` such as `__m128` (x86) or `int8x16_t` (ARM).
1281
1282Here is the list of currently supported register classes:
1283
1284| Architecture | Register class | Registers | LLVM constraint code |
1285| ------------ | -------------- | --------- | -------------------- |
1286| x86 | `reg` | `ax`, `bx`, `cx`, `dx`, `si`, `di`, `bp`, `r[8-15]` (x86-64 only) | `r` |
1287| x86 | `reg_abcd` | `ax`, `bx`, `cx`, `dx` | `Q` |
1288| x86-32 | `reg_byte` | `al`, `bl`, `cl`, `dl`, `ah`, `bh`, `ch`, `dh` | `q` |
1289| x86-64 | `reg_byte`\* | `al`, `bl`, `cl`, `dl`, `sil`, `dil`, `bpl`, `r[8-15]b` | `q` |
1290| x86 | `xmm_reg` | `xmm[0-7]` (x86) `xmm[0-15]` (x86-64) | `x` |
1291| x86 | `ymm_reg` | `ymm[0-7]` (x86) `ymm[0-15]` (x86-64) | `x` |
1292| x86 | `zmm_reg` | `zmm[0-7]` (x86) `zmm[0-31]` (x86-64) | `v` |
1293| x86 | `kreg` | `k[1-7]` | `Yk` |
1294| AArch64 | `reg` | `x[0-30]` | `r` |
1295| AArch64 | `vreg` | `v[0-31]` | `w` |
1296| AArch64 | `vreg_low16` | `v[0-15]` | `x` |
1297| ARM | `reg` | `r[0-12]`, `r14` | `r` |
1298| ARM (Thumb) | `reg_thumb` | `r[0-r7]` | `l` |
1299| ARM (ARM) | `reg_thumb` | `r[0-r12]`, `r14` | `l` |
1300| ARM | `sreg` | `s[0-31]` | `t` |
1301| ARM | `sreg_low16` | `s[0-15]` | `x` |
1302| ARM | `dreg` | `d[0-31]` | `w` |
1303| ARM | `dreg_low16` | `d[0-15]` | `t` |
1304| ARM | `dreg_low8` | `d[0-8]` | `x` |
1305| ARM | `qreg` | `q[0-15]` | `w` |
1306| ARM | `qreg_low8` | `q[0-7]` | `t` |
1307| ARM | `qreg_low4` | `q[0-3]` | `x` |
1308| MIPS | `reg` | `$[2-25]` | `r` |
1309| MIPS | `freg` | `$f[0-31]` | `f` |
1310| NVPTX | `reg16` | None\* | `h` |
1311| NVPTX | `reg32` | None\* | `r` |
1312| NVPTX | `reg64` | None\* | `l` |
1313| RISC-V | `reg` | `x1`, `x[5-7]`, `x[9-15]`, `x[16-31]` (non-RV32E) | `r` |
1314| RISC-V | `freg` | `f[0-31]` | `f` |
1315| Hexagon | `reg` | `r[0-28]` | `r` |
1316| PowerPC | `reg` | `r[0-31]` | `r` |
1317| PowerPC | `reg_nonzero` | | `r[1-31]` | `b` |
1318| PowerPC | `freg` | `f[0-31]` | `f` |
1319| wasm32 | `local` | None\* | `r` |
1320
1321> **Note**: On x86 we treat `reg_byte` differently from `reg` because the compiler can allocate `al` and `ah` separately whereas `reg` reserves the whole register.
1322>
1323> Note #2: On x86-64 the high byte registers (e.g. `ah`) are not available in the `reg_byte` register class.
1324>
1325> Note #3: NVPTX doesn't have a fixed register set, so named registers are not supported.
1326>
1327> Note #4: WebAssembly doesn't have registers, so named registers are not supported.
1328
1329Additional register classes may be added in the future based on demand (e.g. MMX, x87, etc).
1330
1331Each register class has constraints on which value types they can be used with. This is necessary because the way a value is loaded into a register depends on its type. For example, on big-endian systems, loading a `i32x4` and a `i8x16` into a SIMD register may result in different register contents even if the byte-wise memory representation of both values is identical. The availability of supported types for a particular register class may depend on what target features are currently enabled.
1332
1333| Architecture | Register class | Target feature | Allowed types |
1334| ------------ | -------------- | -------------- | ------------- |
1335| x86-32 | `reg` | None | `i16`, `i32`, `f32` |
1336| x86-64 | `reg` | None | `i16`, `i32`, `f32`, `i64`, `f64` |
1337| x86 | `reg_byte` | None | `i8` |
1338| x86 | `xmm_reg` | `sse` | `i32`, `f32`, `i64`, `f64`, <br> `i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` |
1339| x86 | `ymm_reg` | `avx` | `i32`, `f32`, `i64`, `f64`, <br> `i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` <br> `i8x32`, `i16x16`, `i32x8`, `i64x4`, `f32x8`, `f64x4` |
1340| x86 | `zmm_reg` | `avx512f` | `i32`, `f32`, `i64`, `f64`, <br> `i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` <br> `i8x32`, `i16x16`, `i32x8`, `i64x4`, `f32x8`, `f64x4` <br> `i8x64`, `i16x32`, `i32x16`, `i64x8`, `f32x16`, `f64x8` |
1341| x86 | `kreg` | `axv512f` | `i8`, `i16` |
1342| x86 | `kreg` | `axv512bw` | `i32`, `i64` |
1343| AArch64 | `reg` | None | `i8`, `i16`, `i32`, `f32`, `i64`, `f64` |
1344| AArch64 | `vreg` | `fp` | `i8`, `i16`, `i32`, `f32`, `i64`, `f64`, <br> `i8x8`, `i16x4`, `i32x2`, `i64x1`, `f32x2`, `f64x1`, <br> `i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` |
1345| ARM | `reg` | None | `i8`, `i16`, `i32`, `f32` |
1346| ARM | `sreg` | `vfp2` | `i32`, `f32` |
1347| ARM | `dreg` | `vfp2` | `i64`, `f64`, `i8x8`, `i16x4`, `i32x2`, `i64x1`, `f32x2` |
1348| ARM | `qreg` | `neon` | `i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4` |
1349| MIPS32 | `reg` | None | `i8`, `i16`, `i32`, `f32` |
1350| MIPS32 | `freg` | None | `f32`, `f64` |
1351| MIPS64 | `reg` | None | `i8`, `i16`, `i32`, `i64`, `f32`, `f64` |
1352| MIPS64 | `freg` | None | `f32`, `f64` |
1353| NVPTX | `reg16` | None | `i8`, `i16` |
1354| NVPTX | `reg32` | None | `i8`, `i16`, `i32`, `f32` |
1355| NVPTX | `reg64` | None | `i8`, `i16`, `i32`, `f32`, `i64`, `f64` |
1356| RISC-V32 | `reg` | None | `i8`, `i16`, `i32`, `f32` |
1357| RISC-V64 | `reg` | None | `i8`, `i16`, `i32`, `f32`, `i64`, `f64` |
1358| RISC-V | `freg` | `f` | `f32` |
1359| RISC-V | `freg` | `d` | `f64` |
1360| Hexagon | `reg` | None | `i8`, `i16`, `i32`, `f32` |
1361| PowerPC | `reg` | None | `i8`, `i16`, `i32` |
1362| PowerPC | `reg_nonzero` | None | `i8`, `i16`, `i32` |
1363| PowerPC | `freg` | None | `f32`, `f64` |
1364| wasm32 | `local` | None | `i8` `i16` `i32` `i64` `f32` `f64` |
1365
1366> **Note**: For the purposes of the above table pointers, function pointers and `isize`/`usize` are treated as the equivalent integer type (`i16`/`i32`/`i64` depending on the target).
1367
1368If a value is of a smaller size than the register it is allocated in then the upper bits of that register will have an undefined value for inputs and will be ignored for outputs. The only exception is the `freg` register class on RISC-V where `f32` values are NaN-boxed in a `f64` as required by the RISC-V architecture.
1369
1370When separate input and output expressions are specified for an `inout` operand, both expressions must have the same type. The only exception is if both operands are pointers or integers, in which case they are only required to have the same size. This restriction exists because the register allocators in LLVM and GCC sometimes cannot handle tied operands with different types.
1371
1372## Register names
1373
1374Some registers have multiple names. These are all treated by the compiler as identical to the base register name. Here is the list of all supported register aliases:
1375
1376| Architecture | Base register | Aliases |
1377| ------------ | ------------- | ------- |
1378| x86 | `ax` | `eax`, `rax` |
1379| x86 | `bx` | `ebx`, `rbx` |
1380| x86 | `cx` | `ecx`, `rcx` |
1381| x86 | `dx` | `edx`, `rdx` |
1382| x86 | `si` | `esi`, `rsi` |
1383| x86 | `di` | `edi`, `rdi` |
1384| x86 | `bp` | `bpl`, `ebp`, `rbp` |
1385| x86 | `sp` | `spl`, `esp`, `rsp` |
1386| x86 | `ip` | `eip`, `rip` |
1387| x86 | `st(0)` | `st` |
1388| x86 | `r[8-15]` | `r[8-15]b`, `r[8-15]w`, `r[8-15]d` |
1389| x86 | `xmm[0-31]` | `ymm[0-31]`, `zmm[0-31]` |
1390| AArch64 | `x[0-30]` | `w[0-30]` |
1391| AArch64 | `x29` | `fp` |
1392| AArch64 | `x30` | `lr` |
1393| AArch64 | `sp` | `wsp` |
1394| AArch64 | `xzr` | `wzr` |
1395| AArch64 | `v[0-31]` | `b[0-31]`, `h[0-31]`, `s[0-31]`, `d[0-31]`, `q[0-31]` |
1396| ARM | `r[0-3]` | `a[1-4]` |
1397| ARM | `r[4-9]` | `v[1-6]` |
1398| ARM | `r9` | `rfp` |
1399| ARM | `r10` | `sl` |
1400| ARM | `r11` | `fp` |
1401| ARM | `r12` | `ip` |
1402| ARM | `r13` | `sp` |
1403| ARM | `r14` | `lr` |
1404| ARM | `r15` | `pc` |
1405| RISC-V | `x0` | `zero` |
1406| RISC-V | `x1` | `ra` |
1407| RISC-V | `x2` | `sp` |
1408| RISC-V | `x3` | `gp` |
1409| RISC-V | `x4` | `tp` |
1410| RISC-V | `x[5-7]` | `t[0-2]` |
1411| RISC-V | `x8` | `fp`, `s0` |
1412| RISC-V | `x9` | `s1` |
1413| RISC-V | `x[10-17]` | `a[0-7]` |
1414| RISC-V | `x[18-27]` | `s[2-11]` |
1415| RISC-V | `x[28-31]` | `t[3-6]` |
1416| RISC-V | `f[0-7]` | `ft[0-7]` |
1417| RISC-V | `f[8-9]` | `fs[0-1]` |
1418| RISC-V | `f[10-17]` | `fa[0-7]` |
1419| RISC-V | `f[18-27]` | `fs[2-11]` |
1420| RISC-V | `f[28-31]` | `ft[8-11]` |
1421| Hexagon | `r29` | `sp` |
1422| Hexagon | `r30` | `fr` |
1423| Hexagon | `r31` | `lr` |
1424
1425Some registers cannot be used for input or output operands:
1426
1427| Architecture | Unsupported register | Reason |
1428| ------------ | -------------------- | ------ |
1429| All | `sp` | The stack pointer must be restored to its original value at the end of an asm code block. |
1430| All | `bp` (x86), `x29` (AArch64), `x8` (RISC-V), `fr` (Hexagon), `$fp` (MIPS) | The frame pointer cannot be used as an input or output. |
1431| ARM | `r7` or `r11` | On ARM the frame pointer can be either `r7` or `r11` depending on the target. The frame pointer cannot be used as an input or output. |
1432| All | `si` (x86-32), `bx` (x86-64), `r6` (ARM), `x19` (AArch64), `r19` (Hexagon), `x9` (RISC-V) | This is used internally by LLVM as a "base pointer" for functions with complex stack frames. |
1433| x86 | `k0` | This is a constant zero register which can't be modified. |
1434| x86 | `ip` | This is the program counter, not a real register. |
1435| x86 | `mm[0-7]` | MMX registers are not currently supported (but may be in the future). |
1436| x86 | `st([0-7])` | x87 registers are not currently supported (but may be in the future). |
1437| AArch64 | `xzr` | This is a constant zero register which can't be modified. |
1438| ARM | `pc` | This is the program counter, not a real register. |
1439| ARM | `r9` | This is a reserved register on some ARM targets. |
1440| MIPS | `$0` or `$zero` | This is a constant zero register which can't be modified. |
1441| MIPS | `$1` or `$at` | Reserved for assembler. |
1442| MIPS | `$26`/`$k0`, `$27`/`$k1` | OS-reserved registers. |
1443| MIPS | `$28`/`$gp` | Global pointer cannot be used as inputs or outputs. |
1444| MIPS | `$ra` | Return address cannot be used as inputs or outputs. |
1445| RISC-V | `x0` | This is a constant zero register which can't be modified. |
1446| RISC-V | `gp`, `tp` | These registers are reserved and cannot be used as inputs or outputs. |
1447| Hexagon | `lr` | This is the link register which cannot be used as an input or output. |
1448
1449In some cases LLVM will allocate a "reserved register" for `reg` operands even though this register cannot be explicitly specified. Assembly code making use of reserved registers should be careful since `reg` operands may alias with those registers. Reserved registers are the frame pointer and base pointer
1450- The frame pointer and LLVM base pointer on all architectures.
1451- `r9` on ARM.
1452- `x18` on AArch64.
1453
1454## Template modifiers
1455
1456The placeholders can be augmented by modifiers which are specified after the `:` in the curly braces. These modifiers do not affect register allocation, but change the way operands are formatted when inserted into the template string. Only one modifier is allowed per template placeholder.
1457
1458The supported modifiers are a subset of LLVM's (and GCC's) [asm template argument modifiers][llvm-argmod], but do not use the same letter codes.
1459
1460| Architecture | Register class | Modifier | Example output | LLVM modifier |
1461| ------------ | -------------- | -------- | -------------- | ------------- |
1462| x86-32 | `reg` | None | `eax` | `k` |
1463| x86-64 | `reg` | None | `rax` | `q` |
1464| x86-32 | `reg_abcd` | `l` | `al` | `b` |
1465| x86-64 | `reg` | `l` | `al` | `b` |
1466| x86 | `reg_abcd` | `h` | `ah` | `h` |
1467| x86 | `reg` | `x` | `ax` | `w` |
1468| x86 | `reg` | `e` | `eax` | `k` |
1469| x86-64 | `reg` | `r` | `rax` | `q` |
1470| x86 | `reg_byte` | None | `al` / `ah` | None |
1471| x86 | `xmm_reg` | None | `xmm0` | `x` |
1472| x86 | `ymm_reg` | None | `ymm0` | `t` |
1473| x86 | `zmm_reg` | None | `zmm0` | `g` |
1474| x86 | `*mm_reg` | `x` | `xmm0` | `x` |
1475| x86 | `*mm_reg` | `y` | `ymm0` | `t` |
1476| x86 | `*mm_reg` | `z` | `zmm0` | `g` |
1477| x86 | `kreg` | None | `k1` | None |
1478| AArch64 | `reg` | None | `x0` | `x` |
1479| AArch64 | `reg` | `w` | `w0` | `w` |
1480| AArch64 | `reg` | `x` | `x0` | `x` |
1481| AArch64 | `vreg` | None | `v0` | None |
1482| AArch64 | `vreg` | `v` | `v0` | None |
1483| AArch64 | `vreg` | `b` | `b0` | `b` |
1484| AArch64 | `vreg` | `h` | `h0` | `h` |
1485| AArch64 | `vreg` | `s` | `s0` | `s` |
1486| AArch64 | `vreg` | `d` | `d0` | `d` |
1487| AArch64 | `vreg` | `q` | `q0` | `q` |
1488| ARM | `reg` | None | `r0` | None |
1489| ARM | `sreg` | None | `s0` | None |
1490| ARM | `dreg` | None | `d0` | `P` |
1491| ARM | `qreg` | None | `q0` | `q` |
1492| ARM | `qreg` | `e` / `f` | `d0` / `d1` | `e` / `f` |
1493| MIPS | `reg` | None | `$2` | None |
1494| MIPS | `freg` | None | `$f0` | None |
1495| NVPTX | `reg16` | None | `rs0` | None |
1496| NVPTX | `reg32` | None | `r0` | None |
1497| NVPTX | `reg64` | None | `rd0` | None |
1498| RISC-V | `reg` | None | `x1` | None |
1499| RISC-V | `freg` | None | `f0` | None |
1500| Hexagon | `reg` | None | `r0` | None |
1501| PowerPC | `reg` | None | `0` | None |
1502| PowerPC | `reg_nonzero` | None | `3` | `b` |
1503| PowerPC | `freg` | None | `0` | None |
1504
1505> Notes:
1506> - on ARM `e` / `f`: this prints the low or high doubleword register name of a NEON quad (128-bit) register.
1507> - on x86: our behavior for `reg` with no modifiers differs from what GCC does. GCC will infer the modifier based on the operand value type, while we default to the full register size.
1508> - on x86 `xmm_reg`: the `x`, `t` and `g` LLVM modifiers are not yet implemented in LLVM (they are supported by GCC only), but this should be a simple change.
1509
1510As stated in the previous section, passing an input value smaller than the register width will result in the upper bits of the register containing undefined values. This is not a problem if the inline asm only accesses the lower bits of the register, which can be done by using a template modifier to use a subregister name in the asm code (e.g. `ax` instead of `rax`). Since this an easy pitfall, the compiler will suggest a template modifier to use where appropriate given the input type. If all references to an operand already have modifiers then the warning is suppressed for that operand.
1511
1512[llvm-argmod]: http://llvm.org/docs/LangRef.html#asm-template-argument-modifiers
1513
1514## Options
1515
1516Flags are used to further influence the behavior of the inline assembly block.
1517Currently the following options are defined:
1518- `pure`: The `asm` block has no side effects, and its outputs depend only on its direct inputs (i.e. the values themselves, not what they point to) or values read from memory (unless the `nomem` options is also set). This allows the compiler to execute the `asm` block fewer times than specified in the program (e.g. by hoisting it out of a loop) or even eliminate it entirely if the outputs are not used.
1519- `nomem`: The `asm` blocks does not read or write to any memory. This allows the compiler to cache the values of modified global variables in registers across the `asm` block since it knows that they are not read or written to by the `asm`.
1520- `readonly`: The `asm` block does not write to any memory. This allows the compiler to cache the values of unmodified global variables in registers across the `asm` block since it knows that they are not written to by the `asm`.
1521- `preserves_flags`: The `asm` block does not modify the flags register (defined in the rules below). This allows the compiler to avoid recomputing the condition flags after the `asm` block.
1522- `noreturn`: The `asm` block never returns, and its return type is defined as `!` (never). Behavior is undefined if execution falls through past the end of the asm code. A `noreturn` asm block behaves just like a function which doesn't return; notably, local variables in scope are not dropped before it is invoked.
1523- `nostack`: The `asm` block does not push data to the stack, or write to the stack red-zone (if supported by the target). If this option is *not* used then the stack pointer is guaranteed to be suitably aligned (according to the target ABI) for a function call.
1524- `att_syntax`: This option is only valid on x86, and causes the assembler to use the `.att_syntax prefix` mode of the GNU assembler. Register operands are substituted in with a leading `%`.
1525
1526The compiler performs some additional checks on options:
1527- The `nomem` and `readonly` options are mutually exclusive: it is a compile-time error to specify both.
1528- The `pure` option must be combined with either the `nomem` or `readonly` options, otherwise a compile-time error is emitted.
1529- It is a compile-time error to specify `pure` on an asm block with no outputs or only discarded outputs (`_`).
1530- It is a compile-time error to specify `noreturn` on an asm block with outputs.
1531
1532## Rules for inline assembly
1533
1534- Any registers not specified as inputs will contain an undefined value on entry to the asm block.
1535 - An "undefined value" in the context of inline assembly means that the register can (non-deterministically) have any one of the possible values allowed by the architecture. Notably it is not the same as an LLVM `undef` which can have a different value every time you read it (since such a concept does not exist in assembly code).
1536- Any registers not specified as outputs must have the same value upon exiting the asm block as they had on entry, otherwise behavior is undefined.
1537 - This only applies to registers which can be specified as an input or output. Other registers follow target-specific rules.
1538 - Note that a `lateout` may be allocated to the same register as an `in`, in which case this rule does not apply. Code should not rely on this however since it depends on the results of register allocation.
1539- Behavior is undefined if execution unwinds out of an asm block.
1540 - This also applies if the assembly code calls a function which then unwinds.
1541- The set of memory locations that assembly code is allowed the read and write are the same as those allowed for an FFI function.
1542 - Refer to the unsafe code guidelines for the exact rules.
1543 - If the `readonly` option is set, then only memory reads are allowed.
1544 - If the `nomem` option is set then no reads or writes to memory are allowed.
1545 - These rules do not apply to memory which is private to the asm code, such as stack space allocated within the asm block.
1546- The compiler cannot assume that the instructions in the asm are the ones that will actually end up executed.
1547 - This effectively means that the compiler must treat the `asm!` as a black box and only take the interface specification into account, not the instructions themselves.
1548 - Runtime code patching is allowed, via target-specific mechanisms (outside the scope of this RFC).
1549- Unless the `nostack` option is set, asm code is allowed to use stack space below the stack pointer.
1550 - On entry to the asm block the stack pointer is guaranteed to be suitably aligned (according to the target ABI) for a function call.
1551 - You are responsible for making sure you don't overflow the stack (e.g. use stack probing to ensure you hit a guard page).
1552 - You should adjust the stack pointer when allocating stack memory as required by the target ABI.
1553 - The stack pointer must be restored to its original value before leaving the asm block.
1554- If the `noreturn` option is set then behavior is undefined if execution falls through to the end of the asm block.
1555- If the `pure` option is set then behavior is undefined if the `asm` has side-effects other than its direct outputs. Behavior is also undefined if two executions of the `asm` code with the same inputs result in different outputs.
1556 - When used with the `nomem` option, "inputs" are just the direct inputs of the `asm!`.
1557 - When used with the `readonly` option, "inputs" comprise the direct inputs of the `asm!` and any memory that the `asm!` block is allowed to read.
1558- These flags registers must be restored upon exiting the asm block if the `preserves_flags` option is set:
1559 - x86
1560 - Status flags in `EFLAGS` (CF, PF, AF, ZF, SF, OF).
1561 - Floating-point status word (all).
1562 - Floating-point exception flags in `MXCSR` (PE, UE, OE, ZE, DE, IE).
1563 - ARM
1564 - Condition flags in `CPSR` (N, Z, C, V)
1565 - Saturation flag in `CPSR` (Q)
1566 - Greater than or equal flags in `CPSR` (GE).
1567 - Condition flags in `FPSCR` (N, Z, C, V)
1568 - Saturation flag in `FPSCR` (QC)
1569 - Floating-point exception flags in `FPSCR` (IDC, IXC, UFC, OFC, DZC, IOC).
1570 - AArch64
1571 - Condition flags (`NZCV` register).
1572 - Floating-point status (`FPSR` register).
1573 - RISC-V
1574 - Floating-point exception flags in `fcsr` (`fflags`).
1575- On x86, the direction flag (DF in `EFLAGS`) is clear on entry to an asm block and must be clear on exit.
1576 - Behavior is undefined if the direction flag is set on exiting an asm block.
1577- The requirement of restoring the stack pointer and non-output registers to their original value only applies when exiting an `asm!` block.
1578 - This means that `asm!` blocks that never return (even if not marked `noreturn`) don't need to preserve these registers.
1579 - When returning to a different `asm!` block than you entered (e.g. for context switching), these registers must contain the value they had upon entering the `asm!` block that you are *exiting*.
1580 - You cannot exit an `asm!` block that has not been entered. Neither can you exit an `asm!` block that has already been exited.
1581 - You are responsible for switching any target-specific state (e.g. thread-local storage, stack bounds).
1582 - The set of memory locations that you may access is the intersection of those allowed by the `asm!` blocks you entered and exited.
1583- You cannot assume that an `asm!` block will appear exactly once in the output binary. The compiler is allowed to instantiate multiple copies of the `asm!` block, for example when the function containing it is inlined in multiple places.
1584
1585> **Note**: As a general rule, the flags covered by `preserves_flags` are those which are *not* preserved when performing a function call.
1586"##,
1587 },
1588 Lint {
1589 label: "auto_traits",
1590 description: r##"# `auto_traits`
1591
1592The tracking issue for this feature is [#13231]
1593
1594[#13231]: https://github.com/rust-lang/rust/issues/13231
1595
1596----
1597
1598The `auto_traits` feature gate allows you to define auto traits.
1599
1600Auto traits, like [`Send`] or [`Sync`] in the standard library, are marker traits
1601that are automatically implemented for every type, unless the type, or a type it contains,
1602has explicitly opted out via a negative impl. (Negative impls are separately controlled
1603by the `negative_impls` feature.)
1604
1605[`Send`]: https://doc.rust-lang.org/std/marker/trait.Send.html
1606[`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html
1607
1608```rust,ignore (partial-example)
1609impl !Trait for Type {}
1610```
1611
1612Example:
1613
1614```rust
1615#![feature(negative_impls)]
1616#![feature(auto_traits)]
1617
1618auto trait Valid {}
1619
1620struct True;
1621struct False;
1622
1623impl !Valid for False {}
1624
1625struct MaybeValid<T>(T);
1626
1627fn must_be_valid<T: Valid>(_t: T) { }
1628
1629fn main() {
1630 // works
1631 must_be_valid( MaybeValid(True) );
1632
1633 // compiler error - trait bound not satisfied
1634 // must_be_valid( MaybeValid(False) );
1635}
1636```
1637
1638## Automatic trait implementations
1639
1640When a type is declared as an `auto trait`, we will automatically
1641create impls for every struct/enum/union, unless an explicit impl is
1642provided. These automatic impls contain a where clause for each field
1643of the form `T: AutoTrait`, where `T` is the type of the field and
1644`AutoTrait` is the auto trait in question. As an example, consider the
1645struct `List` and the auto trait `Send`:
1646
1647```rust
1648struct List<T> {
1649 data: T,
1650 next: Option<Box<List<T>>>,
1651}
1652```
1653
1654Presuming that there is no explicit impl of `Send` for `List`, the
1655compiler will supply an automatic impl of the form:
1656
1657```rust
1658struct List<T> {
1659 data: T,
1660 next: Option<Box<List<T>>>,
1661}
1662
1663unsafe impl<T> Send for List<T>
1664where
1665 T: Send, // from the field `data`
1666 Option<Box<List<T>>>: Send, // from the field `next`
1667{ }
1668```
1669
1670Explicit impls may be either positive or negative. They take the form:
1671
1672```rust,ignore (partial-example)
1673impl<...> AutoTrait for StructName<..> { }
1674impl<...> !AutoTrait for StructName<..> { }
1675```
1676
1677## Coinduction: Auto traits permit cyclic matching
1678
1679Unlike ordinary trait matching, auto traits are **coinductive**. This
1680means, in short, that cycles which occur in trait matching are
1681considered ok. As an example, consider the recursive struct `List`
1682introduced in the previous section. In attempting to determine whether
1683`List: Send`, we would wind up in a cycle: to apply the impl, we must
1684show that `Option<Box<List>>: Send`, which will in turn require
1685`Box<List>: Send` and then finally `List: Send` again. Under ordinary
1686trait matching, this cycle would be an error, but for an auto trait it
1687is considered a successful match.
1688
1689## Items
1690
1691Auto traits cannot have any trait items, such as methods or associated types. This ensures that we can generate default implementations.
1692
1693## Supertraits
1694
1695Auto traits cannot have supertraits. This is for soundness reasons, as the interaction of coinduction with implied bounds is difficult to reconcile.
1696"##,
1697 },
1698 Lint {
1699 label: "box_patterns",
1700 description: r##"# `box_patterns`
1701
1702The tracking issue for this feature is: [#29641]
1703
1704[#29641]: https://github.com/rust-lang/rust/issues/29641
1705
1706See also [`box_syntax`](box-syntax.md)
1707
1708------------------------
1709
1710Box patterns let you match on `Box<T>`s:
1711
1712
1713```rust
1714#![feature(box_patterns)]
1715
1716fn main() {
1717 let b = Some(Box::new(5));
1718 match b {
1719 Some(box n) if n < 0 => {
1720 println!("Box contains negative number {}", n);
1721 },
1722 Some(box n) if n >= 0 => {
1723 println!("Box contains non-negative number {}", n);
1724 },
1725 None => {
1726 println!("No box");
1727 },
1728 _ => unreachable!()
1729 }
1730}
1731```
1732"##,
1733 },
1734 Lint {
1735 label: "box_syntax",
1736 description: r##"# `box_syntax`
1737
1738The tracking issue for this feature is: [#49733]
1739
1740[#49733]: https://github.com/rust-lang/rust/issues/49733
1741
1742See also [`box_patterns`](box-patterns.md)
1743
1744------------------------
1745
1746Currently the only stable way to create a `Box` is via the `Box::new` method.
1747Also it is not possible in stable Rust to destructure a `Box` in a match
1748pattern. The unstable `box` keyword can be used to create a `Box`. An example
1749usage would be:
1750
1751```rust
1752#![feature(box_syntax)]
1753
1754fn main() {
1755 let b = box 5;
1756}
1757```
1758"##,
1759 },
1760 Lint {
1761 label: "c_unwind",
1762 description: r##"# `c_unwind`
1763
1764The tracking issue for this feature is: [#74990]
1765
1766[#74990]: https://github.com/rust-lang/rust/issues/74990
1767
1768------------------------
1769
1770Introduces four new ABI strings: "C-unwind", "stdcall-unwind",
1771"thiscall-unwind", and "system-unwind". These enable unwinding from other
1772languages (such as C++) into Rust frames and from Rust into other languages.
1773
1774See [RFC 2945] for more information.
1775
1776[RFC 2945]: https://github.com/rust-lang/rfcs/blob/master/text/2945-c-unwind-abi.md
1777"##,
1778 },
1779 Lint {
1780 label: "c_variadic",
1781 description: r##"# `c_variadic`
1782
1783The tracking issue for this feature is: [#44930]
1784
1785[#44930]: https://github.com/rust-lang/rust/issues/44930
1786
1787------------------------
1788
1789The `c_variadic` language feature enables C-variadic functions to be
1790defined in Rust. The may be called both from within Rust and via FFI.
1791
1792## Examples
1793
1794```rust
1795#![feature(c_variadic)]
1796
1797pub unsafe extern "C" fn add(n: usize, mut args: ...) -> usize {
1798 let mut sum = 0;
1799 for _ in 0..n {
1800 sum += args.arg::<usize>();
1801 }
1802 sum
1803}
1804```
1805"##,
1806 },
1807 Lint {
1808 label: "c_variadic",
1809 description: r##"# `c_variadic`
1810
1811The tracking issue for this feature is: [#44930]
1812
1813[#44930]: https://github.com/rust-lang/rust/issues/44930
1814
1815------------------------
1816
1817The `c_variadic` library feature exposes the `VaList` structure,
1818Rust's analogue of C's `va_list` type.
1819
1820## Examples
1821
1822```rust
1823#![feature(c_variadic)]
1824
1825use std::ffi::VaList;
1826
1827pub unsafe extern "C" fn vadd(n: usize, mut args: VaList) -> usize {
1828 let mut sum = 0;
1829 for _ in 0..n {
1830 sum += args.arg::<usize>();
1831 }
1832 sum
1833}
1834```
1835"##,
1836 },
1837 Lint {
1838 label: "c_void_variant",
1839 description: r##"# `c_void_variant`
1840
1841This feature is internal to the Rust compiler and is not intended for general use.
1842
1843------------------------
1844"##,
1845 },
1846 Lint {
1847 label: "cfg_panic",
1848 description: r##"# `cfg_panic`
1849
1850The tracking issue for this feature is: [#77443]
1851
1852[#77443]: https://github.com/rust-lang/rust/issues/77443
1853
1854------------------------
1855
1856The `cfg_panic` feature makes it possible to execute different code
1857depending on the panic strategy.
1858
1859Possible values at the moment are `"unwind"` or `"abort"`, although
1860it is possible that new panic strategies may be added to Rust in the
1861future.
1862
1863## Examples
1864
1865```rust
1866#![feature(cfg_panic)]
1867
1868#[cfg(panic = "unwind")]
1869fn a() {
1870 // ...
1871}
1872
1873#[cfg(not(panic = "unwind"))]
1874fn a() {
1875 // ...
1876}
1877
1878fn b() {
1879 if cfg!(panic = "abort") {
1880 // ...
1881 } else {
1882 // ...
1883 }
1884}
1885```
1886"##,
1887 },
1888 Lint {
1889 label: "cfg_sanitize",
1890 description: r##"# `cfg_sanitize`
1891
1892The tracking issue for this feature is: [#39699]
1893
1894[#39699]: https://github.com/rust-lang/rust/issues/39699
1895
1896------------------------
1897
1898The `cfg_sanitize` feature makes it possible to execute different code
1899depending on whether a particular sanitizer is enabled or not.
1900
1901## Examples
1902
1903```rust
1904#![feature(cfg_sanitize)]
1905
1906#[cfg(sanitize = "thread")]
1907fn a() {
1908 // ...
1909}
1910
1911#[cfg(not(sanitize = "thread"))]
1912fn a() {
1913 // ...
1914}
1915
1916fn b() {
1917 if cfg!(sanitize = "leak") {
1918 // ...
1919 } else {
1920 // ...
1921 }
1922}
1923```
1924"##,
1925 },
1926 Lint {
1927 label: "cfg_version",
1928 description: r##"# `cfg_version`
1929
1930The tracking issue for this feature is: [#64796]
1931
1932[#64796]: https://github.com/rust-lang/rust/issues/64796
1933
1934------------------------
1935
1936The `cfg_version` feature makes it possible to execute different code
1937depending on the compiler version. It will return true if the compiler
1938version is greater than or equal to the specified version.
1939
1940## Examples
1941
1942```rust
1943#![feature(cfg_version)]
1944
1945#[cfg(version("1.42"))] // 1.42 and above
1946fn a() {
1947 // ...
1948}
1949
1950#[cfg(not(version("1.42")))] // 1.41 and below
1951fn a() {
1952 // ...
1953}
1954
1955fn b() {
1956 if cfg!(version("1.42")) {
1957 // ...
1958 } else {
1959 // ...
1960 }
1961}
1962```
1963"##,
1964 },
1965 Lint {
1966 label: "char_error_internals",
1967 description: r##"# `char_error_internals`
1968
1969This feature is internal to the Rust compiler and is not intended for general use.
1970
1971------------------------
1972"##,
1973 },
1974 Lint {
1975 label: "cmse_nonsecure_entry",
1976 description: r##"# `cmse_nonsecure_entry`
1977
1978The tracking issue for this feature is: [#75835]
1979
1980[#75835]: https://github.com/rust-lang/rust/issues/75835
1981
1982------------------------
1983
1984The [TrustZone-M
1985feature](https://developer.arm.com/documentation/100690/latest/) is available
1986for targets with the Armv8-M architecture profile (`thumbv8m` in their target
1987name).
1988LLVM, the Rust compiler and the linker are providing
1989[support](https://developer.arm.com/documentation/ecm0359818/latest/) for the
1990TrustZone-M feature.
1991
1992One of the things provided, with this unstable feature, is the
1993`cmse_nonsecure_entry` attribute. This attribute marks a Secure function as an
1994entry function (see [section
19955.4](https://developer.arm.com/documentation/ecm0359818/latest/) for details).
1996With this attribute, the compiler will do the following:
1997* add a special symbol on the function which is the `__acle_se_` prefix and the
1998 standard function name
1999* constrain the number of parameters to avoid using the Non-Secure stack
2000* before returning from the function, clear registers that might contain Secure
2001 information
2002* use the `BXNS` instruction to return
2003
2004Because the stack can not be used to pass parameters, there will be compilation
2005errors if:
2006* the total size of all parameters is too big (for example more than four 32
2007 bits integers)
2008* the entry function is not using a C ABI
2009
2010The special symbol `__acle_se_` will be used by the linker to generate a secure
2011gateway veneer.
2012
2013<!-- NOTE(ignore) this example is specific to thumbv8m targets -->
2014
2015``` rust,ignore
2016#![feature(cmse_nonsecure_entry)]
2017
2018#[no_mangle]
2019#[cmse_nonsecure_entry]
2020pub extern "C" fn entry_function(input: u32) -> u32 {
2021 input + 6
2022}
2023```
2024
2025``` text
2026$ rustc --emit obj --crate-type lib --target thumbv8m.main-none-eabi function.rs
2027$ arm-none-eabi-objdump -D function.o
2028
202900000000 <entry_function>:
2030 0: b580 push {r7, lr}
2031 2: 466f mov r7, sp
2032 4: b082 sub sp, #8
2033 6: 9001 str r0, [sp, #4]
2034 8: 1d81 adds r1, r0, #6
2035 a: 460a mov r2, r1
2036 c: 4281 cmp r1, r0
2037 e: 9200 str r2, [sp, #0]
2038 10: d30b bcc.n 2a <entry_function+0x2a>
2039 12: e7ff b.n 14 <entry_function+0x14>
2040 14: 9800 ldr r0, [sp, #0]
2041 16: b002 add sp, #8
2042 18: e8bd 4080 ldmia.w sp!, {r7, lr}
2043 1c: 4671 mov r1, lr
2044 1e: 4672 mov r2, lr
2045 20: 4673 mov r3, lr
2046 22: 46f4 mov ip, lr
2047 24: f38e 8800 msr CPSR_f, lr
2048 28: 4774 bxns lr
2049 2a: f240 0000 movw r0, #0
2050 2e: f2c0 0000 movt r0, #0
2051 32: f240 0200 movw r2, #0
2052 36: f2c0 0200 movt r2, #0
2053 3a: 211c movs r1, #28
2054 3c: f7ff fffe bl 0 <_ZN4core9panicking5panic17h5c028258ca2fb3f5E>
2055 40: defe udf #254 ; 0xfe
2056```
2057"##,
2058 },
2059 Lint {
2060 label: "compiler_builtins",
2061 description: r##"# `compiler_builtins`
2062
2063This feature is internal to the Rust compiler and is not intended for general use.
2064
2065------------------------
2066"##,
2067 },
2068 Lint {
2069 label: "concat_idents",
2070 description: r##"# `concat_idents`
2071
2072The tracking issue for this feature is: [#29599]
2073
2074[#29599]: https://github.com/rust-lang/rust/issues/29599
2075
2076------------------------
2077
2078The `concat_idents` feature adds a macro for concatenating multiple identifiers
2079into one identifier.
2080
2081## Examples
2082
2083```rust
2084#![feature(concat_idents)]
2085
2086fn main() {
2087 fn foobar() -> u32 { 23 }
2088 let f = concat_idents!(foo, bar);
2089 assert_eq!(f(), 23);
2090}
2091```
2092"##,
2093 },
2094 Lint {
2095 label: "const_eval_limit",
2096 description: r##"# `const_eval_limit`
2097
2098The tracking issue for this feature is: [#67217]
2099
2100[#67217]: https://github.com/rust-lang/rust/issues/67217
2101
2102The `const_eval_limit` allows someone to limit the evaluation steps the CTFE undertakes to evaluate a `const fn`.
2103"##,
2104 },
2105 Lint {
2106 label: "core_intrinsics",
2107 description: r##"# `core_intrinsics`
2108
2109This feature is internal to the Rust compiler and is not intended for general use.
2110
2111------------------------
2112"##,
2113 },
2114 Lint {
2115 label: "core_panic",
2116 description: r##"# `core_panic`
2117
2118This feature is internal to the Rust compiler and is not intended for general use.
2119
2120------------------------
2121"##,
2122 },
2123 Lint {
2124 label: "core_private_bignum",
2125 description: r##"# `core_private_bignum`
2126
2127This feature is internal to the Rust compiler and is not intended for general use.
2128
2129------------------------
2130"##,
2131 },
2132 Lint {
2133 label: "core_private_diy_float",
2134 description: r##"# `core_private_diy_float`
2135
2136This feature is internal to the Rust compiler and is not intended for general use.
2137
2138------------------------
2139"##,
2140 },
2141 Lint {
2142 label: "crate_visibility_modifier",
2143 description: r##"# `crate_visibility_modifier`
2144
2145The tracking issue for this feature is: [#53120]
2146
2147[#53120]: https://github.com/rust-lang/rust/issues/53120
2148
2149-----
2150
2151The `crate_visibility_modifier` feature allows the `crate` keyword to be used
2152as a visibility modifier synonymous to `pub(crate)`, indicating that a type
2153(function, _&c._) is to be visible to the entire enclosing crate, but not to
2154other crates.
2155
2156```rust
2157#![feature(crate_visibility_modifier)]
2158
2159crate struct Foo {
2160 bar: usize,
2161}
2162```
2163"##,
2164 },
2165 Lint {
2166 label: "custom_test_frameworks",
2167 description: r##"# `custom_test_frameworks`
2168
2169The tracking issue for this feature is: [#50297]
2170
2171[#50297]: https://github.com/rust-lang/rust/issues/50297
2172
2173------------------------
2174
2175The `custom_test_frameworks` feature allows the use of `#[test_case]` and `#![test_runner]`.
2176Any function, const, or static can be annotated with `#[test_case]` causing it to be aggregated (like `#[test]`)
2177and be passed to the test runner determined by the `#![test_runner]` crate attribute.
2178
2179```rust
2180#![feature(custom_test_frameworks)]
2181#![test_runner(my_runner)]
2182
2183fn my_runner(tests: &[&i32]) {
2184 for t in tests {
2185 if **t == 0 {
2186 println!("PASSED");
2187 } else {
2188 println!("FAILED");
2189 }
2190 }
2191}
2192
2193#[test_case]
2194const WILL_PASS: i32 = 0;
2195
2196#[test_case]
2197const WILL_FAIL: i32 = 4;
2198```
2199"##,
2200 },
2201 Lint {
2202 label: "dec2flt",
2203 description: r##"# `dec2flt`
2204
2205This feature is internal to the Rust compiler and is not intended for general use.
2206
2207------------------------
2208"##,
2209 },
2210 Lint {
2211 label: "default_free_fn",
2212 description: r##"# `default_free_fn`
2213
2214The tracking issue for this feature is: [#73014]
2215
2216[#73014]: https://github.com/rust-lang/rust/issues/73014
2217
2218------------------------
2219
2220Adds a free `default()` function to the `std::default` module. This function
2221just forwards to [`Default::default()`], but may remove repetition of the word
2222"default" from the call site.
2223
2224[`Default::default()`]: https://doc.rust-lang.org/nightly/std/default/trait.Default.html#tymethod.default
2225
2226Here is an example:
2227
2228```rust
2229#![feature(default_free_fn)]
2230use std::default::default;
2231
2232#[derive(Default)]
2233struct AppConfig {
2234 foo: FooConfig,
2235 bar: BarConfig,
2236}
2237
2238#[derive(Default)]
2239struct FooConfig {
2240 foo: i32,
2241}
2242
2243#[derive(Default)]
2244struct BarConfig {
2245 bar: f32,
2246 baz: u8,
2247}
2248
2249fn main() {
2250 let options = AppConfig {
2251 foo: default(),
2252 bar: BarConfig {
2253 bar: 10.1,
2254 ..default()
2255 },
2256 };
2257}
2258```
2259"##,
2260 },
2261 Lint {
2262 label: "derive_clone_copy",
2263 description: r##"# `derive_clone_copy`
2264
2265This feature is internal to the Rust compiler and is not intended for general use.
2266
2267------------------------
2268"##,
2269 },
2270 Lint {
2271 label: "derive_eq",
2272 description: r##"# `derive_eq`
2273
2274This feature is internal to the Rust compiler and is not intended for general use.
2275
2276------------------------
2277"##,
2278 },
2279 Lint {
2280 label: "doc_cfg",
2281 description: r##"# `doc_cfg`
2282
2283The tracking issue for this feature is: [#43781]
2284
2285------
2286
2287The `doc_cfg` feature allows an API be documented as only available in some specific platforms.
2288This attribute has two effects:
2289
22901. In the annotated item's documentation, there will be a message saying "This is supported on
2291 (platform) only".
2292
22932. The item's doc-tests will only run on the specific platform.
2294
2295In addition to allowing the use of the `#[doc(cfg)]` attribute, this feature enables the use of a
2296special conditional compilation flag, `#[cfg(doc)]`, set whenever building documentation on your
2297crate.
2298
2299This feature was introduced as part of PR [#43348] to allow the platform-specific parts of the
2300standard library be documented.
2301
2302```rust
2303#![feature(doc_cfg)]
2304
2305#[cfg(any(windows, doc))]
2306#[doc(cfg(windows))]
2307/// The application's icon in the notification area (a.k.a. system tray).
2308///
2309/// # Examples
2310///
2311/// ```no_run
2312/// extern crate my_awesome_ui_library;
2313/// use my_awesome_ui_library::current_app;
2314/// use my_awesome_ui_library::windows::notification;
2315///
2316/// let icon = current_app().get::<notification::Icon>();
2317/// icon.show();
2318/// icon.show_message("Hello");
2319/// ```
2320pub struct Icon {
2321 // ...
2322}
2323```
2324
2325[#43781]: https://github.com/rust-lang/rust/issues/43781
2326[#43348]: https://github.com/rust-lang/rust/issues/43348
2327"##,
2328 },
2329 Lint {
2330 label: "doc_masked",
2331 description: r##"# `doc_masked`
2332
2333The tracking issue for this feature is: [#44027]
2334
2335-----
2336
2337The `doc_masked` feature allows a crate to exclude types from a given crate from appearing in lists
2338of trait implementations. The specifics of the feature are as follows:
2339
23401. When rustdoc encounters an `extern crate` statement annotated with a `#[doc(masked)]` attribute,
2341 it marks the crate as being masked.
2342
23432. When listing traits a given type implements, rustdoc ensures that traits from masked crates are
2344 not emitted into the documentation.
2345
23463. When listing types that implement a given trait, rustdoc ensures that types from masked crates
2347 are not emitted into the documentation.
2348
2349This feature was introduced in PR [#44026] to ensure that compiler-internal and
2350implementation-specific types and traits were not included in the standard library's documentation.
2351Such types would introduce broken links into the documentation.
2352
2353[#44026]: https://github.com/rust-lang/rust/pull/44026
2354[#44027]: https://github.com/rust-lang/rust/pull/44027
2355"##,
2356 },
2357 Lint {
2358 label: "doc_notable_trait",
2359 description: r##"# `doc_notable_trait`
2360
2361The tracking issue for this feature is: [#45040]
2362
2363The `doc_notable_trait` feature allows the use of the `#[doc(notable_trait)]`
2364attribute, which will display the trait in a "Notable traits" dialog for
2365functions returning types that implement the trait. For example, this attribute
2366is applied to the `Iterator`, `Future`, `io::Read`, and `io::Write` traits in
2367the standard library.
2368
2369You can do this on your own traits like so:
2370
2371```
2372#![feature(doc_notable_trait)]
2373
2374#[doc(notable_trait)]
2375pub trait MyTrait {}
2376
2377pub struct MyStruct;
2378impl MyTrait for MyStruct {}
2379
2380/// The docs for this function will have a button that displays a dialog about
2381/// `MyStruct` implementing `MyTrait`.
2382pub fn my_fn() -> MyStruct { MyStruct }
2383```
2384
2385This feature was originally implemented in PR [#45039].
2386
2387See also its documentation in [the rustdoc book][rustdoc-book-notable_trait].
2388
2389[#45040]: https://github.com/rust-lang/rust/issues/45040
2390[#45039]: https://github.com/rust-lang/rust/pull/45039
2391[rustdoc-book-notable_trait]: ../../rustdoc/unstable-features.html#adding-your-trait-to-the-notable-traits-dialog
2392"##,
2393 },
2394 Lint {
2395 label: "external_doc",
2396 description: r##"# `external_doc`
2397
2398The tracking issue for this feature is: [#44732]
2399
2400The `external_doc` feature allows the use of the `include` parameter to the `#[doc]` attribute, to
2401include external files in documentation. Use the attribute in place of, or in addition to, regular
2402doc comments and `#[doc]` attributes, and `rustdoc` will load the given file when it renders
2403documentation for your crate.
2404
2405With the following files in the same directory:
2406
2407`external-doc.md`:
2408
2409```markdown
2410# My Awesome Type
2411
2412This is the documentation for this spectacular type.
2413```
2414
2415`lib.rs`:
2416
2417```no_run (needs-external-files)
2418#![feature(external_doc)]
2419
2420#[doc(include = "external-doc.md")]
2421pub struct MyAwesomeType;
2422```
2423
2424`rustdoc` will load the file `external-doc.md` and use it as the documentation for the `MyAwesomeType`
2425struct.
2426
2427When locating files, `rustdoc` will base paths in the `src/` directory, as if they were alongside the
2428`lib.rs` for your crate. So if you want a `docs/` folder to live alongside the `src/` directory,
2429start your paths with `../docs/` for `rustdoc` to properly find the file.
2430
2431This feature was proposed in [RFC #1990] and initially implemented in PR [#44781].
2432
2433[#44732]: https://github.com/rust-lang/rust/issues/44732
2434[RFC #1990]: https://github.com/rust-lang/rfcs/pull/1990
2435[#44781]: https://github.com/rust-lang/rust/pull/44781
2436"##,
2437 },
2438 Lint {
2439 label: "fd",
2440 description: r##"# `fd`
2441
2442This feature is internal to the Rust compiler and is not intended for general use.
2443
2444------------------------
2445"##,
2446 },
2447 Lint {
2448 label: "fd_read",
2449 description: r##"# `fd_read`
2450
2451This feature is internal to the Rust compiler and is not intended for general use.
2452
2453------------------------
2454"##,
2455 },
2456 Lint {
2457 label: "ffi_const",
2458 description: r##"# `ffi_const`
2459
2460The tracking issue for this feature is: [#58328]
2461
2462------
2463
2464The `#[ffi_const]` attribute applies clang's `const` attribute to foreign
2465functions declarations.
2466
2467That is, `#[ffi_const]` functions shall have no effects except for its return
2468value, which can only depend on the values of the function parameters, and is
2469not affected by changes to the observable state of the program.
2470
2471Applying the `#[ffi_const]` attribute to a function that violates these
2472requirements is undefined behaviour.
2473
2474This attribute enables Rust to perform common optimizations, like sub-expression
2475elimination, and it can avoid emitting some calls in repeated invocations of the
2476function with the same argument values regardless of other operations being
2477performed in between these functions calls (as opposed to `#[ffi_pure]`
2478functions).
2479
2480## Pitfalls
2481
2482A `#[ffi_const]` function can only read global memory that would not affect
2483its return value for the whole execution of the program (e.g. immutable global
2484memory). `#[ffi_const]` functions are referentially-transparent and therefore
2485more strict than `#[ffi_pure]` functions.
2486
2487A common pitfall involves applying the `#[ffi_const]` attribute to a
2488function that reads memory through pointer arguments which do not necessarily
2489point to immutable global memory.
2490
2491A `#[ffi_const]` function that returns unit has no effect on the abstract
2492machine's state, and a `#[ffi_const]` function cannot be `#[ffi_pure]`.
2493
2494A `#[ffi_const]` function must not diverge, neither via a side effect (e.g. a
2495call to `abort`) nor by infinite loops.
2496
2497When translating C headers to Rust FFI, it is worth verifying for which targets
2498the `const` attribute is enabled in those headers, and using the appropriate
2499`cfg` macros in the Rust side to match those definitions. While the semantics of
2500`const` are implemented identically by many C and C++ compilers, e.g., clang,
2501[GCC], [ARM C/C++ compiler], [IBM ILE C/C++], etc. they are not necessarily
2502implemented in this way on all of them. It is therefore also worth verifying
2503that the semantics of the C toolchain used to compile the binary being linked
2504against are compatible with those of the `#[ffi_const]`.
2505
2506[#58328]: https://github.com/rust-lang/rust/issues/58328
2507[ARM C/C++ compiler]: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0491c/Cacgigch.html
2508[GCC]: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-const-function-attribute
2509[IBM ILE C/C++]: https://www.ibm.com/support/knowledgecenter/fr/ssw_ibm_i_71/rzarg/fn_attrib_const.htm
2510"##,
2511 },
2512 Lint {
2513 label: "ffi_pure",
2514 description: r##"# `ffi_pure`
2515
2516The tracking issue for this feature is: [#58329]
2517
2518------
2519
2520The `#[ffi_pure]` attribute applies clang's `pure` attribute to foreign
2521functions declarations.
2522
2523That is, `#[ffi_pure]` functions shall have no effects except for its return
2524value, which shall not change across two consecutive function calls with
2525the same parameters.
2526
2527Applying the `#[ffi_pure]` attribute to a function that violates these
2528requirements is undefined behavior.
2529
2530This attribute enables Rust to perform common optimizations, like sub-expression
2531elimination and loop optimizations. Some common examples of pure functions are
2532`strlen` or `memcmp`.
2533
2534These optimizations are only applicable when the compiler can prove that no
2535program state observable by the `#[ffi_pure]` function has changed between calls
2536of the function, which could alter the result. See also the `#[ffi_const]`
2537attribute, which provides stronger guarantees regarding the allowable behavior
2538of a function, enabling further optimization.
2539
2540## Pitfalls
2541
2542A `#[ffi_pure]` function can read global memory through the function
2543parameters (e.g. pointers), globals, etc. `#[ffi_pure]` functions are not
2544referentially-transparent, and are therefore more relaxed than `#[ffi_const]`
2545functions.
2546
2547However, accessing global memory through volatile or atomic reads can violate the
2548requirement that two consecutive function calls shall return the same value.
2549
2550A `pure` function that returns unit has no effect on the abstract machine's
2551state.
2552
2553A `#[ffi_pure]` function must not diverge, neither via a side effect (e.g. a
2554call to `abort`) nor by infinite loops.
2555
2556When translating C headers to Rust FFI, it is worth verifying for which targets
2557the `pure` attribute is enabled in those headers, and using the appropriate
2558`cfg` macros in the Rust side to match those definitions. While the semantics of
2559`pure` are implemented identically by many C and C++ compilers, e.g., clang,
2560[GCC], [ARM C/C++ compiler], [IBM ILE C/C++], etc. they are not necessarily
2561implemented in this way on all of them. It is therefore also worth verifying
2562that the semantics of the C toolchain used to compile the binary being linked
2563against are compatible with those of the `#[ffi_pure]`.
2564
2565
2566[#58329]: https://github.com/rust-lang/rust/issues/58329
2567[ARM C/C++ compiler]: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0491c/Cacigdac.html
2568[GCC]: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-pure-function-attribute
2569[IBM ILE C/C++]: https://www.ibm.com/support/knowledgecenter/fr/ssw_ibm_i_71/rzarg/fn_attrib_pure.htm
2570"##,
2571 },
2572 Lint {
2573 label: "flt2dec",
2574 description: r##"# `flt2dec`
2575
2576This feature is internal to the Rust compiler and is not intended for general use.
2577
2578------------------------
2579"##,
2580 },
2581 Lint {
2582 label: "fmt_internals",
2583 description: r##"# `fmt_internals`
2584
2585This feature is internal to the Rust compiler and is not intended for general use.
2586
2587------------------------
2588"##,
2589 },
2590 Lint {
2591 label: "fn_traits",
2592 description: r##"# `fn_traits`
2593
2594The tracking issue for this feature is [#29625]
2595
2596See Also: [`unboxed_closures`](../language-features/unboxed-closures.md)
2597
2598[#29625]: https://github.com/rust-lang/rust/issues/29625
2599
2600----
2601
2602The `fn_traits` feature allows for implementation of the [`Fn*`] traits
2603for creating custom closure-like types.
2604
2605[`Fn*`]: https://doc.rust-lang.org/std/ops/trait.Fn.html
2606
2607```rust
2608#![feature(unboxed_closures)]
2609#![feature(fn_traits)]
2610
2611struct Adder {
2612 a: u32
2613}
2614
2615impl FnOnce<(u32, )> for Adder {
2616 type Output = u32;
2617 extern "rust-call" fn call_once(self, b: (u32, )) -> Self::Output {
2618 self.a + b.0
2619 }
2620}
2621
2622fn main() {
2623 let adder = Adder { a: 3 };
2624 assert_eq!(adder(2), 5);
2625}
2626```
2627"##,
2628 },
2629 Lint {
2630 label: "format_args_capture",
2631 description: r##"# `format_args_capture`
2632
2633The tracking issue for this feature is: [#67984]
2634
2635[#67984]: https://github.com/rust-lang/rust/issues/67984
2636
2637------------------------
2638
2639Enables `format_args!` (and macros which use `format_args!` in their implementation, such
2640as `format!`, `print!` and `panic!`) to capture variables from the surrounding scope.
2641This avoids the need to pass named parameters when the binding in question
2642already exists in scope.
2643
2644```rust
2645#![feature(format_args_capture)]
2646
2647let (person, species, name) = ("Charlie Brown", "dog", "Snoopy");
2648
2649// captures named argument `person`
2650print!("Hello {person}");
2651
2652// captures named arguments `species` and `name`
2653format!("The {species}'s name is {name}.");
2654```
2655
2656This also works for formatting parameters such as width and precision:
2657
2658```rust
2659#![feature(format_args_capture)]
2660
2661let precision = 2;
2662let s = format!("{:.precision$}", 1.324223);
2663
2664assert_eq!(&s, "1.32");
2665```
2666
2667A non-exhaustive list of macros which benefit from this functionality include:
2668- `format!`
2669- `print!` and `println!`
2670- `eprint!` and `eprintln!`
2671- `write!` and `writeln!`
2672- `panic!`
2673- `unreachable!`
2674- `unimplemented!`
2675- `todo!`
2676- `assert!` and similar
2677- macros in many thirdparty crates, such as `log`
2678"##,
2679 },
2680 Lint {
2681 label: "generators",
2682 description: r##"# `generators`
2683
2684The tracking issue for this feature is: [#43122]
2685
2686[#43122]: https://github.com/rust-lang/rust/issues/43122
2687
2688------------------------
2689
2690The `generators` feature gate in Rust allows you to define generator or
2691coroutine literals. A generator is a "resumable function" that syntactically
2692resembles a closure but compiles to much different semantics in the compiler
2693itself. The primary feature of a generator is that it can be suspended during
2694execution to be resumed at a later date. Generators use the `yield` keyword to
2695"return", and then the caller can `resume` a generator to resume execution just
2696after the `yield` keyword.
2697
2698Generators are an extra-unstable feature in the compiler right now. Added in
2699[RFC 2033] they're mostly intended right now as a information/constraint
2700gathering phase. The intent is that experimentation can happen on the nightly
2701compiler before actual stabilization. A further RFC will be required to
2702stabilize generators/coroutines and will likely contain at least a few small
2703tweaks to the overall design.
2704
2705[RFC 2033]: https://github.com/rust-lang/rfcs/pull/2033
2706
2707A syntactical example of a generator is:
2708
2709```rust
2710#![feature(generators, generator_trait)]
2711
2712use std::ops::{Generator, GeneratorState};
2713use std::pin::Pin;
2714
2715fn main() {
2716 let mut generator = || {
2717 yield 1;
2718 return "foo"
2719 };
2720
2721 match Pin::new(&mut generator).resume(()) {
2722 GeneratorState::Yielded(1) => {}
2723 _ => panic!("unexpected value from resume"),
2724 }
2725 match Pin::new(&mut generator).resume(()) {
2726 GeneratorState::Complete("foo") => {}
2727 _ => panic!("unexpected value from resume"),
2728 }
2729}
2730```
2731
2732Generators are closure-like literals which can contain a `yield` statement. The
2733`yield` statement takes an optional expression of a value to yield out of the
2734generator. All generator literals implement the `Generator` trait in the
2735`std::ops` module. The `Generator` trait has one main method, `resume`, which
2736resumes execution of the generator at the previous suspension point.
2737
2738An example of the control flow of generators is that the following example
2739prints all numbers in order:
2740
2741```rust
2742#![feature(generators, generator_trait)]
2743
2744use std::ops::Generator;
2745use std::pin::Pin;
2746
2747fn main() {
2748 let mut generator = || {
2749 println!("2");
2750 yield;
2751 println!("4");
2752 };
2753
2754 println!("1");
2755 Pin::new(&mut generator).resume(());
2756 println!("3");
2757 Pin::new(&mut generator).resume(());
2758 println!("5");
2759}
2760```
2761
2762At this time the main intended use case of generators is an implementation
2763primitive for async/await syntax, but generators will likely be extended to
2764ergonomic implementations of iterators and other primitives in the future.
2765Feedback on the design and usage is always appreciated!
2766
2767### The `Generator` trait
2768
2769The `Generator` trait in `std::ops` currently looks like:
2770
2771```rust
2772# #![feature(arbitrary_self_types, generator_trait)]
2773# use std::ops::GeneratorState;
2774# use std::pin::Pin;
2775
2776pub trait Generator<R = ()> {
2777 type Yield;
2778 type Return;
2779 fn resume(self: Pin<&mut Self>, resume: R) -> GeneratorState<Self::Yield, Self::Return>;
2780}
2781```
2782
2783The `Generator::Yield` type is the type of values that can be yielded with the
2784`yield` statement. The `Generator::Return` type is the returned type of the
2785generator. This is typically the last expression in a generator's definition or
2786any value passed to `return` in a generator. The `resume` function is the entry
2787point for executing the `Generator` itself.
2788
2789The return value of `resume`, `GeneratorState`, looks like:
2790
2791```rust
2792pub enum GeneratorState<Y, R> {
2793 Yielded(Y),
2794 Complete(R),
2795}
2796```
2797
2798The `Yielded` variant indicates that the generator can later be resumed. This
2799corresponds to a `yield` point in a generator. The `Complete` variant indicates
2800that the generator is complete and cannot be resumed again. Calling `resume`
2801after a generator has returned `Complete` will likely result in a panic of the
2802program.
2803
2804### Closure-like semantics
2805
2806The closure-like syntax for generators alludes to the fact that they also have
2807closure-like semantics. Namely:
2808
2809* When created, a generator executes no code. A closure literal does not
2810 actually execute any of the closure's code on construction, and similarly a
2811 generator literal does not execute any code inside the generator when
2812 constructed.
2813
2814* Generators can capture outer variables by reference or by move, and this can
2815 be tweaked with the `move` keyword at the beginning of the closure. Like
2816 closures all generators will have an implicit environment which is inferred by
2817 the compiler. Outer variables can be moved into a generator for use as the
2818 generator progresses.
2819
2820* Generator literals produce a value with a unique type which implements the
2821 `std::ops::Generator` trait. This allows actual execution of the generator
2822 through the `Generator::resume` method as well as also naming it in return
2823 types and such.
2824
2825* Traits like `Send` and `Sync` are automatically implemented for a `Generator`
2826 depending on the captured variables of the environment. Unlike closures,
2827 generators also depend on variables live across suspension points. This means
2828 that although the ambient environment may be `Send` or `Sync`, the generator
2829 itself may not be due to internal variables live across `yield` points being
2830 not-`Send` or not-`Sync`. Note that generators do
2831 not implement traits like `Copy` or `Clone` automatically.
2832
2833* Whenever a generator is dropped it will drop all captured environment
2834 variables.
2835
2836### Generators as state machines
2837
2838In the compiler, generators are currently compiled as state machines. Each
2839`yield` expression will correspond to a different state that stores all live
2840variables over that suspension point. Resumption of a generator will dispatch on
2841the current state and then execute internally until a `yield` is reached, at
2842which point all state is saved off in the generator and a value is returned.
2843
2844Let's take a look at an example to see what's going on here:
2845
2846```rust
2847#![feature(generators, generator_trait)]
2848
2849use std::ops::Generator;
2850use std::pin::Pin;
2851
2852fn main() {
2853 let ret = "foo";
2854 let mut generator = move || {
2855 yield 1;
2856 return ret
2857 };
2858
2859 Pin::new(&mut generator).resume(());
2860 Pin::new(&mut generator).resume(());
2861}
2862```
2863
2864This generator literal will compile down to something similar to:
2865
2866```rust
2867#![feature(arbitrary_self_types, generators, generator_trait)]
2868
2869use std::ops::{Generator, GeneratorState};
2870use std::pin::Pin;
2871
2872fn main() {
2873 let ret = "foo";
2874 let mut generator = {
2875 enum __Generator {
2876 Start(&'static str),
2877 Yield1(&'static str),
2878 Done,
2879 }
2880
2881 impl Generator for __Generator {
2882 type Yield = i32;
2883 type Return = &'static str;
2884
2885 fn resume(mut self: Pin<&mut Self>, resume: ()) -> GeneratorState<i32, &'static str> {
2886 use std::mem;
2887 match mem::replace(&mut *self, __Generator::Done) {
2888 __Generator::Start(s) => {
2889 *self = __Generator::Yield1(s);
2890 GeneratorState::Yielded(1)
2891 }
2892
2893 __Generator::Yield1(s) => {
2894 *self = __Generator::Done;
2895 GeneratorState::Complete(s)
2896 }
2897
2898 __Generator::Done => {
2899 panic!("generator resumed after completion")
2900 }
2901 }
2902 }
2903 }
2904
2905 __Generator::Start(ret)
2906 };
2907
2908 Pin::new(&mut generator).resume(());
2909 Pin::new(&mut generator).resume(());
2910}
2911```
2912
2913Notably here we can see that the compiler is generating a fresh type,
2914`__Generator` in this case. This type has a number of states (represented here
2915as an `enum`) corresponding to each of the conceptual states of the generator.
2916At the beginning we're closing over our outer variable `foo` and then that
2917variable is also live over the `yield` point, so it's stored in both states.
2918
2919When the generator starts it'll immediately yield 1, but it saves off its state
2920just before it does so indicating that it has reached the yield point. Upon
2921resuming again we'll execute the `return ret` which returns the `Complete`
2922state.
2923
2924Here we can also note that the `Done` state, if resumed, panics immediately as
2925it's invalid to resume a completed generator. It's also worth noting that this
2926is just a rough desugaring, not a normative specification for what the compiler
2927does.
2928"##,
2929 },
2930 Lint {
2931 label: "global_asm",
2932 description: r##"# `global_asm`
2933
2934The tracking issue for this feature is: [#35119]
2935
2936[#35119]: https://github.com/rust-lang/rust/issues/35119
2937
2938------------------------
2939
2940The `global_asm!` macro allows the programmer to write arbitrary
2941assembly outside the scope of a function body, passing it through
2942`rustc` and `llvm` to the assembler. That is to say, `global_asm!` is
2943equivalent to assembling the asm with an external assembler and then
2944linking the resulting object file with the current crate.
2945
2946`global_asm!` fills a role not currently satisfied by either `asm!`
2947or `#[naked]` functions. The programmer has _all_ features of the
2948assembler at their disposal. The linker will expect to resolve any
2949symbols defined in the inline assembly, modulo any symbols marked as
2950external. It also means syntax for directives and assembly follow the
2951conventions of the assembler in your toolchain.
2952
2953A simple usage looks like this:
2954
2955```rust,ignore (requires-external-file)
2956#![feature(global_asm)]
2957# // you also need relevant target_arch cfgs
2958global_asm!(include_str!("something_neato.s"));
2959```
2960
2961And a more complicated usage looks like this:
2962
2963```rust,no_run
2964#![feature(global_asm)]
2965# #[cfg(any(target_arch="x86", target_arch="x86_64"))]
2966# mod x86 {
2967
2968pub mod sally {
2969 global_asm!(
2970 ".global foo",
2971 "foo:",
2972 "jmp baz",
2973 );
2974
2975 #[no_mangle]
2976 pub unsafe extern "C" fn baz() {}
2977}
2978
2979// the symbols `foo` and `bar` are global, no matter where
2980// `global_asm!` was used.
2981extern "C" {
2982 fn foo();
2983 fn bar();
2984}
2985
2986pub mod harry {
2987 global_asm!(
2988 ".global bar",
2989 "bar:",
2990 "jmp quux",
2991 );
2992
2993 #[no_mangle]
2994 pub unsafe extern "C" fn quux() {}
2995}
2996# }
2997```
2998
2999You may use `global_asm!` multiple times, anywhere in your crate, in
3000whatever way suits you. However, you should not rely on assembler state
3001(e.g. assembler macros) defined in one `global_asm!` to be available in
3002another one. It is implementation-defined whether the multiple usages
3003are concatenated into one or assembled separately.
3004
3005`global_asm!` also supports `const` operands like `asm!`, which allows
3006constants defined in Rust to be used in assembly code:
3007
3008```rust,no_run
3009#![feature(global_asm)]
3010# #[cfg(any(target_arch="x86", target_arch="x86_64"))]
3011# mod x86 {
3012const C: i32 = 1234;
3013global_asm!(
3014 ".global bar",
3015 "bar: .word {c}",
3016 c = const C,
3017);
3018# }
3019```
3020
3021The syntax for passing operands is the same as `asm!` except that only
3022`const` operands are allowed. Refer to the [asm](asm.md) documentation
3023for more details.
3024
3025On x86, the assembly code will use intel syntax by default. You can
3026override this by adding `options(att_syntax)` at the end of the macro
3027arguments list:
3028
3029```rust,no_run
3030#![feature(global_asm)]
3031# #[cfg(any(target_arch="x86", target_arch="x86_64"))]
3032# mod x86 {
3033global_asm!("movl ${}, %ecx", const 5, options(att_syntax));
3034// is equivalent to
3035global_asm!("mov ecx, {}", const 5);
3036# }
3037```
3038
3039------------------------
3040
3041If you don't need quite as much power and flexibility as
3042`global_asm!` provides, and you don't mind restricting your inline
3043assembly to `fn` bodies only, you might try the
3044[asm](asm.md) feature instead.
3045"##,
3046 },
3047 Lint {
3048 label: "impl_trait_in_bindings",
3049 description: r##"# `impl_trait_in_bindings`
3050
3051The tracking issue for this feature is: [#63065]
3052
3053[#63065]: https://github.com/rust-lang/rust/issues/63065
3054
3055------------------------
3056
3057The `impl_trait_in_bindings` feature gate lets you use `impl Trait` syntax in
3058`let`, `static`, and `const` bindings.
3059
3060A simple example is:
3061
3062```rust
3063#![feature(impl_trait_in_bindings)]
3064
3065use std::fmt::Debug;
3066
3067fn main() {
3068 let a: impl Debug + Clone = 42;
3069 let b = a.clone();
3070 println!("{:?}", b); // prints `42`
3071}
3072```
3073
3074Note however that because the types of `a` and `b` are opaque in the above
3075example, calling inherent methods or methods outside of the specified traits
3076(e.g., `a.abs()` or `b.abs()`) is not allowed, and yields an error.
3077"##,
3078 },
3079 Lint {
3080 label: "infer_static_outlives_requirements",
3081 description: r##"# `infer_static_outlives_requirements`
3082
3083The tracking issue for this feature is: [#54185]
3084
3085[#54185]: https://github.com/rust-lang/rust/issues/54185
3086
3087------------------------
3088The `infer_static_outlives_requirements` feature indicates that certain
3089`'static` outlives requirements can be inferred by the compiler rather than
3090stating them explicitly.
3091
3092Note: It is an accompanying feature to `infer_outlives_requirements`,
3093which must be enabled to infer outlives requirements.
3094
3095For example, currently generic struct definitions that contain
3096references, require where-clauses of the form T: 'static. By using
3097this feature the outlives predicates will be inferred, although
3098they may still be written explicitly.
3099
3100```rust,ignore (pseudo-Rust)
3101struct Foo<U> where U: 'static { // <-- currently required
3102 bar: Bar<U>
3103}
3104struct Bar<T: 'static> {
3105 x: T,
3106}
3107```
3108
3109
3110## Examples:
3111
3112```rust,ignore (pseudo-Rust)
3113#![feature(infer_outlives_requirements)]
3114#![feature(infer_static_outlives_requirements)]
3115
3116#[rustc_outlives]
3117// Implicitly infer U: 'static
3118struct Foo<U> {
3119 bar: Bar<U>
3120}
3121struct Bar<T: 'static> {
3122 x: T,
3123}
3124```
3125"##,
3126 },
3127 Lint {
3128 label: "inline_const",
3129 description: r##"# `inline_const`
3130
3131The tracking issue for this feature is: [#76001]
3132
3133------
3134
3135This feature allows you to use inline constant expressions. For example, you can
3136turn this code:
3137
3138```rust
3139# fn add_one(x: i32) -> i32 { x + 1 }
3140const MY_COMPUTATION: i32 = 1 + 2 * 3 / 4;
3141
3142fn main() {
3143 let x = add_one(MY_COMPUTATION);
3144}
3145```
3146
3147into this code:
3148
3149```rust
3150#![feature(inline_const)]
3151
3152# fn add_one(x: i32) -> i32 { x + 1 }
3153fn main() {
3154 let x = add_one(const { 1 + 2 * 3 / 4 });
3155}
3156```
3157
3158You can also use inline constant expressions in patterns:
3159
3160```rust
3161#![feature(inline_const)]
3162
3163const fn one() -> i32 { 1 }
3164
3165let some_int = 3;
3166match some_int {
3167 const { 1 + 2 } => println!("Matched 1 + 2"),
3168 const { one() } => println!("Matched const fn returning 1"),
3169 _ => println!("Didn't match anything :("),
3170}
3171```
3172
3173[#76001]: https://github.com/rust-lang/rust/issues/76001
3174"##,
3175 },
3176 Lint {
3177 label: "int_error_internals",
3178 description: r##"# `int_error_internals`
3179
3180This feature is internal to the Rust compiler and is not intended for general use.
3181
3182------------------------
3183"##,
3184 },
3185 Lint {
3186 label: "internal_output_capture",
3187 description: r##"# `internal_output_capture`
3188
3189This feature is internal to the Rust compiler and is not intended for general use.
3190
3191------------------------
3192"##,
3193 },
3194 Lint {
3195 label: "intra_doc_pointers",
3196 description: r##"# `intra-doc-pointers`
3197
3198The tracking issue for this feature is: [#80896]
3199
3200[#80896]: https://github.com/rust-lang/rust/issues/80896
3201
3202------------------------
3203
3204Rustdoc does not currently allow disambiguating between `*const` and `*mut`, and
3205raw pointers in intra-doc links are unstable until it does.
3206
3207```rust
3208#![feature(intra_doc_pointers)]
3209//! [pointer::add]
3210```
3211"##,
3212 },
3213 Lint {
3214 label: "intrinsics",
3215 description: r##"# `intrinsics`
3216
3217The tracking issue for this feature is: None.
3218
3219Intrinsics are never intended to be stable directly, but intrinsics are often
3220exported in some sort of stable manner. Prefer using the stable interfaces to
3221the intrinsic directly when you can.
3222
3223------------------------
3224
3225
3226These are imported as if they were FFI functions, with the special
3227`rust-intrinsic` ABI. For example, if one was in a freestanding
3228context, but wished to be able to `transmute` between types, and
3229perform efficient pointer arithmetic, one would import those functions
3230via a declaration like
3231
3232```rust
3233#![feature(intrinsics)]
3234# fn main() {}
3235
3236extern "rust-intrinsic" {
3237 fn transmute<T, U>(x: T) -> U;
3238
3239 fn offset<T>(dst: *const T, offset: isize) -> *const T;
3240}
3241```
3242
3243As with any other FFI functions, these are always `unsafe` to call.
3244"##,
3245 },
3246 Lint {
3247 label: "is_sorted",
3248 description: r##"# `is_sorted`
3249
3250The tracking issue for this feature is: [#53485]
3251
3252[#53485]: https://github.com/rust-lang/rust/issues/53485
3253
3254------------------------
3255
3256Add the methods `is_sorted`, `is_sorted_by` and `is_sorted_by_key` to `[T]`;
3257add the methods `is_sorted`, `is_sorted_by` and `is_sorted_by_key` to
3258`Iterator`.
3259"##,
3260 },
3261 Lint {
3262 label: "lang_items",
3263 description: r##"# `lang_items`
3264
3265The tracking issue for this feature is: None.
3266
3267------------------------
3268
3269The `rustc` compiler has certain pluggable operations, that is,
3270functionality that isn't hard-coded into the language, but is
3271implemented in libraries, with a special marker to tell the compiler
3272it exists. The marker is the attribute `#[lang = "..."]` and there are
3273various different values of `...`, i.e. various different 'lang
3274items'.
3275
3276For example, `Box` pointers require two lang items, one for allocation
3277and one for deallocation. A freestanding program that uses the `Box`
3278sugar for dynamic allocations via `malloc` and `free`:
3279
3280```rust,ignore (libc-is-finicky)
3281#![feature(lang_items, box_syntax, start, libc, core_intrinsics, rustc_private)]
3282#![no_std]
3283use core::intrinsics;
3284use core::panic::PanicInfo;
3285
3286extern crate libc;
3287
3288#[lang = "owned_box"]
3289pub struct Box<T>(*mut T);
3290
3291#[lang = "exchange_malloc"]
3292unsafe fn allocate(size: usize, _align: usize) -> *mut u8 {
3293 let p = libc::malloc(size as libc::size_t) as *mut u8;
3294
3295 // Check if `malloc` failed:
3296 if p as usize == 0 {
3297 intrinsics::abort();
3298 }
3299
3300 p
3301}
3302
3303#[lang = "box_free"]
3304unsafe fn box_free<T: ?Sized>(ptr: *mut T) {
3305 libc::free(ptr as *mut libc::c_void)
3306}
3307
3308#[start]
3309fn main(_argc: isize, _argv: *const *const u8) -> isize {
3310 let _x = box 1;
3311
3312 0
3313}
3314
3315#[lang = "eh_personality"] extern fn rust_eh_personality() {}
3316#[lang = "panic_impl"] extern fn rust_begin_panic(info: &PanicInfo) -> ! { unsafe { intrinsics::abort() } }
3317#[no_mangle] pub extern fn rust_eh_register_frames () {}
3318#[no_mangle] pub extern fn rust_eh_unregister_frames () {}
3319```
3320
3321Note the use of `abort`: the `exchange_malloc` lang item is assumed to
3322return a valid pointer, and so needs to do the check internally.
3323
3324Other features provided by lang items include:
3325
3326- overloadable operators via traits: the traits corresponding to the
3327 `==`, `<`, dereferencing (`*`) and `+` (etc.) operators are all
3328 marked with lang items; those specific four are `eq`, `ord`,
3329 `deref`, and `add` respectively.
3330- stack unwinding and general failure; the `eh_personality`,
3331 `panic` and `panic_bounds_check` lang items.
3332- the traits in `std::marker` used to indicate types of
3333 various kinds; lang items `send`, `sync` and `copy`.
3334- the marker types and variance indicators found in
3335 `std::marker`; lang items `covariant_type`,
3336 `contravariant_lifetime`, etc.
3337
3338Lang items are loaded lazily by the compiler; e.g. if one never uses
3339`Box` then there is no need to define functions for `exchange_malloc`
3340and `box_free`. `rustc` will emit an error when an item is needed
3341but not found in the current crate or any that it depends on.
3342
3343