aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Wirth <[email protected]>2021-06-04 16:03:18 +0100
committerLukas Wirth <[email protected]>2021-06-04 16:03:18 +0100
commit5d17b6a6873d530eda89d271807dcb70a811a200 (patch)
tree88b06d926b9311a214d937641990395c5af896de
parentcd46255d7e8bb59b93a32d5cb50581f418ca5f3b (diff)
Implement hover for lints
-rw-r--r--crates/ide/src/hover.rs90
-rw-r--r--crates/ide_completion/src/completions/attribute/lint.rs108
-rw-r--r--crates/ide_completion/src/generated_lint_completions.rs5640
-rw-r--r--crates/ide_completion/src/lib.rs3
-rw-r--r--xtask/src/codegen/gen_lint_completions.rs20
5 files changed, 3026 insertions, 2835 deletions
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs
index 04598cd06..4d91c5c4f 100644
--- a/crates/ide/src/hover.rs
+++ b/crates/ide/src/hover.rs
@@ -3,6 +3,7 @@ use hir::{
3 AsAssocItem, AssocItemContainer, GenericParam, HasAttrs, HasSource, HirDisplay, InFile, Module, 3 AsAssocItem, AssocItemContainer, GenericParam, HasAttrs, HasSource, HirDisplay, InFile, Module,
4 ModuleDef, Semantics, 4 ModuleDef, Semantics,
5}; 5};
6use ide_completion::generated_lint_completions::{CLIPPY_LINTS, FEATURES};
6use ide_db::{ 7use ide_db::{
7 base_db::SourceDatabase, 8 base_db::SourceDatabase,
8 defs::{Definition, NameClass, NameRefClass}, 9 defs::{Definition, NameClass, NameRefClass},
@@ -11,7 +12,10 @@ use ide_db::{
11}; 12};
12use itertools::Itertools; 13use itertools::Itertools;
13use stdx::format_to; 14use stdx::format_to;
14use syntax::{ast, match_ast, AstNode, AstToken, SyntaxKind::*, SyntaxToken, TokenAtOffset, T}; 15use syntax::{
16 algo, ast, match_ast, AstNode, AstToken, Direction, SyntaxKind::*, SyntaxToken, TokenAtOffset,
17 T,
18};
15 19
16use crate::{ 20use crate::{
17 display::{macro_label, TryToNav}, 21 display::{macro_label, TryToNav},
@@ -115,8 +119,8 @@ pub(crate) fn hover(
115 |d| d.defined(db), 119 |d| d.defined(db),
116 ), 120 ),
117 121
118 _ => ast::Comment::cast(token.clone()) 122 _ => {
119 .and_then(|_| { 123 if ast::Comment::cast(token.clone()).is_some() {
120 let (attributes, def) = doc_attributes(&sema, &node)?; 124 let (attributes, def) = doc_attributes(&sema, &node)?;
121 let (docs, doc_mapping) = attributes.docs_with_rangemap(db)?; 125 let (docs, doc_mapping) = attributes.docs_with_rangemap(db)?;
122 let (idl_range, link, ns) = 126 let (idl_range, link, ns) =
@@ -129,9 +133,11 @@ pub(crate) fn hover(
129 } 133 }
130 })?; 134 })?;
131 range = Some(idl_range); 135 range = Some(idl_range);
132 resolve_doc_path_for_def(db, def, &link, ns) 136 resolve_doc_path_for_def(db, def, &link, ns).map(Definition::ModuleDef)
133 }) 137 } else {
134 .map(Definition::ModuleDef), 138 return try_hover_for_attribute(&token);
139 }
140 },
135 } 141 }
136 }; 142 };
137 143
@@ -194,6 +200,40 @@ pub(crate) fn hover(
194 Some(RangeInfo::new(range, res)) 200 Some(RangeInfo::new(range, res))
195} 201}
196 202
203fn try_hover_for_attribute(token: &SyntaxToken) -> Option<RangeInfo<HoverResult>> {
204 let attr = token.ancestors().nth(1).and_then(ast::Attr::cast)?;
205 let (path, tt) = attr.as_simple_call()?;
206 if !tt.syntax().text_range().contains(token.text_range().start()) {
207 return None;
208 }
209 let lints = match &*path {
210 "feature" => FEATURES,
211 "allow" | "warn" | "forbid" | "error" => {
212 let is_clippy = algo::skip_trivia_token(token.clone(), Direction::Prev)
213 .filter(|t| t.kind() == T![::])
214 .and_then(|t| algo::skip_trivia_token(t, Direction::Prev))
215 .map_or(false, |t| t.kind() == T![ident] && t.text() == "clippy");
216 if is_clippy {
217 CLIPPY_LINTS
218 } else {
219 &[]
220 }
221 }
222 _ => return None,
223 };
224 let lint = lints
225 .binary_search_by_key(&token.text(), |lint| lint.label)
226 .ok()
227 .map(|idx| &FEATURES[idx])?;
228 Some(RangeInfo::new(
229 token.text_range(),
230 HoverResult {
231 markup: Markup::from(format!("```\n{}\n```\n___\n\n{}", lint.label, lint.description)),
232 ..Default::default()
233 },
234 ))
235}
236
197fn show_implementations_action(db: &RootDatabase, def: Definition) -> Option<HoverAction> { 237fn show_implementations_action(db: &RootDatabase, def: Definition) -> Option<HoverAction> {
198 fn to_action(nav_target: NavigationTarget) -> HoverAction { 238 fn to_action(nav_target: NavigationTarget) -> HoverAction {
199 HoverAction::Implementation(FilePosition { 239 HoverAction::Implementation(FilePosition {
@@ -3977,4 +4017,42 @@ pub fn foo() {}
3977 "#]], 4017 "#]],
3978 ) 4018 )
3979 } 4019 }
4020
4021 #[test]
4022 fn hover_feature() {
4023 check(
4024 r#"#![feature(box_syntax$0)]"#,
4025 expect![[r##"
4026 *box_syntax*
4027 ```
4028 box_syntax
4029 ```
4030 ___
4031
4032 # `box_syntax`
4033
4034 The tracking issue for this feature is: [#49733]
4035
4036 [#49733]: https://github.com/rust-lang/rust/issues/49733
4037
4038 See also [`box_patterns`](box-patterns.md)
4039
4040 ------------------------
4041
4042 Currently the only stable way to create a `Box` is via the `Box::new` method.
4043 Also it is not possible in stable Rust to destructure a `Box` in a match
4044 pattern. The unstable `box` keyword can be used to create a `Box`. An example
4045 usage would be:
4046
4047 ```rust
4048 #![feature(box_syntax)]
4049
4050 fn main() {
4051 let b = box 5;
4052 }
4053 ```
4054
4055 "##]],
4056 )
4057 }
3980} 4058}
diff --git a/crates/ide_completion/src/completions/attribute/lint.rs b/crates/ide_completion/src/completions/attribute/lint.rs
index 403630dce..608e71cec 100644
--- a/crates/ide_completion/src/completions/attribute/lint.rs
+++ b/crates/ide_completion/src/completions/attribute/lint.rs
@@ -29,128 +29,128 @@ pub(super) fn complete_lint(
29 } 29 }
30} 30}
31 31
32pub(crate) struct LintCompletion { 32pub struct LintCompletion {
33 pub(crate) label: &'static str, 33 pub label: &'static str,
34 pub(crate) description: &'static str, 34 pub description: &'static str,
35} 35}
36 36
37#[rustfmt::skip] 37#[rustfmt::skip]
38pub(super) const DEFAULT_LINT_COMPLETIONS: &[LintCompletion] = &[ 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"# }, 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"# },
40 LintCompletion { label: "anonymous_parameters", description: r#"detects anonymous parameters"# }, 41 LintCompletion { label: "anonymous_parameters", description: r#"detects anonymous parameters"# },
41 LintCompletion { label: "box_pointers", description: r#"use of owned (Box type) heap memory"# }, 42 LintCompletion { label: "arithmetic_overflow", description: r#"arithmetic operation overflows"# },
42 LintCompletion { label: "deprecated_in_future", description: r#"detects use of items that will be deprecated in a future version"# },
43 LintCompletion { label: "elided_lifetimes_in_paths", description: r#"hidden lifetime parameters in types are deprecated"# },
44 LintCompletion { label: "explicit_outlives_requirements", description: r#"outlives requirements can be inferred"# },
45 LintCompletion { label: "indirect_structural_match", description: r#"pattern with const indirectly referencing non-structural-match type"# },
46 LintCompletion { label: "keyword_idents", description: r#"detects edition keywords being used as an identifier"# },
47 LintCompletion { label: "macro_use_extern_crate", description: r#"the `#[macro_use]` attribute is now deprecated in favor of using macros via the module system"# },
48 LintCompletion { label: "meta_variable_misuse", description: r#"possible meta-variable misuse at macro definition"# },
49 LintCompletion { label: "missing_copy_implementations", description: r#"detects potentially-forgotten implementations of `Copy`"# },
50 LintCompletion { label: "missing_crate_level_docs", description: r#"detects crates with no crate-level documentation"# },
51 LintCompletion { label: "missing_debug_implementations", description: r#"detects missing implementations of Debug"# },
52 LintCompletion { label: "missing_docs", description: r#"detects missing documentation for public members"# },
53 LintCompletion { label: "missing_doc_code_examples", description: r#"detects publicly-exported items without code samples in their documentation"# },
54 LintCompletion { label: "non_ascii_idents", description: r#"detects non-ASCII identifiers"# },
55 LintCompletion { label: "private_doc_tests", description: r#"detects code samples in docs of private items not documented by rustdoc"# },
56 LintCompletion { label: "single_use_lifetimes", description: r#"detects lifetime parameters that are only used once"# },
57 LintCompletion { label: "trivial_casts", description: r#"detects trivial casts which could be removed"# },
58 LintCompletion { label: "trivial_numeric_casts", description: r#"detects trivial casts of numeric types which could be removed"# },
59 LintCompletion { label: "unaligned_references", description: r#"detects unaligned references to fields of packed structs"# },
60 LintCompletion { label: "unreachable_pub", description: r#"`pub` items not reachable from crate root"# },
61 LintCompletion { label: "unsafe_code", description: r#"usage of `unsafe` code"# },
62 LintCompletion { label: "unsafe_op_in_unsafe_fn", description: r#"unsafe operations in unsafe functions without an explicit unsafe block are deprecated"# },
63 LintCompletion { label: "unstable_features", description: r#"enabling unstable features (deprecated. do not use)"# },
64 LintCompletion { label: "unused_crate_dependencies", description: r#"crate dependencies that are never used"# },
65 LintCompletion { label: "unused_extern_crates", description: r#"extern crates that are never used"# },
66 LintCompletion { label: "unused_import_braces", description: r#"unnecessary braces around an imported item"# },
67 LintCompletion { label: "unused_lifetimes", description: r#"detects lifetime parameters that are never used"# },
68 LintCompletion { label: "unused_qualifications", description: r#"detects unnecessarily qualified names"# },
69 LintCompletion { label: "unused_results", description: r#"unused result of an expression in a statement"# },
70 LintCompletion { label: "variant_size_differences", description: r#"detects enums with widely varying variant sizes"# },
71 LintCompletion { label: "array_into_iter", description: r#"detects calling `into_iter` on arrays"# }, 43 LintCompletion { label: "array_into_iter", description: r#"detects calling `into_iter` on arrays"# },
72 LintCompletion { label: "asm_sub_register", description: r#"using only a subset of a register for inline asm inputs"# }, 44 LintCompletion { label: "asm_sub_register", description: r#"using only a subset of a register for inline asm inputs"# },
73 LintCompletion { label: "bare_trait_objects", description: r#"suggest using `dyn Trait` for trait objects"# }, 45 LintCompletion { label: "bare_trait_objects", description: r#"suggest using `dyn Trait` for trait objects"# },
74 LintCompletion { label: "bindings_with_variant_name", description: r#"detects pattern bindings with the same name as one of the matched variants"# }, 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"# },
75 LintCompletion { label: "cenum_impl_drop_cast", description: r#"a C-like enum implementing Drop is cast"# }, 48 LintCompletion { label: "cenum_impl_drop_cast", description: r#"a C-like enum implementing Drop is cast"# },
76 LintCompletion { label: "clashing_extern_declarations", description: r#"detects when an extern fn has been declared with the same name but different types"# }, 49 LintCompletion { label: "clashing_extern_declarations", description: r#"detects when an extern fn has been declared with the same name but different types"# },
77 LintCompletion { label: "coherence_leak_check", description: r#"distinct impls distinguished only by the leak-check code"# }, 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"# },
78 LintCompletion { label: "confusable_idents", description: r#"detects visually confusable pairs between identifiers"# }, 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"# },
79 LintCompletion { label: "dead_code", description: r#"detect unused, unexported items"# }, 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"# },
80 LintCompletion { label: "deprecated", description: r#"detects use of deprecated items"# }, 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"# },
81 LintCompletion { label: "ellipsis_inclusive_range_patterns", description: r#"`...` range patterns 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"# },
82 LintCompletion { label: "exported_private_dependencies", description: r#"public interface leaks type from a private dependency"# }, 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"# },
83 LintCompletion { label: "illegal_floating_point_literal_pattern", description: r#"floating-point literals cannot be used in patterns"# }, 62 LintCompletion { label: "illegal_floating_point_literal_pattern", description: r#"floating-point literals cannot be used in patterns"# },
84 LintCompletion { label: "improper_ctypes", description: r#"proper use of libc types in foreign modules"# },
85 LintCompletion { label: "improper_ctypes_definitions", description: r#"proper use of libc types in foreign item definitions"# }, 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"# },
86 LintCompletion { label: "incomplete_features", description: r#"incomplete features that may function improperly in some or all cases"# }, 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"# },
87 LintCompletion { label: "inline_no_sanitize", description: r#"detects incompatible use of `#[inline(always)]` and `#[no_sanitize(...)]`"# }, 68 LintCompletion { label: "inline_no_sanitize", description: r#"detects incompatible use of `#[inline(always)]` and `#[no_sanitize(...)]`"# },
88 LintCompletion { label: "intra_doc_link_resolution_failure", description: r#"failures in resolving intra-doc link targets"# }, 69 LintCompletion { label: "intra_doc_link_resolution_failure", description: r#"failures in resolving intra-doc link targets"# },
89 LintCompletion { label: "invalid_codeblock_attributes", description: r#"codeblock attribute looks a lot like a known one"# }, 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"# },
90 LintCompletion { label: "invalid_value", description: r#"an invalid value is being created (such as a NULL reference)"# }, 72 LintCompletion { label: "invalid_value", description: r#"an invalid value is being created (such as a NULL reference)"# },
91 LintCompletion { label: "irrefutable_let_patterns", description: r#"detects irrefutable patterns in if-let and while-let statements"# }, 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"# },
92 LintCompletion { label: "late_bound_lifetime_arguments", description: r#"detects generic lifetime arguments in path segments with late bound lifetime parameters"# }, 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"# },
93 LintCompletion { label: "mixed_script_confusables", description: r#"detects Unicode scripts whose mixed script confusables codepoints are solely used"# }, 85 LintCompletion { label: "mixed_script_confusables", description: r#"detects Unicode scripts whose mixed script confusables codepoints are solely used"# },
94 LintCompletion { label: "mutable_borrow_reservation_conflict", description: r#"reservation of a two-phased borrow conflicts with other shared borrows"# }, 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"# },
95 LintCompletion { label: "non_camel_case_types", description: r#"types, variants, traits and type parameters should have camel case names"# }, 91 LintCompletion { label: "non_camel_case_types", description: r#"types, variants, traits and type parameters should have camel case names"# },
96 LintCompletion { label: "non_shorthand_field_patterns", description: r#"using `Struct { x: x }` instead of `Struct { x }` in a pattern"# }, 92 LintCompletion { label: "non_shorthand_field_patterns", description: r#"using `Struct { x: x }` instead of `Struct { x }` in a pattern"# },
97 LintCompletion { label: "non_snake_case", description: r#"variables, methods, functions, lifetime parameters and modules should have snake case names"# }, 93 LintCompletion { label: "non_snake_case", description: r#"variables, methods, functions, lifetime parameters and modules should have snake case names"# },
98 LintCompletion { label: "non_upper_case_globals", description: r#"static constants should have uppercase identifiers"# }, 94 LintCompletion { label: "non_upper_case_globals", description: r#"static constants should have uppercase identifiers"# },
99 LintCompletion { label: "no_mangle_generic_items", description: r#"generic items must be mangled"# }, 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"# },
100 LintCompletion { label: "overlapping_patterns", description: r#"detects overlapping patterns"# }, 97 LintCompletion { label: "overlapping_patterns", description: r#"detects overlapping patterns"# },
101 LintCompletion { label: "path_statements", description: r#"path statements with no effect"# }, 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"# },
102 LintCompletion { label: "private_in_public", description: r#"detect private items in public interfaces not caught by the old implementation"# }, 101 LintCompletion { label: "private_in_public", description: r#"detect private items in public interfaces not caught by the old implementation"# },
103 LintCompletion { label: "proc_macro_derive_resolution_fallback", description: r#"detects proc macro derives using inaccessible names from parent modules"# }, 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"# }, 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"# }, 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"# }, 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"# },
107 LintCompletion { label: "stable_features", description: r#"stable features found in `#[feature]` directive"# }, 109 LintCompletion { label: "stable_features", description: r#"stable features found in `#[feature]` directive"# },
108 LintCompletion { label: "trivial_bounds", description: r#"these bounds don't depend on an type parameters"# }, 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"# },
109 LintCompletion { label: "type_alias_bounds", description: r#"bounds in type aliases are not enforced"# }, 113 LintCompletion { label: "type_alias_bounds", description: r#"bounds in type aliases are not enforced"# },
110 LintCompletion { label: "tyvar_behind_raw_pointer", description: r#"raw pointer to an inference variable"# }, 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"# },
111 LintCompletion { label: "uncommon_codepoints", description: r#"detects uncommon Unicode codepoints in identifiers"# }, 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"# },
112 LintCompletion { label: "unconditional_recursion", description: r#"functions that cannot return without calling themselves"# }, 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"# },
113 LintCompletion { label: "unknown_lints", description: r#"unrecognized lint attribute"# }, 120 LintCompletion { label: "unknown_lints", description: r#"unrecognized lint attribute"# },
114 LintCompletion { label: "unnameable_test_items", description: r#"detects an item that cannot be named being marked as `#[test_case]`"# }, 121 LintCompletion { label: "unnameable_test_items", description: r#"detects an item that cannot be named being marked as `#[test_case]`"# },
115 LintCompletion { label: "unreachable_code", description: r#"detects unreachable code paths"# }, 122 LintCompletion { label: "unreachable_code", description: r#"detects unreachable code paths"# },
116 LintCompletion { label: "unreachable_patterns", description: r#"detects unreachable patterns"# }, 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)"# },
117 LintCompletion { label: "unstable_name_collisions", description: r#"detects name collision with an existing but unstable method"# }, 128 LintCompletion { label: "unstable_name_collisions", description: r#"detects name collision with an existing but unstable method"# },
118 LintCompletion { label: "unused_allocation", description: r#"detects unnecessary allocations that can be eliminated"# }, 129 LintCompletion { label: "unused_allocation", description: r#"detects unnecessary allocations that can be eliminated"# },
119 LintCompletion { label: "unused_assignments", description: r#"detect assignments that will never be read"# }, 130 LintCompletion { label: "unused_assignments", description: r#"detect assignments that will never be read"# },
120 LintCompletion { label: "unused_attributes", description: r#"detects attributes that were not used by the compiler"# }, 131 LintCompletion { label: "unused_attributes", description: r#"detects attributes that were not used by the compiler"# },
121 LintCompletion { label: "unused_braces", description: r#"unnecessary braces around an expression"# }, 132 LintCompletion { label: "unused_braces", description: r#"unnecessary braces around an expression"# },
122 LintCompletion { label: "unused_comparisons", description: r#"comparisons made useless by limits of the types involved"# }, 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"# },
123 LintCompletion { label: "unused_doc_comments", description: r#"detects doc comments that aren't used by rustdoc"# }, 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"# },
124 LintCompletion { label: "unused_features", description: r#"unused features found in crate-level `#[feature]` directives"# }, 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"# },
125 LintCompletion { label: "unused_imports", description: r#"imports that are never used"# }, 139 LintCompletion { label: "unused_imports", description: r#"imports that are never used"# },
126 LintCompletion { label: "unused_labels", description: r#"detects labels 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"# },
127 LintCompletion { label: "unused_macros", description: r#"detects macros that were not used"# }, 142 LintCompletion { label: "unused_macros", description: r#"detects macros that were not used"# },
128 LintCompletion { label: "unused_must_use", description: r#"unused result of a type flagged as `#[must_use]`"# }, 143 LintCompletion { label: "unused_must_use", description: r#"unused result of a type flagged as `#[must_use]`"# },
129 LintCompletion { label: "unused_mut", description: r#"detect mut variables which don't need to be mutable"# }, 144 LintCompletion { label: "unused_mut", description: r#"detect mut variables which don't need to be mutable"# },
130 LintCompletion { label: "unused_parens", description: r#"`if`, `match`, `while` and `return` do not need parentheses"# }, 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"# },
131 LintCompletion { label: "unused_unsafe", description: r#"unnecessary use of an `unsafe` block"# }, 148 LintCompletion { label: "unused_unsafe", description: r#"unnecessary use of an `unsafe` block"# },
132 LintCompletion { label: "unused_variables", description: r#"detect variables which are not used in any way"# }, 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"# },
133 LintCompletion { label: "warnings", description: r#"mass-change the level for lints which produce warnings"# }, 151 LintCompletion { label: "warnings", description: r#"mass-change the level for lints which produce warnings"# },
134 LintCompletion { label: "where_clauses_object_safety", description: r#"checks the object safety of where clauses"# }, 152 LintCompletion { label: "where_clauses_object_safety", description: r#"checks the object safety of where clauses"# },
135 LintCompletion { label: "while_true", description: r#"suggest using `loop { }` instead of `while true { }`"# }, 153 LintCompletion { label: "while_true", description: r#"suggest using `loop { }` instead of `while true { }`"# },
136 LintCompletion { label: "ambiguous_associated_items", description: r#"ambiguous associated items"# },
137 LintCompletion { label: "arithmetic_overflow", description: r#"arithmetic operation overflows"# },
138 LintCompletion { label: "conflicting_repr_hints", description: r#"conflicts between `#[repr(..)]` hints that were previously accepted and used in practice"# },
139 LintCompletion { label: "const_err", description: r#"constant evaluation detected erroneous expression"# },
140 LintCompletion { label: "ill_formed_attribute_input", description: r#"ill-formed attribute inputs that were previously accepted and used in practice"# },
141 LintCompletion { label: "incomplete_include", description: r#"trailing content in included file"# },
142 LintCompletion { label: "invalid_type_param_default", description: r#"type parameter default erroneously allowed in invalid location"# },
143 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"# },
144 LintCompletion { label: "missing_fragment_specifier", description: r#"detects missing fragment specifiers in unused `macro_rules!` patterns"# },
145 LintCompletion { label: "mutable_transmutes", description: r#"mutating transmuted &mut T from &T may cause undefined behavior"# },
146 LintCompletion { label: "no_mangle_const_items", description: r#"const items will not have their symbols exported"# },
147 LintCompletion { label: "order_dependent_trait_objects", description: r#"trait-object types were treated as different depending on marker-trait order"# },
148 LintCompletion { label: "overflowing_literals", description: r#"literal out of range for its type"# },
149 LintCompletion { label: "patterns_in_fns_without_body", description: r#"patterns in functions without body were erroneously allowed"# },
150 LintCompletion { label: "pub_use_of_private_extern_crate", description: r#"detect public re-exports of private extern crates"# },
151 LintCompletion { label: "soft_unstable", description: r#"a feature gate that doesn't break dependent crates"# },
152 LintCompletion { label: "unconditional_panic", description: r#"operation will cause a panic at runtime"# },
153 LintCompletion { label: "unknown_crate_types", description: r#"unknown crate type found in `#[crate_type]` directive"# },
154]; 154];
155 155
156#[cfg(test)] 156#[cfg(test)]
diff --git a/crates/ide_completion/src/generated_lint_completions.rs b/crates/ide_completion/src/generated_lint_completions.rs
index 0d405350d..fe9554526 100644
--- a/crates/ide_completion/src/generated_lint_completions.rs
+++ b/crates/ide_completion/src/generated_lint_completions.rs
@@ -1,319 +1,8 @@
1//! Generated file, do not edit by hand, see `xtask/src/codegen` 1//! Generated file, do not edit by hand, see `xtask/src/codegen`
2 2
3use crate::completions::attribute::LintCompletion; 3use crate::completions::attribute::LintCompletion;
4pub(super) const FEATURES: &[LintCompletion] = &[
5 LintCompletion {
6 label: "plugin_registrar",
7 description: r##"# `plugin_registrar`
8
9The tracking issue for this feature is: [#29597]
10
11[#29597]: https://github.com/rust-lang/rust/issues/29597
12
13This feature is part of "compiler plugins." It will often be used with the
14[`plugin`] and `rustc_private` features as well. For more details, see
15their docs.
16
17[`plugin`]: plugin.md
18
19------------------------
20"##,
21 },
22 LintCompletion {
23 label: "inline_const",
24 description: r##"# `inline_const`
25
26The tracking issue for this feature is: [#76001]
27
28------
29
30This feature allows you to use inline constant expressions. For example, you can
31turn this code:
32
33```rust
34# fn add_one(x: i32) -> i32 { x + 1 }
35const MY_COMPUTATION: i32 = 1 + 2 * 3 / 4;
36
37fn main() {
38 let x = add_one(MY_COMPUTATION);
39}
40```
41
42into this code:
43
44```rust
45#![feature(inline_const)]
46
47# fn add_one(x: i32) -> i32 { x + 1 }
48fn main() {
49 let x = add_one(const { 1 + 2 * 3 / 4 });
50}
51```
52
53You can also use inline constant expressions in patterns:
54
55```rust
56#![feature(inline_const)]
57
58const fn one() -> i32 { 1 }
59
60let some_int = 3;
61match some_int {
62 const { 1 + 2 } => println!("Matched 1 + 2"),
63 const { one() } => println!("Matched const fn returning 1"),
64 _ => println!("Didn't match anything :("),
65}
66```
67
68[#76001]: https://github.com/rust-lang/rust/issues/76001
69"##,
70 },
71 LintCompletion {
72 label: "auto_traits",
73 description: r##"# `auto_traits`
74
75The tracking issue for this feature is [#13231]
76
77[#13231]: https://github.com/rust-lang/rust/issues/13231
78
79----
80
81The `auto_traits` feature gate allows you to define auto traits.
82
83Auto traits, like [`Send`] or [`Sync`] in the standard library, are marker traits
84that are automatically implemented for every type, unless the type, or a type it contains,
85has explicitly opted out via a negative impl. (Negative impls are separately controlled
86by the `negative_impls` feature.)
87
88[`Send`]: https://doc.rust-lang.org/std/marker/trait.Send.html
89[`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html
90
91```rust,ignore (partial-example)
92impl !Trait for Type {}
93```
94
95Example:
96
97```rust
98#![feature(negative_impls)]
99#![feature(auto_traits)]
100
101auto trait Valid {}
102
103struct True;
104struct False;
105
106impl !Valid for False {}
107
108struct MaybeValid<T>(T);
109
110fn must_be_valid<T: Valid>(_t: T) { }
111
112fn main() {
113 // works
114 must_be_valid( MaybeValid(True) );
115
116 // compiler error - trait bound not satisfied
117 // must_be_valid( MaybeValid(False) );
118}
119```
120
121## Automatic trait implementations
122
123When a type is declared as an `auto trait`, we will automatically
124create impls for every struct/enum/union, unless an explicit impl is
125provided. These automatic impls contain a where clause for each field
126of the form `T: AutoTrait`, where `T` is the type of the field and
127`AutoTrait` is the auto trait in question. As an example, consider the
128struct `List` and the auto trait `Send`:
129
130```rust
131struct List<T> {
132 data: T,
133 next: Option<Box<List<T>>>,
134}
135```
136
137Presuming that there is no explicit impl of `Send` for `List`, the
138compiler will supply an automatic impl of the form:
139
140```rust
141struct List<T> {
142 data: T,
143 next: Option<Box<List<T>>>,
144}
145
146unsafe impl<T> Send for List<T>
147where
148 T: Send, // from the field `data`
149 Option<Box<List<T>>>: Send, // from the field `next`
150{ }
151```
152
153Explicit impls may be either positive or negative. They take the form:
154
155```rust,ignore (partial-example)
156impl<...> AutoTrait for StructName<..> { }
157impl<...> !AutoTrait for StructName<..> { }
158```
159
160## Coinduction: Auto traits permit cyclic matching
161
162Unlike ordinary trait matching, auto traits are **coinductive**. This
163means, in short, that cycles which occur in trait matching are
164considered ok. As an example, consider the recursive struct `List`
165introduced in the previous section. In attempting to determine whether
166`List: Send`, we would wind up in a cycle: to apply the impl, we must
167show that `Option<Box<List>>: Send`, which will in turn require
168`Box<List>: Send` and then finally `List: Send` again. Under ordinary
169trait matching, this cycle would be an error, but for an auto trait it
170is considered a successful match.
171
172## Items
173
174Auto traits cannot have any trait items, such as methods or associated types. This ensures that we can generate default implementations.
175
176## Supertraits
177
178Auto traits cannot have supertraits. This is for soundness reasons, as the interaction of coinduction with implied bounds is difficult to reconcile.
179"##,
180 },
181 LintCompletion {
182 label: "ffi_const",
183 description: r##"# `ffi_const`
184
185The tracking issue for this feature is: [#58328]
186
187------
188
189The `#[ffi_const]` attribute applies clang's `const` attribute to foreign
190functions declarations.
191
192That is, `#[ffi_const]` functions shall have no effects except for its return
193value, which can only depend on the values of the function parameters, and is
194not affected by changes to the observable state of the program.
195
196Applying the `#[ffi_const]` attribute to a function that violates these
197requirements is undefined behaviour.
198
199This attribute enables Rust to perform common optimizations, like sub-expression
200elimination, and it can avoid emitting some calls in repeated invocations of the
201function with the same argument values regardless of other operations being
202performed in between these functions calls (as opposed to `#[ffi_pure]`
203functions).
204
205## Pitfalls
206
207A `#[ffi_const]` function can only read global memory that would not affect
208its return value for the whole execution of the program (e.g. immutable global
209memory). `#[ffi_const]` functions are referentially-transparent and therefore
210more strict than `#[ffi_pure]` functions.
211
212A common pitfall involves applying the `#[ffi_const]` attribute to a
213function that reads memory through pointer arguments which do not necessarily
214point to immutable global memory.
215
216A `#[ffi_const]` function that returns unit has no effect on the abstract
217machine's state, and a `#[ffi_const]` function cannot be `#[ffi_pure]`.
218
219A `#[ffi_const]` function must not diverge, neither via a side effect (e.g. a
220call to `abort`) nor by infinite loops.
221
222When translating C headers to Rust FFI, it is worth verifying for which targets
223the `const` attribute is enabled in those headers, and using the appropriate
224`cfg` macros in the Rust side to match those definitions. While the semantics of
225`const` are implemented identically by many C and C++ compilers, e.g., clang,
226[GCC], [ARM C/C++ compiler], [IBM ILE C/C++], etc. they are not necessarily
227implemented in this way on all of them. It is therefore also worth verifying
228that the semantics of the C toolchain used to compile the binary being linked
229against are compatible with those of the `#[ffi_const]`.
230
231[#58328]: https://github.com/rust-lang/rust/issues/58328
232[ARM C/C++ compiler]: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0491c/Cacgigch.html
233[GCC]: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-const-function-attribute
234[IBM ILE C/C++]: https://www.ibm.com/support/knowledgecenter/fr/ssw_ibm_i_71/rzarg/fn_attrib_const.htm
235"##,
236 },
237 LintCompletion {
238 label: "external_doc",
239 description: r##"# `external_doc`
240
241The tracking issue for this feature is: [#44732]
242
243The `external_doc` feature allows the use of the `include` parameter to the `#[doc]` attribute, to
244include external files in documentation. Use the attribute in place of, or in addition to, regular
245doc comments and `#[doc]` attributes, and `rustdoc` will load the given file when it renders
246documentation for your crate.
247
248With the following files in the same directory:
249
250`external-doc.md`:
251 4
252```markdown 5pub const FEATURES: &[LintCompletion] = &[
253# My Awesome Type
254
255This is the documentation for this spectacular type.
256```
257
258`lib.rs`:
259
260```no_run (needs-external-files)
261#![feature(external_doc)]
262
263#[doc(include = "external-doc.md")]
264pub struct MyAwesomeType;
265```
266
267`rustdoc` will load the file `external-doc.md` and use it as the documentation for the `MyAwesomeType`
268struct.
269
270When locating files, `rustdoc` will base paths in the `src/` directory, as if they were alongside the
271`lib.rs` for your crate. So if you want a `docs/` folder to live alongside the `src/` directory,
272start your paths with `../docs/` for `rustdoc` to properly find the file.
273
274This feature was proposed in [RFC #1990] and initially implemented in PR [#44781].
275
276[#44732]: https://github.com/rust-lang/rust/issues/44732
277[RFC #1990]: https://github.com/rust-lang/rfcs/pull/1990
278[#44781]: https://github.com/rust-lang/rust/pull/44781
279"##,
280 },
281 LintCompletion {
282 label: "box_patterns",
283 description: r##"# `box_patterns`
284
285The tracking issue for this feature is: [#29641]
286
287[#29641]: https://github.com/rust-lang/rust/issues/29641
288
289See also [`box_syntax`](box-syntax.md)
290
291------------------------
292
293Box patterns let you match on `Box<T>`s:
294
295
296```rust
297#![feature(box_patterns)]
298
299fn main() {
300 let b = Some(Box::new(5));
301 match b {
302 Some(box n) if n < 0 => {
303 println!("Box contains negative number {}", n);
304 },
305 Some(box n) if n >= 0 => {
306 println!("Box contains non-negative number {}", n);
307 },
308 None => {
309 println!("No box");
310 },
311 _ => unreachable!()
312 }
313}
314```
315"##,
316 },
317 LintCompletion { 6 LintCompletion {
318 label: "abi_c_cmse_nonsecure_call", 7 label: "abi_c_cmse_nonsecure_call",
319 description: r##"# `abi_c_cmse_nonsecure_call` 8 description: r##"# `abi_c_cmse_nonsecure_call`
@@ -407,1681 +96,6 @@ call_nonsecure_function:
407"##, 96"##,
408 }, 97 },
409 LintCompletion { 98 LintCompletion {
410 label: "member_constraints",
411 description: r##"# `member_constraints`
412
413The tracking issue for this feature is: [#61997]
414
415[#61997]: https://github.com/rust-lang/rust/issues/61997
416
417------------------------
418
419The `member_constraints` feature gate lets you use `impl Trait` syntax with
420multiple unrelated lifetime parameters.
421
422A simple example is:
423
424```rust
425#![feature(member_constraints)]
426
427trait Trait<'a, 'b> { }
428impl<T> Trait<'_, '_> for T {}
429
430fn foo<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Trait<'a, 'b> {
431 (x, y)
432}
433
434fn main() { }
435```
436
437Without the `member_constraints` feature gate, the above example is an
438error because both `'a` and `'b` appear in the impl Trait bounds, but
439neither outlives the other.
440"##,
441 },
442 LintCompletion {
443 label: "allocator_internals",
444 description: r##"# `allocator_internals`
445
446This feature does not have a tracking issue, it is an unstable implementation
447detail of the `global_allocator` feature not intended for use outside the
448compiler.
449
450------------------------
451"##,
452 },
453 LintCompletion {
454 label: "cfg_sanitize",
455 description: r##"# `cfg_sanitize`
456
457The tracking issue for this feature is: [#39699]
458
459[#39699]: https://github.com/rust-lang/rust/issues/39699
460
461------------------------
462
463The `cfg_sanitize` feature makes it possible to execute different code
464depending on whether a particular sanitizer is enabled or not.
465
466## Examples
467
468```rust
469#![feature(cfg_sanitize)]
470
471#[cfg(sanitize = "thread")]
472fn a() {
473 // ...
474}
475
476#[cfg(not(sanitize = "thread"))]
477fn a() {
478 // ...
479}
480
481fn b() {
482 if cfg!(sanitize = "leak") {
483 // ...
484 } else {
485 // ...
486 }
487}
488```
489"##,
490 },
491 LintCompletion {
492 label: "cfg_panic",
493 description: r##"# `cfg_panic`
494
495The tracking issue for this feature is: [#77443]
496
497[#77443]: https://github.com/rust-lang/rust/issues/77443
498
499------------------------
500
501The `cfg_panic` feature makes it possible to execute different code
502depending on the panic strategy.
503
504Possible values at the moment are `"unwind"` or `"abort"`, although
505it is possible that new panic strategies may be added to Rust in the
506future.
507
508## Examples
509
510```rust
511#![feature(cfg_panic)]
512
513#[cfg(panic = "unwind")]
514fn a() {
515 // ...
516}
517
518#[cfg(not(panic = "unwind"))]
519fn a() {
520 // ...
521}
522
523fn b() {
524 if cfg!(panic = "abort") {
525 // ...
526 } else {
527 // ...
528 }
529}
530```
531"##,
532 },
533 LintCompletion {
534 label: "ffi_pure",
535 description: r##"# `ffi_pure`
536
537The tracking issue for this feature is: [#58329]
538
539------
540
541The `#[ffi_pure]` attribute applies clang's `pure` attribute to foreign
542functions declarations.
543
544That is, `#[ffi_pure]` functions shall have no effects except for its return
545value, which shall not change across two consecutive function calls with
546the same parameters.
547
548Applying the `#[ffi_pure]` attribute to a function that violates these
549requirements is undefined behavior.
550
551This attribute enables Rust to perform common optimizations, like sub-expression
552elimination and loop optimizations. Some common examples of pure functions are
553`strlen` or `memcmp`.
554
555These optimizations are only applicable when the compiler can prove that no
556program state observable by the `#[ffi_pure]` function has changed between calls
557of the function, which could alter the result. See also the `#[ffi_const]`
558attribute, which provides stronger guarantees regarding the allowable behavior
559of a function, enabling further optimization.
560
561## Pitfalls
562
563A `#[ffi_pure]` function can read global memory through the function
564parameters (e.g. pointers), globals, etc. `#[ffi_pure]` functions are not
565referentially-transparent, and are therefore more relaxed than `#[ffi_const]`
566functions.
567
568However, accessing global memory through volatile or atomic reads can violate the
569requirement that two consecutive function calls shall return the same value.
570
571A `pure` function that returns unit has no effect on the abstract machine's
572state.
573
574A `#[ffi_pure]` function must not diverge, neither via a side effect (e.g. a
575call to `abort`) nor by infinite loops.
576
577When translating C headers to Rust FFI, it is worth verifying for which targets
578the `pure` attribute is enabled in those headers, and using the appropriate
579`cfg` macros in the Rust side to match those definitions. While the semantics of
580`pure` are implemented identically by many C and C++ compilers, e.g., clang,
581[GCC], [ARM C/C++ compiler], [IBM ILE C/C++], etc. they are not necessarily
582implemented in this way on all of them. It is therefore also worth verifying
583that the semantics of the C toolchain used to compile the binary being linked
584against are compatible with those of the `#[ffi_pure]`.
585
586
587[#58329]: https://github.com/rust-lang/rust/issues/58329
588[ARM C/C++ compiler]: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0491c/Cacigdac.html
589[GCC]: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-pure-function-attribute
590[IBM ILE C/C++]: https://www.ibm.com/support/knowledgecenter/fr/ssw_ibm_i_71/rzarg/fn_attrib_pure.htm
591"##,
592 },
593 LintCompletion {
594 label: "repr128",
595 description: r##"# `repr128`
596
597The tracking issue for this feature is: [#56071]
598
599[#56071]: https://github.com/rust-lang/rust/issues/56071
600
601------------------------
602
603The `repr128` feature adds support for `#[repr(u128)]` on `enum`s.
604
605```rust
606#![feature(repr128)]
607
608#[repr(u128)]
609enum Foo {
610 Bar(u64),
611}
612```
613"##,
614 },
615 LintCompletion {
616 label: "generators",
617 description: r##"# `generators`
618
619The tracking issue for this feature is: [#43122]
620
621[#43122]: https://github.com/rust-lang/rust/issues/43122
622
623------------------------
624
625The `generators` feature gate in Rust allows you to define generator or
626coroutine literals. A generator is a "resumable function" that syntactically
627resembles a closure but compiles to much different semantics in the compiler
628itself. The primary feature of a generator is that it can be suspended during
629execution to be resumed at a later date. Generators use the `yield` keyword to
630"return", and then the caller can `resume` a generator to resume execution just
631after the `yield` keyword.
632
633Generators are an extra-unstable feature in the compiler right now. Added in
634[RFC 2033] they're mostly intended right now as a information/constraint
635gathering phase. The intent is that experimentation can happen on the nightly
636compiler before actual stabilization. A further RFC will be required to
637stabilize generators/coroutines and will likely contain at least a few small
638tweaks to the overall design.
639
640[RFC 2033]: https://github.com/rust-lang/rfcs/pull/2033
641
642A syntactical example of a generator is:
643
644```rust
645#![feature(generators, generator_trait)]
646
647use std::ops::{Generator, GeneratorState};
648use std::pin::Pin;
649
650fn main() {
651 let mut generator = || {
652 yield 1;
653 return "foo"
654 };
655
656 match Pin::new(&mut generator).resume(()) {
657 GeneratorState::Yielded(1) => {}
658 _ => panic!("unexpected value from resume"),
659 }
660 match Pin::new(&mut generator).resume(()) {
661 GeneratorState::Complete("foo") => {}
662 _ => panic!("unexpected value from resume"),
663 }
664}
665```
666
667Generators are closure-like literals which can contain a `yield` statement. The
668`yield` statement takes an optional expression of a value to yield out of the
669generator. All generator literals implement the `Generator` trait in the
670`std::ops` module. The `Generator` trait has one main method, `resume`, which
671resumes execution of the generator at the previous suspension point.
672
673An example of the control flow of generators is that the following example
674prints all numbers in order:
675
676```rust
677#![feature(generators, generator_trait)]
678
679use std::ops::Generator;
680use std::pin::Pin;
681
682fn main() {
683 let mut generator = || {
684 println!("2");
685 yield;
686 println!("4");
687 };
688
689 println!("1");
690 Pin::new(&mut generator).resume(());
691 println!("3");
692 Pin::new(&mut generator).resume(());
693 println!("5");
694}
695```
696
697At this time the main intended use case of generators is an implementation
698primitive for async/await syntax, but generators will likely be extended to
699ergonomic implementations of iterators and other primitives in the future.
700Feedback on the design and usage is always appreciated!
701
702### The `Generator` trait
703
704The `Generator` trait in `std::ops` currently looks like:
705
706```rust
707# #![feature(arbitrary_self_types, generator_trait)]
708# use std::ops::GeneratorState;
709# use std::pin::Pin;
710
711pub trait Generator<R = ()> {
712 type Yield;
713 type Return;
714 fn resume(self: Pin<&mut Self>, resume: R) -> GeneratorState<Self::Yield, Self::Return>;
715}
716```
717
718The `Generator::Yield` type is the type of values that can be yielded with the
719`yield` statement. The `Generator::Return` type is the returned type of the
720generator. This is typically the last expression in a generator's definition or
721any value passed to `return` in a generator. The `resume` function is the entry
722point for executing the `Generator` itself.
723
724The return value of `resume`, `GeneratorState`, looks like:
725
726```rust
727pub enum GeneratorState<Y, R> {
728 Yielded(Y),
729 Complete(R),
730}
731```
732
733The `Yielded` variant indicates that the generator can later be resumed. This
734corresponds to a `yield` point in a generator. The `Complete` variant indicates
735that the generator is complete and cannot be resumed again. Calling `resume`
736after a generator has returned `Complete` will likely result in a panic of the
737program.
738
739### Closure-like semantics
740
741The closure-like syntax for generators alludes to the fact that they also have
742closure-like semantics. Namely:
743
744* When created, a generator executes no code. A closure literal does not
745 actually execute any of the closure's code on construction, and similarly a
746 generator literal does not execute any code inside the generator when
747 constructed.
748
749* Generators can capture outer variables by reference or by move, and this can
750 be tweaked with the `move` keyword at the beginning of the closure. Like
751 closures all generators will have an implicit environment which is inferred by
752 the compiler. Outer variables can be moved into a generator for use as the
753 generator progresses.
754
755* Generator literals produce a value with a unique type which implements the
756 `std::ops::Generator` trait. This allows actual execution of the generator
757 through the `Generator::resume` method as well as also naming it in return
758 types and such.
759
760* Traits like `Send` and `Sync` are automatically implemented for a `Generator`
761 depending on the captured variables of the environment. Unlike closures,
762 generators also depend on variables live across suspension points. This means
763 that although the ambient environment may be `Send` or `Sync`, the generator
764 itself may not be due to internal variables live across `yield` points being
765 not-`Send` or not-`Sync`. Note that generators do
766 not implement traits like `Copy` or `Clone` automatically.
767
768* Whenever a generator is dropped it will drop all captured environment
769 variables.
770
771### Generators as state machines
772
773In the compiler, generators are currently compiled as state machines. Each
774`yield` expression will correspond to a different state that stores all live
775variables over that suspension point. Resumption of a generator will dispatch on
776the current state and then execute internally until a `yield` is reached, at
777which point all state is saved off in the generator and a value is returned.
778
779Let's take a look at an example to see what's going on here:
780
781```rust
782#![feature(generators, generator_trait)]
783
784use std::ops::Generator;
785use std::pin::Pin;
786
787fn main() {
788 let ret = "foo";
789 let mut generator = move || {
790 yield 1;
791 return ret
792 };
793
794 Pin::new(&mut generator).resume(());
795 Pin::new(&mut generator).resume(());
796}
797```
798
799This generator literal will compile down to something similar to:
800
801```rust
802#![feature(arbitrary_self_types, generators, generator_trait)]
803
804use std::ops::{Generator, GeneratorState};
805use std::pin::Pin;
806
807fn main() {
808 let ret = "foo";
809 let mut generator = {
810 enum __Generator {
811 Start(&'static str),
812 Yield1(&'static str),
813 Done,
814 }
815
816 impl Generator for __Generator {
817 type Yield = i32;
818 type Return = &'static str;
819
820 fn resume(mut self: Pin<&mut Self>, resume: ()) -> GeneratorState<i32, &'static str> {
821 use std::mem;
822 match mem::replace(&mut *self, __Generator::Done) {
823 __Generator::Start(s) => {
824 *self = __Generator::Yield1(s);
825 GeneratorState::Yielded(1)
826 }
827
828 __Generator::Yield1(s) => {
829 *self = __Generator::Done;
830 GeneratorState::Complete(s)
831 }
832
833 __Generator::Done => {
834 panic!("generator resumed after completion")
835 }
836 }
837 }
838 }
839
840 __Generator::Start(ret)
841 };
842
843 Pin::new(&mut generator).resume(());
844 Pin::new(&mut generator).resume(());
845}
846```
847
848Notably here we can see that the compiler is generating a fresh type,
849`__Generator` in this case. This type has a number of states (represented here
850as an `enum`) corresponding to each of the conceptual states of the generator.
851At the beginning we're closing over our outer variable `foo` and then that
852variable is also live over the `yield` point, so it's stored in both states.
853
854When the generator starts it'll immediately yield 1, but it saves off its state
855just before it does so indicating that it has reached the yield point. Upon
856resuming again we'll execute the `return ret` which returns the `Complete`
857state.
858
859Here we can also note that the `Done` state, if resumed, panics immediately as
860it's invalid to resume a completed generator. It's also worth noting that this
861is just a rough desugaring, not a normative specification for what the compiler
862does.
863"##,
864 },
865 LintCompletion {
866 label: "non_ascii_idents",
867 description: r##"# `non_ascii_idents`
868
869The tracking issue for this feature is: [#55467]
870
871[#55467]: https://github.com/rust-lang/rust/issues/55467
872
873------------------------
874
875The `non_ascii_idents` feature adds support for non-ASCII identifiers.
876
877## Examples
878
879```rust
880#![feature(non_ascii_idents)]
881
882const ε: f64 = 0.00001f64;
883const Π: f64 = 3.14f64;
884```
885
886## Changes to the language reference
887
888> **<sup>Lexer:<sup>**\
889> IDENTIFIER :\
890> &nbsp;&nbsp; &nbsp;&nbsp; XID_start XID_continue<sup>\*</sup>\
891> &nbsp;&nbsp; | `_` XID_continue<sup>+</sup>
892
893An identifier is any nonempty Unicode string of the following form:
894
895Either
896
897 * The first character has property [`XID_start`]
898 * The remaining characters have property [`XID_continue`]
899
900Or
901
902 * The first character is `_`
903 * The identifier is more than one character, `_` alone is not an identifier
904 * The remaining characters have property [`XID_continue`]
905
906that does _not_ occur in the set of [strict keywords].
907
908> **Note**: [`XID_start`] and [`XID_continue`] as character properties cover the
909> character ranges used to form the more familiar C and Java language-family
910> identifiers.
911
912[`XID_start`]: http://unicode.org/cldr/utility/list-unicodeset.jsp?a=%5B%3AXID_Start%3A%5D&abb=on&g=&i=
913[`XID_continue`]: http://unicode.org/cldr/utility/list-unicodeset.jsp?a=%5B%3AXID_Continue%3A%5D&abb=on&g=&i=
914[strict keywords]: ../../reference/keywords.md#strict-keywords
915"##,
916 },
917 LintCompletion {
918 label: "compiler_builtins",
919 description: r##"# `compiler_builtins`
920
921This feature is internal to the Rust compiler and is not intended for general use.
922
923------------------------
924"##,
925 },
926 LintCompletion {
927 label: "or_patterns",
928 description: r##"# `or_patterns`
929
930The tracking issue for this feature is: [#54883]
931
932[#54883]: https://github.com/rust-lang/rust/issues/54883
933
934------------------------
935
936The `or_pattern` language feature allows `|` to be arbitrarily nested within
937a pattern, for example, `Some(A(0) | B(1 | 2))` becomes a valid pattern.
938
939## Examples
940
941```rust,no_run
942#![feature(or_patterns)]
943
944pub enum Foo {
945 Bar,
946 Baz,
947 Quux,
948}
949
950pub fn example(maybe_foo: Option<Foo>) {
951 match maybe_foo {
952 Some(Foo::Bar | Foo::Baz) => {
953 println!("The value contained `Bar` or `Baz`");
954 }
955 Some(_) => {
956 println!("The value did not contain `Bar` or `Baz`");
957 }
958 None => {
959 println!("The value was `None`");
960 }
961 }
962}
963```
964"##,
965 },
966 LintCompletion {
967 label: "negative_impls",
968 description: r##"# `negative_impls`
969
970The tracking issue for this feature is [#68318].
971
972[#68318]: https://github.com/rust-lang/rust/issues/68318
973
974----
975
976With the feature gate `negative_impls`, you can write negative impls as well as positive ones:
977
978```rust
979#![feature(negative_impls)]
980trait DerefMut { }
981impl<T: ?Sized> !DerefMut for &T { }
982```
983
984Negative 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.
985
986Negative impls have the following characteristics:
987
988* They do not have any items.
989* They must obey the orphan rules as if they were a positive impl.
990* They cannot "overlap" with any positive impls.
991
992## Semver interaction
993
994It is a breaking change to remove a negative impl. Negative impls are a commitment not to implement the given trait for the named types.
995
996## Orphan and overlap rules
997
998Negative 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.
999
1000Similarly, 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.)
1001
1002## Interaction with auto traits
1003
1004Declaring a negative impl `impl !SomeAutoTrait for SomeType` for an
1005auto-trait serves two purposes:
1006
1007* as with any trait, it declares that `SomeType` will never implement `SomeAutoTrait`;
1008* it disables the automatic `SomeType: SomeAutoTrait` impl that would otherwise have been generated.
1009
1010Note that, at present, there is no way to indicate that a given type
1011does not implement an auto trait *but that it may do so in the
1012future*. For ordinary types, this is done by simply not declaring any
1013impl at all, but that is not an option for auto traits. A workaround
1014is that one could embed a marker type as one of the fields, where the
1015marker type is `!AutoTrait`.
1016
1017## Immediate uses
1018
1019Negative 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).
1020
1021This serves two purposes:
1022
1023* For proving the correctness of unsafe code, we can use that impl as evidence that no `DerefMut` or `Clone` impl exists.
1024* It prevents downstream crates from creating such impls.
1025"##,
1026 },
1027 LintCompletion {
1028 label: "cmse_nonsecure_entry",
1029 description: r##"# `cmse_nonsecure_entry`
1030
1031The tracking issue for this feature is: [#75835]
1032
1033[#75835]: https://github.com/rust-lang/rust/issues/75835
1034
1035------------------------
1036
1037The [TrustZone-M
1038feature](https://developer.arm.com/documentation/100690/latest/) is available
1039for targets with the Armv8-M architecture profile (`thumbv8m` in their target
1040name).
1041LLVM, the Rust compiler and the linker are providing
1042[support](https://developer.arm.com/documentation/ecm0359818/latest/) for the
1043TrustZone-M feature.
1044
1045One of the things provided, with this unstable feature, is the
1046`cmse_nonsecure_entry` attribute. This attribute marks a Secure function as an
1047entry function (see [section
10485.4](https://developer.arm.com/documentation/ecm0359818/latest/) for details).
1049With this attribute, the compiler will do the following:
1050* add a special symbol on the function which is the `__acle_se_` prefix and the
1051 standard function name
1052* constrain the number of parameters to avoid using the Non-Secure stack
1053* before returning from the function, clear registers that might contain Secure
1054 information
1055* use the `BXNS` instruction to return
1056
1057Because the stack can not be used to pass parameters, there will be compilation
1058errors if:
1059* the total size of all parameters is too big (for example more than four 32
1060 bits integers)
1061* the entry function is not using a C ABI
1062
1063The special symbol `__acle_se_` will be used by the linker to generate a secure
1064gateway veneer.
1065
1066<!-- NOTE(ignore) this example is specific to thumbv8m targets -->
1067
1068``` rust,ignore
1069#![feature(cmse_nonsecure_entry)]
1070
1071#[no_mangle]
1072#[cmse_nonsecure_entry]
1073pub extern "C" fn entry_function(input: u32) -> u32 {
1074 input + 6
1075}
1076```
1077
1078``` text
1079$ rustc --emit obj --crate-type lib --target thumbv8m.main-none-eabi function.rs
1080$ arm-none-eabi-objdump -D function.o
1081
108200000000 <entry_function>:
1083 0: b580 push {r7, lr}
1084 2: 466f mov r7, sp
1085 4: b082 sub sp, #8
1086 6: 9001 str r0, [sp, #4]
1087 8: 1d81 adds r1, r0, #6
1088 a: 460a mov r2, r1
1089 c: 4281 cmp r1, r0
1090 e: 9200 str r2, [sp, #0]
1091 10: d30b bcc.n 2a <entry_function+0x2a>
1092 12: e7ff b.n 14 <entry_function+0x14>
1093 14: 9800 ldr r0, [sp, #0]
1094 16: b002 add sp, #8
1095 18: e8bd 4080 ldmia.w sp!, {r7, lr}
1096 1c: 4671 mov r1, lr
1097 1e: 4672 mov r2, lr
1098 20: 4673 mov r3, lr
1099 22: 46f4 mov ip, lr
1100 24: f38e 8800 msr CPSR_f, lr
1101 28: 4774 bxns lr
1102 2a: f240 0000 movw r0, #0
1103 2e: f2c0 0000 movt r0, #0
1104 32: f240 0200 movw r2, #0
1105 36: f2c0 0200 movt r2, #0
1106 3a: 211c movs r1, #28
1107 3c: f7ff fffe bl 0 <_ZN4core9panicking5panic17h5c028258ca2fb3f5E>
1108 40: defe udf #254 ; 0xfe
1109```
1110"##,
1111 },
1112 LintCompletion {
1113 label: "plugin",
1114 description: r##"# `plugin`
1115
1116The tracking issue for this feature is: [#29597]
1117
1118[#29597]: https://github.com/rust-lang/rust/issues/29597
1119
1120
1121This feature is part of "compiler plugins." It will often be used with the
1122[`plugin_registrar`] and `rustc_private` features.
1123
1124[`plugin_registrar`]: plugin-registrar.md
1125
1126------------------------
1127
1128`rustc` can load compiler plugins, which are user-provided libraries that
1129extend the compiler's behavior with new lint checks, etc.
1130
1131A plugin is a dynamic library crate with a designated *registrar* function that
1132registers extensions with `rustc`. Other crates can load these extensions using
1133the crate attribute `#![plugin(...)]`. See the
1134`rustc_driver::plugin` documentation for more about the
1135mechanics of defining and loading a plugin.
1136
1137In the vast majority of cases, a plugin should *only* be used through
1138`#![plugin]` and not through an `extern crate` item. Linking a plugin would
1139pull in all of librustc_ast and librustc as dependencies of your crate. This is
1140generally unwanted unless you are building another plugin.
1141
1142The usual practice is to put compiler plugins in their own crate, separate from
1143any `macro_rules!` macros or ordinary Rust code meant to be used by consumers
1144of a library.
1145
1146# Lint plugins
1147
1148Plugins can extend [Rust's lint
1149infrastructure](../../reference/attributes/diagnostics.md#lint-check-attributes) with
1150additional checks for code style, safety, etc. Now let's write a plugin
1151[`lint-plugin-test.rs`](https://github.com/rust-lang/rust/blob/master/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs)
1152that warns about any item named `lintme`.
1153
1154```rust,ignore (requires-stage-2)
1155#![feature(plugin_registrar)]
1156#![feature(box_syntax, rustc_private)]
1157
1158extern crate rustc_ast;
1159
1160// Load rustc as a plugin to get macros
1161extern crate rustc_driver;
1162#[macro_use]
1163extern crate rustc_lint;
1164#[macro_use]
1165extern crate rustc_session;
1166
1167use rustc_driver::plugin::Registry;
1168use rustc_lint::{EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass};
1169use rustc_ast::ast;
1170declare_lint!(TEST_LINT, Warn, "Warn about items named 'lintme'");
1171
1172declare_lint_pass!(Pass => [TEST_LINT]);
1173
1174impl EarlyLintPass for Pass {
1175 fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) {
1176 if it.ident.name.as_str() == "lintme" {
1177 cx.lint(TEST_LINT, |lint| {
1178 lint.build("item is named 'lintme'").set_span(it.span).emit()
1179 });
1180 }
1181 }
1182}
1183
1184#[plugin_registrar]
1185pub fn plugin_registrar(reg: &mut Registry) {
1186 reg.lint_store.register_lints(&[&TEST_LINT]);
1187 reg.lint_store.register_early_pass(|| box Pass);
1188}
1189```
1190
1191Then code like
1192
1193```rust,ignore (requires-plugin)
1194#![feature(plugin)]
1195#![plugin(lint_plugin_test)]
1196
1197fn lintme() { }
1198```
1199
1200will produce a compiler warning:
1201
1202```txt
1203foo.rs:4:1: 4:16 warning: item is named 'lintme', #[warn(test_lint)] on by default
1204foo.rs:4 fn lintme() { }
1205 ^~~~~~~~~~~~~~~
1206```
1207
1208The components of a lint plugin are:
1209
1210* one or more `declare_lint!` invocations, which define static `Lint` structs;
1211
1212* a struct holding any state needed by the lint pass (here, none);
1213
1214* a `LintPass`
1215 implementation defining how to check each syntax element. A single
1216 `LintPass` may call `span_lint` for several different `Lint`s, but should
1217 register them all through the `get_lints` method.
1218
1219Lint passes are syntax traversals, but they run at a late stage of compilation
1220where type information is available. `rustc`'s [built-in
1221lints](https://github.com/rust-lang/rust/blob/master/src/librustc_session/lint/builtin.rs)
1222mostly use the same infrastructure as lint plugins, and provide examples of how
1223to access type information.
1224
1225Lints defined by plugins are controlled by the usual [attributes and compiler
1226flags](../../reference/attributes/diagnostics.md#lint-check-attributes), e.g.
1227`#[allow(test_lint)]` or `-A test-lint`. These identifiers are derived from the
1228first argument to `declare_lint!`, with appropriate case and punctuation
1229conversion.
1230
1231You can run `rustc -W help foo.rs` to see a list of lints known to `rustc`,
1232including those provided by plugins loaded by `foo.rs`.
1233"##,
1234 },
1235 LintCompletion {
1236 label: "intrinsics",
1237 description: r##"# `intrinsics`
1238
1239The tracking issue for this feature is: None.
1240
1241Intrinsics are never intended to be stable directly, but intrinsics are often
1242exported in some sort of stable manner. Prefer using the stable interfaces to
1243the intrinsic directly when you can.
1244
1245------------------------
1246
1247
1248These are imported as if they were FFI functions, with the special
1249`rust-intrinsic` ABI. For example, if one was in a freestanding
1250context, but wished to be able to `transmute` between types, and
1251perform efficient pointer arithmetic, one would import those functions
1252via a declaration like
1253
1254```rust
1255#![feature(intrinsics)]
1256# fn main() {}
1257
1258extern "rust-intrinsic" {
1259 fn transmute<T, U>(x: T) -> U;
1260
1261 fn offset<T>(dst: *const T, offset: isize) -> *const T;
1262}
1263```
1264
1265As with any other FFI functions, these are always `unsafe` to call.
1266"##,
1267 },
1268 LintCompletion {
1269 label: "rustc_attrs",
1270 description: r##"# `rustc_attrs`
1271
1272This feature has no tracking issue, and is therefore internal to
1273the compiler, not being intended for general use.
1274
1275Note: `rustc_attrs` enables many rustc-internal attributes and this page
1276only discuss a few of them.
1277
1278------------------------
1279
1280The `rustc_attrs` feature allows debugging rustc type layouts by using
1281`#[rustc_layout(...)]` to debug layout at compile time (it even works
1282with `cargo check`) as an alternative to `rustc -Z print-type-sizes`
1283that is way more verbose.
1284
1285Options provided by `#[rustc_layout(...)]` are `debug`, `size`, `align`,
1286`abi`. Note that it only works on sized types without generics.
1287
1288## Examples
1289
1290```rust,compile_fail
1291#![feature(rustc_attrs)]
1292
1293#[rustc_layout(abi, size)]
1294pub enum X {
1295 Y(u8, u8, u8),
1296 Z(isize),
1297}
1298```
1299
1300When that is compiled, the compiler will error with something like
1301
1302```text
1303error: abi: Aggregate { sized: true }
1304 --> src/lib.rs:4:1
1305 |
13064 | / pub enum T {
13075 | | Y(u8, u8, u8),
13086 | | Z(isize),
13097 | | }
1310 | |_^
1311
1312error: size: Size { raw: 16 }
1313 --> src/lib.rs:4:1
1314 |
13154 | / pub enum T {
13165 | | Y(u8, u8, u8),
13176 | | Z(isize),
13187 | | }
1319 | |_^
1320
1321error: aborting due to 2 previous errors
1322```
1323"##,
1324 },
1325 LintCompletion {
1326 label: "const_fn",
1327 description: r##"# `const_fn`
1328
1329The tracking issue for this feature is: [#57563]
1330
1331[#57563]: https://github.com/rust-lang/rust/issues/57563
1332
1333------------------------
1334
1335The `const_fn` feature enables additional functionality not stabilized in the
1336[minimal subset of `const_fn`](https://github.com/rust-lang/rust/issues/53555)
1337"##,
1338 },
1339 LintCompletion {
1340 label: "abi_thiscall",
1341 description: r##"# `abi_thiscall`
1342
1343The tracking issue for this feature is: [#42202]
1344
1345[#42202]: https://github.com/rust-lang/rust/issues/42202
1346
1347------------------------
1348
1349The MSVC ABI on x86 Windows uses the `thiscall` calling convention for C++
1350instance methods by default; it is identical to the usual (C) calling
1351convention on x86 Windows except that the first parameter of the method,
1352the `this` pointer, is passed in the ECX register.
1353"##,
1354 },
1355 LintCompletion {
1356 label: "trait_alias",
1357 description: r##"# `trait_alias`
1358
1359The tracking issue for this feature is: [#41517]
1360
1361[#41517]: https://github.com/rust-lang/rust/issues/41517
1362
1363------------------------
1364
1365The `trait_alias` feature adds support for trait aliases. These allow aliases
1366to be created for one or more traits (currently just a single regular trait plus
1367any number of auto-traits), and used wherever traits would normally be used as
1368either bounds or trait objects.
1369
1370```rust
1371#![feature(trait_alias)]
1372
1373trait Foo = std::fmt::Debug + Send;
1374trait Bar = Foo + Sync;
1375
1376// Use trait alias as bound on type parameter.
1377fn foo<T: Foo>(v: &T) {
1378 println!("{:?}", v);
1379}
1380
1381pub fn main() {
1382 foo(&1);
1383
1384 // Use trait alias for trait objects.
1385 let a: &Bar = &123;
1386 println!("{:?}", a);
1387 let b = Box::new(456) as Box<dyn Foo>;
1388 println!("{:?}", b);
1389}
1390```
1391"##,
1392 },
1393 LintCompletion {
1394 label: "lang_items",
1395 description: r##"# `lang_items`
1396
1397The tracking issue for this feature is: None.
1398
1399------------------------
1400
1401The `rustc` compiler has certain pluggable operations, that is,
1402functionality that isn't hard-coded into the language, but is
1403implemented in libraries, with a special marker to tell the compiler
1404it exists. The marker is the attribute `#[lang = "..."]` and there are
1405various different values of `...`, i.e. various different 'lang
1406items'.
1407
1408For example, `Box` pointers require two lang items, one for allocation
1409and one for deallocation. A freestanding program that uses the `Box`
1410sugar for dynamic allocations via `malloc` and `free`:
1411
1412```rust,ignore (libc-is-finicky)
1413#![feature(lang_items, box_syntax, start, libc, core_intrinsics, rustc_private)]
1414#![no_std]
1415use core::intrinsics;
1416use core::panic::PanicInfo;
1417
1418extern crate libc;
1419
1420#[lang = "owned_box"]
1421pub struct Box<T>(*mut T);
1422
1423#[lang = "exchange_malloc"]
1424unsafe fn allocate(size: usize, _align: usize) -> *mut u8 {
1425 let p = libc::malloc(size as libc::size_t) as *mut u8;
1426
1427 // Check if `malloc` failed:
1428 if p as usize == 0 {
1429 intrinsics::abort();
1430 }
1431
1432 p
1433}
1434
1435#[lang = "box_free"]
1436unsafe fn box_free<T: ?Sized>(ptr: *mut T) {
1437 libc::free(ptr as *mut libc::c_void)
1438}
1439
1440#[start]
1441fn main(_argc: isize, _argv: *const *const u8) -> isize {
1442 let _x = box 1;
1443
1444 0
1445}
1446
1447#[lang = "eh_personality"] extern fn rust_eh_personality() {}
1448#[lang = "panic_impl"] extern fn rust_begin_panic(info: &PanicInfo) -> ! { unsafe { intrinsics::abort() } }
1449#[no_mangle] pub extern fn rust_eh_register_frames () {}
1450#[no_mangle] pub extern fn rust_eh_unregister_frames () {}
1451```
1452
1453Note the use of `abort`: the `exchange_malloc` lang item is assumed to
1454return a valid pointer, and so needs to do the check internally.
1455
1456Other features provided by lang items include:
1457
1458- overloadable operators via traits: the traits corresponding to the
1459 `==`, `<`, dereferencing (`*`) and `+` (etc.) operators are all
1460 marked with lang items; those specific four are `eq`, `ord`,
1461 `deref`, and `add` respectively.
1462- stack unwinding and general failure; the `eh_personality`,
1463 `panic` and `panic_bounds_check` lang items.
1464- the traits in `std::marker` used to indicate types of
1465 various kinds; lang items `send`, `sync` and `copy`.
1466- the marker types and variance indicators found in
1467 `std::marker`; lang items `covariant_type`,
1468 `contravariant_lifetime`, etc.
1469
1470Lang items are loaded lazily by the compiler; e.g. if one never uses
1471`Box` then there is no need to define functions for `exchange_malloc`
1472and `box_free`. `rustc` will emit an error when an item is needed
1473but not found in the current crate or any that it depends on.
1474
1475Most lang items are defined by `libcore`, but if you're trying to build
1476an executable without the standard library, you'll run into the need
1477for lang items. The rest of this page focuses on this use-case, even though
1478lang items are a bit broader than that.
1479
1480### Using libc
1481
1482In order to build a `#[no_std]` executable we will need libc as a dependency.
1483We can specify this using our `Cargo.toml` file:
1484
1485```toml
1486[dependencies]
1487libc = { version = "0.2.14", default-features = false }
1488```
1489
1490Note that the default features have been disabled. This is a critical step -
1491**the default features of libc include the standard library and so must be
1492disabled.**
1493
1494### Writing an executable without stdlib
1495
1496Controlling the entry point is possible in two ways: the `#[start]` attribute,
1497or overriding the default shim for the C `main` function with your own.
1498
1499The function marked `#[start]` is passed the command line parameters
1500in the same format as C:
1501
1502```rust,ignore (libc-is-finicky)
1503#![feature(lang_items, core_intrinsics, rustc_private)]
1504#![feature(start)]
1505#![no_std]
1506use core::intrinsics;
1507use core::panic::PanicInfo;
1508
1509// Pull in the system libc library for what crt0.o likely requires.
1510extern crate libc;
1511
1512// Entry point for this program.
1513#[start]
1514fn start(_argc: isize, _argv: *const *const u8) -> isize {
1515 0
1516}
1517
1518// These functions are used by the compiler, but not
1519// for a bare-bones hello world. These are normally
1520// provided by libstd.
1521#[lang = "eh_personality"]
1522#[no_mangle]
1523pub extern fn rust_eh_personality() {
1524}
1525
1526#[lang = "panic_impl"]
1527#[no_mangle]
1528pub extern fn rust_begin_panic(info: &PanicInfo) -> ! {
1529 unsafe { intrinsics::abort() }
1530}
1531```
1532
1533To override the compiler-inserted `main` shim, one has to disable it
1534with `#![no_main]` and then create the appropriate symbol with the
1535correct ABI and the correct name, which requires overriding the
1536compiler's name mangling too:
1537
1538```rust,ignore (libc-is-finicky)
1539#![feature(lang_items, core_intrinsics, rustc_private)]
1540#![feature(start)]
1541#![no_std]
1542#![no_main]
1543use core::intrinsics;
1544use core::panic::PanicInfo;
1545
1546// Pull in the system libc library for what crt0.o likely requires.
1547extern crate libc;
1548
1549// Entry point for this program.
1550#[no_mangle] // ensure that this symbol is called `main` in the output
1551pub extern fn main(_argc: i32, _argv: *const *const u8) -> i32 {
1552 0
1553}
1554
1555// These functions are used by the compiler, but not
1556// for a bare-bones hello world. These are normally
1557// provided by libstd.
1558#[lang = "eh_personality"]
1559#[no_mangle]
1560pub extern fn rust_eh_personality() {
1561}
1562
1563#[lang = "panic_impl"]
1564#[no_mangle]
1565pub extern fn rust_begin_panic(info: &PanicInfo) -> ! {
1566 unsafe { intrinsics::abort() }
1567}
1568```
1569
1570In many cases, you may need to manually link to the `compiler_builtins` crate
1571when building a `no_std` binary. You may observe this via linker error messages
1572such as "```undefined reference to `__rust_probestack'```".
1573
1574## More about the language items
1575
1576The compiler currently makes a few assumptions about symbols which are
1577available in the executable to call. Normally these functions are provided by
1578the standard library, but without it you must define your own. These symbols
1579are called "language items", and they each have an internal name, and then a
1580signature that an implementation must conform to.
1581
1582The first of these functions, `rust_eh_personality`, is used by the failure
1583mechanisms of the compiler. This is often mapped to GCC's personality function
1584(see the [libstd implementation][unwind] for more information), but crates
1585which do not trigger a panic can be assured that this function is never
1586called. The language item's name is `eh_personality`.
1587
1588[unwind]: https://github.com/rust-lang/rust/blob/master/src/libpanic_unwind/gcc.rs
1589
1590The second function, `rust_begin_panic`, is also used by the failure mechanisms of the
1591compiler. When a panic happens, this controls the message that's displayed on
1592the screen. While the language item's name is `panic_impl`, the symbol name is
1593`rust_begin_panic`.
1594
1595Finally, a `eh_catch_typeinfo` static is needed for certain targets which
1596implement Rust panics on top of C++ exceptions.
1597
1598## List of all language items
1599
1600This is a list of all language items in Rust along with where they are located in
1601the source code.
1602
1603- Primitives
1604 - `i8`: `libcore/num/mod.rs`
1605 - `i16`: `libcore/num/mod.rs`
1606 - `i32`: `libcore/num/mod.rs`
1607 - `i64`: `libcore/num/mod.rs`
1608 - `i128`: `libcore/num/mod.rs`
1609 - `isize`: `libcore/num/mod.rs`
1610 - `u8`: `libcore/num/mod.rs`
1611 - `u16`: `libcore/num/mod.rs`
1612 - `u32`: `libcore/num/mod.rs`
1613 - `u64`: `libcore/num/mod.rs`
1614 - `u128`: `libcore/num/mod.rs`
1615 - `usize`: `libcore/num/mod.rs`
1616 - `f32`: `libstd/f32.rs`
1617 - `f64`: `libstd/f64.rs`
1618 - `char`: `libcore/char.rs`
1619 - `slice`: `liballoc/slice.rs`
1620 - `str`: `liballoc/str.rs`
1621 - `const_ptr`: `libcore/ptr.rs`
1622 - `mut_ptr`: `libcore/ptr.rs`
1623 - `unsafe_cell`: `libcore/cell.rs`
1624- Runtime
1625 - `start`: `libstd/rt.rs`
1626 - `eh_personality`: `libpanic_unwind/emcc.rs` (EMCC)
1627 - `eh_personality`: `libpanic_unwind/gcc.rs` (GNU)
1628 - `eh_personality`: `libpanic_unwind/seh.rs` (SEH)
1629 - `eh_catch_typeinfo`: `libpanic_unwind/emcc.rs` (EMCC)
1630 - `panic`: `libcore/panicking.rs`
1631 - `panic_bounds_check`: `libcore/panicking.rs`
1632 - `panic_impl`: `libcore/panicking.rs`
1633 - `panic_impl`: `libstd/panicking.rs`
1634- Allocations
1635 - `owned_box`: `liballoc/boxed.rs`
1636 - `exchange_malloc`: `liballoc/heap.rs`
1637 - `box_free`: `liballoc/heap.rs`
1638- Operands
1639 - `not`: `libcore/ops/bit.rs`
1640 - `bitand`: `libcore/ops/bit.rs`
1641 - `bitor`: `libcore/ops/bit.rs`
1642 - `bitxor`: `libcore/ops/bit.rs`
1643 - `shl`: `libcore/ops/bit.rs`
1644 - `shr`: `libcore/ops/bit.rs`
1645 - `bitand_assign`: `libcore/ops/bit.rs`
1646 - `bitor_assign`: `libcore/ops/bit.rs`
1647 - `bitxor_assign`: `libcore/ops/bit.rs`
1648 - `shl_assign`: `libcore/ops/bit.rs`
1649 - `shr_assign`: `libcore/ops/bit.rs`
1650 - `deref`: `libcore/ops/deref.rs`
1651 - `deref_mut`: `libcore/ops/deref.rs`
1652 - `index`: `libcore/ops/index.rs`
1653 - `index_mut`: `libcore/ops/index.rs`
1654 - `add`: `libcore/ops/arith.rs`
1655 - `sub`: `libcore/ops/arith.rs`
1656 - `mul`: `libcore/ops/arith.rs`
1657 - `div`: `libcore/ops/arith.rs`
1658 - `rem`: `libcore/ops/arith.rs`
1659 - `neg`: `libcore/ops/arith.rs`
1660 - `add_assign`: `libcore/ops/arith.rs`
1661 - `sub_assign`: `libcore/ops/arith.rs`
1662 - `mul_assign`: `libcore/ops/arith.rs`
1663 - `div_assign`: `libcore/ops/arith.rs`
1664 - `rem_assign`: `libcore/ops/arith.rs`
1665 - `eq`: `libcore/cmp.rs`
1666 - `ord`: `libcore/cmp.rs`
1667- Functions
1668 - `fn`: `libcore/ops/function.rs`
1669 - `fn_mut`: `libcore/ops/function.rs`
1670 - `fn_once`: `libcore/ops/function.rs`
1671 - `generator_state`: `libcore/ops/generator.rs`
1672 - `generator`: `libcore/ops/generator.rs`
1673- Other
1674 - `coerce_unsized`: `libcore/ops/unsize.rs`
1675 - `drop`: `libcore/ops/drop.rs`
1676 - `drop_in_place`: `libcore/ptr.rs`
1677 - `clone`: `libcore/clone.rs`
1678 - `copy`: `libcore/marker.rs`
1679 - `send`: `libcore/marker.rs`
1680 - `sized`: `libcore/marker.rs`
1681 - `unsize`: `libcore/marker.rs`
1682 - `sync`: `libcore/marker.rs`
1683 - `phantom_data`: `libcore/marker.rs`
1684 - `discriminant_kind`: `libcore/marker.rs`
1685 - `freeze`: `libcore/marker.rs`
1686 - `debug_trait`: `libcore/fmt/mod.rs`
1687 - `non_zero`: `libcore/nonzero.rs`
1688 - `arc`: `liballoc/sync.rs`
1689 - `rc`: `liballoc/rc.rs`
1690"##,
1691 },
1692 LintCompletion {
1693 label: "doc_spotlight",
1694 description: r##"# `doc_spotlight`
1695
1696The tracking issue for this feature is: [#45040]
1697
1698The `doc_spotlight` feature allows the use of the `spotlight` parameter to the `#[doc]` attribute,
1699to "spotlight" a specific trait on the return values of functions. Adding a `#[doc(spotlight)]`
1700attribute to a trait definition will make rustdoc print extra information for functions which return
1701a type that implements that trait. For example, this attribute is applied to the `Iterator`,
1702`io::Read`, `io::Write`, and `Future` traits in the standard library.
1703
1704You can do this on your own traits, like this:
1705
1706```
1707#![feature(doc_spotlight)]
1708
1709#[doc(spotlight)]
1710pub trait MyTrait {}
1711
1712pub struct MyStruct;
1713impl MyTrait for MyStruct {}
1714
1715/// The docs for this function will have an extra line about `MyStruct` implementing `MyTrait`,
1716/// without having to write that yourself!
1717pub fn my_fn() -> MyStruct { MyStruct }
1718```
1719
1720This feature was originally implemented in PR [#45039].
1721
1722[#45040]: https://github.com/rust-lang/rust/issues/45040
1723[#45039]: https://github.com/rust-lang/rust/pull/45039
1724"##,
1725 },
1726 LintCompletion {
1727 label: "c_variadic",
1728 description: r##"# `c_variadic`
1729
1730The tracking issue for this feature is: [#44930]
1731
1732[#44930]: https://github.com/rust-lang/rust/issues/44930
1733
1734------------------------
1735
1736The `c_variadic` language feature enables C-variadic functions to be
1737defined in Rust. The may be called both from within Rust and via FFI.
1738
1739## Examples
1740
1741```rust
1742#![feature(c_variadic)]
1743
1744pub unsafe extern "C" fn add(n: usize, mut args: ...) -> usize {
1745 let mut sum = 0;
1746 for _ in 0..n {
1747 sum += args.arg::<usize>();
1748 }
1749 sum
1750}
1751```
1752"##,
1753 },
1754 LintCompletion {
1755 label: "intra_doc_pointers",
1756 description: r##"# `intra-doc-pointers`
1757
1758The tracking issue for this feature is: [#80896]
1759
1760[#80896]: https://github.com/rust-lang/rust/issues/80896
1761
1762------------------------
1763
1764Rustdoc does not currently allow disambiguating between `*const` and `*mut`, and
1765raw pointers in intra-doc links are unstable until it does.
1766
1767```rust
1768#![feature(intra_doc_pointers)]
1769//! [pointer::add]
1770```
1771"##,
1772 },
1773 LintCompletion {
1774 label: "box_syntax",
1775 description: r##"# `box_syntax`
1776
1777The tracking issue for this feature is: [#49733]
1778
1779[#49733]: https://github.com/rust-lang/rust/issues/49733
1780
1781See also [`box_patterns`](box-patterns.md)
1782
1783------------------------
1784
1785Currently the only stable way to create a `Box` is via the `Box::new` method.
1786Also it is not possible in stable Rust to destructure a `Box` in a match
1787pattern. The unstable `box` keyword can be used to create a `Box`. An example
1788usage would be:
1789
1790```rust
1791#![feature(box_syntax)]
1792
1793fn main() {
1794 let b = box 5;
1795}
1796```
1797"##,
1798 },
1799 LintCompletion {
1800 label: "unsized_locals",
1801 description: r##"# `unsized_locals`
1802
1803The tracking issue for this feature is: [#48055]
1804
1805[#48055]: https://github.com/rust-lang/rust/issues/48055
1806
1807------------------------
1808
1809This implements [RFC1909]. When turned on, you can have unsized arguments and locals:
1810
1811[RFC1909]: https://github.com/rust-lang/rfcs/blob/master/text/1909-unsized-rvalues.md
1812
1813```rust
1814#![allow(incomplete_features)]
1815#![feature(unsized_locals, unsized_fn_params)]
1816
1817use std::any::Any;
1818
1819fn main() {
1820 let x: Box<dyn Any> = Box::new(42);
1821 let x: dyn Any = *x;
1822 // ^ unsized local variable
1823 // ^^ unsized temporary
1824 foo(x);
1825}
1826
1827fn foo(_: dyn Any) {}
1828// ^^^^^^ unsized argument
1829```
1830
1831The RFC still forbids the following unsized expressions:
1832
1833```rust,compile_fail
1834#![feature(unsized_locals)]
1835
1836use std::any::Any;
1837
1838struct MyStruct<T: ?Sized> {
1839 content: T,
1840}
1841
1842struct MyTupleStruct<T: ?Sized>(T);
1843
1844fn answer() -> Box<dyn Any> {
1845 Box::new(42)
1846}
1847
1848fn main() {
1849 // You CANNOT have unsized statics.
1850 static X: dyn Any = *answer(); // ERROR
1851 const Y: dyn Any = *answer(); // ERROR
1852
1853 // You CANNOT have struct initialized unsized.
1854 MyStruct { content: *answer() }; // ERROR
1855 MyTupleStruct(*answer()); // ERROR
1856 (42, *answer()); // ERROR
1857
1858 // You CANNOT have unsized return types.
1859 fn my_function() -> dyn Any { *answer() } // ERROR
1860
1861 // You CAN have unsized local variables...
1862 let mut x: dyn Any = *answer(); // OK
1863 // ...but you CANNOT reassign to them.
1864 x = *answer(); // ERROR
1865
1866 // You CANNOT even initialize them separately.
1867 let y: dyn Any; // OK
1868 y = *answer(); // ERROR
1869
1870 // Not mentioned in the RFC, but by-move captured variables are also Sized.
1871 let x: dyn Any = *answer();
1872 (move || { // ERROR
1873 let y = x;
1874 })();
1875
1876 // You CAN create a closure with unsized arguments,
1877 // but you CANNOT call it.
1878 // This is an implementation detail and may be changed in the future.
1879 let f = |x: dyn Any| {};
1880 f(*answer()); // ERROR
1881}
1882```
1883
1884## By-value trait objects
1885
1886With this feature, you can have by-value `self` arguments without `Self: Sized` bounds.
1887
1888```rust
1889#![feature(unsized_fn_params)]
1890
1891trait Foo {
1892 fn foo(self) {}
1893}
1894
1895impl<T: ?Sized> Foo for T {}
1896
1897fn main() {
1898 let slice: Box<[i32]> = Box::new([1, 2, 3]);
1899 <[i32] as Foo>::foo(*slice);
1900}
1901```
1902
1903And `Foo` will also be object-safe.
1904
1905```rust
1906#![feature(unsized_fn_params)]
1907
1908trait Foo {
1909 fn foo(self) {}
1910}
1911
1912impl<T: ?Sized> Foo for T {}
1913
1914fn main () {
1915 let slice: Box<dyn Foo> = Box::new([1, 2, 3]);
1916 // doesn't compile yet
1917 <dyn Foo as Foo>::foo(*slice);
1918}
1919```
1920
1921One of the objectives of this feature is to allow `Box<dyn FnOnce>`.
1922
1923## Variable length arrays
1924
1925The 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]`.
1926
1927```rust,ignore (not-yet-implemented)
1928#![feature(unsized_locals)]
1929
1930fn mergesort<T: Ord>(a: &mut [T]) {
1931 let mut tmp = [T; dyn a.len()];
1932 // ...
1933}
1934
1935fn main() {
1936 let mut a = [3, 1, 5, 6];
1937 mergesort(&mut a);
1938 assert_eq!(a, [1, 3, 5, 6]);
1939}
1940```
1941
1942VLAs 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]`.
1943
1944## Advisory on stack usage
1945
1946It's advised not to casually use the `#![feature(unsized_locals)]` feature. Typical use-cases are:
1947
1948- When you need a by-value trait objects.
1949- When you really need a fast allocation of small temporary arrays.
1950
1951Another 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
1952
1953```rust
1954#![feature(unsized_locals)]
1955
1956fn main() {
1957 let x: Box<[i32]> = Box::new([1, 2, 3, 4, 5]);
1958 let _x = {{{{{{{{{{*x}}}}}}}}}};
1959}
1960```
1961
1962and the code
1963
1964```rust
1965#![feature(unsized_locals)]
1966
1967fn main() {
1968 for _ in 0..10 {
1969 let x: Box<[i32]> = Box::new([1, 2, 3, 4, 5]);
1970 let _x = *x;
1971 }
1972}
1973```
1974
1975will unnecessarily extend the stack frame.
1976"##,
1977 },
1978 LintCompletion {
1979 label: "arbitrary_enum_discriminant",
1980 description: r##"# `arbitrary_enum_discriminant`
1981
1982The tracking issue for this feature is: [#60553]
1983
1984[#60553]: https://github.com/rust-lang/rust/issues/60553
1985
1986------------------------
1987
1988The `arbitrary_enum_discriminant` feature permits tuple-like and
1989struct-like enum variants with `#[repr(<int-type>)]` to have explicit discriminants.
1990
1991## Examples
1992
1993```rust
1994#![feature(arbitrary_enum_discriminant)]
1995
1996#[allow(dead_code)]
1997#[repr(u8)]
1998enum Enum {
1999 Unit = 3,
2000 Tuple(u16) = 2,
2001 Struct {
2002 a: u8,
2003 b: u16,
2004 } = 1,
2005}
2006
2007impl Enum {
2008 fn tag(&self) -> u8 {
2009 unsafe { *(self as *const Self as *const u8) }
2010 }
2011}
2012
2013assert_eq!(3, Enum::Unit.tag());
2014assert_eq!(2, Enum::Tuple(5).tag());
2015assert_eq!(1, Enum::Struct{a: 7, b: 11}.tag());
2016```
2017"##,
2018 },
2019 LintCompletion {
2020 label: "unboxed_closures",
2021 description: r##"# `unboxed_closures`
2022
2023The tracking issue for this feature is [#29625]
2024
2025See Also: [`fn_traits`](../library-features/fn-traits.md)
2026
2027[#29625]: https://github.com/rust-lang/rust/issues/29625
2028
2029----
2030
2031The `unboxed_closures` feature allows you to write functions using the `"rust-call"` ABI,
2032required for implementing the [`Fn*`] family of traits. `"rust-call"` functions must have
2033exactly one (non self) argument, a tuple representing the argument list.
2034
2035[`Fn*`]: https://doc.rust-lang.org/std/ops/trait.Fn.html
2036
2037```rust
2038#![feature(unboxed_closures)]
2039
2040extern "rust-call" fn add_args(args: (u32, u32)) -> u32 {
2041 args.0 + args.1
2042}
2043
2044fn main() {}
2045```
2046"##,
2047 },
2048 LintCompletion {
2049 label: "custom_test_frameworks",
2050 description: r##"# `custom_test_frameworks`
2051
2052The tracking issue for this feature is: [#50297]
2053
2054[#50297]: https://github.com/rust-lang/rust/issues/50297
2055
2056------------------------
2057
2058The `custom_test_frameworks` feature allows the use of `#[test_case]` and `#![test_runner]`.
2059Any function, const, or static can be annotated with `#[test_case]` causing it to be aggregated (like `#[test]`)
2060and be passed to the test runner determined by the `#![test_runner]` crate attribute.
2061
2062```rust
2063#![feature(custom_test_frameworks)]
2064#![test_runner(my_runner)]
2065
2066fn my_runner(tests: &[&i32]) {
2067 for t in tests {
2068 if **t == 0 {
2069 println!("PASSED");
2070 } else {
2071 println!("FAILED");
2072 }
2073 }
2074}
2075
2076#[test_case]
2077const WILL_PASS: i32 = 0;
2078
2079#[test_case]
2080const WILL_FAIL: i32 = 4;
2081```
2082"##,
2083 },
2084 LintCompletion {
2085 label: "abi_msp430_interrupt", 99 label: "abi_msp430_interrupt",
2086 description: r##"# `abi_msp430_interrupt` 100 description: r##"# `abi_msp430_interrupt`
2087 101
@@ -2128,200 +142,6 @@ Disassembly of section .text:
2128"##, 142"##,
2129 }, 143 },
2130 LintCompletion { 144 LintCompletion {
2131 label: "impl_trait_in_bindings",
2132 description: r##"# `impl_trait_in_bindings`
2133
2134The tracking issue for this feature is: [#63065]
2135
2136[#63065]: https://github.com/rust-lang/rust/issues/63065
2137
2138------------------------
2139
2140The `impl_trait_in_bindings` feature gate lets you use `impl Trait` syntax in
2141`let`, `static`, and `const` bindings.
2142
2143A simple example is:
2144
2145```rust
2146#![feature(impl_trait_in_bindings)]
2147
2148use std::fmt::Debug;
2149
2150fn main() {
2151 let a: impl Debug + Clone = 42;
2152 let b = a.clone();
2153 println!("{:?}", b); // prints `42`
2154}
2155```
2156
2157Note however that because the types of `a` and `b` are opaque in the above
2158example, calling inherent methods or methods outside of the specified traits
2159(e.g., `a.abs()` or `b.abs()`) is not allowed, and yields an error.
2160"##,
2161 },
2162 LintCompletion {
2163 label: "cfg_version",
2164 description: r##"# `cfg_version`
2165
2166The tracking issue for this feature is: [#64796]
2167
2168[#64796]: https://github.com/rust-lang/rust/issues/64796
2169
2170------------------------
2171
2172The `cfg_version` feature makes it possible to execute different code
2173depending on the compiler version.
2174
2175## Examples
2176
2177```rust
2178#![feature(cfg_version)]
2179
2180#[cfg(version("1.42"))]
2181fn a() {
2182 // ...
2183}
2184
2185#[cfg(not(version("1.42")))]
2186fn a() {
2187 // ...
2188}
2189
2190fn b() {
2191 if cfg!(version("1.42")) {
2192 // ...
2193 } else {
2194 // ...
2195 }
2196}
2197```
2198"##,
2199 },
2200 LintCompletion {
2201 label: "link_cfg",
2202 description: r##"# `link_cfg`
2203
2204This feature is internal to the Rust compiler and is not intended for general use.
2205
2206------------------------
2207"##,
2208 },
2209 LintCompletion {
2210 label: "infer_static_outlives_requirements",
2211 description: r##"# `infer_static_outlives_requirements`
2212
2213The tracking issue for this feature is: [#54185]
2214
2215[#54185]: https://github.com/rust-lang/rust/issues/54185
2216
2217------------------------
2218The `infer_static_outlives_requirements` feature indicates that certain
2219`'static` outlives requirements can be inferred by the compiler rather than
2220stating them explicitly.
2221
2222Note: It is an accompanying feature to `infer_outlives_requirements`,
2223which must be enabled to infer outlives requirements.
2224
2225For example, currently generic struct definitions that contain
2226references, require where-clauses of the form T: 'static. By using
2227this feature the outlives predicates will be inferred, although
2228they may still be written explicitly.
2229
2230```rust,ignore (pseudo-Rust)
2231struct Foo<U> where U: 'static { // <-- currently required
2232 bar: Bar<U>
2233}
2234struct Bar<T: 'static> {
2235 x: T,
2236}
2237```
2238
2239
2240## Examples:
2241
2242```rust,ignore (pseudo-Rust)
2243#![feature(infer_outlives_requirements)]
2244#![feature(infer_static_outlives_requirements)]
2245
2246#[rustc_outlives]
2247// Implicitly infer U: 'static
2248struct Foo<U> {
2249 bar: Bar<U>
2250}
2251struct Bar<T: 'static> {
2252 x: T,
2253}
2254```
2255"##,
2256 },
2257 LintCompletion {
2258 label: "marker_trait_attr",
2259 description: r##"# `marker_trait_attr`
2260
2261The tracking issue for this feature is: [#29864]
2262
2263[#29864]: https://github.com/rust-lang/rust/issues/29864
2264
2265------------------------
2266
2267Normally, Rust keeps you from adding trait implementations that could
2268overlap with each other, as it would be ambiguous which to use. This
2269feature, however, carves out an exception to that rule: a trait can
2270opt-in to having overlapping implementations, at the cost that those
2271implementations are not allowed to override anything (and thus the
2272trait itself cannot have any associated items, as they're pointless
2273when they'd need to do the same thing for every type anyway).
2274
2275```rust
2276#![feature(marker_trait_attr)]
2277
2278#[marker] trait CheapToClone: Clone {}
2279
2280impl<T: Copy> CheapToClone for T {}
2281
2282// These could potentially overlap with the blanket implementation above,
2283// so are only allowed because CheapToClone is a marker trait.
2284impl<T: CheapToClone, U: CheapToClone> CheapToClone for (T, U) {}
2285impl<T: CheapToClone> CheapToClone for std::ops::Range<T> {}
2286
2287fn cheap_clone<T: CheapToClone>(t: T) -> T {
2288 t.clone()
2289}
2290```
2291
2292This is expected to replace the unstable `overlapping_marker_traits`
2293feature, which applied to all empty traits (without needing an opt-in).
2294"##,
2295 },
2296 LintCompletion {
2297 label: "doc_masked",
2298 description: r##"# `doc_masked`
2299
2300The tracking issue for this feature is: [#44027]
2301
2302-----
2303
2304The `doc_masked` feature allows a crate to exclude types from a given crate from appearing in lists
2305of trait implementations. The specifics of the feature are as follows:
2306
23071. When rustdoc encounters an `extern crate` statement annotated with a `#[doc(masked)]` attribute,
2308 it marks the crate as being masked.
2309
23102. When listing traits a given type implements, rustdoc ensures that traits from masked crates are
2311 not emitted into the documentation.
2312
23133. When listing types that implement a given trait, rustdoc ensures that types from masked crates
2314 are not emitted into the documentation.
2315
2316This feature was introduced in PR [#44026] to ensure that compiler-internal and
2317implementation-specific types and traits were not included in the standard library's documentation.
2318Such types would introduce broken links into the documentation.
2319
2320[#44026]: https://github.com/rust-lang/rust/pull/44026
2321[#44027]: https://github.com/rust-lang/rust/pull/44027
2322"##,
2323 },
2324 LintCompletion {
2325 label: "abi_ptx", 145 label: "abi_ptx",
2326 description: r##"# `abi_ptx` 146 description: r##"# `abi_ptx`
2327 147
@@ -2386,336 +206,90 @@ $ cat $(find -name '*.s')
2386"##, 206"##,
2387 }, 207 },
2388 LintCompletion { 208 LintCompletion {
2389 label: "profiler_runtime", 209 label: "abi_thiscall",
2390 description: r##"# `profiler_runtime` 210 description: r##"# `abi_thiscall`
2391
2392The tracking issue for this feature is: [#42524](https://github.com/rust-lang/rust/issues/42524).
2393
2394------------------------
2395"##,
2396 },
2397 LintCompletion {
2398 label: "crate_visibility_modifier",
2399 description: r##"# `crate_visibility_modifier`
2400
2401The tracking issue for this feature is: [#53120]
2402
2403[#53120]: https://github.com/rust-lang/rust/issues/53120
2404
2405-----
2406
2407The `crate_visibility_modifier` feature allows the `crate` keyword to be used
2408as a visibility modifier synonymous to `pub(crate)`, indicating that a type
2409(function, _&c._) is to be visible to the entire enclosing crate, but not to
2410other crates.
2411
2412```rust
2413#![feature(crate_visibility_modifier)]
2414
2415crate struct Foo {
2416 bar: usize,
2417}
2418```
2419"##,
2420 },
2421 LintCompletion {
2422 label: "doc_cfg",
2423 description: r##"# `doc_cfg`
2424
2425The tracking issue for this feature is: [#43781]
2426
2427------
2428
2429The `doc_cfg` feature allows an API be documented as only available in some specific platforms.
2430This attribute has two effects:
2431
24321. In the annotated item's documentation, there will be a message saying "This is supported on
2433 (platform) only".
2434
24352. The item's doc-tests will only run on the specific platform.
2436
2437In addition to allowing the use of the `#[doc(cfg)]` attribute, this feature enables the use of a
2438special conditional compilation flag, `#[cfg(doc)]`, set whenever building documentation on your
2439crate.
2440
2441This feature was introduced as part of PR [#43348] to allow the platform-specific parts of the
2442standard library be documented.
2443
2444```rust
2445#![feature(doc_cfg)]
2446
2447#[cfg(any(windows, doc))]
2448#[doc(cfg(windows))]
2449/// The application's icon in the notification area (a.k.a. system tray).
2450///
2451/// # Examples
2452///
2453/// ```no_run
2454/// extern crate my_awesome_ui_library;
2455/// use my_awesome_ui_library::current_app;
2456/// use my_awesome_ui_library::windows::notification;
2457///
2458/// let icon = current_app().get::<notification::Icon>();
2459/// icon.show();
2460/// icon.show_message("Hello");
2461/// ```
2462pub struct Icon {
2463 // ...
2464}
2465```
2466
2467[#43781]: https://github.com/rust-lang/rust/issues/43781
2468[#43348]: https://github.com/rust-lang/rust/issues/43348
2469"##,
2470 },
2471 LintCompletion {
2472 label: "unsized_tuple_coercion",
2473 description: r##"# `unsized_tuple_coercion`
2474 211
2475The tracking issue for this feature is: [#42877] 212The tracking issue for this feature is: [#42202]
2476 213
2477[#42877]: https://github.com/rust-lang/rust/issues/42877 214[#42202]: https://github.com/rust-lang/rust/issues/42202
2478 215
2479------------------------ 216------------------------
2480 217
2481This is a part of [RFC0401]. According to the RFC, there should be an implementation like this: 218The MSVC ABI on x86 Windows uses the `thiscall` calling convention for C++
2482 219instance methods by default; it is identical to the usual (C) calling
2483```rust,ignore (partial-example) 220convention on x86 Windows except that the first parameter of the method,
2484impl<..., T, U: ?Sized> Unsized<(..., U)> for (..., T) where T: Unsized<U> {} 221the `this` pointer, is passed in the ECX register.
2485```
2486
2487This implementation is currently gated behind `#[feature(unsized_tuple_coercion)]` to avoid insta-stability. Therefore you can use it like this:
2488
2489```rust
2490#![feature(unsized_tuple_coercion)]
2491
2492fn main() {
2493 let x : ([i32; 3], [i32; 3]) = ([1, 2, 3], [4, 5, 6]);
2494 let y : &([i32; 3], [i32]) = &x;
2495 assert_eq!(y.1[0], 4);
2496}
2497```
2498
2499[RFC0401]: https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md
2500"##, 222"##,
2501 }, 223 },
2502 LintCompletion { 224 LintCompletion {
2503 label: "no_sanitize", 225 label: "allocator_api",
2504 description: r##"# `no_sanitize` 226 description: r##"# `allocator_api`
2505 227
2506The tracking issue for this feature is: [#39699] 228The tracking issue for this feature is [#32838]
2507 229
2508[#39699]: https://github.com/rust-lang/rust/issues/39699 230[#32838]: https://github.com/rust-lang/rust/issues/32838
2509 231
2510------------------------ 232------------------------
2511 233
2512The `no_sanitize` attribute can be used to selectively disable sanitizer 234Sometimes you want the memory for one collection to use a different
2513instrumentation in an annotated function. This might be useful to: avoid 235allocator than the memory for another collection. In this case,
2514instrumentation overhead in a performance critical function, or avoid 236replacing the global allocator is not a workable option. Instead,
2515instrumenting code that contains constructs unsupported by given sanitizer. 237you need to pass in an instance of an `AllocRef` to each collection
2516 238for which you want a custom allocator.
2517The precise effect of this annotation depends on particular sanitizer in use.
2518For example, with `no_sanitize(thread)`, the thread sanitizer will no longer
2519instrument non-atomic store / load operations, but it will instrument atomic
2520operations to avoid reporting false positives and provide meaning full stack
2521traces.
2522
2523## Examples
2524
2525``` rust
2526#![feature(no_sanitize)]
2527 239
2528#[no_sanitize(address)] 240TBD
2529fn foo() {
2530 // ...
2531}
2532```
2533"##, 241"##,
2534 }, 242 },
2535 LintCompletion { 243 LintCompletion {
2536 label: "try_blocks", 244 label: "allocator_internals",
2537 description: r##"# `try_blocks` 245 description: r##"# `allocator_internals`
2538
2539The tracking issue for this feature is: [#31436]
2540 246
2541[#31436]: https://github.com/rust-lang/rust/issues/31436 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.
2542 250
2543------------------------ 251------------------------
2544
2545The `try_blocks` feature adds support for `try` blocks. A `try`
2546block creates a new scope one can use the `?` operator in.
2547
2548```rust,edition2018
2549#![feature(try_blocks)]
2550
2551use std::num::ParseIntError;
2552
2553let result: Result<i32, ParseIntError> = try {
2554 "1".parse::<i32>()?
2555 + "2".parse::<i32>()?
2556 + "3".parse::<i32>()?
2557};
2558assert_eq!(result, Ok(6));
2559
2560let result: Result<i32, ParseIntError> = try {
2561 "1".parse::<i32>()?
2562 + "foo".parse::<i32>()?
2563 + "3".parse::<i32>()?
2564};
2565assert!(result.is_err());
2566```
2567"##, 252"##,
2568 }, 253 },
2569 LintCompletion { 254 LintCompletion {
2570 label: "transparent_unions", 255 label: "arbitrary_enum_discriminant",
2571 description: r##"# `transparent_unions` 256 description: r##"# `arbitrary_enum_discriminant`
2572
2573The tracking issue for this feature is [#60405]
2574
2575[#60405]: https://github.com/rust-lang/rust/issues/60405
2576
2577----
2578 257
2579The `transparent_unions` feature allows you mark `union`s as 258The tracking issue for this feature is: [#60553]
2580`#[repr(transparent)]`. A `union` may be `#[repr(transparent)]` in exactly the
2581same conditions in which a `struct` may be `#[repr(transparent)]` (generally,
2582this means the `union` must have exactly one non-zero-sized field). Some
2583concrete illustrations follow.
2584 259
2585```rust 260[#60553]: https://github.com/rust-lang/rust/issues/60553
2586#![feature(transparent_unions)]
2587 261
2588// This union has the same representation as `f32`. 262------------------------
2589#[repr(transparent)]
2590union SingleFieldUnion {
2591 field: f32,
2592}
2593 263
2594// This union has the same representation as `usize`. 264The `arbitrary_enum_discriminant` feature permits tuple-like and
2595#[repr(transparent)] 265struct-like enum variants with `#[repr(<int-type>)]` to have explicit discriminants.
2596union MultiFieldUnion {
2597 field: usize,
2598 nothing: (),
2599}
2600```
2601 266
2602For consistency with transparent `struct`s, `union`s must have exactly one 267## Examples
2603non-zero-sized field. If all fields are zero-sized, the `union` must not be
2604`#[repr(transparent)]`:
2605 268
2606```rust 269```rust
2607#![feature(transparent_unions)] 270#![feature(arbitrary_enum_discriminant)]
2608 271
2609// This (non-transparent) union is already valid in stable Rust: 272#[allow(dead_code)]
2610pub union GoodUnion { 273#[repr(u8)]
2611 pub nothing: (), 274enum Enum {
275 Unit = 3,
276 Tuple(u16) = 2,
277 Struct {
278 a: u8,
279 b: u16,
280 } = 1,
2612} 281}
2613 282
2614// Error: transparent union needs exactly one non-zero-sized field, but has 0 283impl Enum {
2615// #[repr(transparent)] 284 fn tag(&self) -> u8 {
2616// pub union BadUnion { 285 unsafe { *(self as *const Self as *const u8) }
2617// pub nothing: (), 286 }
2618// }
2619```
2620
2621The one exception is if the `union` is generic over `T` and has a field of type
2622`T`, it may be `#[repr(transparent)]` even if `T` is a zero-sized type:
2623
2624```rust
2625#![feature(transparent_unions)]
2626
2627// This union has the same representation as `T`.
2628#[repr(transparent)]
2629pub union GenericUnion<T: Copy> { // Unions with non-`Copy` fields are unstable.
2630 pub field: T,
2631 pub nothing: (),
2632} 287}
2633 288
2634// This is okay even though `()` is a zero-sized type. 289assert_eq!(3, Enum::Unit.tag());
2635pub const THIS_IS_OKAY: GenericUnion<()> = GenericUnion { field: () }; 290assert_eq!(2, Enum::Tuple(5).tag());
2636``` 291assert_eq!(1, Enum::Struct{a: 7, b: 11}.tag());
2637
2638Like transarent `struct`s, a transparent `union` of type `U` has the same
2639layout, size, and ABI as its single non-ZST field. If it is generic over a type
2640`T`, and all its fields are ZSTs except for exactly one field of type `T`, then
2641it has the same layout and ABI as `T` (even if `T` is a ZST when monomorphized).
2642
2643Like transparent `struct`s, transparent `union`s are FFI-safe if and only if
2644their underlying representation type is also FFI-safe.
2645
2646A `union` may not be eligible for the same nonnull-style optimizations that a
2647`struct` or `enum` (with the same fields) are eligible for. Adding
2648`#[repr(transparent)]` to `union` does not change this. To give a more concrete
2649example, it is unspecified whether `size_of::<T>()` is equal to
2650`size_of::<Option<T>>()`, where `T` is a `union` (regardless of whether or not
2651it is transparent). The Rust compiler is free to perform this optimization if
2652possible, but is not required to, and different compiler versions may differ in
2653their application of these optimizations.
2654"##,
2655 },
2656 LintCompletion {
2657 label: "const_eval_limit",
2658 description: r##"# `const_eval_limit`
2659
2660The tracking issue for this feature is: [#67217]
2661
2662[#67217]: https://github.com/rust-lang/rust/issues/67217
2663
2664The `const_eval_limit` allows someone to limit the evaluation steps the CTFE undertakes to evaluate a `const fn`.
2665"##,
2666 },
2667 LintCompletion {
2668 label: "link_args",
2669 description: r##"# `link_args`
2670
2671The tracking issue for this feature is: [#29596]
2672
2673[#29596]: https://github.com/rust-lang/rust/issues/29596
2674
2675------------------------
2676
2677You can tell `rustc` how to customize linking, and that is via the `link_args`
2678attribute. This attribute is applied to `extern` blocks and specifies raw flags
2679which need to get passed to the linker when producing an artifact. An example
2680usage would be:
2681
2682```rust,no_run
2683#![feature(link_args)]
2684
2685#[link_args = "-foo -bar -baz"]
2686extern "C" {}
2687# fn main() {}
2688``` 292```
2689
2690Note that this feature is currently hidden behind the `feature(link_args)` gate
2691because this is not a sanctioned way of performing linking. Right now `rustc`
2692shells out to the system linker (`gcc` on most systems, `link.exe` on MSVC), so
2693it makes sense to provide extra command line arguments, but this will not
2694always be the case. In the future `rustc` may use LLVM directly to link native
2695libraries, in which case `link_args` will have no meaning. You can achieve the
2696same effect as the `link_args` attribute with the `-C link-args` argument to
2697`rustc`.
2698
2699It is highly recommended to *not* use this attribute, and rather use the more
2700formal `#[link(...)]` attribute on `extern` blocks instead.
2701"##,
2702 },
2703 LintCompletion {
2704 label: "internal_output_capture",
2705 description: r##"# `internal_output_capture`
2706
2707This feature is internal to the Rust compiler and is not intended for general use.
2708
2709------------------------
2710"##,
2711 },
2712 LintCompletion {
2713 label: "windows_handle",
2714 description: r##"# `windows_handle`
2715
2716This feature is internal to the Rust compiler and is not intended for general use.
2717
2718------------------------
2719"##, 293"##,
2720 }, 294 },
2721 LintCompletion { 295 LintCompletion {
@@ -2748,6 +322,7 @@ Inline assembly is currently supported on the following architectures:
2748- AArch64 322- AArch64
2749- RISC-V 323- RISC-V
2750- NVPTX 324- NVPTX
325- PowerPC
2751- Hexagon 326- Hexagon
2752- MIPS32r2 and MIPS64r2 327- MIPS32r2 and MIPS64r2
2753- wasm32 328- wasm32
@@ -2757,7 +332,7 @@ Inline assembly is currently supported on the following architectures:
2757Let us start with the simplest possible example: 332Let us start with the simplest possible example:
2758 333
2759```rust,allow_fail 334```rust,allow_fail
2760# #![feature(asm)] 335#![feature(asm)]
2761unsafe { 336unsafe {
2762 asm!("nop"); 337 asm!("nop");
2763} 338}
@@ -2774,7 +349,7 @@ Now inserting an instruction that does nothing is rather boring. Let us do somet
2774actually acts on data: 349actually acts on data:
2775 350
2776```rust,allow_fail 351```rust,allow_fail
2777# #![feature(asm)] 352#![feature(asm)]
2778let x: u64; 353let x: u64;
2779unsafe { 354unsafe {
2780 asm!("mov {}, 5", out(reg) x); 355 asm!("mov {}, 5", out(reg) x);
@@ -2796,7 +371,7 @@ the template and will read the variable from there after the inline assembly fin
2796Let us see another example that also uses an input: 371Let us see another example that also uses an input:
2797 372
2798```rust,allow_fail 373```rust,allow_fail
2799# #![feature(asm)] 374#![feature(asm)]
2800let i: u64 = 3; 375let i: u64 = 3;
2801let o: u64; 376let o: u64;
2802unsafe { 377unsafe {
@@ -2836,7 +411,7 @@ readability, and allows reordering instructions without changing the argument or
2836We can further refine the above example to avoid the `mov` instruction: 411We can further refine the above example to avoid the `mov` instruction:
2837 412
2838```rust,allow_fail 413```rust,allow_fail
2839# #![feature(asm)] 414#![feature(asm)]
2840let mut x: u64 = 3; 415let mut x: u64 = 3;
2841unsafe { 416unsafe {
2842 asm!("add {0}, {number}", inout(reg) x, number = const 5); 417 asm!("add {0}, {number}", inout(reg) x, number = const 5);
@@ -2850,7 +425,7 @@ This is different from specifying an input and output separately in that it is g
2850It is also possible to specify different variables for the input and output parts of an `inout` operand: 425It is also possible to specify different variables for the input and output parts of an `inout` operand:
2851 426
2852```rust,allow_fail 427```rust,allow_fail
2853# #![feature(asm)] 428#![feature(asm)]
2854let x: u64 = 3; 429let x: u64 = 3;
2855let y: u64; 430let y: u64;
2856unsafe { 431unsafe {
@@ -2872,7 +447,7 @@ There is also a `inlateout` variant of this specifier.
2872Here is an example where `inlateout` *cannot* be used: 447Here is an example where `inlateout` *cannot* be used:
2873 448
2874```rust,allow_fail 449```rust,allow_fail
2875# #![feature(asm)] 450#![feature(asm)]
2876let mut a: u64 = 4; 451let mut a: u64 = 4;
2877let b: u64 = 4; 452let b: u64 = 4;
2878let c: u64 = 4; 453let c: u64 = 4;
@@ -2893,7 +468,7 @@ Here the compiler is free to allocate the same register for inputs `b` and `c` s
2893However the following example can use `inlateout` since the output is only modified after all input registers have been read: 468However the following example can use `inlateout` since the output is only modified after all input registers have been read:
2894 469
2895```rust,allow_fail 470```rust,allow_fail
2896# #![feature(asm)] 471#![feature(asm)]
2897let mut a: u64 = 4; 472let mut a: u64 = 4;
2898let b: u64 = 4; 473let b: u64 = 4;
2899unsafe { 474unsafe {
@@ -2912,7 +487,7 @@ While `reg` is generally available on any architecture, these are highly archite
2912among others can be addressed by their name. 487among others can be addressed by their name.
2913 488
2914```rust,allow_fail,no_run 489```rust,allow_fail,no_run
2915# #![feature(asm)] 490#![feature(asm)]
2916let cmd = 0xd1; 491let cmd = 0xd1;
2917unsafe { 492unsafe {
2918 asm!("out 0x64, eax", in("eax") cmd); 493 asm!("out 0x64, eax", in("eax") cmd);
@@ -2928,7 +503,7 @@ Note that unlike other operand types, explicit register operands cannot be used
2928Consider this example which uses the x86 `mul` instruction: 503Consider this example which uses the x86 `mul` instruction:
2929 504
2930```rust,allow_fail 505```rust,allow_fail
2931# #![feature(asm)] 506#![feature(asm)]
2932fn mul(a: u64, b: u64) -> u128 { 507fn mul(a: u64, b: u64) -> u128 {
2933 let lo: u64; 508 let lo: u64;
2934 let hi: u64; 509 let hi: u64;
@@ -2964,7 +539,7 @@ We need to tell the compiler about this since it may need to save and restore th
2964around the inline assembly block. 539around the inline assembly block.
2965 540
2966```rust,allow_fail 541```rust,allow_fail
2967# #![feature(asm)] 542#![feature(asm)]
2968let ebx: u32; 543let ebx: u32;
2969let ecx: u32; 544let ecx: u32;
2970 545
@@ -2994,7 +569,7 @@ However we still need to tell the compiler that `eax` and `edx` have been modifi
2994This can also be used with a general register class (e.g. `reg`) to obtain a scratch register for use inside the asm code: 569This can also be used with a general register class (e.g. `reg`) to obtain a scratch register for use inside the asm code:
2995 570
2996```rust,allow_fail 571```rust,allow_fail
2997# #![feature(asm)] 572#![feature(asm)]
2998// Multiply x by 6 using shifts and adds 573// Multiply x by 6 using shifts and adds
2999let mut x: u64 = 4; 574let mut x: u64 = 4;
3000unsafe { 575unsafe {
@@ -3016,7 +591,7 @@ A special operand type, `sym`, allows you to use the symbol name of a `fn` or `s
3016This allows you to call a function or access a global variable without needing to keep its address in a register. 591This allows you to call a function or access a global variable without needing to keep its address in a register.
3017 592
3018```rust,allow_fail 593```rust,allow_fail
3019# #![feature(asm)] 594#![feature(asm)]
3020extern "C" fn foo(arg: i32) { 595extern "C" fn foo(arg: i32) {
3021 println!("arg = {}", arg); 596 println!("arg = {}", arg);
3022} 597}
@@ -3028,13 +603,19 @@ fn call_foo(arg: i32) {
3028 sym foo, 603 sym foo,
3029 // 1st argument in rdi, which is caller-saved 604 // 1st argument in rdi, which is caller-saved
3030 inout("rdi") arg => _, 605 inout("rdi") arg => _,
3031 // All caller-saved registers must be marked as clobberred 606 // All caller-saved registers must be marked as clobbered
3032 out("rax") _, out("rcx") _, out("rdx") _, out("rsi") _, 607 out("rax") _, out("rcx") _, out("rdx") _, out("rsi") _,
3033 out("r8") _, out("r9") _, out("r10") _, out("r11") _, 608 out("r8") _, out("r9") _, out("r10") _, out("r11") _,
3034 out("xmm0") _, out("xmm1") _, out("xmm2") _, out("xmm3") _, 609 out("xmm0") _, out("xmm1") _, out("xmm2") _, out("xmm3") _,
3035 out("xmm4") _, out("xmm5") _, out("xmm6") _, out("xmm7") _, 610 out("xmm4") _, out("xmm5") _, out("xmm6") _, out("xmm7") _,
3036 out("xmm8") _, out("xmm9") _, out("xmm10") _, out("xmm11") _, 611 out("xmm8") _, out("xmm9") _, out("xmm10") _, out("xmm11") _,
3037 out("xmm12") _, out("xmm13") _, out("xmm14") _, out("xmm15") _, 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") _,
3038 ) 619 )
3039 } 620 }
3040} 621}
@@ -3052,7 +633,7 @@ By default the compiler will always choose the name that refers to the full regi
3052This default can be overriden by using modifiers on the template string operands, just like you would with format strings: 633This default can be overriden by using modifiers on the template string operands, just like you would with format strings:
3053 634
3054```rust,allow_fail 635```rust,allow_fail
3055# #![feature(asm)] 636#![feature(asm)]
3056let mut x: u16 = 0xab; 637let mut x: u16 = 0xab;
3057 638
3058unsafe { 639unsafe {
@@ -3077,7 +658,7 @@ For example, in x86/x86_64 and intel assembly syntax, you should wrap inputs/out
3077to indicate they are memory operands: 658to indicate they are memory operands:
3078 659
3079```rust,allow_fail 660```rust,allow_fail
3080# #![feature(asm, llvm_asm)] 661#![feature(asm, llvm_asm)]
3081# fn load_fpu_control_word(control: u16) { 662# fn load_fpu_control_word(control: u16) {
3082unsafe { 663unsafe {
3083 asm!("fldcw [{}]", in(reg) &control, options(nostack)); 664 asm!("fldcw [{}]", in(reg) &control, options(nostack));
@@ -3088,6 +669,43 @@ unsafe {
3088# } 669# }
3089``` 670```
3090 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
3091## Options 709## Options
3092 710
3093By 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. 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.
@@ -3095,7 +713,7 @@ By default, an inline assembly block is treated the same way as an external FFI
3095Let's take our previous example of an `add` instruction: 713Let's take our previous example of an `add` instruction:
3096 714
3097```rust,allow_fail 715```rust,allow_fail
3098# #![feature(asm)] 716#![feature(asm)]
3099let mut a: u64 = 4; 717let mut a: u64 = 4;
3100let b: u64 = 4; 718let b: u64 = 4;
3101unsafe { 719unsafe {
@@ -3138,7 +756,7 @@ options := "options(" option *["," option] [","] ")"
3138asm := "asm!(" format_string *("," format_string) *("," [ident "="] operand) ["," options] [","] ")" 756asm := "asm!(" format_string *("," format_string) *("," [ident "="] operand) ["," options] [","] ")"
3139``` 757```
3140 758
3141The macro will initially be supported only on ARM, AArch64, Hexagon, 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. 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.
3142 760
3143[format-syntax]: https://doc.rust-lang.org/std/fmt/#syntax 761[format-syntax]: https://doc.rust-lang.org/std/fmt/#syntax
3144 762
@@ -3187,7 +805,7 @@ Several types of operands are supported:
3187 - 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`). 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`).
3188 - You should only write to the register after all inputs are read, otherwise you may clobber an input. 806 - You should only write to the register after all inputs are read, otherwise you may clobber an input.
3189* `const <expr>` 807* `const <expr>`
3190 - `<expr>` must be an integer or floating-point constant expression. 808 - `<expr>` must be an integer constant expression.
3191 - The value of the expression is formatted as a string and substituted directly into the asm template string. 809 - The value of the expression is formatted as a string and substituted directly into the asm template string.
3192* `sym <path>` 810* `sym <path>`
3193 - `<path>` must refer to a `fn` or `static`. 811 - `<path>` must refer to a `fn` or `static`.
@@ -3214,20 +832,20 @@ Here is the list of currently supported register classes:
3214 832
3215| Architecture | Register class | Registers | LLVM constraint code | 833| Architecture | Register class | Registers | LLVM constraint code |
3216| ------------ | -------------- | --------- | -------------------- | 834| ------------ | -------------- | --------- | -------------------- |
3217| x86 | `reg` | `ax`, `bx`, `cx`, `dx`, `si`, `di`, `r[8-15]` (x86-64 only) | `r` | 835| x86 | `reg` | `ax`, `bx`, `cx`, `dx`, `si`, `di`, `bp`, `r[8-15]` (x86-64 only) | `r` |
3218| x86 | `reg_abcd` | `ax`, `bx`, `cx`, `dx` | `Q` | 836| x86 | `reg_abcd` | `ax`, `bx`, `cx`, `dx` | `Q` |
3219| x86-32 | `reg_byte` | `al`, `bl`, `cl`, `dl`, `ah`, `bh`, `ch`, `dh` | `q` | 837| x86-32 | `reg_byte` | `al`, `bl`, `cl`, `dl`, `ah`, `bh`, `ch`, `dh` | `q` |
3220| x86-64 | `reg_byte` | `al`, `bl`, `cl`, `dl`, `sil`, `dil`, `r[8-15]b`, `ah`\*, `bh`\*, `ch`\*, `dh`\* | `q` | 838| x86-64 | `reg_byte`\* | `al`, `bl`, `cl`, `dl`, `sil`, `dil`, `bpl`, `r[8-15]b` | `q` |
3221| x86 | `xmm_reg` | `xmm[0-7]` (x86) `xmm[0-15]` (x86-64) | `x` | 839| x86 | `xmm_reg` | `xmm[0-7]` (x86) `xmm[0-15]` (x86-64) | `x` |
3222| x86 | `ymm_reg` | `ymm[0-7]` (x86) `ymm[0-15]` (x86-64) | `x` | 840| x86 | `ymm_reg` | `ymm[0-7]` (x86) `ymm[0-15]` (x86-64) | `x` |
3223| x86 | `zmm_reg` | `zmm[0-7]` (x86) `zmm[0-31]` (x86-64) | `v` | 841| x86 | `zmm_reg` | `zmm[0-7]` (x86) `zmm[0-31]` (x86-64) | `v` |
3224| x86 | `kreg` | `k[1-7]` | `Yk` | 842| x86 | `kreg` | `k[1-7]` | `Yk` |
3225| AArch64 | `reg` | `x[0-28]`, `x30` | `r` | 843| AArch64 | `reg` | `x[0-30]` | `r` |
3226| AArch64 | `vreg` | `v[0-31]` | `w` | 844| AArch64 | `vreg` | `v[0-31]` | `w` |
3227| AArch64 | `vreg_low16` | `v[0-15]` | `x` | 845| AArch64 | `vreg_low16` | `v[0-15]` | `x` |
3228| ARM | `reg` | `r[0-5]` `r7`\*, `r[8-10]`, `r11`\*, `r12`, `r14` | `r` | 846| ARM | `reg` | `r[0-12]`, `r14` | `r` |
3229| ARM (Thumb) | `reg_thumb` | `r[0-r7]` | `l` | 847| ARM (Thumb) | `reg_thumb` | `r[0-r7]` | `l` |
3230| ARM (ARM) | `reg_thumb` | `r[0-r10]`, `r12`, `r14` | `l` | 848| ARM (ARM) | `reg_thumb` | `r[0-r12]`, `r14` | `l` |
3231| ARM | `sreg` | `s[0-31]` | `t` | 849| ARM | `sreg` | `s[0-31]` | `t` |
3232| ARM | `sreg_low16` | `s[0-15]` | `x` | 850| ARM | `sreg_low16` | `s[0-15]` | `x` |
3233| ARM | `dreg` | `d[0-31]` | `w` | 851| ARM | `dreg` | `d[0-31]` | `w` |
@@ -3244,17 +862,18 @@ Here is the list of currently supported register classes:
3244| RISC-V | `reg` | `x1`, `x[5-7]`, `x[9-15]`, `x[16-31]` (non-RV32E) | `r` | 862| RISC-V | `reg` | `x1`, `x[5-7]`, `x[9-15]`, `x[16-31]` (non-RV32E) | `r` |
3245| RISC-V | `freg` | `f[0-31]` | `f` | 863| RISC-V | `freg` | `f[0-31]` | `f` |
3246| Hexagon | `reg` | `r[0-28]` | `r` | 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` |
3247| wasm32 | `local` | None\* | `r` | 868| wasm32 | `local` | None\* | `r` |
3248 869
3249> **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. 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.
3250> 871>
3251> Note #2: On x86-64 the high byte registers (e.g. `ah`) are only available when used as an explicit register. Specifying the `reg_byte` register class for an operand will always allocate a low byte register. 872> Note #2: On x86-64 the high byte registers (e.g. `ah`) are not available in the `reg_byte` register class.
3252> 873>
3253> Note #3: NVPTX doesn't have a fixed register set, so named registers are not supported. 874> Note #3: NVPTX doesn't have a fixed register set, so named registers are not supported.
3254> 875>
3255> Note #4: On ARM the frame pointer is either `r7` or `r11` depending on the platform. 876> Note #4: WebAssembly doesn't have registers, so named registers are not supported.
3256>
3257> Note #5: WebAssembly doesn't have registers, so named registers are not supported.
3258 877
3259Additional register classes may be added in the future based on demand (e.g. MMX, x87, etc). 878Additional register classes may be added in the future based on demand (e.g. MMX, x87, etc).
3260 879
@@ -3288,6 +907,9 @@ Each register class has constraints on which value types they can be used with.
3288| RISC-V | `freg` | `f` | `f32` | 907| RISC-V | `freg` | `f` | `f32` |
3289| RISC-V | `freg` | `d` | `f64` | 908| RISC-V | `freg` | `d` | `f64` |
3290| Hexagon | `reg` | None | `i8`, `i16`, `i32`, `f32` | 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` |
3291| wasm32 | `local` | None | `i8` `i16` `i32` `i64` `f32` `f64` | 913| wasm32 | `local` | None | `i8` `i16` `i32` `i64` `f32` `f64` |
3292 914
3293> **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). 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).
@@ -3356,13 +978,14 @@ Some registers cannot be used for input or output operands:
3356| All | `sp` | The stack pointer must be restored to its original value at the end of an asm code block. | 978| All | `sp` | The stack pointer must be restored to its original value at the end of an asm code block. |
3357| All | `bp` (x86), `x29` (AArch64), `x8` (RISC-V), `fr` (Hexagon), `$fp` (MIPS) | The frame pointer cannot be used as an input or output. | 979| All | `bp` (x86), `x29` (AArch64), `x8` (RISC-V), `fr` (Hexagon), `$fp` (MIPS) | The frame pointer cannot be used as an input or output. |
3358| 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. | 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. |
3359| ARM | `r6` | `r6` is used internally by LLVM as a base pointer and therefore 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. |
3360| x86 | `k0` | This is a constant zero register which can't be modified. | 982| x86 | `k0` | This is a constant zero register which can't be modified. |
3361| x86 | `ip` | This is the program counter, not a real register. | 983| x86 | `ip` | This is the program counter, not a real register. |
3362| x86 | `mm[0-7]` | MMX registers are not currently supported (but may be in the future). | 984| x86 | `mm[0-7]` | MMX registers are not currently supported (but may be in the future). |
3363| x86 | `st([0-7])` | x87 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). |
3364| AArch64 | `xzr` | This is a constant zero register which can't be modified. | 986| AArch64 | `xzr` | This is a constant zero register which can't be modified. |
3365| ARM | `pc` | This is the program counter, not a real register. | 987| ARM | `pc` | This is the program counter, not a real register. |
988| ARM | `r9` | This is a reserved register on some ARM targets. |
3366| MIPS | `$0` or `$zero` | This is a constant zero register which can't be modified. | 989| MIPS | `$0` or `$zero` | This is a constant zero register which can't be modified. |
3367| MIPS | `$1` or `$at` | Reserved for assembler. | 990| MIPS | `$1` or `$at` | Reserved for assembler. |
3368| MIPS | `$26`/`$k0`, `$27`/`$k1` | OS-reserved registers. | 991| MIPS | `$26`/`$k0`, `$27`/`$k1` | OS-reserved registers. |
@@ -3372,9 +995,10 @@ Some registers cannot be used for input or output operands:
3372| RISC-V | `gp`, `tp` | These registers are reserved and cannot be used as inputs or outputs. | 995| RISC-V | `gp`, `tp` | These registers are reserved and cannot be used as inputs or outputs. |
3373| Hexagon | `lr` | This is the link register which cannot be used as an input or output. | 996| Hexagon | `lr` | This is the link register which cannot be used as an input or output. |
3374 997
3375In 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: 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
3376- The frame pointer on all architectures. 999- The frame pointer and LLVM base pointer on all architectures.
3377- `r6` on ARM. 1000- `r9` on ARM.
1001- `x18` on AArch64.
3378 1002
3379## Template modifiers 1003## Template modifiers
3380 1004
@@ -3423,6 +1047,9 @@ The supported modifiers are a subset of LLVM's (and GCC's) [asm template argumen
3423| RISC-V | `reg` | None | `x1` | None | 1047| RISC-V | `reg` | None | `x1` | None |
3424| RISC-V | `freg` | None | `f0` | None | 1048| RISC-V | `freg` | None | `f0` | None |
3425| Hexagon | `reg` | None | `r0` | 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 |
3426 1053
3427> Notes: 1054> Notes:
3428> - on ARM `e` / `f`: this prints the low or high doubleword register name of a NEON quad (128-bit) register. 1055> - on ARM `e` / `f`: this prints the low or high doubleword register name of a NEON quad (128-bit) register.
@@ -3503,16 +1130,262 @@ The compiler performs some additional checks on options:
3503 - You are responsible for switching any target-specific state (e.g. thread-local storage, stack bounds). 1130 - You are responsible for switching any target-specific state (e.g. thread-local storage, stack bounds).
3504 - The set of memory locations that you may access is the intersection of those allowed by the `asm!` blocks you entered and exited. 1131 - The set of memory locations that you may access is the intersection of those allowed by the `asm!` blocks you entered and exited.
3505- 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. 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.
3506 - As a consequence, you should only use [local labels] inside inline assembly code. Defining symbols in assembly code may lead to assembler and/or linker errors due to duplicate symbol definitions.
3507 1133
3508> **Note**: As a general rule, the flags covered by `preserves_flags` are those which are *not* preserved when performing a function call. 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`
3509 1140
3510[local labels]: https://sourceware.org/binutils/docs/as/Symbol-Names.html#Local-Labels 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.
3511"##, 1245"##,
3512 }, 1246 },
3513 LintCompletion { 1247 LintCompletion {
3514 label: "flt2dec", 1248 label: "box_patterns",
3515 description: r##"# `flt2dec` 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`
3516 1389
3517This feature is internal to the Rust compiler and is not intended for general use. 1390This feature is internal to the Rust compiler and is not intended for general use.
3518 1391
@@ -3520,92 +1393,363 @@ This feature is internal to the Rust compiler and is not intended for general us
3520"##, 1393"##,
3521 }, 1394 },
3522 LintCompletion { 1395 LintCompletion {
3523 label: "global_asm", 1396 label: "cfg_panic",
3524 description: r##"# `global_asm` 1397 description: r##"# `cfg_panic`
3525 1398
3526The tracking issue for this feature is: [#35119] 1399The tracking issue for this feature is: [#77443]
3527 1400
3528[#35119]: https://github.com/rust-lang/rust/issues/35119 1401[#77443]: https://github.com/rust-lang/rust/issues/77443
3529 1402
3530------------------------ 1403------------------------
3531 1404
3532The `global_asm!` macro allows the programmer to write arbitrary 1405The `cfg_panic` feature makes it possible to execute different code
3533assembly outside the scope of a function body, passing it through 1406depending on the panic strategy.
3534`rustc` and `llvm` to the assembler. The macro is a no-frills
3535interface to LLVM's concept of [module-level inline assembly]. That is,
3536all caveats applicable to LLVM's module-level inline assembly apply
3537to `global_asm!`.
3538 1407
3539[module-level inline assembly]: http://llvm.org/docs/LangRef.html#module-level-inline-assembly 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.
3540 1411
3541`global_asm!` fills a role not currently satisfied by either `asm!` 1412## Examples
3542or `#[naked]` functions. The programmer has _all_ features of the
3543assembler at their disposal. The linker will expect to resolve any
3544symbols defined in the inline assembly, modulo any symbols marked as
3545external. It also means syntax for directives and assembly follow the
3546conventions of the assembler in your toolchain.
3547 1413
3548A simple usage looks like this: 1414```rust
1415#![feature(cfg_panic)]
3549 1416
3550```rust,ignore (requires-external-file) 1417#[cfg(panic = "unwind")]
3551#![feature(global_asm)] 1418fn a() {
3552# // you also need relevant target_arch cfgs 1419 // ...
3553global_asm!(include_str!("something_neato.s")); 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}
3554``` 1434```
1435"##,
1436 },
1437 LintCompletion {
1438 label: "cfg_sanitize",
1439 description: r##"# `cfg_sanitize`
3555 1440
3556And a more complicated usage looks like this: 1441The tracking issue for this feature is: [#39699]
3557 1442
3558```rust,no_run 1443[#39699]: https://github.com/rust-lang/rust/issues/39699
3559#![feature(global_asm)]
3560# #[cfg(any(target_arch="x86", target_arch="x86_64"))]
3561# mod x86 {
3562 1444
3563pub mod sally { 1445------------------------
3564 global_asm!(r#"
3565 .global foo
3566 foo:
3567 jmp baz
3568 "#);
3569 1446
3570 #[no_mangle] 1447The `cfg_sanitize` feature makes it possible to execute different code
3571 pub unsafe extern "C" fn baz() {} 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 // ...
3572} 1458}
3573 1459
3574// the symbols `foo` and `bar` are global, no matter where 1460#[cfg(not(sanitize = "thread"))]
3575// `global_asm!` was used. 1461fn a() {
3576extern "C" { 1462 // ...
3577 fn foo();
3578 fn bar();
3579} 1463}
3580 1464
3581pub mod harry { 1465fn b() {
3582 global_asm!(r#" 1466 if cfg!(sanitize = "leak") {
3583 .global bar 1467 // ...
3584 bar: 1468 } else {
3585 jmp quux 1469 // ...
3586 "#); 1470 }
1471}
1472```
1473"##,
1474 },
1475 LintCompletion {
1476 label: "cfg_version",
1477 description: r##"# `cfg_version`
3587 1478
3588 #[no_mangle] 1479The tracking issue for this feature is: [#64796]
3589 pub unsafe extern "C" fn quux() {} 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 }
3590} 1510}
3591# }
3592``` 1511```
1512"##,
1513 },
1514 LintCompletion {
1515 label: "char_error_internals",
1516 description: r##"# `char_error_internals`
3593 1517
3594You may use `global_asm!` multiple times, anywhere in your crate, in 1518This feature is internal to the Rust compiler and is not intended for general use.
3595whatever way suits you. The effect is as if you concatenated all
3596usages and placed the larger, single usage in the crate root.
3597 1519
3598------------------------ 1520------------------------
1521"##,
1522 },
1523 LintCompletion {
1524 label: "cmse_nonsecure_entry",
1525 description: r##"# `cmse_nonsecure_entry`
3599 1526
3600If you don't need quite as much power and flexibility as 1527The tracking issue for this feature is: [#75835]
3601`global_asm!` provides, and you don't mind restricting your inline 1528
3602assembly to `fn` bodies only, you might try the 1529[#75835]: https://github.com/rust-lang/rust/issues/75835
3603[asm](asm.md) feature instead. 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```
3604"##, 1606"##,
3605 }, 1607 },
3606 LintCompletion { 1608 LintCompletion {
3607 label: "derive_eq", 1609 label: "compiler_builtins",
3608 description: r##"# `derive_eq` 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`
3609 1753
3610This feature is internal to the Rust compiler and is not intended for general use. 1754This feature is internal to the Rust compiler and is not intended for general use.
3611 1755
@@ -3664,8 +1808,8 @@ fn main() {
3664"##, 1808"##,
3665 }, 1809 },
3666 LintCompletion { 1810 LintCompletion {
3667 label: "char_error_internals", 1811 label: "derive_clone_copy",
3668 description: r##"# `char_error_internals` 1812 description: r##"# `derive_clone_copy`
3669 1813
3670This feature is internal to the Rust compiler and is not intended for general use. 1814This feature is internal to the Rust compiler and is not intended for general use.
3671 1815
@@ -3673,8 +1817,8 @@ This feature is internal to the Rust compiler and is not intended for general us
3673"##, 1817"##,
3674 }, 1818 },
3675 LintCompletion { 1819 LintCompletion {
3676 label: "libstd_sys_internals", 1820 label: "derive_eq",
3677 description: r##"# `libstd_sys_internals` 1821 description: r##"# `derive_eq`
3678 1822
3679This feature is internal to the Rust compiler and is not intended for general use. 1823This feature is internal to the Rust compiler and is not intended for general use.
3680 1824
@@ -3682,23 +1826,167 @@ This feature is internal to the Rust compiler and is not intended for general us
3682"##, 1826"##,
3683 }, 1827 },
3684 LintCompletion { 1828 LintCompletion {
3685 label: "is_sorted", 1829 label: "doc_cfg",
3686 description: r##"# `is_sorted` 1830 description: r##"# `doc_cfg`
3687 1831
3688The tracking issue for this feature is: [#53485] 1832The tracking issue for this feature is: [#43781]
3689 1833
3690[#53485]: https://github.com/rust-lang/rust/issues/53485 1834------
3691 1835
3692------------------------ 1836The `doc_cfg` feature allows an API be documented as only available in some specific platforms.
1837This attribute has two effects:
3693 1838
3694Add the methods `is_sorted`, `is_sorted_by` and `is_sorted_by_key` to `[T]`; 18391. In the annotated item's documentation, there will be a message saying "This is supported on
3695add the methods `is_sorted`, `is_sorted_by` and `is_sorted_by_key` to 1840 (platform) only".
3696`Iterator`. 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
3697"##, 1876"##,
3698 }, 1877 },
3699 LintCompletion { 1878 LintCompletion {
3700 label: "c_void_variant", 1879 label: "doc_masked",
3701 description: r##"# `c_void_variant` 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`
3702 1990
3703This feature is internal to the Rust compiler and is not intended for general use. 1991This feature is internal to the Rust compiler and is not intended for general use.
3704 1992
@@ -3706,27 +1994,183 @@ This feature is internal to the Rust compiler and is not intended for general us
3706"##, 1994"##,
3707 }, 1995 },
3708 LintCompletion { 1996 LintCompletion {
3709 label: "concat_idents", 1997 label: "fd_read",
3710 description: r##"# `concat_idents` 1998 description: r##"# `fd_read`
3711 1999
3712The tracking issue for this feature is: [#29599] 2000This feature is internal to the Rust compiler and is not intended for general use.
3713 2001
3714[#29599]: https://github.com/rust-lang/rust/issues/29599 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.
3715 2126
3716------------------------ 2127------------------------
2128"##,
2129 },
2130 LintCompletion {
2131 label: "fmt_internals",
2132 description: r##"# `fmt_internals`
3717 2133
3718The `concat_idents` feature adds a macro for concatenating multiple identifiers 2134This feature is internal to the Rust compiler and is not intended for general use.
3719into one identifier.
3720 2135
3721## Examples 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
3722 2155
3723```rust 2156```rust
3724#![feature(concat_idents)] 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}
3725 2170
3726fn main() { 2171fn main() {
3727 fn foobar() -> u32 { 23 } 2172 let adder = Adder { a: 3 };
3728 let f = concat_idents!(foo, bar); 2173 assert_eq!(adder(2), 5);
3729 assert_eq!(f(), 23);
3730} 2174}
3731``` 2175```
3732"##, 2176"##,
@@ -3783,8 +2227,906 @@ A non-exhaustive list of macros which benefit from this functionality include:
3783"##, 2227"##,
3784 }, 2228 },
3785 LintCompletion { 2229 LintCompletion {
3786 label: "print_internals", 2230 label: "generators",
3787 description: r##"# `print_internals` 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`
3788 3130
3789This feature is internal to the Rust compiler and is not intended for general use. 3131This feature is internal to the Rust compiler and is not intended for general use.
3790 3132
@@ -3989,135 +3331,421 @@ If you need more power and don't mind losing some of the niceties of
3989"##, 3331"##,
3990 }, 3332 },
3991 LintCompletion { 3333 LintCompletion {
3992 label: "core_intrinsics", 3334 label: "marker_trait_attr",
3993 description: r##"# `core_intrinsics` 3335 description: r##"# `marker_trait_attr`
3994 3336
3995This feature is internal to the Rust compiler and is not intended for general use. 3337The tracking issue for this feature is: [#29864]
3338
3339[#29864]: https://github.com/rust-lang/rust/issues/29864
3996 3340
3997------------------------ 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).
3998"##, 3370"##,
3999 }, 3371 },
4000 LintCompletion { 3372 LintCompletion {
4001 label: "trace_macros", 3373 label: "native_link_modifiers",
4002 description: r##"# `trace_macros` 3374 description: r##"# `native_link_modifiers`
4003 3375
4004The tracking issue for this feature is [#29598]. 3376The tracking issue for this feature is: [#81490]
4005 3377
4006[#29598]: https://github.com/rust-lang/rust/issues/29598 3378[#81490]: https://github.com/rust-lang/rust/issues/81490
4007 3379
4008------------------------ 3380------------------------
4009 3381
4010With `trace_macros` you can trace the expansion of macros in your code. 3382The `native_link_modifiers` feature allows you to use the `modifiers` syntax with the `#[link(..)]` attribute.
4011 3383
4012## Examples 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`
4013 3390
4014```rust 3391The tracking issue for this feature is: [#81490]
4015#![feature(trace_macros)]
4016 3392
4017fn main() { 3393[#81490]: https://github.com/rust-lang/rust/issues/81490
4018 trace_macros!(true);
4019 println!("Hello, Rust!");
4020 trace_macros!(false);
4021}
4022```
4023 3394
4024The `cargo build` output: 3395------------------------
4025 3396
4026```txt 3397The `native_link_modifiers_as_needed` feature allows you to use the `as-needed` modifier.
4027note: trace_macro
4028 --> src/main.rs:5:5
4029 |
40305 | println!("Hello, Rust!");
4031 | ^^^^^^^^^^^^^^^^^^^^^^^^^
4032 |
4033 = note: expanding `println! { "Hello, Rust!" }`
4034 = note: to `print ! ( concat ! ( "Hello, Rust!" , "\n" ) )`
4035 = note: expanding `print! { concat ! ( "Hello, Rust!" , "\n" ) }`
4036 = note: to `$crate :: io :: _print ( format_args ! ( concat ! ( "Hello, Rust!" , "\n" ) )
4037 )`
4038 3398
4039 Finished dev [unoptimized + debuginfo] target(s) in 0.60 secs 3399`as-needed` is only compatible with the `dynamic` and `framework` linking kinds. Using any other kind will result in a compiler error.
4040``` 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.
4041"##, 3407"##,
4042 }, 3408 },
4043 LintCompletion { 3409 LintCompletion {
4044 label: "update_panic_count", 3410 label: "native_link_modifiers_bundle",
4045 description: r##"# `update_panic_count` 3411 description: r##"# `native_link_modifiers_bundle`
4046 3412
4047This feature is internal to the Rust compiler and is not intended for general use. 3413The tracking issue for this feature is: [#81490]
3414
3415[#81490]: https://github.com/rust-lang/rust/issues/81490
4048 3416
4049------------------------ 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.
4050"##, 3430"##,
4051 }, 3431 },
4052 LintCompletion { 3432 LintCompletion {
4053 label: "core_private_bignum", 3433 label: "native_link_modifiers_verbatim",
4054 description: r##"# `core_private_bignum` 3434 description: r##"# `native_link_modifiers_verbatim`
4055 3435
4056This feature is internal to the Rust compiler and is not intended for general use. 3436The tracking issue for this feature is: [#81490]
3437
3438[#81490]: https://github.com/rust-lang/rust/issues/81490
4057 3439
4058------------------------ 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`.
4059"##, 3454"##,
4060 }, 3455 },
4061 LintCompletion { 3456 LintCompletion {
4062 label: "sort_internals", 3457 label: "native_link_modifiers_whole_archive",
4063 description: r##"# `sort_internals` 3458 description: r##"# `native_link_modifiers_whole_archive`
4064 3459
4065This feature is internal to the Rust compiler and is not intended for general use. 3460The tracking issue for this feature is: [#81490]
3461
3462[#81490]: https://github.com/rust-lang/rust/issues/81490
4066 3463
4067------------------------ 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`.
4068"##, 3476"##,
4069 }, 3477 },
4070 LintCompletion { 3478 LintCompletion {
4071 label: "windows_net", 3479 label: "negative_impls",
4072 description: r##"# `windows_net` 3480 description: r##"# `negative_impls`
4073 3481
4074This feature is internal to the Rust compiler and is not intended for general use. 3482The tracking issue for this feature is [#68318].
4075 3483
4076------------------------ 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.
4077"##, 3537"##,
4078 }, 3538 },
4079 LintCompletion { 3539 LintCompletion {
4080 label: "c_variadic", 3540 label: "no_coverage",
4081 description: r##"# `c_variadic` 3541 description: r##"# `no_coverage`
4082 3542
4083The tracking issue for this feature is: [#44930] 3543The tracking issue for this feature is: [#84605]
4084 3544
4085[#44930]: https://github.com/rust-lang/rust/issues/44930 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
4086 3580
4087------------------------ 3581------------------------
4088 3582
4089The `c_variadic` library feature exposes the `VaList` structure, 3583The `no_sanitize` attribute can be used to selectively disable sanitizer
4090Rust's analogue of C's `va_list` type. 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.
4091 3593
4092## Examples 3594## Examples
4093 3595
4094```rust 3596``` rust
4095#![feature(c_variadic)] 3597#![feature(no_sanitize)]
4096 3598
4097use std::ffi::VaList; 3599#[no_sanitize(address)]
3600fn foo() {
3601 // ...
3602}
3603```
3604"##,
3605 },
3606 LintCompletion {
3607 label: "plugin",
3608 description: r##"# `plugin`
4098 3609
4099pub unsafe extern "C" fn vadd(n: usize, mut args: VaList) -> usize { 3610The tracking issue for this feature is: [#29597]
4100 let mut sum = 0; 3611
4101 for _ in 0..n { 3612[#29597]: https://github.com/rust-lang/rust/issues/29597
4102 sum += args.arg::<usize>(); 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 }
4103 } 3675 }
4104 sum 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);
4105} 3682}
4106``` 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`.
4107"##, 3727"##,
4108 }, 3728 },
4109 LintCompletion { 3729 LintCompletion {
4110 label: "core_private_diy_float", 3730 label: "plugin_registrar",
4111 description: r##"# `core_private_diy_float` 3731 description: r##"# `plugin_registrar`
4112 3732
4113This feature is internal to the Rust compiler and is not intended for general use. 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
4114 3742
4115------------------------ 3743------------------------
4116"##, 3744"##,
4117 }, 3745 },
4118 LintCompletion { 3746 LintCompletion {
4119 label: "profiler_runtime_lib", 3747 label: "print_internals",
4120 description: r##"# `profiler_runtime_lib` 3748 description: r##"# `print_internals`
4121 3749
4122This feature is internal to the Rust compiler and is not intended for general use. 3750This feature is internal to the Rust compiler and is not intended for general use.
4123 3751
@@ -4125,17 +3753,17 @@ This feature is internal to the Rust compiler and is not intended for general us
4125"##, 3753"##,
4126 }, 3754 },
4127 LintCompletion { 3755 LintCompletion {
4128 label: "thread_local_internals", 3756 label: "profiler_runtime",
4129 description: r##"# `thread_local_internals` 3757 description: r##"# `profiler_runtime`
4130 3758
4131This feature is internal to the Rust compiler and is not intended for general use. 3759The tracking issue for this feature is: [#42524](https://github.com/rust-lang/rust/issues/42524).
4132 3760
4133------------------------ 3761------------------------
4134"##, 3762"##,
4135 }, 3763 },
4136 LintCompletion { 3764 LintCompletion {
4137 label: "int_error_internals", 3765 label: "profiler_runtime_lib",
4138 description: r##"# `int_error_internals` 3766 description: r##"# `profiler_runtime_lib`
4139 3767
4140This feature is internal to the Rust compiler and is not intended for general use. 3768This feature is internal to the Rust compiler and is not intended for general use.
4141 3769
@@ -4143,17 +3771,30 @@ This feature is internal to the Rust compiler and is not intended for general us
4143"##, 3771"##,
4144 }, 3772 },
4145 LintCompletion { 3773 LintCompletion {
4146 label: "windows_stdio", 3774 label: "repr128",
4147 description: r##"# `windows_stdio` 3775 description: r##"# `repr128`
4148 3776
4149This feature is internal to the Rust compiler and is not intended for general use. 3777The tracking issue for this feature is: [#56071]
3778
3779[#56071]: https://github.com/rust-lang/rust/issues/56071
4150 3780
4151------------------------ 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```
4152"##, 3793"##,
4153 }, 3794 },
4154 LintCompletion { 3795 LintCompletion {
4155 label: "fmt_internals", 3796 label: "rt",
4156 description: r##"# `fmt_internals` 3797 description: r##"# `rt`
4157 3798
4158This feature is internal to the Rust compiler and is not intended for general use. 3799This feature is internal to the Rust compiler and is not intended for general use.
4159 3800
@@ -4161,8 +3802,65 @@ This feature is internal to the Rust compiler and is not intended for general us
4161"##, 3802"##,
4162 }, 3803 },
4163 LintCompletion { 3804 LintCompletion {
4164 label: "fd_read", 3805 label: "rustc_attrs",
4165 description: r##"# `fd_read` 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`
4166 3864
4167This feature is internal to the Rust compiler and is not intended for general use. 3865This feature is internal to the Rust compiler and is not intended for general use.
4168 3866
@@ -4341,8 +4039,8 @@ even when using either of the above.
4341"##, 4039"##,
4342 }, 4040 },
4343 LintCompletion { 4041 LintCompletion {
4344 label: "windows_c", 4042 label: "thread_local_internals",
4345 description: r##"# `windows_c` 4043 description: r##"# `thread_local_internals`
4346 4044
4347This feature is internal to the Rust compiler and is not intended for general use. 4045This feature is internal to the Rust compiler and is not intended for general use.
4348 4046
@@ -4350,87 +4048,204 @@ This feature is internal to the Rust compiler and is not intended for general us
4350"##, 4048"##,
4351 }, 4049 },
4352 LintCompletion { 4050 LintCompletion {
4353 label: "dec2flt", 4051 label: "trace_macros",
4354 description: r##"# `dec2flt` 4052 description: r##"# `trace_macros`
4355 4053
4356This feature is internal to the Rust compiler and is not intended for general use. 4054The tracking issue for this feature is [#29598].
4055
4056[#29598]: https://github.com/rust-lang/rust/issues/29598
4357 4057
4358------------------------ 4058------------------------
4359"##,
4360 },
4361 LintCompletion {
4362 label: "derive_clone_copy",
4363 description: r##"# `derive_clone_copy`
4364 4059
4365This feature is internal to the Rust compiler and is not intended for general use. 4060With `trace_macros` you can trace the expansion of macros in your code.
4366 4061
4367------------------------ 4062## Examples
4368"##,
4369 },
4370 LintCompletion {
4371 label: "allocator_api",
4372 description: r##"# `allocator_api`
4373 4063
4374The tracking issue for this feature is [#32838] 4064```rust
4065#![feature(trace_macros)]
4375 4066
4376[#32838]: https://github.com/rust-lang/rust/issues/32838 4067fn main() {
4068 trace_macros!(true);
4069 println!("Hello, Rust!");
4070 trace_macros!(false);
4071}
4072```
4377 4073
4378------------------------ 4074The `cargo build` output:
4379 4075
4380Sometimes you want the memory for one collection to use a different 4076```txt
4381allocator than the memory for another collection. In this case, 4077note: trace_macro
4382replacing the global allocator is not a workable option. Instead, 4078 --> src/main.rs:5:5
4383you need to pass in an instance of an `AllocRef` to each collection 4079 |
4384for which you want a custom allocator. 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 )`
4385 4088
4386TBD 4089 Finished dev [unoptimized + debuginfo] target(s) in 0.60 secs
4090```
4387"##, 4091"##,
4388 }, 4092 },
4389 LintCompletion { 4093 LintCompletion {
4390 label: "core_panic", 4094 label: "trait_alias",
4391 description: r##"# `core_panic` 4095 description: r##"# `trait_alias`
4392 4096
4393This feature is internal to the Rust compiler and is not intended for general use. 4097The tracking issue for this feature is: [#41517]
4098
4099[#41517]: https://github.com/rust-lang/rust/issues/41517
4394 4100
4395------------------------ 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```
4396"##, 4129"##,
4397 }, 4130 },
4398 LintCompletion { 4131 LintCompletion {
4399 label: "fn_traits", 4132 label: "transparent_unions",
4400 description: r##"# `fn_traits` 4133 description: r##"# `transparent_unions`
4401
4402The tracking issue for this feature is [#29625]
4403 4134
4404See Also: [`unboxed_closures`](../language-features/unboxed-closures.md) 4135The tracking issue for this feature is [#60405]
4405 4136
4406[#29625]: https://github.com/rust-lang/rust/issues/29625 4137[#60405]: https://github.com/rust-lang/rust/issues/60405
4407 4138
4408---- 4139----
4409 4140
4410The `fn_traits` feature allows for implementation of the [`Fn*`] traits 4141The `transparent_unions` feature allows you mark `union`s as
4411for creating custom closure-like types. 4142`#[repr(transparent)]`. A `union` may be `#[repr(transparent)]` in exactly the
4412 4143same conditions in which a `struct` may be `#[repr(transparent)]` (generally,
4413[`Fn*`]: https://doc.rust-lang.org/std/ops/trait.Fn.html 4144this means the `union` must have exactly one non-zero-sized field). Some
4145concrete illustrations follow.
4414 4146
4415```rust 4147```rust
4416#![feature(unboxed_closures)] 4148#![feature(transparent_unions)]
4417#![feature(fn_traits)]
4418 4149
4419struct Adder { 4150// This union has the same representation as `f32`.
4420 a: u32 4151#[repr(transparent)]
4152union SingleFieldUnion {
4153 field: f32,
4421} 4154}
4422 4155
4423impl FnOnce<(u32, )> for Adder { 4156// This union has the same representation as `usize`.
4424 type Output = u32; 4157#[repr(transparent)]
4425 extern "rust-call" fn call_once(self, b: (u32, )) -> Self::Output { 4158union MultiFieldUnion {
4426 self.a + b.0 4159 field: usize,
4427 } 4160 nothing: (),
4428} 4161}
4162```
4429 4163
4430fn main() { 4164For consistency with transparent `struct`s, `union`s must have exactly one
4431 let adder = Adder { a: 3 }; 4165non-zero-sized field. If all fields are zero-sized, the `union` must not be
4432 assert_eq!(adder(2), 5); 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: (),
4433} 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());
4434``` 4249```
4435"##, 4250"##,
4436 }, 4251 },
@@ -4489,8 +4304,247 @@ just `()`, or similar) restricts this to where it's semantically meaningful.
4489"##, 4304"##,
4490 }, 4305 },
4491 LintCompletion { 4306 LintCompletion {
4492 label: "rt", 4307 label: "unboxed_closures",
4493 description: r##"# `rt` 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`
4494 4548
4495This feature is internal to the Rust compiler and is not intended for general use. 4549This feature is internal to the Rust compiler and is not intended for general use.
4496 4550
@@ -4498,8 +4552,8 @@ This feature is internal to the Rust compiler and is not intended for general us
4498"##, 4552"##,
4499 }, 4553 },
4500 LintCompletion { 4554 LintCompletion {
4501 label: "fd", 4555 label: "windows_c",
4502 description: r##"# `fd` 4556 description: r##"# `windows_c`
4503 4557
4504This feature is internal to the Rust compiler and is not intended for general use. 4558This feature is internal to the Rust compiler and is not intended for general use.
4505 4559
@@ -4507,8 +4561,26 @@ This feature is internal to the Rust compiler and is not intended for general us
4507"##, 4561"##,
4508 }, 4562 },
4509 LintCompletion { 4563 LintCompletion {
4510 label: "libstd_thread_internals", 4564 label: "windows_handle",
4511 description: r##"# `libstd_thread_internals` 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`
4512 4584
4513This feature is internal to the Rust compiler and is not intended for general use. 4585This feature is internal to the Rust compiler and is not intended for general use.
4514 4586
@@ -4517,7 +4589,7 @@ This feature is internal to the Rust compiler and is not intended for general us
4517 }, 4589 },
4518]; 4590];
4519 4591
4520pub(super) const CLIPPY_LINTS: &[LintCompletion] = &[ 4592pub const CLIPPY_LINTS: &[LintCompletion] = &[
4521 LintCompletion { 4593 LintCompletion {
4522 label: "clippy::absurd_extreme_comparisons", 4594 label: "clippy::absurd_extreme_comparisons",
4523 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."##, 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."##,
@@ -4579,6 +4651,10 @@ pub(super) const CLIPPY_LINTS: &[LintCompletion] = &[
4579 description: r##"Checks for `if` conditions that use blocks containing an\nexpression, statements or conditions that use closures with blocks."##, 4651 description: r##"Checks for `if` conditions that use blocks containing an\nexpression, statements or conditions that use closures with blocks."##,
4580 }, 4652 },
4581 LintCompletion { 4653 LintCompletion {
4654 label: "clippy::bool_assert_comparison",
4655 description: r##"This lint warns about boolean comparisons in assert-like macros."##,
4656 },
4657 LintCompletion {
4582 label: "clippy::bool_comparison", 4658 label: "clippy::bool_comparison",
4583 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."##, 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."##,
4584 }, 4660 },
@@ -4599,6 +4675,10 @@ pub(super) const CLIPPY_LINTS: &[LintCompletion] = &[
4599 description: r##"Checks for usage of `Box<T>` where an unboxed `T` would\nwork fine."##, 4675 description: r##"Checks for usage of `Box<T>` where an unboxed `T` would\nwork fine."##,
4600 }, 4676 },
4601 LintCompletion { 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 {
4602 label: "clippy::builtin_type_shadow", 4682 label: "clippy::builtin_type_shadow",
4603 description: r##"Warns if a generic shadows a built-in type."##, 4683 description: r##"Warns if a generic shadows a built-in type."##,
4604 }, 4684 },
@@ -4670,6 +4750,10 @@ pub(super) const CLIPPY_LINTS: &[LintCompletion] = &[
4670 label: "clippy::clone_on_ref_ptr", 4750 label: "clippy::clone_on_ref_ptr",
4671 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)`)."##, 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)`)."##,
4672 }, 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 },
4673 LintCompletion { label: "clippy::cmp_nan", description: r##"Checks for comparisons to NaN."## }, 4757 LintCompletion { label: "clippy::cmp_nan", description: r##"Checks for comparisons to NaN."## },
4674 LintCompletion { 4758 LintCompletion {
4675 label: "clippy::cmp_null", 4759 label: "clippy::cmp_null",
@@ -4788,10 +4872,6 @@ pub(super) const CLIPPY_LINTS: &[LintCompletion] = &[
4788 description: r##"Checks for unnecessary double parentheses."##, 4872 description: r##"Checks for unnecessary double parentheses."##,
4789 }, 4873 },
4790 LintCompletion { 4874 LintCompletion {
4791 label: "clippy::drop_bounds",
4792 description: r##"Nothing. This lint has been deprecated."##,
4793 },
4794 LintCompletion {
4795 label: "clippy::drop_copy", 4875 label: "clippy::drop_copy",
4796 description: r##"Checks for calls to `std::mem::drop` with a value\nthat derives the Copy trait"##, 4876 description: r##"Checks for calls to `std::mem::drop` with a value\nthat derives the Copy trait"##,
4797 }, 4877 },
@@ -4917,7 +4997,7 @@ pub(super) const CLIPPY_LINTS: &[LintCompletion] = &[
4917 }, 4997 },
4918 LintCompletion { 4998 LintCompletion {
4919 label: "clippy::filter_map", 4999 label: "clippy::filter_map",
4920 description: r##"Checks for usage of `_.filter(_).map(_)`,\n`_.filter(_).flat_map(_)`, `_.filter_map(_).flat_map(_)` and similar."##, 5000 description: r##"Nothing. This lint has been deprecated."##,
4921 }, 5001 },
4922 LintCompletion { 5002 LintCompletion {
4923 label: "clippy::filter_map_identity", 5003 label: "clippy::filter_map_identity",
@@ -4940,6 +5020,10 @@ pub(super) const CLIPPY_LINTS: &[LintCompletion] = &[
4940 description: r##"Checks for usage of `flat_map(|x| x)`."##, 5020 description: r##"Checks for usage of `flat_map(|x| x)`."##,
4941 }, 5021 },
4942 LintCompletion { 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 {
4943 label: "clippy::float_arithmetic", 5027 label: "clippy::float_arithmetic",
4944 description: r##"Checks for float arithmetic."##, 5028 description: r##"Checks for float arithmetic."##,
4945 }, 5029 },
@@ -5036,6 +5120,10 @@ pub(super) const CLIPPY_LINTS: &[LintCompletion] = &[
5036 description: r##"Checks for `if/else` with the same body as the *then* part\nand the *else* part."##, 5120 description: r##"Checks for `if/else` with the same body as the *then* part\nand the *else* part."##,
5037 }, 5121 },
5038 LintCompletion { 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 {
5039 label: "clippy::ifs_same_cond", 5127 label: "clippy::ifs_same_cond",
5040 description: r##"Checks for consecutive `if`s with the same condition."##, 5128 description: r##"Checks for consecutive `if`s with the same condition."##,
5041 }, 5129 },
@@ -5065,7 +5153,7 @@ pub(super) const CLIPPY_LINTS: &[LintCompletion] = &[
5065 }, 5153 },
5066 LintCompletion { 5154 LintCompletion {
5067 label: "clippy::inconsistent_struct_constructor", 5155 label: "clippy::inconsistent_struct_constructor",
5068 description: r##"Checks for struct constructors where the order of the field init\nshorthand in the constructor is inconsistent with the order in the struct definition."##, 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."##,
5069 }, 5157 },
5070 LintCompletion { 5158 LintCompletion {
5071 label: "clippy::indexing_slicing", 5159 label: "clippy::indexing_slicing",
@@ -5128,10 +5216,6 @@ pub(super) const CLIPPY_LINTS: &[LintCompletion] = &[
5128 description: r##"Checks for division of integers"##, 5216 description: r##"Checks for division of integers"##,
5129 }, 5217 },
5130 LintCompletion { 5218 LintCompletion {
5131 label: "clippy::into_iter_on_array",
5132 description: r##"Nothing. This lint has been deprecated."##,
5133 },
5134 LintCompletion {
5135 label: "clippy::into_iter_on_ref", 5219 label: "clippy::into_iter_on_ref",
5136 description: r##"Checks for `into_iter` calls on references which should be replaced by `iter`\nor `iter_mut`."##, 5220 description: r##"Checks for `into_iter` calls on references which should be replaced by `iter`\nor `iter_mut`."##,
5137 }, 5221 },
@@ -5140,8 +5224,8 @@ pub(super) const CLIPPY_LINTS: &[LintCompletion] = &[
5140 description: r##"Checks for usage of invalid atomic\nordering in atomic loads/stores/exchanges/updates and\nmemory fences."##, 5224 description: r##"Checks for usage of invalid atomic\nordering in atomic loads/stores/exchanges/updates and\nmemory fences."##,
5141 }, 5225 },
5142 LintCompletion { 5226 LintCompletion {
5143 label: "clippy::invalid_ref", 5227 label: "clippy::invalid_null_ptr_usage",
5144 description: r##"Nothing. This lint has been deprecated."##, 5228 description: r##"This lint checks for invalid usages of `ptr::null`."##,
5145 }, 5229 },
5146 LintCompletion { 5230 LintCompletion {
5147 label: "clippy::invalid_regex", 5231 label: "clippy::invalid_regex",
@@ -5164,6 +5248,10 @@ pub(super) const CLIPPY_LINTS: &[LintCompletion] = &[
5164 description: r##"Checks for the use of `.cloned().collect()` on slice to\ncreate a `Vec`."##, 5248 description: r##"Checks for the use of `.cloned().collect()` on slice to\ncreate a `Vec`."##,
5165 }, 5249 },
5166 LintCompletion { 5250 LintCompletion {
5251 label: "clippy::iter_count",
5252 description: r##"Checks for the use of `.iter().count()`."##,
5253 },
5254 LintCompletion {
5167 label: "clippy::iter_next_loop", 5255 label: "clippy::iter_next_loop",
5168 description: r##"Checks for loops on `x.next()`."##, 5256 description: r##"Checks for loops on `x.next()`."##,
5169 }, 5257 },
@@ -5300,6 +5388,10 @@ pub(super) const CLIPPY_LINTS: &[LintCompletion] = &[
5300 description: r##"Checks for `.checked_add/sub(x).unwrap_or(MAX/MIN)`."##, 5388 description: r##"Checks for `.checked_add/sub(x).unwrap_or(MAX/MIN)`."##,
5301 }, 5389 },
5302 LintCompletion { 5390 LintCompletion {
5391 label: "clippy::manual_str_repeat",
5392 description: r##"Checks for manual implementations of `str::repeat`"##,
5393 },
5394 LintCompletion {
5303 label: "clippy::manual_strip", 5395 label: "clippy::manual_strip",
5304 description: r##"Suggests using `strip_{prefix,suffix}` over `str::{starts,ends}_with` and slicing using\nthe pattern's length."##, 5396 description: r##"Suggests using `strip_{prefix,suffix}` over `str::{starts,ends}_with` and slicing using\nthe pattern's length."##,
5305 }, 5397 },
@@ -5333,7 +5425,7 @@ pub(super) const CLIPPY_LINTS: &[LintCompletion] = &[
5333 }, 5425 },
5334 LintCompletion { 5426 LintCompletion {
5335 label: "clippy::map_flatten", 5427 label: "clippy::map_flatten",
5336 description: r##"Checks for usage of `_.map(_).flatten(_)`,"##, 5428 description: r##"Checks for usage of `_.map(_).flatten(_)` on `Iterator` and `Option`"##,
5337 }, 5429 },
5338 LintCompletion { 5430 LintCompletion {
5339 label: "clippy::map_identity", 5431 label: "clippy::map_identity",
@@ -5524,6 +5616,10 @@ pub(super) const CLIPPY_LINTS: &[LintCompletion] = &[
5524 description: r##"The lint checks for `self` in fn parameters that\nspecify the `Self`-type explicitly"##, 5616 description: r##"The lint checks for `self` in fn parameters that\nspecify the `Self`-type explicitly"##,
5525 }, 5617 },
5526 LintCompletion { 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 {
5527 label: "clippy::needless_bool", 5623 label: "clippy::needless_bool",
5528 description: r##"Checks for expressions of the form `if c { true } else {\nfalse }` (or vice versa) and suggests using the condition directly."##, 5624 description: r##"Checks for expressions of the form `if c { true } else {\nfalse }` (or vice versa) and suggests using the condition directly."##,
5529 }, 5625 },
@@ -5533,7 +5629,7 @@ pub(super) const CLIPPY_LINTS: &[LintCompletion] = &[
5533 }, 5629 },
5534 LintCompletion { 5630 LintCompletion {
5535 label: "clippy::needless_borrowed_reference", 5631 label: "clippy::needless_borrowed_reference",
5536 description: r##"Checks for useless borrowed references."##, 5632 description: r##"Checks for bindings that destructure a reference and borrow the inner\nvalue with `&ref`."##,
5537 }, 5633 },
5538 LintCompletion { 5634 LintCompletion {
5539 label: "clippy::needless_collect", 5635 label: "clippy::needless_collect",
@@ -5548,6 +5644,10 @@ pub(super) const CLIPPY_LINTS: &[LintCompletion] = &[
5548 description: r##"Checks for `fn main() { .. }` in doctests"##, 5644 description: r##"Checks for `fn main() { .. }` in doctests"##,
5549 }, 5645 },
5550 LintCompletion { 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 {
5551 label: "clippy::needless_lifetimes", 5651 label: "clippy::needless_lifetimes",
5552 description: r##"Checks for lifetime annotations which can be removed by\nrelying on lifetime elision."##, 5652 description: r##"Checks for lifetime annotations which can be removed by\nrelying on lifetime elision."##,
5553 }, 5653 },
@@ -5600,6 +5700,10 @@ pub(super) const CLIPPY_LINTS: &[LintCompletion] = &[
5600 description: r##"Checks for non-ASCII characters in string literals."##, 5700 description: r##"Checks for non-ASCII characters in string literals."##,
5601 }, 5701 },
5602 LintCompletion { 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 {
5603 label: "clippy::nonminimal_bool", 5707 label: "clippy::nonminimal_bool",
5604 description: r##"Checks for boolean expressions that can be written more\nconcisely."##, 5708 description: r##"Checks for boolean expressions that can be written more\nconcisely."##,
5605 }, 5709 },
@@ -5609,7 +5713,7 @@ pub(super) const CLIPPY_LINTS: &[LintCompletion] = &[
5609 }, 5713 },
5610 LintCompletion { 5714 LintCompletion {
5611 label: "clippy::not_unsafe_ptr_arg_deref", 5715 label: "clippy::not_unsafe_ptr_arg_deref",
5612 description: r##"Checks for public functions that dereference raw pointer\narguments but are not marked unsafe."##, 5716 description: r##"Checks for public functions that dereference raw pointer\narguments but are not marked `unsafe`."##,
5613 }, 5717 },
5614 LintCompletion { 5718 LintCompletion {
5615 label: "clippy::ok_expect", 5719 label: "clippy::ok_expect",
@@ -5628,6 +5732,10 @@ pub(super) const CLIPPY_LINTS: &[LintCompletion] = &[
5628 description: r##"Checks for usage of `option_env!(...).unwrap()` and\nsuggests usage of the `env!` macro."##, 5732 description: r##"Checks for usage of `option_env!(...).unwrap()` and\nsuggests usage of the `env!` macro."##,
5629 }, 5733 },
5630 LintCompletion { 5734 LintCompletion {
5735 label: "clippy::option_filter_map",
5736 description: r##"Checks for indirect collection of populated `Option`"##,
5737 },
5738 LintCompletion {
5631 label: "clippy::option_if_let_else", 5739 label: "clippy::option_if_let_else",
5632 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)."##, 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)."##,
5633 }, 5741 },
@@ -5661,10 +5769,6 @@ pub(super) const CLIPPY_LINTS: &[LintCompletion] = &[
5661 description: r##"Checks for usage of `panic!`, `unimplemented!`, `todo!`, `unreachable!` or assertions in a function of type result."##, 5769 description: r##"Checks for usage of `panic!`, `unimplemented!`, `todo!`, `unreachable!` or assertions in a function of type result."##,
5662 }, 5770 },
5663 LintCompletion { 5771 LintCompletion {
5664 label: "clippy::panic_params",
5665 description: r##"Nothing. This lint has been deprecated."##,
5666 },
5667 LintCompletion {
5668 label: "clippy::panicking_unwrap", 5772 label: "clippy::panicking_unwrap",
5669 description: r##"Checks for calls of `unwrap[_err]()` that will always fail."##, 5773 description: r##"Checks for calls of `unwrap[_err]()` that will always fail."##,
5670 }, 5774 },
@@ -5726,7 +5830,7 @@ pub(super) const CLIPPY_LINTS: &[LintCompletion] = &[
5726 }, 5830 },
5727 LintCompletion { 5831 LintCompletion {
5728 label: "clippy::pub_enum_variant_names", 5832 label: "clippy::pub_enum_variant_names",
5729 description: r##"Detects public enumeration variants that are\nprefixed or suffixed by the same characters."##, 5833 description: r##"Nothing. This lint has been deprecated."##,
5730 }, 5834 },
5731 LintCompletion { 5835 LintCompletion {
5732 label: "clippy::question_mark", 5836 label: "clippy::question_mark",
@@ -5801,6 +5905,10 @@ pub(super) const CLIPPY_LINTS: &[LintCompletion] = &[
5801 description: r##"Checks for constants and statics with an explicit `'static` lifetime."##, 5905 description: r##"Checks for constants and statics with an explicit `'static` lifetime."##,
5802 }, 5906 },
5803 LintCompletion { 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 {
5804 label: "clippy::ref_in_deref", 5912 label: "clippy::ref_in_deref",
5805 description: r##"Checks for references in expressions that use\nauto dereference."##, 5913 description: r##"Checks for references in expressions that use\nauto dereference."##,
5806 }, 5914 },
@@ -5834,7 +5942,7 @@ pub(super) const CLIPPY_LINTS: &[LintCompletion] = &[
5834 }, 5942 },
5835 LintCompletion { 5943 LintCompletion {
5836 label: "clippy::result_unit_err", 5944 label: "clippy::result_unit_err",
5837 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`]."##, 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`."##,
5838 }, 5946 },
5839 LintCompletion { 5947 LintCompletion {
5840 label: "clippy::reversed_empty_ranges", 5948 label: "clippy::reversed_empty_ranges",
@@ -5850,7 +5958,7 @@ pub(super) const CLIPPY_LINTS: &[LintCompletion] = &[
5850 }, 5958 },
5851 LintCompletion { 5959 LintCompletion {
5852 label: "clippy::search_is_some", 5960 label: "clippy::search_is_some",
5853 description: r##"Checks for an iterator or string search (such as `find()`,\n`position()`, or `rposition()`) followed by a call to `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()`."##,
5854 }, 5962 },
5855 LintCompletion { 5963 LintCompletion {
5856 label: "clippy::self_assignment", 5964 label: "clippy::self_assignment",
@@ -5858,7 +5966,7 @@ pub(super) const CLIPPY_LINTS: &[LintCompletion] = &[
5858 }, 5966 },
5859 LintCompletion { 5967 LintCompletion {
5860 label: "clippy::semicolon_if_nothing_returned", 5968 label: "clippy::semicolon_if_nothing_returned",
5861 description: r##"Looks for blocks of expressions and fires if the last expression returns `()`\nbut is not followed by a semicolon."##, 5969 description: r##"Looks for blocks of expressions and fires if the last expression returns\n`()` but is not followed by a semicolon."##,
5862 }, 5970 },
5863 LintCompletion { 5971 LintCompletion {
5864 label: "clippy::serde_api_misuse", 5972 label: "clippy::serde_api_misuse",
@@ -5993,6 +6101,10 @@ pub(super) const CLIPPY_LINTS: &[LintCompletion] = &[
5993 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."##, 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."##,
5994 }, 6102 },
5995 LintCompletion { 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 {
5996 label: "clippy::suspicious_unary_op_formatting", 6108 label: "clippy::suspicious_unary_op_formatting",
5997 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."##, 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."##,
5998 }, 6110 },
@@ -6005,10 +6117,6 @@ pub(super) const CLIPPY_LINTS: &[LintCompletion] = &[
6005 description: r##"Checks for construction of a structure or tuple just to\nassign a value in it."##, 6117 description: r##"Checks for construction of a structure or tuple just to\nassign a value in it."##,
6006 }, 6118 },
6007 LintCompletion { 6119 LintCompletion {
6008 label: "clippy::temporary_cstring_as_ptr",
6009 description: r##"Nothing. This lint has been deprecated."##,
6010 },
6011 LintCompletion {
6012 label: "clippy::to_digit_is_some", 6120 label: "clippy::to_digit_is_some",
6013 description: r##"Checks for `.to_digit(..).is_some()` on `char`s."##, 6121 description: r##"Checks for `.to_digit(..).is_some()` on `char`s."##,
6014 }, 6122 },
@@ -6118,10 +6226,6 @@ pub(super) const CLIPPY_LINTS: &[LintCompletion] = &[
6118 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."##, 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."##,
6119 }, 6227 },
6120 LintCompletion { 6228 LintCompletion {
6121 label: "clippy::unknown_clippy_lints",
6122 description: r##"Nothing. This lint has been deprecated."##,
6123 },
6124 LintCompletion {
6125 label: "clippy::unnecessary_cast", 6229 label: "clippy::unnecessary_cast",
6126 description: r##"Checks for casts to the same type, casts of int literals to integer types\nand casts of float literals to float types."##, 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."##,
6127 }, 6231 },
@@ -6146,6 +6250,10 @@ pub(super) const CLIPPY_LINTS: &[LintCompletion] = &[
6146 description: r##"Checks for expression statements that can be reduced to a\nsub-expression."##, 6250 description: r##"Checks for expression statements that can be reduced to a\nsub-expression."##,
6147 }, 6251 },
6148 LintCompletion { 6252 LintCompletion {
6253 label: "clippy::unnecessary_self_imports",
6254 description: r##"Checks for imports ending in `::{self}`."##,
6255 },
6256 LintCompletion {
6149 label: "clippy::unnecessary_sort_by", 6257 label: "clippy::unnecessary_sort_by",
6150 description: r##"Detects uses of `Vec::sort_by` passing in a closure\nwhich compares the two arguments, either directly or indirectly."##, 6258 description: r##"Detects uses of `Vec::sort_by` passing in a closure\nwhich compares the two arguments, either directly or indirectly."##,
6151 }, 6259 },
@@ -6206,6 +6314,10 @@ pub(super) const CLIPPY_LINTS: &[LintCompletion] = &[
6206 description: r##"Nothing. This lint has been deprecated."##, 6314 description: r##"Nothing. This lint has been deprecated."##,
6207 }, 6315 },
6208 LintCompletion { 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 {
6209 label: "clippy::unused_collect", 6321 label: "clippy::unused_collect",
6210 description: r##"Nothing. This lint has been deprecated."##, 6322 description: r##"Nothing. This lint has been deprecated."##,
6211 }, 6323 },
@@ -6214,10 +6326,6 @@ pub(super) const CLIPPY_LINTS: &[LintCompletion] = &[
6214 description: r##"Checks for unused written/read amount."##, 6326 description: r##"Checks for unused written/read amount."##,
6215 }, 6327 },
6216 LintCompletion { 6328 LintCompletion {
6217 label: "clippy::unused_label",
6218 description: r##"Nothing. This lint has been deprecated."##,
6219 },
6220 LintCompletion {
6221 label: "clippy::unused_self", 6329 label: "clippy::unused_self",
6222 description: r##"Checks methods that contain a `self` argument but don't use it"##, 6330 description: r##"Checks methods that contain a `self` argument but don't use it"##,
6223 }, 6331 },
@@ -6347,11 +6455,11 @@ pub(super) const CLIPPY_LINTS: &[LintCompletion] = &[
6347 }, 6455 },
6348 LintCompletion { 6456 LintCompletion {
6349 label: "clippy::wrong_pub_self_convention", 6457 label: "clippy::wrong_pub_self_convention",
6350 description: r##"This is the same as\n[`wrong_self_convention`](#wrong_self_convention), but for public items."##, 6458 description: r##"Nothing. This lint has been deprecated."##,
6351 }, 6459 },
6352 LintCompletion { 6460 LintCompletion {
6353 label: "clippy::wrong_self_convention", 6461 label: "clippy::wrong_self_convention",
6354 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 |`self` taken |\n|-------|----------------------|\n|`as_` |`&self` or `&mut self`|\n|`from_`| none |\n|`into_`|`self` |\n|`is_` |`&self` or none |\n|`to_` |`&self` |"##, 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"##,
6355 }, 6463 },
6356 LintCompletion { 6464 LintCompletion {
6357 label: "clippy::wrong_transmute", 6465 label: "clippy::wrong_transmute",
diff --git a/crates/ide_completion/src/lib.rs b/crates/ide_completion/src/lib.rs
index 1152a9850..1f0158745 100644
--- a/crates/ide_completion/src/lib.rs
+++ b/crates/ide_completion/src/lib.rs
@@ -4,13 +4,14 @@ mod config;
4mod item; 4mod item;
5mod context; 5mod context;
6mod patterns; 6mod patterns;
7mod generated_lint_completions;
8#[cfg(test)] 7#[cfg(test)]
9mod test_utils; 8mod test_utils;
10mod render; 9mod render;
11 10
12mod completions; 11mod completions;
13 12
13pub mod generated_lint_completions;
14
14use completions::flyimport::position_for_import; 15use completions::flyimport::position_for_import;
15use ide_db::{ 16use ide_db::{
16 base_db::FilePosition, 17 base_db::FilePosition,
diff --git a/xtask/src/codegen/gen_lint_completions.rs b/xtask/src/codegen/gen_lint_completions.rs
index 24dbc6a39..f5736d1b5 100644
--- a/xtask/src/codegen/gen_lint_completions.rs
+++ b/xtask/src/codegen/gen_lint_completions.rs
@@ -28,9 +28,9 @@ pub(crate) fn generate_lint_completions() -> Result<()> {
28} 28}
29 29
30fn generate_descriptor(buf: &mut String, src_dir: PathBuf) -> Result<()> { 30fn generate_descriptor(buf: &mut String, src_dir: PathBuf) -> Result<()> {
31 buf.push_str(r#"pub(super) const FEATURES: &[LintCompletion] = &["#); 31 buf.push_str(r#"pub const FEATURES: &[LintCompletion] = &["#);
32 buf.push('\n'); 32 buf.push('\n');
33 ["language-features", "library-features"] 33 let mut vec = ["language-features", "library-features"]
34 .iter() 34 .iter()
35 .flat_map(|it| WalkDir::new(src_dir.join(it))) 35 .flat_map(|it| WalkDir::new(src_dir.join(it)))
36 .filter_map(|e| e.ok()) 36 .filter_map(|e| e.ok())
@@ -38,13 +38,17 @@ fn generate_descriptor(buf: &mut String, src_dir: PathBuf) -> Result<()> {
38 // Get all `.md ` files 38 // Get all `.md ` files
39 entry.file_type().is_file() && entry.path().extension().unwrap_or_default() == "md" 39 entry.file_type().is_file() && entry.path().extension().unwrap_or_default() == "md"
40 }) 40 })
41 .for_each(|entry| { 41 .map(|entry| {
42 let path = entry.path(); 42 let path = entry.path();
43 let feature_ident = path.file_stem().unwrap().to_str().unwrap().replace("-", "_"); 43 let feature_ident = path.file_stem().unwrap().to_str().unwrap().replace("-", "_");
44 let doc = read_file(path).unwrap(); 44 let doc = read_file(path).unwrap();
45 45 (feature_ident, doc)
46 push_lint_completion(buf, &feature_ident, &doc); 46 })
47 }); 47 .collect::<Vec<_>>();
48 vec.sort_by(|(feature_ident, _), (feature_ident2, _)| feature_ident.cmp(feature_ident2));
49 vec.into_iter().for_each(|(feature_ident, doc)| {
50 push_lint_completion(buf, &feature_ident, &doc);
51 });
48 buf.push_str("];\n"); 52 buf.push_str("];\n");
49 Ok(()) 53 Ok(())
50} 54}
@@ -85,8 +89,8 @@ fn generate_descriptor_clippy(buf: &mut String, path: &Path) -> Result<()> {
85 .into(); 89 .into();
86 } 90 }
87 } 91 }
88 92 clippy_lints.sort_by(|lint, lint2| lint.id.cmp(&lint2.id));
89 buf.push_str(r#"pub(super) const CLIPPY_LINTS: &[LintCompletion] = &["#); 93 buf.push_str(r#"pub const CLIPPY_LINTS: &[LintCompletion] = &["#);
90 buf.push('\n'); 94 buf.push('\n');
91 clippy_lints.into_iter().for_each(|clippy_lint| { 95 clippy_lints.into_iter().for_each(|clippy_lint| {
92 let lint_ident = format!("clippy::{}", clippy_lint.id); 96 let lint_ident = format!("clippy::{}", clippy_lint.id);