aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_completion/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide_completion/src')
-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 each have an internal name, and then a
2997signature that an implementation must conform to.
2998
2999The first of these functions, `rust_eh_personality`, is used by the failure
3000mechanisms of the compiler. This is often mapped to GCC's personality function
3001(see the [libstd implementation][unwind] for more information), but crates
3002which do not trigger a panic can be assured that this function is never
3003called. The language item's name is `eh_personality`.
3004
3005[unwind]: https://github.com/rust-lang/rust/blob/master/library/panic_unwind/src/gcc.rs
3006
3007The second function, `rust_begin_panic`, is also used by the failure mechanisms of the
3008compiler. When a panic happens, this controls the message that's displayed on
3009the screen. While the language item's name is `panic_impl`, the symbol name is
3010`rust_begin_panic`.
3011
3012Finally, a `eh_catch_typeinfo` static is needed for certain targets which
3013implement Rust panics on top of C++ exceptions.
3014
3015## List of all language items
3016
3017This is a list of all language items in Rust along with where they are located in
3018the source code.
3019
3020- Primitives
3021 - `i8`: `libcore/num/mod.rs`
3022 - `i16`: `libcore/num/mod.rs`
3023 - `i32`: `libcore/num/mod.rs`
3024 - `i64`: `libcore/num/mod.rs`
3025 - `i128`: `libcore/num/mod.rs`
3026 - `isize`: `libcore/num/mod.rs`
3027 - `u8`: `libcore/num/mod.rs`
3028 - `u16`: `libcore/num/mod.rs`
3029 - `u32`: `libcore/num/mod.rs`
3030 - `u64`: `libcore/num/mod.rs`
3031 - `u128`: `libcore/num/mod.rs`
3032 - `usize`: `libcore/num/mod.rs`
3033 - `f32`: `libstd/f32.rs`
3034 - `f64`: `libstd/f64.rs`
3035 - `char`: `libcore/char.rs`
3036 - `slice`: `liballoc/slice.rs`
3037 - `str`: `liballoc/str.rs`
3038 - `const_ptr`: `libcore/ptr.rs`
3039 - `mut_ptr`: `libcore/ptr.rs`
3040 - `unsafe_cell`: `libcore/cell.rs`
3041- Runtime
3042 - `start`: `libstd/rt.rs`
3043 - `eh_personality`: `libpanic_unwind/emcc.rs` (EMCC)
3044 - `eh_personality`: `libpanic_unwind/gcc.rs` (GNU)
3045 - `eh_personality`: `libpanic_unwind/seh.rs` (SEH)
3046 - `eh_catch_typeinfo`: `libpanic_unwind/emcc.rs` (EMCC)
3047 - `panic`: `libcore/panicking.rs`
3048 - `panic_bounds_check`: `libcore/panicking.rs`
3049 - `panic_impl`: `libcore/panicking.rs`
3050 - `panic_impl`: `libstd/panicking.rs`
3051- Allocations
3052 - `owned_box`: `liballoc/boxed.rs`
3053 - `exchange_malloc`: `liballoc/heap.rs`
3054 - `box_free`: `liballoc/heap.rs`
3055- Operands
3056 - `not`: `libcore/ops/bit.rs`
3057 - `bitand`: `libcore/ops/bit.rs`
3058 - `bitor`: `libcore/ops/bit.rs`
3059 - `bitxor`: `libcore/ops/bit.rs`
3060 - `shl`: `libcore/ops/bit.rs`
3061 - `shr`: `libcore/ops/bit.rs`
3062 - `bitand_assign`: `libcore/ops/bit.rs`
3063 - `bitor_assign`: `libcore/ops/bit.rs`
3064 - `bitxor_assign`: `libcore/ops/bit.rs`
3065 - `shl_assign`: `libcore/ops/bit.rs`
3066 - `shr_assign`: `libcore/ops/bit.rs`
3067 - `deref`: `libcore/ops/deref.rs`
3068 - `deref_mut`: `libcore/ops/deref.rs`
3069 - `index`: `libcore/ops/index.rs`
3070 - `index_mut`: `libcore/ops/index.rs`
3071 - `add`: `libcore/ops/arith.rs`
3072 - `sub`: `libcore/ops/arith.rs`
3073 - `mul`: `libcore/ops/arith.rs`
3074 - `div`: `libcore/ops/arith.rs`
3075 - `rem`: `libcore/ops/arith.rs`
3076 - `neg`: `libcore/ops/arith.rs`
3077 - `add_assign`: `libcore/ops/arith.rs`
3078 - `sub_assign`: `libcore/ops/arith.rs`
3079 - `mul_assign`: `libcore/ops/arith.rs`
3080 - `div_assign`: `libcore/ops/arith.rs`
3081 - `rem_assign`: `libcore/ops/arith.rs`
3082 - `eq`: `libcore/cmp.rs`
3083 - `ord`: `libcore/cmp.rs`
3084- Functions
3085 - `fn`: `libcore/ops/function.rs`
3086 - `fn_mut`: `libcore/ops/function.rs`
3087 - `fn_once`: `libcore/ops/function.rs`
3088 - `generator_state`: `libcore/ops/generator.rs`
3089 - `generator`: `libcore/ops/generator.rs`
3090- Other
3091 - `coerce_unsized`: `libcore/ops/unsize.rs`
3092 - `drop`: `libcore/ops/drop.rs`
3093 - `drop_in_place`: `libcore/ptr.rs`
3094 - `clone`: `libcore/clone.rs`
3095 - `copy`: `libcore/marker.rs`
3096 - `send`: `libcore/marker.rs`
3097 - `sized`: `libcore/marker.rs`
3098 - `unsize`: `libcore/marker.rs`
3099 - `sync`: `libcore/marker.rs`
3100 - `phantom_data`: `libcore/marker.rs`
3101 - `discriminant_kind`: `libcore/marker.rs`
3102 - `freeze`: `libcore/marker.rs`
3103 - `debug_trait`: `libcore/fmt/mod.rs`
3104 - `non_zero`: `libcore/nonzero.rs`
3105 - `arc`: `liballoc/sync.rs`
3106 - `rc`: `liballoc/rc.rs`
3107"##,
3108 },
3109 LintCompletion {
3110 label: "libstd_sys_internals",
3111 description: r##"# `libstd_sys_internals`
3112
3113This feature is internal to the Rust compiler and is not intended for general use.
3114
3115------------------------
3116"##,
3117 },
3118 LintCompletion {
3119 label: "libstd_thread_internals",
3120 description: r##"# `libstd_thread_internals`
3121
3122This feature is internal to the Rust compiler and is not intended for general use.
3123
3124------------------------
3125"##,
3126 },
3127 LintCompletion {
3128 label: "link_cfg",
3129 description: r##"# `link_cfg`
3130
3131This feature is internal to the Rust compiler and is not intended for general use.
3132
3133------------------------
3134"##,
3135 },
3136 LintCompletion {
3137 label: "llvm_asm",
3138 description: r##"# `llvm_asm`
3139
3140The tracking issue for this feature is: [#70173]
3141
3142[#70173]: https://github.com/rust-lang/rust/issues/70173
3143
3144------------------------
3145
3146For extremely low-level manipulations and performance reasons, one
3147might wish to control the CPU directly. Rust supports using inline
3148assembly to do this via the `llvm_asm!` macro.
3149
3150```rust,ignore (pseudo-code)
3151llvm_asm!(assembly template
3152 : output operands
3153 : input operands
3154 : clobbers
3155 : options
3156 );
3157```
3158
3159Any use of `llvm_asm` is feature gated (requires `#![feature(llvm_asm)]` on the
3160crate to allow) and of course requires an `unsafe` block.
3161
3162> **Note**: the examples here are given in x86/x86-64 assembly, but
3163> all platforms are supported.
3164
3165## Assembly template
3166
3167The `assembly template` is the only required parameter and must be a
3168literal string (i.e. `""`)
3169
3170```rust
3171#![feature(llvm_asm)]
3172
3173#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
3174fn foo() {
3175 unsafe {
3176 llvm_asm!("NOP");
3177 }
3178}
3179
3180// Other platforms:
3181#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
3182fn foo() { /* ... */ }
3183
3184fn main() {
3185 // ...
3186 foo();
3187 // ...
3188}
3189```
3190
3191(The `feature(llvm_asm)` and `#[cfg]`s are omitted from now on.)
3192
3193Output operands, input operands, clobbers and options are all optional
3194but you must add the right number of `:` if you skip them:
3195
3196```rust
3197# #![feature(llvm_asm)]
3198# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
3199# fn main() { unsafe {
3200llvm_asm!("xor %eax, %eax"
3201 :
3202 :
3203 : "eax"
3204 );
3205# } }
3206# #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
3207# fn main() {}
3208```
3209
3210Whitespace also doesn't matter:
3211
3212```rust
3213# #![feature(llvm_asm)]
3214# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
3215# fn main() { unsafe {
3216llvm_asm!("xor %eax, %eax" ::: "eax");
3217# } }
3218# #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
3219# fn main() {}
3220```
3221
3222## Operands
3223
3224Input and output operands follow the same format: `:
3225"constraints1"(expr1), "constraints2"(expr2), ..."`. Output operand
3226expressions must be mutable place, or not yet assigned:
3227
3228```rust
3229# #![feature(llvm_asm)]
3230# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
3231fn add(a: i32, b: i32) -> i32 {
3232 let c: i32;
3233 unsafe {
3234 llvm_asm!("add $2, $0"
3235 : "=r"(c)
3236 : "0"(a), "r"(b)
3237 );
3238 }
3239 c
3240}
3241# #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
3242# fn add(a: i32, b: i32) -> i32 { a + b }
3243
3244fn main() {
3245 assert_eq!(add(3, 14159), 14162)
3246}
3247```
3248
3249If you would like to use real operands in this position, however,
3250you are required to put curly braces `{}` around the register that
3251you want, and you are required to put the specific size of the
3252operand. This is useful for very low level programming, where
3253which register you use is important:
3254
3255```rust
3256# #![feature(llvm_asm)]
3257# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
3258# unsafe fn read_byte_in(port: u16) -> u8 {
3259let result: u8;
3260llvm_asm!("in %dx, %al" : "={al}"(result) : "{dx}"(port));
3261result
3262# }
3263```
3264
3265## Clobbers
3266
3267Some instructions modify registers which might otherwise have held
3268different values so we use the clobbers list to indicate to the
3269compiler not to assume any values loaded into those registers will
3270stay valid.
3271
3272```rust
3273# #![feature(llvm_asm)]
3274# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
3275# fn main() { unsafe {
3276// Put the value 0x200 in eax:
3277llvm_asm!("mov $$0x200, %eax" : /* no outputs */ : /* no inputs */ : "eax");
3278# } }
3279# #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
3280# fn main() {}
3281```
3282
3283Input and output registers need not be listed since that information
3284is already communicated by the given constraints. Otherwise, any other
3285registers used either implicitly or explicitly should be listed.
3286
3287If the assembly changes the condition code register `cc` should be
3288specified as one of the clobbers. Similarly, if the assembly modifies
3289memory, `memory` should also be specified.
3290
3291## Options
3292
3293The last section, `options` is specific to Rust. The format is comma
3294separated literal strings (i.e. `:"foo", "bar", "baz"`). It's used to
3295specify some extra info about the inline assembly:
3296
3297Current valid options are:
3298
32991. `volatile` - specifying this is analogous to
3300 `__asm__ __volatile__ (...)` in gcc/clang.
33012. `alignstack` - certain instructions expect the stack to be
3302 aligned a certain way (i.e. SSE) and specifying this indicates to
3303 the compiler to insert its usual stack alignment code
33043. `intel` - use intel syntax instead of the default AT&T.
3305
3306```rust
3307# #![feature(llvm_asm)]
3308# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
3309# fn main() {
3310let result: i32;
3311unsafe {
3312 llvm_asm!("mov eax, 2" : "={eax}"(result) : : : "intel")
3313}
3314println!("eax is currently {}", result);
3315# }
3316# #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
3317# fn main() {}
3318```
3319
3320## More Information
3321
3322The current implementation of the `llvm_asm!` macro is a direct binding to [LLVM's
3323inline assembler expressions][llvm-docs], so be sure to check out [their
3324documentation as well][llvm-docs] for more information about clobbers,
3325constraints, etc.
3326
3327[llvm-docs]: http://llvm.org/docs/LangRef.html#inline-assembler-expressions
3328
3329If you need more power and don't mind losing some of the niceties of
3330`llvm_asm!`, check out [global_asm](global-asm.md).
3331"##,
3332 },
3333 LintCompletion {
3334 label: "marker_trait_attr",
3335 description: r##"# `marker_trait_attr`
3336
3337The tracking issue for this feature is: [#29864]
3338
3339[#29864]: https://github.com/rust-lang/rust/issues/29864
3340
3341------------------------
3342
3343Normally, Rust keeps you from adding trait implementations that could
3344overlap with each other, as it would be ambiguous which to use. This
3345feature, however, carves out an exception to that rule: a trait can
3346opt-in to having overlapping implementations, at the cost that those
3347implementations are not allowed to override anything (and thus the
3348trait itself cannot have any associated items, as they're pointless
3349when they'd need to do the same thing for every type anyway).
3350
3351```rust
3352#![feature(marker_trait_attr)]
3353
3354#[marker] trait CheapToClone: Clone {}
3355
3356impl<T: Copy> CheapToClone for T {}
3357
3358// These could potentially overlap with the blanket implementation above,
3359// so are only allowed because CheapToClone is a marker trait.
3360impl<T: CheapToClone, U: CheapToClone> CheapToClone for (T, U) {}
3361impl<T: CheapToClone> CheapToClone for std::ops::Range<T> {}
3362
3363fn cheap_clone<T: CheapToClone>(t: T) -> T {
3364 t.clone()
3365}
3366```
3367
3368This is expected to replace the unstable `overlapping_marker_traits`
3369feature, which applied to all empty traits (without needing an opt-in).
3370"##,
3371 },
3372 LintCompletion {
3373 label: "native_link_modifiers",
3374 description: r##"# `native_link_modifiers`
3375
3376The tracking issue for this feature is: [#81490]
3377
3378[#81490]: https://github.com/rust-lang/rust/issues/81490
3379
3380------------------------
3381
3382The `native_link_modifiers` feature allows you to use the `modifiers` syntax with the `#[link(..)]` attribute.
3383
3384Modifiers are specified as a comma-delimited string with each modifier prefixed with either a `+` or `-` to indicate that the modifier is enabled or disabled, respectively. The last boolean value specified for a given modifier wins.
3385"##,
3386 },
3387 LintCompletion {
3388 label: "native_link_modifiers_as_needed",
3389 description: r##"# `native_link_modifiers_as_needed`
3390
3391The tracking issue for this feature is: [#81490]
3392
3393[#81490]: https://github.com/rust-lang/rust/issues/81490
3394
3395------------------------
3396
3397The `native_link_modifiers_as_needed` feature allows you to use the `as-needed` modifier.
3398
3399`as-needed` is only compatible with the `dynamic` and `framework` linking kinds. Using any other kind will result in a compiler error.
3400
3401`+as-needed` means that the library will be actually linked only if it satisfies some undefined symbols at the point at which it is specified on the command line, making it similar to static libraries in this regard.
3402
3403This modifier translates to `--as-needed` for ld-like linkers, and to `-dead_strip_dylibs` / `-needed_library` / `-needed_framework` for ld64.
3404The modifier does nothing for linkers that don't support it (e.g. `link.exe`).
3405
3406The default for this modifier is unclear, some targets currently specify it as `+as-needed`, some do not. We may want to try making `+as-needed` a default for all targets.
3407"##,
3408 },
3409 LintCompletion {
3410 label: "native_link_modifiers_bundle",
3411 description: r##"# `native_link_modifiers_bundle`
3412
3413The tracking issue for this feature is: [#81490]
3414
3415[#81490]: https://github.com/rust-lang/rust/issues/81490
3416
3417------------------------
3418
3419The `native_link_modifiers_bundle` feature allows you to use the `bundle` modifier.
3420
3421Only compatible with the `static` linking kind. Using any other kind will result in a compiler error.
3422
3423`+bundle` means objects from the static library are bundled into the produced crate (a rlib, for example) and are used from this crate later during linking of the final binary.
3424
3425`-bundle` means the static library is included into the produced rlib "by name" and object files from it are included only during linking of the final binary, the file search by that name is also performed during final linking.
3426
3427This modifier is supposed to supersede the `static-nobundle` linking kind defined by [RFC 1717](https://github.com/rust-lang/rfcs/pull/1717).
3428
3429The default for this modifier is currently `+bundle`, but it could be changed later on some future edition boundary.
3430"##,
3431 },
3432 LintCompletion {
3433 label: "native_link_modifiers_verbatim",
3434 description: r##"# `native_link_modifiers_verbatim`
3435
3436The tracking issue for this feature is: [#81490]
3437
3438[#81490]: https://github.com/rust-lang/rust/issues/81490
3439
3440------------------------
3441
3442The `native_link_modifiers_verbatim` feature allows you to use the `verbatim` modifier.
3443
3444`+verbatim` means that rustc itself won't add any target-specified library prefixes or suffixes (like `lib` or `.a`) to the library name, and will try its best to ask for the same thing from the linker.
3445
3446For `ld`-like linkers rustc will use the `-l:filename` syntax (note the colon) when passing the library, so the linker won't add any prefixes or suffixes as well.
3447See [`-l namespec`](https://sourceware.org/binutils/docs/ld/Options.html) in ld documentation for more details.
3448For linkers not supporting any verbatim modifiers (e.g. `link.exe` or `ld64`) the library name will be passed as is.
3449
3450The default for this modifier is `-verbatim`.
3451
3452This RFC changes the behavior of `raw-dylib` linking kind specified by [RFC 2627](https://github.com/rust-lang/rfcs/pull/2627). The `.dll` suffix (or other target-specified suffixes for other targets) is now added automatically.
3453If your DLL doesn't have the `.dll` suffix, it can be specified with `+verbatim`.
3454"##,
3455 },
3456 LintCompletion {
3457 label: "native_link_modifiers_whole_archive",
3458 description: r##"# `native_link_modifiers_whole_archive`
3459
3460The tracking issue for this feature is: [#81490]
3461
3462[#81490]: https://github.com/rust-lang/rust/issues/81490
3463
3464------------------------
3465
3466The `native_link_modifiers_whole_archive` feature allows you to use the `whole-archive` modifier.
3467
3468Only compatible with the `static` linking kind. Using any other kind will result in a compiler error.
3469
3470`+whole-archive` means that the static library is linked as a whole archive without throwing any object files away.
3471
3472This modifier translates to `--whole-archive` for `ld`-like linkers, to `/WHOLEARCHIVE` for `link.exe`, and to `-force_load` for `ld64`.
3473The modifier does nothing for linkers that don't support it.
3474
3475The default for this modifier is `-whole-archive`.
3476"##,
3477 },
3478 LintCompletion {
3479 label: "negative_impls",
3480 description: r##"# `negative_impls`
3481
3482The tracking issue for this feature is [#68318].
3483
3484[#68318]: https://github.com/rust-lang/rust/issues/68318
3485
3486----
3487
3488With the feature gate `negative_impls`, you can write negative impls as well as positive ones:
3489
3490```rust
3491#![feature(negative_impls)]
3492trait DerefMut { }
3493impl<T: ?Sized> !DerefMut for &T { }
3494```
3495
3496Negative impls indicate a semver guarantee that the given trait will not be implemented for the given types. Negative impls play an additional purpose for auto traits, described below.
3497
3498Negative impls have the following characteristics:
3499
3500* They do not have any items.
3501* They must obey the orphan rules as if they were a positive impl.
3502* They cannot "overlap" with any positive impls.
3503
3504## Semver interaction
3505
3506It is a breaking change to remove a negative impl. Negative impls are a commitment not to implement the given trait for the named types.
3507
3508## Orphan and overlap rules
3509
3510Negative impls must obey the same orphan rules as a positive impl. This implies you cannot add a negative impl for types defined in upstream crates and so forth.
3511
3512Similarly, negative impls cannot overlap with positive impls, again using the same "overlap" check that we ordinarily use to determine if two impls overlap. (Note that positive impls typically cannot overlap with one another either, except as permitted by specialization.)
3513
3514## Interaction with auto traits
3515
3516Declaring a negative impl `impl !SomeAutoTrait for SomeType` for an
3517auto-trait serves two purposes:
3518
3519* as with any trait, it declares that `SomeType` will never implement `SomeAutoTrait`;
3520* it disables the automatic `SomeType: SomeAutoTrait` impl that would otherwise have been generated.
3521
3522Note that, at present, there is no way to indicate that a given type
3523does not implement an auto trait *but that it may do so in the
3524future*. For ordinary types, this is done by simply not declaring any
3525impl at all, but that is not an option for auto traits. A workaround
3526is that one could embed a marker type as one of the fields, where the
3527marker type is `!AutoTrait`.
3528
3529## Immediate uses
3530
3531Negative impls are used to declare that `&T: !DerefMut` and `&mut T: !Clone`, as required to fix the soundness of `Pin` described in [#66544](https://github.com/rust-lang/rust/issues/66544).
3532
3533This serves two purposes:
3534
3535* For proving the correctness of unsafe code, we can use that impl as evidence that no `DerefMut` or `Clone` impl exists.
3536* It prevents downstream crates from creating such impls.
3537"##,
3538 },
3539 LintCompletion {
3540 label: "no_coverage",
3541 description: r##"# `no_coverage`
3542
3543The tracking issue for this feature is: [#84605]
3544
3545[#84605]: https://github.com/rust-lang/rust/issues/84605
3546
3547---
3548
3549The `no_coverage` attribute can be used to selectively disable coverage
3550instrumentation in an annotated function. This might be useful to:
3551
3552- Avoid instrumentation overhead in a performance critical function
3553- Avoid generating coverage for a function that is not meant to be executed,
3554 but still target 100% coverage for the rest of the program.
3555
3556## Example
3557
3558```rust
3559#![feature(no_coverage)]
3560
3561// `foo()` will get coverage instrumentation (by default)
3562fn foo() {
3563 // ...
3564}
3565
3566#[no_coverage]
3567fn bar() {
3568 // ...
3569}
3570```
3571"##,
3572 },
3573 LintCompletion {
3574 label: "no_sanitize",
3575 description: r##"# `no_sanitize`
3576
3577The tracking issue for this feature is: [#39699]
3578
3579[#39699]: https://github.com/rust-lang/rust/issues/39699
3580
3581------------------------
3582
3583The `no_sanitize` attribute can be used to selectively disable sanitizer
3584instrumentation in an annotated function. This might be useful to: avoid
3585instrumentation overhead in a performance critical function, or avoid
3586instrumenting code that contains constructs unsupported by given sanitizer.
3587
3588The precise effect of this annotation depends on particular sanitizer in use.
3589For example, with `no_sanitize(thread)`, the thread sanitizer will no longer
3590instrument non-atomic store / load operations, but it will instrument atomic
3591operations to avoid reporting false positives and provide meaning full stack
3592traces.
3593
3594## Examples
3595
3596``` rust
3597#![feature(no_sanitize)]
3598
3599#[no_sanitize(address)]
3600fn foo() {
3601 // ...
3602}
3603```
3604"##,
3605 },
3606 LintCompletion {
3607 label: "plugin",
3608 description: r##"# `plugin`
3609
3610The tracking issue for this feature is: [#29597]
3611
3612[#29597]: https://github.com/rust-lang/rust/issues/29597
3613
3614
3615This feature is part of "compiler plugins." It will often be used with the
3616[`plugin_registrar`] and `rustc_private` features.
3617
3618[`plugin_registrar`]: plugin-registrar.md
3619
3620------------------------
3621
3622`rustc` can load compiler plugins, which are user-provided libraries that
3623extend the compiler's behavior with new lint checks, etc.
3624
3625A plugin is a dynamic library crate with a designated *registrar* function that
3626registers extensions with `rustc`. Other crates can load these extensions using
3627the crate attribute `#![plugin(...)]`. See the
3628`rustc_driver::plugin` documentation for more about the
3629mechanics of defining and loading a plugin.
3630
3631In the vast majority of cases, a plugin should *only* be used through
3632`#![plugin]` and not through an `extern crate` item. Linking a plugin would
3633pull in all of librustc_ast and librustc as dependencies of your crate. This is
3634generally unwanted unless you are building another plugin.
3635
3636The usual practice is to put compiler plugins in their own crate, separate from
3637any `macro_rules!` macros or ordinary Rust code meant to be used by consumers
3638of a library.
3639
3640# Lint plugins
3641
3642Plugins can extend [Rust's lint
3643infrastructure](../../reference/attributes/diagnostics.md#lint-check-attributes) with
3644additional checks for code style, safety, etc. Now let's write a plugin
3645[`lint-plugin-test.rs`](https://github.com/rust-lang/rust/blob/master/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs)
3646that warns about any item named `lintme`.
3647
3648```rust,ignore (requires-stage-2)
3649#![feature(plugin_registrar)]
3650#![feature(box_syntax, rustc_private)]
3651
3652extern crate rustc_ast;
3653
3654// Load rustc as a plugin to get macros
3655extern crate rustc_driver;
3656#[macro_use]
3657extern crate rustc_lint;
3658#[macro_use]
3659extern crate rustc_session;
3660
3661use rustc_driver::plugin::Registry;
3662use rustc_lint::{EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass};
3663use rustc_ast::ast;
3664declare_lint!(TEST_LINT, Warn, "Warn about items named 'lintme'");
3665
3666declare_lint_pass!(Pass => [TEST_LINT]);
3667
3668impl EarlyLintPass for Pass {
3669 fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) {
3670 if it.ident.name.as_str() == "lintme" {
3671 cx.lint(TEST_LINT, |lint| {
3672 lint.build("item is named 'lintme'").set_span(it.span).emit()
3673 });
3674 }
3675 }
3676}
3677
3678#[plugin_registrar]
3679pub fn plugin_registrar(reg: &mut Registry) {
3680 reg.lint_store.register_lints(&[&TEST_LINT]);
3681 reg.lint_store.register_early_pass(|| box Pass);
3682}
3683```
3684
3685Then code like
3686
3687```rust,ignore (requires-plugin)
3688#![feature(plugin)]
3689#![plugin(lint_plugin_test)]
3690
3691fn lintme() { }
3692```
3693
3694will produce a compiler warning:
3695
3696```txt
3697foo.rs:4:1: 4:16 warning: item is named 'lintme', #[warn(test_lint)] on by default
3698foo.rs:4 fn lintme() { }
3699 ^~~~~~~~~~~~~~~
3700```
3701
3702The components of a lint plugin are:
3703
3704* one or more `declare_lint!` invocations, which define static `Lint` structs;
3705
3706* a struct holding any state needed by the lint pass (here, none);
3707
3708* a `LintPass`
3709 implementation defining how to check each syntax element. A single
3710 `LintPass` may call `span_lint` for several different `Lint`s, but should
3711 register them all through the `get_lints` method.
3712
3713Lint passes are syntax traversals, but they run at a late stage of compilation
3714where type information is available. `rustc`'s [built-in
3715lints](https://github.com/rust-lang/rust/blob/master/src/librustc_session/lint/builtin.rs)
3716mostly use the same infrastructure as lint plugins, and provide examples of how
3717to access type information.
3718
3719Lints defined by plugins are controlled by the usual [attributes and compiler
3720flags](../../reference/attributes/diagnostics.md#lint-check-attributes), e.g.
3721`#[allow(test_lint)]` or `-A test-lint`. These identifiers are derived from the
3722first argument to `declare_lint!`, with appropriate case and punctuation
3723conversion.
3724
3725You can run `rustc -W help foo.rs` to see a list of lints known to `rustc`,
3726including those provided by plugins loaded by `foo.rs`.
3727"##,
3728 },
3729 LintCompletion {
3730 label: "plugin_registrar",
3731 description: r##"# `plugin_registrar`
3732
3733The tracking issue for this feature is: [#29597]
3734
3735[#29597]: https://github.com/rust-lang/rust/issues/29597
3736
3737This feature is part of "compiler plugins." It will often be used with the
3738[`plugin`] and `rustc_private` features as well. For more details, see
3739their docs.
3740
3741[`plugin`]: plugin.md
3742
3743------------------------
3744"##,
3745 },
3746 LintCompletion {
3747 label: "print_internals",
3748 description: r##"# `print_internals`
3749
3750This feature is internal to the Rust compiler and is not intended for general use.
3751
3752------------------------
3753"##,
3754 },
3755 LintCompletion {
3756 label: "profiler_runtime",
3757 description: r##"# `profiler_runtime`
3758
3759The tracking issue for this feature is: [#42524](https://github.com/rust-lang/rust/issues/42524).
3760
3761------------------------
3762"##,
3763 },
3764 LintCompletion {
3765 label: "profiler_runtime_lib",
3766 description: r##"# `profiler_runtime_lib`
3767
3768This feature is internal to the Rust compiler and is not intended for general use.
3769
3770------------------------
3771"##,
3772 },
3773 LintCompletion {
3774 label: "repr128",
3775 description: r##"# `repr128`
3776
3777The tracking issue for this feature is: [#56071]
3778
3779[#56071]: https://github.com/rust-lang/rust/issues/56071
3780
3781------------------------
3782
3783The `repr128` feature adds support for `#[repr(u128)]` on `enum`s.
3784
3785```rust
3786#![feature(repr128)]
3787
3788#[repr(u128)]
3789enum Foo {
3790 Bar(u64),
3791}
3792```
3793"##,
3794 },
3795 LintCompletion {
3796 label: "rt",
3797 description: r##"# `rt`
3798
3799This feature is internal to the Rust compiler and is not intended for general use.
3800
3801------------------------
3802"##,
3803 },
3804 LintCompletion {
3805 label: "rustc_attrs",
3806 description: r##"# `rustc_attrs`
3807
3808This feature has no tracking issue, and is therefore internal to
3809the compiler, not being intended for general use.
3810
3811Note: `rustc_attrs` enables many rustc-internal attributes and this page
3812only discuss a few of them.
3813
3814------------------------
3815
3816The `rustc_attrs` feature allows debugging rustc type layouts by using
3817`#[rustc_layout(...)]` to debug layout at compile time (it even works
3818with `cargo check`) as an alternative to `rustc -Z print-type-sizes`
3819that is way more verbose.
3820
3821Options provided by `#[rustc_layout(...)]` are `debug`, `size`, `align`,
3822`abi`. Note that it only works on sized types without generics.
3823
3824## Examples
3825
3826```rust,compile_fail
3827#![feature(rustc_attrs)]
3828
3829#[rustc_layout(abi, size)]
3830pub enum X {
3831 Y(u8, u8, u8),
3832 Z(isize),
3833}
3834```
3835
3836When that is compiled, the compiler will error with something like
3837
3838```text
3839error: abi: Aggregate { sized: true }
3840 --> src/lib.rs:4:1
3841 |
38424 | / pub enum T {
38435 | | Y(u8, u8, u8),
38446 | | Z(isize),
38457 | | }
3846 | |_^
3847
3848error: size: Size { raw: 16 }
3849 --> src/lib.rs:4:1
3850 |
38514 | / pub enum T {
38525 | | Y(u8, u8, u8),
38536 | | Z(isize),
38547 | | }
3855 | |_^
3856
3857error: aborting due to 2 previous errors
3858```
3859"##,
3860 },
3861 LintCompletion {
3862 label: "sort_internals",
3863 description: r##"# `sort_internals`
3864
3865This feature is internal to the Rust compiler and is not intended for general use.
3866
3867------------------------
3868"##,
3869 },
3870 LintCompletion {
3871 label: "str_internals",
3872 description: r##"# `str_internals`
3873
3874This feature is internal to the Rust compiler and is not intended for general use.
3875
3876------------------------
3877"##,
3878 },
3879 LintCompletion {
3880 label: "test",
3881 description: r##"# `test`
3882
3883The tracking issue for this feature is: None.
3884
3885------------------------
3886
3887The internals of the `test` crate are unstable, behind the `test` flag. The
3888most widely used part of the `test` crate are benchmark tests, which can test
3889the performance of your code. Let's make our `src/lib.rs` look like this
3890(comments elided):
3891
3892```rust,no_run
3893#![feature(test)]
3894
3895extern crate test;
3896
3897pub fn add_two(a: i32) -> i32 {
3898 a + 2
3899}
3900
3901#[cfg(test)]
3902mod tests {
3903 use super::*;
3904 use test::Bencher;
3905
3906 #[test]
3907 fn it_works() {
3908 assert_eq!(4, add_two(2));
3909 }
3910
3911 #[bench]
3912 fn bench_add_two(b: &mut Bencher) {
3913 b.iter(|| add_two(2));
3914 }
3915}
3916```
3917
3918Note the `test` feature gate, which enables this unstable feature.
3919
3920We've imported the `test` crate, which contains our benchmarking support.
3921We have a new function as well, with the `bench` attribute. Unlike regular
3922tests, which take no arguments, benchmark tests take a `&mut Bencher`. This
3923`Bencher` provides an `iter` method, which takes a closure. This closure
3924contains the code we'd like to benchmark.
3925
3926We can run benchmark tests with `cargo bench`:
3927
3928```bash
3929$ cargo bench
3930 Compiling adder v0.0.1 (file:///home/steve/tmp/adder)
3931 Running target/release/adder-91b3e234d4ed382a
3932
3933running 2 tests
3934test tests::it_works ... ignored
3935test tests::bench_add_two ... bench: 1 ns/iter (+/- 0)
3936
3937test result: ok. 0 passed; 0 failed; 1 ignored; 1 measured
3938```
3939
3940Our non-benchmark test was ignored. You may have noticed that `cargo bench`
3941takes a bit longer than `cargo test`. This is because Rust runs our benchmark
3942a number of times, and then takes the average. Because we're doing so little
3943work in this example, we have a `1 ns/iter (+/- 0)`, but this would show
3944the variance if there was one.
3945
3946Advice on writing benchmarks:
3947
3948
3949* Move setup code outside the `iter` loop; only put the part you want to measure inside
3950* Make the code do "the same thing" on each iteration; do not accumulate or change state
3951* Make the outer function idempotent too; the benchmark runner is likely to run
3952 it many times
3953* Make the inner `iter` loop short and fast so benchmark runs are fast and the
3954 calibrator can adjust the run-length at fine resolution
3955* Make the code in the `iter` loop do something simple, to assist in pinpointing
3956 performance improvements (or regressions)
3957
3958## Gotcha: optimizations
3959
3960There's another tricky part to writing benchmarks: benchmarks compiled with
3961optimizations activated can be dramatically changed by the optimizer so that
3962the benchmark is no longer benchmarking what one expects. For example, the
3963compiler might recognize that some calculation has no external effects and
3964remove it entirely.
3965
3966```rust,no_run
3967#![feature(test)]
3968
3969extern crate test;
3970use test::Bencher;
3971
3972#[bench]
3973fn bench_xor_1000_ints(b: &mut Bencher) {
3974 b.iter(|| {
3975 (0..1000).fold(0, |old, new| old ^ new);
3976 });
3977}
3978```
3979
3980gives the following results
3981
3982```text
3983running 1 test
3984test bench_xor_1000_ints ... bench: 0 ns/iter (+/- 0)
3985
3986test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
3987```
3988
3989The benchmarking runner offers two ways to avoid this. Either, the closure that
3990the `iter` method receives can return an arbitrary value which forces the
3991optimizer to consider the result used and ensures it cannot remove the
3992computation entirely. This could be done for the example above by adjusting the
3993`b.iter` call to
3994
3995```rust
3996# struct X;
3997# impl X { fn iter<T, F>(&self, _: F) where F: FnMut() -> T {} } let b = X;
3998b.iter(|| {
3999 // Note lack of `;` (could also use an explicit `return`).
4000 (0..1000).fold(0, |old, new| old ^ new)
4001});
4002```
4003
4004Or, the other option is to call the generic `test::black_box` function, which
4005is an opaque "black box" to the optimizer and so forces it to consider any
4006argument as used.
4007
4008```rust
4009#![feature(test)]
4010
4011extern crate test;
4012
4013# fn main() {
4014# struct X;
4015# impl X { fn iter<T, F>(&self, _: F) where F: FnMut() -> T {} } let b = X;
4016b.iter(|| {
4017 let n = test::black_box(1000);
4018
4019 (0..n).fold(0, |a, b| a ^ b)
4020})
4021# }
4022```
4023
4024Neither of these read or modify the value, and are very cheap for small values.
4025Larger values can be passed indirectly to reduce overhead (e.g.
4026`black_box(&huge_struct)`).
4027
4028Performing either of the above changes gives the following benchmarking results
4029
4030```text
4031running 1 test
4032test bench_xor_1000_ints ... bench: 131 ns/iter (+/- 3)
4033
4034test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
4035```
4036
4037However, the optimizer can still modify a testcase in an undesirable manner
4038even when using either of the above.
4039"##,
4040 },
4041 LintCompletion {
4042 label: "thread_local_internals",
4043 description: r##"# `thread_local_internals`
4044
4045This feature is internal to the Rust compiler and is not intended for general use.
4046
4047------------------------
4048"##,
4049 },
4050 LintCompletion {
4051 label: "trace_macros",
4052 description: r##"# `trace_macros`
4053
4054The tracking issue for this feature is [#29598].
4055
4056[#29598]: https://github.com/rust-lang/rust/issues/29598
4057
4058------------------------
4059
4060With `trace_macros` you can trace the expansion of macros in your code.
4061
4062## Examples
4063
4064```rust
4065#![feature(trace_macros)]
4066
4067fn main() {
4068 trace_macros!(true);
4069 println!("Hello, Rust!");
4070 trace_macros!(false);
4071}
4072```
4073
4074The `cargo build` output:
4075
4076```txt
4077note: trace_macro
4078 --> src/main.rs:5:5
4079 |
40805 | println!("Hello, Rust!");
4081 | ^^^^^^^^^^^^^^^^^^^^^^^^^
4082 |
4083 = note: expanding `println! { "Hello, Rust!" }`
4084 = note: to `print ! ( concat ! ( "Hello, Rust!" , "\n" ) )`
4085 = note: expanding `print! { concat ! ( "Hello, Rust!" , "\n" ) }`
4086 = note: to `$crate :: io :: _print ( format_args ! ( concat ! ( "Hello, Rust!" , "\n" ) )
4087 )`
4088
4089 Finished dev [unoptimized + debuginfo] target(s) in 0.60 secs
4090```
4091"##,
4092 },
4093 LintCompletion {
4094 label: "trait_alias",
4095 description: r##"# `trait_alias`
4096
4097The tracking issue for this feature is: [#41517]
4098
4099[#41517]: https://github.com/rust-lang/rust/issues/41517
4100
4101------------------------
4102
4103The `trait_alias` feature adds support for trait aliases. These allow aliases
4104to be created for one or more traits (currently just a single regular trait plus
4105any number of auto-traits), and used wherever traits would normally be used as
4106either bounds or trait objects.
4107
4108```rust
4109#![feature(trait_alias)]
4110
4111trait Foo = std::fmt::Debug + Send;
4112trait Bar = Foo + Sync;
4113
4114// Use trait alias as bound on type parameter.
4115fn foo<T: Foo>(v: &T) {
4116 println!("{:?}", v);
4117}
4118
4119pub fn main() {
4120 foo(&1);
4121
4122 // Use trait alias for trait objects.
4123 let a: &Bar = &123;
4124 println!("{:?}", a);
4125 let b = Box::new(456) as Box<dyn Foo>;
4126 println!("{:?}", b);
4127}
4128```
4129"##,
4130 },
4131 LintCompletion {
4132 label: "transparent_unions",
4133 description: r##"# `transparent_unions`
4134
4135The tracking issue for this feature is [#60405]
4136
4137[#60405]: https://github.com/rust-lang/rust/issues/60405
4138
4139----
4140
4141The `transparent_unions` feature allows you mark `union`s as
4142`#[repr(transparent)]`. A `union` may be `#[repr(transparent)]` in exactly the
4143same conditions in which a `struct` may be `#[repr(transparent)]` (generally,
4144this means the `union` must have exactly one non-zero-sized field). Some
4145concrete illustrations follow.
4146
4147```rust
4148#![feature(transparent_unions)]
4149
4150// This union has the same representation as `f32`.
4151#[repr(transparent)]
4152union SingleFieldUnion {
4153 field: f32,
4154}
4155
4156// This union has the same representation as `usize`.
4157#[repr(transparent)]
4158union MultiFieldUnion {
4159 field: usize,
4160 nothing: (),
4161}
4162```
4163
4164For consistency with transparent `struct`s, `union`s must have exactly one
4165non-zero-sized field. If all fields are zero-sized, the `union` must not be
4166`#[repr(transparent)]`:
4167
4168```rust
4169#![feature(transparent_unions)]
4170
4171// This (non-transparent) union is already valid in stable Rust:
4172pub union GoodUnion {
4173 pub nothing: (),
4174}
4175
4176// Error: transparent union needs exactly one non-zero-sized field, but has 0
4177// #[repr(transparent)]
4178// pub union BadUnion {
4179// pub nothing: (),
4180// }
4181```
4182
4183The one exception is if the `union` is generic over `T` and has a field of type
4184`T`, it may be `#[repr(transparent)]` even if `T` is a zero-sized type:
4185
4186```rust
4187#![feature(transparent_unions)]
4188
4189// This union has the same representation as `T`.
4190#[repr(transparent)]
4191pub union GenericUnion<T: Copy> { // Unions with non-`Copy` fields are unstable.
4192 pub field: T,
4193 pub nothing: (),
4194}
4195
4196// This is okay even though `()` is a zero-sized type.
4197pub const THIS_IS_OKAY: GenericUnion<()> = GenericUnion { field: () };
4198```
4199
4200Like transarent `struct`s, a transparent `union` of type `U` has the same
4201layout, size, and ABI as its single non-ZST field. If it is generic over a type
4202`T`, and all its fields are ZSTs except for exactly one field of type `T`, then
4203it has the same layout and ABI as `T` (even if `T` is a ZST when monomorphized).
4204
4205Like transparent `struct`s, transparent `union`s are FFI-safe if and only if
4206their underlying representation type is also FFI-safe.
4207
4208A `union` may not be eligible for the same nonnull-style optimizations that a
4209`struct` or `enum` (with the same fields) are eligible for. Adding
4210`#[repr(transparent)]` to `union` does not change this. To give a more concrete
4211example, it is unspecified whether `size_of::<T>()` is equal to
4212`size_of::<Option<T>>()`, where `T` is a `union` (regardless of whether or not
4213it is transparent). The Rust compiler is free to perform this optimization if
4214possible, but is not required to, and different compiler versions may differ in
4215their application of these optimizations.
4216"##,
4217 },
4218 LintCompletion {
4219 label: "try_blocks",
4220 description: r##"# `try_blocks`
4221
4222The tracking issue for this feature is: [#31436]
4223
4224[#31436]: https://github.com/rust-lang/rust/issues/31436
4225
4226------------------------
4227
4228The `try_blocks` feature adds support for `try` blocks. A `try`
4229block creates a new scope one can use the `?` operator in.
4230
4231```rust,edition2018
4232#![feature(try_blocks)]
4233
4234use std::num::ParseIntError;
4235
4236let result: Result<i32, ParseIntError> = try {
4237 "1".parse::<i32>()?
4238 + "2".parse::<i32>()?
4239 + "3".parse::<i32>()?
4240};
4241assert_eq!(result, Ok(6));
4242
4243let result: Result<i32, ParseIntError> = try {
4244 "1".parse::<i32>()?
4245 + "foo".parse::<i32>()?
4246 + "3".parse::<i32>()?
4247};
4248assert!(result.is_err());
4249```
4250"##,
4251 },
4252 LintCompletion {
4253 label: "try_trait",
4254 description: r##"# `try_trait`
4255
4256The tracking issue for this feature is: [#42327]
4257
4258[#42327]: https://github.com/rust-lang/rust/issues/42327
4259
4260------------------------
4261
4262This introduces a new trait `Try` for extending the `?` operator to types
4263other than `Result` (a part of [RFC 1859]). The trait provides the canonical
4264way to _view_ a type in terms of a success/failure dichotomy. This will
4265allow `?` to supplant the `try_opt!` macro on `Option` and the `try_ready!`
4266macro on `Poll`, among other things.
4267
4268[RFC 1859]: https://github.com/rust-lang/rfcs/pull/1859
4269
4270Here's an example implementation of the trait:
4271
4272```rust,ignore (cannot-reimpl-Try)
4273/// A distinct type to represent the `None` value of an `Option`.
4274///
4275/// This enables using the `?` operator on `Option`; it's rarely useful alone.
4276#[derive(Debug)]
4277#[unstable(feature = "try_trait", issue = "42327")]
4278pub struct None { _priv: () }
4279
4280#[unstable(feature = "try_trait", issue = "42327")]
4281impl<T> ops::Try for Option<T> {
4282 type Ok = T;
4283 type Error = None;
4284
4285 fn into_result(self) -> Result<T, None> {
4286 self.ok_or(None { _priv: () })
4287 }
4288
4289 fn from_ok(v: T) -> Self {
4290 Some(v)
4291 }
4292
4293 fn from_error(_: None) -> Self {
4294 None
4295 }
4296}
4297```
4298
4299Note the `Error` associated type here is a new marker. The `?` operator
4300allows interconversion between different `Try` implementers only when
4301the error type can be converted `Into` the error type of the enclosing
4302function (or catch block). Having a distinct error type (as opposed to
4303just `()`, or similar) restricts this to where it's semantically meaningful.
4304"##,
4305 },
4306 LintCompletion {
4307 label: "unboxed_closures",
4308 description: r##"# `unboxed_closures`
4309
4310The tracking issue for this feature is [#29625]
4311
4312See Also: [`fn_traits`](../library-features/fn-traits.md)
4313
4314[#29625]: https://github.com/rust-lang/rust/issues/29625
4315
4316----
4317
4318The `unboxed_closures` feature allows you to write functions using the `"rust-call"` ABI,
4319required for implementing the [`Fn*`] family of traits. `"rust-call"` functions must have
4320exactly one (non self) argument, a tuple representing the argument list.
4321
4322[`Fn*`]: https://doc.rust-lang.org/std/ops/trait.Fn.html
4323
4324```rust
4325#![feature(unboxed_closures)]
4326
4327extern "rust-call" fn add_args(args: (u32, u32)) -> u32 {
4328 args.0 + args.1
4329}
4330
4331fn main() {}
4332```
4333"##,
4334 },
4335 LintCompletion {
4336 label: "unsized_locals",
4337 description: r##"# `unsized_locals`
4338
4339The tracking issue for this feature is: [#48055]
4340
4341[#48055]: https://github.com/rust-lang/rust/issues/48055
4342
4343------------------------
4344
4345This implements [RFC1909]. When turned on, you can have unsized arguments and locals:
4346
4347[RFC1909]: https://github.com/rust-lang/rfcs/blob/master/text/1909-unsized-rvalues.md
4348
4349```rust
4350#![allow(incomplete_features)]
4351#![feature(unsized_locals, unsized_fn_params)]
4352
4353use std::any::Any;
4354
4355fn main() {
4356 let x: Box<dyn Any> = Box::new(42);
4357 let x: dyn Any = *x;
4358 // ^ unsized local variable
4359 // ^^ unsized temporary
4360 foo(x);
4361}
4362
4363fn foo(_: dyn Any) {}
4364// ^^^^^^ unsized argument
4365```
4366
4367The RFC still forbids the following unsized expressions:
4368
4369```rust,compile_fail
4370#![feature(unsized_locals)]
4371
4372use std::any::Any;
4373
4374struct MyStruct<T: ?Sized> {
4375 content: T,
4376}
4377
4378struct MyTupleStruct<T: ?Sized>(T);
4379
4380fn answer() -> Box<dyn Any> {
4381 Box::new(42)
4382}
4383
4384fn main() {
4385 // You CANNOT have unsized statics.
4386 static X: dyn Any = *answer(); // ERROR
4387 const Y: dyn Any = *answer(); // ERROR
4388
4389 // You CANNOT have struct initialized unsized.
4390 MyStruct { content: *answer() }; // ERROR
4391 MyTupleStruct(*answer()); // ERROR
4392 (42, *answer()); // ERROR
4393
4394 // You CANNOT have unsized return types.
4395 fn my_function() -> dyn Any { *answer() } // ERROR
4396
4397 // You CAN have unsized local variables...
4398 let mut x: dyn Any = *answer(); // OK
4399 // ...but you CANNOT reassign to them.
4400 x = *answer(); // ERROR
4401
4402 // You CANNOT even initialize them separately.
4403 let y: dyn Any; // OK
4404 y = *answer(); // ERROR
4405
4406 // Not mentioned in the RFC, but by-move captured variables are also Sized.
4407 let x: dyn Any = *answer();
4408 (move || { // ERROR
4409 let y = x;
4410 })();
4411
4412 // You CAN create a closure with unsized arguments,
4413 // but you CANNOT call it.
4414 // This is an implementation detail and may be changed in the future.
4415 let f = |x: dyn Any| {};
4416 f(*answer()); // ERROR
4417}
4418```
4419
4420## By-value trait objects
4421
4422With this feature, you can have by-value `self` arguments without `Self: Sized` bounds.
4423
4424```rust
4425#![feature(unsized_fn_params)]
4426
4427trait Foo {
4428 fn foo(self) {}
4429}
4430
4431impl<T: ?Sized> Foo for T {}
4432
4433fn main() {
4434 let slice: Box<[i32]> = Box::new([1, 2, 3]);
4435 <[i32] as Foo>::foo(*slice);
4436}
4437```
4438
4439And `Foo` will also be object-safe.
4440
4441```rust
4442#![feature(unsized_fn_params)]
4443
4444trait Foo {
4445 fn foo(self) {}
4446}
4447
4448impl<T: ?Sized> Foo for T {}
4449
4450fn main () {
4451 let slice: Box<dyn Foo> = Box::new([1, 2, 3]);
4452 // doesn't compile yet
4453 <dyn Foo as Foo>::foo(*slice);
4454}
4455```
4456
4457One of the objectives of this feature is to allow `Box<dyn FnOnce>`.
4458
4459## Variable length arrays
4460
4461The RFC also describes an extension to the array literal syntax: `[e; dyn n]`. In the syntax, `n` isn't necessarily a constant expression. The array is dynamically allocated on the stack and has the type of `[T]`, instead of `[T; n]`.
4462
4463```rust,ignore (not-yet-implemented)
4464#![feature(unsized_locals)]
4465
4466fn mergesort<T: Ord>(a: &mut [T]) {
4467 let mut tmp = [T; dyn a.len()];
4468 // ...
4469}
4470
4471fn main() {
4472 let mut a = [3, 1, 5, 6];
4473 mergesort(&mut a);
4474 assert_eq!(a, [1, 3, 5, 6]);
4475}
4476```
4477
4478VLAs are not implemented yet. The syntax isn't final, either. We may need an alternative syntax for Rust 2015 because, in Rust 2015, expressions like `[e; dyn(1)]` would be ambiguous. One possible alternative proposed in the RFC is `[e; n]`: if `n` captures one or more local variables, then it is considered as `[e; dyn n]`.
4479
4480## Advisory on stack usage
4481
4482It's advised not to casually use the `#![feature(unsized_locals)]` feature. Typical use-cases are:
4483
4484- When you need a by-value trait objects.
4485- When you really need a fast allocation of small temporary arrays.
4486
4487Another pitfall is repetitive allocation and temporaries. Currently the compiler simply extends the stack frame every time it encounters an unsized assignment. So for example, the code
4488
4489```rust
4490#![feature(unsized_locals)]
4491
4492fn main() {
4493 let x: Box<[i32]> = Box::new([1, 2, 3, 4, 5]);
4494 let _x = {{{{{{{{{{*x}}}}}}}}}};
4495}
4496```
4497
4498and the code
4499
4500```rust
4501#![feature(unsized_locals)]
4502
4503fn main() {
4504 for _ in 0..10 {
4505 let x: Box<[i32]> = Box::new([1, 2, 3, 4, 5]);
4506 let _x = *x;
4507 }
4508}
4509```
4510
4511will unnecessarily extend the stack frame.
4512"##,
4513 },
4514 LintCompletion {
4515 label: "unsized_tuple_coercion",
4516 description: r##"# `unsized_tuple_coercion`
4517
4518The tracking issue for this feature is: [#42877]
4519
4520[#42877]: https://github.com/rust-lang/rust/issues/42877
4521
4522------------------------
4523
4524This is a part of [RFC0401]. According to the RFC, there should be an implementation like this:
4525
4526```rust,ignore (partial-example)
4527impl<..., T, U: ?Sized> Unsized<(..., U)> for (..., T) where T: Unsized<U> {}
4528```
4529
4530This implementation is currently gated behind `#[feature(unsized_tuple_coercion)]` to avoid insta-stability. Therefore you can use it like this:
4531
4532```rust
4533#![feature(unsized_tuple_coercion)]
4534
4535fn main() {
4536 let x : ([i32; 3], [i32; 3]) = ([1, 2, 3], [4, 5, 6]);
4537 let y : &([i32; 3], [i32]) = &x;
4538 assert_eq!(y.1[0], 4);
4539}
4540```
4541
4542[RFC0401]: https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md
4543"##,
4544 },
4545 LintCompletion {
4546 label: "update_panic_count",
4547 description: r##"# `update_panic_count`
4548
4549This feature is internal to the Rust compiler and is not intended for general use.
4550
4551------------------------
4552"##,
4553 },
4554 LintCompletion {
4555 label: "windows_c",
4556 description: r##"# `windows_c`
4557
4558This feature is internal to the Rust compiler and is not intended for general use.
4559
4560------------------------
4561"##,
4562 },
4563 LintCompletion {
4564 label: "windows_handle",
4565 description: r##"# `windows_handle`
4566
4567This feature is internal to the Rust compiler and is not intended for general use.
4568
4569------------------------
4570"##,
4571 },
4572 LintCompletion {
4573 label: "windows_net",
4574 description: r##"# `windows_net`
4575
4576This feature is internal to the Rust compiler and is not intended for general use.
4577
4578------------------------
4579"##,
4580 },
4581 LintCompletion {
4582 label: "windows_stdio",
4583 description: r##"# `windows_stdio`
4584
4585This feature is internal to the Rust compiler and is not intended for general use.
4586
4587------------------------
4588"##,
4589 },
4590];
4591
4592pub const CLIPPY_LINTS: &[LintCompletion] = &[
4593 LintCompletion {
4594 label: "clippy::absurd_extreme_comparisons",
4595 description: r##"Checks for comparisons where one side of the relation is\neither the minimum or maximum value for its type and warns if it involves a\ncase that is always true or always false. Only integer and boolean types are\nchecked."##,
4596 },
4597 LintCompletion {
4598 label: "clippy::almost_swapped",
4599 description: r##"Checks for `foo = bar; bar = foo` sequences."##,
4600 },
4601 LintCompletion {
4602 label: "clippy::approx_constant",
4603 description: r##"Checks for floating point literals that approximate\nconstants which are defined in\n[`std::f32::consts`](https://doc.rust-lang.org/stable/std/f32/consts/#constants)\nor\n[`std::f64::consts`](https://doc.rust-lang.org/stable/std/f64/consts/#constants),\nrespectively, suggesting to use the predefined constant."##,
4604 },
4605 LintCompletion {
4606 label: "clippy::as_conversions",
4607 description: r##"Checks for usage of `as` conversions.\n\nNote that this lint is specialized in linting *every single* use of `as`\nregardless of whether good alternatives exist or not.\nIf you want more precise lints for `as`, please consider using these separate lints:\n`unnecessary_cast`, `cast_lossless/possible_truncation/possible_wrap/precision_loss/sign_loss`,\n`fn_to_numeric_cast(_with_truncation)`, `char_lit_as_u8`, `ref_to_mut` and `ptr_as_ptr`.\nThere is a good explanation the reason why this lint should work in this way and how it is useful\n[in this issue](https://github.com/rust-lang/rust-clippy/issues/5122)."##,
4608 },
4609 LintCompletion {
4610 label: "clippy::assertions_on_constants",
4611 description: r##"Checks for `assert!(true)` and `assert!(false)` calls."##,
4612 },
4613 LintCompletion {
4614 label: "clippy::assign_op_pattern",
4615 description: r##"Checks for `a = a op b` or `a = b commutative_op a`\npatterns."##,
4616 },
4617 LintCompletion {
4618 label: "clippy::assign_ops",
4619 description: r##"Nothing. This lint has been deprecated."##,
4620 },
4621 LintCompletion {
4622 label: "clippy::async_yields_async",
4623 description: r##"Checks for async blocks that yield values of types\nthat can themselves be awaited."##,
4624 },
4625 LintCompletion {
4626 label: "clippy::await_holding_lock",
4627 description: r##"Checks for calls to await while holding a\nnon-async-aware MutexGuard."##,
4628 },
4629 LintCompletion {
4630 label: "clippy::await_holding_refcell_ref",
4631 description: r##"Checks for calls to await while holding a\n`RefCell` `Ref` or `RefMut`."##,
4632 },
4633 LintCompletion {
4634 label: "clippy::bad_bit_mask",
4635 description: r##"Checks for incompatible bit masks in comparisons.\n\nThe formula for detecting if an expression of the type `_ <bit_op> m\n<cmp_op> c` (where `<bit_op>` is one of {`&`, `|`} and `<cmp_op>` is one of\n{`!=`, `>=`, `>`, `!=`, `>=`, `>`}) can be determined from the following\ntable:\n\n|Comparison |Bit Op|Example |is always|Formula |\n|------------|------|------------|---------|----------------------|\n|`==` or `!=`| `&` |`x & 2 == 3`|`false` |`c & m != c` |\n|`<` or `>=`| `&` |`x & 2 < 3` |`true` |`m < c` |\n|`>` or `<=`| `&` |`x & 1 > 1` |`false` |`m <= c` |\n|`==` or `!=`| `|` |`x | 1 == 0`|`false` |`c | m != c` |\n|`<` or `>=`| `|` |`x | 1 < 1` |`false` |`m >= c` |\n|`<=` or `>` | `|` |`x | 1 > 0` |`true` |`m > c` |"##,
4636 },
4637 LintCompletion {
4638 label: "clippy::bind_instead_of_map",
4639 description: r##"Checks for usage of `_.and_then(|x| Some(y))`, `_.and_then(|x| Ok(y))` or\n`_.or_else(|x| Err(y))`."##,
4640 },
4641 LintCompletion {
4642 label: "clippy::blacklisted_name",
4643 description: r##"Checks for usage of blacklisted names for variables, such\nas `foo`."##,
4644 },
4645 LintCompletion {
4646 label: "clippy::blanket_clippy_restriction_lints",
4647 description: r##"Checks for `warn`/`deny`/`forbid` attributes targeting the whole clippy::restriction category."##,
4648 },
4649 LintCompletion {
4650 label: "clippy::blocks_in_if_conditions",
4651 description: r##"Checks for `if` conditions that use blocks containing an\nexpression, statements or conditions that use closures with blocks."##,
4652 },
4653 LintCompletion {
4654 label: "clippy::bool_assert_comparison",
4655 description: r##"This lint warns about boolean comparisons in assert-like macros."##,
4656 },
4657 LintCompletion {
4658 label: "clippy::bool_comparison",
4659 description: r##"Checks for expressions of the form `x == true`,\n`x != true` and order comparisons such as `x < true` (or vice versa) and\nsuggest using the variable directly."##,
4660 },
4661 LintCompletion {
4662 label: "clippy::borrow_interior_mutable_const",
4663 description: r##"Checks if `const` items which is interior mutable (e.g.,\ncontains a `Cell`, `Mutex`, `AtomicXxxx`, etc.) has been borrowed directly."##,
4664 },
4665 LintCompletion {
4666 label: "clippy::borrowed_box",
4667 description: r##"Checks for use of `&Box<T>` anywhere in the code.\nCheck the [Box documentation](https://doc.rust-lang.org/std/boxed/index.html) for more information."##,
4668 },
4669 LintCompletion {
4670 label: "clippy::box_vec",
4671 description: r##"Checks for use of `Box<Vec<_>>` anywhere in the code.\nCheck the [Box documentation](https://doc.rust-lang.org/std/boxed/index.html) for more information."##,
4672 },
4673 LintCompletion {
4674 label: "clippy::boxed_local",
4675 description: r##"Checks for usage of `Box<T>` where an unboxed `T` would\nwork fine."##,
4676 },
4677 LintCompletion {
4678 label: "clippy::branches_sharing_code",
4679 description: r##"Checks if the `if` and `else` block contain shared code that can be\nmoved out of the blocks."##,
4680 },
4681 LintCompletion {
4682 label: "clippy::builtin_type_shadow",
4683 description: r##"Warns if a generic shadows a built-in type."##,
4684 },
4685 LintCompletion {
4686 label: "clippy::bytes_nth",
4687 description: r##"Checks for the use of `.bytes().nth()`."##,
4688 },
4689 LintCompletion {
4690 label: "clippy::cargo_common_metadata",
4691 description: r##"Checks to see if all common metadata is defined in\n`Cargo.toml`. See: https://rust-lang-nursery.github.io/api-guidelines/documentation.html#cargotoml-includes-all-common-metadata-c-metadata"##,
4692 },
4693 LintCompletion {
4694 label: "clippy::case_sensitive_file_extension_comparisons",
4695 description: r##"Checks for calls to `ends_with` with possible file extensions\nand suggests to use a case-insensitive approach instead."##,
4696 },
4697 LintCompletion {
4698 label: "clippy::cast_lossless",
4699 description: r##"Checks for casts between numerical types that may\nbe replaced by safe conversion functions."##,
4700 },
4701 LintCompletion {
4702 label: "clippy::cast_possible_truncation",
4703 description: r##"Checks for casts between numerical types that may\ntruncate large values. This is expected behavior, so the cast is `Allow` by\ndefault."##,
4704 },
4705 LintCompletion {
4706 label: "clippy::cast_possible_wrap",
4707 description: r##"Checks for casts from an unsigned type to a signed type of\nthe same size. Performing such a cast is a 'no-op' for the compiler,\ni.e., nothing is changed at the bit level, and the binary representation of\nthe value is reinterpreted. This can cause wrapping if the value is too big\nfor the target signed type. However, the cast works as defined, so this lint\nis `Allow` by default."##,
4708 },
4709 LintCompletion {
4710 label: "clippy::cast_precision_loss",
4711 description: r##"Checks for casts from any numerical to a float type where\nthe receiving type cannot store all values from the original type without\nrounding errors. This possible rounding is to be expected, so this lint is\n`Allow` by default.\n\nBasically, this warns on casting any integer with 32 or more bits to `f32`\nor any 64-bit integer to `f64`."##,
4712 },
4713 LintCompletion {
4714 label: "clippy::cast_ptr_alignment",
4715 description: r##"Checks for casts, using `as` or `pointer::cast`,\nfrom a less-strictly-aligned pointer to a more-strictly-aligned pointer"##,
4716 },
4717 LintCompletion {
4718 label: "clippy::cast_ref_to_mut",
4719 description: r##"Checks for casts of `&T` to `&mut T` anywhere in the code."##,
4720 },
4721 LintCompletion {
4722 label: "clippy::cast_sign_loss",
4723 description: r##"Checks for casts from a signed to an unsigned numerical\ntype. In this case, negative values wrap around to large positive values,\nwhich can be quite surprising in practice. However, as the cast works as\ndefined, this lint is `Allow` by default."##,
4724 },
4725 LintCompletion {
4726 label: "clippy::char_lit_as_u8",
4727 description: r##"Checks for expressions where a character literal is cast\nto `u8` and suggests using a byte literal instead."##,
4728 },
4729 LintCompletion {
4730 label: "clippy::chars_last_cmp",
4731 description: r##"Checks for usage of `_.chars().last()` or\n`_.chars().next_back()` on a `str` to check if it ends with a given char."##,
4732 },
4733 LintCompletion {
4734 label: "clippy::chars_next_cmp",
4735 description: r##"Checks for usage of `.chars().next()` on a `str` to check\nif it starts with a given char."##,
4736 },
4737 LintCompletion {
4738 label: "clippy::checked_conversions",
4739 description: r##"Checks for explicit bounds checking when casting."##,
4740 },
4741 LintCompletion {
4742 label: "clippy::clone_double_ref",
4743 description: r##"Checks for usage of `.clone()` on an `&&T`."##,
4744 },
4745 LintCompletion {
4746 label: "clippy::clone_on_copy",
4747 description: r##"Checks for usage of `.clone()` on a `Copy` type."##,
4748 },
4749 LintCompletion {
4750 label: "clippy::clone_on_ref_ptr",
4751 description: r##"Checks for usage of `.clone()` on a ref-counted pointer,\n(`Rc`, `Arc`, `rc::Weak`, or `sync::Weak`), and suggests calling Clone via unified\nfunction syntax instead (e.g., `Rc::clone(foo)`)."##,
4752 },
4753 LintCompletion {
4754 label: "clippy::cloned_instead_of_copied",
4755 description: r##"Checks for usages of `cloned()` on an `Iterator` or `Option` where\n`copied()` could be used instead."##,
4756 },
4757 LintCompletion { label: "clippy::cmp_nan", description: r##"Checks for comparisons to NaN."## },
4758 LintCompletion {
4759 label: "clippy::cmp_null",
4760 description: r##"This lint checks for equality comparisons with `ptr::null`"##,
4761 },
4762 LintCompletion {
4763 label: "clippy::cmp_owned",
4764 description: r##"Checks for conversions to owned values just for the sake\nof a comparison."##,
4765 },
4766 LintCompletion {
4767 label: "clippy::cognitive_complexity",
4768 description: r##"Checks for methods with high cognitive complexity."##,
4769 },
4770 LintCompletion {
4771 label: "clippy::collapsible_else_if",
4772 description: r##"Checks for collapsible `else { if ... }` expressions\nthat can be collapsed to `else if ...`."##,
4773 },
4774 LintCompletion {
4775 label: "clippy::collapsible_if",
4776 description: r##"Checks for nested `if` statements which can be collapsed\nby `&&`-combining their conditions."##,
4777 },
4778 LintCompletion {
4779 label: "clippy::collapsible_match",
4780 description: r##"Finds nested `match` or `if let` expressions where the patterns may be \"collapsed\" together\nwithout adding any branches.\n\nNote that this lint is not intended to find _all_ cases where nested match patterns can be merged, but only\ncases where merging would most likely make the code more readable."##,
4781 },
4782 LintCompletion {
4783 label: "clippy::comparison_chain",
4784 description: r##"Checks comparison chains written with `if` that can be\nrewritten with `match` and `cmp`."##,
4785 },
4786 LintCompletion {
4787 label: "clippy::comparison_to_empty",
4788 description: r##"Checks for comparing to an empty slice such as `\"\"` or `[]`,\nand suggests using `.is_empty()` where applicable."##,
4789 },
4790 LintCompletion {
4791 label: "clippy::copy_iterator",
4792 description: r##"Checks for types that implement `Copy` as well as\n`Iterator`."##,
4793 },
4794 LintCompletion {
4795 label: "clippy::create_dir",
4796 description: r##"Checks usage of `std::fs::create_dir` and suggest using `std::fs::create_dir_all` instead."##,
4797 },
4798 LintCompletion {
4799 label: "clippy::crosspointer_transmute",
4800 description: r##"Checks for transmutes between a type `T` and `*T`."##,
4801 },
4802 LintCompletion {
4803 label: "clippy::dbg_macro",
4804 description: r##"Checks for usage of dbg!() macro."##,
4805 },
4806 LintCompletion {
4807 label: "clippy::debug_assert_with_mut_call",
4808 description: r##"Checks for function/method calls with a mutable\nparameter in `debug_assert!`, `debug_assert_eq!` and `debug_assert_ne!` macros."##,
4809 },
4810 LintCompletion {
4811 label: "clippy::decimal_literal_representation",
4812 description: r##"Warns if there is a better representation for a numeric literal."##,
4813 },
4814 LintCompletion {
4815 label: "clippy::declare_interior_mutable_const",
4816 description: r##"Checks for declaration of `const` items which is interior\nmutable (e.g., contains a `Cell`, `Mutex`, `AtomicXxxx`, etc.)."##,
4817 },
4818 LintCompletion {
4819 label: "clippy::default_numeric_fallback",
4820 description: r##"Checks for usage of unconstrained numeric literals which may cause default numeric fallback in type\ninference.\n\nDefault numeric fallback means that if numeric types have not yet been bound to concrete\ntypes at the end of type inference, then integer type is bound to `i32`, and similarly\nfloating type is bound to `f64`.\n\nSee [RFC0212](https://github.com/rust-lang/rfcs/blob/master/text/0212-restore-int-fallback.md) for more information about the fallback."##,
4821 },
4822 LintCompletion {
4823 label: "clippy::default_trait_access",
4824 description: r##"Checks for literal calls to `Default::default()`."##,
4825 },
4826 LintCompletion {
4827 label: "clippy::deprecated_cfg_attr",
4828 description: r##"Checks for `#[cfg_attr(rustfmt, rustfmt_skip)]` and suggests to replace it\nwith `#[rustfmt::skip]`."##,
4829 },
4830 LintCompletion {
4831 label: "clippy::deprecated_semver",
4832 description: r##"Checks for `#[deprecated]` annotations with a `since`\nfield that is not a valid semantic version."##,
4833 },
4834 LintCompletion {
4835 label: "clippy::deref_addrof",
4836 description: r##"Checks for usage of `*&` and `*&mut` in expressions."##,
4837 },
4838 LintCompletion {
4839 label: "clippy::derive_hash_xor_eq",
4840 description: r##"Checks for deriving `Hash` but implementing `PartialEq`\nexplicitly or vice versa."##,
4841 },
4842 LintCompletion {
4843 label: "clippy::derive_ord_xor_partial_ord",
4844 description: r##"Checks for deriving `Ord` but implementing `PartialOrd`\nexplicitly or vice versa."##,
4845 },
4846 LintCompletion {
4847 label: "clippy::disallowed_method",
4848 description: r##"Denies the configured methods and functions in clippy.toml"##,
4849 },
4850 LintCompletion {
4851 label: "clippy::diverging_sub_expression",
4852 description: r##"Checks for diverging calls that are not match arms or\nstatements."##,
4853 },
4854 LintCompletion {
4855 label: "clippy::doc_markdown",
4856 description: r##"Checks for the presence of `_`, `::` or camel-case words\noutside ticks in documentation."##,
4857 },
4858 LintCompletion {
4859 label: "clippy::double_comparisons",
4860 description: r##"Checks for double comparisons that could be simplified to a single expression."##,
4861 },
4862 LintCompletion {
4863 label: "clippy::double_must_use",
4864 description: r##"Checks for a [`#[must_use]`] attribute without\nfurther information on functions and methods that return a type already\nmarked as `#[must_use]`.\n\n[`#[must_use]`]: https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-must_use-attribute"##,
4865 },
4866 LintCompletion {
4867 label: "clippy::double_neg",
4868 description: r##"Detects expressions of the form `--x`."##,
4869 },
4870 LintCompletion {
4871 label: "clippy::double_parens",
4872 description: r##"Checks for unnecessary double parentheses."##,
4873 },
4874 LintCompletion {
4875 label: "clippy::drop_copy",
4876 description: r##"Checks for calls to `std::mem::drop` with a value\nthat derives the Copy trait"##,
4877 },
4878 LintCompletion {
4879 label: "clippy::drop_ref",
4880 description: r##"Checks for calls to `std::mem::drop` with a reference\ninstead of an owned value."##,
4881 },
4882 LintCompletion {
4883 label: "clippy::duplicate_underscore_argument",
4884 description: r##"Checks for function arguments having the similar names\ndiffering by an underscore."##,
4885 },
4886 LintCompletion {
4887 label: "clippy::duration_subsec",
4888 description: r##"Checks for calculation of subsecond microseconds or milliseconds\nfrom other `Duration` methods."##,
4889 },
4890 LintCompletion {
4891 label: "clippy::else_if_without_else",
4892 description: r##"Checks for usage of if expressions with an `else if` branch,\nbut without a final `else` branch."##,
4893 },
4894 LintCompletion {
4895 label: "clippy::empty_enum",
4896 description: r##"Checks for `enum`s with no variants.\n\nAs of this writing, the `never_type` is still a\nnightly-only experimental API. Therefore, this lint is only triggered\nif the `never_type` is enabled."##,
4897 },
4898 LintCompletion {
4899 label: "clippy::empty_line_after_outer_attr",
4900 description: r##"Checks for empty lines after outer attributes"##,
4901 },
4902 LintCompletion {
4903 label: "clippy::empty_loop",
4904 description: r##"Checks for empty `loop` expressions."##,
4905 },
4906 LintCompletion {
4907 label: "clippy::enum_clike_unportable_variant",
4908 description: r##"Checks for C-like enumerations that are\n`repr(isize/usize)` and have values that don't fit into an `i32`."##,
4909 },
4910 LintCompletion {
4911 label: "clippy::enum_glob_use",
4912 description: r##"Checks for `use Enum::*`."##,
4913 },
4914 LintCompletion {
4915 label: "clippy::enum_variant_names",
4916 description: r##"Detects enumeration variants that are prefixed or suffixed\nby the same characters."##,
4917 },
4918 LintCompletion {
4919 label: "clippy::eq_op",
4920 description: r##"Checks for equal operands to comparison, logical and\nbitwise, difference and division binary operators (`==`, `>`, etc., `&&`,\n`||`, `&`, `|`, `^`, `-` and `/`)."##,
4921 },
4922 LintCompletion {
4923 label: "clippy::erasing_op",
4924 description: r##"Checks for erasing operations, e.g., `x * 0`."##,
4925 },
4926 LintCompletion {
4927 label: "clippy::eval_order_dependence",
4928 description: r##"Checks for a read and a write to the same variable where\nwhether the read occurs before or after the write depends on the evaluation\norder of sub-expressions."##,
4929 },
4930 LintCompletion {
4931 label: "clippy::excessive_precision",
4932 description: r##"Checks for float literals with a precision greater\nthan that supported by the underlying type."##,
4933 },
4934 LintCompletion {
4935 label: "clippy::exhaustive_enums",
4936 description: r##"Warns on any exported `enum`s that are not tagged `#[non_exhaustive]`"##,
4937 },
4938 LintCompletion {
4939 label: "clippy::exhaustive_structs",
4940 description: r##"Warns on any exported `structs`s that are not tagged `#[non_exhaustive]`"##,
4941 },
4942 LintCompletion {
4943 label: "clippy::exit",
4944 description: r##"`exit()` terminates the program and doesn't provide a\nstack trace."##,
4945 },
4946 LintCompletion {
4947 label: "clippy::expect_fun_call",
4948 description: r##"Checks for calls to `.expect(&format!(...))`, `.expect(foo(..))`,\netc., and suggests to use `unwrap_or_else` instead"##,
4949 },
4950 LintCompletion {
4951 label: "clippy::expect_used",
4952 description: r##"Checks for `.expect()` calls on `Option`s and `Result`s."##,
4953 },
4954 LintCompletion {
4955 label: "clippy::expl_impl_clone_on_copy",
4956 description: r##"Checks for explicit `Clone` implementations for `Copy`\ntypes."##,
4957 },
4958 LintCompletion {
4959 label: "clippy::explicit_counter_loop",
4960 description: r##"Checks `for` loops over slices with an explicit counter\nand suggests the use of `.enumerate()`."##,
4961 },
4962 LintCompletion {
4963 label: "clippy::explicit_deref_methods",
4964 description: r##"Checks for explicit `deref()` or `deref_mut()` method calls."##,
4965 },
4966 LintCompletion {
4967 label: "clippy::explicit_into_iter_loop",
4968 description: r##"Checks for loops on `y.into_iter()` where `y` will do, and\nsuggests the latter."##,
4969 },
4970 LintCompletion {
4971 label: "clippy::explicit_iter_loop",
4972 description: r##"Checks for loops on `x.iter()` where `&x` will do, and\nsuggests the latter."##,
4973 },
4974 LintCompletion {
4975 label: "clippy::explicit_write",
4976 description: r##"Checks for usage of `write!()` / `writeln()!` which can be\nreplaced with `(e)print!()` / `(e)println!()`"##,
4977 },
4978 LintCompletion {
4979 label: "clippy::extend_from_slice",
4980 description: r##"Nothing. This lint has been deprecated."##,
4981 },
4982 LintCompletion {
4983 label: "clippy::extra_unused_lifetimes",
4984 description: r##"Checks for lifetimes in generics that are never used\nanywhere else."##,
4985 },
4986 LintCompletion {
4987 label: "clippy::fallible_impl_from",
4988 description: r##"Checks for impls of `From<..>` that contain `panic!()` or `unwrap()`"##,
4989 },
4990 LintCompletion {
4991 label: "clippy::field_reassign_with_default",
4992 description: r##"Checks for immediate reassignment of fields initialized\nwith Default::default()."##,
4993 },
4994 LintCompletion {
4995 label: "clippy::filetype_is_file",
4996 description: r##"Checks for `FileType::is_file()`."##,
4997 },
4998 LintCompletion {
4999 label: "clippy::filter_map",
5000 description: r##"Nothing. This lint has been deprecated."##,
5001 },
5002 LintCompletion {
5003 label: "clippy::filter_map_identity",
5004 description: r##"Checks for usage of `filter_map(|x| x)`."##,
5005 },
5006 LintCompletion {
5007 label: "clippy::filter_map_next",
5008 description: r##"Checks for usage of `_.filter_map(_).next()`."##,
5009 },
5010 LintCompletion {
5011 label: "clippy::filter_next",
5012 description: r##"Checks for usage of `_.filter(_).next()`."##,
5013 },
5014 LintCompletion {
5015 label: "clippy::find_map",
5016 description: r##"Nothing. This lint has been deprecated."##,
5017 },
5018 LintCompletion {
5019 label: "clippy::flat_map_identity",
5020 description: r##"Checks for usage of `flat_map(|x| x)`."##,
5021 },
5022 LintCompletion {
5023 label: "clippy::flat_map_option",
5024 description: r##"Checks for usages of `Iterator::flat_map()` where `filter_map()` could be\nused instead."##,
5025 },
5026 LintCompletion {
5027 label: "clippy::float_arithmetic",
5028 description: r##"Checks for float arithmetic."##,
5029 },
5030 LintCompletion {
5031 label: "clippy::float_cmp",
5032 description: r##"Checks for (in-)equality comparisons on floating-point\nvalues (apart from zero), except in functions called `*eq*` (which probably\nimplement equality for a type involving floats)."##,
5033 },
5034 LintCompletion {
5035 label: "clippy::float_cmp_const",
5036 description: r##"Checks for (in-)equality comparisons on floating-point\nvalue and constant, except in functions called `*eq*` (which probably\nimplement equality for a type involving floats)."##,
5037 },
5038 LintCompletion {
5039 label: "clippy::float_equality_without_abs",
5040 description: r##"Checks for statements of the form `(a - b) < f32::EPSILON` or\n`(a - b) < f64::EPSILON`. Notes the missing `.abs()`."##,
5041 },
5042 LintCompletion {
5043 label: "clippy::fn_address_comparisons",
5044 description: r##"Checks for comparisons with an address of a function item."##,
5045 },
5046 LintCompletion {
5047 label: "clippy::fn_params_excessive_bools",
5048 description: r##"Checks for excessive use of\nbools in function definitions."##,
5049 },
5050 LintCompletion {
5051 label: "clippy::fn_to_numeric_cast",
5052 description: r##"Checks for casts of function pointers to something other than usize"##,
5053 },
5054 LintCompletion {
5055 label: "clippy::fn_to_numeric_cast_with_truncation",
5056 description: r##"Checks for casts of a function pointer to a numeric type not wide enough to\nstore address."##,
5057 },
5058 LintCompletion {
5059 label: "clippy::for_kv_map",
5060 description: r##"Checks for iterating a map (`HashMap` or `BTreeMap`) and\nignoring either the keys or values."##,
5061 },
5062 LintCompletion {
5063 label: "clippy::for_loops_over_fallibles",
5064 description: r##"Checks for `for` loops over `Option` or `Result` values."##,
5065 },
5066 LintCompletion {
5067 label: "clippy::forget_copy",
5068 description: r##"Checks for calls to `std::mem::forget` with a value that\nderives the Copy trait"##,
5069 },
5070 LintCompletion {
5071 label: "clippy::forget_ref",
5072 description: r##"Checks for calls to `std::mem::forget` with a reference\ninstead of an owned value."##,
5073 },
5074 LintCompletion {
5075 label: "clippy::from_iter_instead_of_collect",
5076 description: r##"Checks for `from_iter()` function calls on types that implement the `FromIterator`\ntrait."##,
5077 },
5078 LintCompletion {
5079 label: "clippy::from_over_into",
5080 description: r##"Searches for implementations of the `Into<..>` trait and suggests to implement `From<..>` instead."##,
5081 },
5082 LintCompletion {
5083 label: "clippy::from_str_radix_10",
5084 description: r##"Checks for function invocations of the form `primitive::from_str_radix(s, 10)`"##,
5085 },
5086 LintCompletion {
5087 label: "clippy::future_not_send",
5088 description: r##"This lint requires Future implementations returned from\nfunctions and methods to implement the `Send` marker trait. It is mostly\nused by library authors (public and internal) that target an audience where\nmultithreaded executors are likely to be used for running these Futures."##,
5089 },
5090 LintCompletion {
5091 label: "clippy::get_last_with_len",
5092 description: r##"Checks for using `x.get(x.len() - 1)` instead of\n`x.last()`."##,
5093 },
5094 LintCompletion {
5095 label: "clippy::get_unwrap",
5096 description: r##"Checks for use of `.get().unwrap()` (or\n`.get_mut().unwrap`) on a standard library type which implements `Index`"##,
5097 },
5098 LintCompletion {
5099 label: "clippy::identity_op",
5100 description: r##"Checks for identity operations, e.g., `x + 0`."##,
5101 },
5102 LintCompletion {
5103 label: "clippy::if_let_mutex",
5104 description: r##"Checks for `Mutex::lock` calls in `if let` expression\nwith lock calls in any of the else blocks."##,
5105 },
5106 LintCompletion {
5107 label: "clippy::if_let_redundant_pattern_matching",
5108 description: r##"Nothing. This lint has been deprecated."##,
5109 },
5110 LintCompletion {
5111 label: "clippy::if_let_some_result",
5112 description: r##"* Checks for unnecessary `ok()` in if let."##,
5113 },
5114 LintCompletion {
5115 label: "clippy::if_not_else",
5116 description: r##"Checks for usage of `!` or `!=` in an if condition with an\nelse branch."##,
5117 },
5118 LintCompletion {
5119 label: "clippy::if_same_then_else",
5120 description: r##"Checks for `if/else` with the same body as the *then* part\nand the *else* part."##,
5121 },
5122 LintCompletion {
5123 label: "clippy::if_then_some_else_none",
5124 description: r##"Checks for if-else that could be written to `bool::then`."##,
5125 },
5126 LintCompletion {
5127 label: "clippy::ifs_same_cond",
5128 description: r##"Checks for consecutive `if`s with the same condition."##,
5129 },
5130 LintCompletion {
5131 label: "clippy::implicit_clone",
5132 description: r##"Checks for the usage of `_.to_owned()`, `vec.to_vec()`, or similar when calling `_.clone()` would be clearer."##,
5133 },
5134 LintCompletion {
5135 label: "clippy::implicit_hasher",
5136 description: r##"Checks for public `impl` or `fn` missing generalization\nover different hashers and implicitly defaulting to the default hashing\nalgorithm (`SipHash`)."##,
5137 },
5138 LintCompletion {
5139 label: "clippy::implicit_return",
5140 description: r##"Checks for missing return statements at the end of a block."##,
5141 },
5142 LintCompletion {
5143 label: "clippy::implicit_saturating_sub",
5144 description: r##"Checks for implicit saturating subtraction."##,
5145 },
5146 LintCompletion {
5147 label: "clippy::imprecise_flops",
5148 description: r##"Looks for floating-point expressions that\ncan be expressed using built-in methods to improve accuracy\nat the cost of performance."##,
5149 },
5150 LintCompletion {
5151 label: "clippy::inconsistent_digit_grouping",
5152 description: r##"Warns if an integral or floating-point constant is\ngrouped inconsistently with underscores."##,
5153 },
5154 LintCompletion {
5155 label: "clippy::inconsistent_struct_constructor",
5156 description: r##"Checks for struct constructors where all fields are shorthand and\nthe order of the field init shorthand in the constructor is inconsistent\nwith the order in the struct definition."##,
5157 },
5158 LintCompletion {
5159 label: "clippy::indexing_slicing",
5160 description: r##"Checks for usage of indexing or slicing. Arrays are special cases, this lint\ndoes report on arrays if we can tell that slicing operations are in bounds and does not\nlint on constant `usize` indexing on arrays because that is handled by rustc's `const_err` lint."##,
5161 },
5162 LintCompletion {
5163 label: "clippy::ineffective_bit_mask",
5164 description: r##"Checks for bit masks in comparisons which can be removed\nwithout changing the outcome. The basic structure can be seen in the\nfollowing table:\n\n|Comparison| Bit Op |Example |equals |\n|----------|---------|-----------|-------|\n|`>` / `<=`|`|` / `^`|`x | 2 > 3`|`x > 3`|\n|`<` / `>=`|`|` / `^`|`x ^ 1 < 4`|`x < 4`|"##,
5165 },
5166 LintCompletion {
5167 label: "clippy::inefficient_to_string",
5168 description: r##"Checks for usage of `.to_string()` on an `&&T` where\n`T` implements `ToString` directly (like `&&str` or `&&String`)."##,
5169 },
5170 LintCompletion {
5171 label: "clippy::infallible_destructuring_match",
5172 description: r##"Checks for matches being used to destructure a single-variant enum\nor tuple struct where a `let` will suffice."##,
5173 },
5174 LintCompletion {
5175 label: "clippy::infinite_iter",
5176 description: r##"Checks for iteration that is guaranteed to be infinite."##,
5177 },
5178 LintCompletion {
5179 label: "clippy::inherent_to_string",
5180 description: r##"Checks for the definition of inherent methods with a signature of `to_string(&self) -> String`."##,
5181 },
5182 LintCompletion {
5183 label: "clippy::inherent_to_string_shadow_display",
5184 description: r##"Checks for the definition of inherent methods with a signature of `to_string(&self) -> String` and if the type implementing this method also implements the `Display` trait."##,
5185 },
5186 LintCompletion {
5187 label: "clippy::inline_always",
5188 description: r##"Checks for items annotated with `#[inline(always)]`,\nunless the annotated function is empty or simply panics."##,
5189 },
5190 LintCompletion {
5191 label: "clippy::inline_asm_x86_att_syntax",
5192 description: r##"Checks for usage of AT&T x86 assembly syntax."##,
5193 },
5194 LintCompletion {
5195 label: "clippy::inline_asm_x86_intel_syntax",
5196 description: r##"Checks for usage of Intel x86 assembly syntax."##,
5197 },
5198 LintCompletion {
5199 label: "clippy::inline_fn_without_body",
5200 description: r##"Checks for `#[inline]` on trait methods without bodies"##,
5201 },
5202 LintCompletion {
5203 label: "clippy::inspect_for_each",
5204 description: r##"Checks for usage of `inspect().for_each()`."##,
5205 },
5206 LintCompletion {
5207 label: "clippy::int_plus_one",
5208 description: r##"Checks for usage of `x >= y + 1` or `x - 1 >= y` (and `<=`) in a block"##,
5209 },
5210 LintCompletion {
5211 label: "clippy::integer_arithmetic",
5212 description: r##"Checks for integer arithmetic operations which could overflow or panic.\n\nSpecifically, checks for any operators (`+`, `-`, `*`, `<<`, etc) which are capable\nof overflowing according to the [Rust\nReference](https://doc.rust-lang.org/reference/expressions/operator-expr.html#overflow),\nor which can panic (`/`, `%`). No bounds analysis or sophisticated reasoning is\nattempted."##,
5213 },
5214 LintCompletion {
5215 label: "clippy::integer_division",
5216 description: r##"Checks for division of integers"##,
5217 },
5218 LintCompletion {
5219 label: "clippy::into_iter_on_ref",
5220 description: r##"Checks for `into_iter` calls on references which should be replaced by `iter`\nor `iter_mut`."##,
5221 },
5222 LintCompletion {
5223 label: "clippy::invalid_atomic_ordering",
5224 description: r##"Checks for usage of invalid atomic\nordering in atomic loads/stores/exchanges/updates and\nmemory fences."##,
5225 },
5226 LintCompletion {
5227 label: "clippy::invalid_null_ptr_usage",
5228 description: r##"This lint checks for invalid usages of `ptr::null`."##,
5229 },
5230 LintCompletion {
5231 label: "clippy::invalid_regex",
5232 description: r##"Checks [regex](https://crates.io/crates/regex) creation\n(with `Regex::new`, `RegexBuilder::new`, or `RegexSet::new`) for correct\nregex syntax."##,
5233 },
5234 LintCompletion {
5235 label: "clippy::invalid_upcast_comparisons",
5236 description: r##"Checks for comparisons where the relation is always either\ntrue or false, but where one side has been upcast so that the comparison is\nnecessary. Only integer types are checked."##,
5237 },
5238 LintCompletion {
5239 label: "clippy::invisible_characters",
5240 description: r##"Checks for invisible Unicode characters in the code."##,
5241 },
5242 LintCompletion {
5243 label: "clippy::items_after_statements",
5244 description: r##"Checks for items declared after some statement in a block."##,
5245 },
5246 LintCompletion {
5247 label: "clippy::iter_cloned_collect",
5248 description: r##"Checks for the use of `.cloned().collect()` on slice to\ncreate a `Vec`."##,
5249 },
5250 LintCompletion {
5251 label: "clippy::iter_count",
5252 description: r##"Checks for the use of `.iter().count()`."##,
5253 },
5254 LintCompletion {
5255 label: "clippy::iter_next_loop",
5256 description: r##"Checks for loops on `x.next()`."##,
5257 },
5258 LintCompletion {
5259 label: "clippy::iter_next_slice",
5260 description: r##"Checks for usage of `iter().next()` on a Slice or an Array"##,
5261 },
5262 LintCompletion {
5263 label: "clippy::iter_nth",
5264 description: r##"Checks for use of `.iter().nth()` (and the related\n`.iter_mut().nth()`) on standard library types with O(1) element access."##,
5265 },
5266 LintCompletion {
5267 label: "clippy::iter_nth_zero",
5268 description: r##"Checks for the use of `iter.nth(0)`."##,
5269 },
5270 LintCompletion {
5271 label: "clippy::iter_skip_next",
5272 description: r##"Checks for use of `.skip(x).next()` on iterators."##,
5273 },
5274 LintCompletion {
5275 label: "clippy::iterator_step_by_zero",
5276 description: r##"Checks for calling `.step_by(0)` on iterators which panics."##,
5277 },
5278 LintCompletion {
5279 label: "clippy::just_underscores_and_digits",
5280 description: r##"Checks if you have variables whose name consists of just\nunderscores and digits."##,
5281 },
5282 LintCompletion {
5283 label: "clippy::large_const_arrays",
5284 description: r##"Checks for large `const` arrays that should\nbe defined as `static` instead."##,
5285 },
5286 LintCompletion {
5287 label: "clippy::large_digit_groups",
5288 description: r##"Warns if the digits of an integral or floating-point\nconstant are grouped into groups that\nare too large."##,
5289 },
5290 LintCompletion {
5291 label: "clippy::large_enum_variant",
5292 description: r##"Checks for large size differences between variants on\n`enum`s."##,
5293 },
5294 LintCompletion {
5295 label: "clippy::large_stack_arrays",
5296 description: r##"Checks for local arrays that may be too large."##,
5297 },
5298 LintCompletion {
5299 label: "clippy::large_types_passed_by_value",
5300 description: r##"Checks for functions taking arguments by value, where\nthe argument type is `Copy` and large enough to be worth considering\npassing by reference. Does not trigger if the function is being exported,\nbecause that might induce API breakage, if the parameter is declared as mutable,\nor if the argument is a `self`."##,
5301 },
5302 LintCompletion {
5303 label: "clippy::len_without_is_empty",
5304 description: r##"Checks for items that implement `.len()` but not\n`.is_empty()`."##,
5305 },
5306 LintCompletion {
5307 label: "clippy::len_zero",
5308 description: r##"Checks for getting the length of something via `.len()`\njust to compare to zero, and suggests using `.is_empty()` where applicable."##,
5309 },
5310 LintCompletion {
5311 label: "clippy::let_and_return",
5312 description: r##"Checks for `let`-bindings, which are subsequently\nreturned."##,
5313 },
5314 LintCompletion {
5315 label: "clippy::let_underscore_drop",
5316 description: r##"Checks for `let _ = <expr>`\nwhere expr has a type that implements `Drop`"##,
5317 },
5318 LintCompletion {
5319 label: "clippy::let_underscore_lock",
5320 description: r##"Checks for `let _ = sync_lock`"##,
5321 },
5322 LintCompletion {
5323 label: "clippy::let_underscore_must_use",
5324 description: r##"Checks for `let _ = <expr>`\nwhere expr is #[must_use]"##,
5325 },
5326 LintCompletion {
5327 label: "clippy::let_unit_value",
5328 description: r##"Checks for binding a unit value."##,
5329 },
5330 LintCompletion {
5331 label: "clippy::linkedlist",
5332 description: r##"Checks for usage of any `LinkedList`, suggesting to use a\n`Vec` or a `VecDeque` (formerly called `RingBuf`)."##,
5333 },
5334 LintCompletion {
5335 label: "clippy::logic_bug",
5336 description: r##"Checks for boolean expressions that contain terminals that\ncan be eliminated."##,
5337 },
5338 LintCompletion {
5339 label: "clippy::lossy_float_literal",
5340 description: r##"Checks for whole number float literals that\ncannot be represented as the underlying type without loss."##,
5341 },
5342 LintCompletion {
5343 label: "clippy::macro_use_imports",
5344 description: r##"Checks for `#[macro_use] use...`."##,
5345 },
5346 LintCompletion {
5347 label: "clippy::main_recursion",
5348 description: r##"Checks for recursion using the entrypoint."##,
5349 },
5350 LintCompletion {
5351 label: "clippy::manual_async_fn",
5352 description: r##"It checks for manual implementations of `async` functions."##,
5353 },
5354 LintCompletion {
5355 label: "clippy::manual_filter_map",
5356 description: r##"Checks for usage of `_.filter(_).map(_)` that can be written more simply\nas `filter_map(_)`."##,
5357 },
5358 LintCompletion {
5359 label: "clippy::manual_find_map",
5360 description: r##"Checks for usage of `_.find(_).map(_)` that can be written more simply\nas `find_map(_)`."##,
5361 },
5362 LintCompletion {
5363 label: "clippy::manual_flatten",
5364 description: r##"Check for unnecessary `if let` usage in a for loop\nwhere only the `Some` or `Ok` variant of the iterator element is used."##,
5365 },
5366 LintCompletion {
5367 label: "clippy::manual_map",
5368 description: r##"Checks for usages of `match` which could be implemented using `map`"##,
5369 },
5370 LintCompletion {
5371 label: "clippy::manual_memcpy",
5372 description: r##"Checks for for-loops that manually copy items between\nslices that could be optimized by having a memcpy."##,
5373 },
5374 LintCompletion {
5375 label: "clippy::manual_non_exhaustive",
5376 description: r##"Checks for manual implementations of the non-exhaustive pattern."##,
5377 },
5378 LintCompletion {
5379 label: "clippy::manual_ok_or",
5380 description: r##"Finds patterns that reimplement `Option::ok_or`."##,
5381 },
5382 LintCompletion {
5383 label: "clippy::manual_range_contains",
5384 description: r##"Checks for expressions like `x >= 3 && x < 8` that could\nbe more readably expressed as `(3..8).contains(x)`."##,
5385 },
5386 LintCompletion {
5387 label: "clippy::manual_saturating_arithmetic",
5388 description: r##"Checks for `.checked_add/sub(x).unwrap_or(MAX/MIN)`."##,
5389 },
5390 LintCompletion {
5391 label: "clippy::manual_str_repeat",
5392 description: r##"Checks for manual implementations of `str::repeat`"##,
5393 },
5394 LintCompletion {
5395 label: "clippy::manual_strip",
5396 description: r##"Suggests using `strip_{prefix,suffix}` over `str::{starts,ends}_with` and slicing using\nthe pattern's length."##,
5397 },
5398 LintCompletion {
5399 label: "clippy::manual_swap",
5400 description: r##"Checks for manual swapping."##,
5401 },
5402 LintCompletion {
5403 label: "clippy::manual_unwrap_or",
5404 description: r##"Finds patterns that reimplement `Option::unwrap_or` or `Result::unwrap_or`."##,
5405 },
5406 LintCompletion {
5407 label: "clippy::many_single_char_names",
5408 description: r##"Checks for too many variables whose name consists of a\nsingle character."##,
5409 },
5410 LintCompletion {
5411 label: "clippy::map_clone",
5412 description: r##"Checks for usage of `map(|x| x.clone())` or\ndereferencing closures for `Copy` types, on `Iterator` or `Option`,\nand suggests `cloned()` or `copied()` instead"##,
5413 },
5414 LintCompletion {
5415 label: "clippy::map_collect_result_unit",
5416 description: r##"Checks for usage of `_.map(_).collect::<Result<(), _>()`."##,
5417 },
5418 LintCompletion {
5419 label: "clippy::map_entry",
5420 description: r##"Checks for uses of `contains_key` + `insert` on `HashMap`\nor `BTreeMap`."##,
5421 },
5422 LintCompletion {
5423 label: "clippy::map_err_ignore",
5424 description: r##"Checks for instances of `map_err(|_| Some::Enum)`"##,
5425 },
5426 LintCompletion {
5427 label: "clippy::map_flatten",
5428 description: r##"Checks for usage of `_.map(_).flatten(_)` on `Iterator` and `Option`"##,
5429 },
5430 LintCompletion {
5431 label: "clippy::map_identity",
5432 description: r##"Checks for instances of `map(f)` where `f` is the identity function."##,
5433 },
5434 LintCompletion {
5435 label: "clippy::map_unwrap_or",
5436 description: r##"Checks for usage of `option.map(_).unwrap_or(_)` or `option.map(_).unwrap_or_else(_)` or\n`result.map(_).unwrap_or_else(_)`."##,
5437 },
5438 LintCompletion {
5439 label: "clippy::match_as_ref",
5440 description: r##"Checks for match which is used to add a reference to an\n`Option` value."##,
5441 },
5442 LintCompletion {
5443 label: "clippy::match_bool",
5444 description: r##"Checks for matches where match expression is a `bool`. It\nsuggests to replace the expression with an `if...else` block."##,
5445 },
5446 LintCompletion {
5447 label: "clippy::match_like_matches_macro",
5448 description: r##"Checks for `match` or `if let` expressions producing a\n`bool` that could be written using `matches!`"##,
5449 },
5450 LintCompletion {
5451 label: "clippy::match_on_vec_items",
5452 description: r##"Checks for `match vec[idx]` or `match vec[n..m]`."##,
5453 },
5454 LintCompletion {
5455 label: "clippy::match_overlapping_arm",
5456 description: r##"Checks for overlapping match arms."##,
5457 },
5458 LintCompletion {
5459 label: "clippy::match_ref_pats",
5460 description: r##"Checks for matches where all arms match a reference,\nsuggesting to remove the reference and deref the matched expression\ninstead. It also checks for `if let &foo = bar` blocks."##,
5461 },
5462 LintCompletion {
5463 label: "clippy::match_same_arms",
5464 description: r##"Checks for `match` with identical arm bodies."##,
5465 },
5466 LintCompletion {
5467 label: "clippy::match_single_binding",
5468 description: r##"Checks for useless match that binds to only one value."##,
5469 },
5470 LintCompletion {
5471 label: "clippy::match_wild_err_arm",
5472 description: r##"Checks for arm which matches all errors with `Err(_)`\nand take drastic actions like `panic!`."##,
5473 },
5474 LintCompletion {
5475 label: "clippy::match_wildcard_for_single_variants",
5476 description: r##"Checks for wildcard enum matches for a single variant."##,
5477 },
5478 LintCompletion {
5479 label: "clippy::maybe_infinite_iter",
5480 description: r##"Checks for iteration that may be infinite."##,
5481 },
5482 LintCompletion {
5483 label: "clippy::mem_discriminant_non_enum",
5484 description: r##"Checks for calls of `mem::discriminant()` on a non-enum type."##,
5485 },
5486 LintCompletion {
5487 label: "clippy::mem_forget",
5488 description: r##"Checks for usage of `std::mem::forget(t)` where `t` is\n`Drop`."##,
5489 },
5490 LintCompletion {
5491 label: "clippy::mem_replace_option_with_none",
5492 description: r##"Checks for `mem::replace()` on an `Option` with\n`None`."##,
5493 },
5494 LintCompletion {
5495 label: "clippy::mem_replace_with_default",
5496 description: r##"Checks for `std::mem::replace` on a value of type\n`T` with `T::default()`."##,
5497 },
5498 LintCompletion {
5499 label: "clippy::mem_replace_with_uninit",
5500 description: r##"Checks for `mem::replace(&mut _, mem::uninitialized())`\nand `mem::replace(&mut _, mem::zeroed())`."##,
5501 },
5502 LintCompletion {
5503 label: "clippy::min_max",
5504 description: r##"Checks for expressions where `std::cmp::min` and `max` are\nused to clamp values, but switched so that the result is constant."##,
5505 },
5506 LintCompletion {
5507 label: "clippy::misaligned_transmute",
5508 description: r##"Nothing. This lint has been deprecated."##,
5509 },
5510 LintCompletion {
5511 label: "clippy::mismatched_target_os",
5512 description: r##"Checks for cfg attributes having operating systems used in target family position."##,
5513 },
5514 LintCompletion {
5515 label: "clippy::misrefactored_assign_op",
5516 description: r##"Checks for `a op= a op b` or `a op= b op a` patterns."##,
5517 },
5518 LintCompletion {
5519 label: "clippy::missing_const_for_fn",
5520 description: r##"Suggests the use of `const` in functions and methods where possible."##,
5521 },
5522 LintCompletion {
5523 label: "clippy::missing_docs_in_private_items",
5524 description: r##"Warns if there is missing doc for any documentable item\n(public or private)."##,
5525 },
5526 LintCompletion {
5527 label: "clippy::missing_errors_doc",
5528 description: r##"Checks the doc comments of publicly visible functions that\nreturn a `Result` type and warns if there is no `# Errors` section."##,
5529 },
5530 LintCompletion {
5531 label: "clippy::missing_inline_in_public_items",
5532 description: r##"it lints if an exported function, method, trait method with default impl,\nor trait method impl is not `#[inline]`."##,
5533 },
5534 LintCompletion {
5535 label: "clippy::missing_panics_doc",
5536 description: r##"Checks the doc comments of publicly visible functions that\nmay panic and warns if there is no `# Panics` section."##,
5537 },
5538 LintCompletion {
5539 label: "clippy::missing_safety_doc",
5540 description: r##"Checks for the doc comments of publicly visible\nunsafe functions and warns if there is no `# Safety` section."##,
5541 },
5542 LintCompletion {
5543 label: "clippy::mistyped_literal_suffixes",
5544 description: r##"Warns for mistyped suffix in literals"##,
5545 },
5546 LintCompletion {
5547 label: "clippy::mixed_case_hex_literals",
5548 description: r##"Warns on hexadecimal literals with mixed-case letter\ndigits."##,
5549 },
5550 LintCompletion {
5551 label: "clippy::module_inception",
5552 description: r##"Checks for modules that have the same name as their\nparent module"##,
5553 },
5554 LintCompletion {
5555 label: "clippy::module_name_repetitions",
5556 description: r##"Detects type names that are prefixed or suffixed by the\ncontaining module's name."##,
5557 },
5558 LintCompletion {
5559 label: "clippy::modulo_arithmetic",
5560 description: r##"Checks for modulo arithmetic."##,
5561 },
5562 LintCompletion {
5563 label: "clippy::modulo_one",
5564 description: r##"Checks for getting the remainder of a division by one or minus\none."##,
5565 },
5566 LintCompletion {
5567 label: "clippy::multiple_crate_versions",
5568 description: r##"Checks to see if multiple versions of a crate are being\nused."##,
5569 },
5570 LintCompletion {
5571 label: "clippy::multiple_inherent_impl",
5572 description: r##"Checks for multiple inherent implementations of a struct"##,
5573 },
5574 LintCompletion {
5575 label: "clippy::must_use_candidate",
5576 description: r##"Checks for public functions that have no\n[`#[must_use]`] attribute, but return something not already marked\nmust-use, have no mutable arg and mutate no statics.\n\n[`#[must_use]`]: https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-must_use-attribute"##,
5577 },
5578 LintCompletion {
5579 label: "clippy::must_use_unit",
5580 description: r##"Checks for a [`#[must_use]`] attribute on\nunit-returning functions and methods.\n\n[`#[must_use]`]: https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-must_use-attribute"##,
5581 },
5582 LintCompletion {
5583 label: "clippy::mut_from_ref",
5584 description: r##"This lint checks for functions that take immutable\nreferences and return mutable ones."##,
5585 },
5586 LintCompletion {
5587 label: "clippy::mut_mut",
5588 description: r##"Checks for instances of `mut mut` references."##,
5589 },
5590 LintCompletion {
5591 label: "clippy::mut_mutex_lock",
5592 description: r##"Checks for `&mut Mutex::lock` calls"##,
5593 },
5594 LintCompletion {
5595 label: "clippy::mut_range_bound",
5596 description: r##"Checks for loops which have a range bound that is a mutable variable"##,
5597 },
5598 LintCompletion {
5599 label: "clippy::mutable_key_type",
5600 description: r##"Checks for sets/maps with mutable key types."##,
5601 },
5602 LintCompletion {
5603 label: "clippy::mutex_atomic",
5604 description: r##"Checks for usages of `Mutex<X>` where an atomic will do."##,
5605 },
5606 LintCompletion {
5607 label: "clippy::mutex_integer",
5608 description: r##"Checks for usages of `Mutex<X>` where `X` is an integral\ntype."##,
5609 },
5610 LintCompletion {
5611 label: "clippy::naive_bytecount",
5612 description: r##"Checks for naive byte counts"##,
5613 },
5614 LintCompletion {
5615 label: "clippy::needless_arbitrary_self_type",
5616 description: r##"The lint checks for `self` in fn parameters that\nspecify the `Self`-type explicitly"##,
5617 },
5618 LintCompletion {
5619 label: "clippy::needless_bitwise_bool",
5620 description: r##"Checks for uses of bitwise and/or operators between booleans, where performance may be improved by using\na lazy and."##,
5621 },
5622 LintCompletion {
5623 label: "clippy::needless_bool",
5624 description: r##"Checks for expressions of the form `if c { true } else {\nfalse }` (or vice versa) and suggests using the condition directly."##,
5625 },
5626 LintCompletion {
5627 label: "clippy::needless_borrow",
5628 description: r##"Checks for address of operations (`&`) that are going to\nbe dereferenced immediately by the compiler."##,
5629 },
5630 LintCompletion {
5631 label: "clippy::needless_borrowed_reference",
5632 description: r##"Checks for bindings that destructure a reference and borrow the inner\nvalue with `&ref`."##,
5633 },
5634 LintCompletion {
5635 label: "clippy::needless_collect",
5636 description: r##"Checks for functions collecting an iterator when collect\nis not needed."##,
5637 },
5638 LintCompletion {
5639 label: "clippy::needless_continue",
5640 description: r##"The lint checks for `if`-statements appearing in loops\nthat contain a `continue` statement in either their main blocks or their\n`else`-blocks, when omitting the `else`-block possibly with some\nrearrangement of code can make the code easier to understand."##,
5641 },
5642 LintCompletion {
5643 label: "clippy::needless_doctest_main",
5644 description: r##"Checks for `fn main() { .. }` in doctests"##,
5645 },
5646 LintCompletion {
5647 label: "clippy::needless_for_each",
5648 description: r##"Checks for usage of `for_each` that would be more simply written as a\n`for` loop."##,
5649 },
5650 LintCompletion {
5651 label: "clippy::needless_lifetimes",
5652 description: r##"Checks for lifetime annotations which can be removed by\nrelying on lifetime elision."##,
5653 },
5654 LintCompletion {
5655 label: "clippy::needless_pass_by_value",
5656 description: r##"Checks for functions taking arguments by value, but not\nconsuming them in its\nbody."##,
5657 },
5658 LintCompletion {
5659 label: "clippy::needless_question_mark",
5660 description: r##"Suggests alternatives for useless applications of `?` in terminating expressions"##,
5661 },
5662 LintCompletion {
5663 label: "clippy::needless_range_loop",
5664 description: r##"Checks for looping over the range of `0..len` of some\ncollection just to get the values by index."##,
5665 },
5666 LintCompletion {
5667 label: "clippy::needless_return",
5668 description: r##"Checks for return statements at the end of a block."##,
5669 },
5670 LintCompletion {
5671 label: "clippy::needless_update",
5672 description: r##"Checks for needlessly including a base struct on update\nwhen all fields are changed anyway.\n\nThis lint is not applied to structs marked with\n[non_exhaustive](https://doc.rust-lang.org/reference/attributes/type_system.html)."##,
5673 },
5674 LintCompletion {
5675 label: "clippy::neg_cmp_op_on_partial_ord",
5676 description: r##"Checks for the usage of negated comparison operators on types which only implement\n`PartialOrd` (e.g., `f64`)."##,
5677 },
5678 LintCompletion {
5679 label: "clippy::neg_multiply",
5680 description: r##"Checks for multiplication by -1 as a form of negation."##,
5681 },
5682 LintCompletion {
5683 label: "clippy::never_loop",
5684 description: r##"Checks for loops that will always `break`, `return` or\n`continue` an outer loop."##,
5685 },
5686 LintCompletion {
5687 label: "clippy::new_ret_no_self",
5688 description: r##"Checks for `new` not returning a type that contains `Self`."##,
5689 },
5690 LintCompletion {
5691 label: "clippy::new_without_default",
5692 description: r##"Checks for types with a `fn new() -> Self` method and no\nimplementation of\n[`Default`](https://doc.rust-lang.org/std/default/trait.Default.html)."##,
5693 },
5694 LintCompletion {
5695 label: "clippy::no_effect",
5696 description: r##"Checks for statements which have no effect."##,
5697 },
5698 LintCompletion {
5699 label: "clippy::non_ascii_literal",
5700 description: r##"Checks for non-ASCII characters in string literals."##,
5701 },
5702 LintCompletion {
5703 label: "clippy::non_octal_unix_permissions",
5704 description: r##"Checks for non-octal values used to set Unix file permissions."##,
5705 },
5706 LintCompletion {
5707 label: "clippy::nonminimal_bool",
5708 description: r##"Checks for boolean expressions that can be written more\nconcisely."##,
5709 },
5710 LintCompletion {
5711 label: "clippy::nonsensical_open_options",
5712 description: r##"Checks for duplicate open options as well as combinations\nthat make no sense."##,
5713 },
5714 LintCompletion {
5715 label: "clippy::not_unsafe_ptr_arg_deref",
5716 description: r##"Checks for public functions that dereference raw pointer\narguments but are not marked `unsafe`."##,
5717 },
5718 LintCompletion {
5719 label: "clippy::ok_expect",
5720 description: r##"Checks for usage of `ok().expect(..)`."##,
5721 },
5722 LintCompletion {
5723 label: "clippy::op_ref",
5724 description: r##"Checks for arguments to `==` which have their address\ntaken to satisfy a bound\nand suggests to dereference the other argument instead"##,
5725 },
5726 LintCompletion {
5727 label: "clippy::option_as_ref_deref",
5728 description: r##"Checks for usage of `_.as_ref().map(Deref::deref)` or it's aliases (such as String::as_str)."##,
5729 },
5730 LintCompletion {
5731 label: "clippy::option_env_unwrap",
5732 description: r##"Checks for usage of `option_env!(...).unwrap()` and\nsuggests usage of the `env!` macro."##,
5733 },
5734 LintCompletion {
5735 label: "clippy::option_filter_map",
5736 description: r##"Checks for indirect collection of populated `Option`"##,
5737 },
5738 LintCompletion {
5739 label: "clippy::option_if_let_else",
5740 description: r##"Lints usage of `if let Some(v) = ... { y } else { x }` which is more\nidiomatically done with `Option::map_or` (if the else bit is a pure\nexpression) or `Option::map_or_else` (if the else bit is an impure\nexpression)."##,
5741 },
5742 LintCompletion {
5743 label: "clippy::option_map_or_none",
5744 description: r##"Checks for usage of `_.map_or(None, _)`."##,
5745 },
5746 LintCompletion {
5747 label: "clippy::option_map_unit_fn",
5748 description: r##"Checks for usage of `option.map(f)` where f is a function\nor closure that returns the unit type `()`."##,
5749 },
5750 LintCompletion {
5751 label: "clippy::option_option",
5752 description: r##"Checks for use of `Option<Option<_>>` in function signatures and type\ndefinitions"##,
5753 },
5754 LintCompletion {
5755 label: "clippy::or_fun_call",
5756 description: r##"Checks for calls to `.or(foo(..))`, `.unwrap_or(foo(..))`,\netc., and suggests to use `or_else`, `unwrap_or_else`, etc., or\n`unwrap_or_default` instead."##,
5757 },
5758 LintCompletion {
5759 label: "clippy::out_of_bounds_indexing",
5760 description: r##"Checks for out of bounds array indexing with a constant\nindex."##,
5761 },
5762 LintCompletion {
5763 label: "clippy::overflow_check_conditional",
5764 description: r##"Detects classic underflow/overflow checks."##,
5765 },
5766 LintCompletion { label: "clippy::panic", description: r##"Checks for usage of `panic!`."## },
5767 LintCompletion {
5768 label: "clippy::panic_in_result_fn",
5769 description: r##"Checks for usage of `panic!`, `unimplemented!`, `todo!`, `unreachable!` or assertions in a function of type result."##,
5770 },
5771 LintCompletion {
5772 label: "clippy::panicking_unwrap",
5773 description: r##"Checks for calls of `unwrap[_err]()` that will always fail."##,
5774 },
5775 LintCompletion {
5776 label: "clippy::partialeq_ne_impl",
5777 description: r##"Checks for manual re-implementations of `PartialEq::ne`."##,
5778 },
5779 LintCompletion {
5780 label: "clippy::path_buf_push_overwrite",
5781 description: r##"* Checks for [push](https://doc.rust-lang.org/std/path/struct.PathBuf.html#method.push)\ncalls on `PathBuf` that can cause overwrites."##,
5782 },
5783 LintCompletion {
5784 label: "clippy::pattern_type_mismatch",
5785 description: r##"Checks for patterns that aren't exact representations of the types\nthey are applied to.\n\nTo satisfy this lint, you will have to adjust either the expression that is matched\nagainst or the pattern itself, as well as the bindings that are introduced by the\nadjusted patterns. For matching you will have to either dereference the expression\nwith the `*` operator, or amend the patterns to explicitly match against `&<pattern>`\nor `&mut <pattern>` depending on the reference mutability. For the bindings you need\nto use the inverse. You can leave them as plain bindings if you wish for the value\nto be copied, but you must use `ref mut <variable>` or `ref <variable>` to construct\na reference into the matched structure.\n\nIf you are looking for a way to learn about ownership semantics in more detail, it\nis recommended to look at IDE options available to you to highlight types, lifetimes\nand reference semantics in your code. The available tooling would expose these things\nin a general way even outside of the various pattern matching mechanics. Of course\nthis lint can still be used to highlight areas of interest and ensure a good understanding\nof ownership semantics."##,
5786 },
5787 LintCompletion {
5788 label: "clippy::possible_missing_comma",
5789 description: r##"Checks for possible missing comma in an array. It lints if\nan array element is a binary operator expression and it lies on two lines."##,
5790 },
5791 LintCompletion {
5792 label: "clippy::precedence",
5793 description: r##"Checks for operations where precedence may be unclear\nand suggests to add parentheses. Currently it catches the following:\n* mixed usage of arithmetic and bit shifting/combining operators without\nparentheses\n* a \"negative\" numeric literal (which is really a unary `-` followed by a\nnumeric literal)\n followed by a method call"##,
5794 },
5795 LintCompletion {
5796 label: "clippy::print_literal",
5797 description: r##"This lint warns about the use of literals as `print!`/`println!` args."##,
5798 },
5799 LintCompletion {
5800 label: "clippy::print_stderr",
5801 description: r##"Checks for printing on *stderr*. The purpose of this lint\nis to catch debugging remnants."##,
5802 },
5803 LintCompletion {
5804 label: "clippy::print_stdout",
5805 description: r##"Checks for printing on *stdout*. The purpose of this lint\nis to catch debugging remnants."##,
5806 },
5807 LintCompletion {
5808 label: "clippy::print_with_newline",
5809 description: r##"This lint warns when you use `print!()` with a format\nstring that ends in a newline."##,
5810 },
5811 LintCompletion {
5812 label: "clippy::println_empty_string",
5813 description: r##"This lint warns when you use `println!(\"\")` to\nprint a newline."##,
5814 },
5815 LintCompletion {
5816 label: "clippy::ptr_arg",
5817 description: r##"This lint checks for function arguments of type `&String`\nor `&Vec` unless the references are mutable. It will also suggest you\nreplace `.clone()` calls with the appropriate `.to_owned()`/`to_string()`\ncalls."##,
5818 },
5819 LintCompletion {
5820 label: "clippy::ptr_as_ptr",
5821 description: r##"Checks for `as` casts between raw pointers without changing its mutability,\nnamely `*const T` to `*const U` and `*mut T` to `*mut U`."##,
5822 },
5823 LintCompletion {
5824 label: "clippy::ptr_eq",
5825 description: r##"Use `std::ptr::eq` when applicable"##,
5826 },
5827 LintCompletion {
5828 label: "clippy::ptr_offset_with_cast",
5829 description: r##"Checks for usage of the `offset` pointer method with a `usize` casted to an\n`isize`."##,
5830 },
5831 LintCompletion {
5832 label: "clippy::pub_enum_variant_names",
5833 description: r##"Nothing. This lint has been deprecated."##,
5834 },
5835 LintCompletion {
5836 label: "clippy::question_mark",
5837 description: r##"Checks for expressions that could be replaced by the question mark operator."##,
5838 },
5839 LintCompletion {
5840 label: "clippy::range_minus_one",
5841 description: r##"Checks for inclusive ranges where 1 is subtracted from\nthe upper bound, e.g., `x..=(y-1)`."##,
5842 },
5843 LintCompletion {
5844 label: "clippy::range_plus_one",
5845 description: r##"Checks for exclusive ranges where 1 is added to the\nupper bound, e.g., `x..(y+1)`."##,
5846 },
5847 LintCompletion {
5848 label: "clippy::range_step_by_zero",
5849 description: r##"Nothing. This lint has been deprecated."##,
5850 },
5851 LintCompletion {
5852 label: "clippy::range_zip_with_len",
5853 description: r##"Checks for zipping a collection with the range of\n`0.._.len()`."##,
5854 },
5855 LintCompletion {
5856 label: "clippy::rc_buffer",
5857 description: r##"Checks for `Rc<T>` and `Arc<T>` when `T` is a mutable buffer type such as `String` or `Vec`."##,
5858 },
5859 LintCompletion {
5860 label: "clippy::redundant_allocation",
5861 description: r##"Checks for use of redundant allocations anywhere in the code."##,
5862 },
5863 LintCompletion {
5864 label: "clippy::redundant_clone",
5865 description: r##"Checks for a redundant `clone()` (and its relatives) which clones an owned\nvalue that is going to be dropped without further use."##,
5866 },
5867 LintCompletion {
5868 label: "clippy::redundant_closure",
5869 description: r##"Checks for closures which just call another function where\nthe function can be called directly. `unsafe` functions or calls where types\nget adjusted are ignored."##,
5870 },
5871 LintCompletion {
5872 label: "clippy::redundant_closure_call",
5873 description: r##"Detects closures called in the same expression where they\nare defined."##,
5874 },
5875 LintCompletion {
5876 label: "clippy::redundant_closure_for_method_calls",
5877 description: r##"Checks for closures which only invoke a method on the closure\nargument and can be replaced by referencing the method directly."##,
5878 },
5879 LintCompletion {
5880 label: "clippy::redundant_else",
5881 description: r##"Checks for `else` blocks that can be removed without changing semantics."##,
5882 },
5883 LintCompletion {
5884 label: "clippy::redundant_field_names",
5885 description: r##"Checks for fields in struct literals where shorthands\ncould be used."##,
5886 },
5887 LintCompletion {
5888 label: "clippy::redundant_pattern",
5889 description: r##"Checks for patterns in the form `name @ _`."##,
5890 },
5891 LintCompletion {
5892 label: "clippy::redundant_pattern_matching",
5893 description: r##"Lint for redundant pattern matching over `Result`, `Option`,\n`std::task::Poll` or `std::net::IpAddr`"##,
5894 },
5895 LintCompletion {
5896 label: "clippy::redundant_pub_crate",
5897 description: r##"Checks for items declared `pub(crate)` that are not crate visible because they\nare inside a private module."##,
5898 },
5899 LintCompletion {
5900 label: "clippy::redundant_slicing",
5901 description: r##"Checks for redundant slicing expressions which use the full range, and\ndo not change the type."##,
5902 },
5903 LintCompletion {
5904 label: "clippy::redundant_static_lifetimes",
5905 description: r##"Checks for constants and statics with an explicit `'static` lifetime."##,
5906 },
5907 LintCompletion {
5908 label: "clippy::ref_binding_to_reference",
5909 description: r##"Checks for `ref` bindings which create a reference to a reference."##,
5910 },
5911 LintCompletion {
5912 label: "clippy::ref_in_deref",
5913 description: r##"Checks for references in expressions that use\nauto dereference."##,
5914 },
5915 LintCompletion {
5916 label: "clippy::ref_option_ref",
5917 description: r##"Checks for usage of `&Option<&T>`."##,
5918 },
5919 LintCompletion {
5920 label: "clippy::regex_macro",
5921 description: r##"Nothing. This lint has been deprecated."##,
5922 },
5923 LintCompletion {
5924 label: "clippy::repeat_once",
5925 description: r##"Checks for usage of `.repeat(1)` and suggest the following method for each types.\n- `.to_string()` for `str`\n- `.clone()` for `String`\n- `.to_vec()` for `slice`"##,
5926 },
5927 LintCompletion {
5928 label: "clippy::replace_consts",
5929 description: r##"Nothing. This lint has been deprecated."##,
5930 },
5931 LintCompletion {
5932 label: "clippy::rest_pat_in_fully_bound_structs",
5933 description: r##"Checks for unnecessary '..' pattern binding on struct when all fields are explicitly matched."##,
5934 },
5935 LintCompletion {
5936 label: "clippy::result_map_or_into_option",
5937 description: r##"Checks for usage of `_.map_or(None, Some)`."##,
5938 },
5939 LintCompletion {
5940 label: "clippy::result_map_unit_fn",
5941 description: r##"Checks for usage of `result.map(f)` where f is a function\nor closure that returns the unit type `()`."##,
5942 },
5943 LintCompletion {
5944 label: "clippy::result_unit_err",
5945 description: r##"Checks for public functions that return a `Result`\nwith an `Err` type of `()`. It suggests using a custom type that\nimplements `std::error::Error`."##,
5946 },
5947 LintCompletion {
5948 label: "clippy::reversed_empty_ranges",
5949 description: r##"Checks for range expressions `x..y` where both `x` and `y`\nare constant and `x` is greater or equal to `y`."##,
5950 },
5951 LintCompletion {
5952 label: "clippy::same_functions_in_if_condition",
5953 description: r##"Checks for consecutive `if`s with the same function call."##,
5954 },
5955 LintCompletion {
5956 label: "clippy::same_item_push",
5957 description: r##"Checks whether a for loop is being used to push a constant\nvalue into a Vec."##,
5958 },
5959 LintCompletion {
5960 label: "clippy::search_is_some",
5961 description: r##"Checks for an iterator or string search (such as `find()`,\n`position()`, or `rposition()`) followed by a call to `is_some()` or `is_none()`."##,
5962 },
5963 LintCompletion {
5964 label: "clippy::self_assignment",
5965 description: r##"Checks for explicit self-assignments."##,
5966 },
5967 LintCompletion {
5968 label: "clippy::semicolon_if_nothing_returned",
5969 description: r##"Looks for blocks of expressions and fires if the last expression returns\n`()` but is not followed by a semicolon."##,
5970 },
5971 LintCompletion {
5972 label: "clippy::serde_api_misuse",
5973 description: r##"Checks for mis-uses of the serde API."##,
5974 },
5975 LintCompletion {
5976 label: "clippy::shadow_reuse",
5977 description: r##"Checks for bindings that shadow other bindings already in\nscope, while reusing the original value."##,
5978 },
5979 LintCompletion {
5980 label: "clippy::shadow_same",
5981 description: r##"Checks for bindings that shadow other bindings already in\nscope, while just changing reference level or mutability."##,
5982 },
5983 LintCompletion {
5984 label: "clippy::shadow_unrelated",
5985 description: r##"Checks for bindings that shadow other bindings already in\nscope, either without a initialization or with one that does not even use\nthe original value."##,
5986 },
5987 LintCompletion {
5988 label: "clippy::short_circuit_statement",
5989 description: r##"Checks for the use of short circuit boolean conditions as\na\nstatement."##,
5990 },
5991 LintCompletion {
5992 label: "clippy::should_assert_eq",
5993 description: r##"Nothing. This lint has been deprecated."##,
5994 },
5995 LintCompletion {
5996 label: "clippy::should_implement_trait",
5997 description: r##"Checks for methods that should live in a trait\nimplementation of a `std` trait (see [llogiq's blog\npost](http://llogiq.github.io/2015/07/30/traits.html) for further\ninformation) instead of an inherent implementation."##,
5998 },
5999 LintCompletion {
6000 label: "clippy::similar_names",
6001 description: r##"Checks for names that are very similar and thus confusing."##,
6002 },
6003 LintCompletion {
6004 label: "clippy::single_char_add_str",
6005 description: r##"Warns when using `push_str`/`insert_str` with a single-character string literal\nwhere `push`/`insert` with a `char` would work fine."##,
6006 },
6007 LintCompletion {
6008 label: "clippy::single_char_pattern",
6009 description: r##"Checks for string methods that receive a single-character\n`str` as an argument, e.g., `_.split(\"x\")`."##,
6010 },
6011 LintCompletion {
6012 label: "clippy::single_component_path_imports",
6013 description: r##"Checking for imports with single component use path."##,
6014 },
6015 LintCompletion {
6016 label: "clippy::single_element_loop",
6017 description: r##"Checks whether a for loop has a single element."##,
6018 },
6019 LintCompletion {
6020 label: "clippy::single_match",
6021 description: r##"Checks for matches with a single arm where an `if let`\nwill usually suffice."##,
6022 },
6023 LintCompletion {
6024 label: "clippy::single_match_else",
6025 description: r##"Checks for matches with two arms where an `if let else` will\nusually suffice."##,
6026 },
6027 LintCompletion {
6028 label: "clippy::size_of_in_element_count",
6029 description: r##"Detects expressions where\n`size_of::<T>` or `size_of_val::<T>` is used as a\ncount of elements of type `T`"##,
6030 },
6031 LintCompletion {
6032 label: "clippy::skip_while_next",
6033 description: r##"Checks for usage of `_.skip_while(condition).next()`."##,
6034 },
6035 LintCompletion {
6036 label: "clippy::slow_vector_initialization",
6037 description: r##"Checks slow zero-filled vector initialization"##,
6038 },
6039 LintCompletion {
6040 label: "clippy::stable_sort_primitive",
6041 description: r##"When sorting primitive values (integers, bools, chars, as well\nas arrays, slices, and tuples of such items), it is better to\nuse an unstable sort than a stable sort."##,
6042 },
6043 LintCompletion {
6044 label: "clippy::str_to_string",
6045 description: r##"This lint checks for `.to_string()` method calls on values of type `&str`."##,
6046 },
6047 LintCompletion {
6048 label: "clippy::string_add",
6049 description: r##"Checks for all instances of `x + _` where `x` is of type\n`String`, but only if [`string_add_assign`](#string_add_assign) does *not*\nmatch."##,
6050 },
6051 LintCompletion {
6052 label: "clippy::string_add_assign",
6053 description: r##"Checks for string appends of the form `x = x + y` (without\n`let`!)."##,
6054 },
6055 LintCompletion {
6056 label: "clippy::string_extend_chars",
6057 description: r##"Checks for the use of `.extend(s.chars())` where s is a\n`&str` or `String`."##,
6058 },
6059 LintCompletion {
6060 label: "clippy::string_from_utf8_as_bytes",
6061 description: r##"Check if the string is transformed to byte array and casted back to string."##,
6062 },
6063 LintCompletion {
6064 label: "clippy::string_lit_as_bytes",
6065 description: r##"Checks for the `as_bytes` method called on string literals\nthat contain only ASCII characters."##,
6066 },
6067 LintCompletion {
6068 label: "clippy::string_to_string",
6069 description: r##"This lint checks for `.to_string()` method calls on values of type `String`."##,
6070 },
6071 LintCompletion {
6072 label: "clippy::struct_excessive_bools",
6073 description: r##"Checks for excessive\nuse of bools in structs."##,
6074 },
6075 LintCompletion {
6076 label: "clippy::suboptimal_flops",
6077 description: r##"Looks for floating-point expressions that\ncan be expressed using built-in methods to improve both\naccuracy and performance."##,
6078 },
6079 LintCompletion {
6080 label: "clippy::suspicious_arithmetic_impl",
6081 description: r##"Lints for suspicious operations in impls of arithmetic operators, e.g.\nsubtracting elements in an Add impl."##,
6082 },
6083 LintCompletion {
6084 label: "clippy::suspicious_assignment_formatting",
6085 description: r##"Checks for use of the non-existent `=*`, `=!` and `=-`\noperators."##,
6086 },
6087 LintCompletion {
6088 label: "clippy::suspicious_else_formatting",
6089 description: r##"Checks for formatting of `else`. It lints if the `else`\nis followed immediately by a newline or the `else` seems to be missing."##,
6090 },
6091 LintCompletion {
6092 label: "clippy::suspicious_map",
6093 description: r##"Checks for calls to `map` followed by a `count`."##,
6094 },
6095 LintCompletion {
6096 label: "clippy::suspicious_op_assign_impl",
6097 description: r##"Lints for suspicious operations in impls of OpAssign, e.g.\nsubtracting elements in an AddAssign impl."##,
6098 },
6099 LintCompletion {
6100 label: "clippy::suspicious_operation_groupings",
6101 description: r##"Checks for unlikely usages of binary operators that are almost\ncertainly typos and/or copy/paste errors, given the other usages\nof binary operators nearby."##,
6102 },
6103 LintCompletion {
6104 label: "clippy::suspicious_splitn",
6105 description: r##"Checks for calls to [`splitn`]\n(https://doc.rust-lang.org/std/primitive.str.html#method.splitn) and\nrelated functions with either zero or one splits."##,
6106 },
6107 LintCompletion {
6108 label: "clippy::suspicious_unary_op_formatting",
6109 description: r##"Checks the formatting of a unary operator on the right hand side\nof a binary operator. It lints if there is no space between the binary and unary operators,\nbut there is a space between the unary and its operand."##,
6110 },
6111 LintCompletion {
6112 label: "clippy::tabs_in_doc_comments",
6113 description: r##"Checks doc comments for usage of tab characters."##,
6114 },
6115 LintCompletion {
6116 label: "clippy::temporary_assignment",
6117 description: r##"Checks for construction of a structure or tuple just to\nassign a value in it."##,
6118 },
6119 LintCompletion {
6120 label: "clippy::to_digit_is_some",
6121 description: r##"Checks for `.to_digit(..).is_some()` on `char`s."##,
6122 },
6123 LintCompletion {
6124 label: "clippy::to_string_in_display",
6125 description: r##"Checks for uses of `to_string()` in `Display` traits."##,
6126 },
6127 LintCompletion { label: "clippy::todo", description: r##"Checks for usage of `todo!`."## },
6128 LintCompletion {
6129 label: "clippy::too_many_arguments",
6130 description: r##"Checks for functions with too many parameters."##,
6131 },
6132 LintCompletion {
6133 label: "clippy::too_many_lines",
6134 description: r##"Checks for functions with a large amount of lines."##,
6135 },
6136 LintCompletion {
6137 label: "clippy::toplevel_ref_arg",
6138 description: r##"Checks for function arguments and let bindings denoted as\n`ref`."##,
6139 },
6140 LintCompletion {
6141 label: "clippy::trait_duplication_in_bounds",
6142 description: r##"Checks for cases where generics are being used and multiple\nsyntax specifications for trait bounds are used simultaneously."##,
6143 },
6144 LintCompletion {
6145 label: "clippy::transmute_bytes_to_str",
6146 description: r##"Checks for transmutes from a `&[u8]` to a `&str`."##,
6147 },
6148 LintCompletion {
6149 label: "clippy::transmute_float_to_int",
6150 description: r##"Checks for transmutes from a float to an integer."##,
6151 },
6152 LintCompletion {
6153 label: "clippy::transmute_int_to_bool",
6154 description: r##"Checks for transmutes from an integer to a `bool`."##,
6155 },
6156 LintCompletion {
6157 label: "clippy::transmute_int_to_char",
6158 description: r##"Checks for transmutes from an integer to a `char`."##,
6159 },
6160 LintCompletion {
6161 label: "clippy::transmute_int_to_float",
6162 description: r##"Checks for transmutes from an integer to a float."##,
6163 },
6164 LintCompletion {
6165 label: "clippy::transmute_ptr_to_ptr",
6166 description: r##"Checks for transmutes from a pointer to a pointer, or\nfrom a reference to a reference."##,
6167 },
6168 LintCompletion {
6169 label: "clippy::transmute_ptr_to_ref",
6170 description: r##"Checks for transmutes from a pointer to a reference."##,
6171 },
6172 LintCompletion {
6173 label: "clippy::transmutes_expressible_as_ptr_casts",
6174 description: r##"Checks for transmutes that could be a pointer cast."##,
6175 },
6176 LintCompletion {
6177 label: "clippy::transmuting_null",
6178 description: r##"Checks for transmute calls which would receive a null pointer."##,
6179 },
6180 LintCompletion {
6181 label: "clippy::trivial_regex",
6182 description: r##"Checks for trivial [regex](https://crates.io/crates/regex)\ncreation (with `Regex::new`, `RegexBuilder::new`, or `RegexSet::new`)."##,
6183 },
6184 LintCompletion {
6185 label: "clippy::trivially_copy_pass_by_ref",
6186 description: r##"Checks for functions taking arguments by reference, where\nthe argument type is `Copy` and small enough to be more efficient to always\npass by value."##,
6187 },
6188 LintCompletion {
6189 label: "clippy::try_err",
6190 description: r##"Checks for usages of `Err(x)?`."##,
6191 },
6192 LintCompletion {
6193 label: "clippy::type_complexity",
6194 description: r##"Checks for types used in structs, parameters and `let`\ndeclarations above a certain complexity threshold."##,
6195 },
6196 LintCompletion {
6197 label: "clippy::type_repetition_in_bounds",
6198 description: r##"This lint warns about unnecessary type repetitions in trait bounds"##,
6199 },
6200 LintCompletion {
6201 label: "clippy::undropped_manually_drops",
6202 description: r##"Prevents the safe `std::mem::drop` function from being called on `std::mem::ManuallyDrop`."##,
6203 },
6204 LintCompletion {
6205 label: "clippy::unicode_not_nfc",
6206 description: r##"Checks for string literals that contain Unicode in a form\nthat is not equal to its\n[NFC-recomposition](http://www.unicode.org/reports/tr15/#Norm_Forms)."##,
6207 },
6208 LintCompletion {
6209 label: "clippy::unimplemented",
6210 description: r##"Checks for usage of `unimplemented!`."##,
6211 },
6212 LintCompletion {
6213 label: "clippy::uninit_assumed_init",
6214 description: r##"Checks for `MaybeUninit::uninit().assume_init()`."##,
6215 },
6216 LintCompletion {
6217 label: "clippy::unit_arg",
6218 description: r##"Checks for passing a unit value as an argument to a function without using a\nunit literal (`()`)."##,
6219 },
6220 LintCompletion {
6221 label: "clippy::unit_cmp",
6222 description: r##"Checks for comparisons to unit. This includes all binary\ncomparisons (like `==` and `<`) and asserts."##,
6223 },
6224 LintCompletion {
6225 label: "clippy::unit_return_expecting_ord",
6226 description: r##"Checks for functions that expect closures of type\nFn(...) -> Ord where the implemented closure returns the unit type.\nThe lint also suggests to remove the semi-colon at the end of the statement if present."##,
6227 },
6228 LintCompletion {
6229 label: "clippy::unnecessary_cast",
6230 description: r##"Checks for casts to the same type, casts of int literals to integer types\nand casts of float literals to float types."##,
6231 },
6232 LintCompletion {
6233 label: "clippy::unnecessary_filter_map",
6234 description: r##"Checks for `filter_map` calls which could be replaced by `filter` or `map`.\nMore specifically it checks if the closure provided is only performing one of the\nfilter or map operations and suggests the appropriate option."##,
6235 },
6236 LintCompletion {
6237 label: "clippy::unnecessary_fold",
6238 description: r##"Checks for using `fold` when a more succinct alternative exists.\nSpecifically, this checks for `fold`s which could be replaced by `any`, `all`,\n`sum` or `product`."##,
6239 },
6240 LintCompletion {
6241 label: "clippy::unnecessary_lazy_evaluations",
6242 description: r##"As the counterpart to `or_fun_call`, this lint looks for unnecessary\nlazily evaluated closures on `Option` and `Result`.\n\nThis lint suggests changing the following functions, when eager evaluation results in\nsimpler code:\n - `unwrap_or_else` to `unwrap_or`\n - `and_then` to `and`\n - `or_else` to `or`\n - `get_or_insert_with` to `get_or_insert`\n - `ok_or_else` to `ok_or`"##,
6243 },
6244 LintCompletion {
6245 label: "clippy::unnecessary_mut_passed",
6246 description: r##"Detects passing a mutable reference to a function that only\nrequires an immutable reference."##,
6247 },
6248 LintCompletion {
6249 label: "clippy::unnecessary_operation",
6250 description: r##"Checks for expression statements that can be reduced to a\nsub-expression."##,
6251 },
6252 LintCompletion {
6253 label: "clippy::unnecessary_self_imports",
6254 description: r##"Checks for imports ending in `::{self}`."##,
6255 },
6256 LintCompletion {
6257 label: "clippy::unnecessary_sort_by",
6258 description: r##"Detects uses of `Vec::sort_by` passing in a closure\nwhich compares the two arguments, either directly or indirectly."##,
6259 },
6260 LintCompletion {
6261 label: "clippy::unnecessary_unwrap",
6262 description: r##"Checks for calls of `unwrap[_err]()` that cannot fail."##,
6263 },
6264 LintCompletion {
6265 label: "clippy::unnecessary_wraps",
6266 description: r##"Checks for private functions that only return `Ok` or `Some`."##,
6267 },
6268 LintCompletion {
6269 label: "clippy::unneeded_field_pattern",
6270 description: r##"Checks for structure field patterns bound to wildcards."##,
6271 },
6272 LintCompletion {
6273 label: "clippy::unneeded_wildcard_pattern",
6274 description: r##"Checks for tuple patterns with a wildcard\npattern (`_`) is next to a rest pattern (`..`).\n\n_NOTE_: While `_, ..` means there is at least one element left, `..`\nmeans there are 0 or more elements left. This can make a difference\nwhen refactoring, but shouldn't result in errors in the refactored code,\nsince the wildcard pattern isn't used anyway."##,
6275 },
6276 LintCompletion {
6277 label: "clippy::unnested_or_patterns",
6278 description: r##"Checks for unnested or-patterns, e.g., `Some(0) | Some(2)` and\nsuggests replacing the pattern with a nested one, `Some(0 | 2)`.\n\nAnother way to think of this is that it rewrites patterns in\n*disjunctive normal form (DNF)* into *conjunctive normal form (CNF)*."##,
6279 },
6280 LintCompletion {
6281 label: "clippy::unreachable",
6282 description: r##"Checks for usage of `unreachable!`."##,
6283 },
6284 LintCompletion {
6285 label: "clippy::unreadable_literal",
6286 description: r##"Warns if a long integral or floating-point constant does\nnot contain underscores."##,
6287 },
6288 LintCompletion {
6289 label: "clippy::unsafe_derive_deserialize",
6290 description: r##"Checks for deriving `serde::Deserialize` on a type that\nhas methods using `unsafe`."##,
6291 },
6292 LintCompletion {
6293 label: "clippy::unsafe_removed_from_name",
6294 description: r##"Checks for imports that remove \"unsafe\" from an item's\nname."##,
6295 },
6296 LintCompletion {
6297 label: "clippy::unsafe_vector_initialization",
6298 description: r##"Nothing. This lint has been deprecated."##,
6299 },
6300 LintCompletion {
6301 label: "clippy::unseparated_literal_suffix",
6302 description: r##"Warns if literal suffixes are not separated by an\nunderscore."##,
6303 },
6304 LintCompletion {
6305 label: "clippy::unsound_collection_transmute",
6306 description: r##"Checks for transmutes between collections whose\ntypes have different ABI, size or alignment."##,
6307 },
6308 LintCompletion {
6309 label: "clippy::unstable_as_mut_slice",
6310 description: r##"Nothing. This lint has been deprecated."##,
6311 },
6312 LintCompletion {
6313 label: "clippy::unstable_as_slice",
6314 description: r##"Nothing. This lint has been deprecated."##,
6315 },
6316 LintCompletion {
6317 label: "clippy::unused_async",
6318 description: r##"Checks for functions that are declared `async` but have no `.await`s inside of them."##,
6319 },
6320 LintCompletion {
6321 label: "clippy::unused_collect",
6322 description: r##"Nothing. This lint has been deprecated."##,
6323 },
6324 LintCompletion {
6325 label: "clippy::unused_io_amount",
6326 description: r##"Checks for unused written/read amount."##,
6327 },
6328 LintCompletion {
6329 label: "clippy::unused_self",
6330 description: r##"Checks methods that contain a `self` argument but don't use it"##,
6331 },
6332 LintCompletion {
6333 label: "clippy::unused_unit",
6334 description: r##"Checks for unit (`()`) expressions that can be removed."##,
6335 },
6336 LintCompletion {
6337 label: "clippy::unusual_byte_groupings",
6338 description: r##"Warns if hexadecimal or binary literals are not grouped\nby nibble or byte."##,
6339 },
6340 LintCompletion {
6341 label: "clippy::unwrap_in_result",
6342 description: r##"Checks for functions of type Result that contain `expect()` or `unwrap()`"##,
6343 },
6344 LintCompletion {
6345 label: "clippy::unwrap_used",
6346 description: r##"Checks for `.unwrap()` calls on `Option`s and on `Result`s."##,
6347 },
6348 LintCompletion {
6349 label: "clippy::upper_case_acronyms",
6350 description: r##"Checks for fully capitalized names and optionally names containing a capitalized acronym."##,
6351 },
6352 LintCompletion {
6353 label: "clippy::use_debug",
6354 description: r##"Checks for use of `Debug` formatting. The purpose of this\nlint is to catch debugging remnants."##,
6355 },
6356 LintCompletion {
6357 label: "clippy::use_self",
6358 description: r##"Checks for unnecessary repetition of structure name when a\nreplacement with `Self` is applicable."##,
6359 },
6360 LintCompletion {
6361 label: "clippy::used_underscore_binding",
6362 description: r##"Checks for the use of bindings with a single leading\nunderscore."##,
6363 },
6364 LintCompletion {
6365 label: "clippy::useless_asref",
6366 description: r##"Checks for usage of `.as_ref()` or `.as_mut()` where the\ntypes before and after the call are the same."##,
6367 },
6368 LintCompletion {
6369 label: "clippy::useless_attribute",
6370 description: r##"Checks for `extern crate` and `use` items annotated with\nlint attributes.\n\nThis lint permits `#[allow(unused_imports)]`, `#[allow(deprecated)]`,\n`#[allow(unreachable_pub)]`, `#[allow(clippy::wildcard_imports)]` and\n`#[allow(clippy::enum_glob_use)]` on `use` items and `#[allow(unused_imports)]` on\n`extern crate` items with a `#[macro_use]` attribute."##,
6371 },
6372 LintCompletion {
6373 label: "clippy::useless_conversion",
6374 description: r##"Checks for `Into`, `TryInto`, `From`, `TryFrom`, or `IntoIter` calls\nwhich uselessly convert to the same type."##,
6375 },
6376 LintCompletion {
6377 label: "clippy::useless_format",
6378 description: r##"Checks for the use of `format!(\"string literal with no\nargument\")` and `format!(\"{}\", foo)` where `foo` is a string."##,
6379 },
6380 LintCompletion {
6381 label: "clippy::useless_let_if_seq",
6382 description: r##"Checks for variable declarations immediately followed by a\nconditional affectation."##,
6383 },
6384 LintCompletion {
6385 label: "clippy::useless_transmute",
6386 description: r##"Checks for transmutes to the original type of the object\nand transmutes that could be a cast."##,
6387 },
6388 LintCompletion {
6389 label: "clippy::useless_vec",
6390 description: r##"Checks for usage of `&vec![..]` when using `&[..]` would\nbe possible."##,
6391 },
6392 LintCompletion {
6393 label: "clippy::vec_box",
6394 description: r##"Checks for use of `Vec<Box<T>>` where T: Sized anywhere in the code.\nCheck the [Box documentation](https://doc.rust-lang.org/std/boxed/index.html) for more information."##,
6395 },
6396 LintCompletion {
6397 label: "clippy::vec_init_then_push",
6398 description: r##"Checks for calls to `push` immediately after creating a new `Vec`."##,
6399 },
6400 LintCompletion {
6401 label: "clippy::vec_resize_to_zero",
6402 description: r##"Finds occurrences of `Vec::resize(0, an_int)`"##,
6403 },
6404 LintCompletion {
6405 label: "clippy::verbose_bit_mask",
6406 description: r##"Checks for bit masks that can be replaced by a call\nto `trailing_zeros`"##,
6407 },
6408 LintCompletion {
6409 label: "clippy::verbose_file_reads",
6410 description: r##"Checks for use of File::read_to_end and File::read_to_string."##,
6411 },
6412 LintCompletion {
6413 label: "clippy::vtable_address_comparisons",
6414 description: r##"Checks for comparisons with an address of a trait vtable."##,
6415 },
6416 LintCompletion {
6417 label: "clippy::while_immutable_condition",
6418 description: r##"Checks whether variables used within while loop condition\ncan be (and are) mutated in the body."##,
6419 },
6420 LintCompletion {
6421 label: "clippy::while_let_loop",
6422 description: r##"Detects `loop + match` combinations that are easier\nwritten as a `while let` loop."##,
6423 },
6424 LintCompletion {
6425 label: "clippy::while_let_on_iterator",
6426 description: r##"Checks for `while let` expressions on iterators."##,
6427 },
6428 LintCompletion {
6429 label: "clippy::wildcard_dependencies",
6430 description: r##"Checks for wildcard dependencies in the `Cargo.toml`."##,
6431 },
6432 LintCompletion {
6433 label: "clippy::wildcard_enum_match_arm",
6434 description: r##"Checks for wildcard enum matches using `_`."##,
6435 },
6436 LintCompletion {
6437 label: "clippy::wildcard_imports",
6438 description: r##"Checks for wildcard imports `use _::*`."##,
6439 },
6440 LintCompletion {
6441 label: "clippy::wildcard_in_or_patterns",
6442 description: r##"Checks for wildcard pattern used with others patterns in same match arm."##,
6443 },
6444 LintCompletion {
6445 label: "clippy::write_literal",
6446 description: r##"This lint warns about the use of literals as `write!`/`writeln!` args."##,
6447 },
6448 LintCompletion {
6449 label: "clippy::write_with_newline",
6450 description: r##"This lint warns when you use `write!()` with a format\nstring that\nends in a newline."##,
6451 },
6452 LintCompletion {
6453 label: "clippy::writeln_empty_string",
6454 description: r##"This lint warns when you use `writeln!(buf, \"\")` to\nprint a newline."##,
6455 },
6456 LintCompletion {
6457 label: "clippy::wrong_pub_self_convention",
6458 description: r##"Nothing. This lint has been deprecated."##,
6459 },
6460 LintCompletion {
6461 label: "clippy::wrong_self_convention",
6462 description: r##"Checks for methods with certain name prefixes and which\ndoesn't match how self is taken. The actual rules are:\n\n|Prefix |Postfix |`self` taken | `self` type |\n|-------|------------|-----------------------|--------------|\n|`as_` | none |`&self` or `&mut self` | any |\n|`from_`| none | none | any |\n|`into_`| none |`self` | any |\n|`is_` | none |`&self` or none | any |\n|`to_` | `_mut` |`&mut self` | any |\n|`to_` | not `_mut` |`self` | `Copy` |\n|`to_` | not `_mut` |`&self` | not `Copy` |\n\nNote: Clippy doesn't trigger methods with `to_` prefix in:\n- Traits definition.\nClippy can not tell if a type that implements a trait is `Copy` or not.\n- Traits implementation, when `&self` is taken.\nThe method signature is controlled by the trait and often `&self` is required for all types that implement the trait\n(see e.g. the `std::string::ToString` trait).\n\nPlease find more info here:\nhttps://rust-lang.github.io/api-guidelines/naming.html#ad-hoc-conversions-follow-as_-to_-into_-conventions-c-conv"##,
6463 },
6464 LintCompletion {
6465 label: "clippy::wrong_transmute",
6466 description: r##"Checks for transmutes that can't ever be correct on any\narchitecture."##,
6467 },
6468 LintCompletion {
6469 label: "clippy::zero_divided_by_zero",
6470 description: r##"Checks for `0.0 / 0.0`."##,
6471 },
6472 LintCompletion {
6473 label: "clippy::zero_prefixed_literal",
6474 description: r##"Warns if an integral constant literal starts with `0`."##,
6475 },
6476 LintCompletion {
6477 label: "clippy::zero_ptr",
6478 description: r##"Catch casts from `0` to some pointer type"##,
6479 },
6480 LintCompletion {
6481 label: "clippy::zero_sized_map_values",
6482 description: r##"Checks for maps with zero-sized value types anywhere in the code."##,
6483 },
6484 LintCompletion {
6485 label: "clippy::zst_offset",
6486 description: r##"Checks for `offset(_)`, `wrapping_`{`add`, `sub`}, etc. on raw pointers to\nzero-sized types"##,
6487 },
6488];
diff --git a/crates/ide_completion/src/lib.rs b/crates/ide_completion/src/lib.rs
index 1f0158745..6fb38f50d 100644
--- a/crates/ide_completion/src/lib.rs
+++ b/crates/ide_completion/src/lib.rs
@@ -10,8 +10,6 @@ mod render;
10 10
11mod completions; 11mod completions;
12 12
13pub mod generated_lint_completions;
14
15use completions::flyimport::position_for_import; 13use completions::flyimport::position_for_import;
16use ide_db::{ 14use ide_db::{
17 base_db::FilePosition, 15 base_db::FilePosition,