aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_completion/src/generated_lint_completions.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide_completion/src/generated_lint_completions.rs')
-rw-r--r--crates/ide_completion/src/generated_lint_completions.rs6380
1 files changed, 0 insertions, 6380 deletions
diff --git a/crates/ide_completion/src/generated_lint_completions.rs b/crates/ide_completion/src/generated_lint_completions.rs
deleted file mode 100644
index 0d405350d..000000000
--- a/crates/ide_completion/src/generated_lint_completions.rs
+++ /dev/null
@@ -1,6380 +0,0 @@
1//! Generated file, do not edit by hand, see `xtask/src/codegen`
2
3use crate::completions::attribute::LintCompletion;
4pub(super) const FEATURES: &[LintCompletion] = &[
5 LintCompletion {
6 label: "plugin_registrar",
7 description: r##"# `plugin_registrar`
8
9The tracking issue for this feature is: [#29597]
10
11[#29597]: https://github.com/rust-lang/rust/issues/29597
12
13This feature is part of "compiler plugins." It will often be used with the
14[`plugin`] and `rustc_private` features as well. For more details, see
15their docs.
16
17[`plugin`]: plugin.md
18
19------------------------
20"##,
21 },
22 LintCompletion {
23 label: "inline_const",
24 description: r##"# `inline_const`
25
26The tracking issue for this feature is: [#76001]
27
28------
29
30This feature allows you to use inline constant expressions. For example, you can
31turn this code:
32
33```rust
34# fn add_one(x: i32) -> i32 { x + 1 }
35const MY_COMPUTATION: i32 = 1 + 2 * 3 / 4;
36
37fn main() {
38 let x = add_one(MY_COMPUTATION);
39}
40```
41
42into this code:
43
44```rust
45#![feature(inline_const)]
46
47# fn add_one(x: i32) -> i32 { x + 1 }
48fn main() {
49 let x = add_one(const { 1 + 2 * 3 / 4 });
50}
51```
52
53You can also use inline constant expressions in patterns:
54
55```rust
56#![feature(inline_const)]
57
58const fn one() -> i32 { 1 }
59
60let some_int = 3;
61match some_int {
62 const { 1 + 2 } => println!("Matched 1 + 2"),
63 const { one() } => println!("Matched const fn returning 1"),
64 _ => println!("Didn't match anything :("),
65}
66```
67
68[#76001]: https://github.com/rust-lang/rust/issues/76001
69"##,
70 },
71 LintCompletion {
72 label: "auto_traits",
73 description: r##"# `auto_traits`
74
75The tracking issue for this feature is [#13231]
76
77[#13231]: https://github.com/rust-lang/rust/issues/13231
78
79----
80
81The `auto_traits` feature gate allows you to define auto traits.
82
83Auto traits, like [`Send`] or [`Sync`] in the standard library, are marker traits
84that are automatically implemented for every type, unless the type, or a type it contains,
85has explicitly opted out via a negative impl. (Negative impls are separately controlled
86by the `negative_impls` feature.)
87
88[`Send`]: https://doc.rust-lang.org/std/marker/trait.Send.html
89[`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html
90
91```rust,ignore (partial-example)
92impl !Trait for Type {}
93```
94
95Example:
96
97```rust
98#![feature(negative_impls)]
99#![feature(auto_traits)]
100
101auto trait Valid {}
102
103struct True;
104struct False;
105
106impl !Valid for False {}
107
108struct MaybeValid<T>(T);
109
110fn must_be_valid<T: Valid>(_t: T) { }
111
112fn main() {
113 // works
114 must_be_valid( MaybeValid(True) );
115
116 // compiler error - trait bound not satisfied
117 // must_be_valid( MaybeValid(False) );
118}
119```
120
121## Automatic trait implementations
122
123When a type is declared as an `auto trait`, we will automatically
124create impls for every struct/enum/union, unless an explicit impl is
125provided. These automatic impls contain a where clause for each field
126of the form `T: AutoTrait`, where `T` is the type of the field and
127`AutoTrait` is the auto trait in question. As an example, consider the
128struct `List` and the auto trait `Send`:
129
130```rust
131struct List<T> {
132 data: T,
133 next: Option<Box<List<T>>>,
134}
135```
136
137Presuming that there is no explicit impl of `Send` for `List`, the
138compiler will supply an automatic impl of the form:
139
140```rust
141struct List<T> {
142 data: T,
143 next: Option<Box<List<T>>>,
144}
145
146unsafe impl<T> Send for List<T>
147where
148 T: Send, // from the field `data`
149 Option<Box<List<T>>>: Send, // from the field `next`
150{ }
151```
152
153Explicit impls may be either positive or negative. They take the form:
154
155```rust,ignore (partial-example)
156impl<...> AutoTrait for StructName<..> { }
157impl<...> !AutoTrait for StructName<..> { }
158```
159
160## Coinduction: Auto traits permit cyclic matching
161
162Unlike ordinary trait matching, auto traits are **coinductive**. This
163means, in short, that cycles which occur in trait matching are
164considered ok. As an example, consider the recursive struct `List`
165introduced in the previous section. In attempting to determine whether
166`List: Send`, we would wind up in a cycle: to apply the impl, we must
167show that `Option<Box<List>>: Send`, which will in turn require
168`Box<List>: Send` and then finally `List: Send` again. Under ordinary
169trait matching, this cycle would be an error, but for an auto trait it
170is considered a successful match.
171
172## Items
173
174Auto traits cannot have any trait items, such as methods or associated types. This ensures that we can generate default implementations.
175
176## Supertraits
177
178Auto traits cannot have supertraits. This is for soundness reasons, as the interaction of coinduction with implied bounds is difficult to reconcile.
179"##,
180 },
181 LintCompletion {
182 label: "ffi_const",
183 description: r##"# `ffi_const`
184
185The tracking issue for this feature is: [#58328]
186
187------
188
189The `#[ffi_const]` attribute applies clang's `const` attribute to foreign
190functions declarations.
191
192That is, `#[ffi_const]` functions shall have no effects except for its return
193value, which can only depend on the values of the function parameters, and is
194not affected by changes to the observable state of the program.
195
196Applying the `#[ffi_const]` attribute to a function that violates these
197requirements is undefined behaviour.
198
199This attribute enables Rust to perform common optimizations, like sub-expression
200elimination, and it can avoid emitting some calls in repeated invocations of the
201function with the same argument values regardless of other operations being
202performed in between these functions calls (as opposed to `#[ffi_pure]`
203functions).
204
205## Pitfalls
206
207A `#[ffi_const]` function can only read global memory that would not affect
208its return value for the whole execution of the program (e.g. immutable global
209memory). `#[ffi_const]` functions are referentially-transparent and therefore
210more strict than `#[ffi_pure]` functions.
211
212A common pitfall involves applying the `#[ffi_const]` attribute to a
213function that reads memory through pointer arguments which do not necessarily
214point to immutable global memory.
215
216A `#[ffi_const]` function that returns unit has no effect on the abstract
217machine's state, and a `#[ffi_const]` function cannot be `#[ffi_pure]`.
218
219A `#[ffi_const]` function must not diverge, neither via a side effect (e.g. a
220call to `abort`) nor by infinite loops.
221
222When translating C headers to Rust FFI, it is worth verifying for which targets
223the `const` attribute is enabled in those headers, and using the appropriate
224`cfg` macros in the Rust side to match those definitions. While the semantics of
225`const` are implemented identically by many C and C++ compilers, e.g., clang,
226[GCC], [ARM C/C++ compiler], [IBM ILE C/C++], etc. they are not necessarily
227implemented in this way on all of them. It is therefore also worth verifying
228that the semantics of the C toolchain used to compile the binary being linked
229against are compatible with those of the `#[ffi_const]`.
230
231[#58328]: https://github.com/rust-lang/rust/issues/58328
232[ARM C/C++ compiler]: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0491c/Cacgigch.html
233[GCC]: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-const-function-attribute
234[IBM ILE C/C++]: https://www.ibm.com/support/knowledgecenter/fr/ssw_ibm_i_71/rzarg/fn_attrib_const.htm
235"##,
236 },
237 LintCompletion {
238 label: "external_doc",
239 description: r##"# `external_doc`
240
241The tracking issue for this feature is: [#44732]
242
243The `external_doc` feature allows the use of the `include` parameter to the `#[doc]` attribute, to
244include external files in documentation. Use the attribute in place of, or in addition to, regular
245doc comments and `#[doc]` attributes, and `rustdoc` will load the given file when it renders
246documentation for your crate.
247
248With the following files in the same directory:
249
250`external-doc.md`:
251
252```markdown
253# My Awesome Type
254
255This is the documentation for this spectacular type.
256```
257
258`lib.rs`:
259
260```no_run (needs-external-files)
261#![feature(external_doc)]
262
263#[doc(include = "external-doc.md")]
264pub struct MyAwesomeType;
265```
266
267`rustdoc` will load the file `external-doc.md` and use it as the documentation for the `MyAwesomeType`
268struct.
269
270When locating files, `rustdoc` will base paths in the `src/` directory, as if they were alongside the
271`lib.rs` for your crate. So if you want a `docs/` folder to live alongside the `src/` directory,
272start your paths with `../docs/` for `rustdoc` to properly find the file.
273
274This feature was proposed in [RFC #1990] and initially implemented in PR [#44781].
275
276[#44732]: https://github.com/rust-lang/rust/issues/44732
277[RFC #1990]: https://github.com/rust-lang/rfcs/pull/1990
278[#44781]: https://github.com/rust-lang/rust/pull/44781
279"##,
280 },
281 LintCompletion {
282 label: "box_patterns",
283 description: r##"# `box_patterns`
284
285The tracking issue for this feature is: [#29641]
286
287[#29641]: https://github.com/rust-lang/rust/issues/29641
288
289See also [`box_syntax`](box-syntax.md)
290
291------------------------
292
293Box patterns let you match on `Box<T>`s:
294
295
296```rust
297#![feature(box_patterns)]
298
299fn main() {
300 let b = Some(Box::new(5));
301 match b {
302 Some(box n) if n < 0 => {
303 println!("Box contains negative number {}", n);
304 },
305 Some(box n) if n >= 0 => {
306 println!("Box contains non-negative number {}", n);
307 },
308 None => {
309 println!("No box");
310 },
311 _ => unreachable!()
312 }
313}
314```
315"##,
316 },
317 LintCompletion {
318 label: "abi_c_cmse_nonsecure_call",
319 description: r##"# `abi_c_cmse_nonsecure_call`
320
321The tracking issue for this feature is: [#81391]
322
323[#81391]: https://github.com/rust-lang/rust/issues/81391
324
325------------------------
326
327The [TrustZone-M
328feature](https://developer.arm.com/documentation/100690/latest/) is available
329for targets with the Armv8-M architecture profile (`thumbv8m` in their target
330name).
331LLVM, the Rust compiler and the linker are providing
332[support](https://developer.arm.com/documentation/ecm0359818/latest/) for the
333TrustZone-M feature.
334
335One 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
337non-secure code to mark a non-secure function call (see [section
3385.5](https://developer.arm.com/documentation/ecm0359818/latest/) for details).
339
340With 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
345
346To avoid using the non-secure stack, the compiler will constrain the number and
347type of parameters/return value.
348
349The `extern "C-cmse-nonsecure-call"` ABI is otherwise equivalent to the
350`extern "C"` ABI.
351
352<!-- NOTE(ignore) this example is specific to thumbv8m targets -->
353
354``` rust,ignore
355#![no_std]
356#![feature(abi_c_cmse_nonsecure_call)]
357
358#[no_mangle]
359pub 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()
363}
364```
365
366``` text
367$ rustc --emit asm --crate-type lib --target thumbv8m.main-none-eabi function.rs
368
369call_nonsecure_function:
370 .fnstart
371 .save {r7, lr}
372 push {r7, lr}
373 .setfp r7, sp
374 mov r7, sp
375 .pad #16
376 sub sp, #16
377 str r0, [sp, #12]
378 ldr r0, [sp, #12]
379 str r0, [sp, #8]
380 b .LBB0_1
381.LBB0_1:
382 ldr r0, [sp, #8]
383 push.w {r4, r5, r6, r7, r8, r9, r10, r11}
384 bic r0, r0, #1
385 mov r1, r0
386 mov r2, r0
387 mov r3, r0
388 mov r4, r0
389 mov r5, r0
390 mov r6, r0
391 mov r7, r0
392 mov r8, r0
393 mov r9, r0
394 mov r10, r0
395 mov r11, r0
396 mov r12, r0
397 msr apsr_nzcvq, r0
398 blxns r0
399 pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
400 str r0, [sp, #4]
401 b .LBB0_2
402.LBB0_2:
403 ldr r0, [sp, #4]
404 add sp, #16
405 pop {r7, pc}
406```
407"##,
408 },
409 LintCompletion {
410 label: "member_constraints",
411 description: r##"# `member_constraints`
412
413The tracking issue for this feature is: [#61997]
414
415[#61997]: https://github.com/rust-lang/rust/issues/61997
416
417------------------------
418
419The `member_constraints` feature gate lets you use `impl Trait` syntax with
420multiple unrelated lifetime parameters.
421
422A simple example is:
423
424```rust
425#![feature(member_constraints)]
426
427trait Trait<'a, 'b> { }
428impl<T> Trait<'_, '_> for T {}
429
430fn foo<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Trait<'a, 'b> {
431 (x, y)
432}
433
434fn main() { }
435```
436
437Without the `member_constraints` feature gate, the above example is an
438error because both `'a` and `'b` appear in the impl Trait bounds, but
439neither outlives the other.
440"##,
441 },
442 LintCompletion {
443 label: "allocator_internals",
444 description: r##"# `allocator_internals`
445
446This feature does not have a tracking issue, it is an unstable implementation
447detail of the `global_allocator` feature not intended for use outside the
448compiler.
449
450------------------------
451"##,
452 },
453 LintCompletion {
454 label: "cfg_sanitize",
455 description: r##"# `cfg_sanitize`
456
457The tracking issue for this feature is: [#39699]
458
459[#39699]: https://github.com/rust-lang/rust/issues/39699
460
461------------------------
462
463The `cfg_sanitize` feature makes it possible to execute different code
464depending on whether a particular sanitizer is enabled or not.
465
466## Examples
467
468```rust
469#![feature(cfg_sanitize)]
470
471#[cfg(sanitize = "thread")]
472fn a() {
473 // ...
474}
475
476#[cfg(not(sanitize = "thread"))]
477fn a() {
478 // ...
479}
480
481fn b() {
482 if cfg!(sanitize = "leak") {
483 // ...
484 } else {
485 // ...
486 }
487}
488```
489"##,
490 },
491 LintCompletion {
492 label: "cfg_panic",
493 description: r##"# `cfg_panic`
494
495The tracking issue for this feature is: [#77443]
496
497[#77443]: https://github.com/rust-lang/rust/issues/77443
498
499------------------------
500
501The `cfg_panic` feature makes it possible to execute different code
502depending on the panic strategy.
503
504Possible values at the moment are `"unwind"` or `"abort"`, although
505it is possible that new panic strategies may be added to Rust in the
506future.
507
508## Examples
509
510```rust
511#![feature(cfg_panic)]
512
513#[cfg(panic = "unwind")]
514fn a() {
515 // ...
516}
517
518#[cfg(not(panic = "unwind"))]
519fn a() {
520 // ...
521}
522
523fn b() {
524 if cfg!(panic = "abort") {
525 // ...
526 } else {
527 // ...
528 }
529}
530```
531"##,
532 },
533 LintCompletion {
534 label: "ffi_pure",
535 description: r##"# `ffi_pure`
536
537The tracking issue for this feature is: [#58329]
538
539------
540
541The `#[ffi_pure]` attribute applies clang's `pure` attribute to foreign
542functions declarations.
543
544That is, `#[ffi_pure]` functions shall have no effects except for its return
545value, which shall not change across two consecutive function calls with
546the same parameters.
547
548Applying the `#[ffi_pure]` attribute to a function that violates these
549requirements is undefined behavior.
550
551This attribute enables Rust to perform common optimizations, like sub-expression
552elimination and loop optimizations. Some common examples of pure functions are
553`strlen` or `memcmp`.
554
555These optimizations are only applicable when the compiler can prove that no
556program state observable by the `#[ffi_pure]` function has changed between calls
557of the function, which could alter the result. See also the `#[ffi_const]`
558attribute, which provides stronger guarantees regarding the allowable behavior
559of a function, enabling further optimization.
560
561## Pitfalls
562
563A `#[ffi_pure]` function can read global memory through the function
564parameters (e.g. pointers), globals, etc. `#[ffi_pure]` functions are not
565referentially-transparent, and are therefore more relaxed than `#[ffi_const]`
566functions.
567
568However, accessing global memory through volatile or atomic reads can violate the
569requirement that two consecutive function calls shall return the same value.
570
571A `pure` function that returns unit has no effect on the abstract machine's
572state.
573
574A `#[ffi_pure]` function must not diverge, neither via a side effect (e.g. a
575call to `abort`) nor by infinite loops.
576
577When translating C headers to Rust FFI, it is worth verifying for which targets
578the `pure` attribute is enabled in those headers, and using the appropriate
579`cfg` macros in the Rust side to match those definitions. While the semantics of
580`pure` are implemented identically by many C and C++ compilers, e.g., clang,
581[GCC], [ARM C/C++ compiler], [IBM ILE C/C++], etc. they are not necessarily
582implemented in this way on all of them. It is therefore also worth verifying
583that the semantics of the C toolchain used to compile the binary being linked
584against are compatible with those of the `#[ffi_pure]`.
585
586
587[#58329]: https://github.com/rust-lang/rust/issues/58329
588[ARM C/C++ compiler]: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0491c/Cacigdac.html
589[GCC]: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-pure-function-attribute
590[IBM ILE C/C++]: https://www.ibm.com/support/knowledgecenter/fr/ssw_ibm_i_71/rzarg/fn_attrib_pure.htm
591"##,
592 },
593 LintCompletion {
594 label: "repr128",
595 description: r##"# `repr128`
596
597The tracking issue for this feature is: [#56071]
598
599[#56071]: https://github.com/rust-lang/rust/issues/56071
600
601------------------------
602
603The `repr128` feature adds support for `#[repr(u128)]` on `enum`s.
604
605```rust
606#![feature(repr128)]
607
608#[repr(u128)]
609enum Foo {
610 Bar(u64),
611}
612```
613"##,
614 },
615 LintCompletion {
616 label: "generators",
617 description: r##"# `generators`
618
619The tracking issue for this feature is: [#43122]
620
621[#43122]: https://github.com/rust-lang/rust/issues/43122
622
623------------------------
624
625The `generators` feature gate in Rust allows you to define generator or
626coroutine literals. A generator is a "resumable function" that syntactically
627resembles a closure but compiles to much different semantics in the compiler
628itself. The primary feature of a generator is that it can be suspended during
629execution to be resumed at a later date. Generators use the `yield` keyword to
630"return", and then the caller can `resume` a generator to resume execution just
631after the `yield` keyword.
632
633Generators are an extra-unstable feature in the compiler right now. Added in
634[RFC 2033] they're mostly intended right now as a information/constraint
635gathering phase. The intent is that experimentation can happen on the nightly
636compiler before actual stabilization. A further RFC will be required to
637stabilize generators/coroutines and will likely contain at least a few small
638tweaks to the overall design.
639
640[RFC 2033]: https://github.com/rust-lang/rfcs/pull/2033
641
642A syntactical example of a generator is:
643
644```rust
645#![feature(generators, generator_trait)]
646
647use std::ops::{Generator, GeneratorState};
648use std::pin::Pin;
649
650fn main() {
651 let mut generator = || {
652 yield 1;
653 return "foo"
654 };
655
656 match Pin::new(&mut generator).resume(()) {
657 GeneratorState::Yielded(1) => {}
658 _ => panic!("unexpected value from resume"),
659 }
660 match Pin::new(&mut generator).resume(()) {
661 GeneratorState::Complete("foo") => {}
662 _ => panic!("unexpected value from resume"),
663 }
664}
665```
666
667Generators are closure-like literals which can contain a `yield` statement. The
668`yield` statement takes an optional expression of a value to yield out of the
669generator. All generator literals implement the `Generator` trait in the
670`std::ops` module. The `Generator` trait has one main method, `resume`, which
671resumes execution of the generator at the previous suspension point.
672
673An example of the control flow of generators is that the following example
674prints all numbers in order:
675
676```rust
677#![feature(generators, generator_trait)]
678
679use std::ops::Generator;
680use std::pin::Pin;
681
682fn main() {
683 let mut generator = || {
684 println!("2");
685 yield;
686 println!("4");
687 };
688
689 println!("1");
690 Pin::new(&mut generator).resume(());
691 println!("3");
692 Pin::new(&mut generator).resume(());
693 println!("5");
694}
695```
696
697At this time the main intended use case of generators is an implementation
698primitive for async/await syntax, but generators will likely be extended to
699ergonomic implementations of iterators and other primitives in the future.
700Feedback on the design and usage is always appreciated!
701
702### The `Generator` trait
703
704The `Generator` trait in `std::ops` currently looks like:
705
706```rust
707# #![feature(arbitrary_self_types, generator_trait)]
708# use std::ops::GeneratorState;
709# use std::pin::Pin;
710
711pub trait Generator<R = ()> {
712 type Yield;
713 type Return;
714 fn resume(self: Pin<&mut Self>, resume: R) -> GeneratorState<Self::Yield, Self::Return>;
715}
716```
717
718The `Generator::Yield` type is the type of values that can be yielded with the
719`yield` statement. The `Generator::Return` type is the returned type of the
720generator. This is typically the last expression in a generator's definition or
721any value passed to `return` in a generator. The `resume` function is the entry
722point for executing the `Generator` itself.
723
724The return value of `resume`, `GeneratorState`, looks like:
725
726```rust
727pub enum GeneratorState<Y, R> {
728 Yielded(Y),
729 Complete(R),
730}
731```
732
733The `Yielded` variant indicates that the generator can later be resumed. This
734corresponds to a `yield` point in a generator. The `Complete` variant indicates
735that the generator is complete and cannot be resumed again. Calling `resume`
736after a generator has returned `Complete` will likely result in a panic of the
737program.
738
739### Closure-like semantics
740
741The closure-like syntax for generators alludes to the fact that they also have
742closure-like semantics. Namely:
743
744* When created, a generator executes no code. A closure literal does not
745 actually execute any of the closure's code on construction, and similarly a
746 generator literal does not execute any code inside the generator when
747 constructed.
748
749* Generators can capture outer variables by reference or by move, and this can
750 be tweaked with the `move` keyword at the beginning of the closure. Like
751 closures all generators will have an implicit environment which is inferred by
752 the compiler. Outer variables can be moved into a generator for use as the
753 generator progresses.
754
755* Generator literals produce a value with a unique type which implements the
756 `std::ops::Generator` trait. This allows actual execution of the generator
757 through the `Generator::resume` method as well as also naming it in return
758 types and such.
759
760* Traits like `Send` and `Sync` are automatically implemented for a `Generator`
761 depending on the captured variables of the environment. Unlike closures,
762 generators also depend on variables live across suspension points. This means
763 that although the ambient environment may be `Send` or `Sync`, the generator
764 itself may not be due to internal variables live across `yield` points being
765 not-`Send` or not-`Sync`. Note that generators do
766 not implement traits like `Copy` or `Clone` automatically.
767
768* Whenever a generator is dropped it will drop all captured environment
769 variables.
770
771### Generators as state machines
772
773In the compiler, generators are currently compiled as state machines. Each
774`yield` expression will correspond to a different state that stores all live
775variables over that suspension point. Resumption of a generator will dispatch on
776the current state and then execute internally until a `yield` is reached, at
777which point all state is saved off in the generator and a value is returned.
778
779Let's take a look at an example to see what's going on here:
780
781```rust
782#![feature(generators, generator_trait)]
783
784use std::ops::Generator;
785use std::pin::Pin;
786
787fn main() {
788 let ret = "foo";
789 let mut generator = move || {
790 yield 1;
791 return ret
792 };
793
794 Pin::new(&mut generator).resume(());
795 Pin::new(&mut generator).resume(());
796}
797```
798
799This generator literal will compile down to something similar to:
800
801```rust
802#![feature(arbitrary_self_types, generators, generator_trait)]
803
804use std::ops::{Generator, GeneratorState};
805use std::pin::Pin;
806
807fn main() {
808 let ret = "foo";
809 let mut generator = {
810 enum __Generator {
811 Start(&'static str),
812 Yield1(&'static str),
813 Done,
814 }
815
816 impl Generator for __Generator {
817 type Yield = i32;
818 type Return = &'static str;
819
820 fn resume(mut self: Pin<&mut Self>, resume: ()) -> GeneratorState<i32, &'static str> {
821 use std::mem;
822 match mem::replace(&mut *self, __Generator::Done) {
823 __Generator::Start(s) => {
824 *self = __Generator::Yield1(s);
825 GeneratorState::Yielded(1)
826 }
827
828 __Generator::Yield1(s) => {
829 *self = __Generator::Done;
830 GeneratorState::Complete(s)
831 }
832
833 __Generator::Done => {
834 panic!("generator resumed after completion")
835 }
836 }
837 }
838 }
839
840 __Generator::Start(ret)
841 };
842
843 Pin::new(&mut generator).resume(());
844 Pin::new(&mut generator).resume(());
845}
846```
847
848Notably here we can see that the compiler is generating a fresh type,
849`__Generator` in this case. This type has a number of states (represented here
850as an `enum`) corresponding to each of the conceptual states of the generator.
851At the beginning we're closing over our outer variable `foo` and then that
852variable is also live over the `yield` point, so it's stored in both states.
853
854When the generator starts it'll immediately yield 1, but it saves off its state
855just before it does so indicating that it has reached the yield point. Upon
856resuming again we'll execute the `return ret` which returns the `Complete`
857state.
858
859Here we can also note that the `Done` state, if resumed, panics immediately as
860it's invalid to resume a completed generator. It's also worth noting that this
861is just a rough desugaring, not a normative specification for what the compiler
862does.
863"##,
864 },
865 LintCompletion {
866 label: "non_ascii_idents",
867 description: r##"# `non_ascii_idents`
868
869The tracking issue for this feature is: [#55467]
870
871[#55467]: https://github.com/rust-lang/rust/issues/55467
872
873------------------------
874
875The `non_ascii_idents` feature adds support for non-ASCII identifiers.
876
877## Examples
878
879```rust
880#![feature(non_ascii_idents)]
881
882const ε: f64 = 0.00001f64;
883const Π: f64 = 3.14f64;
884```
885
886## Changes to the language reference
887
888> **<sup>Lexer:<sup>**\
889> IDENTIFIER :\
890> &nbsp;&nbsp; &nbsp;&nbsp; XID_start XID_continue<sup>\*</sup>\
891> &nbsp;&nbsp; | `_` XID_continue<sup>+</sup>
892
893An identifier is any nonempty Unicode string of the following form:
894
895Either
896
897 * The first character has property [`XID_start`]
898 * The remaining characters have property [`XID_continue`]
899
900Or
901
902 * The first character is `_`
903 * The identifier is more than one character, `_` alone is not an identifier
904 * The remaining characters have property [`XID_continue`]
905
906that does _not_ occur in the set of [strict keywords].
907
908> **Note**: [`XID_start`] and [`XID_continue`] as character properties cover the
909> character ranges used to form the more familiar C and Java language-family
910> identifiers.
911
912[`XID_start`]: http://unicode.org/cldr/utility/list-unicodeset.jsp?a=%5B%3AXID_Start%3A%5D&abb=on&g=&i=
913[`XID_continue`]: http://unicode.org/cldr/utility/list-unicodeset.jsp?a=%5B%3AXID_Continue%3A%5D&abb=on&g=&i=
914[strict keywords]: ../../reference/keywords.md#strict-keywords
915"##,
916 },
917 LintCompletion {
918 label: "compiler_builtins",
919 description: r##"# `compiler_builtins`
920
921This feature is internal to the Rust compiler and is not intended for general use.
922
923------------------------
924"##,
925 },
926 LintCompletion {
927 label: "or_patterns",
928 description: r##"# `or_patterns`
929
930The tracking issue for this feature is: [#54883]
931
932[#54883]: https://github.com/rust-lang/rust/issues/54883
933
934------------------------
935
936The `or_pattern` language feature allows `|` to be arbitrarily nested within
937a pattern, for example, `Some(A(0) | B(1 | 2))` becomes a valid pattern.
938
939## Examples
940
941```rust,no_run
942#![feature(or_patterns)]
943
944pub enum Foo {
945 Bar,
946 Baz,
947 Quux,
948}
949
950pub fn example(maybe_foo: Option<Foo>) {
951 match maybe_foo {
952 Some(Foo::Bar | Foo::Baz) => {
953 println!("The value contained `Bar` or `Baz`");
954 }
955 Some(_) => {
956 println!("The value did not contain `Bar` or `Baz`");
957 }
958 None => {
959 println!("The value was `None`");
960 }
961 }
962}
963```
964"##,
965 },
966 LintCompletion {
967 label: "negative_impls",
968 description: r##"# `negative_impls`
969
970The tracking issue for this feature is [#68318].
971
972[#68318]: https://github.com/rust-lang/rust/issues/68318
973
974----
975
976With the feature gate `negative_impls`, you can write negative impls as well as positive ones:
977
978```rust
979#![feature(negative_impls)]
980trait DerefMut { }
981impl<T: ?Sized> !DerefMut for &T { }
982```
983
984Negative impls indicate a semver guarantee that the given trait will not be implemented for the given types. Negative impls play an additional purpose for auto traits, described below.
985
986Negative impls have the following characteristics:
987
988* They do not have any items.
989* They must obey the orphan rules as if they were a positive impl.
990* They cannot "overlap" with any positive impls.
991
992## Semver interaction
993
994It is a breaking change to remove a negative impl. Negative impls are a commitment not to implement the given trait for the named types.
995
996## Orphan and overlap rules
997
998Negative impls must obey the same orphan rules as a positive impl. This implies you cannot add a negative impl for types defined in upstream crates and so forth.
999
1000Similarly, negative impls cannot overlap with positive impls, again using the same "overlap" check that we ordinarily use to determine if two impls overlap. (Note that positive impls typically cannot overlap with one another either, except as permitted by specialization.)
1001
1002## Interaction with auto traits
1003
1004Declaring a negative impl `impl !SomeAutoTrait for SomeType` for an
1005auto-trait serves two purposes:
1006
1007* as with any trait, it declares that `SomeType` will never implement `SomeAutoTrait`;
1008* it disables the automatic `SomeType: SomeAutoTrait` impl that would otherwise have been generated.
1009
1010Note that, at present, there is no way to indicate that a given type
1011does not implement an auto trait *but that it may do so in the
1012future*. For ordinary types, this is done by simply not declaring any
1013impl at all, but that is not an option for auto traits. A workaround
1014is that one could embed a marker type as one of the fields, where the
1015marker type is `!AutoTrait`.
1016
1017## Immediate uses
1018
1019Negative impls are used to declare that `&T: !DerefMut` and `&mut T: !Clone`, as required to fix the soundness of `Pin` described in [#66544](https://github.com/rust-lang/rust/issues/66544).
1020
1021This serves two purposes:
1022
1023* For proving the correctness of unsafe code, we can use that impl as evidence that no `DerefMut` or `Clone` impl exists.
1024* It prevents downstream crates from creating such impls.
1025"##,
1026 },
1027 LintCompletion {
1028 label: "cmse_nonsecure_entry",
1029 description: r##"# `cmse_nonsecure_entry`
1030
1031The tracking issue for this feature is: [#75835]
1032
1033[#75835]: https://github.com/rust-lang/rust/issues/75835
1034
1035------------------------
1036
1037The [TrustZone-M
1038feature](https://developer.arm.com/documentation/100690/latest/) is available
1039for targets with the Armv8-M architecture profile (`thumbv8m` in their target
1040name).
1041LLVM, the Rust compiler and the linker are providing
1042[support](https://developer.arm.com/documentation/ecm0359818/latest/) for the
1043TrustZone-M feature.
1044
1045One of the things provided, with this unstable feature, is the
1046`cmse_nonsecure_entry` attribute. This attribute marks a Secure function as an
1047entry function (see [section
10485.4](https://developer.arm.com/documentation/ecm0359818/latest/) for details).
1049With this attribute, the compiler will do the following:
1050* add a special symbol on the function which is the `__acle_se_` prefix and the
1051 standard function name
1052* constrain the number of parameters to avoid using the Non-Secure stack
1053* before returning from the function, clear registers that might contain Secure
1054 information
1055* use the `BXNS` instruction to return
1056
1057Because the stack can not be used to pass parameters, there will be compilation
1058errors if:
1059* the total size of all parameters is too big (for example more than four 32
1060 bits integers)
1061* the entry function is not using a C ABI
1062
1063The special symbol `__acle_se_` will be used by the linker to generate a secure
1064gateway veneer.
1065
1066<!-- NOTE(ignore) this example is specific to thumbv8m targets -->
1067
1068``` rust,ignore
1069#![feature(cmse_nonsecure_entry)]
1070
1071#[no_mangle]
1072#[cmse_nonsecure_entry]
1073pub extern "C" fn entry_function(input: u32) -> u32 {
1074 input + 6
1075}
1076```
1077
1078``` text
1079$ rustc --emit obj --crate-type lib --target thumbv8m.main-none-eabi function.rs
1080$ arm-none-eabi-objdump -D function.o
1081
108200000000 <entry_function>:
1083 0: b580 push {r7, lr}
1084 2: 466f mov r7, sp
1085 4: b082 sub sp, #8
1086 6: 9001 str r0, [sp, #4]
1087 8: 1d81 adds r1, r0, #6
1088 a: 460a mov r2, r1
1089 c: 4281 cmp r1, r0
1090 e: 9200 str r2, [sp, #0]
1091 10: d30b bcc.n 2a <entry_function+0x2a>
1092 12: e7ff b.n 14 <entry_function+0x14>
1093 14: 9800 ldr r0, [sp, #0]
1094 16: b002 add sp, #8
1095 18: e8bd 4080 ldmia.w sp!, {r7, lr}
1096 1c: 4671 mov r1, lr
1097 1e: 4672 mov r2, lr
1098 20: 4673 mov r3, lr
1099 22: 46f4 mov ip, lr
1100 24: f38e 8800 msr CPSR_f, lr
1101 28: 4774 bxns lr
1102 2a: f240 0000 movw r0, #0
1103 2e: f2c0 0000 movt r0, #0
1104 32: f240 0200 movw r2, #0
1105 36: f2c0 0200 movt r2, #0
1106 3a: 211c movs r1, #28
1107 3c: f7ff fffe bl 0 <_ZN4core9panicking5panic17h5c028258ca2fb3f5E>
1108 40: defe udf #254 ; 0xfe
1109```
1110"##,
1111 },
1112 LintCompletion {
1113 label: "plugin",
1114 description: r##"# `plugin`
1115
1116The tracking issue for this feature is: [#29597]
1117
1118[#29597]: https://github.com/rust-lang/rust/issues/29597
1119
1120
1121This feature is part of "compiler plugins." It will often be used with the
1122[`plugin_registrar`] and `rustc_private` features.
1123
1124[`plugin_registrar`]: plugin-registrar.md
1125
1126------------------------
1127
1128`rustc` can load compiler plugins, which are user-provided libraries that
1129extend the compiler's behavior with new lint checks, etc.
1130
1131A plugin is a dynamic library crate with a designated *registrar* function that
1132registers extensions with `rustc`. Other crates can load these extensions using
1133the crate attribute `#![plugin(...)]`. See the
1134`rustc_driver::plugin` documentation for more about the
1135mechanics of defining and loading a plugin.
1136
1137In the vast majority of cases, a plugin should *only* be used through
1138`#![plugin]` and not through an `extern crate` item. Linking a plugin would
1139pull in all of librustc_ast and librustc as dependencies of your crate. This is
1140generally unwanted unless you are building another plugin.
1141
1142The usual practice is to put compiler plugins in their own crate, separate from
1143any `macro_rules!` macros or ordinary Rust code meant to be used by consumers
1144of a library.
1145
1146# Lint plugins
1147
1148Plugins can extend [Rust's lint
1149infrastructure](../../reference/attributes/diagnostics.md#lint-check-attributes) with
1150additional checks for code style, safety, etc. Now let's write a plugin
1151[`lint-plugin-test.rs`](https://github.com/rust-lang/rust/blob/master/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs)
1152that warns about any item named `lintme`.
1153
1154```rust,ignore (requires-stage-2)
1155#![feature(plugin_registrar)]
1156#![feature(box_syntax, rustc_private)]
1157
1158extern crate rustc_ast;
1159
1160// Load rustc as a plugin to get macros
1161extern crate rustc_driver;
1162#[macro_use]
1163extern crate rustc_lint;
1164#[macro_use]
1165extern crate rustc_session;
1166
1167use rustc_driver::plugin::Registry;
1168use rustc_lint::{EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass};
1169use rustc_ast::ast;
1170declare_lint!(TEST_LINT, Warn, "Warn about items named 'lintme'");
1171
1172declare_lint_pass!(Pass => [TEST_LINT]);
1173
1174impl EarlyLintPass for Pass {
1175 fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) {
1176 if it.ident.name.as_str() == "lintme" {
1177 cx.lint(TEST_LINT, |lint| {
1178 lint.build("item is named 'lintme'").set_span(it.span).emit()
1179 });
1180 }
1181 }
1182}
1183
1184#[plugin_registrar]
1185pub fn plugin_registrar(reg: &mut Registry) {
1186 reg.lint_store.register_lints(&[&TEST_LINT]);
1187 reg.lint_store.register_early_pass(|| box Pass);
1188}
1189```
1190
1191Then code like
1192
1193```rust,ignore (requires-plugin)
1194#![feature(plugin)]
1195#![plugin(lint_plugin_test)]
1196
1197fn lintme() { }
1198```
1199
1200will produce a compiler warning:
1201
1202```txt
1203foo.rs:4:1: 4:16 warning: item is named 'lintme', #[warn(test_lint)] on by default
1204foo.rs:4 fn lintme() { }
1205 ^~~~~~~~~~~~~~~
1206```
1207
1208The components of a lint plugin are:
1209
1210* one or more `declare_lint!` invocations, which define static `Lint` structs;
1211
1212* a struct holding any state needed by the lint pass (here, none);
1213
1214* a `LintPass`
1215 implementation defining how to check each syntax element. A single
1216 `LintPass` may call `span_lint` for several different `Lint`s, but should
1217 register them all through the `get_lints` method.
1218
1219Lint passes are syntax traversals, but they run at a late stage of compilation
1220where type information is available. `rustc`'s [built-in
1221lints](https://github.com/rust-lang/rust/blob/master/src/librustc_session/lint/builtin.rs)
1222mostly use the same infrastructure as lint plugins, and provide examples of how
1223to access type information.
1224
1225Lints defined by plugins are controlled by the usual [attributes and compiler
1226flags](../../reference/attributes/diagnostics.md#lint-check-attributes), e.g.
1227`#[allow(test_lint)]` or `-A test-lint`. These identifiers are derived from the
1228first argument to `declare_lint!`, with appropriate case and punctuation
1229conversion.
1230
1231You can run `rustc -W help foo.rs` to see a list of lints known to `rustc`,
1232including those provided by plugins loaded by `foo.rs`.
1233"##,
1234 },
1235 LintCompletion {
1236 label: "intrinsics",
1237 description: r##"# `intrinsics`
1238
1239The tracking issue for this feature is: None.
1240
1241Intrinsics are never intended to be stable directly, but intrinsics are often
1242exported in some sort of stable manner. Prefer using the stable interfaces to
1243the intrinsic directly when you can.
1244
1245------------------------
1246
1247
1248These are imported as if they were FFI functions, with the special
1249`rust-intrinsic` ABI. For example, if one was in a freestanding
1250context, but wished to be able to `transmute` between types, and
1251perform efficient pointer arithmetic, one would import those functions
1252via a declaration like
1253
1254```rust
1255#![feature(intrinsics)]
1256# fn main() {}
1257
1258extern "rust-intrinsic" {
1259 fn transmute<T, U>(x: T) -> U;
1260
1261 fn offset<T>(dst: *const T, offset: isize) -> *const T;
1262}
1263```
1264
1265As with any other FFI functions, these are always `unsafe` to call.
1266"##,
1267 },
1268 LintCompletion {
1269 label: "rustc_attrs",
1270 description: r##"# `rustc_attrs`
1271
1272This feature has no tracking issue, and is therefore internal to
1273the compiler, not being intended for general use.
1274
1275Note: `rustc_attrs` enables many rustc-internal attributes and this page
1276only discuss a few of them.
1277
1278------------------------
1279
1280The `rustc_attrs` feature allows debugging rustc type layouts by using
1281`#[rustc_layout(...)]` to debug layout at compile time (it even works
1282with `cargo check`) as an alternative to `rustc -Z print-type-sizes`
1283that is way more verbose.
1284
1285Options provided by `#[rustc_layout(...)]` are `debug`, `size`, `align`,
1286`abi`. Note that it only works on sized types without generics.
1287
1288## Examples
1289
1290```rust,compile_fail
1291#![feature(rustc_attrs)]
1292
1293#[rustc_layout(abi, size)]
1294pub enum X {
1295 Y(u8, u8, u8),
1296 Z(isize),
1297}
1298```
1299
1300When that is compiled, the compiler will error with something like
1301
1302```text
1303error: abi: Aggregate { sized: true }
1304 --> src/lib.rs:4:1
1305 |
13064 | / pub enum T {
13075 | | Y(u8, u8, u8),
13086 | | Z(isize),
13097 | | }
1310 | |_^
1311
1312error: size: Size { raw: 16 }
1313 --> src/lib.rs:4:1
1314 |
13154 | / pub enum T {
13165 | | Y(u8, u8, u8),
13176 | | Z(isize),
13187 | | }
1319 | |_^
1320
1321error: aborting due to 2 previous errors
1322```
1323"##,
1324 },
1325 LintCompletion {
1326 label: "const_fn",
1327 description: r##"# `const_fn`
1328
1329The tracking issue for this feature is: [#57563]
1330
1331[#57563]: https://github.com/rust-lang/rust/issues/57563
1332
1333------------------------
1334
1335The `const_fn` feature enables additional functionality not stabilized in the
1336[minimal subset of `const_fn`](https://github.com/rust-lang/rust/issues/53555)
1337"##,
1338 },
1339 LintCompletion {
1340 label: "abi_thiscall",
1341 description: r##"# `abi_thiscall`
1342
1343The tracking issue for this feature is: [#42202]
1344
1345[#42202]: https://github.com/rust-lang/rust/issues/42202
1346
1347------------------------
1348
1349The MSVC ABI on x86 Windows uses the `thiscall` calling convention for C++
1350instance methods by default; it is identical to the usual (C) calling
1351convention on x86 Windows except that the first parameter of the method,
1352the `this` pointer, is passed in the ECX register.
1353"##,
1354 },
1355 LintCompletion {
1356 label: "trait_alias",
1357 description: r##"# `trait_alias`
1358
1359The tracking issue for this feature is: [#41517]
1360
1361[#41517]: https://github.com/rust-lang/rust/issues/41517
1362
1363------------------------
1364
1365The `trait_alias` feature adds support for trait aliases. These allow aliases
1366to be created for one or more traits (currently just a single regular trait plus
1367any number of auto-traits), and used wherever traits would normally be used as
1368either bounds or trait objects.
1369
1370```rust
1371#![feature(trait_alias)]
1372
1373trait Foo = std::fmt::Debug + Send;
1374trait Bar = Foo + Sync;
1375
1376// Use trait alias as bound on type parameter.
1377fn foo<T: Foo>(v: &T) {
1378 println!("{:?}", v);
1379}
1380
1381pub fn main() {
1382 foo(&1);
1383
1384 // Use trait alias for trait objects.
1385 let a: &Bar = &123;
1386 println!("{:?}", a);
1387 let b = Box::new(456) as Box<dyn Foo>;
1388 println!("{:?}", b);
1389}
1390```
1391"##,
1392 },
1393 LintCompletion {
1394 label: "lang_items",
1395 description: r##"# `lang_items`
1396
1397The tracking issue for this feature is: None.
1398
1399------------------------
1400
1401The `rustc` compiler has certain pluggable operations, that is,
1402functionality that isn't hard-coded into the language, but is
1403implemented in libraries, with a special marker to tell the compiler
1404it exists. The marker is the attribute `#[lang = "..."]` and there are
1405various different values of `...`, i.e. various different 'lang
1406items'.
1407
1408For example, `Box` pointers require two lang items, one for allocation
1409and one for deallocation. A freestanding program that uses the `Box`
1410sugar for dynamic allocations via `malloc` and `free`:
1411
1412```rust,ignore (libc-is-finicky)
1413#![feature(lang_items, box_syntax, start, libc, core_intrinsics, rustc_private)]
1414#![no_std]
1415use core::intrinsics;
1416use core::panic::PanicInfo;
1417
1418extern crate libc;
1419
1420#[lang = "owned_box"]
1421pub struct Box<T>(*mut T);
1422
1423#[lang = "exchange_malloc"]
1424unsafe fn allocate(size: usize, _align: usize) -> *mut u8 {
1425 let p = libc::malloc(size as libc::size_t) as *mut u8;
1426
1427 // Check if `malloc` failed:
1428 if p as usize == 0 {
1429 intrinsics::abort();
1430 }
1431
1432 p
1433}
1434
1435#[lang = "box_free"]
1436unsafe fn box_free<T: ?Sized>(ptr: *mut T) {
1437 libc::free(ptr as *mut libc::c_void)
1438}
1439
1440#[start]
1441fn main(_argc: isize, _argv: *const *const u8) -> isize {
1442 let _x = box 1;
1443
1444 0
1445}
1446
1447#[lang = "eh_personality"] extern fn rust_eh_personality() {}
1448#[lang = "panic_impl"] extern fn rust_begin_panic(info: &PanicInfo) -> ! { unsafe { intrinsics::abort() } }
1449#[no_mangle] pub extern fn rust_eh_register_frames () {}
1450#[no_mangle] pub extern fn rust_eh_unregister_frames () {}
1451```
1452
1453Note the use of `abort`: the `exchange_malloc` lang item is assumed to
1454return a valid pointer, and so needs to do the check internally.
1455
1456Other features provided by lang items include:
1457
1458- overloadable operators via traits: the traits corresponding to the
1459 `==`, `<`, dereferencing (`*`) and `+` (etc.) operators are all
1460 marked with lang items; those specific four are `eq`, `ord`,
1461 `deref`, and `add` respectively.
1462- stack unwinding and general failure; the `eh_personality`,
1463 `panic` and `panic_bounds_check` lang items.
1464- the traits in `std::marker` used to indicate types of
1465 various kinds; lang items `send`, `sync` and `copy`.
1466- the marker types and variance indicators found in
1467 `std::marker`; lang items `covariant_type`,
1468 `contravariant_lifetime`, etc.
1469
1470Lang items are loaded lazily by the compiler; e.g. if one never uses
1471`Box` then there is no need to define functions for `exchange_malloc`
1472and `box_free`. `rustc` will emit an error when an item is needed
1473but not found in the current crate or any that it depends on.
1474
1475Most lang items are defined by `libcore`, but if you're trying to build
1476an executable without the standard library, you'll run into the need
1477for lang items. The rest of this page focuses on this use-case, even though
1478lang items are a bit broader than that.
1479
1480### Using libc
1481
1482In order to build a `#[no_std]` executable we will need libc as a dependency.
1483We can specify this using our `Cargo.toml` file:
1484
1485```toml
1486[dependencies]
1487libc = { version = "0.2.14", default-features = false }
1488```
1489
1490Note that the default features have been disabled. This is a critical step -
1491**the default features of libc include the standard library and so must be
1492disabled.**
1493
1494### Writing an executable without stdlib
1495
1496Controlling the entry point is possible in two ways: the `#[start]` attribute,
1497or overriding the default shim for the C `main` function with your own.
1498
1499The function marked `#[start]` is passed the command line parameters
1500in the same format as C:
1501
1502```rust,ignore (libc-is-finicky)
1503#![feature(lang_items, core_intrinsics, rustc_private)]
1504#![feature(start)]
1505#![no_std]
1506use core::intrinsics;
1507use core::panic::PanicInfo;
1508
1509// Pull in the system libc library for what crt0.o likely requires.
1510extern crate libc;
1511
1512// Entry point for this program.
1513#[start]
1514fn start(_argc: isize, _argv: *const *const u8) -> isize {
1515 0
1516}
1517
1518// These functions are used by the compiler, but not
1519// for a bare-bones hello world. These are normally
1520// provided by libstd.
1521#[lang = "eh_personality"]
1522#[no_mangle]
1523pub extern fn rust_eh_personality() {
1524}
1525
1526#[lang = "panic_impl"]
1527#[no_mangle]
1528pub extern fn rust_begin_panic(info: &PanicInfo) -> ! {
1529 unsafe { intrinsics::abort() }
1530}
1531```
1532
1533To override the compiler-inserted `main` shim, one has to disable it
1534with `#![no_main]` and then create the appropriate symbol with the
1535correct ABI and the correct name, which requires overriding the
1536compiler's name mangling too:
1537
1538```rust,ignore (libc-is-finicky)
1539#![feature(lang_items, core_intrinsics, rustc_private)]
1540#![feature(start)]
1541#![no_std]
1542#![no_main]
1543use core::intrinsics;
1544use core::panic::PanicInfo;
1545
1546// Pull in the system libc library for what crt0.o likely requires.
1547extern crate libc;
1548
1549// Entry point for this program.
1550#[no_mangle] // ensure that this symbol is called `main` in the output
1551pub extern fn main(_argc: i32, _argv: *const *const u8) -> i32 {
1552 0
1553}
1554
1555// These functions are used by the compiler, but not
1556// for a bare-bones hello world. These are normally
1557// provided by libstd.
1558#[lang = "eh_personality"]
1559#[no_mangle]
1560pub extern fn rust_eh_personality() {
1561}
1562
1563#[lang = "panic_impl"]
1564#[no_mangle]
1565pub extern fn rust_begin_panic(info: &PanicInfo) -> ! {
1566 unsafe { intrinsics::abort() }
1567}
1568```
1569
1570In many cases, you may need to manually link to the `compiler_builtins` crate
1571when building a `no_std` binary. You may observe this via linker error messages
1572such as "```undefined reference to `__rust_probestack'```".
1573
1574## More about the language items
1575
1576The compiler currently makes a few assumptions about symbols which are
1577available in the executable to call. Normally these functions are provided by
1578the standard library, but without it you must define your own. These symbols
1579are called "language items", and they each have an internal name, and then a
1580signature that an implementation must conform to.
1581
1582The first of these functions, `rust_eh_personality`, is used by the failure
1583mechanisms of the compiler. This is often mapped to GCC's personality function
1584(see the [libstd implementation][unwind] for more information), but crates
1585which do not trigger a panic can be assured that this function is never
1586called. The language item's name is `eh_personality`.
1587
1588[unwind]: https://github.com/rust-lang/rust/blob/master/src/libpanic_unwind/gcc.rs
1589
1590The second function, `rust_begin_panic`, is also used by the failure mechanisms of the
1591compiler. When a panic happens, this controls the message that's displayed on
1592the screen. While the language item's name is `panic_impl`, the symbol name is
1593`rust_begin_panic`.
1594
1595Finally, a `eh_catch_typeinfo` static is needed for certain targets which
1596implement Rust panics on top of C++ exceptions.
1597
1598## List of all language items
1599
1600This is a list of all language items in Rust along with where they are located in
1601the source code.
1602
1603- Primitives
1604 - `i8`: `libcore/num/mod.rs`
1605 - `i16`: `libcore/num/mod.rs`
1606 - `i32`: `libcore/num/mod.rs`
1607 - `i64`: `libcore/num/mod.rs`
1608 - `i128`: `libcore/num/mod.rs`
1609 - `isize`: `libcore/num/mod.rs`
1610 - `u8`: `libcore/num/mod.rs`
1611 - `u16`: `libcore/num/mod.rs`
1612 - `u32`: `libcore/num/mod.rs`
1613 - `u64`: `libcore/num/mod.rs`
1614 - `u128`: `libcore/num/mod.rs`
1615 - `usize`: `libcore/num/mod.rs`
1616 - `f32`: `libstd/f32.rs`
1617 - `f64`: `libstd/f64.rs`
1618 - `char`: `libcore/char.rs`
1619 - `slice`: `liballoc/slice.rs`
1620 - `str`: `liballoc/str.rs`
1621 - `const_ptr`: `libcore/ptr.rs`
1622 - `mut_ptr`: `libcore/ptr.rs`
1623 - `unsafe_cell`: `libcore/cell.rs`
1624- Runtime
1625 - `start`: `libstd/rt.rs`
1626 - `eh_personality`: `libpanic_unwind/emcc.rs` (EMCC)
1627 - `eh_personality`: `libpanic_unwind/gcc.rs` (GNU)
1628 - `eh_personality`: `libpanic_unwind/seh.rs` (SEH)
1629 - `eh_catch_typeinfo`: `libpanic_unwind/emcc.rs` (EMCC)
1630 - `panic`: `libcore/panicking.rs`
1631 - `panic_bounds_check`: `libcore/panicking.rs`
1632 - `panic_impl`: `libcore/panicking.rs`
1633 - `panic_impl`: `libstd/panicking.rs`
1634- Allocations
1635 - `owned_box`: `liballoc/boxed.rs`
1636 - `exchange_malloc`: `liballoc/heap.rs`
1637 - `box_free`: `liballoc/heap.rs`
1638- Operands
1639 - `not`: `libcore/ops/bit.rs`
1640 - `bitand`: `libcore/ops/bit.rs`
1641 - `bitor`: `libcore/ops/bit.rs`
1642 - `bitxor`: `libcore/ops/bit.rs`
1643 - `shl`: `libcore/ops/bit.rs`
1644 - `shr`: `libcore/ops/bit.rs`
1645 - `bitand_assign`: `libcore/ops/bit.rs`
1646 - `bitor_assign`: `libcore/ops/bit.rs`
1647 - `bitxor_assign`: `libcore/ops/bit.rs`
1648 - `shl_assign`: `libcore/ops/bit.rs`
1649 - `shr_assign`: `libcore/ops/bit.rs`
1650 - `deref`: `libcore/ops/deref.rs`
1651 - `deref_mut`: `libcore/ops/deref.rs`
1652 - `index`: `libcore/ops/index.rs`
1653 - `index_mut`: `libcore/ops/index.rs`
1654 - `add`: `libcore/ops/arith.rs`
1655 - `sub`: `libcore/ops/arith.rs`
1656 - `mul`: `libcore/ops/arith.rs`
1657 - `div`: `libcore/ops/arith.rs`
1658 - `rem`: `libcore/ops/arith.rs`
1659 - `neg`: `libcore/ops/arith.rs`
1660 - `add_assign`: `libcore/ops/arith.rs`
1661 - `sub_assign`: `libcore/ops/arith.rs`
1662 - `mul_assign`: `libcore/ops/arith.rs`
1663 - `div_assign`: `libcore/ops/arith.rs`
1664 - `rem_assign`: `libcore/ops/arith.rs`
1665 - `eq`: `libcore/cmp.rs`
1666 - `ord`: `libcore/cmp.rs`
1667- Functions
1668 - `fn`: `libcore/ops/function.rs`
1669 - `fn_mut`: `libcore/ops/function.rs`
1670 - `fn_once`: `libcore/ops/function.rs`
1671 - `generator_state`: `libcore/ops/generator.rs`
1672 - `generator`: `libcore/ops/generator.rs`
1673- Other
1674 - `coerce_unsized`: `libcore/ops/unsize.rs`
1675 - `drop`: `libcore/ops/drop.rs`
1676 - `drop_in_place`: `libcore/ptr.rs`
1677 - `clone`: `libcore/clone.rs`
1678 - `copy`: `libcore/marker.rs`
1679 - `send`: `libcore/marker.rs`
1680 - `sized`: `libcore/marker.rs`
1681 - `unsize`: `libcore/marker.rs`
1682 - `sync`: `libcore/marker.rs`
1683 - `phantom_data`: `libcore/marker.rs`
1684 - `discriminant_kind`: `libcore/marker.rs`
1685 - `freeze`: `libcore/marker.rs`
1686 - `debug_trait`: `libcore/fmt/mod.rs`
1687 - `non_zero`: `libcore/nonzero.rs`
1688 - `arc`: `liballoc/sync.rs`
1689 - `rc`: `liballoc/rc.rs`
1690"##,
1691 },
1692 LintCompletion {
1693 label: "doc_spotlight",
1694 description: r##"# `doc_spotlight`
1695
1696The tracking issue for this feature is: [#45040]
1697
1698The `doc_spotlight` feature allows the use of the `spotlight` parameter to the `#[doc]` attribute,
1699to "spotlight" a specific trait on the return values of functions. Adding a `#[doc(spotlight)]`
1700attribute to a trait definition will make rustdoc print extra information for functions which return
1701a type that implements that trait. For example, this attribute is applied to the `Iterator`,
1702`io::Read`, `io::Write`, and `Future` traits in the standard library.
1703
1704You can do this on your own traits, like this:
1705
1706```
1707#![feature(doc_spotlight)]
1708
1709#[doc(spotlight)]
1710pub trait MyTrait {}
1711
1712pub struct MyStruct;
1713impl MyTrait for MyStruct {}
1714
1715/// The docs for this function will have an extra line about `MyStruct` implementing `MyTrait`,
1716/// without having to write that yourself!
1717pub fn my_fn() -> MyStruct { MyStruct }
1718```
1719
1720This feature was originally implemented in PR [#45039].
1721
1722[#45040]: https://github.com/rust-lang/rust/issues/45040
1723[#45039]: https://github.com/rust-lang/rust/pull/45039
1724"##,
1725 },
1726 LintCompletion {
1727 label: "c_variadic",
1728 description: r##"# `c_variadic`
1729
1730The tracking issue for this feature is: [#44930]
1731
1732[#44930]: https://github.com/rust-lang/rust/issues/44930
1733
1734------------------------
1735
1736The `c_variadic` language feature enables C-variadic functions to be
1737defined in Rust. The may be called both from within Rust and via FFI.
1738
1739## Examples
1740
1741```rust
1742#![feature(c_variadic)]
1743
1744pub unsafe extern "C" fn add(n: usize, mut args: ...) -> usize {
1745 let mut sum = 0;
1746 for _ in 0..n {
1747 sum += args.arg::<usize>();
1748 }
1749 sum
1750}
1751```
1752"##,
1753 },
1754 LintCompletion {
1755 label: "intra_doc_pointers",
1756 description: r##"# `intra-doc-pointers`
1757
1758The tracking issue for this feature is: [#80896]
1759
1760[#80896]: https://github.com/rust-lang/rust/issues/80896
1761
1762------------------------
1763
1764Rustdoc does not currently allow disambiguating between `*const` and `*mut`, and
1765raw pointers in intra-doc links are unstable until it does.
1766
1767```rust
1768#![feature(intra_doc_pointers)]
1769//! [pointer::add]
1770```
1771"##,
1772 },
1773 LintCompletion {
1774 label: "box_syntax",
1775 description: r##"# `box_syntax`
1776
1777The tracking issue for this feature is: [#49733]
1778
1779[#49733]: https://github.com/rust-lang/rust/issues/49733
1780
1781See also [`box_patterns`](box-patterns.md)
1782
1783------------------------
1784
1785Currently the only stable way to create a `Box` is via the `Box::new` method.
1786Also it is not possible in stable Rust to destructure a `Box` in a match
1787pattern. The unstable `box` keyword can be used to create a `Box`. An example
1788usage would be:
1789
1790```rust
1791#![feature(box_syntax)]
1792
1793fn main() {
1794 let b = box 5;
1795}
1796```
1797"##,
1798 },
1799 LintCompletion {
1800 label: "unsized_locals",
1801 description: r##"# `unsized_locals`
1802
1803The tracking issue for this feature is: [#48055]
1804
1805[#48055]: https://github.com/rust-lang/rust/issues/48055
1806
1807------------------------
1808
1809This implements [RFC1909]. When turned on, you can have unsized arguments and locals:
1810
1811[RFC1909]: https://github.com/rust-lang/rfcs/blob/master/text/1909-unsized-rvalues.md
1812
1813```rust
1814#![allow(incomplete_features)]
1815#![feature(unsized_locals, unsized_fn_params)]
1816
1817use std::any::Any;
1818
1819fn main() {
1820 let x: Box<dyn Any> = Box::new(42);
1821 let x: dyn Any = *x;
1822 // ^ unsized local variable
1823 // ^^ unsized temporary
1824 foo(x);
1825}
1826
1827fn foo(_: dyn Any) {}
1828// ^^^^^^ unsized argument
1829```
1830
1831The RFC still forbids the following unsized expressions:
1832
1833```rust,compile_fail
1834#![feature(unsized_locals)]
1835
1836use std::any::Any;
1837
1838struct MyStruct<T: ?Sized> {
1839 content: T,
1840}
1841
1842struct MyTupleStruct<T: ?Sized>(T);
1843
1844fn answer() -> Box<dyn Any> {
1845 Box::new(42)
1846}
1847
1848fn main() {
1849 // You CANNOT have unsized statics.
1850 static X: dyn Any = *answer(); // ERROR
1851 const Y: dyn Any = *answer(); // ERROR
1852
1853 // You CANNOT have struct initialized unsized.
1854 MyStruct { content: *answer() }; // ERROR
1855 MyTupleStruct(*answer()); // ERROR
1856 (42, *answer()); // ERROR
1857
1858 // You CANNOT have unsized return types.
1859 fn my_function() -> dyn Any { *answer() } // ERROR
1860
1861 // You CAN have unsized local variables...
1862 let mut x: dyn Any = *answer(); // OK
1863 // ...but you CANNOT reassign to them.
1864 x = *answer(); // ERROR
1865
1866 // You CANNOT even initialize them separately.
1867 let y: dyn Any; // OK
1868 y = *answer(); // ERROR
1869
1870 // Not mentioned in the RFC, but by-move captured variables are also Sized.
1871 let x: dyn Any = *answer();
1872 (move || { // ERROR
1873 let y = x;
1874 })();
1875
1876 // You CAN create a closure with unsized arguments,
1877 // but you CANNOT call it.
1878 // This is an implementation detail and may be changed in the future.
1879 let f = |x: dyn Any| {};
1880 f(*answer()); // ERROR
1881}
1882```
1883
1884## By-value trait objects
1885
1886With this feature, you can have by-value `self` arguments without `Self: Sized` bounds.
1887
1888```rust
1889#![feature(unsized_fn_params)]
1890
1891trait Foo {
1892 fn foo(self) {}
1893}
1894
1895impl<T: ?Sized> Foo for T {}
1896
1897fn main() {
1898 let slice: Box<[i32]> = Box::new([1, 2, 3]);
1899 <[i32] as Foo>::foo(*slice);
1900}
1901```
1902
1903And `Foo` will also be object-safe.
1904
1905```rust
1906#![feature(unsized_fn_params)]
1907
1908trait Foo {
1909 fn foo(self) {}
1910}
1911
1912impl<T: ?Sized> Foo for T {}
1913
1914fn main () {
1915 let slice: Box<dyn Foo> = Box::new([1, 2, 3]);
1916 // doesn't compile yet
1917 <dyn Foo as Foo>::foo(*slice);
1918}
1919```
1920
1921One of the objectives of this feature is to allow `Box<dyn FnOnce>`.
1922
1923## Variable length arrays
1924
1925The RFC also describes an extension to the array literal syntax: `[e; dyn n]`. In the syntax, `n` isn't necessarily a constant expression. The array is dynamically allocated on the stack and has the type of `[T]`, instead of `[T; n]`.
1926
1927```rust,ignore (not-yet-implemented)
1928#![feature(unsized_locals)]
1929
1930fn mergesort<T: Ord>(a: &mut [T]) {
1931 let mut tmp = [T; dyn a.len()];
1932 // ...
1933}
1934
1935fn main() {
1936 let mut a = [3, 1, 5, 6];
1937 mergesort(&mut a);
1938 assert_eq!(a, [1, 3, 5, 6]);
1939}
1940```
1941
1942VLAs are not implemented yet. The syntax isn't final, either. We may need an alternative syntax for Rust 2015 because, in Rust 2015, expressions like `[e; dyn(1)]` would be ambiguous. One possible alternative proposed in the RFC is `[e; n]`: if `n` captures one or more local variables, then it is considered as `[e; dyn n]`.
1943
1944## Advisory on stack usage
1945
1946It's advised not to casually use the `#![feature(unsized_locals)]` feature. Typical use-cases are:
1947
1948- When you need a by-value trait objects.
1949- When you really need a fast allocation of small temporary arrays.
1950
1951Another pitfall is repetitive allocation and temporaries. Currently the compiler simply extends the stack frame every time it encounters an unsized assignment. So for example, the code
1952
1953```rust
1954#![feature(unsized_locals)]
1955
1956fn main() {
1957 let x: Box<[i32]> = Box::new([1, 2, 3, 4, 5]);
1958 let _x = {{{{{{{{{{*x}}}}}}}}}};
1959}
1960```
1961
1962and the code
1963
1964```rust
1965#![feature(unsized_locals)]
1966
1967fn main() {
1968 for _ in 0..10 {
1969 let x: Box<[i32]> = Box::new([1, 2, 3, 4, 5]);
1970 let _x = *x;
1971 }
1972}
1973```
1974
1975will unnecessarily extend the stack frame.
1976"##,
1977 },
1978 LintCompletion {
1979 label: "arbitrary_enum_discriminant",
1980 description: r##"# `arbitrary_enum_discriminant`
1981
1982The tracking issue for this feature is: [#60553]
1983
1984[#60553]: https://github.com/rust-lang/rust/issues/60553
1985
1986------------------------
1987
1988The `arbitrary_enum_discriminant` feature permits tuple-like and
1989struct-like enum variants with `#[repr(<int-type>)]` to have explicit discriminants.
1990
1991## Examples
1992
1993```rust
1994#![feature(arbitrary_enum_discriminant)]
1995
1996#[allow(dead_code)]
1997#[repr(u8)]
1998enum Enum {
1999 Unit = 3,
2000 Tuple(u16) = 2,
2001 Struct {
2002 a: u8,
2003 b: u16,
2004 } = 1,
2005}
2006
2007impl Enum {
2008 fn tag(&self) -> u8 {
2009 unsafe { *(self as *const Self as *const u8) }
2010 }
2011}
2012
2013assert_eq!(3, Enum::Unit.tag());
2014assert_eq!(2, Enum::Tuple(5).tag());
2015assert_eq!(1, Enum::Struct{a: 7, b: 11}.tag());
2016```
2017"##,
2018 },
2019 LintCompletion {
2020 label: "unboxed_closures",
2021 description: r##"# `unboxed_closures`
2022
2023The tracking issue for this feature is [#29625]
2024
2025See Also: [`fn_traits`](../library-features/fn-traits.md)
2026
2027[#29625]: https://github.com/rust-lang/rust/issues/29625
2028
2029----
2030
2031The `unboxed_closures` feature allows you to write functions using the `"rust-call"` ABI,
2032required for implementing the [`Fn*`] family of traits. `"rust-call"` functions must have
2033exactly one (non self) argument, a tuple representing the argument list.
2034
2035[`Fn*`]: https://doc.rust-lang.org/std/ops/trait.Fn.html
2036
2037```rust
2038#![feature(unboxed_closures)]
2039
2040extern "rust-call" fn add_args(args: (u32, u32)) -> u32 {
2041 args.0 + args.1
2042}
2043
2044fn main() {}
2045```
2046"##,
2047 },
2048 LintCompletion {
2049 label: "custom_test_frameworks",
2050 description: r##"# `custom_test_frameworks`
2051
2052The tracking issue for this feature is: [#50297]
2053
2054[#50297]: https://github.com/rust-lang/rust/issues/50297
2055
2056------------------------
2057
2058The `custom_test_frameworks` feature allows the use of `#[test_case]` and `#![test_runner]`.
2059Any function, const, or static can be annotated with `#[test_case]` causing it to be aggregated (like `#[test]`)
2060and be passed to the test runner determined by the `#![test_runner]` crate attribute.
2061
2062```rust
2063#![feature(custom_test_frameworks)]
2064#![test_runner(my_runner)]
2065
2066fn my_runner(tests: &[&i32]) {
2067 for t in tests {
2068 if **t == 0 {
2069 println!("PASSED");
2070 } else {
2071 println!("FAILED");
2072 }
2073 }
2074}
2075
2076#[test_case]
2077const WILL_PASS: i32 = 0;
2078
2079#[test_case]
2080const WILL_FAIL: i32 = 4;
2081```
2082"##,
2083 },
2084 LintCompletion {
2085 label: "abi_msp430_interrupt",
2086 description: r##"# `abi_msp430_interrupt`
2087
2088The tracking issue for this feature is: [#38487]
2089
2090[#38487]: https://github.com/rust-lang/rust/issues/38487
2091
2092------------------------
2093
2094In the MSP430 architecture, interrupt handlers have a special calling
2095convention. You can use the `"msp430-interrupt"` ABI to make the compiler apply
2096the right calling convention to the interrupt handlers you define.
2097
2098<!-- NOTE(ignore) this example is specific to the msp430 target -->
2099
2100``` rust,ignore
2101#![feature(abi_msp430_interrupt)]
2102#![no_std]
2103
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"]
2107#[no_mangle]
2108pub static TIM0_VECTOR: extern "msp430-interrupt" fn() = tim0;
2109
2110// The interrupt handler
2111extern "msp430-interrupt" fn tim0() {
2112 // ..
2113}
2114```
2115
2116``` text
2117$ msp430-elf-objdump -CD ./target/msp430/release/app
2118Disassembly of section __interrupt_vector_10:
2119
21200000fff2 <TIM0_VECTOR>:
2121 fff2: 00 c0 interrupt service routine at 0xc000
2122
2123Disassembly of section .text:
2124
21250000c000 <int::tim0>:
2126 c000: 00 13 reti
2127```
2128"##,
2129 },
2130 LintCompletion {
2131 label: "impl_trait_in_bindings",
2132 description: r##"# `impl_trait_in_bindings`
2133
2134The tracking issue for this feature is: [#63065]
2135
2136[#63065]: https://github.com/rust-lang/rust/issues/63065
2137
2138------------------------
2139
2140The `impl_trait_in_bindings` feature gate lets you use `impl Trait` syntax in
2141`let`, `static`, and `const` bindings.
2142
2143A simple example is:
2144
2145```rust
2146#![feature(impl_trait_in_bindings)]
2147
2148use std::fmt::Debug;
2149
2150fn main() {
2151 let a: impl Debug + Clone = 42;
2152 let b = a.clone();
2153 println!("{:?}", b); // prints `42`
2154}
2155```
2156
2157Note however that because the types of `a` and `b` are opaque in the above
2158example, calling inherent methods or methods outside of the specified traits
2159(e.g., `a.abs()` or `b.abs()`) is not allowed, and yields an error.
2160"##,
2161 },
2162 LintCompletion {
2163 label: "cfg_version",
2164 description: r##"# `cfg_version`
2165
2166The tracking issue for this feature is: [#64796]
2167
2168[#64796]: https://github.com/rust-lang/rust/issues/64796
2169
2170------------------------
2171
2172The `cfg_version` feature makes it possible to execute different code
2173depending on the compiler version.
2174
2175## Examples
2176
2177```rust
2178#![feature(cfg_version)]
2179
2180#[cfg(version("1.42"))]
2181fn a() {
2182 // ...
2183}
2184
2185#[cfg(not(version("1.42")))]
2186fn a() {
2187 // ...
2188}
2189
2190fn b() {
2191 if cfg!(version("1.42")) {
2192 // ...
2193 } else {
2194 // ...
2195 }
2196}
2197```
2198"##,
2199 },
2200 LintCompletion {
2201 label: "link_cfg",
2202 description: r##"# `link_cfg`
2203
2204This feature is internal to the Rust compiler and is not intended for general use.
2205
2206------------------------
2207"##,
2208 },
2209 LintCompletion {
2210 label: "infer_static_outlives_requirements",
2211 description: r##"# `infer_static_outlives_requirements`
2212
2213The tracking issue for this feature is: [#54185]
2214
2215[#54185]: https://github.com/rust-lang/rust/issues/54185
2216
2217------------------------
2218The `infer_static_outlives_requirements` feature indicates that certain
2219`'static` outlives requirements can be inferred by the compiler rather than
2220stating them explicitly.
2221
2222Note: It is an accompanying feature to `infer_outlives_requirements`,
2223which must be enabled to infer outlives requirements.
2224
2225For example, currently generic struct definitions that contain
2226references, require where-clauses of the form T: 'static. By using
2227this feature the outlives predicates will be inferred, although
2228they may still be written explicitly.
2229
2230```rust,ignore (pseudo-Rust)
2231struct Foo<U> where U: 'static { // <-- currently required
2232 bar: Bar<U>
2233}
2234struct Bar<T: 'static> {
2235 x: T,
2236}
2237```
2238
2239
2240## Examples:
2241
2242```rust,ignore (pseudo-Rust)
2243#![feature(infer_outlives_requirements)]
2244#![feature(infer_static_outlives_requirements)]
2245
2246#[rustc_outlives]
2247// Implicitly infer U: 'static
2248struct Foo<U> {
2249 bar: Bar<U>
2250}
2251struct Bar<T: 'static> {
2252 x: T,
2253}
2254```
2255"##,
2256 },
2257 LintCompletion {
2258 label: "marker_trait_attr",
2259 description: r##"# `marker_trait_attr`
2260
2261The tracking issue for this feature is: [#29864]
2262
2263[#29864]: https://github.com/rust-lang/rust/issues/29864
2264
2265------------------------
2266
2267Normally, Rust keeps you from adding trait implementations that could
2268overlap with each other, as it would be ambiguous which to use. This
2269feature, however, carves out an exception to that rule: a trait can
2270opt-in to having overlapping implementations, at the cost that those
2271implementations are not allowed to override anything (and thus the
2272trait itself cannot have any associated items, as they're pointless
2273when they'd need to do the same thing for every type anyway).
2274
2275```rust
2276#![feature(marker_trait_attr)]
2277
2278#[marker] trait CheapToClone: Clone {}
2279
2280impl<T: Copy> CheapToClone for T {}
2281
2282// These could potentially overlap with the blanket implementation above,
2283// so are only allowed because CheapToClone is a marker trait.
2284impl<T: CheapToClone, U: CheapToClone> CheapToClone for (T, U) {}
2285impl<T: CheapToClone> CheapToClone for std::ops::Range<T> {}
2286
2287fn cheap_clone<T: CheapToClone>(t: T) -> T {
2288 t.clone()
2289}
2290```
2291
2292This is expected to replace the unstable `overlapping_marker_traits`
2293feature, which applied to all empty traits (without needing an opt-in).
2294"##,
2295 },
2296 LintCompletion {
2297 label: "doc_masked",
2298 description: r##"# `doc_masked`
2299
2300The tracking issue for this feature is: [#44027]
2301
2302-----
2303
2304The `doc_masked` feature allows a crate to exclude types from a given crate from appearing in lists
2305of trait implementations. The specifics of the feature are as follows:
2306
23071. When rustdoc encounters an `extern crate` statement annotated with a `#[doc(masked)]` attribute,
2308 it marks the crate as being masked.
2309
23102. When listing traits a given type implements, rustdoc ensures that traits from masked crates are
2311 not emitted into the documentation.
2312
23133. When listing types that implement a given trait, rustdoc ensures that types from masked crates
2314 are not emitted into the documentation.
2315
2316This feature was introduced in PR [#44026] to ensure that compiler-internal and
2317implementation-specific types and traits were not included in the standard library's documentation.
2318Such types would introduce broken links into the documentation.
2319
2320[#44026]: https://github.com/rust-lang/rust/pull/44026
2321[#44027]: https://github.com/rust-lang/rust/pull/44027
2322"##,
2323 },
2324 LintCompletion {
2325 label: "abi_ptx",
2326 description: r##"# `abi_ptx`
2327
2328The tracking issue for this feature is: [#38788]
2329
2330[#38788]: https://github.com/rust-lang/rust/issues/38788
2331
2332------------------------
2333
2334When emitting PTX code, all vanilla Rust functions (`fn`) get translated to
2335"device" functions. These functions are *not* callable from the host via the
2336CUDA API so a crate with only device functions is not too useful!
2337
2338OTOH, "global" functions *can* be called by the host; you can think of them
2339as the real public API of your crate. To produce a global function use the
2340`"ptx-kernel"` ABI.
2341
2342<!-- NOTE(ignore) this example is specific to the nvptx targets -->
2343
2344``` rust,ignore
2345#![feature(abi_ptx)]
2346#![no_std]
2347
2348pub unsafe extern "ptx-kernel" fn global_function() {
2349 device_function();
2350}
2351
2352pub fn device_function() {
2353 // ..
2354}
2355```
2356
2357``` text
2358$ xargo rustc --target nvptx64-nvidia-cuda --release -- --emit=asm
2359
2360$ cat $(find -name '*.s')
2361//
2362// Generated by LLVM NVPTX Back-End
2363//
2364
2365.version 3.2
2366.target sm_20
2367.address_size 64
2368
2369 // .globl _ZN6kernel15global_function17h46111ebe6516b382E
2370
2371.visible .entry _ZN6kernel15global_function17h46111ebe6516b382E()
2372{
2373
2374
2375 ret;
2376}
2377
2378 // .globl _ZN6kernel15device_function17hd6a0e4993bbf3f78E
2379.visible .func _ZN6kernel15device_function17hd6a0e4993bbf3f78E()
2380{
2381
2382
2383 ret;
2384}
2385```
2386"##,
2387 },
2388 LintCompletion {
2389 label: "profiler_runtime",
2390 description: r##"# `profiler_runtime`
2391
2392The tracking issue for this feature is: [#42524](https://github.com/rust-lang/rust/issues/42524).
2393
2394------------------------
2395"##,
2396 },
2397 LintCompletion {
2398 label: "crate_visibility_modifier",
2399 description: r##"# `crate_visibility_modifier`
2400
2401The tracking issue for this feature is: [#53120]
2402
2403[#53120]: https://github.com/rust-lang/rust/issues/53120
2404
2405-----
2406
2407The `crate_visibility_modifier` feature allows the `crate` keyword to be used
2408as a visibility modifier synonymous to `pub(crate)`, indicating that a type
2409(function, _&c._) is to be visible to the entire enclosing crate, but not to
2410other crates.
2411
2412```rust
2413#![feature(crate_visibility_modifier)]
2414
2415crate struct Foo {
2416 bar: usize,
2417}
2418```
2419"##,
2420 },
2421 LintCompletion {
2422 label: "doc_cfg",
2423 description: r##"# `doc_cfg`
2424
2425The tracking issue for this feature is: [#43781]
2426
2427------
2428
2429The `doc_cfg` feature allows an API be documented as only available in some specific platforms.
2430This attribute has two effects:
2431
24321. In the annotated item's documentation, there will be a message saying "This is supported on
2433 (platform) only".
2434
24352. The item's doc-tests will only run on the specific platform.
2436
2437In addition to allowing the use of the `#[doc(cfg)]` attribute, this feature enables the use of a
2438special conditional compilation flag, `#[cfg(doc)]`, set whenever building documentation on your
2439crate.
2440
2441This feature was introduced as part of PR [#43348] to allow the platform-specific parts of the
2442standard library be documented.
2443
2444```rust
2445#![feature(doc_cfg)]
2446
2447#[cfg(any(windows, doc))]
2448#[doc(cfg(windows))]
2449/// The application's icon in the notification area (a.k.a. system tray).
2450///
2451/// # Examples
2452///
2453/// ```no_run
2454/// extern crate my_awesome_ui_library;
2455/// use my_awesome_ui_library::current_app;
2456/// use my_awesome_ui_library::windows::notification;
2457///
2458/// let icon = current_app().get::<notification::Icon>();
2459/// icon.show();
2460/// icon.show_message("Hello");
2461/// ```
2462pub struct Icon {
2463 // ...
2464}
2465```
2466
2467[#43781]: https://github.com/rust-lang/rust/issues/43781
2468[#43348]: https://github.com/rust-lang/rust/issues/43348
2469"##,
2470 },
2471 LintCompletion {
2472 label: "unsized_tuple_coercion",
2473 description: r##"# `unsized_tuple_coercion`
2474
2475The tracking issue for this feature is: [#42877]
2476
2477[#42877]: https://github.com/rust-lang/rust/issues/42877
2478
2479------------------------
2480
2481This is a part of [RFC0401]. According to the RFC, there should be an implementation like this:
2482
2483```rust,ignore (partial-example)
2484impl<..., T, U: ?Sized> Unsized<(..., U)> for (..., T) where T: Unsized<U> {}
2485```
2486
2487This implementation is currently gated behind `#[feature(unsized_tuple_coercion)]` to avoid insta-stability. Therefore you can use it like this:
2488
2489```rust
2490#![feature(unsized_tuple_coercion)]
2491
2492fn main() {
2493 let x : ([i32; 3], [i32; 3]) = ([1, 2, 3], [4, 5, 6]);
2494 let y : &([i32; 3], [i32]) = &x;
2495 assert_eq!(y.1[0], 4);
2496}
2497```
2498
2499[RFC0401]: https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md
2500"##,
2501 },
2502 LintCompletion {
2503 label: "no_sanitize",
2504 description: r##"# `no_sanitize`
2505
2506The tracking issue for this feature is: [#39699]
2507
2508[#39699]: https://github.com/rust-lang/rust/issues/39699
2509
2510------------------------
2511
2512The `no_sanitize` attribute can be used to selectively disable sanitizer
2513instrumentation in an annotated function. This might be useful to: avoid
2514instrumentation overhead in a performance critical function, or avoid
2515instrumenting code that contains constructs unsupported by given sanitizer.
2516
2517The precise effect of this annotation depends on particular sanitizer in use.
2518For example, with `no_sanitize(thread)`, the thread sanitizer will no longer
2519instrument non-atomic store / load operations, but it will instrument atomic
2520operations to avoid reporting false positives and provide meaning full stack
2521traces.
2522
2523## Examples
2524
2525``` rust
2526#![feature(no_sanitize)]
2527
2528#[no_sanitize(address)]
2529fn foo() {
2530 // ...
2531}
2532```
2533"##,
2534 },
2535 LintCompletion {
2536 label: "try_blocks",
2537 description: r##"# `try_blocks`
2538
2539The tracking issue for this feature is: [#31436]
2540
2541[#31436]: https://github.com/rust-lang/rust/issues/31436
2542
2543------------------------
2544
2545The `try_blocks` feature adds support for `try` blocks. A `try`
2546block creates a new scope one can use the `?` operator in.
2547
2548```rust,edition2018
2549#![feature(try_blocks)]
2550
2551use std::num::ParseIntError;
2552
2553let result: Result<i32, ParseIntError> = try {
2554 "1".parse::<i32>()?
2555 + "2".parse::<i32>()?
2556 + "3".parse::<i32>()?
2557};
2558assert_eq!(result, Ok(6));
2559
2560let result: Result<i32, ParseIntError> = try {
2561 "1".parse::<i32>()?
2562 + "foo".parse::<i32>()?
2563 + "3".parse::<i32>()?
2564};
2565assert!(result.is_err());
2566```
2567"##,
2568 },
2569 LintCompletion {
2570 label: "transparent_unions",
2571 description: r##"# `transparent_unions`
2572
2573The tracking issue for this feature is [#60405]
2574
2575[#60405]: https://github.com/rust-lang/rust/issues/60405
2576
2577----
2578
2579The `transparent_unions` feature allows you mark `union`s as
2580`#[repr(transparent)]`. A `union` may be `#[repr(transparent)]` in exactly the
2581same conditions in which a `struct` may be `#[repr(transparent)]` (generally,
2582this means the `union` must have exactly one non-zero-sized field). Some
2583concrete illustrations follow.
2584
2585```rust
2586#![feature(transparent_unions)]
2587
2588// This union has the same representation as `f32`.
2589#[repr(transparent)]
2590union SingleFieldUnion {
2591 field: f32,
2592}
2593
2594// This union has the same representation as `usize`.
2595#[repr(transparent)]
2596union MultiFieldUnion {
2597 field: usize,
2598 nothing: (),
2599}
2600```
2601
2602For consistency with transparent `struct`s, `union`s must have exactly one
2603non-zero-sized field. If all fields are zero-sized, the `union` must not be
2604`#[repr(transparent)]`:
2605
2606```rust
2607#![feature(transparent_unions)]
2608
2609// This (non-transparent) union is already valid in stable Rust:
2610pub union GoodUnion {
2611 pub nothing: (),
2612}
2613
2614// Error: transparent union needs exactly one non-zero-sized field, but has 0
2615// #[repr(transparent)]
2616// pub union BadUnion {
2617// pub nothing: (),
2618// }
2619```
2620
2621The one exception is if the `union` is generic over `T` and has a field of type
2622`T`, it may be `#[repr(transparent)]` even if `T` is a zero-sized type:
2623
2624```rust
2625#![feature(transparent_unions)]
2626
2627// This union has the same representation as `T`.
2628#[repr(transparent)]
2629pub union GenericUnion<T: Copy> { // Unions with non-`Copy` fields are unstable.
2630 pub field: T,
2631 pub nothing: (),
2632}
2633
2634// This is okay even though `()` is a zero-sized type.
2635pub const THIS_IS_OKAY: GenericUnion<()> = GenericUnion { field: () };
2636```
2637
2638Like transarent `struct`s, a transparent `union` of type `U` has the same
2639layout, size, and ABI as its single non-ZST field. If it is generic over a type
2640`T`, and all its fields are ZSTs except for exactly one field of type `T`, then
2641it has the same layout and ABI as `T` (even if `T` is a ZST when monomorphized).
2642
2643Like transparent `struct`s, transparent `union`s are FFI-safe if and only if
2644their underlying representation type is also FFI-safe.
2645
2646A `union` may not be eligible for the same nonnull-style optimizations that a
2647`struct` or `enum` (with the same fields) are eligible for. Adding
2648`#[repr(transparent)]` to `union` does not change this. To give a more concrete
2649example, it is unspecified whether `size_of::<T>()` is equal to
2650`size_of::<Option<T>>()`, where `T` is a `union` (regardless of whether or not
2651it is transparent). The Rust compiler is free to perform this optimization if
2652possible, but is not required to, and different compiler versions may differ in
2653their application of these optimizations.
2654"##,
2655 },
2656 LintCompletion {
2657 label: "const_eval_limit",
2658 description: r##"# `const_eval_limit`
2659
2660The tracking issue for this feature is: [#67217]
2661
2662[#67217]: https://github.com/rust-lang/rust/issues/67217
2663
2664The `const_eval_limit` allows someone to limit the evaluation steps the CTFE undertakes to evaluate a `const fn`.
2665"##,
2666 },
2667 LintCompletion {
2668 label: "link_args",
2669 description: r##"# `link_args`
2670
2671The tracking issue for this feature is: [#29596]
2672
2673[#29596]: https://github.com/rust-lang/rust/issues/29596
2674
2675------------------------
2676
2677You can tell `rustc` how to customize linking, and that is via the `link_args`
2678attribute. This attribute is applied to `extern` blocks and specifies raw flags
2679which need to get passed to the linker when producing an artifact. An example
2680usage would be:
2681
2682```rust,no_run
2683#![feature(link_args)]
2684
2685#[link_args = "-foo -bar -baz"]
2686extern "C" {}
2687# fn main() {}
2688```
2689
2690Note that this feature is currently hidden behind the `feature(link_args)` gate
2691because this is not a sanctioned way of performing linking. Right now `rustc`
2692shells out to the system linker (`gcc` on most systems, `link.exe` on MSVC), so
2693it makes sense to provide extra command line arguments, but this will not
2694always be the case. In the future `rustc` may use LLVM directly to link native
2695libraries, in which case `link_args` will have no meaning. You can achieve the
2696same effect as the `link_args` attribute with the `-C link-args` argument to
2697`rustc`.
2698
2699It is highly recommended to *not* use this attribute, and rather use the more
2700formal `#[link(...)]` attribute on `extern` blocks instead.
2701"##,
2702 },
2703 LintCompletion {
2704 label: "internal_output_capture",
2705 description: r##"# `internal_output_capture`
2706
2707This feature is internal to the Rust compiler and is not intended for general use.
2708
2709------------------------
2710"##,
2711 },
2712 LintCompletion {
2713 label: "windows_handle",
2714 description: r##"# `windows_handle`
2715
2716This feature is internal to the Rust compiler and is not intended for general use.
2717
2718------------------------
2719"##,
2720 },
2721 LintCompletion {
2722 label: "asm",
2723 description: r##"# `asm`
2724
2725The tracking issue for this feature is: [#72016]
2726
2727[#72016]: https://github.com/rust-lang/rust/issues/72016
2728
2729------------------------
2730
2731For extremely low-level manipulations and performance reasons, one
2732might wish to control the CPU directly. Rust supports using inline
2733assembly to do this via the `asm!` macro.
2734
2735# Guide-level explanation
2736[guide-level-explanation]: #guide-level-explanation
2737
2738Rust provides support for inline assembly via the `asm!` macro.
2739It can be used to embed handwritten assembly in the assembly output generated by the compiler.
2740Generally this should not be necessary, but might be where the required performance or timing
2741cannot be otherwise achieved. Accessing low level hardware primitives, e.g. in kernel code, may also demand this functionality.
2742
2743> **Note**: the examples here are given in x86/x86-64 assembly, but other architectures are also supported.
2744
2745Inline assembly is currently supported on the following architectures:
2746- x86 and x86-64
2747- ARM
2748- AArch64
2749- RISC-V
2750- NVPTX
2751- Hexagon
2752- MIPS32r2 and MIPS64r2
2753- wasm32
2754
2755## Basic usage
2756
2757Let us start with the simplest possible example:
2758
2759```rust,allow_fail
2760# #![feature(asm)]
2761unsafe {
2762 asm!("nop");
2763}
2764```
2765
2766This will insert a NOP (no operation) instruction into the assembly generated by the compiler.
2767Note that all `asm!` invocations have to be inside an `unsafe` block, as they could insert
2768arbitrary instructions and break various invariants. The instructions to be inserted are listed
2769in the first argument of the `asm!` macro as a string literal.
2770
2771## Inputs and outputs
2772
2773Now inserting an instruction that does nothing is rather boring. Let us do something that
2774actually acts on data:
2775
2776```rust,allow_fail
2777# #![feature(asm)]
2778let x: u64;
2779unsafe {
2780 asm!("mov {}, 5", out(reg) x);
2781}
2782assert_eq!(x, 5);
2783```
2784
2785This will write the value `5` into the `u64` variable `x`.
2786You can see that the string literal we use to specify instructions is actually a template string.
2787It is governed by the same rules as Rust [format strings][format-syntax].
2788The arguments that are inserted into the template however look a bit different then you may
2789be familiar with. First we need to specify if the variable is an input or an output of the
2790inline assembly. In this case it is an output. We declared this by writing `out`.
2791We also need to specify in what kind of register the assembly expects the variable.
2792In this case we put it in an arbitrary general purpose register by specifying `reg`.
2793The compiler will choose an appropriate register to insert into
2794the template and will read the variable from there after the inline assembly finishes executing.
2795
2796Let us see another example that also uses an input:
2797
2798```rust,allow_fail
2799# #![feature(asm)]
2800let i: u64 = 3;
2801let o: u64;
2802unsafe {
2803 asm!(
2804 "mov {0}, {1}",
2805 "add {0}, {number}",
2806 out(reg) o,
2807 in(reg) i,
2808 number = const 5,
2809 );
2810}
2811assert_eq!(o, 8);
2812```
2813
2814This will add `5` to the input in variable `i` and write the result to variable `o`.
2815The particular way this assembly does this is first copying the value from `i` to the output,
2816and then adding `5` to it.
2817
2818The example shows a few things:
2819
2820First, we can see that `asm!` allows multiple template string arguments; each
2821one is treated as a separate line of assembly code, as if they were all joined
2822together with newlines between them. This makes it easy to format assembly
2823code.
2824
2825Second, we can see that inputs are declared by writing `in` instead of `out`.
2826
2827Third, one of our operands has a type we haven't seen yet, `const`.
2828This tells the compiler to expand this argument to value directly inside the assembly template.
2829This is only possible for constants and literals.
2830
2831Fourth, we can see that we can specify an argument number, or name as in any format string.
2832For inline assembly templates this is particularly useful as arguments are often used more than once.
2833For more complex inline assembly using this facility is generally recommended, as it improves
2834readability, and allows reordering instructions without changing the argument order.
2835
2836We can further refine the above example to avoid the `mov` instruction:
2837
2838```rust,allow_fail
2839# #![feature(asm)]
2840let mut x: u64 = 3;
2841unsafe {
2842 asm!("add {0}, {number}", inout(reg) x, number = const 5);
2843}
2844assert_eq!(x, 8);
2845```
2846
2847We can see that `inout` is used to specify an argument that is both input and output.
2848This is different from specifying an input and output separately in that it is guaranteed to assign both to the same register.
2849
2850It is also possible to specify different variables for the input and output parts of an `inout` operand:
2851
2852```rust,allow_fail
2853# #![feature(asm)]
2854let x: u64 = 3;
2855let y: u64;
2856unsafe {
2857 asm!("add {0}, {number}", inout(reg) x => y, number = const 5);
2858}
2859assert_eq!(y, 8);
2860```
2861
2862## Late output operands
2863
2864The Rust compiler is conservative with its allocation of operands. It is assumed that an `out`
2865can be written at any time, and can therefore not share its location with any other argument.
2866However, to guarantee optimal performance it is important to use as few registers as possible,
2867so they won't have to be saved and reloaded around the inline assembly block.
2868To achieve this Rust provides a `lateout` specifier. This can be used on any output that is
2869written only after all inputs have been consumed.
2870There is also a `inlateout` variant of this specifier.
2871
2872Here is an example where `inlateout` *cannot* be used:
2873
2874```rust,allow_fail
2875# #![feature(asm)]
2876let mut a: u64 = 4;
2877let b: u64 = 4;
2878let c: u64 = 4;
2879unsafe {
2880 asm!(
2881 "add {0}, {1}",
2882 "add {0}, {2}",
2883 inout(reg) a,
2884 in(reg) b,
2885 in(reg) c,
2886 );
2887}
2888assert_eq!(a, 12);
2889```
2890
2891Here 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.
2892
2893However the following example can use `inlateout` since the output is only modified after all input registers have been read:
2894
2895```rust,allow_fail
2896# #![feature(asm)]
2897let mut a: u64 = 4;
2898let b: u64 = 4;
2899unsafe {
2900 asm!("add {0}, {1}", inlateout(reg) a, in(reg) b);
2901}
2902assert_eq!(a, 8);
2903```
2904
2905As you can see, this assembly fragment will still work correctly if `a` and `b` are assigned to the same register.
2906
2907## Explicit register operands
2908
2909Some instructions require that the operands be in a specific register.
2910Therefore, Rust inline assembly provides some more specific constraint specifiers.
2911While `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`
2912among others can be addressed by their name.
2913
2914```rust,allow_fail,no_run
2915# #![feature(asm)]
2916let cmd = 0xd1;
2917unsafe {
2918 asm!("out 0x64, eax", in("eax") cmd);
2919}
2920```
2921
2922In this example we call the `out` instruction to output the content of the `cmd` variable
2923to port `0x64`. Since the `out` instruction only accepts `eax` (and its sub registers) as operand
2924we had to use the `eax` constraint specifier.
2925
2926Note 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.
2927
2928Consider this example which uses the x86 `mul` instruction:
2929
2930```rust,allow_fail
2931# #![feature(asm)]
2932fn mul(a: u64, b: u64) -> u128 {
2933 let lo: u64;
2934 let hi: u64;
2935
2936 unsafe {
2937 asm!(
2938 // The x86 mul instruction takes rax as an implicit input and writes
2939 // the 128-bit result of the multiplication to rax:rdx.
2940 "mul {}",
2941 in(reg) a,
2942 inlateout("rax") b => lo,
2943 lateout("rdx") hi
2944 );
2945 }
2946
2947 ((hi as u128) << 64) + lo as u128
2948}
2949```
2950
2951This uses the `mul` instruction to multiply two 64-bit inputs with a 128-bit result.
2952The only explicit operand is a register, that we fill from the variable `a`.
2953The second operand is implicit, and must be the `rax` register, which we fill from the variable `b`.
2954The lower 64 bits of the result are stored in `rax` from which we fill the variable `lo`.
2955The higher 64 bits are stored in `rdx` from which we fill the variable `hi`.
2956
2957## Clobbered registers
2958
2959In many cases inline assembly will modify state that is not needed as an output.
2960Usually this is either because we have to use a scratch register in the assembly,
2961or instructions modify state that we don't need to further examine.
2962This state is generally referred to as being "clobbered".
2963We need to tell the compiler about this since it may need to save and restore this state
2964around the inline assembly block.
2965
2966```rust,allow_fail
2967# #![feature(asm)]
2968let ebx: u32;
2969let ecx: u32;
2970
2971unsafe {
2972 asm!(
2973 "cpuid",
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,
2978 lateout("ebx") ebx,
2979 lateout("edx") _,
2980 );
2981}
2982
2983println!(
2984 "L1 Cache: {}",
2985 ((ebx >> 22) + 1) * (((ebx >> 12) & 0x3ff) + 1) * ((ebx & 0xfff) + 1) * (ecx + 1)
2986);
2987```
2988
2989In the example above we use the `cpuid` instruction to get the L1 cache size.
2990This instruction writes to `eax`, `ebx`, `ecx`, and `edx`, but for the cache size we only care about the contents of `ebx` and `ecx`.
2991
2992However 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.
2993
2994This can also be used with a general register class (e.g. `reg`) to obtain a scratch register for use inside the asm code:
2995
2996```rust,allow_fail
2997# #![feature(asm)]
2998// Multiply x by 6 using shifts and adds
2999let mut x: u64 = 4;
3000unsafe {
3001 asm!(
3002 "mov {tmp}, {x}",
3003 "shl {tmp}, 1",
3004 "shl {x}, 2",
3005 "add {x}, {tmp}",
3006 x = inout(reg) x,
3007 tmp = out(reg) _,
3008 );
3009}
3010assert_eq!(x, 4 * 6);
3011```
3012
3013## Symbol operands
3014
3015A special operand type, `sym`, allows you to use the symbol name of a `fn` or `static` in inline assembly code.
3016This allows you to call a function or access a global variable without needing to keep its address in a register.
3017
3018```rust,allow_fail
3019# #![feature(asm)]
3020extern "C" fn foo(arg: i32) {
3021 println!("arg = {}", arg);
3022}
3023
3024fn call_foo(arg: i32) {
3025 unsafe {
3026 asm!(
3027 "call {}",
3028 sym foo,
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") _,
3038 )
3039 }
3040}
3041```
3042
3043Note that the `fn` or `static` item does not need to be public or `#[no_mangle]`:
3044the compiler will automatically insert the appropriate mangled symbol name into the assembly code.
3045
3046## Register template modifiers
3047
3048In 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).
3049
3050By 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).
3051
3052This default can be overriden by using modifiers on the template string operands, just like you would with format strings:
3053
3054```rust,allow_fail
3055# #![feature(asm)]
3056let mut x: u16 = 0xab;
3057
3058unsafe {
3059 asm!("mov {0:h}, {0:l}", inout(reg_abcd) x);
3060}
3061
3062assert_eq!(x, 0xabab);
3063```
3064
3065In 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.
3066
3067Let us assume that the register allocator has chosen to allocate `x` in the `ax` register.
3068The `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.
3069
3070If 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.
3071
3072## Memory address operands
3073
3074Sometimes assembly instructions require operands passed via memory addresses/memory locations.
3075You have to manually use the memory address syntax specified by the respectively architectures.
3076For example, in x86/x86_64 and intel assembly syntax, you should wrap inputs/outputs in `[]`
3077to indicate they are memory operands:
3078
3079```rust,allow_fail
3080# #![feature(asm, llvm_asm)]
3081# fn load_fpu_control_word(control: u16) {
3082unsafe {
3083 asm!("fldcw [{}]", in(reg) &control, options(nostack));
3084
3085 // Previously this would have been written with the deprecated `llvm_asm!` like this
3086 llvm_asm!("fldcw $0" :: "m" (control) :: "volatile");
3087}
3088# }
3089```
3090
3091## Options
3092
3093By default, an inline assembly block is treated the same way as an external FFI function call with a custom calling convention: it may read/write memory, have observable side effects, etc. However in many cases, it is desirable to give the compiler more information about what the assembly code is actually doing so that it can optimize better.
3094
3095Let's take our previous example of an `add` instruction:
3096
3097```rust,allow_fail
3098# #![feature(asm)]
3099let mut a: u64 = 4;
3100let b: u64 = 4;
3101unsafe {
3102 asm!(
3103 "add {0}, {1}",
3104 inlateout(reg) a, in(reg) b,
3105 options(pure, nomem, nostack),
3106 );
3107}
3108assert_eq!(a, 8);
3109```
3110
3111Options 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.
3115
3116These allow the compiler to better optimize code using `asm!`, for example by eliminating pure `asm!` blocks whose outputs are not needed.
3117
3118See the reference for the full list of available options and their effects.
3119
3120# Reference-level explanation
3121[reference-level-explanation]: #reference-level-explanation
3122
3123Inline assembler is implemented as an unsafe macro `asm!()`.
3124The first argument to this macro is a template string literal used to build the final assembly.
3125The following arguments specify input and output operands.
3126When required, options are specified as the final argument.
3127
3128The following ABNF specifies the general syntax:
3129
3130```text
3131dir_spec := "in" / "out" / "lateout" / "inout" / "inlateout"
3132reg_spec := <register class> / "<explicit register>"
3133operand_expr := expr / "_" / expr "=>" expr / expr "=>" "_"
3134reg_operand := dir_spec "(" reg_spec ")" operand_expr
3135operand := reg_operand / "const" const_expr / "sym" path
3136option := "pure" / "nomem" / "readonly" / "preserves_flags" / "noreturn" / "nostack" / "att_syntax"
3137options := "options(" option *["," option] [","] ")"
3138asm := "asm!(" format_string *("," format_string) *("," [ident "="] operand) ["," options] [","] ")"
3139```
3140
3141The macro will initially be supported only on ARM, AArch64, Hexagon, x86, x86-64 and RISC-V targets. Support for more targets may be added in the future. The compiler will emit an error if `asm!` is used on an unsupported target.
3142
3143[format-syntax]: https://doc.rust-lang.org/std/fmt/#syntax
3144
3145## Template string arguments
3146
3147The 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.
3148
3149An `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.
3150
3151As 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.
3152
3153Explicit 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.
3154
3155The 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.
3156
3157The 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.
3158
3159[rfc-2795]: https://github.com/rust-lang/rfcs/pull/2795
3160
3161## Operand type
3162
3163Several types of operands are supported:
3164
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.
3189* `const <expr>`
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.
3192* `sym <path>`
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.
3197
3198Operand 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.
3199
3200## Register operands
3201
3202Input 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).
3203
3204Note 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.
3205
3206Only the following types are allowed as operands for inline assembly:
3207- Integers (signed and unsigned)
3208- Floating-point numbers
3209- Pointers (thin only)
3210- Function pointers
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).
3212
3213Here is the list of currently supported register classes:
3214
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` |
3248
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.
3250>
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.
3252>
3253> Note #3: NVPTX doesn't have a fixed register set, so named registers are not supported.
3254>
3255> Note #4: On ARM the frame pointer is either `r7` or `r11` depending on the platform.
3256>
3257> Note #5: WebAssembly doesn't have registers, so named registers are not supported.
3258
3259Additional register classes may be added in the future based on demand (e.g. MMX, x87, etc).
3260
3261Each 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.
3262
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` |
3292
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).
3294
3295If 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.
3296
3297When 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.
3298
3299## Register names
3300
3301Some 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:
3302
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` |
3351
3352Some registers cannot be used for input or output operands:
3353
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. |
3374
3375In some cases LLVM will allocate a "reserved register" for `reg` operands even though this register cannot be explicitly specified. Assembly code making use of reserved registers should be careful since `reg` operands may alias with those registers. Reserved registers are:
3376- The frame pointer on all architectures.
3377- `r6` on ARM.
3378
3379## Template modifiers
3380
3381The 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.
3382
3383The 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.
3384
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 |
3426
3427> Notes:
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.
3431
3432As 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.
3433
3434[llvm-argmod]: http://llvm.org/docs/LangRef.html#asm-template-argument-modifiers
3435
3436## Options
3437
3438Flags are used to further influence the behavior of the inline assembly block.
3439Currently 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 `%`.
3447
3448The 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.
3453
3454## Rules for inline assembly
3455
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:
3481 - x86
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).
3485 - ARM
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).
3492 - AArch64
3493 - Condition flags (`NZCV` register).
3494 - Floating-point status (`FPSR` register).
3495 - RISC-V
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.
3507
3508> **Note**: As a general rule, the flags covered by `preserves_flags` are those which are *not* preserved when performing a function call.
3509
3510[local labels]: https://sourceware.org/binutils/docs/as/Symbol-Names.html#Local-Labels
3511"##,
3512 },
3513 LintCompletion {
3514 label: "flt2dec",
3515 description: r##"# `flt2dec`
3516
3517This feature is internal to the Rust compiler and is not intended for general use.
3518
3519------------------------
3520"##,
3521 },
3522 LintCompletion {
3523 label: "global_asm",
3524 description: r##"# `global_asm`
3525
3526The tracking issue for this feature is: [#35119]
3527
3528[#35119]: https://github.com/rust-lang/rust/issues/35119
3529
3530------------------------
3531
3532The `global_asm!` macro allows the programmer to write arbitrary
3533assembly outside the scope of a function body, passing it through
3534`rustc` and `llvm` to the assembler. The macro is a no-frills
3535interface to LLVM's concept of [module-level inline assembly]. That is,
3536all caveats applicable to LLVM's module-level inline assembly apply
3537to `global_asm!`.
3538
3539[module-level inline assembly]: http://llvm.org/docs/LangRef.html#module-level-inline-assembly
3540
3541`global_asm!` fills a role not currently satisfied by either `asm!`
3542or `#[naked]` functions. The programmer has _all_ features of the
3543assembler at their disposal. The linker will expect to resolve any
3544symbols defined in the inline assembly, modulo any symbols marked as
3545external. It also means syntax for directives and assembly follow the
3546conventions of the assembler in your toolchain.
3547
3548A simple usage looks like this:
3549
3550```rust,ignore (requires-external-file)
3551#![feature(global_asm)]
3552# // you also need relevant target_arch cfgs
3553global_asm!(include_str!("something_neato.s"));
3554```
3555
3556And a more complicated usage looks like this:
3557
3558```rust,no_run
3559#![feature(global_asm)]
3560# #[cfg(any(target_arch="x86", target_arch="x86_64"))]
3561# mod x86 {
3562
3563pub mod sally {
3564 global_asm!(r#"
3565 .global foo
3566 foo:
3567 jmp baz
3568 "#);
3569
3570 #[no_mangle]
3571 pub unsafe extern "C" fn baz() {}
3572}
3573
3574// the symbols `foo` and `bar` are global, no matter where
3575// `global_asm!` was used.
3576extern "C" {
3577 fn foo();
3578 fn bar();
3579}
3580
3581pub mod harry {
3582 global_asm!(r#"
3583 .global bar
3584 bar:
3585 jmp quux
3586 "#);
3587
3588 #[no_mangle]
3589 pub unsafe extern "C" fn quux() {}
3590}
3591# }
3592```
3593
3594You may use `global_asm!` multiple times, anywhere in your crate, in
3595whatever way suits you. The effect is as if you concatenated all
3596usages and placed the larger, single usage in the crate root.
3597
3598------------------------
3599
3600If you don't need quite as much power and flexibility as
3601`global_asm!` provides, and you don't mind restricting your inline
3602assembly to `fn` bodies only, you might try the
3603[asm](asm.md) feature instead.
3604"##,
3605 },
3606 LintCompletion {
3607 label: "derive_eq",
3608 description: r##"# `derive_eq`
3609
3610This feature is internal to the Rust compiler and is not intended for general use.
3611
3612------------------------
3613"##,
3614 },
3615 LintCompletion {
3616 label: "default_free_fn",
3617 description: r##"# `default_free_fn`
3618
3619The tracking issue for this feature is: [#73014]
3620
3621[#73014]: https://github.com/rust-lang/rust/issues/73014
3622
3623------------------------
3624
3625Adds a free `default()` function to the `std::default` module. This function
3626just forwards to [`Default::default()`], but may remove repetition of the word
3627"default" from the call site.
3628
3629[`Default::default()`]: https://doc.rust-lang.org/nightly/std/default/trait.Default.html#tymethod.default
3630
3631Here is an example:
3632
3633```rust
3634#![feature(default_free_fn)]
3635use std::default::default;
3636
3637#[derive(Default)]
3638struct AppConfig {
3639 foo: FooConfig,
3640 bar: BarConfig,
3641}
3642
3643#[derive(Default)]
3644struct FooConfig {
3645 foo: i32,
3646}
3647
3648#[derive(Default)]
3649struct BarConfig {
3650 bar: f32,
3651 baz: u8,
3652}
3653
3654fn main() {
3655 let options = AppConfig {
3656 foo: default(),
3657 bar: BarConfig {
3658 bar: 10.1,
3659 ..default()
3660 },
3661 };
3662}
3663```
3664"##,
3665 },
3666 LintCompletion {
3667 label: "char_error_internals",
3668 description: r##"# `char_error_internals`
3669
3670This feature is internal to the Rust compiler and is not intended for general use.
3671
3672------------------------
3673"##,
3674 },
3675 LintCompletion {
3676 label: "libstd_sys_internals",
3677 description: r##"# `libstd_sys_internals`
3678
3679This feature is internal to the Rust compiler and is not intended for general use.
3680
3681------------------------
3682"##,
3683 },
3684 LintCompletion {
3685 label: "is_sorted",
3686 description: r##"# `is_sorted`
3687
3688The tracking issue for this feature is: [#53485]
3689
3690[#53485]: https://github.com/rust-lang/rust/issues/53485
3691
3692------------------------
3693
3694Add the methods `is_sorted`, `is_sorted_by` and `is_sorted_by_key` to `[T]`;
3695add the methods `is_sorted`, `is_sorted_by` and `is_sorted_by_key` to
3696`Iterator`.
3697"##,
3698 },
3699 LintCompletion {
3700 label: "c_void_variant",
3701 description: r##"# `c_void_variant`
3702
3703This feature is internal to the Rust compiler and is not intended for general use.
3704
3705------------------------
3706"##,
3707 },
3708 LintCompletion {
3709 label: "concat_idents",
3710 description: r##"# `concat_idents`
3711
3712The tracking issue for this feature is: [#29599]
3713
3714[#29599]: https://github.com/rust-lang/rust/issues/29599
3715
3716------------------------
3717
3718The `concat_idents` feature adds a macro for concatenating multiple identifiers
3719into one identifier.
3720
3721## Examples
3722
3723```rust
3724#![feature(concat_idents)]
3725
3726fn main() {
3727 fn foobar() -> u32 { 23 }
3728 let f = concat_idents!(foo, bar);
3729 assert_eq!(f(), 23);
3730}
3731```
3732"##,
3733 },
3734 LintCompletion {
3735 label: "format_args_capture",
3736 description: r##"# `format_args_capture`
3737
3738The tracking issue for this feature is: [#67984]
3739
3740[#67984]: https://github.com/rust-lang/rust/issues/67984
3741
3742------------------------
3743
3744Enables `format_args!` (and macros which use `format_args!` in their implementation, such
3745as `format!`, `print!` and `panic!`) to capture variables from the surrounding scope.
3746This avoids the need to pass named parameters when the binding in question
3747already exists in scope.
3748
3749```rust
3750#![feature(format_args_capture)]
3751
3752let (person, species, name) = ("Charlie Brown", "dog", "Snoopy");
3753
3754// captures named argument `person`
3755print!("Hello {person}");
3756
3757// captures named arguments `species` and `name`
3758format!("The {species}'s name is {name}.");
3759```
3760
3761This also works for formatting parameters such as width and precision:
3762
3763```rust
3764#![feature(format_args_capture)]
3765
3766let precision = 2;
3767let s = format!("{:.precision$}", 1.324223);
3768
3769assert_eq!(&s, "1.32");
3770```
3771
3772A non-exhaustive list of macros which benefit from this functionality include:
3773- `format!`
3774- `print!` and `println!`
3775- `eprint!` and `eprintln!`
3776- `write!` and `writeln!`
3777- `panic!`
3778- `unreachable!`
3779- `unimplemented!`
3780- `todo!`
3781- `assert!` and similar
3782- macros in many thirdparty crates, such as `log`
3783"##,
3784 },
3785 LintCompletion {
3786 label: "print_internals",
3787 description: r##"# `print_internals`
3788
3789This feature is internal to the Rust compiler and is not intended for general use.
3790
3791------------------------
3792"##,
3793 },
3794 LintCompletion {
3795 label: "llvm_asm",
3796 description: r##"# `llvm_asm`
3797
3798The tracking issue for this feature is: [#70173]
3799
3800[#70173]: https://github.com/rust-lang/rust/issues/70173
3801
3802------------------------
3803
3804For extremely low-level manipulations and performance reasons, one
3805might wish to control the CPU directly. Rust supports using inline
3806assembly to do this via the `llvm_asm!` macro.
3807
3808```rust,ignore (pseudo-code)
3809llvm_asm!(assembly template
3810 : output operands
3811 : input operands
3812 : clobbers
3813 : options
3814 );
3815```
3816
3817Any use of `llvm_asm` is feature gated (requires `#![feature(llvm_asm)]` on the
3818crate to allow) and of course requires an `unsafe` block.
3819
3820> **Note**: the examples here are given in x86/x86-64 assembly, but
3821> all platforms are supported.
3822
3823## Assembly template
3824
3825The `assembly template` is the only required parameter and must be a
3826literal string (i.e. `""`)
3827
3828```rust
3829#![feature(llvm_asm)]
3830
3831#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
3832fn foo() {
3833 unsafe {
3834 llvm_asm!("NOP");
3835 }
3836}
3837
3838// Other platforms:
3839#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
3840fn foo() { /* ... */ }
3841
3842fn main() {
3843 // ...
3844 foo();
3845 // ...
3846}
3847```
3848
3849(The `feature(llvm_asm)` and `#[cfg]`s are omitted from now on.)
3850
3851Output operands, input operands, clobbers and options are all optional
3852but you must add the right number of `:` if you skip them:
3853
3854```rust
3855# #![feature(llvm_asm)]
3856# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
3857# fn main() { unsafe {
3858llvm_asm!("xor %eax, %eax"
3859 :
3860 :
3861 : "eax"
3862 );
3863# } }
3864# #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
3865# fn main() {}
3866```
3867
3868Whitespace also doesn't matter:
3869
3870```rust
3871# #![feature(llvm_asm)]
3872# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
3873# fn main() { unsafe {
3874llvm_asm!("xor %eax, %eax" ::: "eax");
3875# } }
3876# #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
3877# fn main() {}
3878```
3879
3880## Operands
3881
3882Input and output operands follow the same format: `:
3883"constraints1"(expr1), "constraints2"(expr2), ..."`. Output operand
3884expressions must be mutable place, or not yet assigned:
3885
3886```rust
3887# #![feature(llvm_asm)]
3888# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
3889fn add(a: i32, b: i32) -> i32 {
3890 let c: i32;
3891 unsafe {
3892 llvm_asm!("add $2, $0"
3893 : "=r"(c)
3894 : "0"(a), "r"(b)
3895 );
3896 }
3897 c
3898}
3899# #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
3900# fn add(a: i32, b: i32) -> i32 { a + b }
3901
3902fn main() {
3903 assert_eq!(add(3, 14159), 14162)
3904}
3905```
3906
3907If you would like to use real operands in this position, however,
3908you are required to put curly braces `{}` around the register that
3909you want, and you are required to put the specific size of the
3910operand. This is useful for very low level programming, where
3911which register you use is important:
3912
3913```rust
3914# #![feature(llvm_asm)]
3915# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
3916# unsafe fn read_byte_in(port: u16) -> u8 {
3917let result: u8;
3918llvm_asm!("in %dx, %al" : "={al}"(result) : "{dx}"(port));
3919result
3920# }
3921```
3922
3923## Clobbers
3924
3925Some instructions modify registers which might otherwise have held
3926different values so we use the clobbers list to indicate to the
3927compiler not to assume any values loaded into those registers will
3928stay valid.
3929
3930```rust
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:
3935llvm_asm!("mov $$0x200, %eax" : /* no outputs */ : /* no inputs */ : "eax");
3936# } }
3937# #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
3938# fn main() {}
3939```
3940
3941Input and output registers need not be listed since that information
3942is already communicated by the given constraints. Otherwise, any other
3943registers used either implicitly or explicitly should be listed.
3944
3945If the assembly changes the condition code register `cc` should be
3946specified as one of the clobbers. Similarly, if the assembly modifies
3947memory, `memory` should also be specified.
3948
3949## Options
3950
3951The last section, `options` is specific to Rust. The format is comma
3952separated literal strings (i.e. `:"foo", "bar", "baz"`). It's used to
3953specify some extra info about the inline assembly:
3954
3955Current valid options are:
3956
39571. `volatile` - specifying this is analogous to
3958 `__asm__ __volatile__ (...)` in gcc/clang.
39592. `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
39623. `intel` - use intel syntax instead of the default AT&T.
3963
3964```rust
3965# #![feature(llvm_asm)]
3966# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
3967# fn main() {
3968let result: i32;
3969unsafe {
3970 llvm_asm!("mov eax, 2" : "={eax}"(result) : : : "intel")
3971}
3972println!("eax is currently {}", result);
3973# }
3974# #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
3975# fn main() {}
3976```
3977
3978## More Information
3979
3980The current implementation of the `llvm_asm!` macro is a direct binding to [LLVM's
3981inline assembler expressions][llvm-docs], so be sure to check out [their
3982documentation as well][llvm-docs] for more information about clobbers,
3983constraints, etc.
3984
3985[llvm-docs]: http://llvm.org/docs/LangRef.html#inline-assembler-expressions
3986
3987If you need more power and don't mind losing some of the niceties of
3988`llvm_asm!`, check out [global_asm](global-asm.md).
3989"##,
3990 },
3991 LintCompletion {
3992 label: "core_intrinsics",
3993 description: r##"# `core_intrinsics`
3994
3995This feature is internal to the Rust compiler and is not intended for general use.
3996
3997------------------------
3998"##,
3999 },
4000 LintCompletion {
4001 label: "trace_macros",
4002 description: r##"# `trace_macros`
4003
4004The tracking issue for this feature is [#29598].
4005
4006[#29598]: https://github.com/rust-lang/rust/issues/29598
4007
4008------------------------
4009
4010With `trace_macros` you can trace the expansion of macros in your code.
4011
4012## Examples
4013
4014```rust
4015#![feature(trace_macros)]
4016
4017fn main() {
4018 trace_macros!(true);
4019 println!("Hello, Rust!");
4020 trace_macros!(false);
4021}
4022```
4023
4024The `cargo build` output:
4025
4026```txt
4027note: trace_macro
4028 --> src/main.rs:5:5
4029 |
40305 | println!("Hello, Rust!");
4031 | ^^^^^^^^^^^^^^^^^^^^^^^^^
4032 |
4033 = note: expanding `println! { "Hello, Rust!" }`
4034 = note: to `print ! ( concat ! ( "Hello, Rust!" , "\n" ) )`
4035 = note: expanding `print! { concat ! ( "Hello, Rust!" , "\n" ) }`
4036 = note: to `$crate :: io :: _print ( format_args ! ( concat ! ( "Hello, Rust!" , "\n" ) )
4037 )`
4038
4039 Finished dev [unoptimized + debuginfo] target(s) in 0.60 secs
4040```
4041"##,
4042 },
4043 LintCompletion {
4044 label: "update_panic_count",
4045 description: r##"# `update_panic_count`
4046
4047This feature is internal to the Rust compiler and is not intended for general use.
4048
4049------------------------
4050"##,
4051 },
4052 LintCompletion {
4053 label: "core_private_bignum",
4054 description: r##"# `core_private_bignum`
4055
4056This feature is internal to the Rust compiler and is not intended for general use.
4057
4058------------------------
4059"##,
4060 },
4061 LintCompletion {
4062 label: "sort_internals",
4063 description: r##"# `sort_internals`
4064
4065This feature is internal to the Rust compiler and is not intended for general use.
4066
4067------------------------
4068"##,
4069 },
4070 LintCompletion {
4071 label: "windows_net",
4072 description: r##"# `windows_net`
4073
4074This feature is internal to the Rust compiler and is not intended for general use.
4075
4076------------------------
4077"##,
4078 },
4079 LintCompletion {
4080 label: "c_variadic",
4081 description: r##"# `c_variadic`
4082
4083The tracking issue for this feature is: [#44930]
4084
4085[#44930]: https://github.com/rust-lang/rust/issues/44930
4086
4087------------------------
4088
4089The `c_variadic` library feature exposes the `VaList` structure,
4090Rust's analogue of C's `va_list` type.
4091
4092## Examples
4093
4094```rust
4095#![feature(c_variadic)]
4096
4097use std::ffi::VaList;
4098
4099pub unsafe extern "C" fn vadd(n: usize, mut args: VaList) -> usize {
4100 let mut sum = 0;
4101 for _ in 0..n {
4102 sum += args.arg::<usize>();
4103 }
4104 sum
4105}
4106```
4107"##,
4108 },
4109 LintCompletion {
4110 label: "core_private_diy_float",
4111 description: r##"# `core_private_diy_float`
4112
4113This feature is internal to the Rust compiler and is not intended for general use.
4114
4115------------------------
4116"##,
4117 },
4118 LintCompletion {
4119 label: "profiler_runtime_lib",
4120 description: r##"# `profiler_runtime_lib`
4121
4122This feature is internal to the Rust compiler and is not intended for general use.
4123
4124------------------------
4125"##,
4126 },
4127 LintCompletion {
4128 label: "thread_local_internals",
4129 description: r##"# `thread_local_internals`
4130
4131This feature is internal to the Rust compiler and is not intended for general use.
4132
4133------------------------
4134"##,
4135 },
4136 LintCompletion {
4137 label: "int_error_internals",
4138 description: r##"# `int_error_internals`
4139
4140This feature is internal to the Rust compiler and is not intended for general use.
4141
4142------------------------
4143"##,
4144 },
4145 LintCompletion {
4146 label: "windows_stdio",
4147 description: r##"# `windows_stdio`
4148
4149This feature is internal to the Rust compiler and is not intended for general use.
4150
4151------------------------
4152"##,
4153 },
4154 LintCompletion {
4155 label: "fmt_internals",
4156 description: r##"# `fmt_internals`
4157
4158This feature is internal to the Rust compiler and is not intended for general use.
4159
4160------------------------
4161"##,
4162 },
4163 LintCompletion {
4164 label: "fd_read",
4165 description: r##"# `fd_read`
4166
4167This feature is internal to the Rust compiler and is not intended for general use.
4168
4169------------------------
4170"##,
4171 },
4172 LintCompletion {
4173 label: "str_internals",
4174 description: r##"# `str_internals`
4175
4176This feature is internal to the Rust compiler and is not intended for general use.
4177
4178------------------------
4179"##,
4180 },
4181 LintCompletion {
4182 label: "test",
4183 description: r##"# `test`
4184
4185The tracking issue for this feature is: None.
4186
4187------------------------
4188
4189The internals of the `test` crate are unstable, behind the `test` flag. The
4190most widely used part of the `test` crate are benchmark tests, which can test
4191the performance of your code. Let's make our `src/lib.rs` look like this
4192(comments elided):
4193
4194```rust,no_run
4195#![feature(test)]
4196
4197extern crate test;
4198
4199pub fn add_two(a: i32) -> i32 {
4200 a + 2
4201}
4202
4203#[cfg(test)]
4204mod tests {
4205 use super::*;
4206 use test::Bencher;
4207
4208 #[test]
4209 fn it_works() {
4210 assert_eq!(4, add_two(2));
4211 }
4212
4213 #[bench]
4214 fn bench_add_two(b: &mut Bencher) {
4215 b.iter(|| add_two(2));
4216 }
4217}
4218```
4219
4220Note the `test` feature gate, which enables this unstable feature.
4221
4222We've imported the `test` crate, which contains our benchmarking support.
4223We have a new function as well, with the `bench` attribute. Unlike regular
4224tests, which take no arguments, benchmark tests take a `&mut Bencher`. This
4225`Bencher` provides an `iter` method, which takes a closure. This closure
4226contains the code we'd like to benchmark.
4227
4228We can run benchmark tests with `cargo bench`:
4229
4230```bash
4231$ cargo bench
4232 Compiling adder v0.0.1 (file:///home/steve/tmp/adder)
4233 Running target/release/adder-91b3e234d4ed382a
4234
4235running 2 tests
4236test tests::it_works ... ignored
4237test tests::bench_add_two ... bench: 1 ns/iter (+/- 0)
4238
4239test result: ok. 0 passed; 0 failed; 1 ignored; 1 measured
4240```
4241
4242Our non-benchmark test was ignored. You may have noticed that `cargo bench`
4243takes a bit longer than `cargo test`. This is because Rust runs our benchmark
4244a number of times, and then takes the average. Because we're doing so little
4245work in this example, we have a `1 ns/iter (+/- 0)`, but this would show
4246the variance if there was one.
4247
4248Advice on writing benchmarks:
4249
4250
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
4254 it many times
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)
4259
4260## Gotcha: optimizations
4261
4262There's another tricky part to writing benchmarks: benchmarks compiled with
4263optimizations activated can be dramatically changed by the optimizer so that
4264the benchmark is no longer benchmarking what one expects. For example, the
4265compiler might recognize that some calculation has no external effects and
4266remove it entirely.
4267
4268```rust,no_run
4269#![feature(test)]
4270
4271extern crate test;
4272use test::Bencher;
4273
4274#[bench]
4275fn bench_xor_1000_ints(b: &mut Bencher) {
4276 b.iter(|| {
4277 (0..1000).fold(0, |old, new| old ^ new);
4278 });
4279}
4280```
4281
4282gives the following results
4283
4284```text
4285running 1 test
4286test bench_xor_1000_ints ... bench: 0 ns/iter (+/- 0)
4287
4288test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
4289```
4290
4291The benchmarking runner offers two ways to avoid this. Either, the closure that
4292the `iter` method receives can return an arbitrary value which forces the
4293optimizer to consider the result used and ensures it cannot remove the
4294computation entirely. This could be done for the example above by adjusting the
4295`b.iter` call to
4296
4297```rust
4298# struct X;
4299# impl X { fn iter<T, F>(&self, _: F) where F: FnMut() -> T {} } let b = X;
4300b.iter(|| {
4301 // Note lack of `;` (could also use an explicit `return`).
4302 (0..1000).fold(0, |old, new| old ^ new)
4303});
4304```
4305
4306Or, the other option is to call the generic `test::black_box` function, which
4307is an opaque "black box" to the optimizer and so forces it to consider any
4308argument as used.
4309
4310```rust
4311#![feature(test)]
4312
4313extern crate test;
4314
4315# fn main() {
4316# struct X;
4317# impl X { fn iter<T, F>(&self, _: F) where F: FnMut() -> T {} } let b = X;
4318b.iter(|| {
4319 let n = test::black_box(1000);
4320
4321 (0..n).fold(0, |a, b| a ^ b)
4322})
4323# }
4324```
4325
4326Neither of these read or modify the value, and are very cheap for small values.
4327Larger values can be passed indirectly to reduce overhead (e.g.
4328`black_box(&huge_struct)`).
4329
4330Performing either of the above changes gives the following benchmarking results
4331
4332```text
4333running 1 test
4334test bench_xor_1000_ints ... bench: 131 ns/iter (+/- 3)
4335
4336test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
4337```
4338
4339However, the optimizer can still modify a testcase in an undesirable manner
4340even when using either of the above.
4341"##,
4342 },
4343 LintCompletion {
4344 label: "windows_c",
4345 description: r##"# `windows_c`
4346
4347This feature is internal to the Rust compiler and is not intended for general use.
4348
4349------------------------
4350"##,
4351 },
4352 LintCompletion {
4353 label: "dec2flt",
4354 description: r##"# `dec2flt`
4355
4356This feature is internal to the Rust compiler and is not intended for general use.
4357
4358------------------------
4359"##,
4360 },
4361 LintCompletion {
4362 label: "derive_clone_copy",
4363 description: r##"# `derive_clone_copy`
4364
4365This feature is internal to the Rust compiler and is not intended for general use.
4366
4367------------------------
4368"##,
4369 },
4370 LintCompletion {
4371 label: "allocator_api",
4372 description: r##"# `allocator_api`
4373
4374The tracking issue for this feature is [#32838]
4375
4376[#32838]: https://github.com/rust-lang/rust/issues/32838
4377
4378------------------------
4379
4380Sometimes you want the memory for one collection to use a different
4381allocator than the memory for another collection. In this case,
4382replacing the global allocator is not a workable option. Instead,
4383you need to pass in an instance of an `AllocRef` to each collection
4384for which you want a custom allocator.
4385
4386TBD
4387"##,
4388 },
4389 LintCompletion {
4390 label: "core_panic",
4391 description: r##"# `core_panic`
4392
4393This feature is internal to the Rust compiler and is not intended for general use.
4394
4395------------------------
4396"##,
4397 },
4398 LintCompletion {
4399 label: "fn_traits",
4400 description: r##"# `fn_traits`
4401
4402The tracking issue for this feature is [#29625]
4403
4404See Also: [`unboxed_closures`](../language-features/unboxed-closures.md)
4405
4406[#29625]: https://github.com/rust-lang/rust/issues/29625
4407
4408----
4409
4410The `fn_traits` feature allows for implementation of the [`Fn*`] traits
4411for creating custom closure-like types.
4412
4413[`Fn*`]: https://doc.rust-lang.org/std/ops/trait.Fn.html
4414
4415```rust
4416#![feature(unboxed_closures)]
4417#![feature(fn_traits)]
4418
4419struct Adder {
4420 a: u32
4421}
4422
4423impl FnOnce<(u32, )> for Adder {
4424 type Output = u32;
4425 extern "rust-call" fn call_once(self, b: (u32, )) -> Self::Output {
4426 self.a + b.0
4427 }
4428}
4429
4430fn main() {
4431 let adder = Adder { a: 3 };
4432 assert_eq!(adder(2), 5);
4433}
4434```
4435"##,
4436 },
4437 LintCompletion {
4438 label: "try_trait",
4439 description: r##"# `try_trait`
4440
4441The tracking issue for this feature is: [#42327]
4442
4443[#42327]: https://github.com/rust-lang/rust/issues/42327
4444
4445------------------------
4446
4447This introduces a new trait `Try` for extending the `?` operator to types
4448other than `Result` (a part of [RFC 1859]). The trait provides the canonical
4449way to _view_ a type in terms of a success/failure dichotomy. This will
4450allow `?` to supplant the `try_opt!` macro on `Option` and the `try_ready!`
4451macro on `Poll`, among other things.
4452
4453[RFC 1859]: https://github.com/rust-lang/rfcs/pull/1859
4454
4455Here's an example implementation of the trait:
4456
4457```rust,ignore (cannot-reimpl-Try)
4458/// A distinct type to represent the `None` value of an `Option`.
4459///
4460/// This enables using the `?` operator on `Option`; it's rarely useful alone.
4461#[derive(Debug)]
4462#[unstable(feature = "try_trait", issue = "42327")]
4463pub struct None { _priv: () }
4464
4465#[unstable(feature = "try_trait", issue = "42327")]
4466impl<T> ops::Try for Option<T> {
4467 type Ok = T;
4468 type Error = None;
4469
4470 fn into_result(self) -> Result<T, None> {
4471 self.ok_or(None { _priv: () })
4472 }
4473
4474 fn from_ok(v: T) -> Self {
4475 Some(v)
4476 }
4477
4478 fn from_error(_: None) -> Self {
4479 None
4480 }
4481}
4482```
4483
4484Note the `Error` associated type here is a new marker. The `?` operator
4485allows interconversion between different `Try` implementers only when
4486the error type can be converted `Into` the error type of the enclosing
4487function (or catch block). Having a distinct error type (as opposed to
4488just `()`, or similar) restricts this to where it's semantically meaningful.
4489"##,
4490 },
4491 LintCompletion {
4492 label: "rt",
4493 description: r##"# `rt`
4494
4495This feature is internal to the Rust compiler and is not intended for general use.
4496
4497------------------------
4498"##,
4499 },
4500 LintCompletion {
4501 label: "fd",
4502 description: r##"# `fd`
4503
4504This feature is internal to the Rust compiler and is not intended for general use.
4505
4506------------------------
4507"##,
4508 },
4509 LintCompletion {
4510 label: "libstd_thread_internals",
4511 description: r##"# `libstd_thread_internals`
4512
4513This feature is internal to the Rust compiler and is not intended for general use.
4514
4515------------------------
4516"##,
4517 },
4518];
4519
4520pub(super) const CLIPPY_LINTS: &[LintCompletion] = &[
4521 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."##,
4524 },
4525 LintCompletion {
4526 label: "clippy::almost_swapped",
4527 description: r##"Checks for `foo = bar; bar = foo` sequences."##,
4528 },
4529 LintCompletion {
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."##,
4532 },
4533 LintCompletion {
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)."##,
4536 },
4537 LintCompletion {
4538 label: "clippy::assertions_on_constants",
4539 description: r##"Checks for `assert!(true)` and `assert!(false)` calls."##,
4540 },
4541 LintCompletion {
4542 label: "clippy::assign_op_pattern",
4543 description: r##"Checks for `a = a op b` or `a = b commutative_op a`\npatterns."##,
4544 },
4545 LintCompletion {
4546 label: "clippy::assign_ops",
4547 description: r##"Nothing. This lint has been deprecated."##,
4548 },
4549 LintCompletion {
4550 label: "clippy::async_yields_async",
4551 description: r##"Checks for async blocks that yield values of types\nthat can themselves be awaited."##,
4552 },
4553 LintCompletion {
4554 label: "clippy::await_holding_lock",
4555 description: r##"Checks for calls to await while holding a\nnon-async-aware MutexGuard."##,
4556 },
4557 LintCompletion {
4558 label: "clippy::await_holding_refcell_ref",
4559 description: r##"Checks for calls to await while holding a\n`RefCell` `Ref` or `RefMut`."##,
4560 },
4561 LintCompletion {
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` |"##,
4564 },
4565 LintCompletion {
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))`."##,
4568 },
4569 LintCompletion {
4570 label: "clippy::blacklisted_name",
4571 description: r##"Checks for usage of blacklisted names for variables, such\nas `foo`."##,
4572 },
4573 LintCompletion {
4574 label: "clippy::blanket_clippy_restriction_lints",
4575 description: r##"Checks for `warn`/`deny`/`forbid` attributes targeting the whole clippy::restriction category."##,
4576 },
4577 LintCompletion {
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."##,
4580 },
4581 LintCompletion {
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."##,
4584 },
4585 LintCompletion {
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."##,
4588 },
4589 LintCompletion {
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."##,
4592 },
4593 LintCompletion {
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."##,
4596 },
4597 LintCompletion {
4598 label: "clippy::boxed_local",
4599 description: r##"Checks for usage of `Box<T>` where an unboxed `T` would\nwork fine."##,
4600 },
4601 LintCompletion {
4602 label: "clippy::builtin_type_shadow",
4603 description: r##"Warns if a generic shadows a built-in type."##,
4604 },
4605 LintCompletion {
4606 label: "clippy::bytes_nth",
4607 description: r##"Checks for the use of `.bytes().nth()`."##,
4608 },
4609 LintCompletion {
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"##,
4612 },
4613 LintCompletion {
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."##,
4616 },
4617 LintCompletion {
4618 label: "clippy::cast_lossless",
4619 description: r##"Checks for casts between numerical types that may\nbe replaced by safe conversion functions."##,
4620 },
4621 LintCompletion {
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."##,
4624 },
4625 LintCompletion {
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."##,
4628 },
4629 LintCompletion {
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`."##,
4632 },
4633 LintCompletion {
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"##,
4636 },
4637 LintCompletion {
4638 label: "clippy::cast_ref_to_mut",
4639 description: r##"Checks for casts of `&T` to `&mut T` anywhere in the code."##,
4640 },
4641 LintCompletion {
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."##,
4644 },
4645 LintCompletion {
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."##,
4648 },
4649 LintCompletion {
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."##,
4652 },
4653 LintCompletion {
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."##,
4656 },
4657 LintCompletion {
4658 label: "clippy::checked_conversions",
4659 description: r##"Checks for explicit bounds checking when casting."##,
4660 },
4661 LintCompletion {
4662 label: "clippy::clone_double_ref",
4663 description: r##"Checks for usage of `.clone()` on an `&&T