1 //! Generated file, do not edit by hand, see `xtask/src/codegen`
3 use crate::completions::attribute::LintCompletion;
4 pub(super) const FEATURES: &[LintCompletion] = &[
6 label: "plugin_registrar",
7 description: r##"# `plugin_registrar`
9 The tracking issue for this feature is: [#29597]
11 [#29597]: https://github.com/rust-lang/rust/issues/29597
13 This 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
19 ------------------------
23 label: "inline_const",
24 description: r##"# `inline_const`
26 The tracking issue for this feature is: [#76001]
30 This feature allows you to use inline constant expressions. For example, you can
34 # fn add_one(x: i32) -> i32 { x + 1 }
35 const MY_COMPUTATION: i32 = 1 + 2 * 3 / 4;
38 let x = add_one(MY_COMPUTATION);
45 #![feature(inline_const)]
47 # fn add_one(x: i32) -> i32 { x + 1 }
49 let x = add_one(const { 1 + 2 * 3 / 4 });
53 You can also use inline constant expressions in patterns:
56 #![feature(inline_const)]
58 const fn one() -> i32 { 1 }
62 const { 1 + 2 } => println!("Matched 1 + 2"),
63 const { one() } => println!("Matched const fn returning 1"),
64 _ => println!("Didn't match anything :("),
68 [#76001]: https://github.com/rust-lang/rust/issues/76001
73 description: r##"# `auto_traits`
75 The tracking issue for this feature is [#13231]
77 [#13231]: https://github.com/rust-lang/rust/issues/13231
81 The `auto_traits` feature gate allows you to define auto traits.
83 Auto traits, like [`Send`] or [`Sync`] in the standard library, are marker traits
84 that are automatically implemented for every type, unless the type, or a type it contains,
85 has explicitly opted out via a negative impl. (Negative impls are separately controlled
86 by the `negative_impls` feature.)
88 [`Send`]: https://doc.rust-lang.org/std/marker/trait.Send.html
89 [`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html
91 ```rust,ignore (partial-example)
92 impl !Trait for Type {}
98 #![feature(negative_impls)]
99 #![feature(auto_traits)]
106 impl !Valid for False {}
108 struct MaybeValid<T>(T);
110 fn must_be_valid<T: Valid>(_t: T) { }
114 must_be_valid( MaybeValid(True) );
116 // compiler error - trait bound not satisfied
117 // must_be_valid( MaybeValid(False) );
121 ## Automatic trait implementations
123 When a type is declared as an `auto trait`, we will automatically
124 create impls for every struct/enum/union, unless an explicit impl is
125 provided. These automatic impls contain a where clause for each field
126 of 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
128 struct `List` and the auto trait `Send`:
133 next: Option<Box<List<T>>>,
137 Presuming that there is no explicit impl of `Send` for `List`, the
138 compiler will supply an automatic impl of the form:
143 next: Option<Box<List<T>>>,
146 unsafe impl<T> Send for List<T>
148 T: Send, // from the field `data`
149 Option<Box<List<T>>>: Send, // from the field `next`
153 Explicit impls may be either positive or negative. They take the form:
155 ```rust,ignore (partial-example)
156 impl<...> AutoTrait for StructName<..> { }
157 impl<...> !AutoTrait for StructName<..> { }
160 ## Coinduction: Auto traits permit cyclic matching
162 Unlike ordinary trait matching, auto traits are **coinductive**. This
163 means, in short, that cycles which occur in trait matching are
164 considered ok. As an example, consider the recursive struct `List`
165 introduced 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
167 show that `Option<Box<List>>: Send`, which will in turn require
168 `Box<List>: Send` and then finally `List: Send` again. Under ordinary
169 trait matching, this cycle would be an error, but for an auto trait it
170 is considered a successful match.
174 Auto traits cannot have any trait items, such as methods or associated types. This ensures that we can generate default implementations.
178 Auto traits cannot have supertraits. This is for soundness reasons, as the interaction of coinduction with implied bounds is difficult to reconcile.
183 description: r##"# `ffi_const`
185 The tracking issue for this feature is: [#58328]
189 The `#[ffi_const]` attribute applies clang's `const` attribute to foreign
190 functions declarations.
192 That is, `#[ffi_const]` functions shall have no effects except for its return
193 value, which can only depend on the values of the function parameters, and is
194 not affected by changes to the observable state of the program.
196 Applying the `#[ffi_const]` attribute to a function that violates these
197 requirements is undefined behaviour.
199 This attribute enables Rust to perform common optimizations, like sub-expression
200 elimination, and it can avoid emitting some calls in repeated invocations of the
201 function with the same argument values regardless of other operations being
202 performed in between these functions calls (as opposed to `#[ffi_pure]`
207 A `#[ffi_const]` function can only read global memory that would not affect
208 its return value for the whole execution of the program (e.g. immutable global
209 memory). `#[ffi_const]` functions are referentially-transparent and therefore
210 more strict than `#[ffi_pure]` functions.
212 A common pitfall involves applying the `#[ffi_const]` attribute to a
213 function that reads memory through pointer arguments which do not necessarily
214 point to immutable global memory.
216 A `#[ffi_const]` function that returns unit has no effect on the abstract
217 machine's state, and a `#[ffi_const]` function cannot be `#[ffi_pure]`.
219 A `#[ffi_const]` function must not diverge, neither via a side effect (e.g. a
220 call to `abort`) nor by infinite loops.
222 When translating C headers to Rust FFI, it is worth verifying for which targets
223 the `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
227 implemented in this way on all of them. It is therefore also worth verifying
228 that the semantics of the C toolchain used to compile the binary being linked
229 against are compatible with those of the `#[ffi_const]`.
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
238 label: "external_doc",
239 description: r##"# `external_doc`
241 The tracking issue for this feature is: [#44732]
243 The `external_doc` feature allows the use of the `include` parameter to the `#[doc]` attribute, to
244 include external files in documentation. Use the attribute in place of, or in addition to, regular
245 doc comments and `#[doc]` attributes, and `rustdoc` will load the given file when it renders
246 documentation for your crate.
248 With the following files in the same directory:
255 This is the documentation for this spectacular type.
260 ```no_run (needs-external-files)
261 #![feature(external_doc)]
263 #[doc(include = "external-doc.md")]
264 pub struct MyAwesomeType;
267 `rustdoc` will load the file `external-doc.md` and use it as the documentation for the `MyAwesomeType`
270 When 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,
272 start your paths with `../docs/` for `rustdoc` to properly find the file.
274 This feature was proposed in [RFC #1990] and initially implemented in PR [#44781].
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
282 label: "box_patterns",
283 description: r##"# `box_patterns`
285 The tracking issue for this feature is: [#29641]
287 [#29641]: https://github.com/rust-lang/rust/issues/29641
289 See also [`box_syntax`](box-syntax.md)
291 ------------------------
293 Box patterns let you match on `Box<T>`s:
297 #![feature(box_patterns)]
300 let b = Some(Box::new(5));
302 Some(box n) if n < 0 => {
303 println!("Box contains negative number {}", n);
305 Some(box n) if n >= 0 => {
306 println!("Box contains non-negative number {}", n);
318 label: "abi_c_cmse_nonsecure_call",
319 description: r##"# `abi_c_cmse_nonsecure_call`
321 The tracking issue for this feature is: [#81391]
323 [#81391]: https://github.com/rust-lang/rust/issues/81391
325 ------------------------
328 feature](https://developer.arm.com/documentation/100690/latest/) is available
329 for targets with the Armv8-M architecture profile (`thumbv8m` in their target
331 LLVM, the Rust compiler and the linker are providing
332 [support](https://developer.arm.com/documentation/ecm0359818/latest/) for the
335 One of the things provided, with this unstable feature, is the
336 `C-cmse-nonsecure-call` function ABI. This ABI is used on function pointers to
337 non-secure code to mark a non-secure function call (see [section
338 5.5](https://developer.arm.com/documentation/ecm0359818/latest/) for details).
340 With this ABI, the compiler will do the following to perform the call:
341 * save registers needed after the call to Secure memory
342 * clear all registers that might contain confidential information
343 * clear the Least Significant Bit of the function address
344 * branches using the BLXNS instruction
346 To avoid using the non-secure stack, the compiler will constrain the number and
347 type of parameters/return value.
349 The `extern "C-cmse-nonsecure-call"` ABI is otherwise equivalent to the
352 <!-- NOTE(ignore) this example is specific to thumbv8m targets -->
356 #![feature(abi_c_cmse_nonsecure_call)]
359 pub fn call_nonsecure_function(addr: usize) -> u32 {
360 let non_secure_function =
361 unsafe { core::mem::transmute::<usize, extern "C-cmse-nonsecure-call" fn() -> u32>(addr) };
362 non_secure_function()
367 $ rustc --emit asm --crate-type lib --target thumbv8m.main-none-eabi function.rs
369 call_nonsecure_function:
383 push.w {r4, r5, r6, r7, r8, r9, r10, r11}
399 pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
410 label: "member_constraints",
411 description: r##"# `member_constraints`
413 The tracking issue for this feature is: [#61997]
415 [#61997]: https://github.com/rust-lang/rust/issues/61997
417 ------------------------
419 The `member_constraints` feature gate lets you use `impl Trait` syntax with
420 multiple unrelated lifetime parameters.
425 #![feature(member_constraints)]
427 trait Trait<'a, 'b> { }
428 impl<T> Trait<'_, '_> for T {}
430 fn foo<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Trait<'a, 'b> {
437 Without the `member_constraints` feature gate, the above example is an
438 error because both `'a` and `'b` appear in the impl Trait bounds, but
439 neither outlives the other.
443 label: "allocator_internals",
444 description: r##"# `allocator_internals`
446 This feature does not have a tracking issue, it is an unstable implementation
447 detail of the `global_allocator` feature not intended for use outside the
450 ------------------------
454 label: "cfg_sanitize",
455 description: r##"# `cfg_sanitize`
457 The tracking issue for this feature is: [#39699]
459 [#39699]: https://github.com/rust-lang/rust/issues/39699
461 ------------------------
463 The `cfg_sanitize` feature makes it possible to execute different code
464 depending on whether a particular sanitizer is enabled or not.
469 #![feature(cfg_sanitize)]
471 #[cfg(sanitize = "thread")]
476 #[cfg(not(sanitize = "thread"))]
482 if cfg!(sanitize = "leak") {
493 description: r##"# `cfg_panic`
495 The tracking issue for this feature is: [#77443]
497 [#77443]: https://github.com/rust-lang/rust/issues/77443
499 ------------------------
501 The `cfg_panic` feature makes it possible to execute different code
502 depending on the panic strategy.
504 Possible values at the moment are `"unwind"` or `"abort"`, although
505 it is possible that new panic strategies may be added to Rust in the
511 #![feature(cfg_panic)]
513 #[cfg(panic = "unwind")]
518 #[cfg(not(panic = "unwind"))]
524 if cfg!(panic = "abort") {
535 description: r##"# `ffi_pure`
537 The tracking issue for this feature is: [#58329]
541 The `#[ffi_pure]` attribute applies clang's `pure` attribute to foreign
542 functions declarations.
544 That is, `#[ffi_pure]` functions shall have no effects except for its return
545 value, which shall not change across two consecutive function calls with
548 Applying the `#[ffi_pure]` attribute to a function that violates these
549 requirements is undefined behavior.
551 This attribute enables Rust to perform common optimizations, like sub-expression
552 elimination and loop optimizations. Some common examples of pure functions are
553 `strlen` or `memcmp`.
555 These optimizations are only applicable when the compiler can prove that no
556 program state observable by the `#[ffi_pure]` function has changed between calls
557 of the function, which could alter the result. See also the `#[ffi_const]`
558 attribute, which provides stronger guarantees regarding the allowable behavior
559 of a function, enabling further optimization.
563 A `#[ffi_pure]` function can read global memory through the function
564 parameters (e.g. pointers), globals, etc. `#[ffi_pure]` functions are not
565 referentially-transparent, and are therefore more relaxed than `#[ffi_const]`
568 However, accessing global memory through volatile or atomic reads can violate the
569 requirement that two consecutive function calls shall return the same value.
571 A `pure` function that returns unit has no effect on the abstract machine's
574 A `#[ffi_pure]` function must not diverge, neither via a side effect (e.g. a
575 call to `abort`) nor by infinite loops.
577 When translating C headers to Rust FFI, it is worth verifying for which targets
578 the `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
582 implemented in this way on all of them. It is therefore also worth verifying
583 that the semantics of the C toolchain used to compile the binary being linked
584 against are compatible with those of the `#[ffi_pure]`.
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
595 description: r##"# `repr128`
597 The tracking issue for this feature is: [#56071]
599 [#56071]: https://github.com/rust-lang/rust/issues/56071
601 ------------------------
603 The `repr128` feature adds support for `#[repr(u128)]` on `enum`s.
617 description: r##"# `generators`
619 The tracking issue for this feature is: [#43122]
621 [#43122]: https://github.com/rust-lang/rust/issues/43122
623 ------------------------
625 The `generators` feature gate in Rust allows you to define generator or
626 coroutine literals. A generator is a "resumable function" that syntactically
627 resembles a closure but compiles to much different semantics in the compiler
628 itself. The primary feature of a generator is that it can be suspended during
629 execution 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
631 after the `yield` keyword.
633 Generators 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
635 gathering phase. The intent is that experimentation can happen on the nightly
636 compiler before actual stabilization. A further RFC will be required to
637 stabilize generators/coroutines and will likely contain at least a few small
638 tweaks to the overall design.
640 [RFC 2033]: https://github.com/rust-lang/rfcs/pull/2033
642 A syntactical example of a generator is:
645 #![feature(generators, generator_trait)]
647 use std::ops::{Generator, GeneratorState};
651 let mut generator = || {
656 match Pin::new(&mut generator).resume(()) {
657 GeneratorState::Yielded(1) => {}
658 _ => panic!("unexpected value from resume"),
660 match Pin::new(&mut generator).resume(()) {
661 GeneratorState::Complete("foo") => {}
662 _ => panic!("unexpected value from resume"),
667 Generators 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
669 generator. All generator literals implement the `Generator` trait in the
670 `std::ops` module. The `Generator` trait has one main method, `resume`, which
671 resumes execution of the generator at the previous suspension point.
673 An example of the control flow of generators is that the following example
674 prints all numbers in order:
677 #![feature(generators, generator_trait)]
679 use std::ops::Generator;
683 let mut generator = || {
690 Pin::new(&mut generator).resume(());
692 Pin::new(&mut generator).resume(());
697 At this time the main intended use case of generators is an implementation
698 primitive for async/await syntax, but generators will likely be extended to
699 ergonomic implementations of iterators and other primitives in the future.
700 Feedback on the design and usage is always appreciated!
702 ### The `Generator` trait
704 The `Generator` trait in `std::ops` currently looks like:
707 # #![feature(arbitrary_self_types, generator_trait)]
708 # use std::ops::GeneratorState;
711 pub trait Generator<R = ()> {
714 fn resume(self: Pin<&mut Self>, resume: R) -> GeneratorState<Self::Yield, Self::Return>;
718 The `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
720 generator. This is typically the last expression in a generator's definition or
721 any value passed to `return` in a generator. The `resume` function is the entry
722 point for executing the `Generator` itself.
724 The return value of `resume`, `GeneratorState`, looks like:
727 pub enum GeneratorState<Y, R> {
733 The `Yielded` variant indicates that the generator can later be resumed. This
734 corresponds to a `yield` point in a generator. The `Complete` variant indicates
735 that the generator is complete and cannot be resumed again. Calling `resume`
736 after a generator has returned `Complete` will likely result in a panic of the
739 ### Closure-like semantics
741 The closure-like syntax for generators alludes to the fact that they also have
742 closure-like semantics. Namely:
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
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.
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
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.
768 * Whenever a generator is dropped it will drop all captured environment
771 ### Generators as state machines
773 In the compiler, generators are currently compiled as state machines. Each
774 `yield` expression will correspond to a different state that stores all live
775 variables over that suspension point. Resumption of a generator will dispatch on
776 the current state and then execute internally until a `yield` is reached, at
777 which point all state is saved off in the generator and a value is returned.
779 Let's take a look at an example to see what's going on here:
782 #![feature(generators, generator_trait)]
784 use std::ops::Generator;
789 let mut generator = move || {
794 Pin::new(&mut generator).resume(());
795 Pin::new(&mut generator).resume(());
799 This generator literal will compile down to something similar to:
802 #![feature(arbitrary_self_types, generators, generator_trait)]
804 use std::ops::{Generator, GeneratorState};
809 let mut generator = {
812 Yield1(&'static str),
816 impl Generator for __Generator {
818 type Return = &'static str;
820 fn resume(mut self: Pin<&mut Self>, resume: ()) -> GeneratorState<i32, &'static str> {
822 match mem::replace(&mut *self, __Generator::Done) {
823 __Generator::Start(s) => {
824 *self = __Generator::Yield1(s);
825 GeneratorState::Yielded(1)
828 __Generator::Yield1(s) => {
829 *self = __Generator::Done;
830 GeneratorState::Complete(s)
833 __Generator::Done => {
834 panic!("generator resumed after completion")
840 __Generator::Start(ret)
843 Pin::new(&mut generator).resume(());
844 Pin::new(&mut generator).resume(());
848 Notably 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
850 as an `enum`) corresponding to each of the conceptual states of the generator.
851 At the beginning we're closing over our outer variable `foo` and then that
852 variable is also live over the `yield` point, so it's stored in both states.
854 When the generator starts it'll immediately yield 1, but it saves off its state
855 just before it does so indicating that it has reached the yield point. Upon
856 resuming again we'll execute the `return ret` which returns the `Complete`
859 Here we can also note that the `Done` state, if resumed, panics immediately as
860 it's invalid to resume a completed generator. It's also worth noting that this
861 is just a rough desugaring, not a normative specification for what the compiler
866 label: "non_ascii_idents",
867 description: r##"# `non_ascii_idents`
869 The tracking issue for this feature is: [#55467]
871 [#55467]: https://github.com/rust-lang/rust/issues/55467
873 ------------------------
875 The `non_ascii_idents` feature adds support for non-ASCII identifiers.
880 #![feature(non_ascii_idents)]
882 const ε: f64 = 0.00001f64;
883 const Î : f64 = 3.14f64;
886 ## Changes to the language reference
888 > **<sup>Lexer:<sup>**\
890 > XID_start XID_continue<sup>\*</sup>\
891 > | `_` XID_continue<sup>+</sup>
893 An identifier is any nonempty Unicode string of the following form:
897 * The first character has property [`XID_start`]
898 * The remaining characters have property [`XID_continue`]
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`]
906 that does _not_ occur in the set of [strict keywords].
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
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
918 label: "compiler_builtins",
919 description: r##"# `compiler_builtins`
921 This feature is internal to the Rust compiler and is not intended for general use.
923 ------------------------
927 label: "or_patterns",
928 description: r##"# `or_patterns`
930 The tracking issue for this feature is: [#54883]
932 [#54883]: https://github.com/rust-lang/rust/issues/54883
934 ------------------------
936 The `or_pattern` language feature allows `|` to be arbitrarily nested within
937 a pattern, for example, `Some(A(0) | B(1 | 2))` becomes a valid pattern.
942 #![feature(or_patterns)]
950 pub fn example(maybe_foo: Option<Foo>) {
952 Some(Foo::Bar | Foo::Baz) => {
953 println!("The value contained `Bar` or `Baz`");
956 println!("The value did not contain `Bar` or `Baz`");
959 println!("The value was `None`");
967 label: "negative_impls",
968 description: r##"# `negative_impls`
970 The tracking issue for this feature is [#68318].
972 [#68318]: https://github.com/rust-lang/rust/issues/68318
976 With the feature gate `negative_impls`, you can write negative impls as well as positive ones:
979 #![feature(negative_impls)]
981 impl<T: ?Sized> !DerefMut for &T { }
984 Negative 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.
986 Negative impls have the following characteristics:
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.
992 ## Semver interaction
994 It is a breaking change to remove a negative impl. Negative impls are a commitment not to implement the given trait for the named types.
996 ## Orphan and overlap rules
998 Negative 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.
1000 Similarly, 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.)
1002 ## Interaction with auto traits
1004 Declaring a negative impl `impl !SomeAutoTrait for SomeType` for an
1005 auto-trait serves two purposes:
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.
1010 Note that, at present, there is no way to indicate that a given type
1011 does not implement an auto trait *but that it may do so in the
1012 future*. For ordinary types, this is done by simply not declaring any
1013 impl at all, but that is not an option for auto traits. A workaround
1014 is that one could embed a marker type as one of the fields, where the
1015 marker type is `!AutoTrait`.
1019 Negative 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).
1021 This serves two purposes:
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.
1028 label: "cmse_nonsecure_entry",
1029 description: r##"# `cmse_nonsecure_entry`
1031 The tracking issue for this feature is: [#75835]
1033 [#75835]: https://github.com/rust-lang/rust/issues/75835
1035 ------------------------
1038 feature](https://developer.arm.com/documentation/100690/latest/) is available
1039 for targets with the Armv8-M architecture profile (`thumbv8m` in their target
1041 LLVM, the Rust compiler and the linker are providing
1042 [support](https://developer.arm.com/documentation/ecm0359818/latest/) for the
1043 TrustZone-M feature.
1045 One of the things provided, with this unstable feature, is the
1046 `cmse_nonsecure_entry` attribute. This attribute marks a Secure function as an
1047 entry function (see [section
1048 5.4](https://developer.arm.com/documentation/ecm0359818/latest/) for details).
1049 With 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
1055 * use the `BXNS` instruction to return
1057 Because the stack can not be used to pass parameters, there will be compilation
1059 * the total size of all parameters is too big (for example more than four 32
1061 * the entry function is not using a C ABI
1063 The special symbol `__acle_se_` will be used by the linker to generate a secure
1066 <!-- NOTE(ignore) this example is specific to thumbv8m targets -->
1069 #![feature(cmse_nonsecure_entry)]
1072 #[cmse_nonsecure_entry]
1073 pub extern "C" fn entry_function(input: u32) -> u32 {
1079 $ rustc --emit obj --crate-type lib --target thumbv8m.main-none-eabi function.rs
1080 $ arm-none-eabi-objdump -D function.o
1082 00000000 <entry_function>:
1083 0: b580 push {r7, lr}
1086 6: 9001 str r0, [sp, #4]
1087 8: 1d81 adds r1, r0, #6
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]
1095 18: e8bd 4080 ldmia.w sp!, {r7, lr}
1100 24: f38e 8800 msr CPSR_f, 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
1114 description: r##"# `plugin`
1116 The tracking issue for this feature is: [#29597]
1118 [#29597]: https://github.com/rust-lang/rust/issues/29597
1121 This feature is part of "compiler plugins." It will often be used with the
1122 [`plugin_registrar`] and `rustc_private` features.
1124 [`plugin_registrar`]: plugin-registrar.md
1126 ------------------------
1128 `rustc` can load compiler plugins, which are user-provided libraries that
1129 extend the compiler's behavior with new lint checks, etc.
1131 A plugin is a dynamic library crate with a designated *registrar* function that
1132 registers extensions with `rustc`. Other crates can load these extensions using
1133 the crate attribute `#![plugin(...)]`. See the
1134 `rustc_driver::plugin` documentation for more about the
1135 mechanics of defining and loading a plugin.
1137 In 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
1139 pull in all of librustc_ast and librustc as dependencies of your crate. This is
1140 generally unwanted unless you are building another plugin.
1142 The usual practice is to put compiler plugins in their own crate, separate from
1143 any `macro_rules!` macros or ordinary Rust code meant to be used by consumers
1148 Plugins can extend [Rust's lint
1149 infrastructure](../../reference/attributes/diagnostics.md#lint-check-attributes) with
1150 additional 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)
1152 that warns about any item named `lintme`.
1154 ```rust,ignore (requires-stage-2)
1155 #![feature(plugin_registrar)]
1156 #![feature(box_syntax, rustc_private)]
1158 extern crate rustc_ast;
1160 // Load rustc as a plugin to get macros
1161 extern crate rustc_driver;
1163 extern crate rustc_lint;
1165 extern crate rustc_session;
1167 use rustc_driver::plugin::Registry;
1168 use rustc_lint::{EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass};
1170 declare_lint!(TEST_LINT, Warn, "Warn about items named 'lintme'");
1172 declare_lint_pass!(Pass => [TEST_LINT]);
1174 impl 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()
1185 pub fn plugin_registrar(reg: &mut Registry) {
1186 reg.lint_store.register_lints(&[&TEST_LINT]);
1187 reg.lint_store.register_early_pass(|| box Pass);
1193 ```rust,ignore (requires-plugin)
1195 #![plugin(lint_plugin_test)]
1200 will produce a compiler warning:
1203 foo.rs:4:1: 4:16 warning: item is named 'lintme', #[warn(test_lint)] on by default
1204 foo.rs:4 fn lintme() { }
1208 The components of a lint plugin are:
1210 * one or more `declare_lint!` invocations, which define static `Lint` structs;
1212 * a struct holding any state needed by the lint pass (here, none);
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.
1219 Lint passes are syntax traversals, but they run at a late stage of compilation
1220 where type information is available. `rustc`'s [built-in
1221 lints](https://github.com/rust-lang/rust/blob/master/src/librustc_session/lint/builtin.rs)
1222 mostly use the same infrastructure as lint plugins, and provide examples of how
1223 to access type information.
1225 Lints defined by plugins are controlled by the usual [attributes and compiler
1226 flags](../../reference/attributes/diagnostics.md#lint-check-attributes), e.g.
1227 `#[allow(test_lint)]` or `-A test-lint`. These identifiers are derived from the
1228 first argument to `declare_lint!`, with appropriate case and punctuation
1231 You can run `rustc -W help foo.rs` to see a list of lints known to `rustc`,
1232 including those provided by plugins loaded by `foo.rs`.
1236 label: "intrinsics",
1237 description: r##"# `intrinsics`
1239 The tracking issue for this feature is: None.
1241 Intrinsics are never intended to be stable directly, but intrinsics are often
1242 exported in some sort of stable manner. Prefer using the stable interfaces to
1243 the intrinsic directly when you can.
1245 ------------------------
1248 These are imported as if they were FFI functions, with the special
1249 `rust-intrinsic` ABI. For example, if one was in a freestanding
1250 context, but wished to be able to `transmute` between types, and
1251 perform efficient pointer arithmetic, one would import those functions
1252 via a declaration like
1255 #![feature(intrinsics)]
1258 extern "rust-intrinsic" {
1259 fn transmute<T, U>(x: T) -> U;
1261 fn offset<T>(dst: *const T, offset: isize) -> *const T;
1265 As with any other FFI functions, these are always `unsafe` to call.
1269 label: "rustc_attrs",
1270 description: r##"# `rustc_attrs`
1272 This feature has no tracking issue, and is therefore internal to
1273 the compiler, not being intended for general use.
1275 Note: `rustc_attrs` enables many rustc-internal attributes and this page
1276 only discuss a few of them.
1278 ------------------------
1280 The `rustc_attrs` feature allows debugging rustc type layouts by using
1281 `#[rustc_layout(...)]` to debug layout at compile time (it even works
1282 with `cargo check`) as an alternative to `rustc -Z print-type-sizes`
1283 that is way more verbose.
1285 Options provided by `#[rustc_layout(...)]` are `debug`, `size`, `align`,
1286 `abi`. Note that it only works on sized types without generics.
1290 ```rust,compile_fail
1291 #![feature(rustc_attrs)]
1293 #[rustc_layout(abi, size)]
1300 When that is compiled, the compiler will error with something like
1303 error: abi: Aggregate { sized: true }
1307 5 | | Y(u8, u8, u8),
1312 error: size: Size { raw: 16 }
1316 5 | | Y(u8, u8, u8),
1321 error: aborting due to 2 previous errors
1327 description: r##"# `const_fn`
1329 The tracking issue for this feature is: [#57563]
1331 [#57563]: https://github.com/rust-lang/rust/issues/57563
1333 ------------------------
1335 The `const_fn` feature enables additional functionality not stabilized in the
1336 [minimal subset of `const_fn`](https://github.com/rust-lang/rust/issues/53555)
1340 label: "abi_thiscall",
1341 description: r##"# `abi_thiscall`
1343 The tracking issue for this feature is: [#42202]
1345 [#42202]: https://github.com/rust-lang/rust/issues/42202
1347 ------------------------
1349 The MSVC ABI on x86 Windows uses the `thiscall` calling convention for C++
1350 instance methods by default; it is identical to the usual (C) calling
1351 convention on x86 Windows except that the first parameter of the method,
1352 the `this` pointer, is passed in the ECX register.
1356 label: "trait_alias",
1357 description: r##"# `trait_alias`
1359 The tracking issue for this feature is: [#41517]
1361 [#41517]: https://github.com/rust-lang/rust/issues/41517
1363 ------------------------
1365 The `trait_alias` feature adds support for trait aliases. These allow aliases
1366 to be created for one or more traits (currently just a single regular trait plus
1367 any number of auto-traits), and used wherever traits would normally be used as
1368 either bounds or trait objects.
1371 #![feature(trait_alias)]
1373 trait Foo = std::fmt::Debug + Send;
1374 trait Bar = Foo + Sync;
1376 // Use trait alias as bound on type parameter.
1377 fn foo<T: Foo>(v: &T) {
1378 println!("{:?}", v);
1384 // Use trait alias for trait objects.
1386 println!("{:?}", a);
1387 let b = Box::new(456) as Box<dyn Foo>;
1388 println!("{:?}", b);
1394 label: "lang_items",
1395 description: r##"# `lang_items`
1397 The tracking issue for this feature is: None.
1399 ------------------------
1401 The `rustc` compiler has certain pluggable operations, that is,
1402 functionality that isn't hard-coded into the language, but is
1403 implemented in libraries, with a special marker to tell the compiler
1404 it exists. The marker is the attribute `#[lang = "..."]` and there are
1405 various different values of `...`, i.e. various different 'lang
1408 For example, `Box` pointers require two lang items, one for allocation
1409 and one for deallocation. A freestanding program that uses the `Box`
1410 sugar for dynamic allocations via `malloc` and `free`:
1412 ```rust,ignore (libc-is-finicky)
1413 #![feature(lang_items, box_syntax, start, libc, core_intrinsics, rustc_private)]
1415 use core::intrinsics;
1416 use core::panic::PanicInfo;
1420 #[lang = "owned_box"]
1421 pub struct Box<T>(*mut T);
1423 #[lang = "exchange_malloc"]
1424 unsafe fn allocate(size: usize, _align: usize) -> *mut u8 {
1425 let p = libc::malloc(size as libc::size_t) as *mut u8;
1427 // Check if `malloc` failed:
1428 if p as usize == 0 {
1429 intrinsics::abort();
1435 #[lang = "box_free"]
1436 unsafe fn box_free<T: ?Sized>(ptr: *mut T) {
1437 libc::free(ptr as *mut libc::c_void)
1441 fn main(_argc: isize, _argv: *const *const u8) -> isize {
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 () {}
1453 Note the use of `abort`: the `exchange_malloc` lang item is assumed to
1454 return a valid pointer, and so needs to do the check internally.
1456 Other features provided by lang items include:
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.
1470 Lang 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`
1472 and `box_free`. `rustc` will emit an error when an item is needed
1473 but not found in the current crate or any that it depends on.
1475 Most lang items are defined by `libcore`, but if you're trying to build
1476 an executable without the standard library, you'll run into the need
1477 for lang items. The rest of this page focuses on this use-case, even though
1478 lang items are a bit broader than that.
1482 In order to build a `#[no_std]` executable we will need libc as a dependency.
1483 We can specify this using our `Cargo.toml` file:
1487 libc = { version = "0.2.14", default-features = false }
1490 Note 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
1494 ### Writing an executable without stdlib
1496 Controlling the entry point is possible in two ways: the `#[start]` attribute,
1497 or overriding the default shim for the C `main` function with your own.
1499 The function marked `#[start]` is passed the command line parameters
1500 in the same format as C:
1502 ```rust,ignore (libc-is-finicky)
1503 #![feature(lang_items, core_intrinsics, rustc_private)]
1506 use core::intrinsics;
1507 use core::panic::PanicInfo;
1509 // Pull in the system libc library for what crt0.o likely requires.
1512 // Entry point for this program.
1514 fn start(_argc: isize, _argv: *const *const u8) -> isize {
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"]
1523 pub extern fn rust_eh_personality() {
1526 #[lang = "panic_impl"]
1528 pub extern fn rust_begin_panic(info: &PanicInfo) -> ! {
1529 unsafe { intrinsics::abort() }
1533 To override the compiler-inserted `main` shim, one has to disable it
1534 with `#![no_main]` and then create the appropriate symbol with the
1535 correct ABI and the correct name, which requires overriding the
1536 compiler's name mangling too:
1538 ```rust,ignore (libc-is-finicky)
1539 #![feature(lang_items, core_intrinsics, rustc_private)]
1543 use core::intrinsics;
1544 use core::panic::PanicInfo;
1546 // Pull in the system libc library for what crt0.o likely requires.
1549 // Entry point for this program.
1550 #[no_mangle] // ensure that this symbol is called `main` in the output
1551 pub extern fn main(_argc: i32, _argv: *const *const u8) -> i32 {
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"]
1560 pub extern fn rust_eh_personality() {
1563 #[lang = "panic_impl"]
1565 pub extern fn rust_begin_panic(info: &PanicInfo) -> ! {
1566 unsafe { intrinsics::abort() }
1570 In many cases, you may need to manually link to the `compiler_builtins` crate
1571 when building a `no_std` binary. You may observe this via linker error messages
1572 such as "```undefined reference to `__rust_probestack'```".
1574 ## More about the language items
1576 The compiler currently makes a few assumptions about symbols which are
1577 available in the executable to call. Normally these functions are provided by
1578 the standard library, but without it you must define your own. These symbols
1579 are called "language items", and they each have an internal name, and then a
1580 signature that an implementation must conform to.
1582 The first of these functions, `rust_eh_personality`, is used by the failure
1583 mechanisms of the compiler. This is often mapped to GCC's personality function
1584 (see the [libstd implementation][unwind] for more information), but crates
1585 which do not trigger a panic can be assured that this function is never
1586 called. The language item's name is `eh_personality`.
1588 [unwind]: https://github.com/rust-lang/rust/blob/master/src/libpanic_unwind/gcc.rs
1590 The second function, `rust_begin_panic`, is also used by the failure mechanisms of the
1591 compiler. When a panic happens, this controls the message that's displayed on
1592 the screen. While the language item's name is `panic_impl`, the symbol name is
1595 Finally, a `eh_catch_typeinfo` static is needed for certain targets which
1596 implement Rust panics on top of C++ exceptions.
1598 ## List of all language items
1600 This is a list of all language items in Rust along with where they are located in
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`
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`
1635 - `owned_box`: `liballoc/boxed.rs`
1636 - `exchange_malloc`: `liballoc/heap.rs`
1637 - `box_free`: `liballoc/heap.rs`
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`
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`
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`
1693 label: "doc_spotlight",
1694 description: r##"# `doc_spotlight`
1696 The tracking issue for this feature is: [#45040]
1698 The `doc_spotlight` feature allows the use of the `spotlight` parameter to the `#[doc]` attribute,
1699 to "spotlight" a specific trait on the return values of functions. Adding a `#[doc(spotlight)]`
1700 attribute to a trait definition will make rustdoc print extra information for functions which return
1701 a 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.
1704 You can do this on your own traits, like this:
1707 #![feature(doc_spotlight)]
1710 pub trait MyTrait {}
1712 pub struct MyStruct;
1713 impl MyTrait for MyStruct {}
1715 /// The docs for this function will have an extra line about `MyStruct` implementing `MyTrait`,
1716 /// without having to write that yourself!
1717 pub fn my_fn() -> MyStruct { MyStruct }
1720 This feature was originally implemented in PR [#45039].
1722 [#45040]: https://github.com/rust-lang/rust/issues/45040
1723 [#45039]: https://github.com/rust-lang/rust/pull/45039
1727 label: "c_variadic",
1728 description: r##"# `c_variadic`
1730 The tracking issue for this feature is: [#44930]
1732 [#44930]: https://github.com/rust-lang/rust/issues/44930
1734 ------------------------
1736 The `c_variadic` language feature enables C-variadic functions to be
1737 defined in Rust. The may be called both from within Rust and via FFI.
1742 #![feature(c_variadic)]
1744 pub unsafe extern "C" fn add(n: usize, mut args: ...) -> usize {
1747 sum += args.arg::<usize>();
1755 label: "intra_doc_pointers",
1756 description: r##"# `intra-doc-pointers`
1758 The tracking issue for this feature is: [#80896]
1760 [#80896]: https://github.com/rust-lang/rust/issues/80896
1762 ------------------------
1764 Rustdoc does not currently allow disambiguating between `*const` and `*mut`, and
1765 raw pointers in intra-doc links are unstable until it does.
1768 #![feature(intra_doc_pointers)]
1774 label: "box_syntax",
1775 description: r##"# `box_syntax`
1777 The tracking issue for this feature is: [#49733]
1779 [#49733]: https://github.com/rust-lang/rust/issues/49733
1781 See also [`box_patterns`](box-patterns.md)
1783 ------------------------
1785 Currently the only stable way to create a `Box` is via the `Box::new` method.
1786 Also it is not possible in stable Rust to destructure a `Box` in a match
1787 pattern. The unstable `box` keyword can be used to create a `Box`. An example
1791 #![feature(box_syntax)]
1800 label: "unsized_locals",
1801 description: r##"# `unsized_locals`
1803 The tracking issue for this feature is: [#48055]
1805 [#48055]: https://github.com/rust-lang/rust/issues/48055
1807 ------------------------
1809 This implements [RFC1909]. When turned on, you can have unsized arguments and locals:
1811 [RFC1909]: https://github.com/rust-lang/rfcs/blob/master/text/1909-unsized-rvalues.md
1814 #![allow(incomplete_features)]
1815 #![feature(unsized_locals, unsized_fn_params)]
1820 let x: Box<dyn Any> = Box::new(42);
1821 let x: dyn Any = *x;
1822 // ^ unsized local variable
1823 // ^^ unsized temporary
1827 fn foo(_: dyn Any) {}
1828 // ^^^^^^ unsized argument
1831 The RFC still forbids the following unsized expressions:
1833 ```rust,compile_fail
1834 #![feature(unsized_locals)]
1838 struct MyStruct<T: ?Sized> {
1842 struct MyTupleStruct<T: ?Sized>(T);
1844 fn answer() -> Box<dyn Any> {
1849 // You CANNOT have unsized statics.
1850 static X: dyn Any = *answer(); // ERROR
1851 const Y: dyn Any = *answer(); // ERROR
1853 // You CANNOT have struct initialized unsized.
1854 MyStruct { content: *answer() }; // ERROR
1855 MyTupleStruct(*answer()); // ERROR
1856 (42, *answer()); // ERROR
1858 // You CANNOT have unsized return types.
1859 fn my_function() -> dyn Any { *answer() } // ERROR
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
1866 // You CANNOT even initialize them separately.
1867 let y: dyn Any; // OK
1868 y = *answer(); // ERROR
1870 // Not mentioned in the RFC, but by-move captured variables are also Sized.
1871 let x: dyn Any = *answer();
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
1884 ## By-value trait objects
1886 With this feature, you can have by-value `self` arguments without `Self: Sized` bounds.
1889 #![feature(unsized_fn_params)]
1895 impl<T: ?Sized> Foo for T {}
1898 let slice: Box<[i32]> = Box::new([1, 2, 3]);
1899 <[i32] as Foo>::foo(*slice);
1903 And `Foo` will also be object-safe.
1906 #![feature(unsized_fn_params)]
1912 impl<T: ?Sized> Foo for T {}
1915 let slice: Box<dyn Foo> = Box::new([1, 2, 3]);
1916 // doesn't compile yet
1917 <dyn Foo as Foo>::foo(*slice);
1921 One of the objectives of this feature is to allow `Box<dyn FnOnce>`.
1923 ## Variable length arrays
1925 The 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]`.
1927 ```rust,ignore (not-yet-implemented)
1928 #![feature(unsized_locals)]
1930 fn mergesort<T: Ord>(a: &mut [T]) {
1931 let mut tmp = [T; dyn a.len()];
1936 let mut a = [3, 1, 5, 6];
1938 assert_eq!(a, [1, 3, 5, 6]);
1942 VLAs 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]`.
1944 ## Advisory on stack usage
1946 It's advised not to casually use the `#![feature(unsized_locals)]` feature. Typical use-cases are:
1948 - When you need a by-value trait objects.
1949 - When you really need a fast allocation of small temporary arrays.
1951 Another 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
1954 #![feature(unsized_locals)]
1957 let x: Box<[i32]> = Box::new([1, 2, 3, 4, 5]);
1958 let _x = {{{{{{{{{{*x}}}}}}}}}};
1965 #![feature(unsized_locals)]
1969 let x: Box<[i32]> = Box::new([1, 2, 3, 4, 5]);
1975 will unnecessarily extend the stack frame.
1979 label: "arbitrary_enum_discriminant",
1980 description: r##"# `arbitrary_enum_discriminant`
1982 The tracking issue for this feature is: [#60553]
1984 [#60553]: https://github.com/rust-lang/rust/issues/60553
1986 ------------------------
1988 The `arbitrary_enum_discriminant` feature permits tuple-like and
1989 struct-like enum variants with `#[repr(<int-type>)]` to have explicit discriminants.
1994 #![feature(arbitrary_enum_discriminant)]
2008 fn tag(&self) -> u8 {
2009 unsafe { *(self as *const Self as *const u8) }
2013 assert_eq!(3, Enum::Unit.tag());
2014 assert_eq!(2, Enum::Tuple(5).tag());
2015 assert_eq!(1, Enum::Struct{a: 7, b: 11}.tag());
2020 label: "unboxed_closures",
2021 description: r##"# `unboxed_closures`
2023 The tracking issue for this feature is [#29625]
2025 See Also: [`fn_traits`](../library-features/fn-traits.md)
2027 [#29625]: https://github.com/rust-lang/rust/issues/29625
2031 The `unboxed_closures` feature allows you to write functions using the `"rust-call"` ABI,
2032 required for implementing the [`Fn*`] family of traits. `"rust-call"` functions must have
2033 exactly one (non self) argument, a tuple representing the argument list.
2035 [`Fn*`]: https://doc.rust-lang.org/std/ops/trait.Fn.html
2038 #![feature(unboxed_closures)]
2040 extern "rust-call" fn add_args(args: (u32, u32)) -> u32 {
2049 label: "custom_test_frameworks",
2050 description: r##"# `custom_test_frameworks`
2052 The tracking issue for this feature is: [#50297]
2054 [#50297]: https://github.com/rust-lang/rust/issues/50297
2056 ------------------------
2058 The `custom_test_frameworks` feature allows the use of `#[test_case]` and `#![test_runner]`.
2059 Any function, const, or static can be annotated with `#[test_case]` causing it to be aggregated (like `#[test]`)
2060 and be passed to the test runner determined by the `#![test_runner]` crate attribute.
2063 #![feature(custom_test_frameworks)]
2064 #![test_runner(my_runner)]
2066 fn my_runner(tests: &[&i32]) {
2077 const WILL_PASS: i32 = 0;
2080 const WILL_FAIL: i32 = 4;
2085 label: "abi_msp430_interrupt",
2086 description: r##"# `abi_msp430_interrupt`
2088 The tracking issue for this feature is: [#38487]
2090 [#38487]: https://github.com/rust-lang/rust/issues/38487
2092 ------------------------
2094 In the MSP430 architecture, interrupt handlers have a special calling
2095 convention. You can use the `"msp430-interrupt"` ABI to make the compiler apply
2096 the right calling convention to the interrupt handlers you define.
2098 <!-- NOTE(ignore) this example is specific to the msp430 target -->
2101 #![feature(abi_msp430_interrupt)]
2104 // Place the interrupt handler at the appropriate memory address
2105 // (Alternatively, you can use `#[used]` and remove `pub` and `#[no_mangle]`)
2106 #[link_section = "__interrupt_vector_10"]
2108 pub static TIM0_VECTOR: extern "msp430-interrupt" fn() = tim0;
2110 // The interrupt handler
2111 extern "msp430-interrupt" fn tim0() {
2117 $ msp430-elf-objdump -CD ./target/msp430/release/app
2118 Disassembly of section __interrupt_vector_10:
2120 0000fff2 <TIM0_VECTOR>:
2121 fff2: 00 c0 interrupt service routine at 0xc000
2123 Disassembly of section .text:
2125 0000c000 <int::tim0>:
2131 label: "impl_trait_in_bindings",
2132 description: r##"# `impl_trait_in_bindings`
2134 The tracking issue for this feature is: [#63065]
2136 [#63065]: https://github.com/rust-lang/rust/issues/63065
2138 ------------------------
2140 The `impl_trait_in_bindings` feature gate lets you use `impl Trait` syntax in
2141 `let`, `static`, and `const` bindings.
2143 A simple example is:
2146 #![feature(impl_trait_in_bindings)]
2148 use std::fmt::Debug;
2151 let a: impl Debug + Clone = 42;
2153 println!("{:?}", b); // prints `42`
2157 Note however that because the types of `a` and `b` are opaque in the above
2158 example, 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.
2163 label: "cfg_version",
2164 description: r##"# `cfg_version`
2166 The tracking issue for this feature is: [#64796]
2168 [#64796]: https://github.com/rust-lang/rust/issues/64796
2170 ------------------------
2172 The `cfg_version` feature makes it possible to execute different code
2173 depending on the compiler version.
2178 #![feature(cfg_version)]
2180 #[cfg(version("1.42"))]
2185 #[cfg(not(version("1.42")))]
2191 if cfg!(version("1.42")) {
2202 description: r##"# `link_cfg`
2204 This feature is internal to the Rust compiler and is not intended for general use.
2206 ------------------------
2210 label: "infer_static_outlives_requirements",
2211 description: r##"# `infer_static_outlives_requirements`
2213 The tracking issue for this feature is: [#54185]
2215 [#54185]: https://github.com/rust-lang/rust/issues/54185
2217 ------------------------
2218 The `infer_static_outlives_requirements` feature indicates that certain
2219 `'static` outlives requirements can be inferred by the compiler rather than
2220 stating them explicitly.
2222 Note: It is an accompanying feature to `infer_outlives_requirements`,
2223 which must be enabled to infer outlives requirements.
2225 For example, currently generic struct definitions that contain
2226 references, require where-clauses of the form T: 'static. By using
2227 this feature the outlives predicates will be inferred, although
2228 they may still be written explicitly.
2230 ```rust,ignore (pseudo-Rust)
2231 struct Foo<U> where U: 'static { // <-- currently required
2234 struct Bar<T: 'static> {
2242 ```rust,ignore (pseudo-Rust)
2243 #![feature(infer_outlives_requirements)]
2244 #![feature(infer_static_outlives_requirements)]
2247 // Implicitly infer U: 'static
2251 struct Bar<T: 'static> {
2258 label: "marker_trait_attr",
2259 description: r##"# `marker_trait_attr`
2261 The tracking issue for this feature is: [#29864]
2263 [#29864]: https://github.com/rust-lang/rust/issues/29864
2265 ------------------------
2267 Normally, Rust keeps you from adding trait implementations that could
2268 overlap with each other, as it would be ambiguous which to use. This
2269 feature, however, carves out an exception to that rule: a trait can
2270 opt-in to having overlapping implementations, at the cost that those
2271 implementations are not allowed to override anything (and thus the
2272 trait itself cannot have any associated items, as they're pointless
2273 when they'd need to do the same thing for every type anyway).
2276 #![feature(marker_trait_attr)]
2278 #[marker] trait CheapToClone: Clone {}
2280 impl<T: Copy> CheapToClone for T {}
2282 // These could potentially overlap with the blanket implementation above,
2283 // so are only allowed because CheapToClone is a marker trait.
2284 impl<T: CheapToClone, U: CheapToClone> CheapToClone for (T, U) {}
2285 impl<T: CheapToClone> CheapToClone for std::ops::Range<T> {}
2287 fn cheap_clone<T: CheapToClone>(t: T) -> T {
2292 This is expected to replace the unstable `overlapping_marker_traits`
2293 feature, which applied to all empty traits (without needing an opt-in).
2297 label: "doc_masked",
2298 description: r##"# `doc_masked`
2300 The tracking issue for this feature is: [#44027]
2304 The `doc_masked` feature allows a crate to exclude types from a given crate from appearing in lists
2305 of trait implementations. The specifics of the feature are as follows:
2307 1. When rustdoc encounters an `extern crate` statement annotated with a `#[doc(masked)]` attribute,
2308 it marks the crate as being masked.
2310 2. When listing traits a given type implements, rustdoc ensures that traits from masked crates are
2311 not emitted into the documentation.
2313 3. When listing types that implement a given trait, rustdoc ensures that types from masked crates
2314 are not emitted into the documentation.
2316 This feature was introduced in PR [#44026] to ensure that compiler-internal and
2317 implementation-specific types and traits were not included in the standard library's documentation.
2318 Such types would introduce broken links into the documentation.
2320 [#44026]: https://github.com/rust-lang/rust/pull/44026
2321 [#44027]: https://github.com/rust-lang/rust/pull/44027
2326 description: r##"# `abi_ptx`
2328 The tracking issue for this feature is: [#38788]
2330 [#38788]: https://github.com/rust-lang/rust/issues/38788
2332 ------------------------
2334 When emitting PTX code, all vanilla Rust functions (`fn`) get translated to
2335 "device" functions. These functions are *not* callable from the host via the
2336 CUDA API so a crate with only device functions is not too useful!
2338 OTOH, "global" functions *can* be called by the host; you can think of them
2339 as the real public API of your crate. To produce a global function use the
2342 <!-- NOTE(ignore) this example is specific to the nvptx targets -->
2345 #![feature(abi_ptx)]
2348 pub unsafe extern "ptx-kernel" fn global_function() {
2352 pub fn device_function() {
2358 $ xargo rustc --target nvptx64-nvidia-cuda --release -- --emit=asm
2360 $ cat $(find -name '*.s')
2362 // Generated by LLVM NVPTX Back-End
2369 // .globl _ZN6kernel15global_function17h46111ebe6516b382E
2371 .visible .entry _ZN6kernel15global_function17h46111ebe6516b382E()
2378 // .globl _ZN6kernel15device_function17hd6a0e4993bbf3f78E
2379 .visible .func _ZN6kernel15device_function17hd6a0e4993bbf3f78E()
2389 label: "profiler_runtime",
2390 description: r##"# `profiler_runtime`
2392 The tracking issue for this feature is: [#42524](https://github.com/rust-lang/rust/issues/42524).
2394 ------------------------
2398 label: "crate_visibility_modifier",
2399 description: r##"# `crate_visibility_modifier`
2401 The tracking issue for this feature is: [#53120]
2403 [#53120]: https://github.com/rust-lang/rust/issues/53120
2407 The `crate_visibility_modifier` feature allows the `crate` keyword to be used
2408 as 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
2413 #![feature(crate_visibility_modifier)]
2423 description: r##"# `doc_cfg`
2425 The tracking issue for this feature is: [#43781]
2429 The `doc_cfg` feature allows an API be documented as only available in some specific platforms.
2430 This attribute has two effects:
2432 1. In the annotated item's documentation, there will be a message saying "This is supported on
2435 2. The item's doc-tests will only run on the specific platform.
2437 In addition to allowing the use of the `#[doc(cfg)]` attribute, this feature enables the use of a
2438 special conditional compilation flag, `#[cfg(doc)]`, set whenever building documentation on your
2441 This feature was introduced as part of PR [#43348] to allow the platform-specific parts of the
2442 standard library be documented.
2445 #![feature(doc_cfg)]
2447 #[cfg(any(windows, doc))]
2448 #[doc(cfg(windows))]
2449 /// The application's icon in the notification area (a.k.a. system tray).
2454 /// extern crate my_awesome_ui_library;
2455 /// use my_awesome_ui_library::current_app;
2456 /// use my_awesome_ui_library::windows::notification;
2458 /// let icon = current_app().get::<notification::Icon>();
2460 /// icon.show_message("Hello");
2467 [#43781]: https://github.com/rust-lang/rust/issues/43781
2468 [#43348]: https://github.com/rust-lang/rust/issues/43348
2472 label: "unsized_tuple_coercion",
2473 description: r##"# `unsized_tuple_coercion`
2475 The tracking issue for this feature is: [#42877]
2477 [#42877]: https://github.com/rust-lang/rust/issues/42877
2479 ------------------------
2481 This is a part of [RFC0401]. According to the RFC, there should be an implementation like this:
2483 ```rust,ignore (partial-example)
2484 impl<..., T, U: ?Sized> Unsized<(..., U)> for (..., T) where T: Unsized<U> {}
2487 This implementation is currently gated behind `#[feature(unsized_tuple_coercion)]` to avoid insta-stability. Therefore you can use it like this:
2490 #![feature(unsized_tuple_coercion)]
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);
2499 [RFC0401]: https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md
2503 label: "no_sanitize",
2504 description: r##"# `no_sanitize`
2506 The tracking issue for this feature is: [#39699]
2508 [#39699]: https://github.com/rust-lang/rust/issues/39699
2510 ------------------------
2512 The `no_sanitize` attribute can be used to selectively disable sanitizer
2513 instrumentation in an annotated function. This might be useful to: avoid
2514 instrumentation overhead in a performance critical function, or avoid
2515 instrumenting code that contains constructs unsupported by given sanitizer.
2517 The precise effect of this annotation depends on particular sanitizer in use.
2518 For example, with `no_sanitize(thread)`, the thread sanitizer will no longer
2519 instrument non-atomic store / load operations, but it will instrument atomic
2520 operations to avoid reporting false positives and provide meaning full stack
2526 #![feature(no_sanitize)]
2528 #[no_sanitize(address)]
2536 label: "try_blocks",
2537 description: r##"# `try_blocks`
2539 The tracking issue for this feature is: [#31436]
2541 [#31436]: https://github.com/rust-lang/rust/issues/31436
2543 ------------------------
2545 The `try_blocks` feature adds support for `try` blocks. A `try`
2546 block creates a new scope one can use the `?` operator in.
2549 #![feature(try_blocks)]
2551 use std::num::ParseIntError;
2553 let result: Result<i32, ParseIntError> = try {
2555 + "2".parse::<i32>()?
2556 + "3".parse::<i32>()?
2558 assert_eq!(result, Ok(6));
2560 let result: Result<i32, ParseIntError> = try {
2562 + "foo".parse::<i32>()?
2563 + "3".parse::<i32>()?
2565 assert!(result.is_err());
2570 label: "transparent_unions",
2571 description: r##"# `transparent_unions`
2573 The tracking issue for this feature is [#60405]
2575 [#60405]: https://github.com/rust-lang/rust/issues/60405
2579 The `transparent_unions` feature allows you mark `union`s as
2580 `#[repr(transparent)]`. A `union` may be `#[repr(transparent)]` in exactly the
2581 same conditions in which a `struct` may be `#[repr(transparent)]` (generally,
2582 this means the `union` must have exactly one non-zero-sized field). Some
2583 concrete illustrations follow.
2586 #![feature(transparent_unions)]
2588 // This union has the same representation as `f32`.
2589 #[repr(transparent)]
2590 union SingleFieldUnion {
2594 // This union has the same representation as `usize`.
2595 #[repr(transparent)]
2596 union MultiFieldUnion {
2602 For consistency with transparent `struct`s, `union`s must have exactly one
2603 non-zero-sized field. If all fields are zero-sized, the `union` must not be
2604 `#[repr(transparent)]`:
2607 #![feature(transparent_unions)]
2609 // This (non-transparent) union is already valid in stable Rust:
2610 pub union GoodUnion {
2614 // Error: transparent union needs exactly one non-zero-sized field, but has 0
2615 // #[repr(transparent)]
2616 // pub union BadUnion {
2621 The 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:
2625 #![feature(transparent_unions)]
2627 // This union has the same representation as `T`.
2628 #[repr(transparent)]
2629 pub union GenericUnion<T: Copy> { // Unions with non-`Copy` fields are unstable.
2634 // This is okay even though `()` is a zero-sized type.
2635 pub const THIS_IS_OKAY: GenericUnion<()> = GenericUnion { field: () };
2638 Like transarent `struct`s, a transparent `union` of type `U` has the same
2639 layout, 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
2641 it has the same layout and ABI as `T` (even if `T` is a ZST when monomorphized).
2643 Like transparent `struct`s, transparent `union`s are FFI-safe if and only if
2644 their underlying representation type is also FFI-safe.
2646 A `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
2649 example, 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
2651 it is transparent). The Rust compiler is free to perform this optimization if
2652 possible, but is not required to, and different compiler versions may differ in
2653 their application of these optimizations.
2657 label: "const_eval_limit",
2658 description: r##"# `const_eval_limit`
2660 The tracking issue for this feature is: [#67217]
2662 [#67217]: https://github.com/rust-lang/rust/issues/67217
2664 The `const_eval_limit` allows someone to limit the evaluation steps the CTFE undertakes to evaluate a `const fn`.
2669 description: r##"# `link_args`
2671 The tracking issue for this feature is: [#29596]
2673 [#29596]: https://github.com/rust-lang/rust/issues/29596
2675 ------------------------
2677 You can tell `rustc` how to customize linking, and that is via the `link_args`
2678 attribute. This attribute is applied to `extern` blocks and specifies raw flags
2679 which need to get passed to the linker when producing an artifact. An example
2683 #![feature(link_args)]
2685 #[link_args = "-foo -bar -baz"]
2690 Note that this feature is currently hidden behind the `feature(link_args)` gate
2691 because this is not a sanctioned way of performing linking. Right now `rustc`
2692 shells out to the system linker (`gcc` on most systems, `link.exe` on MSVC), so
2693 it makes sense to provide extra command line arguments, but this will not
2694 always be the case. In the future `rustc` may use LLVM directly to link native
2695 libraries, in which case `link_args` will have no meaning. You can achieve the
2696 same effect as the `link_args` attribute with the `-C link-args` argument to
2699 It is highly recommended to *not* use this attribute, and rather use the more
2700 formal `#[link(...)]` attribute on `extern` blocks instead.
2704 label: "internal_output_capture",
2705 description: r##"# `internal_output_capture`
2707 This feature is internal to the Rust compiler and is not intended for general use.
2709 ------------------------
2713 label: "windows_handle",
2714 description: r##"# `windows_handle`
2716 This feature is internal to the Rust compiler and is not intended for general use.
2718 ------------------------
2723 description: r##"# `asm`
2725 The tracking issue for this feature is: [#72016]
2727 [#72016]: https://github.com/rust-lang/rust/issues/72016
2729 ------------------------
2731 For extremely low-level manipulations and performance reasons, one
2732 might wish to control the CPU directly. Rust supports using inline
2733 assembly to do this via the `asm!` macro.
2735 # Guide-level explanation
2736 [guide-level-explanation]: #guide-level-explanation
2738 Rust provides support for inline assembly via the `asm!` macro.
2739 It can be used to embed handwritten assembly in the assembly output generated by the compiler.
2740 Generally this should not be necessary, but might be where the required performance or timing
2741 cannot be otherwise achieved. Accessing low level hardware primitives, e.g. in kernel code, may also demand this functionality.
2743 > **Note**: the examples here are given in x86/x86-64 assembly, but other architectures are also supported.
2745 Inline assembly is currently supported on the following architectures:
2752 - MIPS32r2 and MIPS64r2
2757 Let us start with the simplest possible example:
2766 This will insert a NOP (no operation) instruction into the assembly generated by the compiler.
2767 Note that all `asm!` invocations have to be inside an `unsafe` block, as they could insert
2768 arbitrary instructions and break various invariants. The instructions to be inserted are listed
2769 in the first argument of the `asm!` macro as a string literal.
2771 ## Inputs and outputs
2773 Now inserting an instruction that does nothing is rather boring. Let us do something that
2774 actually acts on data:
2780 asm!("mov {}, 5", out(reg) x);
2785 This will write the value `5` into the `u64` variable `x`.
2786 You can see that the string literal we use to specify instructions is actually a template string.
2787 It is governed by the same rules as Rust [format strings][format-syntax].
2788 The arguments that are inserted into the template however look a bit different then you may
2789 be familiar with. First we need to specify if the variable is an input or an output of the
2790 inline assembly. In this case it is an output. We declared this by writing `out`.
2791 We also need to specify in what kind of register the assembly expects the variable.
2792 In this case we put it in an arbitrary general purpose register by specifying `reg`.
2793 The compiler will choose an appropriate register to insert into
2794 the template and will read the variable from there after the inline assembly finishes executing.
2796 Let us see another example that also uses an input:
2805 "add {0}, {number}",
2814 This will add `5` to the input in variable `i` and write the result to variable `o`.
2815 The particular way this assembly does this is first copying the value from `i` to the output,
2816 and then adding `5` to it.
2818 The example shows a few things:
2820 First, we can see that `asm!` allows multiple template string arguments; each
2821 one is treated as a separate line of assembly code, as if they were all joined
2822 together with newlines between them. This makes it easy to format assembly
2825 Second, we can see that inputs are declared by writing `in` instead of `out`.
2827 Third, one of our operands has a type we haven't seen yet, `const`.
2828 This tells the compiler to expand this argument to value directly inside the assembly template.
2829 This is only possible for constants and literals.
2831 Fourth, we can see that we can specify an argument number, or name as in any format string.
2832 For inline assembly templates this is particularly useful as arguments are often used more than once.
2833 For more complex inline assembly using this facility is generally recommended, as it improves
2834 readability, and allows reordering instructions without changing the argument order.
2836 We can further refine the above example to avoid the `mov` instruction:
2842 asm!("add {0}, {number}", inout(reg) x, number = const 5);
2847 We can see that `inout` is used to specify an argument that is both input and output.
2848 This is different from specifying an input and output separately in that it is guaranteed to assign both to the same register.
2850 It is also possible to specify different variables for the input and output parts of an `inout` operand:
2857 asm!("add {0}, {number}", inout(reg) x => y, number = const 5);
2862 ## Late output operands
2864 The Rust compiler is conservative with its allocation of operands. It is assumed that an `out`
2865 can be written at any time, and can therefore not share its location with any other argument.
2866 However, to guarantee optimal performance it is important to use as few registers as possible,
2867 so they won't have to be saved and reloaded around the inline assembly block.
2868 To achieve this Rust provides a `lateout` specifier. This can be used on any output that is
2869 written only after all inputs have been consumed.
2870 There is also a `inlateout` variant of this specifier.
2872 Here is an example where `inlateout` *cannot* be used:
2891 Here the compiler is free to allocate the same register for inputs `b` and `c` since it knows they have the same value. However it must allocate a separate register for `a` since it uses `inout` and not `inlateout`. If `inlateout` was used, then `a` and `c` could be allocated to the same register, in which case the first instruction to overwrite the value of `c` and cause the assembly code to produce the wrong result.
2893 However the following example can use `inlateout` since the output is only modified after all input registers have been read:
2900 asm!("add {0}, {1}", inlateout(reg) a, in(reg) b);
2905 As you can see, this assembly fragment will still work correctly if `a` and `b` are assigned to the same register.
2907 ## Explicit register operands
2909 Some instructions require that the operands be in a specific register.
2910 Therefore, Rust inline assembly provides some more specific constraint specifiers.
2911 While `reg` is generally available on any architecture, these are highly architecture specific. E.g. for x86 the general purpose registers `eax`, `ebx`, `ecx`, `edx`, `ebp`, `esi`, and `edi`
2912 among others can be addressed by their name.
2914 ```rust,allow_fail,no_run
2918 asm!("out 0x64, eax", in("eax") cmd);
2922 In this example we call the `out` instruction to output the content of the `cmd` variable
2923 to port `0x64`. Since the `out` instruction only accepts `eax` (and its sub registers) as operand
2924 we had to use the `eax` constraint specifier.
2926 Note that unlike other operand types, explicit register operands cannot be used in the template string: you can't use `{}` and should write the register name directly instead. Also, they must appear at the end of the operand list after all other operand types.
2928 Consider this example which uses the x86 `mul` instruction:
2932 fn mul(a: u64, b: u64) -> u128 {
2938 // The x86 mul instruction takes rax as an implicit input and writes
2939 // the 128-bit result of the multiplication to rax:rdx.
2942 inlateout("rax") b => lo,
2947 ((hi as u128) << 64) + lo as u128
2951 This uses the `mul` instruction to multiply two 64-bit inputs with a 128-bit result.
2952 The only explicit operand is a register, that we fill from the variable `a`.
2953 The second operand is implicit, and must be the `rax` register, which we fill from the variable `b`.
2954 The lower 64 bits of the result are stored in `rax` from which we fill the variable `lo`.
2955 The higher 64 bits are stored in `rdx` from which we fill the variable `hi`.
2957 ## Clobbered registers
2959 In many cases inline assembly will modify state that is not needed as an output.
2960 Usually this is either because we have to use a scratch register in the assembly,
2961 or instructions modify state that we don't need to further examine.
2962 This state is generally referred to as being "clobbered".
2963 We need to tell the compiler about this since it may need to save and restore this state
2964 around the inline assembly block.
2974 // EAX 4 selects the "Deterministic Cache Parameters" CPUID leaf
2975 inout("eax") 4 => _,
2976 // ECX 0 selects the L0 cache information.
2977 inout("ecx") 0 => ecx,
2985 ((ebx >> 22) + 1) * (((ebx >> 12) & 0x3ff) + 1) * ((ebx & 0xfff) + 1) * (ecx + 1)
2989 In the example above we use the `cpuid` instruction to get the L1 cache size.
2990 This instruction writes to `eax`, `ebx`, `ecx`, and `edx`, but for the cache size we only care about the contents of `ebx` and `ecx`.
2992 However we still need to tell the compiler that `eax` and `edx` have been modified so that it can save any values that were in these registers before the asm. This is done by declaring these as outputs but with `_` instead of a variable name, which indicates that the output value is to be discarded.
2994 This can also be used with a general register class (e.g. `reg`) to obtain a scratch register for use inside the asm code:
2998 // Multiply x by 6 using shifts and adds
3010 assert_eq!(x, 4 * 6);
3015 A special operand type, `sym`, allows you to use the symbol name of a `fn` or `static` in inline assembly code.
3016 This allows you to call a function or access a global variable without needing to keep its address in a register.
3020 extern "C" fn foo(arg: i32) {
3021 println!("arg = {}", arg);
3024 fn call_foo(arg: i32) {
3029 // 1st argument in rdi, which is caller-saved
3030 inout("rdi") arg => _,
3031 // All caller-saved registers must be marked as clobberred
3032 out("rax") _, out("rcx") _, out("rdx") _, out("rsi") _,
3033 out("r8") _, out("r9") _, out("r10") _, out("r11") _,
3034 out("xmm0") _, out("xmm1") _, out("xmm2") _, out("xmm3") _,
3035 out("xmm4") _, out("xmm5") _, out("xmm6") _, out("xmm7") _,
3036 out("xmm8") _, out("xmm9") _, out("xmm10") _, out("xmm11") _,
3037 out("xmm12") _, out("xmm13") _, out("xmm14") _, out("xmm15") _,
3043 Note that the `fn` or `static` item does not need to be public or `#[no_mangle]`:
3044 the compiler will automatically insert the appropriate mangled symbol name into the assembly code.
3046 ## Register template modifiers
3048 In some cases, fine control is needed over the way a register name is formatted when inserted into the template string. This is needed when an architecture's assembly language has several names for the same register, each typically being a "view" over a subset of the register (e.g. the low 32 bits of a 64-bit register).
3050 By default the compiler will always choose the name that refers to the full register size (e.g. `rax` on x86-64, `eax` on x86, etc).
3052 This default can be overriden by using modifiers on the template string operands, just like you would with format strings:
3056 let mut x: u16 = 0xab;
3059 asm!("mov {0:h}, {0:l}", inout(reg_abcd) x);
3062 assert_eq!(x, 0xabab);
3065 In this example, we use the `reg_abcd` register class to restrict the register allocator to the 4 legacy x86 register (`ax`, `bx`, `cx`, `dx`) of which the first two bytes can be addressed independently.
3067 Let us assume that the register allocator has chosen to allocate `x` in the `ax` register.
3068 The `h` modifier will emit the register name for the high byte of that register and the `l` modifier will emit the register name for the low byte. The asm code will therefore be expanded as `mov ah, al` which copies the low byte of the value into the high byte.
3070 If you use a smaller data type (e.g. `u16`) with an operand and forget the use template modifiers, the compiler will emit a warning and suggest the correct modifier to use.
3072 ## Memory address operands
3074 Sometimes assembly instructions require operands passed via memory addresses/memory locations.
3075 You have to manually use the memory address syntax specified by the respectively architectures.
3076 For example, in x86/x86_64 and intel assembly syntax, you should wrap inputs/outputs in `[]`
3077 to indicate they are memory operands:
3080 # #![feature(asm, llvm_asm)]
3081 # fn load_fpu_control_word(control: u16) {
3083 asm!("fldcw [{}]", in(reg) &control, options(nostack));
3085 // Previously this would have been written with the deprecated `llvm_asm!` like this
3086 llvm_asm!("fldcw $0" :: "m" (control) :: "volatile");
3093 By 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 Let's take our previous example of an `add` instruction:
3104 inlateout(reg) a, in(reg) b,
3105 options(pure, nomem, nostack),
3111 Options can be provided as an optional final argument to the `asm!` macro. We specified three options here:
3112 - `pure` means that the asm code has no observable side effects and that its output depends only on its inputs. This allows the compiler optimizer to call the inline asm fewer times or even eliminate it entirely.
3113 - `nomem` means that the asm code does not read or write to memory. By default the compiler will assume that inline assembly can read or write any memory address that is accessible to it (e.g. through a pointer passed as an operand, or a global).
3114 - `nostack` means that the asm code does not push any data onto the stack. This allows the compiler to use optimizations such as the stack red zone on x86-64 to avoid stack pointer adjustments.
3116 These allow the compiler to better optimize code using `asm!`, for example by eliminating pure `asm!` blocks whose outputs are not needed.
3118 See the reference for the full list of available options and their effects.
3120 # Reference-level explanation
3121 [reference-level-explanation]: #reference-level-explanation
3123 Inline assembler is implemented as an unsafe macro `asm!()`.
3124 The first argument to this macro is a template string literal used to build the final assembly.
3125 The following arguments specify input and output operands.
3126 When required, options are specified as the final argument.
3128 The following ABNF specifies the general syntax:
3131 dir_spec := "in" / "out" / "lateout" / "inout" / "inlateout"
3132 reg_spec := <register class> / "<explicit register>"
3133 operand_expr := expr / "_" / expr "=>" expr / expr "=>" "_"
3134 reg_operand := dir_spec "(" reg_spec ")" operand_expr
3135 operand := reg_operand / "const" const_expr / "sym" path
3136 option := "pure" / "nomem" / "readonly" / "preserves_flags" / "noreturn" / "nostack" / "att_syntax"
3137 options := "options(" option *["," option] [","] ")"
3138 asm := "asm!(" format_string *("," format_string) *("," [ident "="] operand) ["," options] [","] ")"
3141 The 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.
3143 [format-syntax]: https://doc.rust-lang.org/std/fmt/#syntax
3145 ## Template string arguments
3147 The assembler template uses the same syntax as [format strings][format-syntax] (i.e. placeholders are specified by curly braces). The corresponding arguments are accessed in order, by index, or by name. However, implicit named arguments (introduced by [RFC #2795][rfc-2795]) are not supported.
3149 An `asm!` invocation may have one or more template string arguments; an `asm!` with multiple template string arguments is treated as if all the strings were concatenated with a `\n` between them. The expected usage is for each template string argument to correspond to a line of assembly code. All template string arguments must appear before any other arguments.
3151 As with format strings, named arguments must appear after positional arguments. Explicit register operands must appear at the end of the operand list, after named arguments if any.
3153 Explicit register operands cannot be used by placeholders in the template string. All other named and positional operands must appear at least once in the template string, otherwise a compiler error is generated.
3155 The exact assembly code syntax is target-specific and opaque to the compiler except for the way operands are substituted into the template string to form the code passed to the assembler.
3157 The 5 targets specified in this RFC (x86, ARM, AArch64, RISC-V, Hexagon) all use the assembly code syntax of the GNU assembler (GAS). On x86, the `.intel_syntax noprefix` mode of GAS is used by default. On ARM, the `.syntax unified` mode is used. These targets impose an additional restriction on the assembly code: any assembler state (e.g. the current section which can be changed with `.section`) must be restored to its original value at the end of the asm string. Assembly code that does not conform to the GAS syntax will result in assembler-specific behavior.
3159 [rfc-2795]: https://github.com/rust-lang/rfcs/pull/2795
3163 Several types of operands are supported:
3165 * `in(<reg>) <expr>`
3166 - `<reg>` can refer to a register class or an explicit register. The allocated register name is substituted into the asm template string.
3167 - The allocated register will contain the value of `<expr>` at the start of the asm code.
3168 - The allocated register must contain the same value at the end of the asm code (except if a `lateout` is allocated to the same register).
3169 * `out(<reg>) <expr>`
3170 - `<reg>` can refer to a register class or an explicit register. The allocated register name is substituted into the asm template string.
3171 - The allocated register will contain an undefined value at the start of the asm code.
3172 - `<expr>` must be a (possibly uninitialized) place expression, to which the contents of the allocated register is written to at the end of the asm code.
3173 - An underscore (`_`) may be specified instead of an expression, which will cause the contents of the register to be discarded at the end of the asm code (effectively acting as a clobber).
3174 * `lateout(<reg>) <expr>`
3175 - Identical to `out` except that the register allocator can reuse a register allocated to an `in`.
3176 - You should only write to the register after all inputs are read, otherwise you may clobber an input.
3177 * `inout(<reg>) <expr>`
3178 - `<reg>` can refer to a register class or an explicit register. The allocated register name is substituted into the asm template string.
3179 - The allocated register will contain the value of `<expr>` at the start of the asm code.
3180 - `<expr>` must be a mutable initialized place expression, to which the contents of the allocated register is written to at the end of the asm code.
3181 * `inout(<reg>) <in expr> => <out expr>`
3182 - Same as `inout` except that the initial value of the register is taken from the value of `<in expr>`.
3183 - `<out expr>` must be a (possibly uninitialized) place expression, to which the contents of the allocated register is written to at the end of the asm code.
3184 - An underscore (`_`) may be specified instead of an expression for `<out expr>`, which will cause the contents of the register to be discarded at the end of the asm code (effectively acting as a clobber).
3185 - `<in expr>` and `<out expr>` may have different types.
3186 * `inlateout(<reg>) <expr>` / `inlateout(<reg>) <in expr> => <out expr>`
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`).
3188 - You should only write to the register after all inputs are read, otherwise you may clobber an input.
3190 - `<expr>` must be an integer or floating-point constant expression.
3191 - The value of the expression is formatted as a string and substituted directly into the asm template string.
3193 - `<path>` must refer to a `fn` or `static`.
3194 - A mangled symbol name referring to the item is substituted into the asm template string.
3195 - The substituted string does not include any modifiers (e.g. GOT, PLT, relocations, etc).
3196 - `<path>` is allowed to point to a `#[thread_local]` static, in which case the asm code can combine the symbol with relocations (e.g. `@plt`, `@TPOFF`) to read from thread-local data.
3198 Operand expressions are evaluated from left to right, just like function call arguments. After the `asm!` has executed, outputs are written to in left to right order. This is significant if two outputs point to the same place: that place will contain the value of the rightmost output.
3200 ## Register operands
3202 Input and output operands can be specified either as an explicit register or as a register class from which the register allocator can select a register. Explicit registers are specified as string literals (e.g. `"eax"`) while register classes are specified as identifiers (e.g. `reg`). Using string literals for register names enables support for architectures that use special characters in register names, such as MIPS (`$0`, `$1`, etc).
3204 Note that explicit registers treat register aliases (e.g. `r14` vs `lr` on ARM) and smaller views of a register (e.g. `eax` vs `rax`) as equivalent to the base register. It is a compile-time error to use the same explicit register for two input operands or two output operands. Additionally, it is also a compile-time error to use overlapping registers (e.g. ARM VFP) in input operands or in output operands.
3206 Only the following types are allowed as operands for inline assembly:
3207 - Integers (signed and unsigned)
3208 - Floating-point numbers
3209 - Pointers (thin only)
3211 - SIMD vectors (structs defined with `#[repr(simd)]` and which implement `Copy`). This includes architecture-specific vector types defined in `std::arch` such as `__m128` (x86) or `int8x16_t` (ARM).
3213 Here is the list of currently supported register classes:
3215 | Architecture | Register class | Registers | LLVM constraint code |
3216 | ------------ | -------------- | --------- | -------------------- |
3217 | x86 | `reg` | `ax`, `bx`, `cx`, `dx`, `si`, `di`, `r[8-15]` (x86-64 only) | `r` |
3218 | x86 | `reg_abcd` | `ax`, `bx`, `cx`, `dx` | `Q` |
3219 | 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` |
3221 | 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` |
3223 | x86 | `zmm_reg` | `zmm[0-7]` (x86) `zmm[0-31]` (x86-64) | `v` |
3224 | x86 | `kreg` | `k[1-7]` | `Yk` |
3225 | AArch64 | `reg` | `x[0-28]`, `x30` | `r` |
3226 | AArch64 | `vreg` | `v[0-31]` | `w` |
3227 | AArch64 | `vreg_low16` | `v[0-15]` | `x` |
3228 | ARM | `reg` | `r[0-5]` `r7`\*, `r[8-10]`, `r11`\*, `r12`, `r14` | `r` |
3229 | ARM (Thumb) | `reg_thumb` | `r[0-r7]` | `l` |
3230 | ARM (ARM) | `reg_thumb` | `r[0-r10]`, `r12`, `r14` | `l` |
3231 | ARM | `sreg` | `s[0-31]` | `t` |
3232 | ARM | `sreg_low16` | `s[0-15]` | `x` |
3233 | ARM | `dreg` | `d[0-31]` | `w` |
3234 | ARM | `dreg_low16` | `d[0-15]` | `t` |
3235 | ARM | `dreg_low8` | `d[0-8]` | `x` |
3236 | ARM | `qreg` | `q[0-15]` | `w` |
3237 | ARM | `qreg_low8` | `q[0-7]` | `t` |
3238 | ARM | `qreg_low4` | `q[0-3]` | `x` |
3239 | MIPS | `reg` | `$[2-25]` | `r` |
3240 | MIPS | `freg` | `$f[0-31]` | `f` |
3241 | NVPTX | `reg16` | None\* | `h` |
3242 | NVPTX | `reg32` | None\* | `r` |
3243 | NVPTX | `reg64` | None\* | `l` |
3244 | RISC-V | `reg` | `x1`, `x[5-7]`, `x[9-15]`, `x[16-31]` (non-RV32E) | `r` |
3245 | RISC-V | `freg` | `f[0-31]` | `f` |
3246 | Hexagon | `reg` | `r[0-28]` | `r` |
3247 | wasm32 | `local` | None\* | `r` |
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.
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.
3253 > Note #3: NVPTX doesn't have a fixed register set, so named registers are not supported.
3255 > Note #4: On ARM the frame pointer is either `r7` or `r11` depending on the platform.
3257 > Note #5: WebAssembly doesn't have registers, so named registers are not supported.
3259 Additional register classes may be added in the future based on demand (e.g. MMX, x87, etc).
3261 Each register class has constraints on which value types they can be used with. This is necessary because the way a value is loaded into a register depends on its type. For example, on big-endian systems, loading a `i32x4` and a `i8x16` into a SIMD register may result in different register contents even if the byte-wise memory representation of both values is identical. The availability of supported types for a particular register class may depend on what target features are currently enabled.
3263 | Architecture | Register class | Target feature | Allowed types |
3264 | ------------ | -------------- | -------------- | ------------- |
3265 | x86-32 | `reg` | None | `i16`, `i32`, `f32` |
3266 | x86-64 | `reg` | None | `i16`, `i32`, `f32`, `i64`, `f64` |
3267 | x86 | `reg_byte` | None | `i8` |
3268 | x86 | `xmm_reg` | `sse` | `i32`, `f32`, `i64`, `f64`, <br> `i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` |
3269 | x86 | `ymm_reg` | `avx` | `i32`, `f32`, `i64`, `f64`, <br> `i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` <br> `i8x32`, `i16x16`, `i32x8`, `i64x4`, `f32x8`, `f64x4` |
3270 | x86 | `zmm_reg` | `avx512f` | `i32`, `f32`, `i64`, `f64`, <br> `i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` <br> `i8x32`, `i16x16`, `i32x8`, `i64x4`, `f32x8`, `f64x4` <br> `i8x64`, `i16x32`, `i32x16`, `i64x8`, `f32x16`, `f64x8` |
3271 | x86 | `kreg` | `axv512f` | `i8`, `i16` |
3272 | x86 | `kreg` | `axv512bw` | `i32`, `i64` |
3273 | AArch64 | `reg` | None | `i8`, `i16`, `i32`, `f32`, `i64`, `f64` |
3274 | AArch64 | `vreg` | `fp` | `i8`, `i16`, `i32`, `f32`, `i64`, `f64`, <br> `i8x8`, `i16x4`, `i32x2`, `i64x1`, `f32x2`, `f64x1`, <br> `i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` |
3275 | ARM | `reg` | None | `i8`, `i16`, `i32`, `f32` |
3276 | ARM | `sreg` | `vfp2` | `i32`, `f32` |
3277 | ARM | `dreg` | `vfp2` | `i64`, `f64`, `i8x8`, `i16x4`, `i32x2`, `i64x1`, `f32x2` |
3278 | ARM | `qreg` | `neon` | `i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4` |
3279 | MIPS32 | `reg` | None | `i8`, `i16`, `i32`, `f32` |
3280 | MIPS32 | `freg` | None | `f32`, `f64` |
3281 | MIPS64 | `reg` | None | `i8`, `i16`, `i32`, `i64`, `f32`, `f64` |
3282 | MIPS64 | `freg` | None | `f32`, `f64` |
3283 | NVPTX | `reg16` | None | `i8`, `i16` |
3284 | NVPTX | `reg32` | None | `i8`, `i16`, `i32`, `f32` |
3285 | NVPTX | `reg64` | None | `i8`, `i16`, `i32`, `f32`, `i64`, `f64` |
3286 | RISC-V32 | `reg` | None | `i8`, `i16`, `i32`, `f32` |
3287 | RISC-V64 | `reg` | None | `i8`, `i16`, `i32`, `f32`, `i64`, `f64` |
3288 | RISC-V | `freg` | `f` | `f32` |
3289 | RISC-V | `freg` | `d` | `f64` |
3290 | Hexagon | `reg` | None | `i8`, `i16`, `i32`, `f32` |
3291 | wasm32 | `local` | None | `i8` `i16` `i32` `i64` `f32` `f64` |
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).
3295 If a value is of a smaller size than the register it is allocated in then the upper bits of that register will have an undefined value for inputs and will be ignored for outputs. The only exception is the `freg` register class on RISC-V where `f32` values are NaN-boxed in a `f64` as required by the RISC-V architecture.
3297 When separate input and output expressions are specified for an `inout` operand, both expressions must have the same type. The only exception is if both operands are pointers or integers, in which case they are only required to have the same size. This restriction exists because the register allocators in LLVM and GCC sometimes cannot handle tied operands with different types.
3301 Some registers have multiple names. These are all treated by the compiler as identical to the base register name. Here is the list of all supported register aliases:
3303 | Architecture | Base register | Aliases |
3304 | ------------ | ------------- | ------- |
3305 | x86 | `ax` | `eax`, `rax` |
3306 | x86 | `bx` | `ebx`, `rbx` |
3307 | x86 | `cx` | `ecx`, `rcx` |
3308 | x86 | `dx` | `edx`, `rdx` |
3309 | x86 | `si` | `esi`, `rsi` |
3310 | x86 | `di` | `edi`, `rdi` |
3311 | x86 | `bp` | `bpl`, `ebp`, `rbp` |
3312 | x86 | `sp` | `spl`, `esp`, `rsp` |
3313 | x86 | `ip` | `eip`, `rip` |
3314 | x86 | `st(0)` | `st` |
3315 | x86 | `r[8-15]` | `r[8-15]b`, `r[8-15]w`, `r[8-15]d` |
3316 | x86 | `xmm[0-31]` | `ymm[0-31]`, `zmm[0-31]` |
3317 | AArch64 | `x[0-30]` | `w[0-30]` |
3318 | AArch64 | `x29` | `fp` |
3319 | AArch64 | `x30` | `lr` |
3320 | AArch64 | `sp` | `wsp` |
3321 | AArch64 | `xzr` | `wzr` |
3322 | AArch64 | `v[0-31]` | `b[0-31]`, `h[0-31]`, `s[0-31]`, `d[0-31]`, `q[0-31]` |
3323 | ARM | `r[0-3]` | `a[1-4]` |
3324 | ARM | `r[4-9]` | `v[1-6]` |
3325 | ARM | `r9` | `rfp` |
3326 | ARM | `r10` | `sl` |
3327 | ARM | `r11` | `fp` |
3328 | ARM | `r12` | `ip` |
3329 | ARM | `r13` | `sp` |
3330 | ARM | `r14` | `lr` |
3331 | ARM | `r15` | `pc` |
3332 | RISC-V | `x0` | `zero` |
3333 | RISC-V | `x1` | `ra` |
3334 | RISC-V | `x2` | `sp` |
3335 | RISC-V | `x3` | `gp` |
3336 | RISC-V | `x4` | `tp` |
3337 | RISC-V | `x[5-7]` | `t[0-2]` |
3338 | RISC-V | `x8` | `fp`, `s0` |
3339 | RISC-V | `x9` | `s1` |
3340 | RISC-V | `x[10-17]` | `a[0-7]` |
3341 | RISC-V | `x[18-27]` | `s[2-11]` |
3342 | RISC-V | `x[28-31]` | `t[3-6]` |
3343 | RISC-V | `f[0-7]` | `ft[0-7]` |
3344 | RISC-V | `f[8-9]` | `fs[0-1]` |
3345 | RISC-V | `f[10-17]` | `fa[0-7]` |
3346 | RISC-V | `f[18-27]` | `fs[2-11]` |
3347 | RISC-V | `f[28-31]` | `ft[8-11]` |
3348 | Hexagon | `r29` | `sp` |
3349 | Hexagon | `r30` | `fr` |
3350 | Hexagon | `r31` | `lr` |
3352 Some registers cannot be used for input or output operands:
3354 | Architecture | Unsupported register | Reason |
3355 | ------------ | -------------------- | ------ |
3356 | 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. |
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. |
3359 | ARM | `r6` | `r6` is used internally by LLVM as a base pointer and therefore cannot be used as an input or output. |
3360 | 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. |
3362 | 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). |
3364 | 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. |
3366 | MIPS | `$0` or `$zero` | This is a constant zero register which can't be modified. |
3367 | MIPS | `$1` or `$at` | Reserved for assembler. |
3368 | MIPS | `$26`/`$k0`, `$27`/`$k1` | OS-reserved registers. |
3369 | MIPS | `$28`/`$gp` | Global pointer cannot be used as inputs or outputs. |
3370 | MIPS | `$ra` | Return address cannot be used as inputs or outputs. |
3371 | RISC-V | `x0` | This is a constant zero register which can't be modified. |
3372 | 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. |
3375 In 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:
3376 - The frame pointer on all architectures.
3379 ## Template modifiers
3381 The placeholders can be augmented by modifiers which are specified after the `:` in the curly braces. These modifiers do not affect register allocation, but change the way operands are formatted when inserted into the template string. Only one modifier is allowed per template placeholder.
3383 The supported modifiers are a subset of LLVM's (and GCC's) [asm template argument modifiers][llvm-argmod], but do not use the same letter codes.
3385 | Architecture | Register class | Modifier | Example output | LLVM modifier |
3386 | ------------ | -------------- | -------- | -------------- | ------------- |
3387 | x86-32 | `reg` | None | `eax` | `k` |
3388 | x86-64 | `reg` | None | `rax` | `q` |
3389 | x86-32 | `reg_abcd` | `l` | `al` | `b` |
3390 | x86-64 | `reg` | `l` | `al` | `b` |
3391 | x86 | `reg_abcd` | `h` | `ah` | `h` |
3392 | x86 | `reg` | `x` | `ax` | `w` |
3393 | x86 | `reg` | `e` | `eax` | `k` |
3394 | x86-64 | `reg` | `r` | `rax` | `q` |
3395 | x86 | `reg_byte` | None | `al` / `ah` | None |
3396 | x86 | `xmm_reg` | None | `xmm0` | `x` |
3397 | x86 | `ymm_reg` | None | `ymm0` | `t` |
3398 | x86 | `zmm_reg` | None | `zmm0` | `g` |
3399 | x86 | `*mm_reg` | `x` | `xmm0` | `x` |
3400 | x86 | `*mm_reg` | `y` | `ymm0` | `t` |
3401 | x86 | `*mm_reg` | `z` | `zmm0` | `g` |
3402 | x86 | `kreg` | None | `k1` | None |
3403 | AArch64 | `reg` | None | `x0` | `x` |
3404 | AArch64 | `reg` | `w` | `w0` | `w` |
3405 | AArch64 | `reg` | `x` | `x0` | `x` |
3406 | AArch64 | `vreg` | None | `v0` | None |
3407 | AArch64 | `vreg` | `v` | `v0` | None |
3408 | AArch64 | `vreg` | `b` | `b0` | `b` |
3409 | AArch64 | `vreg` | `h` | `h0` | `h` |
3410 | AArch64 | `vreg` | `s` | `s0` | `s` |
3411 | AArch64 | `vreg` | `d` | `d0` | `d` |
3412 | AArch64 | `vreg` | `q` | `q0` | `q` |
3413 | ARM | `reg` | None | `r0` | None |
3414 | ARM | `sreg` | None | `s0` | None |
3415 | ARM | `dreg` | None | `d0` | `P` |
3416 | ARM | `qreg` | None | `q0` | `q` |
3417 | ARM | `qreg` | `e` / `f` | `d0` / `d1` | `e` / `f` |
3418 | MIPS | `reg` | None | `$2` | None |
3419 | MIPS | `freg` | None | `$f0` | None |
3420 | NVPTX | `reg16` | None | `rs0` | None |
3421 | NVPTX | `reg32` | None | `r0` | None |
3422 | NVPTX | `reg64` | None | `rd0` | None |
3423 | RISC-V | `reg` | None | `x1` | None |
3424 | RISC-V | `freg` | None | `f0` | None |
3425 | Hexagon | `reg` | None | `r0` | None |
3428 > - on ARM `e` / `f`: this prints the low or high doubleword register name of a NEON quad (128-bit) register.
3429 > - on x86: our behavior for `reg` with no modifiers differs from what GCC does. GCC will infer the modifier based on the operand value type, while we default to the full register size.
3430 > - on x86 `xmm_reg`: the `x`, `t` and `g` LLVM modifiers are not yet implemented in LLVM (they are supported by GCC only), but this should be a simple change.
3432 As stated in the previous section, passing an input value smaller than the register width will result in the upper bits of the register containing undefined values. This is not a problem if the inline asm only accesses the lower bits of the register, which can be done by using a template modifier to use a subregister name in the asm code (e.g. `ax` instead of `rax`). Since this an easy pitfall, the compiler will suggest a template modifier to use where appropriate given the input type. If all references to an operand already have modifiers then the warning is suppressed for that operand.
3434 [llvm-argmod]: http://llvm.org/docs/LangRef.html#asm-template-argument-modifiers
3438 Flags are used to further influence the behavior of the inline assembly block.
3439 Currently the following options are defined:
3440 - `pure`: The `asm` block has no side effects, and its outputs depend only on its direct inputs (i.e. the values themselves, not what they point to) or values read from memory (unless the `nomem` options is also set). This allows the compiler to execute the `asm` block fewer times than specified in the program (e.g. by hoisting it out of a loop) or even eliminate it entirely if the outputs are not used.
3441 - `nomem`: The `asm` blocks does not read or write to any memory. This allows the compiler to cache the values of modified global variables in registers across the `asm` block since it knows that they are not read or written to by the `asm`.
3442 - `readonly`: The `asm` block does not write to any memory. This allows the compiler to cache the values of unmodified global variables in registers across the `asm` block since it knows that they are not written to by the `asm`.
3443 - `preserves_flags`: The `asm` block does not modify the flags register (defined in the rules below). This allows the compiler to avoid recomputing the condition flags after the `asm` block.
3444 - `noreturn`: The `asm` block never returns, and its return type is defined as `!` (never). Behavior is undefined if execution falls through past the end of the asm code. A `noreturn` asm block behaves just like a function which doesn't return; notably, local variables in scope are not dropped before it is invoked.
3445 - `nostack`: The `asm` block does not push data to the stack, or write to the stack red-zone (if supported by the target). If this option is *not* used then the stack pointer is guaranteed to be suitably aligned (according to the target ABI) for a function call.
3446 - `att_syntax`: This option is only valid on x86, and causes the assembler to use the `.att_syntax prefix` mode of the GNU assembler. Register operands are substituted in with a leading `%`.
3448 The compiler performs some additional checks on options:
3449 - The `nomem` and `readonly` options are mutually exclusive: it is a compile-time error to specify both.
3450 - The `pure` option must be combined with either the `nomem` or `readonly` options, otherwise a compile-time error is emitted.
3451 - It is a compile-time error to specify `pure` on an asm block with no outputs or only discarded outputs (`_`).
3452 - It is a compile-time error to specify `noreturn` on an asm block with outputs.
3454 ## Rules for inline assembly
3456 - Any registers not specified as inputs will contain an undefined value on entry to the asm block.
3457 - An "undefined value" in the context of inline assembly means that the register can (non-deterministically) have any one of the possible values allowed by the architecture. Notably it is not the same as an LLVM `undef` which can have a different value every time you read it (since such a concept does not exist in assembly code).
3458 - Any registers not specified as outputs must have the same value upon exiting the asm block as they had on entry, otherwise behavior is undefined.
3459 - This only applies to registers which can be specified as an input or output. Other registers follow target-specific rules.
3460 - Note that a `lateout` may be allocated to the same register as an `in`, in which case this rule does not apply. Code should not rely on this however since it depends on the results of register allocation.
3461 - Behavior is undefined if execution unwinds out of an asm block.
3462 - This also applies if the assembly code calls a function which then unwinds.
3463 - The set of memory locations that assembly code is allowed the read and write are the same as those allowed for an FFI function.
3464 - Refer to the unsafe code guidelines for the exact rules.
3465 - If the `readonly` option is set, then only memory reads are allowed.
3466 - If the `nomem` option is set then no reads or writes to memory are allowed.
3467 - These rules do not apply to memory which is private to the asm code, such as stack space allocated within the asm block.
3468 - The compiler cannot assume that the instructions in the asm are the ones that will actually end up executed.
3469 - This effectively means that the compiler must treat the `asm!` as a black box and only take the interface specification into account, not the instructions themselves.
3470 - Runtime code patching is allowed, via target-specific mechanisms (outside the scope of this RFC).
3471 - Unless the `nostack` option is set, asm code is allowed to use stack space below the stack pointer.
3472 - On entry to the asm block the stack pointer is guaranteed to be suitably aligned (according to the target ABI) for a function call.
3473 - You are responsible for making sure you don't overflow the stack (e.g. use stack probing to ensure you hit a guard page).
3474 - You should adjust the stack pointer when allocating stack memory as required by the target ABI.
3475 - The stack pointer must be restored to its original value before leaving the asm block.
3476 - If the `noreturn` option is set then behavior is undefined if execution falls through to the end of the asm block.
3477 - If the `pure` option is set then behavior is undefined if the `asm` has side-effects other than its direct outputs. Behavior is also undefined if two executions of the `asm` code with the same inputs result in different outputs.
3478 - When used with the `nomem` option, "inputs" are just the direct inputs of the `asm!`.
3479 - When used with the `readonly` option, "inputs" comprise the direct inputs of the `asm!` and any memory that the `asm!` block is allowed to read.
3480 - These flags registers must be restored upon exiting the asm block if the `preserves_flags` option is set:
3482 - Status flags in `EFLAGS` (CF, PF, AF, ZF, SF, OF).
3483 - Floating-point status word (all).
3484 - Floating-point exception flags in `MXCSR` (PE, UE, OE, ZE, DE, IE).
3486 - Condition flags in `CPSR` (N, Z, C, V)
3487 - Saturation flag in `CPSR` (Q)
3488 - Greater than or equal flags in `CPSR` (GE).
3489 - Condition flags in `FPSCR` (N, Z, C, V)
3490 - Saturation flag in `FPSCR` (QC)
3491 - Floating-point exception flags in `FPSCR` (IDC, IXC, UFC, OFC, DZC, IOC).
3493 - Condition flags (`NZCV` register).
3494 - Floating-point status (`FPSR` register).
3496 - Floating-point exception flags in `fcsr` (`fflags`).
3497 - On x86, the direction flag (DF in `EFLAGS`) is clear on entry to an asm block and must be clear on exit.
3498 - Behavior is undefined if the direction flag is set on exiting an asm block.
3499 - The requirement of restoring the stack pointer and non-output registers to their original value only applies when exiting an `asm!` block.
3500 - This means that `asm!` blocks that never return (even if not marked `noreturn`) don't need to preserve these registers.
3501 - When returning to a different `asm!` block than you entered (e.g. for context switching), these registers must contain the value they had upon entering the `asm!` block that you are *exiting*.
3502 - You cannot exit an `asm!` block that has not been entered. Neither can you exit an `asm!` block that has already been exited.
3503 - 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.
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.
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.
3508 > **Note**: As a general rule, the flags covered by `preserves_flags` are those which are *not* preserved when performing a function call.
3510 [local labels]: https://sourceware.org/binutils/docs/as/Symbol-Names.html#Local-Labels
3515 description: r##"# `flt2dec`
3517 This feature is internal to the Rust compiler and is not intended for general use.
3519 ------------------------
3523 label: "global_asm",
3524 description: r##"# `global_asm`
3526 The tracking issue for this feature is: [#35119]
3528 [#35119]: https://github.com/rust-lang/rust/issues/35119
3530 ------------------------
3532 The `global_asm!` macro allows the programmer to write arbitrary
3533 assembly outside the scope of a function body, passing it through
3534 `rustc` and `llvm` to the assembler. The macro is a no-frills
3535 interface to LLVM's concept of [module-level inline assembly]. That is,
3536 all caveats applicable to LLVM's module-level inline assembly apply
3539 [module-level inline assembly]: http://llvm.org/docs/LangRef.html#module-level-inline-assembly
3541 `global_asm!` fills a role not currently satisfied by either `asm!`
3542 or `#[naked]` functions. The programmer has _all_ features of the
3543 assembler at their disposal. The linker will expect to resolve any
3544 symbols defined in the inline assembly, modulo any symbols marked as
3545 external. It also means syntax for directives and assembly follow the
3546 conventions of the assembler in your toolchain.
3548 A simple usage looks like this:
3550 ```rust,ignore (requires-external-file)
3551 #![feature(global_asm)]
3552 # // you also need relevant target_arch cfgs
3553 global_asm!(include_str!("something_neato.s"));
3556 And a more complicated usage looks like this:
3559 #![feature(global_asm)]
3560 # #[cfg(any(target_arch="x86", target_arch="x86_64"))]
3571 pub unsafe extern "C" fn baz() {}
3574 // the symbols `foo` and `bar` are global, no matter where
3575 // `global_asm!` was used.
3589 pub unsafe extern "C" fn quux() {}
3594 You may use `global_asm!` multiple times, anywhere in your crate, in
3595 whatever way suits you. The effect is as if you concatenated all
3596 usages and placed the larger, single usage in the crate root.
3598 ------------------------
3600 If you don't need quite as much power and flexibility as
3601 `global_asm!` provides, and you don't mind restricting your inline
3602 assembly to `fn` bodies only, you might try the
3603 [asm](asm.md) feature instead.
3608 description: r##"# `derive_eq`
3610 This feature is internal to the Rust compiler and is not intended for general use.
3612 ------------------------
3616 label: "default_free_fn",
3617 description: r##"# `default_free_fn`
3619 The tracking issue for this feature is: [#73014]
3621 [#73014]: https://github.com/rust-lang/rust/issues/73014
3623 ------------------------
3625 Adds a free `default()` function to the `std::default` module. This function
3626 just forwards to [`Default::default()`], but may remove repetition of the word
3627 "default" from the call site.
3629 [`Default::default()`]: https://doc.rust-lang.org/nightly/std/default/trait.Default.html#tymethod.default
3634 #![feature(default_free_fn)]
3635 use std::default::default;
3655 let options = AppConfig {
3667 label: "char_error_internals",
3668 description: r##"# `char_error_internals`
3670 This feature is internal to the Rust compiler and is not intended for general use.
3672 ------------------------
3676 label: "libstd_sys_internals",
3677 description: r##"# `libstd_sys_internals`
3679 This feature is internal to the Rust compiler and is not intended for general use.
3681 ------------------------
3686 description: r##"# `is_sorted`
3688 The tracking issue for this feature is: [#53485]
3690 [#53485]: https://github.com/rust-lang/rust/issues/53485
3692 ------------------------
3694 Add the methods `is_sorted`, `is_sorted_by` and `is_sorted_by_key` to `[T]`;
3695 add the methods `is_sorted`, `is_sorted_by` and `is_sorted_by_key` to
3700 label: "c_void_variant",
3701 description: r##"# `c_void_variant`
3703 This feature is internal to the Rust compiler and is not intended for general use.
3705 ------------------------
3709 label: "concat_idents",
3710 description: r##"# `concat_idents`
3712 The tracking issue for this feature is: [#29599]
3714 [#29599]: https://github.com/rust-lang/rust/issues/29599
3716 ------------------------
3718 The `concat_idents` feature adds a macro for concatenating multiple identifiers
3719 into one identifier.
3724 #![feature(concat_idents)]
3727 fn foobar() -> u32 { 23 }
3728 let f = concat_idents!(foo, bar);
3729 assert_eq!(f(), 23);
3735 label: "format_args_capture",
3736 description: r##"# `format_args_capture`
3738 The tracking issue for this feature is: [#67984]
3740 [#67984]: https://github.com/rust-lang/rust/issues/67984
3742 ------------------------
3744 Enables `format_args!` (and macros which use `format_args!` in their implementation, such
3745 as `format!`, `print!` and `panic!`) to capture variables from the surrounding scope.
3746 This avoids the need to pass named parameters when the binding in question
3747 already exists in scope.
3750 #![feature(format_args_capture)]
3752 let (person, species, name) = ("Charlie Brown", "dog", "Snoopy");
3754 // captures named argument `person`
3755 print!("Hello {person}");
3757 // captures named arguments `species` and `name`
3758 format!("The {species}'s name is {name}.");
3761 This also works for formatting parameters such as width and precision:
3764 #![feature(format_args_capture)]
3767 let s = format!("{:.precision$}", 1.324223);
3769 assert_eq!(&s, "1.32");
3772 A non-exhaustive list of macros which benefit from this functionality include:
3774 - `print!` and `println!`
3775 - `eprint!` and `eprintln!`
3776 - `write!` and `writeln!`
3781 - `assert!` and similar
3782 - macros in many thirdparty crates, such as `log`
3786 label: "print_internals",
3787 description: r##"# `print_internals`
3789 This feature is internal to the Rust compiler and is not intended for general use.
3791 ------------------------
3796 description: r##"# `llvm_asm`
3798 The tracking issue for this feature is: [#70173]
3800 [#70173]: https://github.com/rust-lang/rust/issues/70173
3802 ------------------------
3804 For extremely low-level manipulations and performance reasons, one
3805 might wish to control the CPU directly. Rust supports using inline
3806 assembly to do this via the `llvm_asm!` macro.
3808 ```rust,ignore (pseudo-code)
3809 llvm_asm!(assembly template
3817 Any use of `llvm_asm` is feature gated (requires `#![feature(llvm_asm)]` on the
3818 crate to allow) and of course requires an `unsafe` block.
3820 > **Note**: the examples here are given in x86/x86-64 assembly, but
3821 > all platforms are supported.
3823 ## Assembly template
3825 The `assembly template` is the only required parameter and must be a
3826 literal string (i.e. `""`)
3829 #![feature(llvm_asm)]
3831 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
3839 #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
3840 fn foo() { /* ... */ }
3849 (The `feature(llvm_asm)` and `#[cfg]`s are omitted from now on.)
3851 Output operands, input operands, clobbers and options are all optional
3852 but you must add the right number of `:` if you skip them:
3855 # #![feature(llvm_asm)]
3856 # #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
3857 # fn main() { unsafe {
3858 llvm_asm!("xor %eax, %eax"
3864 # #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
3868 Whitespace also doesn't matter:
3871 # #![feature(llvm_asm)]
3872 # #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
3873 # fn main() { unsafe {
3874 llvm_asm!("xor %eax, %eax" ::: "eax");
3876 # #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
3882 Input and output operands follow the same format: `:
3883 "constraints1"(expr1), "constraints2"(expr2), ..."`. Output operand
3884 expressions must be mutable place, or not yet assigned:
3887 # #![feature(llvm_asm)]
3888 # #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
3889 fn add(a: i32, b: i32) -> i32 {
3892 llvm_asm!("add $2, $0"
3899 # #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
3900 # fn add(a: i32, b: i32) -> i32 { a + b }
3903 assert_eq!(add(3, 14159), 14162)
3907 If you would like to use real operands in this position, however,
3908 you are required to put curly braces `{}` around the register that
3909 you want, and you are required to put the specific size of the
3910 operand. This is useful for very low level programming, where
3911 which register you use is important:
3914 # #![feature(llvm_asm)]
3915 # #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
3916 # unsafe fn read_byte_in(port: u16) -> u8 {
3918 llvm_asm!("in %dx, %al" : "={al}"(result) : "{dx}"(port));
3925 Some instructions modify registers which might otherwise have held
3926 different values so we use the clobbers list to indicate to the
3927 compiler not to assume any values loaded into those registers will
3931 # #![feature(llvm_asm)]
3932 # #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
3933 # fn main() { unsafe {
3934 // Put the value 0x200 in eax:
3935 llvm_asm!("mov $$0x200, %eax" : /* no outputs */ : /* no inputs */ : "eax");
3937 # #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
3941 Input and output registers need not be listed since that information
3942 is already communicated by the given constraints. Otherwise, any other
3943 registers used either implicitly or explicitly should be listed.
3945 If the assembly changes the condition code register `cc` should be
3946 specified as one of the clobbers. Similarly, if the assembly modifies
3947 memory, `memory` should also be specified.
3951 The last section, `options` is specific to Rust. The format is comma
3952 separated literal strings (i.e. `:"foo", "bar", "baz"`). It's used to
3953 specify some extra info about the inline assembly:
3955 Current valid options are:
3957 1. `volatile` - specifying this is analogous to
3958 `__asm__ __volatile__ (...)` in gcc/clang.
3959 2. `alignstack` - certain instructions expect the stack to be
3960 aligned a certain way (i.e. SSE) and specifying this indicates to
3961 the compiler to insert its usual stack alignment code
3962 3. `intel` - use intel syntax instead of the default AT&T.
3965 # #![feature(llvm_asm)]
3966 # #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
3970 llvm_asm!("mov eax, 2" : "={eax}"(result) : : : "intel")
3972 println!("eax is currently {}", result);
3974 # #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
3980 The current implementation of the `llvm_asm!` macro is a direct binding to [LLVM's
3981 inline assembler expressions][llvm-docs], so be sure to check out [their
3982 documentation as well][llvm-docs] for more information about clobbers,
3985 [llvm-docs]: http://llvm.org/docs/LangRef.html#inline-assembler-expressions
3987 If you need more power and don't mind losing some of the niceties of
3988 `llvm_asm!`, check out [global_asm](global-asm.md).
3992 label: "core_intrinsics",
3993 description: r##"# `core_intrinsics`
3995 This feature is internal to the Rust compiler and is not intended for general use.
3997 ------------------------
4001 label: "trace_macros",
4002 description: r##"# `trace_macros`
4004 The tracking issue for this feature is [#29598].
4006 [#29598]: https://github.com/rust-lang/rust/issues/29598
4008 ------------------------
4010 With `trace_macros` you can trace the expansion of macros in your code.
4015 #![feature(trace_macros)]
4018 trace_macros!(true);
4019 println!("Hello, Rust!");
4020 trace_macros!(false);
4024 The `cargo build` output:
4030 5 | println!("Hello, Rust!");
4031 | ^^^^^^^^^^^^^^^^^^^^^^^^^
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" ) )
4039 Finished dev [unoptimized + debuginfo] target(s) in 0.60 secs
4044 label: "update_panic_count",
4045 description: r##"# `update_panic_count`
4047 This feature is internal to the Rust compiler and is not intended for general use.
4049 ------------------------
4053 label: "core_private_bignum",
4054 description: r##"# `core_private_bignum`
4056 This feature is internal to the Rust compiler and is not intended for general use.
4058 ------------------------
4062 label: "sort_internals",
4063 description: r##"# `sort_internals`
4065 This feature is internal to the Rust compiler and is not intended for general use.
4067 ------------------------
4071 label: "windows_net",
4072 description: r##"# `windows_net`
4074 This feature is internal to the Rust compiler and is not intended for general use.
4076 ------------------------
4080 label: "c_variadic",
4081 description: r##"# `c_variadic`
4083 The tracking issue for this feature is: [#44930]
4085 [#44930]: https://github.com/rust-lang/rust/issues/44930
4087 ------------------------
4089 The `c_variadic` library feature exposes the `VaList` structure,
4090 Rust's analogue of C's `va_list` type.
4095 #![feature(c_variadic)]
4097 use std::ffi::VaList;
4099 pub unsafe extern "C" fn vadd(n: usize, mut args: VaList) -> usize {
4102 sum += args.arg::<usize>();
4110 label: "core_private_diy_float",
4111 description: r##"# `core_private_diy_float`
4113 This feature is internal to the Rust compiler and is not intended for general use.
4115 ------------------------
4119 label: "profiler_runtime_lib",
4120 description: r##"# `profiler_runtime_lib`
4122 This feature is internal to the Rust compiler and is not intended for general use.
4124 ------------------------
4128 label: "thread_local_internals",
4129 description: r##"# `thread_local_internals`
4131 This feature is internal to the Rust compiler and is not intended for general use.
4133 ------------------------
4137 label: "int_error_internals",
4138 description: r##"# `int_error_internals`
4140 This feature is internal to the Rust compiler and is not intended for general use.
4142 ------------------------
4146 label: "windows_stdio",
4147 description: r##"# `windows_stdio`
4149 This feature is internal to the Rust compiler and is not intended for general use.
4151 ------------------------
4155 label: "fmt_internals",
4156 description: r##"# `fmt_internals`
4158 This feature is internal to the Rust compiler and is not intended for general use.
4160 ------------------------
4165 description: r##"# `fd_read`
4167 This feature is internal to the Rust compiler and is not intended for general use.
4169 ------------------------
4173 label: "str_internals",
4174 description: r##"# `str_internals`
4176 This feature is internal to the Rust compiler and is not intended for general use.
4178 ------------------------
4183 description: r##"# `test`
4185 The tracking issue for this feature is: None.
4187 ------------------------
4189 The internals of the `test` crate are unstable, behind the `test` flag. The
4190 most widely used part of the `test` crate are benchmark tests, which can test
4191 the performance of your code. Let's make our `src/lib.rs` look like this
4199 pub fn add_two(a: i32) -> i32 {
4210 assert_eq!(4, add_two(2));
4214 fn bench_add_two(b: &mut Bencher) {
4215 b.iter(|| add_two(2));
4220 Note the `test` feature gate, which enables this unstable feature.
4222 We've imported the `test` crate, which contains our benchmarking support.
4223 We have a new function as well, with the `bench` attribute. Unlike regular
4224 tests, which take no arguments, benchmark tests take a `&mut Bencher`. This
4225 `Bencher` provides an `iter` method, which takes a closure. This closure
4226 contains the code we'd like to benchmark.
4228 We can run benchmark tests with `cargo bench`:
4232 Compiling adder v0.0.1 (file:///home/steve/tmp/adder)
4233 Running target/release/adder-91b3e234d4ed382a
4236 test tests::it_works ... ignored
4237 test tests::bench_add_two ... bench: 1 ns/iter (+/- 0)
4239 test result: ok. 0 passed; 0 failed; 1 ignored; 1 measured
4242 Our non-benchmark test was ignored. You may have noticed that `cargo bench`
4243 takes a bit longer than `cargo test`. This is because Rust runs our benchmark
4244 a number of times, and then takes the average. Because we're doing so little
4245 work in this example, we have a `1 ns/iter (+/- 0)`, but this would show
4246 the variance if there was one.
4248 Advice on writing benchmarks:
4251 * Move setup code outside the `iter` loop; only put the part you want to measure inside
4252 * Make the code do "the same thing" on each iteration; do not accumulate or change state
4253 * Make the outer function idempotent too; the benchmark runner is likely to run
4255 * Make the inner `iter` loop short and fast so benchmark runs are fast and the
4256 calibrator can adjust the run-length at fine resolution
4257 * Make the code in the `iter` loop do something simple, to assist in pinpointing
4258 performance improvements (or regressions)
4260 ## Gotcha: optimizations
4262 There's another tricky part to writing benchmarks: benchmarks compiled with
4263 optimizations activated can be dramatically changed by the optimizer so that
4264 the benchmark is no longer benchmarking what one expects. For example, the
4265 compiler might recognize that some calculation has no external effects and
4275 fn bench_xor_1000_ints(b: &mut Bencher) {
4277 (0..1000).fold(0, |old, new| old ^ new);
4282 gives the following results
4286 test bench_xor_1000_ints ... bench: 0 ns/iter (+/- 0)
4288 test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
4291 The benchmarking runner offers two ways to avoid this. Either, the closure that
4292 the `iter` method receives can return an arbitrary value which forces the
4293 optimizer to consider the result used and ensures it cannot remove the
4294 computation entirely. This could be done for the example above by adjusting the
4299 # impl X { fn iter<T, F>(&self, _: F) where F: FnMut() -> T {} } let b = X;
4301 // Note lack of `;` (could also use an explicit `return`).
4302 (0..1000).fold(0, |old, new| old ^ new)
4306 Or, the other option is to call the generic `test::black_box` function, which
4307 is an opaque "black box" to the optimizer and so forces it to consider any
4317 # impl X { fn iter<T, F>(&self, _: F) where F: FnMut() -> T {} } let b = X;
4319 let n = test::black_box(1000);
4321 (0..n).fold(0, |a, b| a ^ b)
4326 Neither of these read or modify the value, and are very cheap for small values.
4327 Larger values can be passed indirectly to reduce overhead (e.g.
4328 `black_box(&huge_struct)`).
4330 Performing either of the above changes gives the following benchmarking results
4334 test bench_xor_1000_ints ... bench: 131 ns/iter (+/- 3)
4336 test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
4339 However, the optimizer can still modify a testcase in an undesirable manner
4340 even when using either of the above.
4345 description: r##"# `windows_c`
4347 This feature is internal to the Rust compiler and is not intended for general use.
4349 ------------------------
4354 description: r##"# `dec2flt`
4356 This feature is internal to the Rust compiler and is not intended for general use.
4358 ------------------------
4362 label: "derive_clone_copy",
4363 description: r##"# `derive_clone_copy`
4365 This feature is internal to the Rust compiler and is not intended for general use.
4367 ------------------------
4371 label: "allocator_api",
4372 description: r##"# `allocator_api`
4374 The tracking issue for this feature is [#32838]
4376 [#32838]: https://github.com/rust-lang/rust/issues/32838
4378 ------------------------
4380 Sometimes you want the memory for one collection to use a different
4381 allocator than the memory for another collection. In this case,
4382 replacing the global allocator is not a workable option. Instead,
4383 you need to pass in an instance of an `AllocRef` to each collection
4384 for which you want a custom allocator.
4390 label: "core_panic",
4391 description: r##"# `core_panic`
4393 This feature is internal to the Rust compiler and is not intended for general use.
4395 ------------------------
4400 description: r##"# `fn_traits`
4402 The tracking issue for this feature is [#29625]
4404 See Also: [`unboxed_closures`](../language-features/unboxed-closures.md)
4406 [#29625]: https://github.com/rust-lang/rust/issues/29625
4410 The `fn_traits` feature allows for implementation of the [`Fn*`] traits
4411 for creating custom closure-like types.
4413 [`Fn*`]: https://doc.rust-lang.org/std/ops/trait.Fn.html
4416 #![feature(unboxed_closures)]
4417 #![feature(fn_traits)]
4423 impl FnOnce<(u32, )> for Adder {
4425 extern "rust-call" fn call_once(self, b: (u32, )) -> Self::Output {
4431 let adder = Adder { a: 3 };
4432 assert_eq!(adder(2), 5);
4439 description: r##"# `try_trait`
4441 The tracking issue for this feature is: [#42327]
4443 [#42327]: https://github.com/rust-lang/rust/issues/42327
4445 ------------------------
4447 This introduces a new trait `Try` for extending the `?` operator to types
4448 other than `Result` (a part of [RFC 1859]). The trait provides the canonical
4449 way to _view_ a type in terms of a success/failure dichotomy. This will
4450 allow `?` to supplant the `try_opt!` macro on `Option` and the `try_ready!`
4451 macro on `Poll`, among other things.
4453 [RFC 1859]: https://github.com/rust-lang/rfcs/pull/1859
4455 Here's an example implementation of the trait:
4457 ```rust,ignore (cannot-reimpl-Try)
4458 /// A distinct type to represent the `None` value of an `Option`.
4460 /// This enables using the `?` operator on `Option`; it's rarely useful alone.
4462 #[unstable(feature = "try_trait", issue = "42327")]
4463 pub struct None { _priv: () }
4465 #[unstable(feature = "try_trait", issue = "42327")]
4466 impl<T> ops::Try for Option<T> {
4470 fn into_result(self) -> Result<T, None> {
4471 self.ok_or(None { _priv: () })
4474 fn from_ok(v: T) -> Self {
4478 fn from_error(_: None) -> Self {
4484 Note the `Error` associated type here is a new marker. The `?` operator
4485 allows interconversion between different `Try` implementers only when
4486 the error type can be converted `Into` the error type of the enclosing
4487 function (or catch block). Having a distinct error type (as opposed to
4488 just `()`, or similar) restricts this to where it's semantically meaningful.
4493 description: r##"# `rt`
4495 This feature is internal to the Rust compiler and is not intended for general use.
4497 ------------------------
4502 description: r##"# `fd`
4504 This feature is internal to the Rust compiler and is not intended for general use.
4506 ------------------------
4510 label: "libstd_thread_internals",
4511 description: r##"# `libstd_thread_internals`
4513 This feature is internal to the Rust compiler and is not intended for general use.
4515 ------------------------
4520 pub(super) const CLIPPY_LINTS: &[LintCompletion] = &[
4522 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."##,
4526 label: "clippy::almost_swapped",
4527 description: r##"Checks for `foo = bar; bar = foo` sequences."##,
4530 label: "clippy::approx_constant",
4531 description: r##"Checks for floating point literals that approximate\nconstants which are defined in\n[`std::f32::consts`](https://doc.rust-lang.org/stable/std/f32/consts/#constants)\nor\n[`std::f64::consts`](https://doc.rust-lang.org/stable/std/f64/consts/#constants),\nrespectively, suggesting to use the predefined constant."##,
4534 label: "clippy::as_conversions",
4535 description: r##"Checks for usage of `as` conversions.\n\nNote that this lint is specialized in linting *every single* use of `as`\nregardless of whether good alternatives exist or not.\nIf you want more precise lints for `as`, please consider using these separate lints:\n`unnecessary_cast`, `cast_lossless/possible_truncation/possible_wrap/precision_loss/sign_loss`,\n`fn_to_numeric_cast(_with_truncation)`, `char_lit_as_u8`, `ref_to_mut` and `ptr_as_ptr`.\nThere is a good explanation the reason why this lint should work in this way and how it is useful\n[in this issue](https://github.com/rust-lang/rust-clippy/issues/5122)."##,
4538 label: "clippy::assertions_on_constants",
4539 description: r##"Checks for `assert!(true)` and `assert!(false)` calls."##,
4542 label: "clippy::assign_op_pattern",
4543 description: r##"Checks for `a = a op b` or `a = b commutative_op a`\npatterns."##,
4546 label: "clippy::assign_ops",
4547 description: r##"Nothing. This lint has been deprecated."##,
4550 label: "clippy::async_yields_async",
4551 description: r##"Checks for async blocks that yield values of types\nthat can themselves be awaited."##,
4554 label: "clippy::await_holding_lock",
4555 description: r##"Checks for calls to await while holding a\nnon-async-aware MutexGuard."##,
4558 label: "clippy::await_holding_refcell_ref",
4559 description: r##"Checks for calls to await while holding a\n`RefCell` `Ref` or `RefMut`."##,
4562 label: "clippy::bad_bit_mask",
4563 description: r##"Checks for incompatible bit masks in comparisons.\n\nThe formula for detecting if an expression of the type `_ <bit_op> m\n<cmp_op> c` (where `<bit_op>` is one of {`&`, `|`} and `<cmp_op>` is one of\n{`!=`, `>=`, `>`, `!=`, `>=`, `>`}) can be determined from the following\ntable:\n\n|Comparison |Bit Op|Example |is always|Formula |\n|------------|------|------------|---------|----------------------|\n|`==` or `!=`| `&` |`x & 2 == 3`|`false` |`c & m != c` |\n|`<` or `>=`| `&` |`x & 2 < 3` |`true` |`m < c` |\n|`>` or `<=`| `&` |`x & 1 > 1` |`false` |`m <= c` |\n|`==` or `!=`| `|` |`x | 1 == 0`|`false` |`c | m != c` |\n|`<` or `>=`| `|` |`x | 1 < 1` |`false` |`m >= c` |\n|`<=` or `>` | `|` |`x | 1 > 0` |`true` |`m > c` |"##,
4566 label: "clippy::bind_instead_of_map",
4567 description: r##"Checks for usage of `_.and_then(|x| Some(y))`, `_.and_then(|x| Ok(y))` or\n`_.or_else(|x| Err(y))`."##,
4570 label: "clippy::blacklisted_name",
4571 description: r##"Checks for usage of blacklisted names for variables, such\nas `foo`."##,
4574 label: "clippy::blanket_clippy_restriction_lints",
4575 description: r##"Checks for `warn`/`deny`/`forbid` attributes targeting the whole clippy::restriction category."##,
4578 label: "clippy::blocks_in_if_conditions",
4579 description: r##"Checks for `if` conditions that use blocks containing an\nexpression, statements or conditions that use closures with blocks."##,
4582 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."##,
4586 label: "clippy::borrow_interior_mutable_const",
4587 description: r##"Checks if `const` items which is interior mutable (e.g.,\ncontains a `Cell`, `Mutex`, `AtomicXxxx`, etc.) has been borrowed directly."##,
4590 label: "clippy::borrowed_box",
4591 description: r##"Checks for use of `&Box<T>` anywhere in the code.\nCheck the [Box documentation](https://doc.rust-lang.org/std/boxed/index.html) for more information."##,
4594 label: "clippy::box_vec",
4595 description: r##"Checks for use of `Box<Vec<_>>` anywhere in the code.\nCheck the [Box documentation](https://doc.rust-lang.org/std/boxed/index.html) for more information."##,
4598 label: "clippy::boxed_local",
4599 description: r##"Checks for usage of `Box<T>` where an unboxed `T` would\nwork fine."##,
4602 label: "clippy::builtin_type_shadow",
4603 description: r##"Warns if a generic shadows a built-in type."##,
4606 label: "clippy::bytes_nth",
4607 description: r##"Checks for the use of `.bytes().nth()`."##,
4610 label: "clippy::cargo_common_metadata",
4611 description: r##"Checks to see if all common metadata is defined in\n`Cargo.toml`. See: https://rust-lang-nursery.github.io/api-guidelines/documentation.html#cargotoml-includes-all-common-metadata-c-metadata"##,
4614 label: "clippy::case_sensitive_file_extension_comparisons",
4615 description: r##"Checks for calls to `ends_with` with possible file extensions\nand suggests to use a case-insensitive approach instead."##,
4618 label: "clippy::cast_lossless",
4619 description: r##"Checks for casts between numerical types that may\nbe replaced by safe conversion functions."##,
4622 label: "clippy::cast_possible_truncation",
4623 description: r##"Checks for casts between numerical types that may\ntruncate large values. This is expected behavior, so the cast is `Allow` by\ndefault."##,
4626 label: "clippy::cast_possible_wrap",
4627 description: r##"Checks for casts from an unsigned type to a signed type of\nthe same size. Performing such a cast is a 'no-op' for the compiler,\ni.e., nothing is changed at the bit level, and the binary representation of\nthe value is reinterpreted. This can cause wrapping if the value is too big\nfor the target signed type. However, the cast works as defined, so this lint\nis `Allow` by default."##,
4630 label: "clippy::cast_precision_loss",
4631 description: r##"Checks for casts from any numerical to a float type where\nthe receiving type cannot store all values from the original type without\nrounding errors. This possible rounding is to be expected, so this lint is\n`Allow` by default.\n\nBasically, this warns on casting any integer with 32 or more bits to `f32`\nor any 64-bit integer to `f64`."##,
4634 label: "clippy::cast_ptr_alignment",
4635 description: r##"Checks for casts, using `as` or `pointer::cast`,\nfrom a less-strictly-aligned pointer to a more-strictly-aligned pointer"##,
4638 label: "clippy::cast_ref_to_mut",
4639 description: r##"Checks for casts of `&T` to `&mut T` anywhere in the code."##,
4642 label: "clippy::cast_sign_loss",
4643 description: r##"Checks for casts from a signed to an unsigned numerical\ntype. In this case, negative values wrap around to large positive values,\nwhich can be quite surprising in practice. However, as the cast works as\ndefined, this lint is `Allow` by default."##,
4646 label: "clippy::char_lit_as_u8",
4647 description: r##"Checks for expressions where a character literal is cast\nto `u8` and suggests using a byte literal instead."##,
4650 label: "clippy::chars_last_cmp",
4651 description: r##"Checks for usage of `_.chars().last()` or\n`_.chars().next_back()` on a `str` to check if it ends with a given char."##,
4654 label: "clippy::chars_next_cmp",
4655 description: r##"Checks for usage of `.chars().next()` on a `str` to check\nif it starts with a given char."##,
4658 label: "clippy::checked_conversions",
4659 description: r##"Checks for explicit bounds checking when casting."##,
4662 label: "clippy::clone_double_ref",
4663 description: r##"Checks for usage of `.clone()` on an `&&T`."##,
4666 label: "clippy::clone_on_copy",
4667 description: r##"Checks for usage of `.clone()` on a `Copy` type."##,
4670 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)`)."##,
4673 LintCompletion { label: "clippy::cmp_nan", description: r##"Checks for comparisons to NaN."## },
4675 label: "clippy::cmp_null",
4676 description: r##"This lint checks for equality comparisons with `ptr::null`"##,
4679 label: "clippy::cmp_owned",
4680 description: r##"Checks for conversions to owned values just for the sake\nof a comparison."##,
4683 label: "clippy::cognitive_complexity",
4684 description: r##"Checks for methods with high cognitive complexity."##,
4687 label: "clippy::collapsible_else_if",
4688 description: r##"Checks for collapsible `else { if ... }` expressions\nthat can be collapsed to `else if ...`."##,
4691 label: "clippy::collapsible_if",
4692 description: r##"Checks for nested `if` statements which can be collapsed\nby `&&`-combining their conditions."##,
4695 label: "clippy::collapsible_match",
4696 description: r##"Finds nested `match` or `if let` expressions where the patterns may be \"collapsed\" together\nwithout adding any branches.\n\nNote that this lint is not intended to find _all_ cases where nested match patterns can be merged, but only\ncases where merging would most likely make the code more readable."##,
4699 label: "clippy::comparison_chain",
4700 description: r##"Checks comparison chains written with `if` that can be\nrewritten with `match` and `cmp`."##,
4703 label: "clippy::comparison_to_empty",
4704 description: r##"Checks for comparing to an empty slice such as `\"\"` or `[]`,\nand suggests using `.is_empty()` where applicable."##,
4707 label: "clippy::copy_iterator",
4708 description: r##"Checks for types that implement `Copy` as well as\n`Iterator`."##,
4711 label: "clippy::create_dir",
4712 description: r##"Checks usage of `std::fs::create_dir` and suggest using `std::fs::create_dir_all` instead."##,
4715 label: "clippy::crosspointer_transmute",
4716 description: r##"Checks for transmutes between a type `T` and `*T`."##,
4719 label: "clippy::dbg_macro",
4720 description: r##"Checks for usage of dbg!() macro."##,
4723 label: "clippy::debug_assert_with_mut_call",
4724 description: r##"Checks for function/method calls with a mutable\nparameter in `debug_assert!`, `debug_assert_eq!` and `debug_assert_ne!` macros."##,
4727 label: "clippy::decimal_literal_representation",
4728 description: r##"Warns if there is a better representation for a numeric literal."##,
4731 label: "clippy::declare_interior_mutable_const",
4732 description: r##"Checks for declaration of `const` items which is interior\nmutable (e.g., contains a `Cell`, `Mutex`, `AtomicXxxx`, etc.)."##,
4735 label: "clippy::default_numeric_fallback",
4736 description: r##"Checks for usage of unconstrained numeric literals which may cause default numeric fallback in type\ninference.\n\nDefault numeric fallback means that if numeric types have not yet been bound to concrete\ntypes at the end of type inference, then integer type is bound to `i32`, and similarly\nfloating type is bound to `f64`.\n\nSee [RFC0212](https://github.com/rust-lang/rfcs/blob/master/text/0212-restore-int-fallback.md) for more information about the fallback."##,
4739 label: "clippy::default_trait_access",
4740 description: r##"Checks for literal calls to `Default::default()`."##,
4743 label: "clippy::deprecated_cfg_attr",
4744 description: r##"Checks for `#[cfg_attr(rustfmt, rustfmt_skip)]` and suggests to replace it\nwith `#[rustfmt::skip]`."##,
4747 label: "clippy::deprecated_semver",
4748 description: r##"Checks for `#[deprecated]` annotations with a `since`\nfield that is not a valid semantic version."##,
4751 label: "clippy::deref_addrof",
4752 description: r##"Checks for usage of `*&` and `*&mut` in expressions."##,
4755 label: "clippy::derive_hash_xor_eq",
4756 description: r##"Checks for deriving `Hash` but implementing `PartialEq`\nexplicitly or vice versa."##,
4759 label: "clippy::derive_ord_xor_partial_ord",
4760 description: r##"Checks for deriving `Ord` but implementing `PartialOrd`\nexplicitly or vice versa."##,
4763 label: "clippy::disallowed_method",
4764 description: r##"Denies the configured methods and functions in clippy.toml"##,
4767 label: "clippy::diverging_sub_expression",
4768 description: r##"Checks for diverging calls that are not match arms or\nstatements."##,
4771 label: "clippy::doc_markdown",
4772 description: r##"Checks for the presence of `_`, `::` or camel-case words\noutside ticks in documentation."##,
4775 label: "clippy::double_comparisons",
4776 description: r##"Checks for double comparisons that could be simplified to a single expression."##,
4779 label: "clippy::double_must_use",
4780 description: r##"Checks for a [`#[must_use]`] attribute without\nfurther information on functions and methods that return a type already\nmarked as `#[must_use]`.\n\n[`#[must_use]`]: https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-must_use-attribute"##,
4783 label: "clippy::double_neg",
4784 description: r##"Detects expressions of the form `--x`."##,
4787 label: "clippy::double_parens",
4788 description: r##"Checks for unnecessary double parentheses."##,
4791 label: "clippy::drop_bounds",
4792 description: r##"Nothing. This lint has been deprecated."##,
4795 label: "clippy::drop_copy",
4796 description: r##"Checks for calls to `std::mem::drop` with a value\nthat derives the Copy trait"##,
4799 label: "clippy::drop_ref",
4800 description: r##"Checks for calls to `std::mem::drop` with a reference\ninstead of an owned value."##,
4803 label: "clippy::duplicate_underscore_argument",
4804 description: r##"Checks for function arguments having the similar names\ndiffering by an underscore."##,
4807 label: "clippy::duration_subsec",
4808 description: r##"Checks for calculation of subsecond microseconds or milliseconds\nfrom other `Duration` methods."##,
4811 label: "clippy::else_if_without_else",
4812 description: r##"Checks for usage of if expressions with an `else if` branch,\nbut without a final `else` branch."##,
4815 label: "clippy::empty_enum",
4816 description: r##"Checks for `enum`s with no variants.\n\nAs of this writing, the `never_type` is still a\nnightly-only experimental API. Therefore, this lint is only triggered\nif the `never_type` is enabled."##,
4819 label: "clippy::empty_line_after_outer_attr",
4820 description: r##"Checks for empty lines after outer attributes"##,
4823 label: "clippy::empty_loop",
4824 description: r##"Checks for empty `loop` expressions."##,
4827 label: "clippy::enum_clike_unportable_variant",
4828 description: r##"Checks for C-like enumerations that are\n`repr(isize/usize)` and have values that don't fit into an `i32`."##,
4831 label: "clippy::enum_glob_use",
4832 description: r##"Checks for `use Enum::*`."##,
4835 label: "clippy::enum_variant_names",
4836 description: r##"Detects enumeration variants that are prefixed or suffixed\nby the same characters."##,
4839 label: "clippy::eq_op",
4840 description: r##"Checks for equal operands to comparison, logical and\nbitwise, difference and division binary operators (`==`, `>`, etc., `&&`,\n`||`, `&`, `|`, `^`, `-` and `/`)."##,
4843 label: "clippy::erasing_op",
4844 description: r##"Checks for erasing operations, e.g., `x * 0`."##,
4847 label: "clippy::eval_order_dependence",
4848 description: r##"Checks for a read and a write to the same variable where\nwhether the read occurs before or after the write depends on the evaluation\norder of sub-expressions."##,
4851 label: "clippy::excessive_precision",
4852 description: r##"Checks for float literals with a precision greater\nthan that supported by the underlying type."##,
4855 label: "clippy::exhaustive_enums",
4856 description: r##"Warns on any exported `enum`s that are not tagged `#[non_exhaustive]`"##,
4859 label: "clippy::exhaustive_structs",
4860 description: r##"Warns on any exported `structs`s that are not tagged `#[non_exhaustive]`"##,
4863 label: "clippy::exit",
4864 description: r##"`exit()` terminates the program and doesn't provide a\nstack trace."##,
4867 label: "clippy::expect_fun_call",
4868 description: r##"Checks for calls to `.expect(&format!(...))`, `.expect(foo(..))`,\netc., and suggests to use `unwrap_or_else` instead"##,
4871 label: "clippy::expect_used",
4872 description: r##"Checks for `.expect()` calls on `Option`s and `Result`s."##,
4875 label: "clippy::expl_impl_clone_on_copy",
4876 description: r##"Checks for explicit `Clone` implementations for `Copy`\ntypes."##,
4879 label: "clippy::explicit_counter_loop",
4880 description: r##"Checks `for` loops over slices with an explicit counter\nand suggests the use of `.enumerate()`."##,
4883 label: "clippy::explicit_deref_methods",
4884 description: r##"Checks for explicit `deref()` or `deref_mut()` method calls."##,
4887 label: "clippy::explicit_into_iter_loop",
4888 description: r##"Checks for loops on `y.into_iter()` where `y` will do, and\nsuggests the latter."##,
4891 label: "clippy::explicit_iter_loop",
4892 description: r##"Checks for loops on `x.iter()` where `&x` will do, and\nsuggests the latter."##,
4895 label: "clippy::explicit_write",
4896 description: r##"Checks for usage of `write!()` / `writeln()!` which can be\nreplaced with `(e)print!()` / `(e)println!()`"##,
4899 label: "clippy::extend_from_slice",
4900 description: r##"Nothing. This lint has been deprecated."##,
4903 label: "clippy::extra_unused_lifetimes",
4904 description: r##"Checks for lifetimes in generics that are never used\nanywhere else."##,
4907 label: "clippy::fallible_impl_from",
4908 description: r##"Checks for impls of `From<..>` that contain `panic!()` or `unwrap()`"##,
4911 label: "clippy::field_reassign_with_default",
4912 description: r##"Checks for immediate reassignment of fields initialized\nwith Default::default()."##,
4915 label: "clippy::filetype_is_file",
4916 description: r##"Checks for `FileType::is_file()`."##,
4919 label: "clippy::filter_map",
4920 description: r##"Checks for usage of `_.filter(_).map(_)`,\n`_.filter(_).flat_map(_)`, `_.filter_map(_).flat_map(_)` and similar."##,
4923 label: "clippy::filter_map_identity",
4924 description: r##"Checks for usage of `filter_map(|x| x)`."##,
4927 label: "clippy::filter_map_next",
4928 description: r##"Checks for usage of `_.filter_map(_).next()`."##,
4931 label: "clippy::filter_next",
4932 description: r##"Checks for usage of `_.filter(_).next()`."##,
4935 label: "clippy::find_map",
4936 description: r##"Nothing. This lint has been deprecated."##,
4939 label: "clippy::flat_map_identity",
4940 description: r##"Checks for usage of `flat_map(|x| x)`."##,
4943 label: "clippy::float_arithmetic",
4944 description: r##"Checks for float arithmetic."##,
4947 label: "clippy::float_cmp",
4948 description: r##"Checks for (in-)equality comparisons on floating-point\nvalues (apart from zero), except in functions called `*eq*` (which probably\nimplement equality for a type involving floats)."##,
4951 label: "clippy::float_cmp_const",
4952 description: r##"Checks for (in-)equality comparisons on floating-point\nvalue and constant, except in functions called `*eq*` (which probably\nimplement equality for a type involving floats)."##,
4955 label: "clippy::float_equality_without_abs",
4956 description: r##"Checks for statements of the form `(a - b) < f32::EPSILON` or\n`(a - b) < f64::EPSILON`. Notes the missing `.abs()`."##,
4959 label: "clippy::fn_address_comparisons",
4960 description: r##"Checks for comparisons with an address of a function item."##,
4963 label: "clippy::fn_params_excessive_bools",
4964 description: r##"Checks for excessive use of\nbools in function definitions."##,
4967 label: "clippy::fn_to_numeric_cast",
4968 description: r##"Checks for casts of function pointers to something other than usize"##,
4971 label: "clippy::fn_to_numeric_cast_with_truncation",
4972 description: r##"Checks for casts of a function pointer to a numeric type not wide enough to\nstore address."##,
4975 label: "clippy::for_kv_map",
4976 description: r##"Checks for iterating a map (`HashMap` or `BTreeMap`) and\nignoring either the keys or values."##,
4979 label: "clippy::for_loops_over_fallibles",
4980 description: r##"Checks for `for` loops over `Option` or `Result` values."##,
4983 label: "clippy::forget_copy",
4984 description: r##"Checks for calls to `std::mem::forget` with a value that\nderives the Copy trait"##,
4987 label: "clippy::forget_ref",
4988 description: r##"Checks for calls to `std::mem::forget` with a reference\ninstead of an owned value."##,
4991 label: "clippy::from_iter_instead_of_collect",
4992 description: r##"Checks for `from_iter()` function calls on types that implement the `FromIterator`\ntrait."##,
4995 label: "clippy::from_over_into",
4996 description: r##"Searches for implementations of the `Into<..>` trait and suggests to implement `From<..>` instead."##,
4999 label: "clippy::from_str_radix_10",
5000 description: r##"Checks for function invocations of the form `primitive::from_str_radix(s, 10)`"##,
5003 label: "clippy::future_not_send",
5004 description: r##"This lint requires Future implementations returned from\nfunctions and methods to implement the `Send` marker trait. It is mostly\nused by library authors (public and internal) that target an audience where\nmultithreaded executors are likely to be used for running these Futures."##,
5007 label: "clippy::get_last_with_len",
5008 description: r##"Checks for using `x.get(x.len() - 1)` instead of\n`x.last()`."##,
5011 label: "clippy::get_unwrap",
5012 description: r##"Checks for use of `.get().unwrap()` (or\n`.get_mut().unwrap`) on a standard library type which implements `Index`"##,
5015 label: "clippy::identity_op",
5016 description: r##"Checks for identity operations, e.g., `x + 0`."##,
5019 label: "clippy::if_let_mutex",
5020 description: r##"Checks for `Mutex::lock` calls in `if let` expression\nwith lock calls in any of the else blocks."##,
5023 label: "clippy::if_let_redundant_pattern_matching",
5024 description: r##"Nothing. This lint has been deprecated."##,
5027 label: "clippy::if_let_some_result",
5028 description: r##"* Checks for unnecessary `ok()` in if let."##,
5031 label: "clippy::if_not_else",
5032 description: r##"Checks for usage of `!` or `!=` in an if condition with an\nelse branch."##,
5035 label: "clippy::if_same_then_else",
5036 description: r##"Checks for `if/else` with the same body as the *then* part\nand the *else* part."##,
5039 label: "clippy::ifs_same_cond",
5040 description: r##"Checks for consecutive `if`s with the same condition."##,
5043 label: "clippy::implicit_clone",
5044 description: r##"Checks for the usage of `_.to_owned()`, `vec.to_vec()`, or similar when calling `_.clone()` would be clearer."##,
5047 label: "clippy::implicit_hasher",
5048 description: r##"Checks for public `impl` or `fn` missing generalization\nover different hashers and implicitly defaulting to the default hashing\nalgorithm (`SipHash`)."##,
5051 label: "clippy::implicit_return",
5052 description: r##"Checks for missing return statements at the end of a block."##,
5055 label: "clippy::implicit_saturating_sub",
5056 description: r##"Checks for implicit saturating subtraction."##,
5059 label: "clippy::imprecise_flops",
5060 description: r##"Looks for floating-point expressions that\ncan be expressed using built-in methods to improve accuracy\nat the cost of performance."##,
5063 label: "clippy::inconsistent_digit_grouping",
5064 description: r##"Warns if an integral or floating-point constant is\ngrouped inconsistently with underscores."##,
5067 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."##,
5071 label: "clippy::indexing_slicing",
5072 description: r##"Checks for usage of indexing or slicing. Arrays are special cases, this lint\ndoes report on arrays if we can tell that slicing operations are in bounds and does not\nlint on constant `usize` indexing on arrays because that is handled by rustc's `const_err` lint."##,
5075 label: "clippy::ineffective_bit_mask",
5076 description: r##"Checks for bit masks in comparisons which can be removed\nwithout changing the outcome. The basic structure can be seen in the\nfollowing table:\n\n|Comparison| Bit Op |Example |equals |\n|----------|---------|-----------|-------|\n|`>` / `<=`|`|` / `^`|`x | 2 > 3`|`x > 3`|\n|`<` / `>=`|`|` / `^`|`x ^ 1 < 4`|`x < 4`|"##,
5079 label: "clippy::inefficient_to_string",
5080 description: r##"Checks for usage of `.to_string()` on an `&&T` where\n`T` implements `ToString` directly (like `&&str` or `&&String`)."##,
5083 label: "clippy::infallible_destructuring_match",
5084 description: r##"Checks for matches being used to destructure a single-variant enum\nor tuple struct where a `let` will suffice."##,
5087 label: "clippy::infinite_iter",
5088 description: r##"Checks for iteration that is guaranteed to be infinite."##,
5091 label: "clippy::inherent_to_string",
5092 description: r##"Checks for the definition of inherent methods with a signature of `to_string(&self) -> String`."##,
5095 label: "clippy::inherent_to_string_shadow_display",
5096 description: r##"Checks for the definition of inherent methods with a signature of `to_string(&self) -> String` and if the type implementing this method also implements the `Display` trait."##,
5099 label: "clippy::inline_always",
5100 description: r##"Checks for items annotated with `#[inline(always)]`,\nunless the annotated function is empty or simply panics."##,
5103 label: "clippy::inline_asm_x86_att_syntax",
5104 description: r##"Checks for usage of AT&T x86 assembly syntax."##,
5107 label: "clippy::inline_asm_x86_intel_syntax",
5108 description: r##"Checks for usage of Intel x86 assembly syntax."##,
5111 label: "clippy::inline_fn_without_body",
5112 description: r##"Checks for `#[inline]` on trait methods without bodies"##,
5115 label: "clippy::inspect_for_each",
5116 description: r##"Checks for usage of `inspect().for_each()`."##,
5119 label: "clippy::int_plus_one",
5120 description: r##"Checks for usage of `x >= y + 1` or `x - 1 >= y` (and `<=`) in a block"##,
5123 label: "clippy::integer_arithmetic",
5124 description: r##"Checks for integer arithmetic operations which could overflow or panic.\n\nSpecifically, checks for any operators (`+`, `-`, `*`, `<<`, etc) which are capable\nof overflowing according to the [Rust\nReference](https://doc.rust-lang.org/reference/expressions/operator-expr.html#overflow),\nor which can panic (`/`, `%`). No bounds analysis or sophisticated reasoning is\nattempted."##,
5127 label: "clippy::integer_division",
5128 description: r##"Checks for division of integers"##,
5131 label: "clippy::into_iter_on_array",
5132 description: r##"Nothing. This lint has been deprecated."##,
5135 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`."##,
5139 label: "clippy::invalid_atomic_ordering",
5140 description: r##"Checks for usage of invalid atomic\nordering in atomic loads/stores/exchanges/updates and\nmemory fences."##,
5143 label: "clippy::invalid_ref",
5144 description: r##"Nothing. This lint has been deprecated."##,
5147 label: "clippy::invalid_regex",
5148 description: r##"Checks [regex](https://crates.io/crates/regex) creation\n(with `Regex::new`, `RegexBuilder::new`, or `RegexSet::new`) for correct\nregex syntax."##,
5151 label: "clippy::invalid_upcast_comparisons",
5152 description: r##"Checks for comparisons where the relation is always either\ntrue or false, but where one side has been upcast so that the comparison is\nnecessary. Only integer types are checked."##,
5155 label: "clippy::invisible_characters",
5156 description: r##"Checks for invisible Unicode characters in the code."##,
5159 label: "clippy::items_after_statements",
5160 description: r##"Checks for items declared after some statement in a block."##,
5163 label: "clippy::iter_cloned_collect",
5164 description: r##"Checks for the use of `.cloned().collect()` on slice to\ncreate a `Vec`."##,
5167 label: "clippy::iter_next_loop",
5168 description: r##"Checks for loops on `x.next()`."##,
5171 label: "clippy::iter_next_slice",
5172 description: r##"Checks for usage of `iter().next()` on a Slice or an Array"##,
5175 label: "clippy::iter_nth",
5176 description: r##"Checks for use of `.iter().nth()` (and the related\n`.iter_mut().nth()`) on standard library types with O(1) element access."##,
5179 label: "clippy::iter_nth_zero",
5180 description: r##"Checks for the use of `iter.nth(0)`."##,
5183 label: "clippy::iter_skip_next",
5184 description: r##"Checks for use of `.skip(x).next()` on iterators."##,
5187 label: "clippy::iterator_step_by_zero",
5188 description: r##"Checks for calling `.step_by(0)` on iterators which panics."##,
5191 label: "clippy::just_underscores_and_digits",
5192 description: r##"Checks if you have variables whose name consists of just\nunderscores and digits."##,
5195 label: "clippy::large_const_arrays",
5196 description: r##"Checks for large `const` arrays that should\nbe defined as `static` instead."##,
5199 label: "clippy::large_digit_groups",
5200 description: r##"Warns if the digits of an integral or floating-point\nconstant are grouped into groups that\nare too large."##,
5203 label: "clippy::large_enum_variant",
5204 description: r##"Checks for large size differences between variants on\n`enum`s."##,
5207 label: "clippy::large_stack_arrays",
5208 description: r##"Checks for local arrays that may be too large."##,
5211 label: "clippy::large_types_passed_by_value",
5212 description: r##"Checks for functions taking arguments by value, where\nthe argument type is `Copy` and large enough to be worth considering\npassing by reference. Does not trigger if the function is being exported,\nbecause that might induce API breakage, if the parameter is declared as mutable,\nor if the argument is a `self`."##,
5215 label: "clippy::len_without_is_empty",
5216 description: r##"Checks for items that implement `.len()` but not\n`.is_empty()`."##,
5219 label: "clippy::len_zero",
5220 description: r##"Checks for getting the length of something via `.len()`\njust to compare to zero, and suggests using `.is_empty()` where applicable."##,
5223 label: "clippy::let_and_return",
5224 description: r##"Checks for `let`-bindings, which are subsequently\nreturned."##,
5227 label: "clippy::let_underscore_drop",
5228 description: r##"Checks for `let _ = <expr>`\nwhere expr has a type that implements `Drop`"##,
5231 label: "clippy::let_underscore_lock",
5232 description: r##"Checks for `let _ = sync_lock`"##,
5235 label: "clippy::let_underscore_must_use",
5236 description: r##"Checks for `let _ = <expr>`\nwhere expr is #[must_use]"##,
5239 label: "clippy::let_unit_value",
5240 description: r##"Checks for binding a unit value."##,
5243 label: "clippy::linkedlist",
5244 description: r##"Checks for usage of any `LinkedList`, suggesting to use a\n`Vec` or a `VecDeque` (formerly called `RingBuf`)."##,
5247 label: "clippy::logic_bug",
5248 description: r##"Checks for boolean expressions that contain terminals that\ncan be eliminated."##,
5251 label: "clippy::lossy_float_literal",
5252 description: r##"Checks for whole number float literals that\ncannot be represented as the underlying type without loss."##,
5255 label: "clippy::macro_use_imports",
5256 description: r##"Checks for `#[macro_use] use...`."##,
5259 label: "clippy::main_recursion",
5260 description: r##"Checks for recursion using the entrypoint."##,
5263 label: "clippy::manual_async_fn",
5264 description: r##"It checks for manual implementations of `async` functions."##,
5267 label: "clippy::manual_filter_map",
5268 description: r##"Checks for usage of `_.filter(_).map(_)` that can be written more simply\nas `filter_map(_)`."##,
5271 label: "clippy::manual_find_map",
5272 description: r##"Checks for usage of `_.find(_).map(_)` that can be written more simply\nas `find_map(_)`."##,
5275 label: "clippy::manual_flatten",
5276 description: r##"Check for unnecessary `if let` usage in a for loop\nwhere only the `Some` or `Ok` variant of the iterator element is used."##,
5279 label: "clippy::manual_map",
5280 description: r##"Checks for usages of `match` which could be implemented using `map`"##,
5283 label: "clippy::manual_memcpy",
5284 description: r##"Checks for for-loops that manually copy items between\nslices that could be optimized by having a memcpy."##,
5287 label: "clippy::manual_non_exhaustive",
5288 description: r##"Checks for manual implementations of the non-exhaustive pattern."##,
5291 label: "clippy::manual_ok_or",
5292 description: r##"Finds patterns that reimplement `Option::ok_or`."##,
5295 label: "clippy::manual_range_contains",
5296 description: r##"Checks for expressions like `x >= 3 && x < 8` that could\nbe more readably expressed as `(3..8).contains(x)`."##,
5299 label: "clippy::manual_saturating_arithmetic",
5300 description: r##"Checks for `.checked_add/sub(x).unwrap_or(MAX/MIN)`."##,
5303 label: "clippy::manual_strip",
5304 description: r##"Suggests using `strip_{prefix,suffix}` over `str::{starts,ends}_with` and slicing using\nthe pattern's length."##,
5307 label: "clippy::manual_swap",
5308 description: r##"Checks for manual swapping."##,
5311 label: "clippy::manual_unwrap_or",
5312 description: r##"Finds patterns that reimplement `Option::unwrap_or` or `Result::unwrap_or`."##,
5315 label: "clippy::many_single_char_names",
5316 description: r##"Checks for too many variables whose name consists of a\nsingle character."##,
5319 label: "clippy::map_clone",
5320 description: r##"Checks for usage of `map(|x| x.clone())` or\ndereferencing closures for `Copy` types, on `Iterator` or `Option`,\nand suggests `cloned()` or `copied()` instead"##,
5323 label: "clippy::map_collect_result_unit",
5324 description: r##"Checks for usage of `_.map(_).collect::<Result<(), _>()`."##,
5327 label: "clippy::map_entry",
5328 description: r##"Checks for uses of `contains_key` + `insert` on `HashMap`\nor `BTreeMap`."##,
5331 label: "clippy::map_err_ignore",
5332 description: r##"Checks for instances of `map_err(|_| Some::Enum)`"##,
5335 label: "clippy::map_flatten",
5336 description: r##"Checks for usage of `_.map(_).flatten(_)`,"##,
5339 label: "clippy::map_identity",
5340 description: r##"Checks for instances of `map(f)` where `f` is the identity function."##,
5343 label: "clippy::map_unwrap_or",
5344 description: r##"Checks for usage of `option.map(_).unwrap_or(_)` or `option.map(_).unwrap_or_else(_)` or\n`result.map(_).unwrap_or_else(_)`."##,
5347 label: "clippy::match_as_ref",
5348 description: r##"Checks for match which is used to add a reference to an\n`Option` value."##,
5351 label: "clippy::match_bool",
5352 description: r##"Checks for matches where match expression is a `bool`. It\nsuggests to replace the expression with an `if...else` block."##,
5355 label: "clippy::match_like_matches_macro",
5356 description: r##"Checks for `match` or `if let` expressions producing a\n`bool` that could be written using `matches!`"##,
5359 label: "clippy::match_on_vec_items",
5360 description: r##"Checks for `match vec[idx]` or `match vec[n..m]`."##,
5363 label: "clippy::match_overlapping_arm",
5364 description: r##"Checks for overlapping match arms."##,
5367 label: "clippy::match_ref_pats",
5368 description: r##"Checks for matches where all arms match a reference,\nsuggesting to remove the reference and deref the matched expression\ninstead. It also checks for `if let &foo = bar` blocks."##,
5371 label: "clippy::match_same_arms",
5372 description: r##"Checks for `match` with identical arm bodies."##,
5375 label: "clippy::match_single_binding",
5376 description: r##"Checks for useless match that binds to only one value."##,
5379 label: "clippy::match_wild_err_arm",
5380 description: r##"Checks for arm which matches all errors with `Err(_)`\nand take drastic actions like `panic!`."##,
5383 label: "clippy::match_wildcard_for_single_variants",
5384 description: r##"Checks for wildcard enum matches for a single variant."##,
5387 label: "clippy::maybe_infinite_iter",
5388 description: r##"Checks for iteration that may be infinite."##,
5391 label: "clippy::mem_discriminant_non_enum",
5392 description: r##"Checks for calls of `mem::discriminant()` on a non-enum type."##,
5395 label: "clippy::mem_forget",
5396 description: r##"Checks for usage of `std::mem::forget(t)` where `t` is\n`Drop`."##,
5399 label: "clippy::mem_replace_option_with_none",
5400 description: r##"Checks for `mem::replace()` on an `Option` with\n`None`."##,
5403 label: "clippy::mem_replace_with_default",
5404 description: r##"Checks for `std::mem::replace` on a value of type\n`T` with `T::default()`."##,
5407 label: "clippy::mem_replace_with_uninit",
5408 description: r##"Checks for `mem::replace(&mut _, mem::uninitialized())`\nand `mem::replace(&mut _, mem::zeroed())`."##,
5411 label: "clippy::min_max",
5412 description: r##"Checks for expressions where `std::cmp::min` and `max` are\nused to clamp values, but switched so that the result is constant."##,
5415 label: "clippy::misaligned_transmute",
5416 description: r##"Nothing. This lint has been deprecated."##,
5419 label: "clippy::mismatched_target_os",
5420 description: r##"Checks for cfg attributes having operating systems used in target family position."##,
5423 label: "clippy::misrefactored_assign_op",
5424 description: r##"Checks for `a op= a op b` or `a op= b op a` patterns."##,
5427 label: "clippy::missing_const_for_fn",
5428 description: r##"Suggests the use of `const` in functions and methods where possible."##,
5431 label: "clippy::missing_docs_in_private_items",
5432 description: r##"Warns if there is missing doc for any documentable item\n(public or private)."##,
5435 label: "clippy::missing_errors_doc",
5436 description: r##"Checks the doc comments of publicly visible functions that\nreturn a `Result` type and warns if there is no `# Errors` section."##,
5439 label: "clippy::missing_inline_in_public_items",
5440 description: r##"it lints if an exported function, method, trait method with default impl,\nor trait method impl is not `#[inline]`."##,
5443 label: "clippy::missing_panics_doc",
5444 description: r##"Checks the doc comments of publicly visible functions that\nmay panic and warns if there is no `# Panics` section."##,
5447 label: "clippy::missing_safety_doc",
5448 description: r##"Checks for the doc comments of publicly visible\nunsafe functions and warns if there is no `# Safety` section."##,
5451 label: "clippy::mistyped_literal_suffixes",
5452 description: r##"Warns for mistyped suffix in literals"##,
5455 label: "clippy::mixed_case_hex_literals",
5456 description: r##"Warns on hexadecimal literals with mixed-case letter\ndigits."##,
5459 label: "clippy::module_inception",
5460 description: r##"Checks for modules that have the same name as their\nparent module"##,
5463 label: "clippy::module_name_repetitions",
5464 description: r##"Detects type names that are prefixed or suffixed by the\ncontaining module's name."##,
5467 label: "clippy::modulo_arithmetic",
5468 description: r##"Checks for modulo arithmetic."##,
5471 label: "clippy::modulo_one",
5472 description: r##"Checks for getting the remainder of a division by one or minus\none."##,
5475 label: "clippy::multiple_crate_versions",
5476 description: r##"Checks to see if multiple versions of a crate are being\nused."##,
5479 label: "clippy::multiple_inherent_impl",
5480 description: r##"Checks for multiple inherent implementations of a struct"##,
5483 label: "clippy::must_use_candidate",
5484 description: r##"Checks for public functions that have no\n[`#[must_use]`] attribute, but return something not already marked\nmust-use, have no mutable arg and mutate no statics.\n\n[`#[must_use]`]: https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-must_use-attribute"##,
5487 label: "clippy::must_use_unit",
5488 description: r##"Checks for a [`#[must_use]`] attribute on\nunit-returning functions and methods.\n\n[`#[must_use]`]: https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-must_use-attribute"##,
5491 label: "clippy::mut_from_ref",
5492 description: r##"This lint checks for functions that take immutable\nreferences and return mutable ones."##,
5495 label: "clippy::mut_mut",
5496 description: r##"Checks for instances of `mut mut` references."##,
5499 label: "clippy::mut_mutex_lock",
5500 description: r##"Checks for `&mut Mutex::lock` calls"##,
5503 label: "clippy::mut_range_bound",
5504 description: r##"Checks for loops which have a range bound that is a mutable variable"##,
5507 label: "clippy::mutable_key_type",
5508 description: r##"Checks for sets/maps with mutable key types."##,
5511 label: "clippy::mutex_atomic",
5512 description: r##"Checks for usages of `Mutex<X>` where an atomic will do."##,
5515 label: "clippy::mutex_integer",
5516 description: r##"Checks for usages of `Mutex<X>` where `X` is an integral\ntype."##,
5519 label: "clippy::naive_bytecount",
5520 description: r##"Checks for naive byte counts"##,
5523 label: "clippy::needless_arbitrary_self_type",
5524 description: r##"The lint checks for `self` in fn parameters that\nspecify the `Self`-type explicitly"##,
5527 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."##,
5531 label: "clippy::needless_borrow",
5532 description: r##"Checks for address of operations (`&`) that are going to\nbe dereferenced immediately by the compiler."##,
5535 label: "clippy::needless_borrowed_reference",
5536 description: r##"Checks for useless borrowed references."##,
5539 label: "clippy::needless_collect",
5540 description: r##"Checks for functions collecting an iterator when collect\nis not needed."##,
5543 label: "clippy::needless_continue",
5544 description: r##"The lint checks for `if`-statements appearing in loops\nthat contain a `continue` statement in either their main blocks or their\n`else`-blocks, when omitting the `else`-block possibly with some\nrearrangement of code can make the code easier to understand."##,
5547 label: "clippy::needless_doctest_main",
5548 description: r##"Checks for `fn main() { .. }` in doctests"##,
5551 label: "clippy::needless_lifetimes",
5552 description: r##"Checks for lifetime annotations which can be removed by\nrelying on lifetime elision."##,
5555 label: "clippy::needless_pass_by_value",
5556 description: r##"Checks for functions taking arguments by value, but not\nconsuming them in its\nbody."##,
5559 label: "clippy::needless_question_mark",
5560 description: r##"Suggests alternatives for useless applications of `?` in terminating expressions"##,
5563 label: "clippy::needless_range_loop",
5564 description: r##"Checks for looping over the range of `0..len` of some\ncollection just to get the values by index."##,
5567 label: "clippy::needless_return",
5568 description: r##"Checks for return statements at the end of a block."##,
5571 label: "clippy::needless_update",
5572 description: r##"Checks for needlessly including a base struct on update\nwhen all fields are changed anyway.\n\nThis lint is not applied to structs marked with\n[non_exhaustive](https://doc.rust-lang.org/reference/attributes/type_system.html)."##,
5575 label: "clippy::neg_cmp_op_on_partial_ord",
5576 description: r##"Checks for the usage of negated comparison operators on types which only implement\n`PartialOrd` (e.g., `f64`)."##,
5579 label: "clippy::neg_multiply",
5580 description: r##"Checks for multiplication by -1 as a form of negation."##,
5583 label: "clippy::never_loop",
5584 description: r##"Checks for loops that will always `break`, `return` or\n`continue` an outer loop."##,
5587 label: "clippy::new_ret_no_self",
5588 description: r##"Checks for `new` not returning a type that contains `Self`."##,
5591 label: "clippy::new_without_default",
5592 description: r##"Checks for types with a `fn new() -> Self` method and no\nimplementation of\n[`Default`](https://doc.rust-lang.org/std/default/trait.Default.html)."##,
5595 label: "clippy::no_effect",
5596 description: r##"Checks for statements which have no effect."##,
5599 label: "clippy::non_ascii_literal",
5600 description: r##"Checks for non-ASCII characters in string literals."##,
5603 label: "clippy::nonminimal_bool",
5604 description: r##"Checks for boolean expressions that can be written more\nconcisely."##,
5607 label: "clippy::nonsensical_open_options",
5608 description: r##"Checks for duplicate open options as well as combinations\nthat make no sense."##,
5611 label: "clippy::not_unsafe_ptr_arg_deref",
5612 description: r##"Checks for public functions that dereference raw pointer\narguments but are not marked unsafe."##,
5615 label: "clippy::ok_expect",
5616 description: r##"Checks for usage of `ok().expect(..)`."##,
5619 label: "clippy::op_ref",
5620 description: r##"Checks for arguments to `==` which have their address\ntaken to satisfy a bound\nand suggests to dereference the other argument instead"##,
5623 label: "clippy::option_as_ref_deref",
5624 description: r##"Checks for usage of `_.as_ref().map(Deref::deref)` or it's aliases (such as String::as_str)."##,
5627 label: "clippy::option_env_unwrap",
5628 description: r##"Checks for usage of `option_env!(...).unwrap()` and\nsuggests usage of the `env!` macro."##,
5631 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)."##,
5635 label: "clippy::option_map_or_none",
5636 description: r##"Checks for usage of `_.map_or(None, _)`."##,
5639 label: "clippy::option_map_unit_fn",
5640 description: r##"Checks for usage of `option.map(f)` where f is a function\nor closure that returns the unit type `()`."##,
5643 label: "clippy::option_option",
5644 description: r##"Checks for use of `Option<Option<_>>` in function signatures and type\ndefinitions"##,
5647 label: "clippy::or_fun_call",
5648 description: r##"Checks for calls to `.or(foo(..))`, `.unwrap_or(foo(..))`,\netc., and suggests to use `or_else`, `unwrap_or_else`, etc., or\n`unwrap_or_default` instead."##,
5651 label: "clippy::out_of_bounds_indexing",
5652 description: r##"Checks for out of bounds array indexing with a constant\nindex."##,
5655 label: "clippy::overflow_check_conditional",
5656 description: r##"Detects classic underflow/overflow checks."##,
5658 LintCompletion { label: "clippy::panic", description: r##"Checks for usage of `panic!`."## },
5660 label: "clippy::panic_in_result_fn",
5661 description: r##"Checks for usage of `panic!`, `unimplemented!`, `todo!`, `unreachable!` or assertions in a function of type result."##,
5664 label: "clippy::panic_params",
5665 description: r##"Nothing. This lint has been deprecated."##,
5668 label: "clippy::panicking_unwrap",
5669 description: r##"Checks for calls of `unwrap[_err]()` that will always fail."##,
5672 label: "clippy::partialeq_ne_impl",
5673 description: r##"Checks for manual re-implementations of `PartialEq::ne`."##,
5676 label: "clippy::path_buf_push_overwrite",
5677 description: r##"* Checks for [push](https://doc.rust-lang.org/std/path/struct.PathBuf.html#method.push)\ncalls on `PathBuf` that can cause overwrites."##,
5680 label: "clippy::pattern_type_mismatch",
5681 description: r##"Checks for patterns that aren't exact representations of the types\nthey are applied to.\n\nTo satisfy this lint, you will have to adjust either the expression that is matched\nagainst or the pattern itself, as well as the bindings that are introduced by the\nadjusted patterns. For matching you will have to either dereference the expression\nwith the `*` operator, or amend the patterns to explicitly match against `&<pattern>`\nor `&mut <pattern>` depending on the reference mutability. For the bindings you need\nto use the inverse. You can leave them as plain bindings if you wish for the value\nto be copied, but you must use `ref mut <variable>` or `ref <variable>` to construct\na reference into the matched structure.\n\nIf you are looking for a way to learn about ownership semantics in more detail, it\nis recommended to look at IDE options available to you to highlight types, lifetimes\nand reference semantics in your code. The available tooling would expose these things\nin a general way even outside of the various pattern matching mechanics. Of course\nthis lint can still be used to highlight areas of interest and ensure a good understanding\nof ownership semantics."##,
5684 label: "clippy::possible_missing_comma",
5685 description: r##"Checks for possible missing comma in an array. It lints if\nan array element is a binary operator expression and it lies on two lines."##,
5688 label: "clippy::precedence",
5689 description: r##"Checks for operations where precedence may be unclear\nand suggests to add parentheses. Currently it catches the following:\n* mixed usage of arithmetic and bit shifting/combining operators without\nparentheses\n* a \"negative\" numeric literal (which is really a unary `-` followed by a\nnumeric literal)\n followed by a method call"##,
5692 label: "clippy::print_literal",
5693 description: r##"This lint warns about the use of literals as `print!`/`println!` args."##,
5696 label: "clippy::print_stderr",
5697 description: r##"Checks for printing on *stderr*. The purpose of this lint\nis to catch debugging remnants."##,
5700 label: "clippy::print_stdout",
5701 description: r##"Checks for printing on *stdout*. The purpose of this lint\nis to catch debugging remnants."##,
5704 label: "clippy::print_with_newline",
5705 description: r##"This lint warns when you use `print!()` with a format\nstring that ends in a newline."##,
5708 label: "clippy::println_empty_string",
5709 description: r##"This lint warns when you use `println!(\"\")` to\nprint a newline."##,
5712 label: "clippy::ptr_arg",
5713 description: r##"This lint checks for function arguments of type `&String`\nor `&Vec` unless the references are mutable. It will also suggest you\nreplace `.clone()` calls with the appropriate `.to_owned()`/`to_string()`\ncalls."##,
5716 label: "clippy::ptr_as_ptr",
5717 description: r##"Checks for `as` casts between raw pointers without changing its mutability,\nnamely `*const T` to `*const U` and `*mut T` to `*mut U`."##,
5720 label: "clippy::ptr_eq",
5721 description: r##"Use `std::ptr::eq` when applicable"##,
5724 label: "clippy::ptr_offset_with_cast",
5725 description: r##"Checks for usage of the `offset` pointer method with a `usize` casted to an\n`isize`."##,
5728 label: "clippy::pub_enum_variant_names",
5729 description: r##"Detects public enumeration variants that are\nprefixed or suffixed by the same characters."##,
5732 label: "clippy::question_mark",
5733 description: r##"Checks for expressions that could be replaced by the question mark operator."##,
5736 label: "clippy::range_minus_one",
5737 description: r##"Checks for inclusive ranges where 1 is subtracted from\nthe upper bound, e.g., `x..=(y-1)`."##,
5740 label: "clippy::range_plus_one",
5741 description: r##"Checks for exclusive ranges where 1 is added to the\nupper bound, e.g., `x..(y+1)`."##,
5744 label: "clippy::range_step_by_zero",
5745 description: r##"Nothing. This lint has been deprecated."##,
5748 label: "clippy::range_zip_with_len",
5749 description: r##"Checks for zipping a collection with the range of\n`0.._.len()`."##,
5752 label: "clippy::rc_buffer",
5753 description: r##"Checks for `Rc<T>` and `Arc<T>` when `T` is a mutable buffer type such as `String` or `Vec`."##,
5756 label: "clippy::redundant_allocation",
5757 description: r##"Checks for use of redundant allocations anywhere in the code."##,
5760 label: "clippy::redundant_clone",
5761 description: r##"Checks for a redundant `clone()` (and its relatives) which clones an owned\nvalue that is going to be dropped without further use."##,
5764 label: "clippy::redundant_closure",
5765 description: r##"Checks for closures which just call another function where\nthe function can be called directly. `unsafe` functions or calls where types\nget adjusted are ignored."##,
5768 label: "clippy::redundant_closure_call",
5769 description: r##"Detects closures called in the same expression where they\nare defined."##,
5772 label: "clippy::redundant_closure_for_method_calls",
5773 description: r##"Checks for closures which only invoke a method on the closure\nargument and can be replaced by referencing the method directly."##,
5776 label: "clippy::redundant_else",
5777 description: r##"Checks for `else` blocks that can be removed without changing semantics."##,
5780 label: "clippy::redundant_field_names",
5781 description: r##"Checks for fields in struct literals where shorthands\ncould be used."##,
5784 label: "clippy::redundant_pattern",
5785 description: r##"Checks for patterns in the form `name @ _`."##,
5788 label: "clippy::redundant_pattern_matching",
5789 description: r##"Lint for redundant pattern matching over `Result`, `Option`,\n`std::task::Poll` or `std::net::IpAddr`"##,
5792 label: "clippy::redundant_pub_crate",
5793 description: r##"Checks for items declared `pub(crate)` that are not crate visible because they\nare inside a private module."##,
5796 label: "clippy::redundant_slicing",
5797 description: r##"Checks for redundant slicing expressions which use the full range, and\ndo not change the type."##,
5800 label: "clippy::redundant_static_lifetimes",
5801 description: r##"Checks for constants and statics with an explicit `'static` lifetime."##,
5804 label: "clippy::ref_in_deref",
5805 description: r##"Checks for references in expressions that use\nauto dereference."##,
5808 label: "clippy::ref_option_ref",
5809 description: r##"Checks for usage of `&Option<&T>`."##,
5812 label: "clippy::regex_macro",
5813 description: r##"Nothing. This lint has been deprecated."##,
5816 label: "clippy::repeat_once",
5817 description: r##"Checks for usage of `.repeat(1)` and suggest the following method for each types.\n- `.to_string()` for `str`\n- `.clone()` for `String`\n- `.to_vec()` for `slice`"##,
5820 label: "clippy::replace_consts",
5821 description: r##"Nothing. This lint has been deprecated."##,
5824 label: "clippy::rest_pat_in_fully_bound_structs",
5825 description: r##"Checks for unnecessary '..' pattern binding on struct when all fields are explicitly matched."##,
5828 label: "clippy::result_map_or_into_option",
5829 description: r##"Checks for usage of `_.map_or(None, Some)`."##,
5832 label: "clippy::result_map_unit_fn",
5833 description: r##"Checks for usage of `result.map(f)` where f is a function\nor closure that returns the unit type `()`."##,
5836 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`]."##,
5840 label: "clippy::reversed_empty_ranges",
5841 description: r##"Checks for range expressions `x..y` where both `x` and `y`\nare constant and `x` is greater or equal to `y`."##,
5844 label: "clippy::same_functions_in_if_condition",
5845 description: r##"Checks for consecutive `if`s with the same function call."##,
5848 label: "clippy::same_item_push",
5849 description: r##"Checks whether a for loop is being used to push a constant\nvalue into a Vec."##,
5852 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()`."##,
5856 label: "clippy::self_assignment",
5857 description: r##"Checks for explicit self-assignments."##,
5860 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."##,
5864 label: "clippy::serde_api_misuse",
5865 description: r##"Checks for mis-uses of the serde API."##,
5868 label: "clippy::shadow_reuse",
5869 description: r##"Checks for bindings that shadow other bindings already in\nscope, while reusing the original value."##,
5872 label: "clippy::shadow_same",
5873 description: r##"Checks for bindings that shadow other bindings already in\nscope, while just changing reference level or mutability."##,
5876 label: "clippy::shadow_unrelated",
5877 description: r##"Checks for bindings that shadow other bindings already in\nscope, either without a initialization or with one that does not even use\nthe original value."##,
5880 label: "clippy::short_circuit_statement",
5881 description: r##"Checks for the use of short circuit boolean conditions as\na\nstatement."##,
5884 label: "clippy::should_assert_eq",
5885 description: r##"Nothing. This lint has been deprecated."##,
5888 label: "clippy::should_implement_trait",
5889 description: r##"Checks for methods that should live in a trait\nimplementation of a `std` trait (see [llogiq's blog\npost](http://llogiq.github.io/2015/07/30/traits.html) for further\ninformation) instead of an inherent implementation."##,
5892 label: "clippy::similar_names",
5893 description: r##"Checks for names that are very similar and thus confusing."##,
5896 label: "clippy::single_char_add_str",
5897 description: r##"Warns when using `push_str`/`insert_str` with a single-character string literal\nwhere `push`/`insert` with a `char` would work fine."##,
5900 label: "clippy::single_char_pattern",
5901 description: r##"Checks for string methods that receive a single-character\n`str` as an argument, e.g., `_.split(\"x\")`."##,
5904 label: "clippy::single_component_path_imports",
5905 description: r##"Checking for imports with single component use path."##,
5908 label: "clippy::single_element_loop",
5909 description: r##"Checks whether a for loop has a single element."##,
5912 label: "clippy::single_match",
5913 description: r##"Checks for matches with a single arm where an `if let`\nwill usually suffice."##,
5916 label: "clippy::single_match_else",
5917 description: r##"Checks for matches with two arms where an `if let else` will\nusually suffice."##,
5920 label: "clippy::size_of_in_element_count",
5921 description: r##"Detects expressions where\n`size_of::<T>` or `size_of_val::<T>` is used as a\ncount of elements of type `T`"##,
5924 label: "clippy::skip_while_next",
5925 description: r##"Checks for usage of `_.skip_while(condition).next()`."##,
5928 label: "clippy::slow_vector_initialization",
5929 description: r##"Checks slow zero-filled vector initialization"##,
5932 label: "clippy::stable_sort_primitive",
5933 description: r##"When sorting primitive values (integers, bools, chars, as well\nas arrays, slices, and tuples of such items), it is better to\nuse an unstable sort than a stable sort."##,
5936 label: "clippy::str_to_string",
5937 description: r##"This lint checks for `.to_string()` method calls on values of type `&str`."##,
5940 label: "clippy::string_add",
5941 description: r##"Checks for all instances of `x + _` where `x` is of type\n`String`, but only if [`string_add_assign`](#string_add_assign) does *not*\nmatch."##,
5944 label: "clippy::string_add_assign",
5945 description: r##"Checks for string appends of the form `x = x + y` (without\n`let`!)."##,
5948 label: "clippy::string_extend_chars",
5949 description: r##"Checks for the use of `.extend(s.chars())` where s is a\n`&str` or `String`."##,
5952 label: "clippy::string_from_utf8_as_bytes",
5953 description: r##"Check if the string is transformed to byte array and casted back to string."##,
5956 label: "clippy::string_lit_as_bytes",
5957 description: r##"Checks for the `as_bytes` method called on string literals\nthat contain only ASCII characters."##,
5960 label: "clippy::string_to_string",
5961 description: r##"This lint checks for `.to_string()` method calls on values of type `String`."##,
5964 label: "clippy::struct_excessive_bools",
5965 description: r##"Checks for excessive\nuse of bools in structs."##,
5968 label: "clippy::suboptimal_flops",
5969 description: r##"Looks for floating-point expressions that\ncan be expressed using built-in methods to improve both\naccuracy and performance."##,
5972 label: "clippy::suspicious_arithmetic_impl",
5973 description: r##"Lints for suspicious operations in impls of arithmetic operators, e.g.\nsubtracting elements in an Add impl."##,
5976 label: "clippy::suspicious_assignment_formatting",
5977 description: r##"Checks for use of the non-existent `=*`, `=!` and `=-`\noperators."##,
5980 label: "clippy::suspicious_else_formatting",
5981 description: r##"Checks for formatting of `else`. It lints if the `else`\nis followed immediately by a newline or the `else` seems to be missing."##,
5984 label: "clippy::suspicious_map",
5985 description: r##"Checks for calls to `map` followed by a `count`."##,
5988 label: "clippy::suspicious_op_assign_impl",
5989 description: r##"Lints for suspicious operations in impls of OpAssign, e.g.\nsubtracting elements in an AddAssign impl."##,
5992 label: "clippy::suspicious_operation_groupings",
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."##,
5996 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."##,
6000 label: "clippy::tabs_in_doc_comments",
6001 description: r##"Checks doc comments for usage of tab characters."##,
6004 label: "clippy::temporary_assignment",
6005 description: r##"Checks for construction of a structure or tuple just to\nassign a value in it."##,
6008 label: "clippy::temporary_cstring_as_ptr",
6009 description: r##"Nothing. This lint has been deprecated."##,
6012 label: "clippy::to_digit_is_some",
6013 description: r##"Checks for `.to_digit(..).is_some()` on `char`s."##,
6016 label: "clippy::to_string_in_display",
6017 description: r##"Checks for uses of `to_string()` in `Display` traits."##,
6019 LintCompletion { label: "clippy::todo", description: r##"Checks for usage of `todo!`."## },
6021 label: "clippy::too_many_arguments",
6022 description: r##"Checks for functions with too many parameters."##,
6025 label: "clippy::too_many_lines",
6026 description: r##"Checks for functions with a large amount of lines."##,
6029 label: "clippy::toplevel_ref_arg",
6030 description: r##"Checks for function arguments and let bindings denoted as\n`ref`."##,
6033 label: "clippy::trait_duplication_in_bounds",
6034 description: r##"Checks for cases where generics are being used and multiple\nsyntax specifications for trait bounds are used simultaneously."##,
6037 label: "clippy::transmute_bytes_to_str",
6038 description: r##"Checks for transmutes from a `&[u8]` to a `&str`."##,
6041 label: "clippy::transmute_float_to_int",
6042 description: r##"Checks for transmutes from a float to an integer."##,
6045 label: "clippy::transmute_int_to_bool",
6046 description: r##"Checks for transmutes from an integer to a `bool`."##,
6049 label: "clippy::transmute_int_to_char",
6050 description: r##"Checks for transmutes from an integer to a `char`."##,
6053 label: "clippy::transmute_int_to_float",
6054 description: r##"Checks for transmutes from an integer to a float."##,
6057 label: "clippy::transmute_ptr_to_ptr",
6058 description: r##"Checks for transmutes from a pointer to a pointer, or\nfrom a reference to a reference."##,
6061 label: "clippy::transmute_ptr_to_ref",
6062 description: r##"Checks for transmutes from a pointer to a reference."##,
6065 label: "clippy::transmutes_expressible_as_ptr_casts",
6066 description: r##"Checks for transmutes that could be a pointer cast."##,
6069 label: "clippy::transmuting_null",
6070 description: r##"Checks for transmute calls which would receive a null pointer."##,
6073 label: "clippy::trivial_regex",
6074 description: r##"Checks for trivial [regex](https://crates.io/crates/regex)\ncreation (with `Regex::new`, `RegexBuilder::new`, or `RegexSet::new`)."##,
6077 label: "clippy::trivially_copy_pass_by_ref",
6078 description: r##"Checks for functions taking arguments by reference, where\nthe argument type is `Copy` and small enough to be more efficient to always\npass by value."##,
6081 label: "clippy::try_err",
6082 description: r##"Checks for usages of `Err(x)?`."##,
6085 label: "clippy::type_complexity",
6086 description: r##"Checks for types used in structs, parameters and `let`\ndeclarations above a certain complexity threshold."##,
6089 label: "clippy::type_repetition_in_bounds",
6090 description: r##"This lint warns about unnecessary type repetitions in trait bounds"##,
6093 label: "clippy::undropped_manually_drops",
6094 description: r##"Prevents the safe `std::mem::drop` function from being called on `std::mem::ManuallyDrop`."##,
6097 label: "clippy::unicode_not_nfc",
6098 description: r##"Checks for string literals that contain Unicode in a form\nthat is not equal to its\n[NFC-recomposition](http://www.unicode.org/reports/tr15/#Norm_Forms)."##,
6101 label: "clippy::unimplemented",
6102 description: r##"Checks for usage of `unimplemented!`."##,
6105 label: "clippy::uninit_assumed_init",
6106 description: r##"Checks for `MaybeUninit::uninit().assume_init()`."##,
6109 label: "clippy::unit_arg",
6110 description: r##"Checks for passing a unit value as an argument to a function without using a\nunit literal (`()`)."##,
6113 label: "clippy::unit_cmp",
6114 description: r##"Checks for comparisons to unit. This includes all binary\ncomparisons (like `==` and `<`) and asserts."##,
6117 label: "clippy::unit_return_expecting_ord",
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."##,
6121 label: "clippy::unknown_clippy_lints",
6122 description: r##"Nothing. This lint has been deprecated."##,
6125 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."##,
6129 label: "clippy::unnecessary_filter_map",
6130 description: r##"Checks for `filter_map` calls which could be replaced by `filter` or `map`.\nMore specifically it checks if the closure provided is only performing one of the\nfilter or map operations and suggests the appropriate option."##,
6133 label: "clippy::unnecessary_fold",
6134 description: r##"Checks for using `fold` when a more succinct alternative exists.\nSpecifically, this checks for `fold`s which could be replaced by `any`, `all`,\n`sum` or `product`."##,
6137 label: "clippy::unnecessary_lazy_evaluations",
6138 description: r##"As the counterpart to `or_fun_call`, this lint looks for unnecessary\nlazily evaluated closures on `Option` and `Result`.\n\nThis lint suggests changing the following functions, when eager evaluation results in\nsimpler code:\n - `unwrap_or_else` to `unwrap_or`\n - `and_then` to `and`\n - `or_else` to `or`\n - `get_or_insert_with` to `get_or_insert`\n - `ok_or_else` to `ok_or`"##,
6141 label: "clippy::unnecessary_mut_passed",
6142 description: r##"Detects passing a mutable reference to a function that only\nrequires an immutable reference."##,
6145 label: "clippy::unnecessary_operation",
6146 description: r##"Checks for expression statements that can be reduced to a\nsub-expression."##,
6149 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."##,
6153 label: "clippy::unnecessary_unwrap",
6154 description: r##"Checks for calls of `unwrap[_err]()` that cannot fail."##,
6157 label: "clippy::unnecessary_wraps",
6158 description: r##"Checks for private functions that only return `Ok` or `Some`."##,
6161 label: "clippy::unneeded_field_pattern",
6162 description: r##"Checks for structure field patterns bound to wildcards."##,
6165 label: "clippy::unneeded_wildcard_pattern",
6166 description: r##"Checks for tuple patterns with a wildcard\npattern (`_`) is next to a rest pattern (`..`).\n\n_NOTE_: While `_, ..` means there is at least one element left, `..`\nmeans there are 0 or more elements left. This can make a difference\nwhen refactoring, but shouldn't result in errors in the refactored code,\nsince the wildcard pattern isn't used anyway."##,
6169 label: "clippy::unnested_or_patterns",
6170 description: r##"Checks for unnested or-patterns, e.g., `Some(0) | Some(2)` and\nsuggests replacing the pattern with a nested one, `Some(0 | 2)`.\n\nAnother way to think of this is that it rewrites patterns in\n*disjunctive normal form (DNF)* into *conjunctive normal form (CNF)*."##,
6173 label: "clippy::unreachable",
6174 description: r##"Checks for usage of `unreachable!`."##,
6177 label: "clippy::unreadable_literal",
6178 description: r##"Warns if a long integral or floating-point constant does\nnot contain underscores."##,
6181 label: "clippy::unsafe_derive_deserialize",
6182 description: r##"Checks for deriving `serde::Deserialize` on a type that\nhas methods using `unsafe`."##,
6185 label: "clippy::unsafe_removed_from_name",
6186 description: r##"Checks for imports that remove \"unsafe\" from an item's\nname."##,
6189 label: "clippy::unsafe_vector_initialization",
6190 description: r##"Nothing. This lint has been deprecated."##,
6193 label: "clippy::unseparated_literal_suffix",
6194 description: r##"Warns if literal suffixes are not separated by an\nunderscore."##,
6197 label: "clippy::unsound_collection_transmute",
6198 description: r##"Checks for transmutes between collections whose\ntypes have different ABI, size or alignment."##,
6201 label: "clippy::unstable_as_mut_slice",
6202 description: r##"Nothing. This lint has been deprecated."##,
6205 label: "clippy::unstable_as_slice",
6206 description: r##"Nothing. This lint has been deprecated."##,
6209 label: "clippy::unused_collect",
6210 description: r##"Nothing. This lint has been deprecated."##,
6213 label: "clippy::unused_io_amount",
6214 description: r##"Checks for unused written/read amount."##,
6217 label: "clippy::unused_label",
6218 description: r##"Nothing. This lint has been deprecated."##,
6221 label: "clippy::unused_self",
6222 description: r##"Checks methods that contain a `self` argument but don't use it"##,
6225 label: "clippy::unused_unit",
6226 description: r##"Checks for unit (`()`) expressions that can be removed."##,
6229 label: "clippy::unusual_byte_groupings",
6230 description: r##"Warns if hexadecimal or binary literals are not grouped\nby nibble or byte."##,
6233 label: "clippy::unwrap_in_result",
6234 description: r##"Checks for functions of type Result that contain `expect()` or `unwrap()`"##,
6237 label: "clippy::unwrap_used",
6238 description: r##"Checks for `.unwrap()` calls on `Option`s and on `Result`s."##,
6241 label: "clippy::upper_case_acronyms",
6242 description: r##"Checks for fully capitalized names and optionally names containing a capitalized acronym."##,
6245 label: "clippy::use_debug",
6246 description: r##"Checks for use of `Debug` formatting. The purpose of this\nlint is to catch debugging remnants."##,
6249 label: "clippy::use_self",
6250 description: r##"Checks for unnecessary repetition of structure name when a\nreplacement with `Self` is applicable."##,
6253 label: "clippy::used_underscore_binding",
6254 description: r##"Checks for the use of bindings with a single leading\nunderscore."##,
6257 label: "clippy::useless_asref",
6258 description: r##"Checks for usage of `.as_ref()` or `.as_mut()` where the\ntypes before and after the call are the same."##,
6261 label: "clippy::useless_attribute",
6262 description: r##"Checks for `extern crate` and `use` items annotated with\nlint attributes.\n\nThis lint permits `#[allow(unused_imports)]`, `#[allow(deprecated)]`,\n`#[allow(unreachable_pub)]`, `#[allow(clippy::wildcard_imports)]` and\n`#[allow(clippy::enum_glob_use)]` on `use` items and `#[allow(unused_imports)]` on\n`extern crate` items with a `#[macro_use]` attribute."##,
6265 label: "clippy::useless_conversion",
6266 description: r##"Checks for `Into`, `TryInto`, `From`, `TryFrom`, or `IntoIter` calls\nwhich uselessly convert to the same type."##,
6269 label: "clippy::useless_format",
6270 description: r##"Checks for the use of `format!(\"string literal with no\nargument\")` and `format!(\"{}\", foo)` where `foo` is a string."##,
6273 label: "clippy::useless_let_if_seq",
6274 description: r##"Checks for variable declarations immediately followed by a\nconditional affectation."##,
6277 label: "clippy::useless_transmute",
6278 description: r##"Checks for transmutes to the original type of the object\nand transmutes that could be a cast."##,
6281 label: "clippy::useless_vec",
6282 description: r##"Checks for usage of `&vec![..]` when using `&[..]` would\nbe possible."##,
6285 label: "clippy::vec_box",
6286 description: r##"Checks for use of `Vec<Box<T>>` where T: Sized anywhere in the code.\nCheck the [Box documentation](https://doc.rust-lang.org/std/boxed/index.html) for more information."##,
6289 label: "clippy::vec_init_then_push",
6290 description: r##"Checks for calls to `push` immediately after creating a new `Vec`."##,
6293 label: "clippy::vec_resize_to_zero",
6294 description: r##"Finds occurrences of `Vec::resize(0, an_int)`"##,
6297 label: "clippy::verbose_bit_mask",
6298 description: r##"Checks for bit masks that can be replaced by a call\nto `trailing_zeros`"##,
6301 label: "clippy::verbose_file_reads",
6302 description: r##"Checks for use of File::read_to_end and File::read_to_string."##,
6305 label: "clippy::vtable_address_comparisons",
6306 description: r##"Checks for comparisons with an address of a trait vtable."##,
6309 label: "clippy::while_immutable_condition",
6310 description: r##"Checks whether variables used within while loop condition\ncan be (and are) mutated in the body."##,
6313 label: "clippy::while_let_loop",
6314 description: r##"Detects `loop + match` combinations that are easier\nwritten as a `while let` loop."##,
6317 label: "clippy::while_let_on_iterator",
6318 description: r##"Checks for `while let` expressions on iterators."##,
6321 label: "clippy::wildcard_dependencies",
6322 description: r##"Checks for wildcard dependencies in the `Cargo.toml`."##,
6325 label: "clippy::wildcard_enum_match_arm",
6326 description: r##"Checks for wildcard enum matches using `_`."##,
6329 label: "clippy::wildcard_imports",
6330 description: r##"Checks for wildcard imports `use _::*`."##,
6333 label: "clippy::wildcard_in_or_patterns",
6334 description: r##"Checks for wildcard pattern used with others patterns in same match arm."##,
6337 label: "clippy::write_literal",
6338 description: r##"This lint warns about the use of literals as `write!`/`writeln!` args."##,
6341 label: "clippy::write_with_newline",
6342 description: r##"This lint warns when you use `write!()` with a format\nstring that\nends in a newline."##,
6345 label: "clippy::writeln_empty_string",
6346 description: r##"This lint warns when you use `writeln!(buf, \"\")` to\nprint a newline."##,
6349 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."##,
6353 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` |"##,
6357 label: "clippy::wrong_transmute",
6358 description: r##"Checks for transmutes that can't ever be correct on any\narchitecture."##,
6361 label: "clippy::zero_divided_by_zero",
6362 description: r##"Checks for `0.0 / 0.0`."##,
6365 label: "clippy::zero_prefixed_literal",
6366 description: r##"Warns if an integral constant literal starts with `0`."##,
6369 label: "clippy::zero_ptr",
6370 description: r##"Catch casts from `0` to some pointer type"##,
6373 label: "clippy::zero_sized_map_values",
6374 description: r##"Checks for maps with zero-sized value types anywhere in the code."##,
6377 label: "clippy::zst_offset",
6378 description: r##"Checks for `offset(_)`, `wrapping_`{`add`, `sub`}, etc. on raw pointers to\nzero-sized types"##,