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