aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_db
diff options
context:
space:
mode:
authorLukas Wirth <[email protected]>2021-06-04 17:35:19 +0100
committerLukas Wirth <[email protected]>2021-06-04 17:35:19 +0100
commit343df88ac7579316a5500fa7f4a07602809af669 (patch)
tree09db0d170e3fa31c118e6d0dce62af98f51ac5e0 /crates/ide_db
parent5d17b6a6873d530eda89d271807dcb70a811a200 (diff)
Generate default lint completions
Diffstat (limited to 'crates/ide_db')
-rw-r--r--crates/ide_db/src/helpers.rs1
-rw-r--r--crates/ide_db/src/helpers/generated_lints.rs6891
2 files changed, 6892 insertions, 0 deletions
diff --git a/crates/ide_db/src/helpers.rs b/crates/ide_db/src/helpers.rs
index 21b48237a..00900cdc2 100644
--- a/crates/ide_db/src/helpers.rs
+++ b/crates/ide_db/src/helpers.rs
@@ -3,6 +3,7 @@ pub mod import_assets;
3pub mod insert_use; 3pub mod insert_use;
4pub mod merge_imports; 4pub mod merge_imports;
5pub mod rust_doc; 5pub mod rust_doc;
6pub mod generated_lints;
6 7
7use std::collections::VecDeque; 8use std::collections::VecDeque;
8 9
diff --git a/crates/ide_db/src/helpers/generated_lints.rs b/crates/ide_db/src/helpers/generated_lints.rs
new file mode 100644
index 000000000..77021bae0
--- /dev/null
+++ b/crates/ide_db/src/helpers/generated_lints.rs
@@ -0,0 +1,6891 @@
1//! Generated file, do not edit by hand, see `xtask/src/codegen`
2
3pub struct Lint {
4 pub label: &'static str,
5 pub description: &'static str,
6}
7
8pub const DEFAULT_LINTS: &[Lint] = &[
9 Lint { label: "----", description: r##"-------"## },
10 Lint {
11 label: "absolute-paths-not-starting-with-crate",
12 description: r##"fully qualified paths that start with a module name instead of `crate`, `self`, or an extern crate name"##,
13 },
14 Lint { label: "ambiguous-associated-items", description: r##"ambiguous associated items"## },
15 Lint { label: "anonymous-parameters", description: r##"detects anonymous parameters"## },
16 Lint { label: "arithmetic-overflow", description: r##"arithmetic operation overflows"## },
17 Lint { label: "array-into-iter", description: r##"detects calling `into_iter` on arrays"## },
18 Lint {
19 label: "asm-sub-register",
20 description: r##"using only a subset of a register for inline asm inputs"##,
21 },
22 Lint { label: "bad-asm-style", description: r##"incorrect use of inline assembly"## },
23 Lint {
24 label: "bare-trait-objects",
25 description: r##"suggest using `dyn Trait` for trait objects"##,
26 },
27 Lint {
28 label: "bindings-with-variant-name",
29 description: r##"detects pattern bindings with the same name as one of the matched variants"##,
30 },
31 Lint { label: "box-pointers", description: r##"use of owned (Box type) heap memory"## },
32 Lint {
33 label: "cenum-impl-drop-cast",
34 description: r##"a C-like enum implementing Drop is cast"##,
35 },
36 Lint {
37 label: "clashing-extern-declarations",
38 description: r##"detects when an extern fn has been declared with the same name but different types"##,
39 },
40 Lint {
41 label: "coherence-leak-check",
42 description: r##"distinct impls distinguished only by the leak-check code"##,
43 },
44 Lint {
45 label: "conflicting-repr-hints",
46 description: r##"conflicts between `#[repr(..)]` hints that were previously accepted and used in practice"##,
47 },
48 Lint {
49 label: "confusable-idents",
50 description: r##"detects visually confusable pairs between identifiers"##,
51 },
52 Lint {
53 label: "const-err",
54 description: r##"constant evaluation encountered erroneous expression"##,
55 },
56 Lint {
57 label: "const-evaluatable-unchecked",
58 description: r##"detects a generic constant is used in a type without a emitting a warning"##,
59 },
60 Lint {
61 label: "const-item-mutation",
62 description: r##"detects attempts to mutate a `const` item"##,
63 },
64 Lint { label: "dead-code", description: r##"detect unused, unexported items"## },
65 Lint { label: "deprecated", description: r##"detects use of deprecated items"## },
66 Lint {
67 label: "deprecated-in-future",
68 description: r##"detects use of items that will be deprecated in a future version"##,
69 },
70 Lint {
71 label: "deref-nullptr",
72 description: r##"detects when an null pointer is dereferenced"##,
73 },
74 Lint {
75 label: "disjoint-capture-migration",
76 description: r##"Drop reorder and auto traits error because of `capture_disjoint_fields`"##,
77 },
78 Lint { label: "drop-bounds", description: r##"bounds of the form `T: Drop` are useless"## },
79 Lint {
80 label: "elided-lifetimes-in-paths",
81 description: r##"hidden lifetime parameters in types are deprecated"##,
82 },
83 Lint {
84 label: "ellipsis-inclusive-range-patterns",
85 description: r##"`...` range patterns are deprecated"##,
86 },
87 Lint {
88 label: "explicit-outlives-requirements",
89 description: r##"outlives requirements can be inferred"##,
90 },
91 Lint {
92 label: "exported-private-dependencies",
93 description: r##"public interface leaks type from a private dependency"##,
94 },
95 Lint { label: "forbidden-lint-groups", description: r##"applying forbid to lint-groups"## },
96 Lint {
97 label: "function-item-references",
98 description: r##"suggest casting to a function pointer when attempting to take references to function items"##,
99 },
100 Lint {
101 label: "ill-formed-attribute-input",
102 description: r##"ill-formed attribute inputs that were previously accepted and used in practice"##,
103 },
104 Lint {
105 label: "illegal-floating-point-literal-pattern",
106 description: r##"floating-point literals cannot be used in patterns"##,
107 },
108 Lint {
109 label: "improper-ctypes",
110 description: r##"proper use of libc types in foreign modules"##,
111 },
112 Lint {
113 label: "improper-ctypes-definitions",
114 description: r##"proper use of libc types in foreign item definitions"##,
115 },
116 Lint {
117 label: "incomplete-features",
118 description: r##"incomplete features that may function improperly in some or all cases"##,
119 },
120 Lint { label: "incomplete-include", description: r##"trailing content in included file"## },
121 Lint {
122 label: "indirect-structural-match",
123 description: r##"constant used in pattern contains value of non-structural-match type in a field or a variant"##,
124 },
125 Lint {
126 label: "ineffective-unstable-trait-impl",
127 description: r##"detects `#[unstable]` on stable trait implementations for stable types"##,
128 },
129 Lint {
130 label: "inline-no-sanitize",
131 description: r##"detects incompatible use of `#[inline(always)]` and `#[no_sanitize(...)]`"##,
132 },
133 Lint {
134 label: "invalid-type-param-default",
135 description: r##"type parameter default erroneously allowed in invalid location"##,
136 },
137 Lint {
138 label: "invalid-value",
139 description: r##"an invalid value is being created (such as a null reference)"##,
140 },
141 Lint {
142 label: "irrefutable-let-patterns",
143 description: r##"detects irrefutable patterns in `if let` and `while let` statements"##,
144 },
145 Lint {
146 label: "keyword-idents",
147 description: r##"detects edition keywords being used as an identifier"##,
148 },
149 Lint { label: "large-assignments", description: r##"detects large moves or copies"## },
150 Lint {
151 label: "late-bound-lifetime-arguments",
152 description: r##"detects generic lifetime arguments in path segments with late bound lifetime parameters"##,
153 },
154 Lint {
155 label: "legacy-derive-helpers",
156 description: r##"detects derive helper attributes that are used before they are introduced"##,
157 },
158 Lint {
159 label: "macro-expanded-macro-exports-accessed-by-absolute-paths",
160 description: r##"macro-expanded `macro_export` macros from the current crate cannot be referred to by absolute paths"##,
161 },
162 Lint {
163 label: "macro-use-extern-crate",
164 description: r##"the `#[macro_use]` attribute is now deprecated in favor of using macros via the module system"##,
165 },
166 Lint {
167 label: "meta-variable-misuse",
168 description: r##"possible meta-variable misuse at macro definition"##,
169 },
170 Lint { label: "missing-abi", description: r##"No declared ABI for extern declaration"## },
171 Lint {
172 label: "missing-copy-implementations",
173 description: r##"detects potentially-forgotten implementations of `Copy`"##,
174 },
175 Lint {
176 label: "missing-debug-implementations",
177 description: r##"detects missing implementations of Debug"##,
178 },
179 Lint {
180 label: "missing-docs",
181 description: r##"detects missing documentation for public members"##,
182 },
183 Lint {
184 label: "missing-fragment-specifier",
185 description: r##"detects missing fragment specifiers in unused `macro_rules!` patterns"##,
186 },
187 Lint {
188 label: "mixed-script-confusables",
189 description: r##"detects Unicode scripts whose mixed script confusables codepoints are solely used"##,
190 },
191 Lint {
192 label: "mutable-borrow-reservation-conflict",
193 description: r##"reservation of a two-phased borrow conflicts with other shared borrows"##,
194 },
195 Lint {
196 label: "mutable-transmutes",
197 description: r##"mutating transmuted &mut T from &T may cause undefined behavior"##,
198 },
199 Lint {
200 label: "no-mangle-const-items",
201 description: r##"const items will not have their symbols exported"##,
202 },
203 Lint { label: "no-mangle-generic-items", description: r##"generic items must be mangled"## },
204 Lint { label: "non-ascii-idents", description: r##"detects non-ASCII identifiers"## },
205 Lint {
206 label: "non-camel-case-types",
207 description: r##"types, variants, traits and type parameters should have camel case names"##,
208 },
209 Lint {
210 label: "non-fmt-panic",
211 description: r##"detect single-argument panic!() invocations in which the argument is not a format string"##,
212 },
213 Lint {
214 label: "non-shorthand-field-patterns",
215 description: r##"using `Struct { x: x }` instead of `Struct { x }` in a pattern"##,
216 },
217 Lint {
218 label: "non-snake-case",
219 description: r##"variables, methods, functions, lifetime parameters and modules should have snake case names"##,
220 },
221 Lint {
222 label: "non-upper-case-globals",
223 description: r##"static constants should have uppercase identifiers"##,
224 },
225 Lint {
226 label: "nontrivial-structural-match",
227 description: r##"constant used in pattern of non-structural-match type and the constant's initializer expression contains values of non-structural-match types"##,
228 },
229 Lint {
230 label: "noop-method-call",
231 description: r##"detects the use of well-known noop methods"##,
232 },
233 Lint {
234 label: "or-patterns-back-compat",
235 description: r##"detects usage of old versions of or-patterns"##,
236 },
237 Lint {
238 label: "order-dependent-trait-objects",
239 description: r##"trait-object types were treated as different depending on marker-trait order"##,
240 },
241 Lint { label: "overflowing-literals", description: r##"literal out of range for its type"## },
242 Lint {
243 label: "overlapping-range-endpoints",
244 description: r##"detects range patterns with overlapping endpoints"##,
245 },
246 Lint { label: "path-statements", description: r##"path statements with no effect"## },
247 Lint {
248 label: "patterns-in-fns-without-body",
249 description: r##"patterns in functions without body were erroneously allowed"##,
250 },
251 Lint {
252 label: "pointer-structural-match",
253 description: r##"pointers are not structural-match"##,
254 },
255 Lint {
256 label: "private-in-public",
257 description: r##"detect private items in public interfaces not caught by the old implementation"##,
258 },
259 Lint {
260 label: "proc-macro-back-compat",
261 description: r##"detects usage of old versions of certain proc-macro crates"##,
262 },
263 Lint {
264 label: "proc-macro-derive-resolution-fallback",
265 description: r##"detects proc macro derives using inaccessible names from parent modules"##,
266 },
267 Lint {
268 label: "pub-use-of-private-extern-crate",
269 description: r##"detect public re-exports of private extern crates"##,
270 },
271 Lint {
272 label: "redundant-semicolons",
273 description: r##"detects unnecessary trailing semicolons"##,
274 },
275 Lint {
276 label: "renamed-and-removed-lints",
277 description: r##"lints that have been renamed or removed"##,
278 },
279 Lint {
280 label: "semicolon-in-expressions-from-macros",
281 description: r##"trailing semicolon in macro body used as expression"##,
282 },
283 Lint {
284 label: "single-use-lifetimes",
285 description: r##"detects lifetime parameters that are only used once"##,
286 },
287 Lint {
288 label: "soft-unstable",
289 description: r##"a feature gate that doesn't break dependent crates"##,
290 },
291 Lint {
292 label: "stable-features",
293 description: r##"stable features found in `#[feature]` directive"##,
294 },
295 Lint {
296 label: "temporary-cstring-as-ptr",
297 description: r##"detects getting the inner pointer of a temporary `CString`"##,
298 },
299 Lint {
300 label: "trivial-bounds",
301 description: r##"these bounds don't depend on an type parameters"##,
302 },
303 Lint {
304 label: "trivial-casts",
305 description: r##"detects trivial casts which could be removed"##,
306 },
307 Lint {
308 label: "trivial-numeric-casts",
309 description: r##"detects trivial casts of numeric types which could be removed"##,
310 },
311 Lint {
312 label: "type-alias-bounds",
313 description: r##"bounds in type aliases are not enforced"##,
314 },
315 Lint {
316 label: "tyvar-behind-raw-pointer",
317 description: r##"raw pointer to an inference variable"##,
318 },
319 Lint {
320 label: "unaligned-references",
321 description: r##"detects unaligned references to fields of packed structs"##,
322 },
323 Lint {
324 label: "uncommon-codepoints",
325 description: r##"detects uncommon Unicode codepoints in identifiers"##,
326 },
327 Lint {
328 label: "unconditional-panic",
329 description: r##"operation will cause a panic at runtime"##,
330 },
331 Lint {
332 label: "unconditional-recursion",
333 description: r##"functions that cannot return without calling themselves"##,
334 },
335 Lint { label: "uninhabited-static", description: r##"uninhabited static"## },
336 Lint {
337 label: "unknown-crate-types",
338 description: r##"unknown crate type found in `#[crate_type]` directive"##,
339 },
340 Lint { label: "unknown-lints", description: r##"unrecognized lint attribute"## },
341 Lint {
342 label: "unnameable-test-items",
343 description: r##"detects an item that cannot be named being marked as `#[test_case]`"##,
344 },
345 Lint { label: "unreachable-code", description: r##"detects unreachable code paths"## },
346 Lint { label: "unreachable-patterns", description: r##"detects unreachable patterns"## },
347 Lint {
348 label: "unreachable-pub",
349 description: r##"`pub` items not reachable from crate root"##,
350 },
351 Lint { label: "unsafe-code", description: r##"usage of `unsafe` code"## },
352 Lint {
353 label: "unsafe-op-in-unsafe-fn",
354 description: r##"unsafe operations in unsafe functions without an explicit unsafe block are deprecated"##,
355 },
356 Lint {
357 label: "unstable-features",
358 description: r##"enabling unstable features (deprecated. do not use)"##,
359 },
360 Lint {
361 label: "unstable-name-collisions",
362 description: r##"detects name collision with an existing but unstable method"##,
363 },
364 Lint {
365 label: "unsupported-naked-functions",
366 description: r##"unsupported naked function definitions"##,
367 },
368 Lint {
369 label: "unused-allocation",
370 description: r##"detects unnecessary allocations that can be eliminated"##,
371 },
372 Lint {
373 label: "unused-assignments",
374 description: r##"detect assignments that will never be read"##,
375 },
376 Lint {
377 label: "unused-attributes",
378 description: r##"detects attributes that were not used by the compiler"##,
379 },
380 Lint { label: "unused-braces", description: r##"unnecessary braces around an expression"## },
381 Lint {
382 label: "unused-comparisons",
383 description: r##"comparisons made useless by limits of the types involved"##,
384 },
385 Lint {
386 label: "unused-crate-dependencies",
387 description: r##"crate dependencies that are never used"##,
388 },
389 Lint {
390 label: "unused-doc-comments",
391 description: r##"detects doc comments that aren't used by rustdoc"##,
392 },
393 Lint { label: "unused-extern-crates", description: r##"extern crates that are never used"## },
394 Lint {
395 label: "unused-features",
396 description: r##"unused features found in crate-level `#[feature]` directives"##,
397 },
398 Lint {
399 label: "unused-import-braces",
400 description: r##"unnecessary braces around an imported item"##,
401 },
402 Lint { label: "unused-imports", description: r##"imports that are never used"## },
403 Lint { label: "unused-labels", description: r##"detects labels that are never used"## },
404 Lint {
405 label: "unused-lifetimes",
406 description: r##"detects lifetime parameters that are never used"##,
407 },
408 Lint { label: "unused-macros", description: r##"detects macros that were not used"## },
409 Lint {
410 label: "unused-must-use",
411 description: r##"unused result of a type flagged as `#[must_use]`"##,
412 },
413 Lint {
414 label: "unused-mut",
415 description: r##"detect mut variables which don't need to be mutable"##,
416 },
417 Lint {
418 label: "unused-parens",
419 description: r##"`if`, `match`, `while` and `return` do not need parentheses"##,
420 },
421 Lint {
422 label: "unused-qualifications",
423 description: r##"detects unnecessarily qualified names"##,
424 },
425 Lint {
426 label: "unused-results",
427 description: r##"unused result of an expression in a statement"##,
428 },
429 Lint { label: "unused-unsafe", description: r##"unnecessary use of an `unsafe` block"## },
430 Lint {
431 label: "unused-variables",
432 description: r##"detect variables which are not used in any way"##,
433 },
434 Lint {
435 label: "useless-deprecated",
436 description: r##"detects deprecation attributes with no effect"##,
437 },
438 Lint {
439 label: "variant-size-differences",
440 description: r##"detects enums with widely varying variant sizes"##,
441 },
442 Lint {
443 label: "warnings",
444 description: r##"mass-change the level for lints which produce warnings"##,
445 },
446 Lint {
447 label: "where-clauses-object-safety",
448 description: r##"checks the object safety of where clauses"##,
449 },
450 Lint {
451 label: "while-true",
452 description: r##"suggest using `loop { }` instead of `while true { }`"##,
453 },
454];
455
456pub const FEATURES: &[Lint] = &[
457 Lint {
458 label: "abi_c_cmse_nonsecure_call",
459 description: r##"# `abi_c_cmse_nonsecure_call`
460
461The tracking issue for this feature is: [#81391]
462
463[#81391]: https://github.com/rust-lang/rust/issues/81391
464
465------------------------
466
467The [TrustZone-M
468feature](https://developer.arm.com/documentation/100690/latest/) is available
469for targets with the Armv8-M architecture profile (`thumbv8m` in their target
470name).
471LLVM, the Rust compiler and the linker are providing
472[support](https://developer.arm.com/documentation/ecm0359818/latest/) for the
473TrustZone-M feature.
474
475One of the things provided, with this unstable feature, is the
476`C-cmse-nonsecure-call` function ABI. This ABI is used on function pointers to
477non-secure code to mark a non-secure function call (see [section
4785.5](https://developer.arm.com/documentation/ecm0359818/latest/) for details).
479
480With this ABI, the compiler will do the following to perform the call:
481* save registers needed after the call to Secure memory
482* clear all registers that might contain confidential information
483* clear the Least Significant Bit of the function address
484* branches using the BLXNS instruction
485
486To avoid using the non-secure stack, the compiler will constrain the number and
487type of parameters/return value.
488
489The `extern "C-cmse-nonsecure-call"` ABI is otherwise equivalent to the
490`extern "C"` ABI.
491
492<!-- NOTE(ignore) this example is specific to thumbv8m targets -->
493
494``` rust,ignore
495#![no_std]
496#![feature(abi_c_cmse_nonsecure_call)]
497
498#[no_mangle]
499pub fn call_nonsecure_function(addr: usize) -> u32 {
500 let non_secure_function =
501 unsafe { core::mem::transmute::<usize, extern "C-cmse-nonsecure-call" fn() -> u32>(addr) };
502 non_secure_function()
503}
504```
505
506``` text
507$ rustc --emit asm --crate-type lib --target thumbv8m.main-none-eabi function.rs
508
509call_nonsecure_function:
510 .fnstart
511 .save {r7, lr}
512 push {r7, lr}
513 .setfp r7, sp
514 mov r7, sp
515 .pad #16
516 sub sp, #16
517 str r0, [sp, #12]
518 ldr r0, [sp, #12]
519 str r0, [sp, #8]
520 b .LBB0_1
521.LBB0_1:
522 ldr r0, [sp, #8]
523 push.w {r4, r5, r6, r7, r8, r9, r10, r11}
524 bic r0, r0, #1
525 mov r1, r0
526 mov r2, r0
527 mov r3, r0
528 mov r4, r0
529 mov r5, r0
530 mov r6, r0
531 mov r7, r0
532 mov r8, r0
533 mov r9, r0
534 mov r10, r0
535 mov r11, r0
536 mov r12, r0
537 msr apsr_nzcvq, r0
538 blxns r0
539 pop.w {r4, r5, r6, r7, r8, r9, r10, r11}
540 str r0, [sp, #4]
541 b .LBB0_2
542.LBB0_2:
543 ldr r0, [sp, #4]
544 add sp, #16
545 pop {r7, pc}
546```
547"##,
548 },
549 Lint {
550 label: "abi_msp430_interrupt",
551 description: r##"# `abi_msp430_interrupt`
552
553The tracking issue for this feature is: [#38487]
554
555[#38487]: https://github.com/rust-lang/rust/issues/38487
556
557------------------------
558
559In the MSP430 architecture, interrupt handlers have a special calling
560convention. You can use the `"msp430-interrupt"` ABI to make the compiler apply
561the right calling convention to the interrupt handlers you define.
562
563<!-- NOTE(ignore) this example is specific to the msp430 target -->
564
565``` rust,ignore
566#![feature(abi_msp430_interrupt)]
567#![no_std]
568
569// Place the interrupt handler at the appropriate memory address
570// (Alternatively, you can use `#[used]` and remove `pub` and `#[no_mangle]`)
571#[link_section = "__interrupt_vector_10"]
572#[no_mangle]
573pub static TIM0_VECTOR: extern "msp430-interrupt" fn() = tim0;
574
575// The interrupt handler
576extern "msp430-interrupt" fn tim0() {
577 // ..
578}
579```
580
581``` text
582$ msp430-elf-objdump -CD ./target/msp430/release/app
583Disassembly of section __interrupt_vector_10:
584
5850000fff2 <TIM0_VECTOR>:
586 fff2: 00 c0 interrupt service routine at 0xc000
587
588Disassembly of section .text:
589
5900000c000 <int::tim0>:
591 c000: 00 13 reti
592```
593"##,
594 },
595 Lint {
596 label: "abi_ptx",
597 description: r##"# `abi_ptx`
598
599The tracking issue for this feature is: [#38788]
600
601[#38788]: https://github.com/rust-lang/rust/issues/38788
602
603------------------------
604
605When emitting PTX code, all vanilla Rust functions (`fn`) get translated to
606"device" functions. These functions are *not* callable from the host via the
607CUDA API so a crate with only device functions is not too useful!
608
609OTOH, "global" functions *can* be called by the host; you can think of them
610as the real public API of your crate. To produce a global function use the
611`"ptx-kernel"` ABI.
612
613<!-- NOTE(ignore) this example is specific to the nvptx targets -->
614
615``` rust,ignore
616#![feature(abi_ptx)]
617#![no_std]
618
619pub unsafe extern "ptx-kernel" fn global_function() {
620 device_function();
621}
622
623pub fn device_function() {
624 // ..
625}
626```
627
628``` text
629$ xargo rustc --target nvptx64-nvidia-cuda --release -- --emit=asm
630
631$ cat $(find -name '*.s')
632//
633// Generated by LLVM NVPTX Back-End
634//
635
636.version 3.2
637.target sm_20
638.address_size 64
639
640 // .globl _ZN6kernel15global_function17h46111ebe6516b382E
641
642.visible .entry _ZN6kernel15global_function17h46111ebe6516b382E()
643{
644
645
646 ret;
647}
648
649 // .globl _ZN6kernel15device_function17hd6a0e4993bbf3f78E
650.visible .func _ZN6kernel15device_function17hd6a0e4993bbf3f78E()
651{
652
653
654 ret;
655}
656```
657"##,
658 },
659 Lint {
660 label: "abi_thiscall",
661 description: r##"# `abi_thiscall`
662
663The tracking issue for this feature is: [#42202]
664
665[#42202]: https://github.com/rust-lang/rust/issues/42202
666
667------------------------
668
669The MSVC ABI on x86 Windows uses the `thiscall` calling convention for C++
670instance methods by default; it is identical to the usual (C) calling
671convention on x86 Windows except that the first parameter of the method,
672the `this` pointer, is passed in the ECX register.
673"##,
674 },
675 Lint {
676 label: "allocator_api",
677 description: r##"# `allocator_api`
678
679The tracking issue for this feature is [#32838]
680
681[#32838]: https://github.com/rust-lang/rust/issues/32838
682
683------------------------
684
685Sometimes you want the memory for one collection to use a different
686allocator than the memory for another collection. In this case,
687replacing the global allocator is not a workable option. Instead,
688you need to pass in an instance of an `AllocRef` to each collection
689for which you want a custom allocator.
690
691TBD
692"##,
693 },
694 Lint {
695 label: "allocator_internals",
696 description: r##"# `allocator_internals`
697
698This feature does not have a tracking issue, it is an unstable implementation
699detail of the `global_allocator` feature not intended for use outside the
700compiler.
701
702------------------------
703"##,
704 },
705 Lint {
706 label: "arbitrary_enum_discriminant",
707 description: r##"# `arbitrary_enum_discriminant`
708
709The tracking issue for this feature is: [#60553]
710
711[#60553]: https://github.com/rust-lang/rust/issues/60553
712
713------------------------
714
715The `arbitrary_enum_discriminant` feature permits tuple-like and
716struct-like enum variants with `#[repr(<int-type>)]` to have explicit discriminants.
717
718## Examples
719
720```rust
721#![feature(arbitrary_enum_discriminant)]
722
723#[allow(dead_code)]
724#[repr(u8)]
725enum Enum {
726 Unit = 3,
727 Tuple(u16) = 2,
728 Struct {
729 a: u8,
730 b: u16,
731 } = 1,
732}
733
734impl Enum {
735 fn tag(&self) -> u8 {
736 unsafe { *(self as *const Self as *const u8) }
737 }
738}
739
740assert_eq!(3, Enum::Unit.tag());
741assert_eq!(2, Enum::Tuple(5).tag());
742assert_eq!(1, Enum::Struct{a: 7, b: 11}.tag());
743```
744"##,
745 },
746 Lint {
747 label: "asm",
748 description: r##"# `asm`
749
750The tracking issue for this feature is: [#72016]
751
752[#72016]: https://github.com/rust-lang/rust/issues/72016
753
754------------------------
755
756For extremely low-level manipulations and performance reasons, one
757might wish to control the CPU directly. Rust supports using inline
758assembly to do this via the `asm!` macro.
759
760# Guide-level explanation
761[guide-level-explanation]: #guide-level-explanation
762
763Rust provides support for inline assembly via the `asm!` macro.
764It can be used to embed handwritten assembly in the assembly output generated by the compiler.
765Generally this should not be necessary, but might be where the required performance or timing
766cannot be otherwise achieved. Accessing low level hardware primitives, e.g. in kernel code, may also demand this functionality.
767
768> **Note**: the examples here are given in x86/x86-64 assembly, but other architectures are also supported.
769
770Inline assembly is currently supported on the following architectures:
771- x86 and x86-64
772- ARM
773- AArch64
774- RISC-V
775- NVPTX
776- PowerPC
777- Hexagon
778- MIPS32r2 and MIPS64r2
779- wasm32
780
781## Basic usage
782
783Let us start with the simplest possible example:
784
785```rust,allow_fail
786#![feature(asm)]
787unsafe {
788 asm!("nop");
789}
790```
791
792This will insert a NOP (no operation) instruction into the assembly generated by the compiler.
793Note that all `asm!` invocations have to be inside an `unsafe` block, as they could insert
794arbitrary instructions and break various invariants. The instructions to be inserted are listed
795in the first argument of the `asm!` macro as a string literal.
796
797## Inputs and outputs
798
799Now inserting an instruction that does nothing is rather boring. Let us do something that
800actually acts on data:
801
802```rust,allow_fail
803#![feature(asm)]
804let x: u64;
805unsafe {
806 asm!("mov {}, 5", out(reg) x);
807}
808assert_eq!(x, 5);
809```
810
811This will write the value `5` into the `u64` variable `x`.
812You can see that the string literal we use to specify instructions is actually a template string.
813It is governed by the same rules as Rust [format strings][format-syntax].
814The arguments that are inserted into the template however look a bit different then you may
815be familiar with. First we need to specify if the variable is an input or an output of the
816inline assembly. In this case it is an output. We declared this by writing `out`.
817We also need to specify in what kind of register the assembly expects the variable.
818In this case we put it in an arbitrary general purpose register by specifying `reg`.
819The compiler will choose an appropriate register to insert into
820the template and will read the variable from there after the inline assembly finishes executing.
821
822Let us see another example that also uses an input:
823
824```rust,allow_fail
825#![feature(asm)]
826let i: u64 = 3;
827let o: u64;
828unsafe {
829 asm!(
830 "mov {0}, {1}",
831 "add {0}, {number}",
832 out(reg) o,
833 in(reg) i,
834 number = const 5,
835 );
836}
837assert_eq!(o, 8);
838```
839
840This will add `5` to the input in variable `i` and write the result to variable `o`.
841The particular way this assembly does this is first copying the value from `i` to the output,
842and then adding `5` to it.
843
844The example shows a few things:
845
846First, we can see that `asm!` allows multiple template string arguments; each
847one is treated as a separate line of assembly code, as if they were all joined
848together with newlines between them. This makes it easy to format assembly
849code.
850
851Second, we can see that inputs are declared by writing `in` instead of `out`.
852
853Third, one of our operands has a type we haven't seen yet, `const`.
854This tells the compiler to expand this argument to value directly inside the assembly template.
855This is only possible for constants and literals.
856
857Fourth, we can see that we can specify an argument number, or name as in any format string.
858For inline assembly templates this is particularly useful as arguments are often used more than once.
859For more complex inline assembly using this facility is generally recommended, as it improves
860readability, and allows reordering instructions without changing the argument order.
861
862We can further refine the above example to avoid the `mov` instruction:
863
864```rust,allow_fail
865#![feature(asm)]
866let mut x: u64 = 3;
867unsafe {
868 asm!("add {0}, {number}", inout(reg) x, number = const 5);
869}
870assert_eq!(x, 8);
871```
872
873We can see that `inout` is used to specify an argument that is both input and output.
874This is different from specifying an input and output separately in that it is guaranteed to assign both to the same register.
875
876It is also possible to specify different variables for the input and output parts of an `inout` operand:
877
878```rust,allow_fail
879#![feature(asm)]
880let x: u64 = 3;
881let y: u64;
882unsafe {
883 asm!("add {0}, {number}", inout(reg) x => y, number = const 5);
884}
885assert_eq!(y, 8);
886```
887
888## Late output operands
889
890The Rust compiler is conservative with its allocation of operands. It is assumed that an `out`
891can be written at any time, and can therefore not share its location with any other argument.
892However, to guarantee optimal performance it is important to use as few registers as possible,
893so they won't have to be saved and reloaded around the inline assembly block.
894To achieve this Rust provides a `lateout` specifier. This can be used on any output that is
895written only after all inputs have been consumed.
896There is also a `inlateout` variant of this specifier.
897
898Here is an example where `inlateout` *cannot* be used:
899
900```rust,allow_fail
901#![feature(asm)]
902let mut a: u64 = 4;
903let b: u64 = 4;
904let c: u64 = 4;
905unsafe {
906 asm!(
907 "add {0}, {1}",
908 "add {0}, {2}",
909 inout(reg) a,
910 in(reg) b,
911 in(reg) c,
912 );
913}
914assert_eq!(a, 12);
915```
916
917Here 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.
918
919However the following example can use `inlateout` since the output is only modified after all input registers have been read:
920
921```rust,allow_fail
922#![feature(asm)]
923let mut a: u64 = 4;
924let b: u64 = 4;
925unsafe {
926 asm!("add {0}, {1}", inlateout(reg) a, in(reg) b);
927}
928assert_eq!(a, 8);
929```
930
931As you can see, this assembly fragment will still work correctly if `a` and `b` are assigned to the same register.
932
933## Explicit register operands
934
935Some instructions require that the operands be in a specific register.
936Therefore, Rust inline assembly provides some more specific constraint specifiers.
937While `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`
938among others can be addressed by their name.
939
940```rust,allow_fail,no_run
941#![feature(asm)]
942let cmd = 0xd1;
943unsafe {
944 asm!("out 0x64, eax", in("eax") cmd);
945}
946```
947
948In this example we call the `out` instruction to output the content of the `cmd` variable
949to port `0x64`. Since the `out` instruction only accepts `eax` (and its sub registers) as operand
950we had to use the `eax` constraint specifier.
951
952Note 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.
953
954Consider this example which uses the x86 `mul` instruction:
955
956```rust,allow_fail
957#![feature(asm)]
958fn mul(a: u64, b: u64) -> u128 {
959 let lo: u64;
960 let hi: u64;
961
962 unsafe {
963 asm!(
964 // The x86 mul instruction takes rax as an implicit input and writes
965 // the 128-bit result of the multiplication to rax:rdx.
966 "mul {}",
967 in(reg) a,
968 inlateout("rax") b => lo,
969 lateout("rdx") hi
970 );
971 }
972
973 ((hi as u128) << 64) + lo as u128
974}
975```
976
977This uses the `mul` instruction to multiply two 64-bit inputs with a 128-bit result.
978The only explicit operand is a register, that we fill from the variable `a`.
979The second operand is implicit, and must be the `rax` register, which we fill from the variable `b`.
980The lower 64 bits of the result are stored in `rax` from which we fill the variable `lo`.
981The higher 64 bits are stored in `rdx` from which we fill the variable `hi`.
982
983## Clobbered registers
984
985In many cases inline assembly will modify state that is not needed as an output.
986Usually this is either because we have to use a scratch register in the assembly,
987or instructions modify state that we don't need to further examine.
988This state is generally referred to as being "clobbered".
989We need to tell the compiler about this since it may need to save and restore this state
990around the inline assembly block.
991
992```rust,allow_fail
993#![feature(asm)]
994let ebx: u32;
995let ecx: u32;
996
997unsafe {
998 asm!(
999 "cpuid",
1000 // EAX 4 selects the "Deterministic Cache Parameters" CPUID leaf
1001 inout("eax") 4 => _,
1002 // ECX 0 selects the L0 cache information.
1003 inout("ecx") 0 => ecx,
1004 lateout("ebx") ebx,
1005 lateout("edx") _,
1006 );
1007}
1008
1009println!(
1010 "L1 Cache: {}",
1011 ((ebx >> 22) + 1) * (((ebx >> 12) & 0x3ff) + 1) * ((ebx & 0xfff) + 1) * (ecx + 1)
1012);
1013```
1014
1015In the example above we use the `cpuid` instruction to get the L1 cache size.
1016This instruction writes to `eax`, `ebx`, `ecx`, and `edx`, but for the cache size we only care about the contents of `ebx` and `ecx`.
1017
1018However 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.
1019
1020This can also be used with a general register class (e.g. `reg`) to obtain a scratch register for use inside the asm code:
1021
1022```rust,allow_fail
1023#![feature(asm)]
1024// Multiply x by 6 using shifts and adds
1025let mut x: u64 = 4;
1026unsafe {
1027 asm!(
1028 "mov {tmp}, {x}",
1029 "shl {tmp}, 1",
1030 "shl {x}, 2",
1031 "add {x}, {tmp}",
1032 x = inout(reg) x,
1033 tmp = out(reg) _,
1034 );
1035}
1036assert_eq!(x, 4 * 6);
1037```
1038
1039## Symbol operands
1040
1041A special operand type, `sym`, allows you to use the symbol name of a `fn` or `static` in inline assembly code.
1042This allows you to call a function or access a global variable without needing to keep its address in a register.
1043
1044```rust,allow_fail
1045#![feature(asm)]
1046extern "C" fn foo(arg: i32) {
1047 println!("arg = {}", arg);
1048}
1049
1050fn call_foo(arg: i32) {
1051 unsafe {
1052 asm!(
1053 "call {}",
1054 sym foo,
1055 // 1st argument in rdi, which is caller-saved
1056 inout("rdi") arg => _,
1057 // All caller-saved registers must be marked as clobbered
1058 out("rax") _, out("rcx") _, out("rdx") _, out("rsi") _,
1059 out("r8") _, out("r9") _, out("r10") _, out("r11") _,
1060 out("xmm0") _, out("xmm1") _, out("xmm2") _, out("xmm3") _,
1061 out("xmm4") _, out("xmm5") _, out("xmm6") _, out("xmm7") _,
1062 out("xmm8") _, out("xmm9") _, out("xmm10") _, out("xmm11") _,
1063 out("xmm12") _, out("xmm13") _, out("xmm14") _, out("xmm15") _,
1064 // Also mark AVX-512 registers as clobbered. This is accepted by the
1065 // compiler even if AVX-512 is not enabled on the current target.
1066 out("xmm16") _, out("xmm17") _, out("xmm18") _, out("xmm19") _,
1067 out("xmm20") _, out("xmm21") _, out("xmm22") _, out("xmm23") _,
1068 out("xmm24") _, out("xmm25") _, out("xmm26") _, out("xmm27") _,
1069 out("xmm28") _, out("xmm29") _, out("xmm30") _, out("xmm31") _,
1070 )
1071 }
1072}
1073```
1074
1075Note that the `fn` or `static` item does not need to be public or `#[no_mangle]`:
1076the compiler will automatically insert the appropriate mangled symbol name into the assembly code.
1077
1078## Register template modifiers
1079
1080In 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).
1081
1082By 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).
1083
1084This default can be overriden by using modifiers on the template string operands, just like you would with format strings:
1085
1086```rust,allow_fail
1087#![feature(asm)]
1088let mut x: u16 = 0xab;
1089
1090unsafe {
1091 asm!("mov {0:h}, {0:l}", inout(reg_abcd) x);
1092}
1093
1094assert_eq!(x, 0xabab);
1095```
1096
1097In 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.
1098
1099Let us assume that the register allocator has chosen to allocate `x` in the `ax` register.
1100The `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.
1101
1102If 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.
1103
1104## Memory address operands
1105
1106Sometimes assembly instructions require operands passed via memory addresses/memory locations.
1107You have to manually use the memory address syntax specified by the respectively architectures.
1108For example, in x86/x86_64 and intel assembly syntax, you should wrap inputs/outputs in `[]`
1109to indicate they are memory operands:
1110
1111```rust,allow_fail
1112#![feature(asm, llvm_asm)]
1113# fn load_fpu_control_word(control: u16) {
1114unsafe {
1115 asm!("fldcw [{}]", in(reg) &control, options(nostack));
1116
1117 // Previously this would have been written with the deprecated `llvm_asm!` like this
1118 llvm_asm!("fldcw $0" :: "m" (control) :: "volatile");
1119}
1120# }
1121```
1122
1123## Labels
1124
1125The compiler is allowed to instantiate multiple copies an `asm!` block, for example when the function containing it is inlined in multiple places. As a consequence, you should only use GNU assembler [local labels] inside inline assembly code. Defining symbols in assembly code may lead to assembler and/or linker errors due to duplicate symbol definitions.
1126
1127Moreover, due to [an llvm bug], you shouldn't use labels exclusively made of `0` and `1` digits, e.g. `0`, `11` or `101010`, as they may end up being interpreted as binary values.
1128
1129```rust,allow_fail
1130#![feature(asm)]
1131
1132let mut a = 0;
1133unsafe {
1134 asm!(
1135 "mov {0}, 10",
1136 "2:",
1137 "sub {0}, 1",
1138 "cmp {0}, 3",
1139 "jle 2f",
1140 "jmp 2b",
1141 "2:",
1142 "add {0}, 2",
1143 out(reg) a
1144 );
1145}
1146assert_eq!(a, 5);
1147```
1148
1149This will decrement the `{0}` register value from 10 to 3, then add 2 and store it in `a`.
1150
1151This example show a few thing:
1152
1153First that the same number can be used as a label multiple times in the same inline block.
1154
1155Second, that when a numeric label is used as a reference (as an instruction operand, for example), the suffixes b (“backward”) or f (“forward”) should be added to the numeric label. It will then refer to the nearest label defined by this number in this direction.
1156
1157[local labels]: https://sourceware.org/binutils/docs/as/Symbol-Names.html#Local-Labels
1158[an llvm bug]: https://bugs.llvm.org/show_bug.cgi?id=36144
1159
1160## Options
1161
1162By 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.
1163
1164Let's take our previous example of an `add` instruction:
1165
1166```rust,allow_fail
1167#![feature(asm)]
1168let mut a: u64 = 4;
1169let b: u64 = 4;
1170unsafe {
1171 asm!(
1172 "add {0}, {1}",
1173 inlateout(reg) a, in(reg) b,
1174 options(pure, nomem, nostack),
1175 );
1176}
1177assert_eq!(a, 8);
1178```
1179
1180Options can be provided as an optional final argument to the `asm!` macro. We specified three options here:
1181- `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.
1182- `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).
1183- `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.
1184
1185These allow the compiler to better optimize code using `asm!`, for example by eliminating pure `asm!` blocks whose outputs are not needed.
1186
1187See the reference for the full list of available options and their effects.
1188
1189# Reference-level explanation
1190[reference-level-explanation]: #reference-level-explanation
1191
1192Inline assembler is implemented as an unsafe macro `asm!()`.
1193The first argument to this macro is a template string literal used to build the final assembly.
1194The following arguments specify input and output operands.
1195When required, options are specified as the final argument.
1196
1197The following ABNF specifies the general syntax:
1198
1199```text
1200dir_spec := "in" / "out" / "lateout" / "inout" / "inlateout"
1201reg_spec := <register class> / "<explicit register>"
1202operand_expr := expr / "_" / expr "=>" expr / expr "=>" "_"
1203reg_operand := dir_spec "(" reg_spec ")" operand_expr
1204operand := reg_operand / "const" const_expr / "sym" path
1205option := "pure" / "nomem" / "readonly" / "preserves_flags" / "noreturn" / "nostack" / "att_syntax"
1206options := "options(" option *["," option] [","] ")"
1207asm := "asm!(" format_string *("," format_string) *("," [ident "="] operand) ["," options] [","] ")"
1208```
1209
1210The macro will initially be supported only on ARM, AArch64, Hexagon, PowerPC, x86, x86-64 and RISC-V targets. Support for more targets may be added in the future. The compiler will emit an error if `asm!` is used on an unsupported target.
1211
1212[format-syntax]: https://doc.rust-lang.org/std/fmt/#syntax
1213
1214## Template string arguments
1215
1216The 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.
1217
1218An `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.
1219
1220As 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.
1221
1222Explicit 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.
1223
1224The 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.
1225
1226The 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.
1227
1228[rfc-2795]: https://github.com/rust-lang/rfcs/pull/2795
1229
1230## Operand type
1231
1232Several types of operands are supported:
1233
1234* `in(<reg>) <expr>`
1235 - `<reg>` can refer to a register class or an explicit register. The allocated register name is substituted into the asm template string.
1236 - The allocated register will contain the value of `<expr>` at the start of the asm code.
1237 - 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).
1238* `out(<reg>) <expr>`
1239 - `<reg>` can refer to a register class or an explicit register. The allocated register name is substituted into the asm template string.
1240 - The allocated register will contain an undefined value at the start of the asm code.
1241 - `<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.
1242 - 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).
1243* `lateout(<reg>) <expr>`
1244 - Identical to `out` except that the register allocator can reuse a register allocated to an `in`.
1245 - You should only write to the register after all inputs are read, otherwise you may clobber an input.
1246* `inout(<reg>) <expr>`
1247 - `<reg>` can refer to a register class or an explicit register. The allocated register name is substituted into the asm template string.
1248 - The allocated register will contain the value of `<expr>` at the start of the asm code.
1249 - `<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.
1250* `inout(<reg>) <in expr> => <out expr>`
1251 - Same as `inout` except that the initial value of the register is taken from the value of `<in expr>`.
1252 - `<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.
1253 - 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).
1254 - `<in expr>` and `<out expr>` may have different types.
1255* `inlateout(<reg>) <expr>` / `inlateout(<reg>) <in expr> => <out expr>`
1256 - 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`).
1257 - You should only write to the register after all inputs are read, otherwise you may clobber an input.
1258* `const <expr>`
1259 - `<expr>` must be an integer constant expression.
1260 - The value of the expression is formatted as a string and substituted directly into the asm template string.
1261* `sym <path>`
1262 - `<path>` must refer to a `fn` or `static`.
1263 - A mangled symbol name referring to the item is substituted into the asm template string.
1264 - The substituted string does not include any modifiers (e.g. GOT, PLT, relocations, etc).
1265 - `<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.
1266
1267Operand 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.
1268
1269## Register operands
1270
1271Input 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).
1272
1273Note 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.
1274
1275Only the following types are allowed as operands for inline assembly:
1276- Integers (signed and unsigned)
1277- Floating-point numbers
1278- Pointers (thin only)
1279- Function pointers
1280- 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).
1281
1282Here is the list of currently supported register classes:
1283
1284| Architecture | Register class | Registers | LLVM constraint code |
1285| ------------ | -------------- | --------- | -------------------- |
1286| x86 | `reg` | `ax`, `bx`, `cx`, `dx`, `si`, `di`, `bp`, `r[8-15]` (x86-64 only) | `r` |
1287| x86 | `reg_abcd` | `ax`, `bx`, `cx`, `dx` | `Q` |
1288| x86-32 | `reg_byte` | `al`, `bl`, `cl`, `dl`, `ah`, `bh`, `ch`, `dh` | `q` |
1289| x86-64 | `reg_byte`\* | `al`, `bl`, `cl`, `dl`, `sil`, `dil`, `bpl`, `r[8-15]b` | `q` |
1290| x86 | `xmm_reg` | `xmm[0-7]` (x86) `xmm[0-15]` (x86-64) | `x` |
1291| x86 | `ymm_reg` | `ymm[0-7]` (x86) `ymm[0-15]` (x86-64) | `x` |
1292| x86 | `zmm_reg` | `zmm[0-7]` (x86) `zmm[0-31]` (x86-64) | `v` |
1293| x86 | `kreg` | `k[1-7]` | `Yk` |
1294| AArch64 | `reg` | `x[0-30]` | `r` |
1295| AArch64 | `vreg` | `v[0-31]` | `w` |
1296| AArch64 | `vreg_low16` | `v[0-15]` | `x` |
1297| ARM | `reg` | `r[0-12]`, `r14` | `r` |
1298| ARM (Thumb) | `reg_thumb` | `r[0-r7]` | `l` |
1299| ARM (ARM) | `reg_thumb` | `r[0-r12]`, `r14` | `l` |
1300| ARM | `sreg` | `s[0-31]` | `t` |
1301| ARM | `sreg_low16` | `s[0-15]` | `x` |
1302| ARM | `dreg` | `d[0-31]` | `w` |
1303| ARM | `dreg_low16` | `d[0-15]` | `t` |
1304| ARM | `dreg_low8` | `d[0-8]` | `x` |
1305| ARM | `qreg` | `q[0-15]` | `w` |
1306| ARM | `qreg_low8` | `q[0-7]` | `t` |
1307| ARM | `qreg_low4` | `q[0-3]` | `x` |
1308| MIPS | `reg` | `$[2-25]` | `r` |
1309| MIPS | `freg` | `$f[0-31]` | `f` |
1310| NVPTX | `reg16` | None\* | `h` |
1311| NVPTX | `reg32` | None\* | `r` |
1312| NVPTX | `reg64` | None\* | `l` |
1313| RISC-V | `reg` | `x1`, `x[5-7]`, `x[9-15]`, `x[16-31]` (non-RV32E) | `r` |
1314| RISC-V | `freg` | `f[0-31]` | `f` |
1315| Hexagon | `reg` | `r[0-28]` | `r` |
1316| PowerPC | `reg` | `r[0-31]` | `r` |
1317| PowerPC | `reg_nonzero` | | `r[1-31]` | `b` |
1318| PowerPC | `freg` | `f[0-31]` | `f` |
1319| wasm32 | `local` | None\* | `r` |
1320
1321> **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.
1322>
1323> Note #2: On x86-64 the high byte registers (e.g. `ah`) are not available in the `reg_byte` register class.
1324>
1325> Note #3: NVPTX doesn't have a fixed register set, so named registers are not supported.
1326>
1327> Note #4: WebAssembly doesn't have registers, so named registers are not supported.
1328
1329Additional register classes may be added in the future based on demand (e.g. MMX, x87, etc).
1330
1331Each 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.
1332
1333| Architecture | Register class | Target feature | Allowed types |
1334| ------------ | -------------- | -------------- | ------------- |
1335| x86-32 | `reg` | None | `i16`, `i32`, `f32` |
1336| x86-64 | `reg` | None | `i16`, `i32`, `f32`, `i64`, `f64` |
1337| x86 | `reg_byte` | None | `i8` |
1338| x86 | `xmm_reg` | `sse` | `i32`, `f32`, `i64`, `f64`, <br> `i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` |
1339| x86 | `ymm_reg` | `avx` | `i32`, `f32`, `i64`, `f64`, <br> `i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` <br> `i8x32`, `i16x16`, `i32x8`, `i64x4`, `f32x8`, `f64x4` |
1340| 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` |
1341| x86 | `kreg` | `axv512f` | `i8`, `i16` |
1342| x86 | `kreg` | `axv512bw` | `i32`, `i64` |
1343| AArch64 | `reg` | None | `i8`, `i16`, `i32`, `f32`, `i64`, `f64` |
1344| AArch64 | `vreg` | `fp` | `i8`, `i16`, `i32`, `f32`, `i64`, `f64`, <br> `i8x8`, `i16x4`, `i32x2`, `i64x1`, `f32x2`, `f64x1`, <br> `i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` |
1345| ARM | `reg` | None | `i8`, `i16`, `i32`, `f32` |
1346| ARM | `sreg` | `vfp2` | `i32`, `f32` |
1347| ARM | `dreg` | `vfp2` | `i64`, `f64`, `i8x8`, `i16x4`, `i32x2`, `i64x1`, `f32x2` |
1348| ARM | `qreg` | `neon` | `i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4` |
1349| MIPS32 | `reg` | None | `i8`, `i16`, `i32`, `f32` |
1350| MIPS32 | `freg` | None | `f32`, `f64` |
1351| MIPS64 | `reg` | None | `i8`, `i16`, `i32`, `i64`, `f32`, `f64` |
1352| MIPS64 | `freg` | None | `f32`, `f64` |
1353| NVPTX | `reg16` | None | `i8`, `i16` |
1354| NVPTX | `reg32` | None | `i8`, `i16`, `i32`, `f32` |
1355| NVPTX | `reg64` | None | `i8`, `i16`, `i32`, `f32`, `i64`, `f64` |
1356| RISC-V32 | `reg` | None | `i8`, `i16`, `i32`, `f32` |
1357| RISC-V64 | `reg` | None | `i8`, `i16`, `i32`, `f32`, `i64`, `f64` |
1358| RISC-V | `freg` | `f` | `f32` |
1359| RISC-V | `freg` | `d` | `f64` |
1360| Hexagon | `reg` | None | `i8`, `i16`, `i32`, `f32` |
1361| PowerPC | `reg` | None | `i8`, `i16`, `i32` |
1362| PowerPC | `reg_nonzero` | None | `i8`, `i16`, `i32` |
1363| PowerPC | `freg` | None | `f32`, `f64` |
1364| wasm32 | `local` | None | `i8` `i16` `i32` `i64` `f32` `f64` |
1365
1366> **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).
1367
1368If 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.
1369
1370When 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.
1371
1372## Register names
1373
1374Some 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:
1375
1376| Architecture | Base register | Aliases |
1377| ------------ | ------------- | ------- |
1378| x86 | `ax` | `eax`, `rax` |
1379| x86 | `bx` | `ebx`, `rbx` |
1380| x86 | `cx` | `ecx`, `rcx` |
1381| x86 | `dx` | `edx`, `rdx` |
1382| x86 | `si` | `esi`, `rsi` |
1383| x86 | `di` | `edi`, `rdi` |
1384| x86 | `bp` | `bpl`, `ebp`, `rbp` |
1385| x86 | `sp` | `spl`, `esp`, `rsp` |
1386| x86 | `ip` | `eip`, `rip` |
1387| x86 | `st(0)` | `st` |
1388| x86 | `r[8-15]` | `r[8-15]b`, `r[8-15]w`, `r[8-15]d` |
1389| x86 | `xmm[0-31]` | `ymm[0-31]`, `zmm[0-31]` |
1390| AArch64 | `x[0-30]` | `w[0-30]` |
1391| AArch64 | `x29` | `fp` |
1392| AArch64 | `x30` | `lr` |
1393| AArch64 | `sp` | `wsp` |
1394| AArch64 | `xzr` | `wzr` |
1395| AArch64 | `v[0-31]` | `b[0-31]`, `h[0-31]`, `s[0-31]`, `d[0-31]`, `q[0-31]` |
1396| ARM | `r[0-3]` | `a[1-4]` |
1397| ARM | `r[4-9]` | `v[1-6]` |
1398| ARM | `r9` | `rfp` |
1399| ARM | `r10` | `sl` |
1400| ARM | `r11` | `fp` |
1401| ARM | `r12` | `ip` |
1402| ARM | `r13` | `sp` |
1403| ARM | `r14` | `lr` |
1404| ARM | `r15` | `pc` |
1405| RISC-V | `x0` | `zero` |
1406| RISC-V | `x1` | `ra` |
1407| RISC-V | `x2` | `sp` |
1408| RISC-V | `x3` | `gp` |
1409| RISC-V | `x4` | `tp` |
1410| RISC-V | `x[5-7]` | `t[0-2]` |
1411| RISC-V | `x8` | `fp`, `s0` |
1412| RISC-V | `x9` | `s1` |
1413| RISC-V | `x[10-17]` | `a[0-7]` |
1414| RISC-V | `x[18-27]` | `s[2-11]` |
1415| RISC-V | `x[28-31]` | `t[3-6]` |
1416| RISC-V | `f[0-7]` | `ft[0-7]` |
1417| RISC-V | `f[8-9]` | `fs[0-1]` |
1418| RISC-V | `f[10-17]` | `fa[0-7]` |
1419| RISC-V | `f[18-27]` | `fs[2-11]` |
1420| RISC-V | `f[28-31]` | `ft[8-11]` |
1421| Hexagon | `r29` | `sp` |
1422| Hexagon | `r30` | `fr` |
1423| Hexagon | `r31` | `lr` |
1424
1425Some registers cannot be used for input or output operands:
1426
1427| Architecture | Unsupported register | Reason |
1428| ------------ | -------------------- | ------ |
1429| All | `sp` | The stack pointer must be restored to its original value at the end of an asm code block. |
1430| All | `bp` (x86), `x29` (AArch64), `x8` (RISC-V), `fr` (Hexagon), `$fp` (MIPS) | The frame pointer cannot be used as an input or output. |
1431| 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. |
1432| All | `si` (x86-32), `bx` (x86-64), `r6` (ARM), `x19` (AArch64), `r19` (Hexagon), `x9` (RISC-V) | This is used internally by LLVM as a "base pointer" for functions with complex stack frames. |
1433| x86 | `k0` | This is a constant zero register which can't be modified. |
1434| x86 | `ip` | This is the program counter, not a real register. |
1435| x86 | `mm[0-7]` | MMX registers are not currently supported (but may be in the future). |
1436| x86 | `st([0-7])` | x87 registers are not currently supported (but may be in the future). |
1437| AArch64 | `xzr` | This is a constant zero register which can't be modified. |
1438| ARM | `pc` | This is the program counter, not a real register. |
1439| ARM | `r9` | This is a reserved register on some ARM targets. |
1440| MIPS | `$0` or `$zero` | This is a constant zero register which can't be modified. |
1441| MIPS | `$1` or `$at` | Reserved for assembler. |
1442| MIPS | `$26`/`$k0`, `$27`/`$k1` | OS-reserved registers. |
1443| MIPS | `$28`/`$gp` | Global pointer cannot be used as inputs or outputs. |
1444| MIPS | `$ra` | Return address cannot be used as inputs or outputs. |
1445| RISC-V | `x0` | This is a constant zero register which can't be modified. |
1446| RISC-V | `gp`, `tp` | These registers are reserved and cannot be used as inputs or outputs. |
1447| Hexagon | `lr` | This is the link register which cannot be used as an input or output. |
1448
1449In some cases LLVM will allocate a "reserved register" for `reg` operands even though this register cannot be explicitly specified. Assembly code making use of reserved registers should be careful since `reg` operands may alias with those registers. Reserved registers are the frame pointer and base pointer
1450- The frame pointer and LLVM base pointer on all architectures.
1451- `r9` on ARM.
1452- `x18` on AArch64.
1453
1454## Template modifiers
1455
1456The 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.
1457
1458The 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.
1459
1460| Architecture | Register class | Modifier | Example output | LLVM modifier |
1461| ------------ | -------------- | -------- | -------------- | ------------- |
1462| x86-32 | `reg` | None | `eax` | `k` |
1463| x86-64 | `reg` | None | `rax` | `q` |
1464| x86-32 | `reg_abcd` | `l` | `al` | `b` |
1465| x86-64 | `reg` | `l` | `al` | `b` |
1466| x86 | `reg_abcd` | `h` | `ah` | `h` |
1467| x86 | `reg` | `x` | `ax` | `w` |
1468| x86 | `reg` | `e` | `eax` | `k` |
1469| x86-64 | `reg` | `r` | `rax` | `q` |
1470| x86 | `reg_byte` | None | `al` / `ah` | None |
1471| x86 | `xmm_reg` | None | `xmm0` | `x` |
1472| x86 | `ymm_reg` | None | `ymm0` | `t` |
1473| x86 | `zmm_reg` | None | `zmm0` | `g` |
1474| x86 | `*mm_reg` | `x` | `xmm0` | `x` |
1475| x86 | `*mm_reg` | `y` | `ymm0` | `t` |
1476| x86 | `*mm_reg` | `z` | `zmm0` | `g` |
1477| x86 | `kreg` | None | `k1` | None |
1478| AArch64 | `reg` | None | `x0` | `x` |
1479| AArch64 | `reg` | `w` | `w0` | `w` |
1480| AArch64 | `reg` | `x` | `x0` | `x` |
1481| AArch64 | `vreg` | None | `v0` | None |
1482| AArch64 | `vreg` | `v` | `v0` | None |
1483| AArch64 | `vreg` | `b` | `b0` | `b` |
1484| AArch64 | `vreg` | `h` | `h0` | `h` |
1485| AArch64 | `vreg` | `s` | `s0` | `s` |
1486| AArch64 | `vreg` | `d` | `d0` | `d` |
1487| AArch64 | `vreg` | `q` | `q0` | `q` |
1488| ARM | `reg` | None | `r0` | None |
1489| ARM | `sreg` | None | `s0` | None |
1490| ARM | `dreg` | None | `d0` | `P` |
1491| ARM | `qreg` | None | `q0` | `q` |
1492| ARM | `qreg` | `e` / `f` | `d0` / `d1` | `e` / `f` |
1493| MIPS | `reg` | None | `$2` | None |
1494| MIPS | `freg` | None | `$f0` | None |
1495| NVPTX | `reg16` | None | `rs0` | None |
1496| NVPTX | `reg32` | None | `r0` | None |
1497| NVPTX | `reg64` | None | `rd0` | None |
1498| RISC-V | `reg` | None | `x1` | None |
1499| RISC-V | `freg` | None | `f0` | None |
1500| Hexagon | `reg` | None | `r0` | None |
1501| PowerPC | `reg` | None | `0` | None |
1502| PowerPC | `reg_nonzero` | None | `3` | `b` |
1503| PowerPC | `freg` | None | `0` | None |
1504
1505> Notes:
1506> - on ARM `e` / `f`: this prints the low or high doubleword register name of a NEON quad (128-bit) register.
1507> - 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.
1508> - 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.
1509
1510As 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.
1511
1512[llvm-argmod]: http://llvm.org/docs/LangRef.html#asm-template-argument-modifiers
1513
1514## Options
1515
1516Flags are used to further influence the behavior of the inline assembly block.
1517Currently the following options are defined:
1518- `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.
1519- `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`.
1520- `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`.
1521- `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.
1522- `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.
1523- `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.
1524- `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 `%`.
1525
1526The compiler performs some additional checks on options:
1527- The `nomem` and `readonly` options are mutually exclusive: it is a compile-time error to specify both.
1528- The `pure` option must be combined with either the `nomem` or `readonly` options, otherwise a compile-time error is emitted.
1529- It is a compile-time error to specify `pure` on an asm block with no outputs or only discarded outputs (`_`).
1530- It is a compile-time error to specify `noreturn` on an asm block with outputs.
1531
1532## Rules for inline assembly
1533
1534- Any registers not specified as inputs will contain an undefined value on entry to the asm block.
1535 - 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).
1536- 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.
1537 - This only applies to registers which can be specified as an input or output. Other registers follow target-specific rules.
1538 - 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.
1539- Behavior is undefined if execution unwinds out of an asm block.
1540 - This also applies if the assembly code calls a function which then unwinds.
1541- The set of memory locations that assembly code is allowed the read and write are the same as those allowed for an FFI function.
1542 - Refer to the unsafe code guidelines for the exact rules.
1543 - If the `readonly` option is set, then only memory reads are allowed.
1544 - If the `nomem` option is set then no reads or writes to memory are allowed.
1545 - These rules do not apply to memory which is private to the asm code, such as stack space allocated within the asm block.
1546- The compiler cannot assume that the instructions in the asm are the ones that will actually end up executed.
1547 - 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.
1548 - Runtime code patching is allowed, via target-specific mechanisms (outside the scope of this RFC).
1549- Unless the `nostack` option is set, asm code is allowed to use stack space below the stack pointer.
1550 - On entry to the asm block the stack pointer is guaranteed to be suitably aligned (according to the target ABI) for a function call.
1551 - You are responsible for making sure you don't overflow the stack (e.g. use stack probing to ensure you hit a guard page).
1552 - You should adjust the stack pointer when allocating stack memory as required by the target ABI.
1553 - The stack pointer must be restored to its original value before leaving the asm block.
1554- If the `noreturn` option is set then behavior is undefined if execution falls through to the end of the asm block.
1555- 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.
1556 - When used with the `nomem` option, "inputs" are just the direct inputs of the `asm!`.
1557 - 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.
1558- These flags registers must be restored upon exiting the asm block if the `preserves_flags` option is set:
1559 - x86
1560 - Status flags in `EFLAGS` (CF, PF, AF, ZF, SF, OF).
1561 - Floating-point status word (all).
1562 - Floating-point exception flags in `MXCSR` (PE, UE, OE, ZE, DE, IE).
1563 - ARM
1564 - Condition flags in `CPSR` (N, Z, C, V)
1565 - Saturation flag in `CPSR` (Q)
1566 - Greater than or equal flags in `CPSR` (GE).
1567 - Condition flags in `FPSCR` (N, Z, C, V)
1568 - Saturation flag in `FPSCR` (QC)
1569 - Floating-point exception flags in `FPSCR` (IDC, IXC, UFC, OFC, DZC, IOC).
1570 - AArch64
1571 - Condition flags (`NZCV` register).
1572 - Floating-point status (`FPSR` register).
1573 - RISC-V
1574 - Floating-point exception flags in `fcsr` (`fflags`).
1575- On x86, the direction flag (DF in `EFLAGS`) is clear on entry to an asm block and must be clear on exit.
1576 - Behavior is undefined if the direction flag is set on exiting an asm block.
1577- The requirement of restoring the stack pointer and non-output registers to their original value only applies when exiting an `asm!` block.
1578 - This means that `asm!` blocks that never return (even if not marked `noreturn`) don't need to preserve these registers.
1579 - 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*.
1580 - You cannot exit an `asm!` block that has not been entered. Neither can you exit an `asm!` block that has already been exited.
1581 - You are responsible for switching any target-specific state (e.g. thread-local storage, stack bounds).
1582 - The set of memory locations that you may access is the intersection of those allowed by the `asm!` blocks you entered and exited.
1583- 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.
1584
1585> **Note**: As a general rule, the flags covered by `preserves_flags` are those which are *not* preserved when performing a function call.
1586"##,
1587 },
1588 Lint {
1589 label: "auto_traits",
1590 description: r##"# `auto_traits`
1591
1592The tracking issue for this feature is [#13231]
1593
1594[#13231]: https://github.com/rust-lang/rust/issues/13231
1595
1596----
1597
1598The `auto_traits` feature gate allows you to define auto traits.
1599
1600Auto traits, like [`Send`] or [`Sync`] in the standard library, are marker traits
1601that are automatically implemented for every type, unless the type, or a type it contains,
1602has explicitly opted out via a negative impl. (Negative impls are separately controlled
1603by the `negative_impls` feature.)
1604
1605[`Send`]: https://doc.rust-lang.org/std/marker/trait.Send.html
1606[`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html
1607
1608```rust,ignore (partial-example)
1609impl !Trait for Type {}
1610```
1611
1612Example:
1613
1614```rust
1615#![feature(negative_impls)]
1616#![feature(auto_traits)]
1617
1618auto trait Valid {}
1619
1620struct True;
1621struct False;
1622
1623impl !Valid for False {}
1624
1625struct MaybeValid<T>(T);
1626
1627fn must_be_valid<T: Valid>(_t: T) { }
1628
1629fn main() {
1630 // works
1631 must_be_valid( MaybeValid(True) );
1632
1633 // compiler error - trait bound not satisfied
1634 // must_be_valid( MaybeValid(False) );
1635}
1636```
1637
1638## Automatic trait implementations
1639
1640When a type is declared as an `auto trait`, we will automatically
1641create impls for every struct/enum/union, unless an explicit impl is
1642provided. These automatic impls contain a where clause for each field
1643of the form `T: AutoTrait`, where `T` is the type of the field and
1644`AutoTrait` is the auto trait in question. As an example, consider the
1645struct `List` and the auto trait `Send`:
1646
1647```rust
1648struct List<T> {
1649 data: T,
1650 next: Option<Box<List<T>>>,
1651}
1652```
1653
1654Presuming that there is no explicit impl of `Send` for `List`, the
1655compiler will supply an automatic impl of the form:
1656
1657```rust
1658struct List<T> {
1659 data: T,
1660 next: Option<Box<List<T>>>,
1661}
1662
1663unsafe impl<T> Send for List<T>
1664where
1665 T: Send, // from the field `data`
1666 Option<Box<List<T>>>: Send, // from the field `next`
1667{ }
1668```
1669
1670Explicit impls may be either positive or negative. They take the form:
1671
1672```rust,ignore (partial-example)
1673impl<...> AutoTrait for StructName<..> { }
1674impl<...> !AutoTrait for StructName<..> { }
1675```
1676
1677## Coinduction: Auto traits permit cyclic matching
1678
1679Unlike ordinary trait matching, auto traits are **coinductive**. This
1680means, in short, that cycles which occur in trait matching are
1681considered ok. As an example, consider the recursive struct `List`
1682introduced in the previous section. In attempting to determine whether
1683`List: Send`, we would wind up in a cycle: to apply the impl, we must
1684show that `Option<Box<List>>: Send`, which will in turn require
1685`Box<List>: Send` and then finally `List: Send` again. Under ordinary
1686trait matching, this cycle would be an error, but for an auto trait it
1687is considered a successful match.
1688
1689## Items
1690
1691Auto traits cannot have any trait items, such as methods or associated types. This ensures that we can generate default implementations.
1692
1693## Supertraits
1694
1695Auto traits cannot have supertraits. This is for soundness reasons, as the interaction of coinduction with implied bounds is difficult to reconcile.
1696"##,
1697 },
1698 Lint {
1699 label: "box_patterns",
1700 description: r##"# `box_patterns`
1701
1702The tracking issue for this feature is: [#29641]
1703
1704[#29641]: https://github.com/rust-lang/rust/issues/29641
1705
1706See also [`box_syntax`](box-syntax.md)
1707
1708------------------------
1709
1710Box patterns let you match on `Box<T>`s:
1711
1712
1713```rust
1714#![feature(box_patterns)]
1715
1716fn main() {
1717 let b = Some(Box::new(5));
1718 match b {
1719 Some(box n) if n < 0 => {
1720 println!("Box contains negative number {}", n);
1721 },
1722 Some(box n) if n >= 0 => {
1723 println!("Box contains non-negative number {}", n);
1724 },
1725 None => {
1726 println!("No box");
1727 },
1728 _ => unreachable!()
1729 }
1730}
1731```
1732"##,
1733 },
1734 Lint {
1735 label: "box_syntax",
1736 description: r##"# `box_syntax`
1737
1738The tracking issue for this feature is: [#49733]
1739
1740[#49733]: https://github.com/rust-lang/rust/issues/49733
1741
1742See also [`box_patterns`](box-patterns.md)
1743
1744------------------------
1745
1746Currently the only stable way to create a `Box` is via the `Box::new` method.
1747Also it is not possible in stable Rust to destructure a `Box` in a match
1748pattern. The unstable `box` keyword can be used to create a `Box`. An example
1749usage would be:
1750
1751```rust
1752#![feature(box_syntax)]
1753
1754fn main() {
1755 let b = box 5;
1756}
1757```
1758"##,
1759 },
1760 Lint {
1761 label: "c_unwind",
1762 description: r##"# `c_unwind`
1763
1764The tracking issue for this feature is: [#74990]
1765
1766[#74990]: https://github.com/rust-lang/rust/issues/74990
1767
1768------------------------
1769
1770Introduces four new ABI strings: "C-unwind", "stdcall-unwind",
1771"thiscall-unwind", and "system-unwind". These enable unwinding from other
1772languages (such as C++) into Rust frames and from Rust into other languages.
1773
1774See [RFC 2945] for more information.
1775
1776[RFC 2945]: https://github.com/rust-lang/rfcs/blob/master/text/2945-c-unwind-abi.md
1777"##,
1778 },
1779 Lint {
1780 label: "c_variadic",
1781 description: r##"# `c_variadic`
1782
1783The tracking issue for this feature is: [#44930]
1784
1785[#44930]: https://github.com/rust-lang/rust/issues/44930
1786
1787------------------------
1788
1789The `c_variadic` language feature enables C-variadic functions to be
1790defined in Rust. The may be called both from within Rust and via FFI.
1791
1792## Examples
1793
1794```rust
1795#![feature(c_variadic)]
1796
1797pub unsafe extern "C" fn add(n: usize, mut args: ...) -> usize {
1798 let mut sum = 0;
1799 for _ in 0..n {
1800 sum += args.arg::<usize>();
1801 }
1802 sum
1803}
1804```
1805"##,
1806 },
1807 Lint {
1808 label: "c_variadic",
1809 description: r##"# `c_variadic`
1810
1811The tracking issue for this feature is: [#44930]
1812
1813[#44930]: https://github.com/rust-lang/rust/issues/44930
1814
1815------------------------
1816
1817The `c_variadic` library feature exposes the `VaList` structure,
1818Rust's analogue of C's `va_list` type.
1819
1820## Examples
1821
1822```rust
1823#![feature(c_variadic)]
1824
1825use std::ffi::VaList;
1826
1827pub unsafe extern "C" fn vadd(n: usize, mut args: VaList) -> usize {
1828 let mut sum = 0;
1829 for _ in 0..n {
1830 sum += args.arg::<usize>();
1831 }
1832 sum
1833}
1834```
1835"##,
1836 },
1837 Lint {
1838 label: "c_void_variant",
1839 description: r##"# `c_void_variant`
1840
1841This feature is internal to the Rust compiler and is not intended for general use.
1842
1843------------------------
1844"##,
1845 },
1846 Lint {
1847 label: "cfg_panic",
1848 description: r##"# `cfg_panic`
1849
1850The tracking issue for this feature is: [#77443]
1851
1852[#77443]: https://github.com/rust-lang/rust/issues/77443
1853
1854------------------------
1855
1856The `cfg_panic` feature makes it possible to execute different code
1857depending on the panic strategy.
1858
1859Possible values at the moment are `"unwind"` or `"abort"`, although
1860it is possible that new panic strategies may be added to Rust in the
1861future.
1862
1863## Examples
1864
1865```rust
1866#![feature(cfg_panic)]
1867
1868#[cfg(panic = "unwind")]
1869fn a() {
1870 // ...
1871}
1872
1873#[cfg(not(panic = "unwind"))]
1874fn a() {
1875 // ...
1876}
1877
1878fn b() {
1879 if cfg!(panic = "abort") {
1880 // ...
1881 } else {
1882 // ...
1883 }
1884}
1885```
1886"##,
1887 },
1888 Lint {
1889 label: "cfg_sanitize",
1890 description: r##"# `cfg_sanitize`
1891
1892The tracking issue for this feature is: [#39699]
1893
1894[#39699]: https://github.com/rust-lang/rust/issues/39699
1895
1896------------------------
1897
1898The `cfg_sanitize` feature makes it possible to execute different code
1899depending on whether a particular sanitizer is enabled or not.
1900
1901## Examples
1902
1903```rust
1904#![feature(cfg_sanitize)]
1905
1906#[cfg(sanitize = "thread")]
1907fn a() {
1908 // ...
1909}
1910
1911#[cfg(not(sanitize = "thread"))]
1912fn a() {
1913 // ...
1914}
1915
1916fn b() {
1917 if cfg!(sanitize = "leak") {
1918 // ...
1919 } else {
1920 // ...
1921 }
1922}
1923```
1924"##,
1925 },
1926 Lint {
1927 label: "cfg_version",
1928 description: r##"# `cfg_version`
1929
1930The tracking issue for this feature is: [#64796]
1931
1932[#64796]: https://github.com/rust-lang/rust/issues/64796
1933
1934------------------------
1935
1936The `cfg_version` feature makes it possible to execute different code
1937depending on the compiler version. It will return true if the compiler
1938version is greater than or equal to the specified version.
1939
1940## Examples
1941
1942```rust
1943#![feature(cfg_version)]
1944
1945#[cfg(version("1.42"))] // 1.42 and above
1946fn a() {
1947 // ...
1948}
1949
1950#[cfg(not(version("1.42")))] // 1.41 and below
1951fn a() {
1952 // ...
1953}
1954
1955fn b() {
1956 if cfg!(version("1.42")) {
1957 // ...
1958 } else {
1959 // ...
1960 }
1961}
1962```
1963"##,
1964 },
1965 Lint {
1966 label: "char_error_internals",
1967 description: r##"# `char_error_internals`
1968
1969This feature is internal to the Rust compiler and is not intended for general use.
1970
1971------------------------
1972"##,
1973 },
1974 Lint {
1975 label: "cmse_nonsecure_entry",
1976 description: r##"# `cmse_nonsecure_entry`
1977
1978The tracking issue for this feature is: [#75835]
1979
1980[#75835]: https://github.com/rust-lang/rust/issues/75835
1981
1982------------------------
1983
1984The [TrustZone-M
1985feature](https://developer.arm.com/documentation/100690/latest/) is available
1986for targets with the Armv8-M architecture profile (`thumbv8m` in their target
1987name).
1988LLVM, the Rust compiler and the linker are providing
1989[support](https://developer.arm.com/documentation/ecm0359818/latest/) for the
1990TrustZone-M feature.
1991
1992One of the things provided, with this unstable feature, is the
1993`cmse_nonsecure_entry` attribute. This attribute marks a Secure function as an
1994entry function (see [section
19955.4](https://developer.arm.com/documentation/ecm0359818/latest/) for details).
1996With this attribute, the compiler will do the following:
1997* add a special symbol on the function which is the `__acle_se_` prefix and the
1998 standard function name
1999* constrain the number of parameters to avoid using the Non-Secure stack
2000* before returning from the function, clear registers that might contain Secure
2001 information
2002* use the `BXNS` instruction to return
2003
2004Because the stack can not be used to pass parameters, there will be compilation
2005errors if:
2006* the total size of all parameters is too big (for example more than four 32
2007 bits integers)
2008* the entry function is not using a C ABI
2009
2010The special symbol `__acle_se_` will be used by the linker to generate a secure
2011gateway veneer.
2012
2013<!-- NOTE(ignore) this example is specific to thumbv8m targets -->
2014
2015``` rust,ignore
2016#![feature(cmse_nonsecure_entry)]
2017
2018#[no_mangle]
2019#[cmse_nonsecure_entry]
2020pub extern "C" fn entry_function(input: u32) -> u32 {
2021 input + 6
2022}
2023```
2024
2025``` text
2026$ rustc --emit obj --crate-type lib --target thumbv8m.main-none-eabi function.rs
2027$ arm-none-eabi-objdump -D function.o
2028
202900000000 <entry_function>:
2030 0: b580 push {r7, lr}
2031 2: 466f mov r7, sp
2032 4: b082 sub sp, #8
2033 6: 9001 str r0, [sp, #4]
2034 8: 1d81 adds r1, r0, #6
2035 a: 460a mov r2, r1
2036 c: 4281 cmp r1, r0
2037 e: 9200 str r2, [sp, #0]
2038 10: d30b bcc.n 2a <entry_function+0x2a>
2039 12: e7ff b.n 14 <entry_function+0x14>
2040 14: 9800 ldr r0, [sp, #0]
2041 16: b002 add sp, #8
2042 18: e8bd 4080 ldmia.w sp!, {r7, lr}
2043 1c: 4671 mov r1, lr
2044 1e: 4672 mov r2, lr
2045 20: 4673 mov r3, lr
2046 22: 46f4 mov ip, lr
2047 24: f38e 8800 msr CPSR_f, lr
2048 28: 4774 bxns lr
2049 2a: f240 0000 movw r0, #0
2050 2e: f2c0 0000 movt r0, #0
2051 32: f240 0200 movw r2, #0
2052 36: f2c0 0200 movt r2, #0
2053 3a: 211c movs r1, #28
2054 3c: f7ff fffe bl 0 <_ZN4core9panicking5panic17h5c028258ca2fb3f5E>
2055 40: defe udf #254 ; 0xfe
2056```
2057"##,
2058 },
2059 Lint {
2060 label: "compiler_builtins",
2061 description: r##"# `compiler_builtins`
2062
2063This feature is internal to the Rust compiler and is not intended for general use.
2064
2065------------------------
2066"##,
2067 },
2068 Lint {
2069 label: "concat_idents",
2070 description: r##"# `concat_idents`
2071
2072The tracking issue for this feature is: [#29599]
2073
2074[#29599]: https://github.com/rust-lang/rust/issues/29599
2075
2076------------------------
2077
2078The `concat_idents` feature adds a macro for concatenating multiple identifiers
2079into one identifier.
2080
2081## Examples
2082
2083```rust
2084#![feature(concat_idents)]
2085
2086fn main() {
2087 fn foobar() -> u32 { 23 }
2088 let f = concat_idents!(foo, bar);
2089 assert_eq!(f(), 23);
2090}
2091```
2092"##,
2093 },
2094 Lint {
2095 label: "const_eval_limit",
2096 description: r##"# `const_eval_limit`
2097
2098The tracking issue for this feature is: [#67217]
2099
2100[#67217]: https://github.com/rust-lang/rust/issues/67217
2101
2102The `const_eval_limit` allows someone to limit the evaluation steps the CTFE undertakes to evaluate a `const fn`.
2103"##,
2104 },
2105 Lint {
2106 label: "core_intrinsics",
2107 description: r##"# `core_intrinsics`
2108
2109This feature is internal to the Rust compiler and is not intended for general use.
2110
2111------------------------
2112"##,
2113 },
2114 Lint {
2115 label: "core_panic",
2116 description: r##"# `core_panic`
2117
2118This feature is internal to the Rust compiler and is not intended for general use.
2119
2120------------------------
2121"##,
2122 },
2123 Lint {
2124 label: "core_private_bignum",
2125 description: r##"# `core_private_bignum`
2126
2127This feature is internal to the Rust compiler and is not intended for general use.
2128
2129------------------------
2130"##,
2131 },
2132 Lint {
2133 label: "core_private_diy_float",
2134 description: r##"# `core_private_diy_float`
2135
2136This feature is internal to the Rust compiler and is not intended for general use.
2137
2138------------------------
2139"##,
2140 },
2141 Lint {
2142 label: "crate_visibility_modifier",
2143 description: r##"# `crate_visibility_modifier`
2144
2145The tracking issue for this feature is: [#53120]
2146
2147[#53120]: https://github.com/rust-lang/rust/issues/53120
2148
2149-----
2150
2151The `crate_visibility_modifier` feature allows the `crate` keyword to be used
2152as a visibility modifier synonymous to `pub(crate)`, indicating that a type
2153(function, _&c._) is to be visible to the entire enclosing crate, but not to
2154other crates.
2155
2156```rust
2157#![feature(crate_visibility_modifier)]
2158
2159crate struct Foo {
2160 bar: usize,
2161}
2162```
2163"##,
2164 },
2165 Lint {
2166 label: "custom_test_frameworks",
2167 description: r##"# `custom_test_frameworks`
2168
2169The tracking issue for this feature is: [#50297]
2170
2171[#50297]: https://github.com/rust-lang/rust/issues/50297
2172
2173------------------------
2174
2175The `custom_test_frameworks` feature allows the use of `#[test_case]` and `#![test_runner]`.
2176Any function, const, or static can be annotated with `#[test_case]` causing it to be aggregated (like `#[test]`)
2177and be passed to the test runner determined by the `#![test_runner]` crate attribute.
2178
2179```rust
2180#![feature(custom_test_frameworks)]
2181#![test_runner(my_runner)]
2182
2183fn my_runner(tests: &[&i32]) {
2184 for t in tests {
2185 if **t == 0 {
2186 println!("PASSED");
2187 } else {
2188 println!("FAILED");
2189 }
2190 }
2191}
2192
2193#[test_case]
2194const WILL_PASS: i32 = 0;
2195
2196#[test_case]
2197const WILL_FAIL: i32 = 4;
2198```
2199"##,
2200 },
2201 Lint {
2202 label: "dec2flt",
2203 description: r##"# `dec2flt`
2204
2205This feature is internal to the Rust compiler and is not intended for general use.
2206
2207------------------------
2208"##,
2209 },
2210 Lint {
2211 label: "default_free_fn",
2212 description: r##"# `default_free_fn`
2213
2214The tracking issue for this feature is: [#73014]
2215
2216[#73014]: https://github.com/rust-lang/rust/issues/73014
2217
2218------------------------
2219
2220Adds a free `default()` function to the `std::default` module. This function
2221just forwards to [`Default::default()`], but may remove repetition of the word
2222"default" from the call site.
2223
2224[`Default::default()`]: https://doc.rust-lang.org/nightly/std/default/trait.Default.html#tymethod.default
2225
2226Here is an example:
2227
2228```rust
2229#![feature(default_free_fn)]
2230use std::default::default;
2231
2232#[derive(Default)]
2233struct AppConfig {
2234 foo: FooConfig,
2235 bar: BarConfig,
2236}
2237
2238#[derive(Default)]
2239struct FooConfig {
2240 foo: i32,
2241}
2242
2243#[derive(Default)]
2244struct BarConfig {
2245 bar: f32,
2246 baz: u8,
2247}
2248
2249fn main() {
2250 let options = AppConfig {
2251 foo: default(),
2252 bar: BarConfig {
2253 bar: 10.1,
2254 ..default()
2255 },
2256 };
2257}
2258```
2259"##,
2260 },
2261 Lint {
2262 label: "derive_clone_copy",
2263 description: r##"# `derive_clone_copy`
2264
2265This feature is internal to the Rust compiler and is not intended for general use.
2266
2267------------------------
2268"##,
2269 },
2270 Lint {
2271 label: "derive_eq",
2272 description: r##"# `derive_eq`
2273
2274This feature is internal to the Rust compiler and is not intended for general use.
2275
2276------------------------
2277"##,
2278 },
2279 Lint {
2280 label: "doc_cfg",
2281 description: r##"# `doc_cfg`
2282
2283The tracking issue for this feature is: [#43781]
2284
2285------
2286
2287The `doc_cfg` feature allows an API be documented as only available in some specific platforms.
2288This attribute has two effects:
2289
22901. In the annotated item's documentation, there will be a message saying "This is supported on
2291 (platform) only".
2292
22932. The item's doc-tests will only run on the specific platform.
2294
2295In addition to allowing the use of the `#[doc(cfg)]` attribute, this feature enables the use of a
2296special conditional compilation flag, `#[cfg(doc)]`, set whenever building documentation on your
2297crate.
2298
2299This feature was introduced as part of PR [#43348] to allow the platform-specific parts of the
2300standard library be documented.
2301
2302```rust
2303#![feature(doc_cfg)]
2304
2305#[cfg(any(windows, doc))]
2306#[doc(cfg(windows))]
2307/// The application's icon in the notification area (a.k.a. system tray).
2308///
2309/// # Examples
2310///
2311/// ```no_run
2312/// extern crate my_awesome_ui_library;
2313/// use my_awesome_ui_library::current_app;
2314/// use my_awesome_ui_library::windows::notification;
2315///
2316/// let icon = current_app().get::<notification::Icon>();
2317/// icon.show();
2318/// icon.show_message("Hello");
2319/// ```
2320pub struct Icon {
2321 // ...
2322}
2323```
2324
2325[#43781]: https://github.com/rust-lang/rust/issues/43781
2326[#43348]: https://github.com/rust-lang/rust/issues/43348
2327"##,
2328 },
2329 Lint {
2330 label: "doc_masked",
2331 description: r##"# `doc_masked`
2332
2333The tracking issue for this feature is: [#44027]
2334
2335-----
2336
2337The `doc_masked` feature allows a crate to exclude types from a given crate from appearing in lists
2338of trait implementations. The specifics of the feature are as follows:
2339
23401. When rustdoc encounters an `extern crate` statement annotated with a `#[doc(masked)]` attribute,
2341 it marks the crate as being masked.
2342
23432. When listing traits a given type implements, rustdoc ensures that traits from masked crates are
2344 not emitted into the documentation.
2345
23463. When listing types that implement a given trait, rustdoc ensures that types from masked crates
2347 are not emitted into the documentation.
2348
2349This feature was introduced in PR [#44026] to ensure that compiler-internal and
2350implementation-specific types and traits were not included in the standard library's documentation.
2351Such types would introduce broken links into the documentation.
2352
2353[#44026]: https://github.com/rust-lang/rust/pull/44026
2354[#44027]: https://github.com/rust-lang/rust/pull/44027
2355"##,
2356 },
2357 Lint {
2358 label: "doc_notable_trait",
2359 description: r##"# `doc_notable_trait`
2360
2361The tracking issue for this feature is: [#45040]
2362
2363The `doc_notable_trait` feature allows the use of the `#[doc(notable_trait)]`
2364attribute, which will display the trait in a "Notable traits" dialog for
2365functions returning types that implement the trait. For example, this attribute
2366is applied to the `Iterator`, `Future`, `io::Read`, and `io::Write` traits in
2367the standard library.
2368
2369You can do this on your own traits like so:
2370
2371```
2372#![feature(doc_notable_trait)]
2373
2374#[doc(notable_trait)]
2375pub trait MyTrait {}
2376
2377pub struct MyStruct;
2378impl MyTrait for MyStruct {}
2379
2380/// The docs for this function will have a button that displays a dialog about
2381/// `MyStruct` implementing `MyTrait`.
2382pub fn my_fn() -> MyStruct { MyStruct }
2383```
2384
2385This feature was originally implemented in PR [#45039].
2386
2387See also its documentation in [the rustdoc book][rustdoc-book-notable_trait].
2388
2389[#45040]: https://github.com/rust-lang/rust/issues/45040
2390[#45039]: https://github.com/rust-lang/rust/pull/45039
2391[rustdoc-book-notable_trait]: ../../rustdoc/unstable-features.html#adding-your-trait-to-the-notable-traits-dialog
2392"##,
2393 },
2394 Lint {
2395 label: "external_doc",
2396 description: r##"# `external_doc`
2397
2398The tracking issue for this feature is: [#44732]
2399
2400The `external_doc` feature allows the use of the `include` parameter to the `#[doc]` attribute, to
2401include external files in documentation. Use the attribute in place of, or in addition to, regular
2402doc comments and `#[doc]` attributes, and `rustdoc` will load the given file when it renders
2403documentation for your crate.
2404
2405With the following files in the same directory:
2406
2407`external-doc.md`:
2408
2409```markdown
2410# My Awesome Type
2411
2412This is the documentation for this spectacular type.
2413```
2414
2415`lib.rs`:
2416
2417```no_run (needs-external-files)
2418#![feature(external_doc)]
2419
2420#[doc(include = "external-doc.md")]
2421pub struct MyAwesomeType;
2422```
2423
2424`rustdoc` will load the file `external-doc.md` and use it as the documentation for the `MyAwesomeType`
2425struct.
2426
2427When locating files, `rustdoc` will base paths in the `src/` directory, as if they were alongside the
2428`lib.rs` for your crate. So if you want a `docs/` folder to live alongside the `src/` directory,
2429start your paths with `../docs/` for `rustdoc` to properly find the file.
2430
2431This feature was proposed in [RFC #1990] and initially implemented in PR [#44781].
2432
2433[#44732]: https://github.com/rust-lang/rust/issues/44732
2434[RFC #1990]: https://github.com/rust-lang/rfcs/pull/1990
2435[#44781]: https://github.com/rust-lang/rust/pull/44781
2436"##,
2437 },
2438 Lint {
2439 label: "fd",
2440 description: r##"# `fd`
2441
2442This feature is internal to the Rust compiler and is not intended for general use.
2443
2444------------------------
2445"##,
2446 },
2447 Lint {
2448 label: "fd_read",
2449 description: r##"# `fd_read`
2450
2451This feature is internal to the Rust compiler and is not intended for general use.
2452
2453------------------------
2454"##,
2455 },
2456 Lint {
2457 label: "ffi_const",
2458 description: r##"# `ffi_const`
2459
2460The tracking issue for this feature is: [#58328]
2461
2462------
2463
2464The `#[ffi_const]` attribute applies clang's `const` attribute to foreign
2465functions declarations.
2466
2467That is, `#[ffi_const]` functions shall have no effects except for its return
2468value, which can only depend on the values of the function parameters, and is
2469not affected by changes to the observable state of the program.
2470
2471Applying the `#[ffi_const]` attribute to a function that violates these
2472requirements is undefined behaviour.
2473
2474This attribute enables Rust to perform common optimizations, like sub-expression
2475elimination, and it can avoid emitting some calls in repeated invocations of the
2476function with the same argument values regardless of other operations being
2477performed in between these functions calls (as opposed to `#[ffi_pure]`
2478functions).
2479
2480## Pitfalls
2481
2482A `#[ffi_const]` function can only read global memory that would not affect
2483its return value for the whole execution of the program (e.g. immutable global
2484memory). `#[ffi_const]` functions are referentially-transparent and therefore
2485more strict than `#[ffi_pure]` functions.
2486
2487A common pitfall involves applying the `#[ffi_const]` attribute to a
2488function that reads memory through pointer arguments which do not necessarily
2489point to immutable global memory.
2490
2491A `#[ffi_const]` function that returns unit has no effect on the abstract
2492machine's state, and a `#[ffi_const]` function cannot be `#[ffi_pure]`.
2493
2494A `#[ffi_const]` function must not diverge, neither via a side effect (e.g. a
2495call to `abort`) nor by infinite loops.
2496
2497When translating C headers to Rust FFI, it is worth verifying for which targets
2498the `const` attribute is enabled in those headers, and using the appropriate
2499`cfg` macros in the Rust side to match those definitions. While the semantics of
2500`const` are implemented identically by many C and C++ compilers, e.g., clang,
2501[GCC], [ARM C/C++ compiler], [IBM ILE C/C++], etc. they are not necessarily
2502implemented in this way on all of them. It is therefore also worth verifying
2503that the semantics of the C toolchain used to compile the binary being linked
2504against are compatible with those of the `#[ffi_const]`.
2505
2506[#58328]: https://github.com/rust-lang/rust/issues/58328
2507[ARM C/C++ compiler]: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0491c/Cacgigch.html
2508[GCC]: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-const-function-attribute
2509[IBM ILE C/C++]: https://www.ibm.com/support/knowledgecenter/fr/ssw_ibm_i_71/rzarg/fn_attrib_const.htm
2510"##,
2511 },
2512 Lint {
2513 label: "ffi_pure",
2514 description: r##"# `ffi_pure`
2515
2516The tracking issue for this feature is: [#58329]
2517
2518------
2519
2520The `#[ffi_pure]` attribute applies clang's `pure` attribute to foreign
2521functions declarations.
2522
2523That is, `#[ffi_pure]` functions shall have no effects except for its return
2524value, which shall not change across two consecutive function calls with
2525the same parameters.
2526
2527Applying the `#[ffi_pure]` attribute to a function that violates these
2528requirements is undefined behavior.
2529
2530This attribute enables Rust to perform common optimizations, like sub-expression
2531elimination and loop optimizations. Some common examples of pure functions are
2532`strlen` or `memcmp`.
2533
2534These optimizations are only applicable when the compiler can prove that no
2535program state observable by the `#[ffi_pure]` function has changed between calls
2536of the function, which could alter the result. See also the `#[ffi_const]`
2537attribute, which provides stronger guarantees regarding the allowable behavior
2538of a function, enabling further optimization.
2539
2540## Pitfalls
2541
2542A `#[ffi_pure]` function can read global memory through the function
2543parameters (e.g. pointers), globals, etc. `#[ffi_pure]` functions are not
2544referentially-transparent, and are therefore more relaxed than `#[ffi_const]`
2545functions.
2546
2547However, accessing global memory through volatile or atomic reads can violate the
2548requirement that two consecutive function calls shall return the same value.
2549
2550A `pure` function that returns unit has no effect on the abstract machine's
2551state.
2552
2553A `#[ffi_pure]` function must not diverge, neither via a side effect (e.g. a
2554call to `abort`) nor by infinite loops.
2555
2556When translating C headers to Rust FFI, it is worth verifying for which targets
2557the `pure` attribute is enabled in those headers, and using the appropriate
2558`cfg` macros in the Rust side to match those definitions. While the semantics of
2559`pure` are implemented identically by many C and C++ compilers, e.g., clang,
2560[GCC], [ARM C/C++ compiler], [IBM ILE C/C++], etc. they are not necessarily
2561implemented in this way on all of them. It is therefore also worth verifying
2562that the semantics of the C toolchain used to compile the binary being linked
2563against are compatible with those of the `#[ffi_pure]`.
2564
2565
2566[#58329]: https://github.com/rust-lang/rust/issues/58329
2567[ARM C/C++ compiler]: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0491c/Cacigdac.html
2568[GCC]: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-pure-function-attribute
2569[IBM ILE C/C++]: https://www.ibm.com/support/knowledgecenter/fr/ssw_ibm_i_71/rzarg/fn_attrib_pure.htm
2570"##,
2571 },
2572 Lint {
2573 label: "flt2dec",
2574 description: r##"# `flt2dec`
2575
2576This feature is internal to the Rust compiler and is not intended for general use.
2577
2578------------------------
2579"##,
2580 },
2581 Lint {
2582 label: "fmt_internals",
2583 description: r##"# `fmt_internals`
2584
2585This feature is internal to the Rust compiler and is not intended for general use.
2586
2587------------------------
2588"##,
2589 },
2590 Lint {
2591 label: "fn_traits",
2592 description: r##"# `fn_traits`
2593
2594The tracking issue for this feature is [#29625]
2595
2596See Also: [`unboxed_closures`](../language-features/unboxed-closures.md)
2597
2598[#29625]: https://github.com/rust-lang/rust/issues/29625
2599
2600----
2601
2602The `fn_traits` feature allows for implementation of the [`Fn*`] traits
2603for creating custom closure-like types.
2604
2605[`Fn*`]: https://doc.rust-lang.org/std/ops/trait.Fn.html
2606
2607```rust
2608#![feature(unboxed_closures)]
2609#![feature(fn_traits)]
2610
2611struct Adder {
2612 a: u32
2613}
2614
2615impl FnOnce<(u32, )> for Adder {
2616 type Output = u32;
2617 extern "rust-call" fn call_once(self, b: (u32, )) -> Self::Output {
2618 self.a + b.0
2619 }
2620}
2621
2622fn main() {
2623 let adder = Adder { a: 3 };
2624 assert_eq!(adder(2), 5);
2625}
2626```
2627"##,
2628 },
2629 Lint {
2630 label: "format_args_capture",
2631 description: r##"# `format_args_capture`
2632
2633The tracking issue for this feature is: [#67984]
2634
2635[#67984]: https://github.com/rust-lang/rust/issues/67984
2636
2637------------------------
2638
2639Enables `format_args!` (and macros which use `format_args!` in their implementation, such
2640as `format!`, `print!` and `panic!`) to capture variables from the surrounding scope.
2641This avoids the need to pass named parameters when the binding in question
2642already exists in scope.
2643
2644```rust
2645#![feature(format_args_capture)]
2646
2647let (person, species, name) = ("Charlie Brown", "dog", "Snoopy");
2648
2649// captures named argument `person`
2650print!("Hello {person}");
2651
2652// captures named arguments `species` and `name`
2653format!("The {species}'s name is {name}.");
2654```
2655
2656This also works for formatting parameters such as width and precision:
2657
2658```rust
2659#![feature(format_args_capture)]
2660
2661let precision = 2;
2662let s = format!("{:.precision$}", 1.324223);
2663
2664assert_eq!(&s, "1.32");
2665```
2666
2667A non-exhaustive list of macros which benefit from this functionality include:
2668- `format!`
2669- `print!` and `println!`
2670- `eprint!` and `eprintln!`
2671- `write!` and `writeln!`
2672- `panic!`
2673- `unreachable!`
2674- `unimplemented!`
2675- `todo!`
2676- `assert!` and similar
2677- macros in many thirdparty crates, such as `log`
2678"##,
2679 },
2680 Lint {
2681 label: "generators",
2682 description: r##"# `generators`
2683
2684The tracking issue for this feature is: [#43122]
2685
2686[#43122]: https://github.com/rust-lang/rust/issues/43122
2687
2688------------------------
2689
2690The `generators` feature gate in Rust allows you to define generator or
2691coroutine literals. A generator is a "resumable function" that syntactically
2692resembles a closure but compiles to much different semantics in the compiler
2693itself. The primary feature of a generator is that it can be suspended during
2694execution to be resumed at a later date. Generators use the `yield` keyword to
2695"return", and then the caller can `resume` a generator to resume execution just
2696after the `yield` keyword.
2697
2698Generators are an extra-unstable feature in the compiler right now. Added in
2699[RFC 2033] they're mostly intended right now as a information/constraint
2700gathering phase. The intent is that experimentation can happen on the nightly
2701compiler before actual stabilization. A further RFC will be required to
2702stabilize generators/coroutines and will likely contain at least a few small
2703tweaks to the overall design.
2704
2705[RFC 2033]: https://github.com/rust-lang/rfcs/pull/2033
2706
2707A syntactical example of a generator is:
2708
2709```rust
2710#![feature(generators, generator_trait)]
2711
2712use std::ops::{Generator, GeneratorState};
2713use std::pin::Pin;
2714
2715fn main() {
2716 let mut generator = || {
2717 yield 1;
2718 return "foo"
2719 };
2720
2721 match Pin::new(&mut generator).resume(()) {
2722 GeneratorState::Yielded(1) => {}
2723 _ => panic!("unexpected value from resume"),
2724 }
2725 match Pin::new(&mut generator).resume(()) {
2726 GeneratorState::Complete("foo") => {}
2727 _ => panic!("unexpected value from resume"),
2728 }
2729}
2730```
2731
2732Generators are closure-like literals which can contain a `yield` statement. The
2733`yield` statement takes an optional expression of a value to yield out of the
2734generator. All generator literals implement the `Generator` trait in the
2735`std::ops` module. The `Generator` trait has one main method, `resume`, which
2736resumes execution of the generator at the previous suspension point.
2737
2738An example of the control flow of generators is that the following example
2739prints all numbers in order:
2740
2741```rust
2742#![feature(generators, generator_trait)]
2743
2744use std::ops::Generator;
2745use std::pin::Pin;
2746
2747fn main() {
2748 let mut generator = || {
2749 println!("2");
2750 yield;
2751 println!("4");
2752 };
2753
2754 println!("1");
2755 Pin::new(&mut generator).resume(());
2756 println!("3");
2757 Pin::new(&mut generator).resume(());
2758 println!("5");
2759}
2760```
2761
2762At this time the main intended use case of generators is an implementation
2763primitive for async/await syntax, but generators will likely be extended to
2764ergonomic implementations of iterators and other primitives in the future.
2765Feedback on the design and usage is always appreciated!
2766
2767### The `Generator` trait
2768
2769The `Generator` trait in `std::ops` currently looks like:
2770
2771```rust
2772# #![feature(arbitrary_self_types, generator_trait)]
2773# use std::ops::GeneratorState;
2774# use std::pin::Pin;
2775
2776pub trait Generator<R = ()> {
2777 type Yield;
2778 type Return;
2779 fn resume(self: Pin<&mut Self>, resume: R) -> GeneratorState<Self::Yield, Self::Return>;
2780}
2781```
2782
2783The `Generator::Yield` type is the type of values that can be yielded with the
2784`yield` statement. The `Generator::Return` type is the returned type of the
2785generator. This is typically the last expression in a generator's definition or
2786any value passed to `return` in a generator. The `resume` function is the entry
2787point for executing the `Generator` itself.
2788
2789The return value of `resume`, `GeneratorState`, looks like:
2790
2791```rust
2792pub enum GeneratorState<Y, R> {
2793 Yielded(Y),
2794 Complete(R),
2795}
2796```
2797
2798The `Yielded` variant indicates that the generator can later be resumed. This
2799corresponds to a `yield` point in a generator. The `Complete` variant indicates
2800that the generator is complete and cannot be resumed again. Calling `resume`
2801after a generator has returned `Complete` will likely result in a panic of the
2802program.
2803
2804### Closure-like semantics
2805
2806The closure-like syntax for generators alludes to the fact that they also have
2807closure-like semantics. Namely:
2808
2809* When created, a generator executes no code. A closure literal does not
2810 actually execute any of the closure's code on construction, and similarly a
2811 generator literal does not execute any code inside the generator when
2812 constructed.
2813
2814* Generators can capture outer variables by reference or by move, and this can
2815 be tweaked with the `move` keyword at the beginning of the closure. Like
2816 closures all generators will have an implicit environment which is inferred by
2817 the compiler. Outer variables can be moved into a generator for use as the
2818 generator progresses.
2819
2820* Generator literals produce a value with a unique type which implements the
2821 `std::ops::Generator` trait. This allows actual execution of the generator
2822 through the `Generator::resume` method as well as also naming it in return
2823 types and such.
2824
2825* Traits like `Send` and `Sync` are automatically implemented for a `Generator`
2826 depending on the captured variables of the environment. Unlike closures,
2827 generators also depend on variables live across suspension points. This means
2828 that although the ambient environment may be `Send` or `Sync`, the generator
2829 itself may not be due to internal variables live across `yield` points being
2830 not-`Send` or not-`Sync`. Note that generators do
2831 not implement traits like `Copy` or `Clone` automatically.
2832
2833* Whenever a generator is dropped it will drop all captured environment
2834 variables.
2835
2836### Generators as state machines
2837
2838In the compiler, generators are currently compiled as state machines. Each
2839`yield` expression will correspond to a different state that stores all live
2840variables over that suspension point. Resumption of a generator will dispatch on
2841the current state and then execute internally until a `yield` is reached, at
2842which point all state is saved off in the generator and a value is returned.
2843
2844Let's take a look at an example to see what's going on here:
2845
2846```rust
2847#![feature(generators, generator_trait)]
2848
2849use std::ops::Generator;
2850use std::pin::Pin;
2851
2852fn main() {
2853 let ret = "foo";
2854 let mut generator = move || {
2855 yield 1;
2856 return ret
2857 };
2858
2859 Pin::new(&mut generator).resume(());
2860 Pin::new(&mut generator).resume(());
2861}
2862```
2863
2864This generator literal will compile down to something similar to:
2865
2866```rust
2867#![feature(arbitrary_self_types, generators, generator_trait)]
2868
2869use std::ops::{Generator, GeneratorState};
2870use std::pin::Pin;
2871
2872fn main() {
2873 let ret = "foo";
2874 let mut generator = {
2875 enum __Generator {
2876 Start(&'static str),
2877 Yield1(&'static str),
2878 Done,
2879 }
2880
2881 impl Generator for __Generator {
2882 type Yield = i32;
2883 type Return = &'static str;
2884
2885 fn resume(mut self: Pin<&mut Self>, resume: ()) -> GeneratorState<i32, &'static str> {
2886 use std::mem;
2887 match mem::replace(&mut *self, __Generator::Done) {
2888 __Generator::Start(s) => {
2889 *self = __Generator::Yield1(s);
2890 GeneratorState::Yielded(1)
2891 }
2892
2893 __Generator::Yield1(s) => {
2894 *self = __Generator::Done;
2895 GeneratorState::Complete(s)
2896 }
2897
2898 __Generator::Done => {
2899 panic!("generator resumed after completion")
2900 }
2901 }
2902 }
2903 }
2904
2905 __Generator::Start(ret)
2906 };
2907
2908 Pin::new(&mut generator).resume(());
2909 Pin::new(&mut generator).resume(());
2910}
2911```
2912
2913Notably here we can see that the compiler is generating a fresh type,
2914`__Generator` in this case. This type has a number of states (represented here
2915as an `enum`) corresponding to each of the conceptual states of the generator.
2916At the beginning we're closing over our outer variable `foo` and then that
2917variable is also live over the `yield` point, so it's stored in both states.
2918
2919When the generator starts it'll immediately yield 1, but it saves off its state
2920just before it does so indicating that it has reached the yield point. Upon
2921resuming again we'll execute the `return ret` which returns the `Complete`
2922state.
2923
2924Here we can also note that the `Done` state, if resumed, panics immediately as
2925it's invalid to resume a completed generator. It's also worth noting that this
2926is just a rough desugaring, not a normative specification for what the compiler
2927does.
2928"##,
2929 },
2930 Lint {
2931 label: "global_asm",
2932 description: r##"# `global_asm`
2933
2934The tracking issue for this feature is: [#35119]
2935
2936[#35119]: https://github.com/rust-lang/rust/issues/35119
2937
2938------------------------
2939
2940The `global_asm!` macro allows the programmer to write arbitrary
2941assembly outside the scope of a function body, passing it through
2942`rustc` and `llvm` to the assembler. That is to say, `global_asm!` is
2943equivalent to assembling the asm with an external assembler and then
2944linking the resulting object file with the current crate.
2945
2946`global_asm!` fills a role not currently satisfied by either `asm!`
2947or `#[naked]` functions. The programmer has _all_ features of the
2948assembler at their disposal. The linker will expect to resolve any
2949symbols defined in the inline assembly, modulo any symbols marked as
2950external. It also means syntax for directives and assembly follow the
2951conventions of the assembler in your toolchain.
2952
2953A simple usage looks like this:
2954
2955```rust,ignore (requires-external-file)
2956#![feature(global_asm)]
2957# // you also need relevant target_arch cfgs
2958global_asm!(include_str!("something_neato.s"));
2959```
2960
2961And a more complicated usage looks like this:
2962
2963```rust,no_run
2964#![feature(global_asm)]
2965# #[cfg(any(target_arch="x86", target_arch="x86_64"))]
2966# mod x86 {
2967
2968pub mod sally {
2969 global_asm!(
2970 ".global foo",
2971 "foo:",
2972 "jmp baz",
2973 );
2974
2975 #[no_mangle]
2976 pub unsafe extern "C" fn baz() {}
2977}
2978
2979// the symbols `foo` and `bar` are global, no matter where
2980// `global_asm!` was used.
2981extern "C" {
2982 fn foo();
2983 fn bar();
2984}
2985
2986pub mod harry {
2987 global_asm!(
2988 ".global bar",
2989 "bar:",
2990 "jmp quux",
2991 );
2992
2993 #[no_mangle]
2994 pub unsafe extern "C" fn quux() {}
2995}
2996# }
2997```
2998
2999You may use `global_asm!` multiple times, anywhere in your crate, in
3000whatever way suits you. However, you should not rely on assembler state
3001(e.g. assembler macros) defined in one `global_asm!` to be available in
3002another one. It is implementation-defined whether the multiple usages
3003are concatenated into one or assembled separately.
3004
3005`global_asm!` also supports `const` operands like `asm!`, which allows
3006constants defined in Rust to be used in assembly code:
3007
3008```rust,no_run
3009#![feature(global_asm)]
3010# #[cfg(any(target_arch="x86", target_arch="x86_64"))]
3011# mod x86 {
3012const C: i32 = 1234;
3013global_asm!(
3014 ".global bar",
3015 "bar: .word {c}",
3016 c = const C,
3017);
3018# }
3019```
3020
3021The syntax for passing operands is the same as `asm!` except that only
3022`const` operands are allowed. Refer to the [asm](asm.md) documentation
3023for more details.
3024
3025On x86, the assembly code will use intel syntax by default. You can
3026override this by adding `options(att_syntax)` at the end of the macro
3027arguments list:
3028
3029```rust,no_run
3030#![feature(global_asm)]
3031# #[cfg(any(target_arch="x86", target_arch="x86_64"))]
3032# mod x86 {
3033global_asm!("movl ${}, %ecx", const 5, options(att_syntax));
3034// is equivalent to
3035global_asm!("mov ecx, {}", const 5);
3036# }
3037```
3038
3039------------------------
3040
3041If you don't need quite as much power and flexibility as
3042`global_asm!` provides, and you don't mind restricting your inline
3043assembly to `fn` bodies only, you might try the
3044[asm](asm.md) feature instead.
3045"##,
3046 },
3047 Lint {
3048 label: "impl_trait_in_bindings",
3049 description: r##"# `impl_trait_in_bindings`
3050
3051The tracking issue for this feature is: [#63065]
3052
3053[#63065]: https://github.com/rust-lang/rust/issues/63065
3054
3055------------------------
3056
3057The `impl_trait_in_bindings` feature gate lets you use `impl Trait` syntax in
3058`let`, `static`, and `const` bindings.
3059
3060A simple example is:
3061
3062```rust
3063#![feature(impl_trait_in_bindings)]
3064
3065use std::fmt::Debug;
3066
3067fn main() {
3068 let a: impl Debug + Clone = 42;
3069 let b = a.clone();
3070 println!("{:?}", b); // prints `42`
3071}
3072```
3073
3074Note however that because the types of `a` and `b` are opaque in the above
3075example, calling inherent methods or methods outside of the specified traits
3076(e.g., `a.abs()` or `b.abs()`) is not allowed, and yields an error.
3077"##,
3078 },
3079 Lint {
3080 label: "infer_static_outlives_requirements",
3081 description: r##"# `infer_static_outlives_requirements`
3082
3083The tracking issue for this feature is: [#54185]
3084
3085[#54185]: https://github.com/rust-lang/rust/issues/54185
3086
3087------------------------
3088The `infer_static_outlives_requirements` feature indicates that certain
3089`'static` outlives requirements can be inferred by the compiler rather than
3090stating them explicitly.
3091
3092Note: It is an accompanying feature to `infer_outlives_requirements`,
3093which must be enabled to infer outlives requirements.
3094
3095For example, currently generic struct definitions that contain
3096references, require where-clauses of the form T: 'static. By using
3097this feature the outlives predicates will be inferred, although
3098they may still be written explicitly.
3099
3100```rust,ignore (pseudo-Rust)
3101struct Foo<U> where U: 'static { // <-- currently required
3102 bar: Bar<U>
3103}
3104struct Bar<T: 'static> {
3105 x: T,
3106}
3107```
3108
3109
3110## Examples:
3111
3112```rust,ignore (pseudo-Rust)
3113#![feature(infer_outlives_requirements)]
3114#![feature(infer_static_outlives_requirements)]
3115
3116#[rustc_outlives]
3117// Implicitly infer U: 'static
3118struct Foo<U> {
3119 bar: Bar<U>
3120}
3121struct Bar<T: 'static> {
3122 x: T,
3123}
3124```
3125"##,
3126 },
3127 Lint {
3128 label: "inline_const",
3129 description: r##"# `inline_const`
3130
3131The tracking issue for this feature is: [#76001]
3132
3133------
3134
3135This feature allows you to use inline constant expressions. For example, you can
3136turn this code:
3137
3138```rust
3139# fn add_one(x: i32) -> i32 { x + 1 }
3140const MY_COMPUTATION: i32 = 1 + 2 * 3 / 4;
3141
3142fn main() {
3143 let x = add_one(MY_COMPUTATION);
3144}
3145```
3146
3147into this code:
3148
3149```rust
3150#![feature(inline_const)]
3151
3152# fn add_one(x: i32) -> i32 { x + 1 }
3153fn main() {
3154 let x = add_one(const { 1 + 2 * 3 / 4 });
3155}
3156```
3157
3158You can also use inline constant expressions in patterns:
3159
3160```rust
3161#![feature(inline_const)]
3162
3163const fn one() -> i32 { 1 }
3164
3165let some_int = 3;
3166match some_int {
3167 const { 1 + 2 } => println!("Matched 1 + 2"),
3168 const { one() } => println!("Matched const fn returning 1"),
3169 _ => println!("Didn't match anything :("),
3170}
3171```
3172
3173[#76001]: https://github.com/rust-lang/rust/issues/76001
3174"##,
3175 },
3176 Lint {
3177 label: "int_error_internals",
3178 description: r##"# `int_error_internals`
3179
3180This feature is internal to the Rust compiler and is not intended for general use.
3181
3182------------------------
3183"##,
3184 },
3185 Lint {
3186 label: "internal_output_capture",
3187 description: r##"# `internal_output_capture`
3188
3189This feature is internal to the Rust compiler and is not intended for general use.
3190
3191------------------------
3192"##,
3193 },
3194 Lint {
3195 label: "intra_doc_pointers",
3196 description: r##"# `intra-doc-pointers`
3197
3198The tracking issue for this feature is: [#80896]
3199
3200[#80896]: https://github.com/rust-lang/rust/issues/80896
3201
3202------------------------
3203
3204Rustdoc does not currently allow disambiguating between `*const` and `*mut`, and
3205raw pointers in intra-doc links are unstable until it does.
3206
3207```rust
3208#![feature(intra_doc_pointers)]
3209//! [pointer::add]
3210```
3211"##,
3212 },
3213 Lint {
3214 label: "intrinsics",
3215 description: r##"# `intrinsics`
3216
3217The tracking issue for this feature is: None.
3218
3219Intrinsics are never intended to be stable directly, but intrinsics are often
3220exported in some sort of stable manner. Prefer using the stable interfaces to
3221the intrinsic directly when you can.
3222
3223------------------------
3224
3225
3226These are imported as if they were FFI functions, with the special
3227`rust-intrinsic` ABI. For example, if one was in a freestanding
3228context, but wished to be able to `transmute` between types, and
3229perform efficient pointer arithmetic, one would import those functions
3230via a declaration like
3231
3232```rust
3233#![feature(intrinsics)]
3234# fn main() {}
3235
3236extern "rust-intrinsic" {
3237 fn transmute<T, U>(x: T) -> U;
3238
3239 fn offset<T>(dst: *const T, offset: isize) -> *const T;
3240}
3241```
3242
3243As with any other FFI functions, these are always `unsafe` to call.
3244"##,
3245 },
3246 Lint {
3247 label: "is_sorted",
3248 description: r##"# `is_sorted`
3249
3250The tracking issue for this feature is: [#53485]
3251
3252[#53485]: https://github.com/rust-lang/rust/issues/53485
3253
3254------------------------
3255
3256Add the methods `is_sorted`, `is_sorted_by` and `is_sorted_by_key` to `[T]`;
3257add the methods `is_sorted`, `is_sorted_by` and `is_sorted_by_key` to
3258`Iterator`.
3259"##,
3260 },
3261 Lint {
3262 label: "lang_items",
3263 description: r##"# `lang_items`
3264
3265The tracking issue for this feature is: None.
3266
3267------------------------
3268
3269The `rustc` compiler has certain pluggable operations, that is,
3270functionality that isn't hard-coded into the language, but is
3271implemented in libraries, with a special marker to tell the compiler
3272it exists. The marker is the attribute `#[lang = "..."]` and there are
3273various different values of `...`, i.e. various different 'lang
3274items'.
3275
3276For example, `Box` pointers require two lang items, one for allocation
3277and one for deallocation. A freestanding program that uses the `Box`
3278sugar for dynamic allocations via `malloc` and `free`:
3279
3280```rust,ignore (libc-is-finicky)
3281#![feature(lang_items, box_syntax, start, libc, core_intrinsics, rustc_private)]
3282#![no_std]
3283use core::intrinsics;
3284use core::panic::PanicInfo;
3285
3286extern crate libc;
3287
3288#[lang = "owned_box"]
3289pub struct Box<T>(*mut T);
3290
3291#[lang = "exchange_malloc"]
3292unsafe fn allocate(size: usize, _align: usize) -> *mut u8 {
3293 let p = libc::malloc(size as libc::size_t) as *mut u8;
3294
3295 // Check if `malloc` failed:
3296 if p as usize == 0 {
3297 intrinsics::abort();
3298 }
3299
3300 p
3301}
3302
3303#[lang = "box_free"]
3304unsafe fn box_free<T: ?Sized>(ptr: *mut T) {
3305 libc::free(ptr as *mut libc::c_void)
3306}
3307
3308#[start]
3309fn main(_argc: isize, _argv: *const *const u8) -> isize {
3310 let _x = box 1;
3311
3312 0
3313}
3314
3315#[lang = "eh_personality"] extern fn rust_eh_personality() {}
3316#[lang = "panic_impl"] extern fn rust_begin_panic(info: &PanicInfo) -> ! { unsafe { intrinsics::abort() } }
3317#[no_mangle] pub extern fn rust_eh_register_frames () {}
3318#[no_mangle] pub extern fn rust_eh_unregister_frames () {}
3319```
3320
3321Note the use of `abort`: the `exchange_malloc` lang item is assumed to
3322return a valid pointer, and so needs to do the check internally.
3323
3324Other features provided by lang items include:
3325
3326- overloadable operators via traits: the traits corresponding to the
3327 `==`, `<`, dereferencing (`*`) and `+` (etc.) operators are all
3328 marked with lang items; those specific four are `eq`, `ord`,
3329 `deref`, and `add` respectively.
3330- stack unwinding and general failure; the `eh_personality`,
3331 `panic` and `panic_bounds_check` lang items.
3332- the traits in `std::marker` used to indicate types of
3333 various kinds; lang items `send`, `sync` and `copy`.
3334- the marker types and variance indicators found in
3335 `std::marker`; lang items `covariant_type`,
3336 `contravariant_lifetime`, etc.
3337
3338Lang items are loaded lazily by the compiler; e.g. if one never uses
3339`Box` then there is no need to define functions for `exchange_malloc`
3340and `box_free`. `rustc` will emit an error when an item is needed
3341but not found in the current crate or any that it depends on.
3342
3343Most lang items are defined by `libcore`, but if you're trying to build
3344an executable without the standard library, you'll run into the need
3345for lang items. The rest of this page focuses on this use-case, even though
3346lang items are a bit broader than that.
3347
3348### Using libc
3349
3350In order to build a `#[no_std]` executable we will need libc as a dependency.
3351We can specify this using our `Cargo.toml` file:
3352
3353```toml
3354[dependencies]
3355libc = { version = "0.2.14", default-features = false }
3356```
3357
3358Note that the default features have been disabled. This is a critical step -
3359**the default features of libc include the standard library and so must be
3360disabled.**
3361
3362### Writing an executable without stdlib
3363
3364Controlling the entry point is possible in two ways: the `#[start]` attribute,
3365or overriding the default shim for the C `main` function with your own.
3366
3367The function marked `#[start]` is passed the command line parameters
3368in the same format as C:
3369
3370```rust,ignore (libc-is-finicky)
3371#![feature(lang_items, core_intrinsics, rustc_private)]
3372#![feature(start)]
3373#![no_std]
3374use core::intrinsics;
3375use core::panic::PanicInfo;
3376
3377// Pull in the system libc library for what crt0.o likely requires.
3378extern crate libc;
3379
3380// Entry point for this program.
3381#[start]
3382fn start(_argc: isize, _argv: *const *const u8) -> isize {
3383 0
3384}
3385
3386// These functions are used by the compiler, but not
3387// for a bare-bones hello world. These are normally
3388// provided by libstd.
3389#[lang = "eh_personality"]
3390#[no_mangle]
3391pub extern fn rust_eh_personality() {
3392}
3393
3394#[lang = "panic_impl"]
3395#[no_mangle]
3396pub extern fn rust_begin_panic(info: &PanicInfo) -> ! {
3397 unsafe { intrinsics::abort() }
3398}
3399```
3400
3401To override the compiler-inserted `main` shim, one has to disable it
3402with `#![no_main]` and then create the appropriate symbol with the
3403correct ABI and the correct name, which requires overriding the
3404compiler's name mangling too:
3405
3406```rust,ignore (libc-is-finicky)
3407#![feature(lang_items, core_intrinsics, rustc_private)]
3408#![feature(start)]
3409#![no_std]
3410#![no_main]
3411use core::intrinsics;
3412use core::panic::PanicInfo;
3413
3414// Pull in the system libc library for what crt0.o likely requires.
3415extern crate libc;
3416
3417// Entry point for this program.
3418#[no_mangle] // ensure that this symbol is called `main` in the output
3419pub extern fn main(_argc: i32, _argv: *const *const u8) -> i32 {
3420 0
3421}
3422
3423// These functions are used by the compiler, but not
3424// for a bare-bones hello world. These are normally
3425// provided by libstd.
3426#[lang = "eh_personality"]
3427#[no_mangle]
3428pub extern fn rust_eh_personality() {
3429}
3430
3431#[lang = "panic_impl"]
3432#[no_mangle]
3433pub extern fn rust_begin_panic(info: &PanicInfo) -> ! {
3434 unsafe { intrinsics::abort() }
3435}
3436```
3437
3438In many cases, you may need to manually link to the `compiler_builtins` crate
3439when building a `no_std` binary. You may observe this via linker error messages
3440such as "```undefined reference to `__rust_probestack'```".
3441
3442## More about the language items
3443
3444The compiler currently makes a few assumptions about symbols which are
3445available in the executable to call. Normally these functions are provided by
3446the standard library, but without it you must define your own. These symbols
3447are called "language items", and they each have an internal name, and then a
3448signature that an implementation must conform to.
3449
3450The first of these functions, `rust_eh_personality`, is used by the failure
3451mechanisms of the compiler. This is often mapped to GCC's personality function
3452(see the [libstd implementation][unwind] for more information), but crates
3453which do not trigger a panic can be assured that this function is never
3454called. The language item's name is `eh_personality`.
3455
3456[unwind]: https://github.com/rust-lang/rust/blob/master/library/panic_unwind/src/gcc.rs
3457
3458The second function, `rust_begin_panic`, is also used by the failure mechanisms of the
3459compiler. When a panic happens, this controls the message that's displayed on
3460the screen. While the language item's name is `panic_impl`, the symbol name is
3461`rust_begin_panic`.
3462
3463Finally, a `eh_catch_typeinfo` static is needed for certain targets which
3464implement Rust panics on top of C++ exceptions.
3465
3466## List of all language items
3467
3468This is a list of all language items in Rust along with where they are located in
3469the source code.
3470
3471- Primitives
3472 - `i8`: `libcore/num/mod.rs`
3473 - `i16`: `libcore/num/mod.rs`
3474 - `i32`: `libcore/num/mod.rs`
3475 - `i64`: `libcore/num/mod.rs`
3476 - `i128`: `libcore/num/mod.rs`
3477 - `isize`: `libcore/num/mod.rs`
3478 - `u8`: `libcore/num/mod.rs`
3479 - `u16`: `libcore/num/mod.rs`
3480 - `u32`: `libcore/num/mod.rs`
3481 - `u64`: `libcore/num/mod.rs`
3482 - `u128`: `libcore/num/mod.rs`
3483 - `usize`: `libcore/num/mod.rs`
3484 - `f32`: `libstd/f32.rs`
3485 - `f64`: `libstd/f64.rs`
3486 - `char`: `libcore/char.rs`
3487 - `slice`: `liballoc/slice.rs`
3488 - `str`: `liballoc/str.rs`
3489 - `const_ptr`: `libcore/ptr.rs`
3490 - `mut_ptr`: `libcore/ptr.rs`
3491 - `unsafe_cell`: `libcore/cell.rs`
3492- Runtime
3493 - `start`: `libstd/rt.rs`
3494 - `eh_personality`: `libpanic_unwind/emcc.rs` (EMCC)
3495 - `eh_personality`: `libpanic_unwind/gcc.rs` (GNU)
3496 - `eh_personality`: `libpanic_unwind/seh.rs` (SEH)
3497 - `eh_catch_typeinfo`: `libpanic_unwind/emcc.rs` (EMCC)
3498 - `panic`: `libcore/panicking.rs`
3499 - `panic_bounds_check`: `libcore/panicking.rs`
3500 - `panic_impl`: `libcore/panicking.rs`
3501 - `panic_impl`: `libstd/panicking.rs`
3502- Allocations
3503 - `owned_box`: `liballoc/boxed.rs`
3504 - `exchange_malloc`: `liballoc/heap.rs`
3505 - `box_free`: `liballoc/heap.rs`
3506- Operands
3507 - `not`: `libcore/ops/bit.rs`
3508 - `bitand`: `libcore/ops/bit.rs`
3509 - `bitor`: `libcore/ops/bit.rs`
3510 - `bitxor`: `libcore/ops/bit.rs`
3511 - `shl`: `libcore/ops/bit.rs`
3512 - `shr`: `libcore/ops/bit.rs`
3513 - `bitand_assign`: `libcore/ops/bit.rs`
3514 - `bitor_assign`: `libcore/ops/bit.rs`
3515 - `bitxor_assign`: `libcore/ops/bit.rs`
3516 - `shl_assign`: `libcore/ops/bit.rs`
3517 - `shr_assign`: `libcore/ops/bit.rs`
3518 - `deref`: `libcore/ops/deref.rs`
3519 - `deref_mut`: `libcore/ops/deref.rs`
3520 - `index`: `libcore/ops/index.rs`
3521 - `index_mut`: `libcore/ops/index.rs`
3522 - `add`: `libcore/ops/arith.rs`
3523 - `sub`: `libcore/ops/arith.rs`
3524 - `mul`: `libcore/ops/arith.rs`
3525 - `div`: `libcore/ops/arith.rs`
3526 - `rem`: `libcore/ops/arith.rs`
3527 - `neg`: `libcore/ops/arith.rs`
3528 - `add_assign`: `libcore/ops/arith.rs`
3529 - `sub_assign`: `libcore/ops/arith.rs`
3530 - `mul_assign`: `libcore/ops/arith.rs`
3531 - `div_assign`: `libcore/ops/arith.rs`
3532 - `rem_assign`: `libcore/ops/arith.rs`
3533 - `eq`: `libcore/cmp.rs`
3534 - `ord`: `libcore/cmp.rs`
3535- Functions
3536 - `fn`: `libcore/ops/function.rs`
3537 - `fn_mut`: `libcore/ops/function.rs`
3538 - `fn_once`: `libcore/ops/function.rs`
3539 - `generator_state`: `libcore/ops/generator.rs`
3540 - `generator`: `libcore/ops/generator.rs`
3541- Other
3542 - `coerce_unsized`: `libcore/ops/unsize.rs`
3543 - `drop`: `libcore/ops/drop.rs`
3544 - `drop_in_place`: `libcore/ptr.rs`
3545 - `clone`: `libcore/clone.rs`
3546 - `copy`: `libcore/marker.rs`
3547 - `send`: `libcore/marker.rs`
3548 - `sized`: `libcore/marker.rs`
3549 - `unsize`: `libcore/marker.rs`
3550 - `sync`: `libcore/marker.rs`
3551 - `phantom_data`: `libcore/marker.rs`
3552 - `discriminant_kind`: `libcore/marker.rs`
3553 - `freeze`: `libcore/marker.rs`
3554 - `debug_trait`: `libcore/fmt/mod.rs`
3555 - `non_zero`: `libcore/nonzero.rs`
3556 - `arc`: `liballoc/sync.rs`
3557 - `rc`: `liballoc/rc.rs`
3558"##,
3559 },
3560 Lint {
3561 label: "libstd_sys_internals",
3562 description: r##"# `libstd_sys_internals`
3563
3564This feature is internal to the Rust compiler and is not intended for general use.
3565
3566------------------------
3567"##,
3568 },
3569 Lint {
3570 label: "libstd_thread_internals",
3571 description: r##"# `libstd_thread_internals`
3572
3573This feature is internal to the Rust compiler and is not intended for general use.
3574
3575------------------------
3576"##,
3577 },
3578 Lint {
3579 label: "link_cfg",
3580 description: r##"# `link_cfg`
3581
3582This feature is internal to the Rust compiler and is not intended for general use.
3583
3584------------------------
3585"##,
3586 },
3587 Lint {
3588 label: "llvm_asm",
3589 description: r##"# `llvm_asm`
3590
3591The tracking issue for this feature is: [#70173]
3592
3593[#70173]: https://github.com/rust-lang/rust/issues/70173
3594
3595------------------------
3596
3597For extremely low-level manipulations and performance reasons, one
3598might wish to control the CPU directly. Rust supports using inline
3599assembly to do this via the `llvm_asm!` macro.
3600
3601```rust,ignore (pseudo-code)
3602llvm_asm!(assembly template
3603 : output operands
3604 : input operands
3605 : clobbers
3606 : options
3607 );
3608```
3609
3610Any use of `llvm_asm` is feature gated (requires `#![feature(llvm_asm)]` on the
3611crate to allow) and of course requires an `unsafe` block.
3612
3613> **Note**: the examples here are given in x86/x86-64 assembly, but
3614> all platforms are supported.
3615
3616## Assembly template
3617
3618The `assembly template` is the only required parameter and must be a
3619literal string (i.e. `""`)
3620
3621```rust
3622#![feature(llvm_asm)]
3623
3624#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
3625fn foo() {
3626 unsafe {
3627 llvm_asm!("NOP");
3628 }
3629}
3630
3631// Other platforms:
3632#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
3633fn foo() { /* ... */ }
3634
3635fn main() {
3636 // ...
3637 foo();
3638 // ...
3639}
3640```
3641
3642(The `feature(llvm_asm)` and `#[cfg]`s are omitted from now on.)
3643
3644Output operands, input operands, clobbers and options are all optional
3645but you must add the right number of `:` if you skip them:
3646
3647```rust
3648# #![feature(llvm_asm)]
3649# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
3650# fn main() { unsafe {
3651llvm_asm!("xor %eax, %eax"
3652 :
3653 :
3654 : "eax"
3655 );
3656# } }
3657# #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
3658# fn main() {}
3659```
3660
3661Whitespace also doesn't matter:
3662
3663```rust
3664# #![feature(llvm_asm)]
3665# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
3666# fn main() { unsafe {
3667llvm_asm!("xor %eax, %eax" ::: "eax");
3668# } }
3669# #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
3670# fn main() {}
3671```
3672
3673## Operands
3674
3675Input and output operands follow the same format: `:
3676"constraints1"(expr1), "constraints2"(expr2), ..."`. Output operand
3677expressions must be mutable place, or not yet assigned:
3678
3679```rust
3680# #![feature(llvm_asm)]
3681# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
3682fn add(a: i32, b: i32) -> i32 {
3683 let c: i32;
3684 unsafe {
3685 llvm_asm!("add $2, $0"
3686 : "=r"(c)
3687 : "0"(a), "r"(b)
3688 );
3689 }
3690 c
3691}
3692# #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
3693# fn add(a: i32, b: i32) -> i32 { a + b }
3694
3695fn main() {
3696 assert_eq!(add(3, 14159), 14162)
3697}
3698```
3699
3700If you would like to use real operands in this position, however,
3701you are required to put curly braces `{}` around the register that
3702you want, and you are required to put the specific size of the
3703operand. This is useful for very low level programming, where
3704which register you use is important:
3705
3706```rust
3707# #![feature(llvm_asm)]
3708# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
3709# unsafe fn read_byte_in(port: u16) -> u8 {
3710let result: u8;
3711llvm_asm!("in %dx, %al" : "={al}"(result) : "{dx}"(port));
3712result
3713# }
3714```
3715
3716## Clobbers
3717
3718Some instructions modify registers which might otherwise have held
3719different values so we use the clobbers list to indicate to the
3720compiler not to assume any values loaded into those registers will
3721stay valid.
3722
3723```rust
3724# #![feature(llvm_asm)]
3725# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
3726# fn main() { unsafe {
3727// Put the value 0x200 in eax:
3728llvm_asm!("mov $$0x200, %eax" : /* no outputs */ : /* no inputs */ : "eax");
3729# } }
3730# #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
3731# fn main() {}
3732```
3733
3734Input and output registers need not be listed since that information
3735is already communicated by the given constraints. Otherwise, any other
3736registers used either implicitly or explicitly should be listed.
3737
3738If the assembly changes the condition code register `cc` should be
3739specified as one of the clobbers. Similarly, if the assembly modifies
3740memory, `memory` should also be specified.
3741
3742## Options
3743
3744The last section, `options` is specific to Rust. The format is comma
3745separated literal strings (i.e. `:"foo", "bar", "baz"`). It's used to
3746specify some extra info about the inline assembly:
3747
3748Current valid options are:
3749
37501. `volatile` - specifying this is analogous to
3751 `__asm__ __volatile__ (...)` in gcc/clang.
37522. `alignstack` - certain instructions expect the stack to be
3753 aligned a certain way (i.e. SSE) and specifying this indicates to
3754 the compiler to insert its usual stack alignment code
37553. `intel` - use intel syntax instead of the default AT&T.
3756
3757```rust
3758# #![feature(llvm_asm)]
3759# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
3760# fn main() {
3761let result: i32;
3762unsafe {
3763 llvm_asm!("mov eax, 2" : "={eax}"(result) : : : "intel")
3764}
3765println!("eax is currently {}", result);
3766# }
3767# #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
3768# fn main() {}
3769```
3770
3771## More Information
3772
3773The current implementation of the `llvm_asm!` macro is a direct binding to [LLVM's
3774inline assembler expressions][llvm-docs], so be sure to check out [their
3775documentation as well][llvm-docs] for more information about clobbers,
3776constraints, etc.
3777
3778[llvm-docs]: http://llvm.org/docs/LangRef.html#inline-assembler-expressions
3779
3780If you need more power and don't mind losing some of the niceties of
3781`llvm_asm!`, check out [global_asm](global-asm.md).
3782"##,
3783 },
3784 Lint {
3785 label: "marker_trait_attr",
3786 description: r##"# `marker_trait_attr`
3787
3788The tracking issue for this feature is: [#29864]
3789
3790[#29864]: https://github.com/rust-lang/rust/issues/29864
3791
3792------------------------
3793
3794Normally, Rust keeps you from adding trait implementations that could
3795overlap with each other, as it would be ambiguous which to use. This
3796feature, however, carves out an exception to that rule: a trait can
3797opt-in to having overlapping implementations, at the cost that those
3798implementations are not allowed to override anything (and thus the
3799trait itself cannot have any associated items, as they're pointless
3800when they'd need to do the same thing for every type anyway).
3801
3802```rust
3803#![feature(marker_trait_attr)]
3804
3805#[marker] trait CheapToClone: Clone {}
3806
3807impl<T: Copy> CheapToClone for T {}
3808
3809// These could potentially overlap with the blanket implementation above,
3810// so are only allowed because CheapToClone is a marker trait.
3811impl<T: CheapToClone, U: CheapToClone> CheapToClone for (T, U) {}
3812impl<T: CheapToClone> CheapToClone for std::ops::Range<T> {}
3813
3814fn cheap_clone<T: CheapToClone>(t: T) -> T {
3815 t.clone()
3816}
3817```
3818
3819This is expected to replace the unstable `overlapping_marker_traits`
3820feature, which applied to all empty traits (without needing an opt-in).
3821"##,
3822 },
3823 Lint {
3824 label: "native_link_modifiers",
3825 description: r##"# `native_link_modifiers`
3826
3827The tracking issue for this feature is: [#81490]
3828
3829[#81490]: https://github.com/rust-lang/rust/issues/81490
3830
3831------------------------
3832
3833The `native_link_modifiers` feature allows you to use the `modifiers` syntax with the `#[link(..)]` attribute.
3834
3835Modifiers are specified as a comma-delimited string with each modifier prefixed with either a `+` or `-` to indicate that the modifier is enabled or disabled, respectively. The last boolean value specified for a given modifier wins.
3836"##,
3837 },
3838 Lint {
3839 label: "native_link_modifiers_as_needed",
3840 description: r##"# `native_link_modifiers_as_needed`
3841
3842The tracking issue for this feature is: [#81490]
3843
3844[#81490]: https://github.com/rust-lang/rust/issues/81490
3845
3846------------------------
3847
3848The `native_link_modifiers_as_needed` feature allows you to use the `as-needed` modifier.
3849
3850`as-needed` is only compatible with the `dynamic` and `framework` linking kinds. Using any other kind will result in a compiler error.
3851
3852`+as-needed` means that the library will be actually linked only if it satisfies some undefined symbols at the point at which it is specified on the command line, making it similar to static libraries in this regard.
3853
3854This modifier translates to `--as-needed` for ld-like linkers, and to `-dead_strip_dylibs` / `-needed_library` / `-needed_framework` for ld64.
3855The modifier does nothing for linkers that don't support it (e.g. `link.exe`).
3856
3857The default for this modifier is unclear, some targets currently specify it as `+as-needed`, some do not. We may want to try making `+as-needed` a default for all targets.
3858"##,
3859 },
3860 Lint {
3861 label: "native_link_modifiers_bundle",
3862 description: r##"# `native_link_modifiers_bundle`
3863
3864The tracking issue for this feature is: [#81490]
3865
3866[#81490]: https://github.com/rust-lang/rust/issues/81490
3867
3868------------------------
3869
3870The `native_link_modifiers_bundle` feature allows you to use the `bundle` modifier.
3871
3872Only compatible with the `static` linking kind. Using any other kind will result in a compiler error.
3873
3874`+bundle` means objects from the static library are bundled into the produced crate (a rlib, for example) and are used from this crate later during linking of the final binary.
3875
3876`-bundle` means the static library is included into the produced rlib "by name" and object files from it are included only during linking of the final binary, the file search by that name is also performed during final linking.
3877
3878This modifier is supposed to supersede the `static-nobundle` linking kind defined by [RFC 1717](https://github.com/rust-lang/rfcs/pull/1717).
3879
3880The default for this modifier is currently `+bundle`, but it could be changed later on some future edition boundary.
3881"##,
3882 },
3883 Lint {
3884 label: "native_link_modifiers_verbatim",
3885 description: r##"# `native_link_modifiers_verbatim`
3886
3887The tracking issue for this feature is: [#81490]
3888
3889[#81490]: https://github.com/rust-lang/rust/issues/81490
3890
3891------------------------
3892
3893The `native_link_modifiers_verbatim` feature allows you to use the `verbatim` modifier.
3894
3895`+verbatim` means that rustc itself won't add any target-specified library prefixes or suffixes (like `lib` or `.a`) to the library name, and will try its best to ask for the same thing from the linker.
3896
3897For `ld`-like linkers rustc will use the `-l:filename` syntax (note the colon) when passing the library, so the linker won't add any prefixes or suffixes as well.
3898See [`-l namespec`](https://sourceware.org/binutils/docs/ld/Options.html) in ld documentation for more details.
3899For linkers not supporting any verbatim modifiers (e.g. `link.exe` or `ld64`) the library name will be passed as is.
3900
3901The default for this modifier is `-verbatim`.
3902
3903This RFC changes the behavior of `raw-dylib` linking kind specified by [RFC 2627](https://github.com/rust-lang/rfcs/pull/2627). The `.dll` suffix (or other target-specified suffixes for other targets) is now added automatically.
3904If your DLL doesn't have the `.dll` suffix, it can be specified with `+verbatim`.
3905"##,
3906 },
3907 Lint {
3908 label: "native_link_modifiers_whole_archive",
3909 description: r##"# `native_link_modifiers_whole_archive`
3910
3911The tracking issue for this feature is: [#81490]
3912
3913[#81490]: https://github.com/rust-lang/rust/issues/81490
3914
3915------------------------
3916
3917The `native_link_modifiers_whole_archive` feature allows you to use the `whole-archive` modifier.
3918
3919Only compatible with the `static` linking kind. Using any other kind will result in a compiler error.
3920
3921`+whole-archive` means that the static library is linked as a whole archive without throwing any object files away.
3922
3923This modifier translates to `--whole-archive` for `ld`-like linkers, to `/WHOLEARCHIVE` for `link.exe`, and to `-force_load` for `ld64`.
3924The modifier does nothing for linkers that don't support it.
3925
3926The default for this modifier is `-whole-archive`.
3927"##,
3928 },
3929 Lint {
3930 label: "negative_impls",
3931 description: r##"# `negative_impls`
3932
3933The tracking issue for this feature is [#68318].
3934
3935[#68318]: https://github.com/rust-lang/rust/issues/68318
3936
3937----
3938
3939With the feature gate `negative_impls`, you can write negative impls as well as positive ones:
3940
3941```rust
3942#![feature(negative_impls)]
3943trait DerefMut { }
3944impl<T: ?Sized> !DerefMut for &T { }
3945```
3946
3947Negative 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.
3948
3949Negative impls have the following characteristics:
3950
3951* They do not have any items.
3952* They must obey the orphan rules as if they were a positive impl.
3953* They cannot "overlap" with any positive impls.
3954
3955## Semver interaction
3956
3957It is a breaking change to remove a negative impl. Negative impls are a commitment not to implement the given trait for the named types.
3958
3959## Orphan and overlap rules
3960
3961Negative 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.
3962
3963Similarly, 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.)
3964
3965## Interaction with auto traits
3966
3967Declaring a negative impl `impl !SomeAutoTrait for SomeType` for an
3968auto-trait serves two purposes:
3969
3970* as with any trait, it declares that `SomeType` will never implement `SomeAutoTrait`;
3971* it disables the automatic `SomeType: SomeAutoTrait` impl that would otherwise have been generated.
3972
3973Note that, at present, there is no way to indicate that a given type
3974does not implement an auto trait *but that it may do so in the
3975future*. For ordinary types, this is done by simply not declaring any
3976impl at all, but that is not an option for auto traits. A workaround
3977is that one could embed a marker type as one of the fields, where the
3978marker type is `!AutoTrait`.
3979
3980## Immediate uses
3981
3982Negative 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).
3983
3984This serves two purposes:
3985
3986* For proving the correctness of unsafe code, we can use that impl as evidence that no `DerefMut` or `Clone` impl exists.
3987* It prevents downstream crates from creating such impls.
3988"##,
3989 },
3990 Lint {
3991 label: "no_coverage",
3992 description: r##"# `no_coverage`
3993
3994The tracking issue for this feature is: [#84605]
3995
3996[#84605]: https://github.com/rust-lang/rust/issues/84605
3997
3998---
3999
4000The `no_coverage` attribute can be used to selectively disable coverage
4001instrumentation in an annotated function. This might be useful to:
4002
4003- Avoid instrumentation overhead in a performance critical function
4004- Avoid generating coverage for a function that is not meant to be executed,
4005 but still target 100% coverage for the rest of the program.
4006
4007## Example
4008
4009```rust
4010#![feature(no_coverage)]
4011
4012// `foo()` will get coverage instrumentation (by default)
4013fn foo() {
4014 // ...
4015}
4016
4017#[no_coverage]
4018fn bar() {
4019 // ...
4020}
4021```
4022"##,
4023 },
4024 Lint {
4025 label: "no_sanitize",
4026 description: r##"# `no_sanitize`
4027
4028The tracking issue for this feature is: [#39699]
4029
4030[#39699]: https://github.com/rust-lang/rust/issues/39699
4031
4032------------------------
4033
4034The `no_sanitize` attribute can be used to selectively disable sanitizer
4035instrumentation in an annotated function. This might be useful to: avoid
4036instrumentation overhead in a performance critical function, or avoid
4037instrumenting code that contains constructs unsupported by given sanitizer.
4038
4039The precise effect of this annotation depends on particular sanitizer in use.
4040For example, with `no_sanitize(thread)`, the thread sanitizer will no longer
4041instrument non-atomic store / load operations, but it will instrument atomic
4042operations to avoid reporting false positives and provide meaning full stack
4043traces.
4044
4045## Examples
4046
4047``` rust
4048#![feature(no_sanitize)]
4049
4050#[no_sanitize(address)]
4051fn foo() {
4052 // ...
4053}
4054```
4055"##,
4056 },
4057 Lint {
4058 label: "plugin",
4059 description: r##"# `plugin`
4060
4061The tracking issue for this feature is: [#29597]
4062
4063[#29597]: https://github.com/rust-lang/rust/issues/29597
4064
4065
4066This feature is part of "compiler plugins." It will often be used with the
4067[`plugin_registrar`] and `rustc_private` features.
4068
4069[`plugin_registrar`]: plugin-registrar.md
4070
4071------------------------
4072
4073`rustc` can load compiler plugins, which are user-provided libraries that
4074extend the compiler's behavior with new lint checks, etc.
4075
4076A plugin is a dynamic library crate with a designated *registrar* function that
4077registers extensions with `rustc`. Other crates can load these extensions using
4078the crate attribute `#![plugin(...)]`. See the
4079`rustc_driver::plugin` documentation for more about the
4080mechanics of defining and loading a plugin.
4081
4082In the vast majority of cases, a plugin should *only* be used through
4083`#![plugin]` and not through an `extern crate` item. Linking a plugin would
4084pull in all of librustc_ast and librustc as dependencies of your crate. This is
4085generally unwanted unless you are building another plugin.
4086
4087The usual practice is to put compiler plugins in their own crate, separate from
4088any `macro_rules!` macros or ordinary Rust code meant to be used by consumers
4089of a library.
4090
4091# Lint plugins
4092
4093Plugins can extend [Rust's lint
4094infrastructure](../../reference/attributes/diagnostics.md#lint-check-attributes) with
4095additional checks for code style, safety, etc. Now let's write a plugin
4096[`lint-plugin-test.rs`](https://github.com/rust-lang/rust/blob/master/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs)
4097that warns about any item named `lintme`.
4098
4099```rust,ignore (requires-stage-2)
4100#![feature(plugin_registrar)]
4101#![feature(box_syntax, rustc_private)]
4102
4103extern crate rustc_ast;
4104
4105// Load rustc as a plugin to get macros
4106extern crate rustc_driver;
4107#[macro_use]
4108extern crate rustc_lint;
4109#[macro_use]
4110extern crate rustc_session;
4111
4112use rustc_driver::plugin::Registry;
4113use rustc_lint::{EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass};
4114use rustc_ast::ast;
4115declare_lint!(TEST_LINT, Warn, "Warn about items named 'lintme'");
4116
4117declare_lint_pass!(Pass => [TEST_LINT]);
4118
4119impl EarlyLintPass for Pass {
4120 fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) {
4121 if it.ident.name.as_str() == "lintme" {
4122 cx.lint(TEST_LINT, |lint| {
4123 lint.build("item is named 'lintme'").set_span(it.span).emit()
4124 });
4125 }
4126 }
4127}
4128
4129#[plugin_registrar]
4130pub fn plugin_registrar(reg: &mut Registry) {
4131 reg.lint_store.register_lints(&[&TEST_LINT]);
4132 reg.lint_store.register_early_pass(|| box Pass);
4133}
4134```
4135
4136Then code like
4137
4138```rust,ignore (requires-plugin)
4139#![feature(plugin)]
4140#![plugin(lint_plugin_test)]
4141
4142fn lintme() { }
4143```
4144
4145will produce a compiler warning:
4146
4147```txt
4148foo.rs:4:1: 4:16 warning: item is named 'lintme', #[warn(test_lint)] on by default
4149foo.rs:4 fn lintme() { }
4150 ^~~~~~~~~~~~~~~
4151```
4152
4153The components of a lint plugin are:
4154
4155* one or more `declare_lint!` invocations, which define static `Lint` structs;
4156
4157* a struct holding any state needed by the lint pass (here, none);
4158
4159* a `LintPass`
4160 implementation defining how to check each syntax element. A single
4161 `LintPass` may call `span_lint` for several different `Lint`s, but should
4162 register them all through the `get_lints` method.
4163
4164Lint passes are syntax traversals, but they run at a late stage of compilation
4165where type information is available. `rustc`'s [built-in
4166lints](https://github.com/rust-lang/rust/blob/master/src/librustc_session/lint/builtin.rs)
4167mostly use the same infrastructure as lint plugins, and provide examples of how
4168to access type information.
4169
4170Lints defined by plugins are controlled by the usual [attributes and compiler
4171flags](../../reference/attributes/diagnostics.md#lint-check-attributes), e.g.
4172`#[allow(test_lint)]` or `-A test-lint`. These identifiers are derived from the
4173first argument to `declare_lint!`, with appropriate case and punctuation
4174conversion.
4175
4176You can run `rustc -W help foo.rs` to see a list of lints known to `rustc`,
4177including those provided by plugins loaded by `foo.rs`.
4178"##,
4179 },
4180 Lint {
4181 label: "plugin_registrar",
4182 description: r##"# `plugin_registrar`
4183
4184The tracking issue for this feature is: [#29597]
4185
4186[#29597]: https://github.com/rust-lang/rust/issues/29597
4187
4188This feature is part of "compiler plugins." It will often be used with the
4189[`plugin`] and `rustc_private` features as well. For more details, see
4190their docs.
4191
4192[`plugin`]: plugin.md
4193
4194------------------------
4195"##,
4196 },
4197 Lint {
4198 label: "print_internals",
4199 description: r##"# `print_internals`
4200
4201This feature is internal to the Rust compiler and is not intended for general use.
4202
4203------------------------
4204"##,
4205 },
4206 Lint {
4207 label: "profiler_runtime",
4208 description: r##"# `profiler_runtime`
4209
4210The tracking issue for this feature is: [#42524](https://github.com/rust-lang/rust/issues/42524).
4211
4212------------------------
4213"##,
4214 },
4215 Lint {
4216 label: "profiler_runtime_lib",
4217 description: r##"# `profiler_runtime_lib`
4218
4219This feature is internal to the Rust compiler and is not intended for general use.
4220
4221------------------------
4222"##,
4223 },
4224 Lint {
4225 label: "repr128",
4226 description: r##"# `repr128`
4227
4228The tracking issue for this feature is: [#56071]
4229
4230[#56071]: https://github.com/rust-lang/rust/issues/56071
4231
4232------------------------
4233
4234The `repr128` feature adds support for `#[repr(u128)]` on `enum`s.
4235
4236```rust
4237#![feature(repr128)]
4238
4239#[repr(u128)]
4240enum Foo {
4241 Bar(u64),
4242}
4243```
4244"##,
4245 },
4246 Lint {
4247 label: "rt",
4248 description: r##"# `rt`
4249
4250This feature is internal to the Rust compiler and is not intended for general use.
4251
4252------------------------
4253"##,
4254 },
4255 Lint {
4256 label: "rustc_attrs",
4257 description: r##"# `rustc_attrs`
4258
4259This feature has no tracking issue, and is therefore internal to
4260the compiler, not being intended for general use.
4261
4262Note: `rustc_attrs` enables many rustc-internal attributes and this page
4263only discuss a few of them.
4264
4265------------------------
4266
4267The `rustc_attrs` feature allows debugging rustc type layouts by using
4268`#[rustc_layout(...)]` to debug layout at compile time (it even works
4269with `cargo check`) as an alternative to `rustc -Z print-type-sizes`
4270that is way more verbose.
4271
4272Options provided by `#[rustc_layout(...)]` are `debug`, `size`, `align`,
4273`abi`. Note that it only works on sized types without generics.
4274
4275## Examples
4276
4277```rust,compile_fail
4278#![feature(rustc_attrs)]
4279
4280#[rustc_layout(abi, size)]
4281pub enum X {
4282 Y(u8, u8, u8),
4283 Z(isize),
4284}
4285```
4286
4287When that is compiled, the compiler will error with something like
4288
4289```text
4290error: abi: Aggregate { sized: true }
4291 --> src/lib.rs:4:1
4292 |
42934 | / pub enum T {
42945 | | Y(u8, u8, u8),
42956 | | Z(isize),
42967 | | }
4297 | |_^
4298
4299error: size: Size { raw: 16 }
4300 --> src/lib.rs:4:1
4301 |
43024 | / pub enum T {
43035 | | Y(u8, u8, u8),
43046 | | Z(isize),
43057 | | }
4306 | |_^
4307
4308error: aborting due to 2 previous errors
4309```
4310"##,
4311 },
4312 Lint {
4313 label: "sort_internals",
4314 description: r##"# `sort_internals`
4315
4316This feature is internal to the Rust compiler and is not intended for general use.
4317
4318------------------------
4319"##,
4320 },
4321 Lint {
4322 label: "str_internals",
4323 description: r##"# `str_internals`
4324
4325This feature is internal to the Rust compiler and is not intended for general use.
4326
4327------------------------
4328"##,
4329 },
4330 Lint {
4331 label: "test",
4332 description: r##"# `test`
4333
4334The tracking issue for this feature is: None.
4335
4336------------------------
4337
4338The internals of the `test` crate are unstable, behind the `test` flag. The
4339most widely used part of the `test` crate are benchmark tests, which can test
4340the performance of your code. Let's make our `src/lib.rs` look like this
4341(comments elided):
4342
4343```rust,no_run
4344#![feature(test)]
4345
4346extern crate test;
4347
4348pub fn add_two(a: i32) -> i32 {
4349 a + 2
4350}
4351
4352#[cfg(test)]
4353mod tests {
4354 use super::*;
4355 use test::Bencher;
4356
4357 #[test]
4358 fn it_works() {
4359 assert_eq!(4, add_two(2));
4360 }
4361
4362 #[bench]
4363 fn bench_add_two(b: &mut Bencher) {
4364 b.iter(|| add_two(2));
4365 }
4366}
4367```
4368
4369Note the `test` feature gate, which enables this unstable feature.
4370
4371We've imported the `test` crate, which contains our benchmarking support.
4372We have a new function as well, with the `bench` attribute. Unlike regular
4373tests, which take no arguments, benchmark tests take a `&mut Bencher`. This
4374`Bencher` provides an `iter` method, which takes a closure. This closure
4375contains the code we'd like to benchmark.
4376
4377We can run benchmark tests with `cargo bench`:
4378
4379```bash
4380$ cargo bench
4381 Compiling adder v0.0.1 (file:///home/steve/tmp/adder)
4382 Running target/release/adder-91b3e234d4ed382a
4383
4384running 2 tests
4385test tests::it_works ... ignored
4386test tests::bench_add_two ... bench: 1 ns/iter (+/- 0)
4387
4388test result: ok. 0 passed; 0 failed; 1 ignored; 1 measured
4389```
4390
4391Our non-benchmark test was ignored. You may have noticed that `cargo bench`
4392takes a bit longer than `cargo test`. This is because Rust runs our benchmark
4393a number of times, and then takes the average. Because we're doing so little
4394work in this example, we have a `1 ns/iter (+/- 0)`, but this would show
4395the variance if there was one.
4396
4397Advice on writing benchmarks:
4398
4399
4400* Move setup code outside the `iter` loop; only put the part you want to measure inside
4401* Make the code do "the same thing" on each iteration; do not accumulate or change state
4402* Make the outer function idempotent too; the benchmark runner is likely to run
4403 it many times
4404* Make the inner `iter` loop short and fast so benchmark runs are fast and the
4405 calibrator can adjust the run-length at fine resolution
4406* Make the code in the `iter` loop do something simple, to assist in pinpointing
4407 performance improvements (or regressions)
4408
4409## Gotcha: optimizations
4410
4411There's another tricky part to writing benchmarks: benchmarks compiled with
4412optimizations activated can be dramatically changed by the optimizer so that
4413the benchmark is no longer benchmarking what one expects. For example, the
4414compiler might recognize that some calculation has no external effects and
4415remove it entirely.
4416
4417```rust,no_run
4418#![feature(test)]
4419
4420extern crate test;
4421use test::Bencher;
4422
4423#[bench]
4424fn bench_xor_1000_ints(b: &mut Bencher) {
4425 b.iter(|| {
4426 (0..1000).fold(0, |old, new| old ^ new);
4427 });
4428}
4429```
4430
4431gives the following results
4432
4433```text
4434running 1 test
4435test bench_xor_1000_ints ... bench: 0 ns/iter (+/- 0)
4436
4437test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
4438```
4439
4440The benchmarking runner offers two ways to avoid this. Either, the closure that
4441the `iter` method receives can return an arbitrary value which forces the
4442optimizer to consider the result used and ensures it cannot remove the
4443computation entirely. This could be done for the example above by adjusting the
4444`b.iter` call to
4445
4446```rust
4447# struct X;
4448# impl X { fn iter<T, F>(&self, _: F) where F: FnMut() -> T {} } let b = X;
4449b.iter(|| {
4450 // Note lack of `;` (could also use an explicit `return`).
4451 (0..1000).fold(0, |old, new| old ^ new)
4452});
4453```
4454
4455Or, the other option is to call the generic `test::black_box` function, which
4456is an opaque "black box" to the optimizer and so forces it to consider any
4457argument as used.
4458
4459```rust
4460#![feature(test)]
4461
4462extern crate test;
4463
4464# fn main() {
4465# struct X;
4466# impl X { fn iter<T, F>(&self, _: F) where F: FnMut() -> T {} } let b = X;
4467b.iter(|| {
4468 let n = test::black_box(1000);
4469
4470 (0..n).fold(0, |a, b| a ^ b)
4471})
4472# }
4473```
4474
4475Neither of these read or modify the value, and are very cheap for small values.
4476Larger values can be passed indirectly to reduce overhead (e.g.
4477`black_box(&huge_struct)`).
4478
4479Performing either of the above changes gives the following benchmarking results
4480
4481```text
4482running 1 test
4483test bench_xor_1000_ints ... bench: 131 ns/iter (+/- 3)
4484
4485test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
4486```
4487
4488However, the optimizer can still modify a testcase in an undesirable manner
4489even when using either of the above.
4490"##,
4491 },
4492 Lint {
4493 label: "thread_local_internals",
4494 description: r##"# `thread_local_internals`
4495
4496This feature is internal to the Rust compiler and is not intended for general use.
4497
4498------------------------
4499"##,
4500 },
4501 Lint {
4502 label: "trace_macros",
4503 description: r##"# `trace_macros`
4504
4505The tracking issue for this feature is [#29598].
4506
4507[#29598]: https://github.com/rust-lang/rust/issues/29598
4508
4509------------------------
4510
4511With `trace_macros` you can trace the expansion of macros in your code.
4512
4513## Examples
4514
4515```rust
4516#![feature(trace_macros)]
4517
4518fn main() {
4519 trace_macros!(true);
4520 println!("Hello, Rust!");
4521 trace_macros!(false);
4522}
4523```
4524
4525The `cargo build` output:
4526
4527```txt
4528note: trace_macro
4529 --> src/main.rs:5:5
4530 |
45315 | println!("Hello, Rust!");
4532 | ^^^^^^^^^^^^^^^^^^^^^^^^^
4533 |
4534 = note: expanding `println! { "Hello, Rust!" }`
4535 = note: to `print ! ( concat ! ( "Hello, Rust!" , "\n" ) )`
4536 = note: expanding `print! { concat ! ( "Hello, Rust!" , "\n" ) }`
4537 = note: to `$crate :: io :: _print ( format_args ! ( concat ! ( "Hello, Rust!" , "\n" ) )
4538 )`
4539
4540 Finished dev [unoptimized + debuginfo] target(s) in 0.60 secs
4541```
4542"##,
4543 },
4544 Lint {
4545 label: "trait_alias",
4546 description: r##"# `trait_alias`
4547
4548The tracking issue for this feature is: [#41517]
4549
4550[#41517]: https://github.com/rust-lang/rust/issues/41517
4551
4552------------------------
4553
4554The `trait_alias` feature adds support for trait aliases. These allow aliases
4555to be created for one or more traits (currently just a single regular trait plus
4556any number of auto-traits), and used wherever traits would normally be used as
4557either bounds or trait objects.
4558
4559```rust
4560#![feature(trait_alias)]
4561
4562trait Foo = std::fmt::Debug + Send;
4563trait Bar = Foo + Sync;
4564
4565// Use trait alias as bound on type parameter.
4566fn foo<T: Foo>(v: &T) {
4567 println!("{:?}", v);
4568}
4569
4570pub fn main() {
4571 foo(&1);
4572
4573 // Use trait alias for trait objects.
4574 let a: &Bar = &123;
4575 println!("{:?}", a);
4576 let b = Box::new(456) as Box<dyn Foo>;
4577 println!("{:?}", b);
4578}
4579```
4580"##,
4581 },
4582 Lint {
4583 label: "transparent_unions",
4584 description: r##"# `transparent_unions`
4585
4586The tracking issue for this feature is [#60405]
4587
4588[#60405]: https://github.com/rust-lang/rust/issues/60405
4589
4590----
4591
4592The `transparent_unions` feature allows you mark `union`s as
4593`#[repr(transparent)]`. A `union` may be `#[repr(transparent)]` in exactly the
4594same conditions in which a `struct` may be `#[repr(transparent)]` (generally,
4595this means the `union` must have exactly one non-zero-sized field). Some
4596concrete illustrations follow.
4597
4598```rust
4599#![feature(transparent_unions)]
4600
4601// This union has the same representation as `f32`.
4602#[repr(transparent)]
4603union SingleFieldUnion {
4604 field: f32,
4605}
4606
4607// This union has the same representation as `usize`.
4608#[repr(transparent)]
4609union MultiFieldUnion {
4610 field: usize,
4611 nothing: (),
4612}
4613```
4614
4615For consistency with transparent `struct`s, `union`s must have exactly one
4616non-zero-sized field. If all fields are zero-sized, the `union` must not be
4617`#[repr(transparent)]`:
4618
4619```rust
4620#![feature(transparent_unions)]
4621
4622// This (non-transparent) union is already valid in stable Rust:
4623pub union GoodUnion {
4624 pub nothing: (),
4625}
4626
4627// Error: transparent union needs exactly one non-zero-sized field, but has 0
4628// #[repr(transparent)]
4629// pub union BadUnion {
4630// pub nothing: (),
4631// }
4632```
4633
4634The one exception is if the `union` is generic over `T` and has a field of type
4635`T`, it may be `#[repr(transparent)]` even if `T` is a zero-sized type:
4636
4637```rust
4638#![feature(transparent_unions)]
4639
4640// This union has the same representation as `T`.
4641#[repr(transparent)]
4642pub union GenericUnion<T: Copy> { // Unions with non-`Copy` fields are unstable.
4643 pub field: T,
4644 pub nothing: (),
4645}
4646
4647// This is okay even though `()` is a zero-sized type.
4648pub const THIS_IS_OKAY: GenericUnion<()> = GenericUnion { field: () };
4649```
4650
4651Like transarent `struct`s, a transparent `union` of type `U` has the same
4652layout, size, and ABI as its single non-ZST field. If it is generic over a type
4653`T`, and all its fields are ZSTs except for exactly one field of type `T`, then
4654it has the same layout and ABI as `T` (even if `T` is a ZST when monomorphized).
4655
4656Like transparent `struct`s, transparent `union`s are FFI-safe if and only if
4657their underlying representation type is also FFI-safe.
4658
4659A `union` may not be eligible for the same nonnull-style optimizations that a
4660`struct` or `enum` (with the same fields) are eligible for. Adding
4661`#[repr(transparent)]` to `union` does not change this. To give a more concrete
4662example, it is unspecified whether `size_of::<T>()` is equal to
4663`size_of::<Option<T>>()`, where `T` is a `union` (regardless of whether or not
4664it is transparent). The Rust compiler is free to perform this optimization if
4665possible, but is not required to, and different compiler versions may differ in
4666their application of these optimizations.
4667"##,
4668 },
4669 Lint {
4670 label: "try_blocks",
4671 description: r##"# `try_blocks`
4672
4673The tracking issue for this feature is: [#31436]
4674
4675[#31436]: https://github.com/rust-lang/rust/issues/31436
4676
4677------------------------
4678
4679The `try_blocks` feature adds support for `try` blocks. A `try`
4680block creates a new scope one can use the `?` operator in.
4681
4682```rust,edition2018
4683#![feature(try_blocks)]
4684
4685use std::num::ParseIntError;
4686
4687let result: Result<i32, ParseIntError> = try {
4688 "1".parse::<i32>()?
4689 + "2".parse::<i32>()?
4690 + "3".parse::<i32>()?
4691};
4692assert_eq!(result, Ok(6));
4693
4694let result: Result<i32, ParseIntError> = try {
4695 "1".parse::<i32>()?
4696 + "foo".parse::<i32>()?
4697 + "3".parse::<i32>()?
4698};
4699assert!(result.is_err());
4700```
4701"##,
4702 },
4703 Lint {
4704 label: "try_trait",
4705 description: r##"# `try_trait`
4706
4707The tracking issue for this feature is: [#42327]
4708
4709[#42327]: https://github.com/rust-lang/rust/issues/42327
4710
4711------------------------
4712
4713This introduces a new trait `Try` for extending the `?` operator to types
4714other than `Result` (a part of [RFC 1859]). The trait provides the canonical
4715way to _view_ a type in terms of a success/failure dichotomy. This will
4716allow `?` to supplant the `try_opt!` macro on `Option` and the `try_ready!`
4717macro on `Poll`, among other things.
4718
4719[RFC 1859]: https://github.com/rust-lang/rfcs/pull/1859
4720
4721Here's an example implementation of the trait:
4722
4723```rust,ignore (cannot-reimpl-Try)
4724/// A distinct type to represent the `None` value of an `Option`.
4725///
4726/// This enables using the `?` operator on `Option`; it's rarely useful alone.
4727#[derive(Debug)]
4728#[unstable(feature = "try_trait", issue = "42327")]
4729pub struct None { _priv: () }
4730
4731#[unstable(feature = "try_trait", issue = "42327")]
4732impl<T> ops::Try for Option<T> {
4733 type Ok = T;
4734 type Error = None;
4735
4736 fn into_result(self) -> Result<T, None> {
4737 self.ok_or(None { _priv: () })
4738 }
4739
4740 fn from_ok(v: T) -> Self {
4741 Some(v)
4742 }
4743
4744 fn from_error(_: None) -> Self {
4745 None
4746 }
4747}
4748```
4749
4750Note the `Error` associated type here is a new marker. The `?` operator
4751allows interconversion between different `Try` implementers only when
4752the error type can be converted `Into` the error type of the enclosing
4753function (or catch block). Having a distinct error type (as opposed to
4754just `()`, or similar) restricts this to where it's semantically meaningful.
4755"##,
4756 },
4757 Lint {
4758 label: "unboxed_closures",
4759 description: r##"# `unboxed_closures`
4760
4761The tracking issue for this feature is [#29625]
4762
4763See Also: [`fn_traits`](../library-features/fn-traits.md)
4764
4765[#29625]: https://github.com/rust-lang/rust/issues/29625
4766
4767----
4768
4769The `unboxed_closures` feature allows you to write functions using the `"rust-call"` ABI,
4770required for implementing the [`Fn*`] family of traits. `"rust-call"` functions must have
4771exactly one (non self) argument, a tuple representing the argument list.
4772
4773[`Fn*`]: https://doc.rust-lang.org/std/ops/trait.Fn.html
4774
4775```rust
4776#![feature(unboxed_closures)]
4777
4778extern "rust-call" fn add_args(args: (u32, u32)) -> u32 {
4779 args.0 + args.1
4780}
4781
4782fn main() {}
4783```
4784"##,
4785 },
4786 Lint {
4787 label: "unsized_locals",
4788 description: r##"# `unsized_locals`
4789
4790The tracking issue for this feature is: [#48055]
4791
4792[#48055]: https://github.com/rust-lang/rust/issues/48055
4793
4794------------------------
4795
4796This implements [RFC1909]. When turned on, you can have unsized arguments and locals:
4797
4798[RFC1909]: https://github.com/rust-lang/rfcs/blob/master/text/1909-unsized-rvalues.md
4799
4800```rust
4801#![allow(incomplete_features)]
4802#![feature(unsized_locals, unsized_fn_params)]
4803
4804use std::any::Any;
4805
4806fn main() {
4807 let x: Box<dyn Any> = Box::new(42);
4808 let x: dyn Any = *x;
4809 // ^ unsized local variable
4810 // ^^ unsized temporary
4811 foo(x);
4812}
4813
4814fn foo(_: dyn Any) {}
4815// ^^^^^^ unsized argument
4816```
4817
4818The RFC still forbids the following unsized expressions:
4819
4820```rust,compile_fail
4821#![feature(unsized_locals)]
4822
4823use std::any::Any;
4824
4825struct MyStruct<T: ?Sized> {
4826 content: T,
4827}
4828
4829struct MyTupleStruct<T: ?Sized>(T);
4830
4831fn answer() -> Box<dyn Any> {
4832 Box::new(42)
4833}
4834
4835fn main() {
4836 // You CANNOT have unsized statics.
4837 static X: dyn Any = *answer(); // ERROR
4838 const Y: dyn Any = *answer(); // ERROR
4839
4840 // You CANNOT have struct initialized unsized.
4841 MyStruct { content: *answer() }; // ERROR
4842 MyTupleStruct(*answer()); // ERROR
4843 (42, *answer()); // ERROR
4844
4845 // You CANNOT have unsized return types.
4846 fn my_function() -> dyn Any { *answer() } // ERROR
4847
4848 // You CAN have unsized local variables...
4849 let mut x: dyn Any = *answer(); // OK
4850 // ...but you CANNOT reassign to them.
4851 x = *answer(); // ERROR
4852
4853 // You CANNOT even initialize them separately.
4854 let y: dyn Any; // OK
4855 y = *answer(); // ERROR
4856
4857 // Not mentioned in the RFC, but by-move captured variables are also Sized.
4858 let x: dyn Any = *answer();
4859 (move || { // ERROR
4860 let y = x;
4861 })();
4862
4863 // You CAN create a closure with unsized arguments,
4864 // but you CANNOT call it.
4865 // This is an implementation detail and may be changed in the future.
4866 let f = |x: dyn Any| {};
4867 f(*answer()); // ERROR
4868}
4869```
4870
4871## By-value trait objects
4872
4873With this feature, you can have by-value `self` arguments without `Self: Sized` bounds.
4874
4875```rust
4876#![feature(unsized_fn_params)]
4877
4878trait Foo {
4879 fn foo(self) {}
4880}
4881
4882impl<T: ?Sized> Foo for T {}
4883
4884fn main() {
4885 let slice: Box<[i32]> = Box::new([1, 2, 3]);
4886 <[i32] as Foo>::foo(*slice);
4887}
4888```
4889
4890And `Foo` will also be object-safe.
4891
4892```rust
4893#![feature(unsized_fn_params)]
4894
4895trait Foo {
4896 fn foo(self) {}
4897}
4898
4899impl<T: ?Sized> Foo for T {}
4900
4901fn main () {
4902 let slice: Box<dyn Foo> = Box::new([1, 2, 3]);
4903 // doesn't compile yet
4904 <dyn Foo as Foo>::foo(*slice);
4905}
4906```
4907
4908One of the objectives of this feature is to allow `Box<dyn FnOnce>`.
4909
4910## Variable length arrays
4911
4912The 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]`.
4913
4914```rust,ignore (not-yet-implemented)
4915#![feature(unsized_locals)]
4916
4917fn mergesort<T: Ord>(a: &mut [T]) {
4918 let mut tmp = [T; dyn a.len()];
4919 // ...
4920}
4921
4922fn main() {
4923 let mut a = [3, 1, 5, 6];
4924 mergesort(&mut a);
4925 assert_eq!(a, [1, 3, 5, 6]);
4926}
4927```
4928
4929VLAs 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]`.
4930
4931## Advisory on stack usage
4932
4933It's advised not to casually use the `#![feature(unsized_locals)]` feature. Typical use-cases are:
4934
4935- When you need a by-value trait objects.
4936- When you really need a fast allocation of small temporary arrays.
4937
4938Another 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
4939
4940```rust
4941#![feature(unsized_locals)]
4942
4943fn main() {
4944 let x: Box<[i32]> = Box::new([1, 2, 3, 4, 5]);
4945 let _x = {{{{{{{{{{*x}}}}}}}}}};
4946}
4947```
4948
4949and the code
4950
4951```rust
4952#![feature(unsized_locals)]
4953
4954fn main() {
4955 for _ in 0..10 {
4956 let x: Box<[i32]> = Box::new([1, 2, 3, 4, 5]);
4957 let _x = *x;
4958 }
4959}
4960```
4961
4962will unnecessarily extend the stack frame.
4963"##,
4964 },
4965 Lint {
4966 label: "unsized_tuple_coercion",
4967 description: r##"# `unsized_tuple_coercion`
4968
4969The tracking issue for this feature is: [#42877]
4970
4971[#42877]: https://github.com/rust-lang/rust/issues/42877
4972
4973------------------------
4974
4975This is a part of [RFC0401]. According to the RFC, there should be an implementation like this:
4976
4977```rust,ignore (partial-example)
4978impl<..., T, U: ?Sized> Unsized<(..., U)> for (..., T) where T: Unsized<U> {}
4979```
4980
4981This implementation is currently gated behind `#[feature(unsized_tuple_coercion)]` to avoid insta-stability. Therefore you can use it like this:
4982
4983```rust
4984#![feature(unsized_tuple_coercion)]
4985
4986fn main() {
4987 let x : ([i32; 3], [i32; 3]) = ([1, 2, 3], [4, 5, 6]);
4988 let y : &([i32; 3], [i32]) = &x;
4989 assert_eq!(y.1[0], 4);
4990}
4991```
4992
4993[RFC0401]: https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md
4994"##,
4995 },
4996 Lint {
4997 label: "update_panic_count",
4998 description: r##"# `update_panic_count`
4999
5000This feature is internal to the Rust compiler and is not intended for general use.
5001
5002------------------------
5003"##,
5004 },
5005 Lint {
5006 label: "windows_c",
5007 description: r##"# `windows_c`
5008
5009This feature is internal to the Rust compiler and is not intended for general use.
5010
5011------------------------
5012"##,
5013 },
5014 Lint {
5015 label: "windows_handle",
5016 description: r##"# `windows_handle`
5017
5018This feature is internal to the Rust compiler and is not intended for general use.
5019
5020------------------------
5021"##,
5022 },
5023 Lint {
5024 label: "windows_net",
5025 description: r##"# `windows_net`
5026
5027This feature is internal to the Rust compiler and is not intended for general use.
5028
5029------------------------
5030"##,
5031 },
5032 Lint {
5033 label: "windows_stdio",
5034 description: r##"# `windows_stdio`
5035
5036This feature is internal to the Rust compiler and is not intended for general use.
5037
5038------------------------
5039"##,
5040 },
5041];
5042
5043pub const CLIPPY_LINTS: &[Lint] = &[
5044 Lint {
5045 label: "clippy::absurd_extreme_comparisons",
5046 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."##,
5047 },
5048 Lint {
5049 label: "clippy::almost_swapped",
5050 description: r##"Checks for `foo = bar; bar = foo` sequences."##,
5051 },
5052 Lint {
5053 label: "clippy::approx_constant",
5054 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."##,
5055 },
5056 Lint {
5057 label: "clippy::as_conversions",
5058 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)."##,
5059 },
5060 Lint {
5061 label: "clippy::assertions_on_constants",
5062 description: r##"Checks for `assert!(true)` and `assert!(false)` calls."##,
5063 },
5064 Lint {
5065 label: "clippy::assign_op_pattern",
5066 description: r##"Checks for `a = a op b` or `a = b commutative_op a`\npatterns."##,
5067 },
5068 Lint {
5069 label: "clippy::assign_ops",
5070 description: r##"Nothing. This lint has been deprecated."##,
5071 },
5072 Lint {
5073 label: "clippy::async_yields_async",
5074 description: r##"Checks for async blocks that yield values of types\nthat can themselves be awaited."##,
5075 },
5076 Lint {
5077 label: "clippy::await_holding_lock",
5078 description: r##"Checks for calls to await while holding a\nnon-async-aware MutexGuard."##,
5079 },
5080 Lint {
5081 label: "clippy::await_holding_refcell_ref",
5082 description: r##"Checks for calls to await while holding a\n`RefCell` `Ref` or `RefMut`."##,
5083 },
5084 Lint {
5085 label: "clippy::bad_bit_mask",
5086 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` |"##,
5087 },
5088 Lint {
5089 label: "clippy::bind_instead_of_map",
5090 description: r##"Checks for usage of `_.and_then(|x| Some(y))`, `_.and_then(|x| Ok(y))` or\n`_.or_else(|x| Err(y))`."##,
5091 },
5092 Lint {
5093 label: "clippy::blacklisted_name",
5094 description: r##"Checks for usage of blacklisted names for variables, such\nas `foo`."##,
5095 },
5096 Lint {
5097 label: "clippy::blanket_clippy_restriction_lints",
5098 description: r##"Checks for `warn`/`deny`/`forbid` attributes targeting the whole clippy::restriction category."##,
5099 },
5100 Lint {
5101 label: "clippy::blocks_in_if_conditions",
5102 description: r##"Checks for `if` conditions that use blocks containing an\nexpression, statements or conditions that use closures with blocks."##,
5103 },
5104 Lint {
5105 label: "clippy::bool_assert_comparison",
5106 description: r##"This lint warns about boolean comparisons in assert-like macros."##,
5107 },
5108 Lint {
5109 label: "clippy::bool_comparison",
5110 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."##,
5111 },
5112 Lint {
5113 label: "clippy::borrow_interior_mutable_const",
5114 description: r##"Checks if `const` items which is interior mutable (e.g.,\ncontains a `Cell`, `Mutex`, `AtomicXxxx`, etc.) has been borrowed directly."##,
5115 },
5116 Lint {
5117 label: "clippy::borrowed_box",
5118 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."##,
5119 },
5120 Lint {
5121 label: "clippy::box_vec",
5122 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."##,
5123 },
5124 Lint {
5125 label: "clippy::boxed_local",
5126 description: r##"Checks for usage of `Box<T>` where an unboxed `T` would\nwork fine."##,
5127 },
5128 Lint {
5129 label: "clippy::branches_sharing_code",
5130 description: r##"Checks if the `if` and `else` block contain shared code that can be\nmoved out of the blocks."##,
5131 },
5132 Lint {
5133 label: "clippy::builtin_type_shadow",
5134 description: r##"Warns if a generic shadows a built-in type."##,
5135 },
5136 Lint {
5137 label: "clippy::bytes_nth",
5138 description: r##"Checks for the use of `.bytes().nth()`."##,
5139 },
5140 Lint {
5141 label: "clippy::cargo_common_metadata",
5142 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"##,
5143 },
5144 Lint {
5145 label: "clippy::case_sensitive_file_extension_comparisons",
5146 description: r##"Checks for calls to `ends_with` with possible file extensions\nand suggests to use a case-insensitive approach instead."##,
5147 },
5148 Lint {
5149 label: "clippy::cast_lossless",
5150 description: r##"Checks for casts between numerical types that may\nbe replaced by safe conversion functions."##,
5151 },
5152 Lint {
5153 label: "clippy::cast_possible_truncation",
5154 description: r##"Checks for casts between numerical types that may\ntruncate large values. This is expected behavior, so the cast is `Allow` by\ndefault."##,
5155 },
5156 Lint {
5157 label: "clippy::cast_possible_wrap",
5158 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."##,
5159 },
5160 Lint {
5161 label: "clippy::cast_precision_loss",
5162 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`."##,
5163 },
5164 Lint {
5165 label: "clippy::cast_ptr_alignment",
5166 description: r##"Checks for casts, using `as` or `pointer::cast`,\nfrom a less-strictly-aligned pointer to a more-strictly-aligned pointer"##,
5167 },
5168 Lint {
5169 label: "clippy::cast_ref_to_mut",
5170 description: r##"Checks for casts of `&T` to `&mut T` anywhere in the code."##,
5171 },
5172 Lint {
5173 label: "clippy::cast_sign_loss",
5174 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."##,
5175 },
5176 Lint {
5177 label: "clippy::char_lit_as_u8",
5178 description: r##"Checks for expressions where a character literal is cast\nto `u8` and suggests using a byte literal instead."##,
5179 },
5180 Lint {
5181 label: "clippy::chars_last_cmp",
5182 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."##,
5183 },
5184 Lint {
5185 label: "clippy::chars_next_cmp",
5186 description: r##"Checks for usage of `.chars().next()` on a `str` to check\nif it starts with a given char."##,
5187 },
5188 Lint {
5189 label: "clippy::checked_conversions",
5190 description: r##"Checks for explicit bounds checking when casting."##,
5191 },
5192 Lint {
5193 label: "clippy::clone_double_ref",
5194 description: r##"Checks for usage of `.clone()` on an `&&T`."##,
5195 },
5196 Lint {
5197 label: "clippy::clone_on_copy",
5198 description: r##"Checks for usage of `.clone()` on a `Copy` type."##,
5199 },
5200 Lint {
5201 label: "clippy::clone_on_ref_ptr",
5202 description: r##"Checks for usage of `.clone()` on a ref-counted pointer,\n(`Rc`, `Arc`, `rc::Weak`, or `sync::Weak`), and suggests calling Clone via unified\nfunction syntax instead (e.g., `Rc::clone(foo)`)."##,
5203 },
5204 Lint {
5205 label: "clippy::cloned_instead_of_copied",
5206 description: r##"Checks for usages of `cloned()` on an `Iterator` or `Option` where\n`copied()` could be used instead."##,
5207 },
5208 Lint { label: "clippy::cmp_nan", description: r##"Checks for comparisons to NaN."## },
5209 Lint {
5210 label: "clippy::cmp_null",
5211 description: r##"This lint checks for equality comparisons with `ptr::null`"##,
5212 },
5213 Lint {
5214 label: "clippy::cmp_owned",
5215 description: r##"Checks for conversions to owned values just for the sake\nof a comparison."##,
5216 },
5217 Lint {
5218 label: "clippy::cognitive_complexity",
5219 description: r##"Checks for methods with high cognitive complexity."##,
5220 },
5221 Lint {
5222 label: "clippy::collapsible_else_if",
5223 description: r##"Checks for collapsible `else { if ... }` expressions\nthat can be collapsed to `else if ...`."##,
5224 },
5225 Lint {
5226 label: "clippy::collapsible_if",
5227 description: r##"Checks for nested `if` statements which can be collapsed\nby `&&`-combining their conditions."##,
5228 },
5229 Lint {
5230 label: "clippy::collapsible_match",
5231 description: r##"Finds nested `match` or `if let` expressions where the patterns may be \"collapsed\" together\nwithout adding any branches.\n\nNote that this lint is not intended to find _all_ cases where nested match patterns can be merged, but only\ncases where merging would most likely make the code more readable."##,
5232 },
5233 Lint {
5234 label: "clippy::comparison_chain",
5235 description: r##"Checks comparison chains written with `if` that can be\nrewritten with `match` and `cmp`."##,
5236 },
5237 Lint {
5238 label: "clippy::comparison_to_empty",
5239 description: r##"Checks for comparing to an empty slice such as `\"\"` or `[]`,\nand suggests using `.is_empty()` where applicable."##,
5240 },
5241 Lint {
5242 label: "clippy::copy_iterator",
5243 description: r##"Checks for types that implement `Copy` as well as\n`Iterator`."##,
5244 },
5245 Lint {
5246 label: "clippy::create_dir",
5247 description: r##"Checks usage of `std::fs::create_dir` and suggest using `std::fs::create_dir_all` instead."##,
5248 },
5249 Lint {
5250 label: "clippy::crosspointer_transmute",
5251 description: r##"Checks for transmutes between a type `T` and `*T`."##,
5252 },
5253 Lint { label: "clippy::dbg_macro", description: r##"Checks for usage of dbg!() macro."## },
5254 Lint {
5255 label: "clippy::debug_assert_with_mut_call",
5256 description: r##"Checks for function/method calls with a mutable\nparameter in `debug_assert!`, `debug_assert_eq!` and `debug_assert_ne!` macros."##,
5257 },
5258 Lint {
5259 label: "clippy::decimal_literal_representation",
5260 description: r##"Warns if there is a better representation for a numeric literal."##,
5261 },
5262 Lint {
5263 label: "clippy::declare_interior_mutable_const",
5264 description: r##"Checks for declaration of `const` items which is interior\nmutable (e.g., contains a `Cell`, `Mutex`, `AtomicXxxx`, etc.)."##,
5265 },
5266 Lint {
5267 label: "clippy::default_numeric_fallback",
5268 description: r##"Checks for usage of unconstrained numeric literals which may cause default numeric fallback in type\ninference.\n\nDefault numeric fallback means that if numeric types have not yet been bound to concrete\ntypes at the end of type inference, then integer type is bound to `i32`, and similarly\nfloating type is bound to `f64`.\n\nSee [RFC0212](https://github.com/rust-lang/rfcs/blob/master/text/0212-restore-int-fallback.md) for more information about the fallback."##,
5269 },
5270 Lint {
5271 label: "clippy::default_trait_access",
5272 description: r##"Checks for literal calls to `Default::default()`."##,
5273 },
5274 Lint {
5275 label: "clippy::deprecated_cfg_attr",
5276 description: r##"Checks for `#[cfg_attr(rustfmt, rustfmt_skip)]` and suggests to replace it\nwith `#[rustfmt::skip]`."##,
5277 },
5278 Lint {
5279 label: "clippy::deprecated_semver",
5280 description: r##"Checks for `#[deprecated]` annotations with a `since`\nfield that is not a valid semantic version."##,
5281 },
5282 Lint {
5283 label: "clippy::deref_addrof",
5284 description: r##"Checks for usage of `*&` and `*&mut` in expressions."##,
5285 },
5286 Lint {
5287 label: "clippy::derive_hash_xor_eq",
5288 description: r##"Checks for deriving `Hash` but implementing `PartialEq`\nexplicitly or vice versa."##,
5289 },
5290 Lint {
5291 label: "clippy::derive_ord_xor_partial_ord",
5292 description: r##"Checks for deriving `Ord` but implementing `PartialOrd`\nexplicitly or vice versa."##,
5293 },
5294 Lint {
5295 label: "clippy::disallowed_method",
5296 description: r##"Denies the configured methods and functions in clippy.toml"##,
5297 },
5298 Lint {
5299 label: "clippy::diverging_sub_expression",
5300 description: r##"Checks for diverging calls that are not match arms or\nstatements."##,
5301 },
5302 Lint {
5303 label: "clippy::doc_markdown",
5304 description: r##"Checks for the presence of `_`, `::` or camel-case words\noutside ticks in documentation."##,
5305 },
5306 Lint {
5307 label: "clippy::double_comparisons",
5308 description: r##"Checks for double comparisons that could be simplified to a single expression."##,
5309 },
5310 Lint {
5311 label: "clippy::double_must_use",
5312 description: r##"Checks for a [`#[must_use]`] attribute without\nfurther information on functions and methods that return a type already\nmarked as `#[must_use]`.\n\n[`#[must_use]`]: https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-must_use-attribute"##,
5313 },
5314 Lint {
5315 label: "clippy::double_neg",
5316 description: r##"Detects expressions of the form `--x`."##,
5317 },
5318 Lint {
5319 label: "clippy::double_parens",
5320 description: r##"Checks for unnecessary double parentheses."##,
5321 },
5322 Lint {
5323 label: "clippy::drop_copy",
5324 description: r##"Checks for calls to `std::mem::drop` with a value\nthat derives the Copy trait"##,
5325 },
5326 Lint {
5327 label: "clippy::drop_ref",
5328 description: r##"Checks for calls to `std::mem::drop` with a reference\ninstead of an owned value."##,
5329 },
5330 Lint {
5331 label: "clippy::duplicate_underscore_argument",
5332 description: r##"Checks for function arguments having the similar names\ndiffering by an underscore."##,
5333 },
5334 Lint {
5335 label: "clippy::duration_subsec",
5336 description: r##"Checks for calculation of subsecond microseconds or milliseconds\nfrom other `Duration` methods."##,
5337 },
5338 Lint {
5339 label: "clippy::else_if_without_else",
5340 description: r##"Checks for usage of if expressions with an `else if` branch,\nbut without a final `else` branch."##,
5341 },
5342 Lint {
5343 label: "clippy::empty_enum",
5344 description: r##"Checks for `enum`s with no variants.\n\nAs of this writing, the `never_type` is still a\nnightly-only experimental API. Therefore, this lint is only triggered\nif the `never_type` is enabled."##,
5345 },
5346 Lint {
5347 label: "clippy::empty_line_after_outer_attr",
5348 description: r##"Checks for empty lines after outer attributes"##,
5349 },
5350 Lint { label: "clippy::empty_loop", description: r##"Checks for empty `loop` expressions."## },
5351 Lint {
5352 label: "clippy::enum_clike_unportable_variant",
5353 description: r##"Checks for C-like enumerations that are\n`repr(isize/usize)` and have values that don't fit into an `i32`."##,
5354 },
5355 Lint { label: "clippy::enum_glob_use", description: r##"Checks for `use Enum::*`."## },
5356 Lint {
5357 label: "clippy::enum_variant_names",
5358 description: r##"Detects enumeration variants that are prefixed or suffixed\nby the same characters."##,
5359 },
5360 Lint {
5361 label: "clippy::eq_op",
5362 description: r##"Checks for equal operands to comparison, logical and\nbitwise, difference and division binary operators (`==`, `>`, etc., `&&`,\n`||`, `&`, `|`, `^`, `-` and `/`)."##,
5363 },
5364 Lint {
5365 label: "clippy::erasing_op",
5366 description: r##"Checks for erasing operations, e.g., `x * 0`."##,
5367 },
5368 Lint {
5369 label: "clippy::eval_order_dependence",
5370 description: r##"Checks for a read and a write to the same variable where\nwhether the read occurs before or after the write depends on the evaluation\norder of sub-expressions."##,
5371 },
5372 Lint {
5373 label: "clippy::excessive_precision",
5374 description: r##"Checks for float literals with a precision greater\nthan that supported by the underlying type."##,
5375 },
5376 Lint {
5377 label: "clippy::exhaustive_enums",
5378 description: r##"Warns on any exported `enum`s that are not tagged `#[non_exhaustive]`"##,
5379 },
5380 Lint {
5381 label: "clippy::exhaustive_structs",
5382 description: r##"Warns on any exported `structs`s that are not tagged `#[non_exhaustive]`"##,
5383 },
5384 Lint {
5385 label: "clippy::exit",
5386 description: r##"`exit()` terminates the program and doesn't provide a\nstack trace."##,
5387 },
5388 Lint {
5389 label: "clippy::expect_fun_call",
5390 description: r##"Checks for calls to `.expect(&format!(...))`, `.expect(foo(..))`,\netc., and suggests to use `unwrap_or_else` instead"##,
5391 },
5392 Lint {
5393 label: "clippy::expect_used",
5394 description: r##"Checks for `.expect()` calls on `Option`s and `Result`s."##,
5395 },
5396 Lint {
5397 label: "clippy::expl_impl_clone_on_copy",
5398 description: r##"Checks for explicit `Clone` implementations for `Copy`\ntypes."##,
5399 },
5400 Lint {
5401 label: "clippy::explicit_counter_loop",
5402 description: r##"Checks `for` loops over slices with an explicit counter\nand suggests the use of `.enumerate()`."##,
5403 },
5404 Lint {
5405 label: "clippy::explicit_deref_methods",
5406 description: r##"Checks for explicit `deref()` or `deref_mut()` method calls."##,
5407 },
5408 Lint {
5409 label: "clippy::explicit_into_iter_loop",
5410 description: r##"Checks for loops on `y.into_iter()` where `y` will do, and\nsuggests the latter."##,
5411 },
5412 Lint {
5413 label: "clippy::explicit_iter_loop",
5414 description: r##"Checks for loops on `x.iter()` where `&x` will do, and\nsuggests the latter."##,
5415 },
5416 Lint {
5417 label: "clippy::explicit_write",
5418 description: r##"Checks for usage of `write!()` / `writeln()!` which can be\nreplaced with `(e)print!()` / `(e)println!()`"##,
5419 },
5420 Lint {
5421 label: "clippy::extend_from_slice",
5422 description: r##"Nothing. This lint has been deprecated."##,
5423 },
5424 Lint {
5425 label: "clippy::extra_unused_lifetimes",
5426 description: r##"Checks for lifetimes in generics that are never used\nanywhere else."##,
5427 },
5428 Lint {
5429 label: "clippy::fallible_impl_from",
5430 description: r##"Checks for impls of `From<..>` that contain `panic!()` or `unwrap()`"##,
5431 },
5432 Lint {
5433 label: "clippy::field_reassign_with_default",
5434 description: r##"Checks for immediate reassignment of fields initialized\nwith Default::default()."##,
5435 },
5436 Lint {
5437 label: "clippy::filetype_is_file",
5438 description: r##"Checks for `FileType::is_file()`."##,
5439 },
5440 Lint {
5441 label: "clippy::filter_map",
5442 description: r##"Nothing. This lint has been deprecated."##,
5443 },
5444 Lint {
5445 label: "clippy::filter_map_identity",
5446 description: r##"Checks for usage of `filter_map(|x| x)`."##,
5447 },
5448 Lint {
5449 label: "clippy::filter_map_next",
5450 description: r##"Checks for usage of `_.filter_map(_).next()`."##,
5451 },
5452 Lint {
5453 label: "clippy::filter_next",
5454 description: r##"Checks for usage of `_.filter(_).next()`."##,
5455 },
5456 Lint { label: "clippy::find_map", description: r##"Nothing. This lint has been deprecated."## },
5457 Lint {
5458 label: "clippy::flat_map_identity",
5459 description: r##"Checks for usage of `flat_map(|x| x)`."##,
5460 },
5461 Lint {
5462 label: "clippy::flat_map_option",
5463 description: r##"Checks for usages of `Iterator::flat_map()` where `filter_map()` could be\nused instead."##,
5464 },
5465 Lint { label: "clippy::float_arithmetic", description: r##"Checks for float arithmetic."## },
5466 Lint {
5467 label: "clippy::float_cmp",
5468 description: r##"Checks for (in-)equality comparisons on floating-point\nvalues (apart from zero), except in functions called `*eq*` (which probably\nimplement equality for a type involving floats)."##,
5469 },
5470 Lint {
5471 label: "clippy::float_cmp_const",
5472 description: r##"Checks for (in-)equality comparisons on floating-point\nvalue and constant, except in functions called `*eq*` (which probably\nimplement equality for a type involving floats)."##,
5473 },
5474 Lint {
5475 label: "clippy::float_equality_without_abs",
5476 description: r##"Checks for statements of the form `(a - b) < f32::EPSILON` or\n`(a - b) < f64::EPSILON`. Notes the missing `.abs()`."##,
5477 },
5478 Lint {
5479 label: "clippy::fn_address_comparisons",
5480 description: r##"Checks for comparisons with an address of a function item."##,
5481 },
5482 Lint {
5483 label: "clippy::fn_params_excessive_bools",
5484 description: r##"Checks for excessive use of\nbools in function definitions."##,
5485 },
5486 Lint {
5487 label: "clippy::fn_to_numeric_cast",
5488 description: r##"Checks for casts of function pointers to something other than usize"##,
5489 },
5490 Lint {
5491 label: "clippy::fn_to_numeric_cast_with_truncation",
5492 description: r##"Checks for casts of a function pointer to a numeric type not wide enough to\nstore address."##,
5493 },
5494 Lint {
5495 label: "clippy::for_kv_map",
5496 description: r##"Checks for iterating a map (`HashMap` or `BTreeMap`) and\nignoring either the keys or values."##,
5497 },
5498 Lint {
5499 label: "clippy::for_loops_over_fallibles",
5500 description: r##"Checks for `for` loops over `Option` or `Result` values."##,
5501 },
5502 Lint {
5503 label: "clippy::forget_copy",
5504 description: r##"Checks for calls to `std::mem::forget` with a value that\nderives the Copy trait"##,
5505 },
5506 Lint {
5507 label: "clippy::forget_ref",
5508 description: r##"Checks for calls to `std::mem::forget` with a reference\ninstead of an owned value."##,
5509 },
5510 Lint {
5511 label: "clippy::from_iter_instead_of_collect",
5512 description: r##"Checks for `from_iter()` function calls on types that implement the `FromIterator`\ntrait."##,
5513 },
5514 Lint {
5515 label: "clippy::from_over_into",
5516 description: r##"Searches for implementations of the `Into<..>` trait and suggests to implement `From<..>` instead."##,
5517 },
5518 Lint {
5519 label: "clippy::from_str_radix_10",
5520 description: r##"Checks for function invocations of the form `primitive::from_str_radix(s, 10)`"##,
5521 },
5522 Lint {
5523 label: "clippy::future_not_send",
5524 description: r##"This lint requires Future implementations returned from\nfunctions and methods to implement the `Send` marker trait. It is mostly\nused by library authors (public and internal) that target an audience where\nmultithreaded executors are likely to be used for running these Futures."##,
5525 },
5526 Lint {
5527 label: "clippy::get_last_with_len",
5528 description: r##"Checks for using `x.get(x.len() - 1)` instead of\n`x.last()`."##,
5529 },
5530 Lint {
5531 label: "clippy::get_unwrap",
5532 description: r##"Checks for use of `.get().unwrap()` (or\n`.get_mut().unwrap`) on a standard library type which implements `Index`"##,
5533 },
5534 Lint {
5535 label: "clippy::identity_op",
5536 description: r##"Checks for identity operations, e.g., `x + 0`."##,
5537 },
5538 Lint {
5539 label: "clippy::if_let_mutex",
5540 description: r##"Checks for `Mutex::lock` calls in `if let` expression\nwith lock calls in any of the else blocks."##,
5541 },
5542 Lint {
5543 label: "clippy::if_let_redundant_pattern_matching",
5544 description: r##"Nothing. This lint has been deprecated."##,
5545 },
5546 Lint {
5547 label: "clippy::if_let_some_result",
5548 description: r##"* Checks for unnecessary `ok()` in if let."##,
5549 },
5550 Lint {
5551 label: "clippy::if_not_else",
5552 description: r##"Checks for usage of `!` or `!=` in an if condition with an\nelse branch."##,
5553 },
5554 Lint {
5555 label: "clippy::if_same_then_else",
5556 description: r##"Checks for `if/else` with the same body as the *then* part\nand the *else* part."##,
5557 },
5558 Lint {
5559 label: "clippy::if_then_some_else_none",
5560 description: r##"Checks for if-else that could be written to `bool::then`."##,
5561 },
5562 Lint {
5563 label: "clippy::ifs_same_cond",
5564 description: r##"Checks for consecutive `if`s with the same condition."##,
5565 },
5566 Lint {
5567 label: "clippy::implicit_clone",
5568 description: r##"Checks for the usage of `_.to_owned()`, `vec.to_vec()`, or similar when calling `_.clone()` would be clearer."##,
5569 },
5570 Lint {
5571 label: "clippy::implicit_hasher",
5572 description: r##"Checks for public `impl` or `fn` missing generalization\nover different hashers and implicitly defaulting to the default hashing\nalgorithm (`SipHash`)."##,
5573 },
5574 Lint {
5575 label: "clippy::implicit_return",
5576 description: r##"Checks for missing return statements at the end of a block."##,
5577 },
5578 Lint {
5579 label: "clippy::implicit_saturating_sub",
5580 description: r##"Checks for implicit saturating subtraction."##,
5581 },
5582 Lint {
5583 label: "clippy::imprecise_flops",
5584 description: r##"Looks for floating-point expressions that\ncan be expressed using built-in methods to improve accuracy\nat the cost of performance."##,
5585 },
5586 Lint {
5587 label: "clippy::inconsistent_digit_grouping",
5588 description: r##"Warns if an integral or floating-point constant is\ngrouped inconsistently with underscores."##,
5589 },
5590 Lint {
5591 label: "clippy::inconsistent_struct_constructor",
5592 description: r##"Checks for struct constructors where all fields are shorthand and\nthe order of the field init shorthand in the constructor is inconsistent\nwith the order in the struct definition."##,
5593 },
5594 Lint {
5595 label: "clippy::indexing_slicing",
5596 description: r##"Checks for usage of indexing or slicing. Arrays are special cases, this lint\ndoes report on arrays if we can tell that slicing operations are in bounds and does not\nlint on constant `usize` indexing on arrays because that is handled by rustc's `const_err` lint."##,
5597 },
5598 Lint {
5599 label: "clippy::ineffective_bit_mask",
5600 description: r##"Checks for bit masks in comparisons which can be removed\nwithout changing the outcome. The basic structure can be seen in the\nfollowing table:\n\n|Comparison| Bit Op |Example |equals |\n|----------|---------|-----------|-------|\n|`>` / `<=`|`|` / `^`|`x | 2 > 3`|`x > 3`|\n|`<` / `>=`|`|` / `^`|`x ^ 1 < 4`|`x < 4`|"##,
5601 },
5602 Lint {
5603 label: "clippy::inefficient_to_string",
5604 description: r##"Checks for usage of `.to_string()` on an `&&T` where\n`T` implements `ToString` directly (like `&&str` or `&&String`)."##,
5605 },
5606 Lint {
5607 label: "clippy::infallible_destructuring_match",
5608 description: r##"Checks for matches being used to destructure a single-variant enum\nor tuple struct where a `let` will suffice."##,
5609 },
5610 Lint {
5611 label: "clippy::infinite_iter",
5612 description: r##"Checks for iteration that is guaranteed to be infinite."##,
5613 },
5614 Lint {
5615 label: "clippy::inherent_to_string",
5616 description: r##"Checks for the definition of inherent methods with a signature of `to_string(&self) -> String`."##,
5617 },
5618 Lint {
5619 label: "clippy::inherent_to_string_shadow_display",
5620 description: r##"Checks for the definition of inherent methods with a signature of `to_string(&self) -> String` and if the type implementing this method also implements the `Display` trait."##,
5621 },
5622 Lint {
5623 label: "clippy::inline_always",
5624 description: r##"Checks for items annotated with `#[inline(always)]`,\nunless the annotated function is empty or simply panics."##,
5625 },
5626 Lint {
5627 label: "clippy::inline_asm_x86_att_syntax",
5628 description: r##"Checks for usage of AT&T x86 assembly syntax."##,
5629 },
5630 Lint {
5631 label: "clippy::inline_asm_x86_intel_syntax",
5632 description: r##"Checks for usage of Intel x86 assembly syntax."##,
5633 },
5634 Lint {
5635 label: "clippy::inline_fn_without_body",
5636 description: r##"Checks for `#[inline]` on trait methods without bodies"##,
5637 },
5638 Lint {
5639 label: "clippy::inspect_for_each",
5640 description: r##"Checks for usage of `inspect().for_each()`."##,
5641 },
5642 Lint {
5643 label: "clippy::int_plus_one",
5644 description: r##"Checks for usage of `x >= y + 1` or `x - 1 >= y` (and `<=`) in a block"##,
5645 },
5646 Lint {
5647 label: "clippy::integer_arithmetic",
5648 description: r##"Checks for integer arithmetic operations which could overflow or panic.\n\nSpecifically, checks for any operators (`+`, `-`, `*`, `<<`, etc) which are capable\nof overflowing according to the [Rust\nReference](https://doc.rust-lang.org/reference/expressions/operator-expr.html#overflow),\nor which can panic (`/`, `%`). No bounds analysis or sophisticated reasoning is\nattempted."##,
5649 },
5650 Lint { label: "clippy::integer_division", description: r##"Checks for division of integers"## },
5651 Lint {
5652 label: "clippy::into_iter_on_ref",
5653 description: r##"Checks for `into_iter` calls on references which should be replaced by `iter`\nor `iter_mut`."##,
5654 },
5655 Lint {
5656 label: "clippy::invalid_atomic_ordering",
5657 description: r##"Checks for usage of invalid atomic\nordering in atomic loads/stores/exchanges/updates and\nmemory fences."##,
5658 },
5659 Lint {
5660 label: "clippy::invalid_null_ptr_usage",
5661 description: r##"This lint checks for invalid usages of `ptr::null`."##,
5662 },
5663 Lint {
5664 label: "clippy::invalid_regex",
5665 description: r##"Checks [regex](https://crates.io/crates/regex) creation\n(with `Regex::new`, `RegexBuilder::new`, or `RegexSet::new`) for correct\nregex syntax."##,
5666 },
5667 Lint {
5668 label: "clippy::invalid_upcast_comparisons",
5669 description: r##"Checks for comparisons where the relation is always either\ntrue or false, but where one side has been upcast so that the comparison is\nnecessary. Only integer types are checked."##,
5670 },
5671 Lint {
5672 label: "clippy::invisible_characters",
5673 description: r##"Checks for invisible Unicode characters in the code."##,
5674 },
5675 Lint {
5676 label: "clippy::items_after_statements",
5677 description: r##"Checks for items declared after some statement in a block."##,
5678 },
5679 Lint {
5680 label: "clippy::iter_cloned_collect",
5681 description: r##"Checks for the use of `.cloned().collect()` on slice to\ncreate a `Vec`."##,
5682 },
5683 Lint {
5684 label: "clippy::iter_count",
5685 description: r##"Checks for the use of `.iter().count()`."##,
5686 },
5687 Lint { label: "clippy::iter_next_loop", description: r##"Checks for loops on `x.next()`."## },
5688 Lint {
5689 label: "clippy::iter_next_slice",
5690 description: r##"Checks for usage of `iter().next()` on a Slice or an Array"##,
5691 },
5692 Lint {
5693 label: "clippy::iter_nth",
5694 description: r##"Checks for use of `.iter().nth()` (and the related\n`.iter_mut().nth()`) on standard library types with O(1) element access."##,
5695 },
5696 Lint {
5697 label: "clippy::iter_nth_zero",
5698 description: r##"Checks for the use of `iter.nth(0)`."##,
5699 },
5700 Lint {
5701 label: "clippy::iter_skip_next",
5702 description: r##"Checks for use of `.skip(x).next()` on iterators."##,
5703 },
5704 Lint {
5705 label: "clippy::iterator_step_by_zero",
5706 description: r##"Checks for calling `.step_by(0)` on iterators which panics."##,
5707 },
5708 Lint {
5709 label: "clippy::just_underscores_and_digits",
5710 description: r##"Checks if you have variables whose name consists of just\nunderscores and digits."##,
5711 },
5712 Lint {
5713 label: "clippy::large_const_arrays",
5714 description: r##"Checks for large `const` arrays that should\nbe defined as `static` instead."##,
5715 },
5716 Lint {
5717 label: "clippy::large_digit_groups",
5718 description: r##"Warns if the digits of an integral or floating-point\nconstant are grouped into groups that\nare too large."##,
5719 },
5720 Lint {
5721 label: "clippy::large_enum_variant",
5722 description: r##"Checks for large size differences between variants on\n`enum`s."##,
5723 },
5724 Lint {
5725 label: "clippy::large_stack_arrays",
5726 description: r##"Checks for local arrays that may be too large."##,
5727 },
5728 Lint {
5729 label: "clippy::large_types_passed_by_value",
5730 description: r##"Checks for functions taking arguments by value, where\nthe argument type is `Copy` and large enough to be worth considering\npassing by reference. Does not trigger if the function is being exported,\nbecause that might induce API breakage, if the parameter is declared as mutable,\nor if the argument is a `self`."##,
5731 },
5732 Lint {
5733 label: "clippy::len_without_is_empty",
5734 description: r##"Checks for items that implement `.len()` but not\n`.is_empty()`."##,
5735 },
5736 Lint {
5737 label: "clippy::len_zero",
5738 description: r##"Checks for getting the length of something via `.len()`\njust to compare to zero, and suggests using `.is_empty()` where applicable."##,
5739 },
5740 Lint {
5741 label: "clippy::let_and_return",
5742 description: r##"Checks for `let`-bindings, which are subsequently\nreturned."##,
5743 },
5744 Lint {
5745 label: "clippy::let_underscore_drop",
5746 description: r##"Checks for `let _ = <expr>`\nwhere expr has a type that implements `Drop`"##,
5747 },
5748 Lint {
5749 label: "clippy::let_underscore_lock",
5750 description: r##"Checks for `let _ = sync_lock`"##,
5751 },
5752 Lint {
5753 label: "clippy::let_underscore_must_use",
5754 description: r##"Checks for `let _ = <expr>`\nwhere expr is #[must_use]"##,
5755 },
5756 Lint { label: "clippy::let_unit_value", description: r##"Checks for binding a unit value."## },
5757 Lint {
5758 label: "clippy::linkedlist",
5759 description: r##"Checks for usage of any `LinkedList`, suggesting to use a\n`Vec` or a `VecDeque` (formerly called `RingBuf`)."##,
5760 },
5761 Lint {
5762 label: "clippy::logic_bug",
5763 description: r##"Checks for boolean expressions that contain terminals that\ncan be eliminated."##,
5764 },
5765 Lint {
5766 label: "clippy::lossy_float_literal",
5767 description: r##"Checks for whole number float literals that\ncannot be represented as the underlying type without loss."##,
5768 },
5769 Lint {
5770 label: "clippy::macro_use_imports",
5771 description: r##"Checks for `#[macro_use] use...`."##,
5772 },
5773 Lint {
5774 label: "clippy::main_recursion",
5775 description: r##"Checks for recursion using the entrypoint."##,
5776 },
5777 Lint {
5778 label: "clippy::manual_async_fn",
5779 description: r##"It checks for manual implementations of `async` functions."##,
5780 },
5781 Lint {
5782 label: "clippy::manual_filter_map",
5783 description: r##"Checks for usage of `_.filter(_).map(_)` that can be written more simply\nas `filter_map(_)`."##,
5784 },
5785 Lint {
5786 label: "clippy::manual_find_map",
5787 description: r##"Checks for usage of `_.find(_).map(_)` that can be written more simply\nas `find_map(_)`."##,
5788 },
5789 Lint {
5790 label: "clippy::manual_flatten",
5791 description: r##"Check for unnecessary `if let` usage in a for loop\nwhere only the `Some` or `Ok` variant of the iterator element is used."##,
5792 },
5793 Lint {
5794 label: "clippy::manual_map",
5795 description: r##"Checks for usages of `match` which could be implemented using `map`"##,
5796 },
5797 Lint {
5798 label: "clippy::manual_memcpy",
5799 description: r##"Checks for for-loops that manually copy items between\nslices that could be optimized by having a memcpy."##,
5800 },
5801 Lint {
5802 label: "clippy::manual_non_exhaustive",
5803 description: r##"Checks for manual implementations of the non-exhaustive pattern."##,
5804 },
5805 Lint {
5806 label: "clippy::manual_ok_or",
5807 description: r##"Finds patterns that reimplement `Option::ok_or`."##,
5808 },
5809 Lint {
5810 label: "clippy::manual_range_contains",
5811 description: r##"Checks for expressions like `x >= 3 && x < 8` that could\nbe more readably expressed as `(3..8).contains(x)`."##,
5812 },
5813 Lint {
5814 label: "clippy::manual_saturating_arithmetic",
5815 description: r##"Checks for `.checked_add/sub(x).unwrap_or(MAX/MIN)`."##,
5816 },
5817 Lint {
5818 label: "clippy::manual_str_repeat",
5819 description: r##"Checks for manual implementations of `str::repeat`"##,
5820 },
5821 Lint {
5822 label: "clippy::manual_strip",
5823 description: r##"Suggests using `strip_{prefix,suffix}` over `str::{starts,ends}_with` and slicing using\nthe pattern's length."##,
5824 },
5825 Lint { label: "clippy::manual_swap", description: r##"Checks for manual swapping."## },
5826 Lint {
5827 label: "clippy::manual_unwrap_or",
5828 description: r##"Finds patterns that reimplement `Option::unwrap_or` or `Result::unwrap_or`."##,
5829 },
5830 Lint {
5831 label: "clippy::many_single_char_names",
5832 description: r##"Checks for too many variables whose name consists of a\nsingle character."##,
5833 },
5834 Lint {
5835 label: "clippy::map_clone",
5836 description: r##"Checks for usage of `map(|x| x.clone())` or\ndereferencing closures for `Copy` types, on `Iterator` or `Option`,\nand suggests `cloned()` or `copied()` instead"##,
5837 },
5838 Lint {
5839 label: "clippy::map_collect_result_unit",
5840 description: r##"Checks for usage of `_.map(_).collect::<Result<(), _>()`."##,
5841 },
5842 Lint {
5843 label: "clippy::map_entry",
5844 description: r##"Checks for uses of `contains_key` + `insert` on `HashMap`\nor `BTreeMap`."##,
5845 },
5846 Lint {
5847 label: "clippy::map_err_ignore",
5848 description: r##"Checks for instances of `map_err(|_| Some::Enum)`"##,
5849 },
5850 Lint {
5851 label: "clippy::map_flatten",
5852 description: r##"Checks for usage of `_.map(_).flatten(_)` on `Iterator` and `Option`"##,
5853 },
5854 Lint {
5855 label: "clippy::map_identity",
5856 description: r##"Checks for instances of `map(f)` where `f` is the identity function."##,
5857 },
5858 Lint {
5859 label: "clippy::map_unwrap_or",
5860 description: r##"Checks for usage of `option.map(_).unwrap_or(_)` or `option.map(_).unwrap_or_else(_)` or\n`result.map(_).unwrap_or_else(_)`."##,
5861 },
5862 Lint {
5863 label: "clippy::match_as_ref",
5864 description: r##"Checks for match which is used to add a reference to an\n`Option` value."##,
5865 },
5866 Lint {
5867 label: "clippy::match_bool",
5868 description: r##"Checks for matches where match expression is a `bool`. It\nsuggests to replace the expression with an `if...else` block."##,
5869 },
5870 Lint {
5871 label: "clippy::match_like_matches_macro",
5872 description: r##"Checks for `match` or `if let` expressions producing a\n`bool` that could be written using `matches!`"##,
5873 },
5874 Lint {
5875 label: "clippy::match_on_vec_items",
5876 description: r##"Checks for `match vec[idx]` or `match vec[n..m]`."##,
5877 },
5878 Lint {
5879 label: "clippy::match_overlapping_arm",
5880 description: r##"Checks for overlapping match arms."##,
5881 },
5882 Lint {
5883 label: "clippy::match_ref_pats",
5884 description: r##"Checks for matches where all arms match a reference,\nsuggesting to remove the reference and deref the matched expression\ninstead. It also checks for `if let &foo = bar` blocks."##,
5885 },
5886 Lint {
5887 label: "clippy::match_same_arms",
5888 description: r##"Checks for `match` with identical arm bodies."##,
5889 },
5890 Lint {
5891 label: "clippy::match_single_binding",
5892 description: r##"Checks for useless match that binds to only one value."##,
5893 },
5894 Lint {
5895 label: "clippy::match_wild_err_arm",
5896 description: r##"Checks for arm which matches all errors with `Err(_)`\nand take drastic actions like `panic!`."##,
5897 },
5898 Lint {
5899 label: "clippy::match_wildcard_for_single_variants",
5900 description: r##"Checks for wildcard enum matches for a single variant."##,
5901 },
5902 Lint {
5903 label: "clippy::maybe_infinite_iter",
5904 description: r##"Checks for iteration that may be infinite."##,
5905 },
5906 Lint {
5907 label: "clippy::mem_discriminant_non_enum",
5908 description: r##"Checks for calls of `mem::discriminant()` on a non-enum type."##,
5909 },
5910 Lint {
5911 label: "clippy::mem_forget",
5912 description: r##"Checks for usage of `std::mem::forget(t)` where `t` is\n`Drop`."##,
5913 },
5914 Lint {
5915 label: "clippy::mem_replace_option_with_none",
5916 description: r##"Checks for `mem::replace()` on an `Option` with\n`None`."##,
5917 },
5918 Lint {
5919 label: "clippy::mem_replace_with_default",
5920 description: r##"Checks for `std::mem::replace` on a value of type\n`T` with `T::default()`."##,
5921 },
5922 Lint {
5923 label: "clippy::mem_replace_with_uninit",
5924 description: r##"Checks for `mem::replace(&mut _, mem::uninitialized())`\nand `mem::replace(&mut _, mem::zeroed())`."##,
5925 },
5926 Lint {
5927 label: "clippy::min_max",
5928 description: r##"Checks for expressions where `std::cmp::min` and `max` are\nused to clamp values, but switched so that the result is constant."##,
5929 },
5930 Lint {
5931 label: "clippy::misaligned_transmute",
5932 description: r##"Nothing. This lint has been deprecated."##,
5933 },
5934 Lint {
5935 label: "clippy::mismatched_target_os",
5936 description: r##"Checks for cfg attributes having operating systems used in target family position."##,
5937 },
5938 Lint {
5939 label: "clippy::misrefactored_assign_op",
5940 description: r##"Checks for `a op= a op b` or `a op= b op a` patterns."##,
5941 },
5942 Lint {
5943 label: "clippy::missing_const_for_fn",
5944 description: r##"Suggests the use of `const` in functions and methods where possible."##,
5945 },
5946 Lint {
5947 label: "clippy::missing_docs_in_private_items",
5948 description: r##"Warns if there is missing doc for any documentable item\n(public or private)."##,
5949 },
5950 Lint {
5951 label: "clippy::missing_errors_doc",
5952 description: r##"Checks the doc comments of publicly visible functions that\nreturn a `Result` type and warns if there is no `# Errors` section."##,
5953 },
5954 Lint {
5955 label: "clippy::missing_inline_in_public_items",
5956 description: r##"it lints if an exported function, method, trait method with default impl,\nor trait method impl is not `#[inline]`."##,
5957 },
5958 Lint {
5959 label: "clippy::missing_panics_doc",
5960 description: r##"Checks the doc comments of publicly visible functions that\nmay panic and warns if there is no `# Panics` section."##,
5961 },
5962 Lint {
5963 label: "clippy::missing_safety_doc",
5964 description: r##"Checks for the doc comments of publicly visible\nunsafe functions and warns if there is no `# Safety` section."##,
5965 },
5966 Lint {
5967 label: "clippy::mistyped_literal_suffixes",
5968 description: r##"Warns for mistyped suffix in literals"##,
5969 },
5970 Lint {
5971 label: "clippy::mixed_case_hex_literals",
5972 description: r##"Warns on hexadecimal literals with mixed-case letter\ndigits."##,
5973 },
5974 Lint {
5975 label: "clippy::module_inception",
5976 description: r##"Checks for modules that have the same name as their\nparent module"##,
5977 },
5978 Lint {
5979 label: "clippy::module_name_repetitions",
5980 description: r##"Detects type names that are prefixed or suffixed by the\ncontaining module's name."##,
5981 },
5982 Lint { label: "clippy::modulo_arithmetic", description: r##"Checks for modulo arithmetic."## },
5983 Lint {
5984 label: "clippy::modulo_one",
5985 description: r##"Checks for getting the remainder of a division by one or minus\none."##,
5986 },
5987 Lint {
5988 label: "clippy::multiple_crate_versions",
5989 description: r##"Checks to see if multiple versions of a crate are being\nused."##,
5990 },
5991 Lint {
5992 label: "clippy::multiple_inherent_impl",
5993 description: r##"Checks for multiple inherent implementations of a struct"##,
5994 },
5995 Lint {
5996 label: "clippy::must_use_candidate",
5997 description: r##"Checks for public functions that have no\n[`#[must_use]`] attribute, but return something not already marked\nmust-use, have no mutable arg and mutate no statics.\n\n[`#[must_use]`]: https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-must_use-attribute"##,
5998 },
5999 Lint {
6000 label: "clippy::must_use_unit",
6001 description: r##"Checks for a [`#[must_use]`] attribute on\nunit-returning functions and methods.\n\n[`#[must_use]`]: https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-must_use-attribute"##,
6002 },
6003 Lint {
6004 label: "clippy::mut_from_ref",
6005 description: r##"This lint checks for functions that take immutable\nreferences and return mutable ones."##,
6006 },
6007 Lint {
6008 label: "clippy::mut_mut",
6009 description: r##"Checks for instances of `mut mut` references."##,
6010 },
6011 Lint {
6012 label: "clippy::mut_mutex_lock",
6013 description: r##"Checks for `&mut Mutex::lock` calls"##,
6014 },
6015 Lint {
6016 label: "clippy::mut_range_bound",
6017 description: r##"Checks for loops which have a range bound that is a mutable variable"##,
6018 },
6019 Lint {
6020 label: "clippy::mutable_key_type",
6021 description: r##"Checks for sets/maps with mutable key types."##,
6022 },
6023 Lint {
6024 label: "clippy::mutex_atomic",
6025 description: r##"Checks for usages of `Mutex<X>` where an atomic will do."##,
6026 },
6027 Lint {
6028 label: "clippy::mutex_integer",
6029 description: r##"Checks for usages of `Mutex<X>` where `X` is an integral\ntype."##,
6030 },
6031 Lint { label: "clippy::naive_bytecount", description: r##"Checks for naive byte counts"## },
6032 Lint {
6033 label: "clippy::needless_arbitrary_self_type",
6034 description: r##"The lint checks for `self` in fn parameters that\nspecify the `Self`-type explicitly"##,
6035 },
6036 Lint {
6037 label: "clippy::needless_bitwise_bool",
6038 description: r##"Checks for uses of bitwise and/or operators between booleans, where performance may be improved by using\na lazy and."##,
6039 },
6040 Lint {
6041 label: "clippy::needless_bool",
6042 description: r##"Checks for expressions of the form `if c { true } else {\nfalse }` (or vice versa) and suggests using the condition directly."##,
6043 },
6044 Lint {
6045 label: "clippy::needless_borrow",
6046 description: r##"Checks for address of operations (`&`) that are going to\nbe dereferenced immediately by the compiler."##,
6047 },
6048 Lint {
6049 label: "clippy::needless_borrowed_reference",
6050 description: r##"Checks for bindings that destructure a reference and borrow the inner\nvalue with `&ref`."##,
6051 },
6052 Lint {
6053 label: "clippy::needless_collect",
6054 description: r##"Checks for functions collecting an iterator when collect\nis not needed."##,
6055 },
6056 Lint {
6057 label: "clippy::needless_continue",
6058 description: r##"The lint checks for `if`-statements appearing in loops\nthat contain a `continue` statement in either their main blocks or their\n`else`-blocks, when omitting the `else`-block possibly with some\nrearrangement of code can make the code easier to understand."##,
6059 },
6060 Lint {
6061 label: "clippy::needless_doctest_main",
6062 description: r##"Checks for `fn main() { .. }` in doctests"##,
6063 },
6064 Lint {
6065 label: "clippy::needless_for_each",
6066 description: r##"Checks for usage of `for_each` that would be more simply written as a\n`for` loop."##,
6067 },
6068 Lint {
6069 label: "clippy::needless_lifetimes",
6070 description: r##"Checks for lifetime annotations which can be removed by\nrelying on lifetime elision."##,
6071 },
6072 Lint {
6073 label: "clippy::needless_pass_by_value",
6074 description: r##"Checks for functions taking arguments by value, but not\nconsuming them in its\nbody."##,
6075 },
6076 Lint {
6077 label: "clippy::needless_question_mark",
6078 description: r##"Suggests alternatives for useless applications of `?` in terminating expressions"##,
6079 },
6080 Lint {
6081 label: "clippy::needless_range_loop",
6082 description: r##"Checks for looping over the range of `0..len` of some\ncollection just to get the values by index."##,
6083 },
6084 Lint {
6085 label: "clippy::needless_return",
6086 description: r##"Checks for return statements at the end of a block."##,
6087 },
6088 Lint {
6089 label: "clippy::needless_update",
6090 description: r##"Checks for needlessly including a base struct on update\nwhen all fields are changed anyway.\n\nThis lint is not applied to structs marked with\n[non_exhaustive](https://doc.rust-lang.org/reference/attributes/type_system.html)."##,
6091 },
6092 Lint {
6093 label: "clippy::neg_cmp_op_on_partial_ord",
6094 description: r##"Checks for the usage of negated comparison operators on types which only implement\n`PartialOrd` (e.g., `f64`)."##,
6095 },
6096 Lint {
6097 label: "clippy::neg_multiply",
6098 description: r##"Checks for multiplication by -1 as a form of negation."##,
6099 },
6100 Lint {
6101 label: "clippy::never_loop",
6102 description: r##"Checks for loops that will always `break`, `return` or\n`continue` an outer loop."##,
6103 },
6104 Lint {
6105 label: "clippy::new_ret_no_self",
6106 description: r##"Checks for `new` not returning a type that contains `Self`."##,
6107 },
6108 Lint {
6109 label: "clippy::new_without_default",
6110 description: r##"Checks for types with a `fn new() -> Self` method and no\nimplementation of\n[`Default`](https://doc.rust-lang.org/std/default/trait.Default.html)."##,
6111 },
6112 Lint {
6113 label: "clippy::no_effect",
6114 description: r##"Checks for statements which have no effect."##,
6115 },
6116 Lint {
6117 label: "clippy::non_ascii_literal",
6118 description: r##"Checks for non-ASCII characters in string literals."##,
6119 },
6120 Lint {
6121 label: "clippy::non_octal_unix_permissions",
6122 description: r##"Checks for non-octal values used to set Unix file permissions."##,
6123 },
6124 Lint {
6125 label: "clippy::nonminimal_bool",
6126 description: r##"Checks for boolean expressions that can be written more\nconcisely."##,
6127 },
6128 Lint {
6129 label: "clippy::nonsensical_open_options",
6130 description: r##"Checks for duplicate open options as well as combinations\nthat make no sense."##,
6131 },
6132 Lint {
6133 label: "clippy::not_unsafe_ptr_arg_deref",
6134 description: r##"Checks for public functions that dereference raw pointer\narguments but are not marked `unsafe`."##,
6135 },
6136 Lint { label: "clippy::ok_expect", description: r##"Checks for usage of `ok().expect(..)`."## },
6137 Lint {
6138 label: "clippy::op_ref",
6139 description: r##"Checks for arguments to `==` which have their address\ntaken to satisfy a bound\nand suggests to dereference the other argument instead"##,
6140 },
6141 Lint {
6142 label: "clippy::option_as_ref_deref",
6143 description: r##"Checks for usage of `_.as_ref().map(Deref::deref)` or it's aliases (such as String::as_str)."##,
6144 },
6145 Lint {
6146 label: "clippy::option_env_unwrap",
6147 description: r##"Checks for usage of `option_env!(...).unwrap()` and\nsuggests usage of the `env!` macro."##,
6148 },
6149 Lint {
6150 label: "clippy::option_filter_map",
6151 description: r##"Checks for indirect collection of populated `Option`"##,
6152 },
6153 Lint {
6154 label: "clippy::option_if_let_else",
6155 description: r##"Lints usage of `if let Some(v) = ... { y } else { x }` which is more\nidiomatically done with `Option::map_or` (if the else bit is a pure\nexpression) or `Option::map_or_else` (if the else bit is an impure\nexpression)."##,
6156 },
6157 Lint {
6158 label: "clippy::option_map_or_none",
6159 description: r##"Checks for usage of `_.map_or(None, _)`."##,
6160 },
6161 Lint {
6162 label: "clippy::option_map_unit_fn",
6163 description: r##"Checks for usage of `option.map(f)` where f is a function\nor closure that returns the unit type `()`."##,
6164 },
6165 Lint {
6166 label: "clippy::option_option",
6167 description: r##"Checks for use of `Option<Option<_>>` in function signatures and type\ndefinitions"##,
6168 },
6169 Lint {
6170 label: "clippy::or_fun_call",
6171 description: r##"Checks for calls to `.or(foo(..))`, `.unwrap_or(foo(..))`,\netc., and suggests to use `or_else`, `unwrap_or_else`, etc., or\n`unwrap_or_default` instead."##,
6172 },
6173 Lint {
6174 label: "clippy::out_of_bounds_indexing",
6175 description: r##"Checks for out of bounds array indexing with a constant\nindex."##,
6176 },
6177 Lint {
6178 label: "clippy::overflow_check_conditional",
6179 description: r##"Detects classic underflow/overflow checks."##,
6180 },
6181 Lint { label: "clippy::panic", description: r##"Checks for usage of `panic!`."## },
6182 Lint {
6183 label: "clippy::panic_in_result_fn",
6184 description: r##"Checks for usage of `panic!`, `unimplemented!`, `todo!`, `unreachable!` or assertions in a function of type result."##,
6185 },
6186 Lint {
6187 label: "clippy::panicking_unwrap",
6188 description: r##"Checks for calls of `unwrap[_err]()` that will always fail."##,
6189 },
6190 Lint {
6191 label: "clippy::partialeq_ne_impl",
6192 description: r##"Checks for manual re-implementations of `PartialEq::ne`."##,
6193 },
6194 Lint {
6195 label: "clippy::path_buf_push_overwrite",
6196 description: r##"* Checks for [push](https://doc.rust-lang.org/std/path/struct.PathBuf.html#method.push)\ncalls on `PathBuf` that can cause overwrites."##,
6197 },
6198 Lint {
6199 label: "clippy::pattern_type_mismatch",
6200 description: r##"Checks for patterns that aren't exact representations of the types\nthey are applied to.\n\nTo satisfy this lint, you will have to adjust either the expression that is matched\nagainst or the pattern itself, as well as the bindings that are introduced by the\nadjusted patterns. For matching you will have to either dereference the expression\nwith the `*` operator, or amend the patterns to explicitly match against `&<pattern>`\nor `&mut <pattern>` depending on the reference mutability. For the bindings you need\nto use the inverse. You can leave them as plain bindings if you wish for the value\nto be copied, but you must use `ref mut <variable>` or `ref <variable>` to construct\na reference into the matched structure.\n\nIf you are looking for a way to learn about ownership semantics in more detail, it\nis recommended to look at IDE options available to you to highlight types, lifetimes\nand reference semantics in your code. The available tooling would expose these things\nin a general way even outside of the various pattern matching mechanics. Of course\nthis lint can still be used to highlight areas of interest and ensure a good understanding\nof ownership semantics."##,
6201 },
6202 Lint {
6203 label: "clippy::possible_missing_comma",
6204 description: r##"Checks for possible missing comma in an array. It lints if\nan array element is a binary operator expression and it lies on two lines."##,
6205 },
6206 Lint {
6207 label: "clippy::precedence",
6208 description: r##"Checks for operations where precedence may be unclear\nand suggests to add parentheses. Currently it catches the following:\n* mixed usage of arithmetic and bit shifting/combining operators without\nparentheses\n* a \"negative\" numeric literal (which is really a unary `-` followed by a\nnumeric literal)\n followed by a method call"##,
6209 },
6210 Lint {
6211 label: "clippy::print_literal",
6212 description: r##"This lint warns about the use of literals as `print!`/`println!` args."##,
6213 },
6214 Lint {
6215 label: "clippy::print_stderr",
6216 description: r##"Checks for printing on *stderr*. The purpose of this lint\nis to catch debugging remnants."##,
6217 },
6218 Lint {
6219 label: "clippy::print_stdout",
6220 description: r##"Checks for printing on *stdout*. The purpose of this lint\nis to catch debugging remnants."##,
6221 },
6222 Lint {
6223 label: "clippy::print_with_newline",
6224 description: r##"This lint warns when you use `print!()` with a format\nstring that ends in a newline."##,
6225 },
6226 Lint {
6227 label: "clippy::println_empty_string",
6228 description: r##"This lint warns when you use `println!(\"\")` to\nprint a newline."##,
6229 },
6230 Lint {
6231 label: "clippy::ptr_arg",
6232 description: r##"This lint checks for function arguments of type `&String`\nor `&Vec` unless the references are mutable. It will also suggest you\nreplace `.clone()` calls with the appropriate `.to_owned()`/`to_string()`\ncalls."##,
6233 },
6234 Lint {
6235 label: "clippy::ptr_as_ptr",
6236 description: r##"Checks for `as` casts between raw pointers without changing its mutability,\nnamely `*const T` to `*const U` and `*mut T` to `*mut U`."##,
6237 },
6238 Lint { label: "clippy::ptr_eq", description: r##"Use `std::ptr::eq` when applicable"## },
6239 Lint {
6240 label: "clippy::ptr_offset_with_cast",
6241 description: r##"Checks for usage of the `offset` pointer method with a `usize` casted to an\n`isize`."##,
6242 },
6243 Lint {
6244 label: "clippy::pub_enum_variant_names",
6245 description: r##"Nothing. This lint has been deprecated."##,
6246 },
6247 Lint {
6248 label: "clippy::question_mark",
6249 description: r##"Checks for expressions that could be replaced by the question mark operator."##,
6250 },
6251 Lint {
6252 label: "clippy::range_minus_one",
6253 description: r##"Checks for inclusive ranges where 1 is subtracted from\nthe upper bound, e.g., `x..=(y-1)`."##,
6254 },
6255 Lint {
6256 label: "clippy::range_plus_one",
6257 description: r##"Checks for exclusive ranges where 1 is added to the\nupper bound, e.g., `x..(y+1)`."##,
6258 },
6259 Lint {
6260 label: "clippy::range_step_by_zero",
6261 description: r##"Nothing. This lint has been deprecated."##,
6262 },
6263 Lint {
6264 label: "clippy::range_zip_with_len",
6265 description: r##"Checks for zipping a collection with the range of\n`0.._.len()`."##,
6266 },
6267 Lint {
6268 label: "clippy::rc_buffer",
6269 description: r##"Checks for `Rc<T>` and `Arc<T>` when `T` is a mutable buffer type such as `String` or `Vec`."##,
6270 },
6271 Lint {
6272 label: "clippy::redundant_allocation",
6273 description: r##"Checks for use of redundant allocations anywhere in the code."##,
6274 },
6275 Lint {
6276 label: "clippy::redundant_clone",
6277 description: r##"Checks for a redundant `clone()` (and its relatives) which clones an owned\nvalue that is going to be dropped without further use."##,
6278 },
6279 Lint {
6280 label: "clippy::redundant_closure",
6281 description: r##"Checks for closures which just call another function where\nthe function can be called directly. `unsafe` functions or calls where types\nget adjusted are ignored."##,
6282 },
6283 Lint {
6284 label: "clippy::redundant_closure_call",
6285 description: r##"Detects closures called in the same expression where they\nare defined."##,
6286 },
6287 Lint {
6288 label: "clippy::redundant_closure_for_method_calls",
6289 description: r##"Checks for closures which only invoke a method on the closure\nargument and can be replaced by referencing the method directly."##,
6290 },
6291 Lint {
6292 label: "clippy::redundant_else",
6293 description: r##"Checks for `else` blocks that can be removed without changing semantics."##,
6294 },
6295 Lint {
6296 label: "clippy::redundant_field_names",
6297 description: r##"Checks for fields in struct literals where shorthands\ncould be used."##,
6298 },
6299 Lint {
6300 label: "clippy::redundant_pattern",
6301 description: r##"Checks for patterns in the form `name @ _`."##,
6302 },
6303 Lint {
6304 label: "clippy::redundant_pattern_matching",
6305 description: r##"Lint for redundant pattern matching over `Result`, `Option`,\n`std::task::Poll` or `std::net::IpAddr`"##,
6306 },
6307 Lint {
6308 label: "clippy::redundant_pub_crate",
6309 description: r##"Checks for items declared `pub(crate)` that are not crate visible because they\nare inside a private module."##,
6310 },
6311 Lint {
6312 label: "clippy::redundant_slicing",
6313 description: r##"Checks for redundant slicing expressions which use the full range, and\ndo not change the type."##,
6314 },
6315 Lint {
6316 label: "clippy::redundant_static_lifetimes",
6317 description: r##"Checks for constants and statics with an explicit `'static` lifetime."##,
6318 },
6319 Lint {
6320 label: "clippy::ref_binding_to_reference",
6321 description: r##"Checks for `ref` bindings which create a reference to a reference."##,
6322 },
6323 Lint {
6324 label: "clippy::ref_in_deref",
6325 description: r##"Checks for references in expressions that use\nauto dereference."##,
6326 },
6327 Lint {
6328 label: "clippy::ref_option_ref",
6329 description: r##"Checks for usage of `&Option<&T>`."##,
6330 },
6331 Lint {
6332 label: "clippy::regex_macro",
6333 description: r##"Nothing. This lint has been deprecated."##,
6334 },
6335 Lint {
6336 label: "clippy::repeat_once",
6337 description: r##"Checks for usage of `.repeat(1)` and suggest the following method for each types.\n- `.to_string()` for `str`\n- `.clone()` for `String`\n- `.to_vec()` for `slice`"##,
6338 },
6339 Lint {
6340 label: "clippy::replace_consts",
6341 description: r##"Nothing. This lint has been deprecated."##,
6342 },
6343 Lint {
6344 label: "clippy::rest_pat_in_fully_bound_structs",
6345 description: r##"Checks for unnecessary '..' pattern binding on struct when all fields are explicitly matched."##,
6346 },
6347 Lint {
6348 label: "clippy::result_map_or_into_option",
6349 description: r##"Checks for usage of `_.map_or(None, Some)`."##,
6350 },
6351 Lint {
6352 label: "clippy::result_map_unit_fn",
6353 description: r##"Checks for usage of `result.map(f)` where f is a function\nor closure that returns the unit type `()`."##,
6354 },
6355 Lint {
6356 label: "clippy::result_unit_err",
6357 description: r##"Checks for public functions that return a `Result`\nwith an `Err` type of `()`. It suggests using a custom type that\nimplements `std::error::Error`."##,
6358 },
6359 Lint {
6360 label: "clippy::reversed_empty_ranges",
6361 description: r##"Checks for range expressions `x..y` where both `x` and `y`\nare constant and `x` is greater or equal to `y`."##,
6362 },
6363 Lint {
6364 label: "clippy::same_functions_in_if_condition",
6365 description: r##"Checks for consecutive `if`s with the same function call."##,
6366 },
6367 Lint {
6368 label: "clippy::same_item_push",
6369 description: r##"Checks whether a for loop is being used to push a constant\nvalue into a Vec."##,
6370 },
6371 Lint {
6372 label: "clippy::search_is_some",
6373 description: r##"Checks for an iterator or string search (such as `find()`,\n`position()`, or `rposition()`) followed by a call to `is_some()` or `is_none()`."##,
6374 },
6375 Lint {
6376 label: "clippy::self_assignment",
6377 description: r##"Checks for explicit self-assignments."##,
6378 },
6379 Lint {
6380 label: "clippy::semicolon_if_nothing_returned",
6381 description: r##"Looks for blocks of expressions and fires if the last expression returns\n`()` but is not followed by a semicolon."##,
6382 },
6383 Lint {
6384 label: "clippy::serde_api_misuse",
6385 description: r##"Checks for mis-uses of the serde API."##,
6386 },
6387 Lint {
6388 label: "clippy::shadow_reuse",
6389 description: r##"Checks for bindings that shadow other bindings already in\nscope, while reusing the original value."##,
6390 },
6391 Lint {
6392 label: "clippy::shadow_same",
6393 description: r##"Checks for bindings that shadow other bindings already in\nscope, while just changing reference level or mutability."##,
6394 },
6395 Lint {
6396 label: "clippy::shadow_unrelated",
6397 description: r##"Checks for bindings that shadow other bindings already in\nscope, either without a initialization or with one that does not even use\nthe original value."##,
6398 },
6399 Lint {
6400 label: "clippy::short_circuit_statement",
6401 description: r##"Checks for the use of short circuit boolean conditions as\na\nstatement."##,
6402 },
6403 Lint {
6404 label: "clippy::should_assert_eq",
6405 description: r##"Nothing. This lint has been deprecated."##,
6406 },
6407 Lint {
6408 label: "clippy::should_implement_trait",
6409 description: r##"Checks for methods that should live in a trait\nimplementation of a `std` trait (see [llogiq's blog\npost](http://llogiq.github.io/2015/07/30/traits.html) for further\ninformation) instead of an inherent implementation."##,
6410 },
6411 Lint {
6412 label: "clippy::similar_names",
6413 description: r##"Checks for names that are very similar and thus confusing."##,
6414 },
6415 Lint {
6416 label: "clippy::single_char_add_str",
6417 description: r##"Warns when using `push_str`/`insert_str` with a single-character string literal\nwhere `push`/`insert` with a `char` would work fine."##,
6418 },
6419 Lint {
6420 label: "clippy::single_char_pattern",
6421 description: r##"Checks for string methods that receive a single-character\n`str` as an argument, e.g., `_.split(\"x\")`."##,
6422 },
6423 Lint {
6424 label: "clippy::single_component_path_imports",
6425 description: r##"Checking for imports with single component use path."##,
6426 },
6427 Lint {
6428 label: "clippy::single_element_loop",
6429 description: r##"Checks whether a for loop has a single element."##,
6430 },
6431 Lint {
6432 label: "clippy::single_match",
6433 description: r##"Checks for matches with a single arm where an `if let`\nwill usually suffice."##,
6434 },
6435 Lint {
6436 label: "clippy::single_match_else",
6437 description: r##"Checks for matches with two arms where an `if let else` will\nusually suffice."##,
6438 },
6439 Lint {
6440 label: "clippy::size_of_in_element_count",
6441 description: r##"Detects expressions where\n`size_of::<T>` or `size_of_val::<T>` is used as a\ncount of elements of type `T`"##,
6442 },
6443 Lint {
6444 label: "clippy::skip_while_next",
6445 description: r##"Checks for usage of `_.skip_while(condition).next()`."##,
6446 },
6447 Lint {
6448 label: "clippy::slow_vector_initialization",
6449 description: r##"Checks slow zero-filled vector initialization"##,
6450 },
6451 Lint {
6452 label: "clippy::stable_sort_primitive",
6453 description: r##"When sorting primitive values (integers, bools, chars, as well\nas arrays, slices, and tuples of such items), it is better to\nuse an unstable sort than a stable sort."##,
6454 },
6455 Lint {
6456 label: "clippy::str_to_string",
6457 description: r##"This lint checks for `.to_string()` method calls on values of type `&str`."##,
6458 },
6459 Lint {
6460 label: "clippy::string_add",
6461 description: r##"Checks for all instances of `x + _` where `x` is of type\n`String`, but only if [`string_add_assign`](#string_add_assign) does *not*\nmatch."##,
6462 },
6463 Lint {
6464 label: "clippy::string_add_assign",
6465 description: r##"Checks for string appends of the form `x = x + y` (without\n`let`!)."##,
6466 },
6467 Lint {
6468 label: "clippy::string_extend_chars",
6469 description: r##"Checks for the use of `.extend(s.chars())` where s is a\n`&str` or `String`."##,
6470 },
6471 Lint {
6472 label: "clippy::string_from_utf8_as_bytes",
6473 description: r##"Check if the string is transformed to byte array and casted back to string."##,
6474 },
6475 Lint {
6476 label: "clippy::string_lit_as_bytes",
6477 description: r##"Checks for the `as_bytes` method called on string literals\nthat contain only ASCII characters."##,
6478 },
6479 Lint {
6480 label: "clippy::string_to_string",
6481 description: r##"This lint checks for `.to_string()` method calls on values of type `String`."##,
6482 },
6483 Lint {
6484 label: "clippy::struct_excessive_bools",
6485 description: r##"Checks for excessive\nuse of bools in structs."##,
6486 },
6487 Lint {
6488 label: "clippy::suboptimal_flops",
6489 description: r##"Looks for floating-point expressions that\ncan be expressed using built-in methods to improve both\naccuracy and performance."##,
6490 },
6491 Lint {
6492 label: "clippy::suspicious_arithmetic_impl",
6493 description: r##"Lints for suspicious operations in impls of arithmetic operators, e.g.\nsubtracting elements in an Add impl."##,
6494 },
6495 Lint {
6496 label: "clippy::suspicious_assignment_formatting",
6497 description: r##"Checks for use of the non-existent `=*`, `=!` and `=-`\noperators."##,
6498 },
6499 Lint {
6500 label: "clippy::suspicious_else_formatting",
6501 description: r##"Checks for formatting of `else`. It lints if the `else`\nis followed immediately by a newline or the `else` seems to be missing."##,
6502 },
6503 Lint {
6504 label: "clippy::suspicious_map",
6505 description: r##"Checks for calls to `map` followed by a `count`."##,
6506 },
6507 Lint {
6508 label: "clippy::suspicious_op_assign_impl",
6509 description: r##"Lints for suspicious operations in impls of OpAssign, e.g.\nsubtracting elements in an AddAssign impl."##,
6510 },
6511 Lint {
6512 label: "clippy::suspicious_operation_groupings",
6513 description: r##"Checks for unlikely usages of binary operators that are almost\ncertainly typos and/or copy/paste errors, given the other usages\nof binary operators nearby."##,
6514 },
6515 Lint {
6516 label: "clippy::suspicious_splitn",
6517 description: r##"Checks for calls to [`splitn`]\n(https://doc.rust-lang.org/std/primitive.str.html#method.splitn) and\nrelated functions with either zero or one splits."##,
6518 },
6519 Lint {
6520 label: "clippy::suspicious_unary_op_formatting",
6521 description: r##"Checks the formatting of a unary operator on the right hand side\nof a binary operator. It lints if there is no space between the binary and unary operators,\nbut there is a space between the unary and its operand."##,
6522 },
6523 Lint {
6524 label: "clippy::tabs_in_doc_comments",
6525 description: r##"Checks doc comments for usage of tab characters."##,
6526 },
6527 Lint {
6528 label: "clippy::temporary_assignment",
6529 description: r##"Checks for construction of a structure or tuple just to\nassign a value in it."##,
6530 },
6531 Lint {
6532 label: "clippy::to_digit_is_some",
6533 description: r##"Checks for `.to_digit(..).is_some()` on `char`s."##,
6534 },
6535 Lint {
6536 label: "clippy::to_string_in_display",
6537 description: r##"Checks for uses of `to_string()` in `Display` traits."##,
6538 },
6539 Lint { label: "clippy::todo", description: r##"Checks for usage of `todo!`."## },
6540 Lint {
6541 label: "clippy::too_many_arguments",
6542 description: r##"Checks for functions with too many parameters."##,
6543 },
6544 Lint {
6545 label: "clippy::too_many_lines",
6546 description: r##"Checks for functions with a large amount of lines."##,
6547 },
6548 Lint {
6549 label: "clippy::toplevel_ref_arg",
6550 description: r##"Checks for function arguments and let bindings denoted as\n`ref`."##,
6551 },
6552 Lint {
6553 label: "clippy::trait_duplication_in_bounds",
6554 description: r##"Checks for cases where generics are being used and multiple\nsyntax specifications for trait bounds are used simultaneously."##,
6555 },
6556 Lint {
6557 label: "clippy::transmute_bytes_to_str",
6558 description: r##"Checks for transmutes from a `&[u8]` to a `&str`."##,
6559 },
6560 Lint {
6561 label: "clippy::transmute_float_to_int",
6562 description: r##"Checks for transmutes from a float to an integer."##,
6563 },
6564 Lint {
6565 label: "clippy::transmute_int_to_bool",
6566 description: r##"Checks for transmutes from an integer to a `bool`."##,
6567 },
6568 Lint {
6569 label: "clippy::transmute_int_to_char",
6570 description: r##"Checks for transmutes from an integer to a `char`."##,
6571 },
6572 Lint {
6573 label: "clippy::transmute_int_to_float",
6574 description: r##"Checks for transmutes from an integer to a float."##,
6575 },
6576 Lint {
6577 label: "clippy::transmute_ptr_to_ptr",
6578 description: r##"Checks for transmutes from a pointer to a pointer, or\nfrom a reference to a reference."##,
6579 },
6580 Lint {
6581 label: "clippy::transmute_ptr_to_ref",
6582 description: r##"Checks for transmutes from a pointer to a reference."##,
6583 },
6584 Lint {
6585 label: "clippy::transmutes_expressible_as_ptr_casts",
6586 description: r##"Checks for transmutes that could be a pointer cast."##,
6587 },
6588 Lint {
6589 label: "clippy::transmuting_null",
6590 description: r##"Checks for transmute calls which would receive a null pointer."##,
6591 },
6592 Lint {
6593 label: "clippy::trivial_regex",
6594 description: r##"Checks for trivial [regex](https://crates.io/crates/regex)\ncreation (with `Regex::new`, `RegexBuilder::new`, or `RegexSet::new`)."##,
6595 },
6596 Lint {
6597 label: "clippy::trivially_copy_pass_by_ref",
6598 description: r##"Checks for functions taking arguments by reference, where\nthe argument type is `Copy` and small enough to be more efficient to always\npass by value."##,
6599 },
6600 Lint { label: "clippy::try_err", description: r##"Checks for usages of `Err(x)?`."## },
6601 Lint {
6602 label: "clippy::type_complexity",
6603 description: r##"Checks for types used in structs, parameters and `let`\ndeclarations above a certain complexity threshold."##,
6604 },
6605 Lint {
6606 label: "clippy::type_repetition_in_bounds",
6607 description: r##"This lint warns about unnecessary type repetitions in trait bounds"##,
6608 },
6609 Lint {
6610 label: "clippy::undropped_manually_drops",
6611 description: r##"Prevents the safe `std::mem::drop` function from being called on `std::mem::ManuallyDrop`."##,
6612 },
6613 Lint {
6614 label: "clippy::unicode_not_nfc",
6615 description: r##"Checks for string literals that contain Unicode in a form\nthat is not equal to its\n[NFC-recomposition](http://www.unicode.org/reports/tr15/#Norm_Forms)."##,
6616 },
6617 Lint {
6618 label: "clippy::unimplemented",
6619 description: r##"Checks for usage of `unimplemented!`."##,
6620 },
6621 Lint {
6622 label: "clippy::uninit_assumed_init",
6623 description: r##"Checks for `MaybeUninit::uninit().assume_init()`."##,
6624 },
6625 Lint {
6626 label: "clippy::unit_arg",
6627 description: r##"Checks for passing a unit value as an argument to a function without using a\nunit literal (`()`)."##,
6628 },
6629 Lint {
6630 label: "clippy::unit_cmp",
6631 description: r##"Checks for comparisons to unit. This includes all binary\ncomparisons (like `==` and `<`) and asserts."##,
6632 },
6633 Lint {
6634 label: "clippy::unit_return_expecting_ord",
6635 description: r##"Checks for functions that expect closures of type\nFn(...) -> Ord where the implemented closure returns the unit type.\nThe lint also suggests to remove the semi-colon at the end of the statement if present."##,
6636 },
6637 Lint {
6638 label: "clippy::unnecessary_cast",
6639 description: r##"Checks for casts to the same type, casts of int literals to integer types\nand casts of float literals to float types."##,
6640 },
6641 Lint {
6642 label: "clippy::unnecessary_filter_map",
6643 description: r##"Checks for `filter_map` calls which could be replaced by `filter` or `map`.\nMore specifically it checks if the closure provided is only performing one of the\nfilter or map operations and suggests the appropriate option."##,
6644 },
6645 Lint {
6646 label: "clippy::unnecessary_fold",
6647 description: r##"Checks for using `fold` when a more succinct alternative exists.\nSpecifically, this checks for `fold`s which could be replaced by `any`, `all`,\n`sum` or `product`."##,
6648 },
6649 Lint {
6650 label: "clippy::unnecessary_lazy_evaluations",
6651 description: r##"As the counterpart to `or_fun_call`, this lint looks for unnecessary\nlazily evaluated closures on `Option` and `Result`.\n\nThis lint suggests changing the following functions, when eager evaluation results in\nsimpler code:\n - `unwrap_or_else` to `unwrap_or`\n - `and_then` to `and`\n - `or_else` to `or`\n - `get_or_insert_with` to `get_or_insert`\n - `ok_or_else` to `ok_or`"##,
6652 },
6653 Lint {
6654 label: "clippy::unnecessary_mut_passed",
6655 description: r##"Detects passing a mutable reference to a function that only\nrequires an immutable reference."##,
6656 },
6657 Lint {
6658 label: "clippy::unnecessary_operation",
6659 description: r##"Checks for expression statements that can be reduced to a\nsub-expression."##,
6660 },
6661 Lint {
6662 label: "clippy::unnecessary_self_imports",
6663 description: r##"Checks for imports ending in `::{self}`."##,
6664 },
6665 Lint {
6666 label: "clippy::unnecessary_sort_by",
6667 description: r##"Detects uses of `Vec::sort_by` passing in a closure\nwhich compares the two arguments, either directly or indirectly."##,
6668 },
6669 Lint {
6670 label: "clippy::unnecessary_unwrap",
6671 description: r##"Checks for calls of `unwrap[_err]()` that cannot fail."##,
6672 },
6673 Lint {
6674 label: "clippy::unnecessary_wraps",
6675 description: r##"Checks for private functions that only return `Ok` or `Some`."##,
6676 },
6677 Lint {
6678 label: "clippy::unneeded_field_pattern",
6679 description: r##"Checks for structure field patterns bound to wildcards."##,
6680 },
6681 Lint {
6682 label: "clippy::unneeded_wildcard_pattern",
6683 description: r##"Checks for tuple patterns with a wildcard\npattern (`_`) is next to a rest pattern (`..`).\n\n_NOTE_: While `_, ..` means there is at least one element left, `..`\nmeans there are 0 or more elements left. This can make a difference\nwhen refactoring, but shouldn't result in errors in the refactored code,\nsince the wildcard pattern isn't used anyway."##,
6684 },
6685 Lint {
6686 label: "clippy::unnested_or_patterns",
6687 description: r##"Checks for unnested or-patterns, e.g., `Some(0) | Some(2)` and\nsuggests replacing the pattern with a nested one, `Some(0 | 2)`.\n\nAnother way to think of this is that it rewrites patterns in\n*disjunctive normal form (DNF)* into *conjunctive normal form (CNF)*."##,
6688 },
6689 Lint { label: "clippy::unreachable", description: r##"Checks for usage of `unreachable!`."## },
6690 Lint {
6691 label: "clippy::unreadable_literal",
6692 description: r##"Warns if a long integral or floating-point constant does\nnot contain underscores."##,
6693 },
6694 Lint {
6695 label: "clippy::unsafe_derive_deserialize",
6696 description: r##"Checks for deriving `serde::Deserialize` on a type that\nhas methods using `unsafe`."##,
6697 },
6698 Lint {
6699 label: "clippy::unsafe_removed_from_name",
6700 description: r##"Checks for imports that remove \"unsafe\" from an item's\nname."##,
6701 },
6702 Lint {
6703 label: "clippy::unsafe_vector_initialization",
6704 description: r##"Nothing. This lint has been deprecated."##,
6705 },
6706 Lint {
6707 label: "clippy::unseparated_literal_suffix",
6708 description: r##"Warns if literal suffixes are not separated by an\nunderscore."##,
6709 },
6710 Lint {
6711 label: "clippy::unsound_collection_transmute",
6712 description: r##"Checks for transmutes between collections whose\ntypes have different ABI, size or alignment."##,
6713 },
6714 Lint {
6715 label: "clippy::unstable_as_mut_slice",
6716 description: r##"Nothing. This lint has been deprecated."##,
6717 },
6718 Lint {
6719 label: "clippy::unstable_as_slice",
6720 description: r##"Nothing. This lint has been deprecated."##,
6721 },
6722 Lint {
6723 label: "clippy::unused_async",
6724 description: r##"Checks for functions that are declared `async` but have no `.await`s inside of them."##,
6725 },
6726 Lint {
6727 label: "clippy::unused_collect",
6728 description: r##"Nothing. This lint has been deprecated."##,
6729 },
6730 Lint {
6731 label: "clippy::unused_io_amount",
6732 description: r##"Checks for unused written/read amount."##,
6733 },
6734 Lint {
6735 label: "clippy::unused_self",
6736 description: r##"Checks methods that contain a `self` argument but don't use it"##,
6737 },
6738 Lint {
6739 label: "clippy::unused_unit",
6740 description: r##"Checks for unit (`()`) expressions that can be removed."##,
6741 },
6742 Lint {
6743 label: "clippy::unusual_byte_groupings",
6744 description: r##"Warns if hexadecimal or binary literals are not grouped\nby nibble or byte."##,
6745 },
6746 Lint {
6747 label: "clippy::unwrap_in_result",
6748 description: r##"Checks for functions of type Result that contain `expect()` or `unwrap()`"##,
6749 },
6750 Lint {
6751 label: "clippy::unwrap_used",
6752 description: r##"Checks for `.unwrap()` calls on `Option`s and on `Result`s."##,
6753 },
6754 Lint {
6755 label: "clippy::upper_case_acronyms",
6756 description: r##"Checks for fully capitalized names and optionally names containing a capitalized acronym."##,
6757 },
6758 Lint {
6759 label: "clippy::use_debug",
6760 description: r##"Checks for use of `Debug` formatting. The purpose of this\nlint is to catch debugging remnants."##,
6761 },
6762 Lint {
6763 label: "clippy::use_self",
6764 description: r##"Checks for unnecessary repetition of structure name when a\nreplacement with `Self` is applicable."##,
6765 },
6766 Lint {
6767 label: "clippy::used_underscore_binding",
6768 description: r##"Checks for the use of bindings with a single leading\nunderscore."##,
6769 },
6770 Lint {
6771 label: "clippy::useless_asref",
6772 description: r##"Checks for usage of `.as_ref()` or `.as_mut()` where the\ntypes before and after the call are the same."##,
6773 },
6774 Lint {
6775 label: "clippy::useless_attribute",
6776 description: r##"Checks for `extern crate` and `use` items annotated with\nlint attributes.\n\nThis lint permits `#[allow(unused_imports)]`, `#[allow(deprecated)]`,\n`#[allow(unreachable_pub)]`, `#[allow(clippy::wildcard_imports)]` and\n`#[allow(clippy::enum_glob_use)]` on `use` items and `#[allow(unused_imports)]` on\n`extern crate` items with a `#[macro_use]` attribute."##,
6777 },
6778 Lint {
6779 label: "clippy::useless_conversion",
6780 description: r##"Checks for `Into`, `TryInto`, `From`, `TryFrom`, or `IntoIter` calls\nwhich uselessly convert to the same type."##,
6781 },
6782 Lint {
6783 label: "clippy::useless_format",
6784 description: r##"Checks for the use of `format!(\"string literal with no\nargument\")` and `format!(\"{}\", foo)` where `foo` is a string."##,
6785 },
6786 Lint {
6787 label: "clippy::useless_let_if_seq",
6788 description: r##"Checks for variable declarations immediately followed by a\nconditional affectation."##,
6789 },
6790 Lint {
6791 label: "clippy::useless_transmute",
6792 description: r##"Checks for transmutes to the original type of the object\nand transmutes that could be a cast."##,
6793 },
6794 Lint {
6795 label: "clippy::useless_vec",
6796 description: r##"Checks for usage of `&vec![..]` when using `&[..]` would\nbe possible."##,
6797 },
6798 Lint {
6799 label: "clippy::vec_box",
6800 description: r##"Checks for use of `Vec<Box<T>>` where T: Sized anywhere in the code.\nCheck the [Box documentation](https://doc.rust-lang.org/std/boxed/index.html) for more information."##,
6801 },
6802 Lint {
6803 label: "clippy::vec_init_then_push",
6804 description: r##"Checks for calls to `push` immediately after creating a new `Vec`."##,
6805 },
6806 Lint {
6807 label: "clippy::vec_resize_to_zero",
6808 description: r##"Finds occurrences of `Vec::resize(0, an_int)`"##,
6809 },
6810 Lint {
6811 label: "clippy::verbose_bit_mask",
6812 description: r##"Checks for bit masks that can be replaced by a call\nto `trailing_zeros`"##,
6813 },
6814 Lint {
6815 label: "clippy::verbose_file_reads",
6816 description: r##"Checks for use of File::read_to_end and File::read_to_string."##,
6817 },
6818 Lint {
6819 label: "clippy::vtable_address_comparisons",
6820 description: r##"Checks for comparisons with an address of a trait vtable."##,
6821 },
6822 Lint {
6823 label: "clippy::while_immutable_condition",
6824 description: r##"Checks whether variables used within while loop condition\ncan be (and are) mutated in the body."##,
6825 },
6826 Lint {
6827 label: "clippy::while_let_loop",
6828 description: r##"Detects `loop + match` combinations that are easier\nwritten as a `while let` loop."##,
6829 },
6830 Lint {
6831 label: "clippy::while_let_on_iterator",
6832 description: r##"Checks for `while let` expressions on iterators."##,
6833 },
6834 Lint {
6835 label: "clippy::wildcard_dependencies",
6836 description: r##"Checks for wildcard dependencies in the `Cargo.toml`."##,
6837 },
6838 Lint {
6839 label: "clippy::wildcard_enum_match_arm",
6840 description: r##"Checks for wildcard enum matches using `_`."##,
6841 },
6842 Lint {
6843 label: "clippy::wildcard_imports",
6844 description: r##"Checks for wildcard imports `use _::*`."##,
6845 },
6846 Lint {
6847 label: "clippy::wildcard_in_or_patterns",
6848 description: r##"Checks for wildcard pattern used with others patterns in same match arm."##,
6849 },
6850 Lint {
6851 label: "clippy::write_literal",
6852 description: r##"This lint warns about the use of literals as `write!`/`writeln!` args."##,
6853 },
6854 Lint {
6855 label: "clippy::write_with_newline",
6856 description: r##"This lint warns when you use `write!()` with a format\nstring that\nends in a newline."##,
6857 },
6858 Lint {
6859 label: "clippy::writeln_empty_string",
6860 description: r##"This lint warns when you use `writeln!(buf, \"\")` to\nprint a newline."##,
6861 },
6862 Lint {
6863 label: "clippy::wrong_pub_self_convention",
6864 description: r##"Nothing. This lint has been deprecated."##,
6865 },
6866 Lint {
6867 label: "clippy::wrong_self_convention",
6868 description: r##"Checks for methods with certain name prefixes and which\ndoesn't match how self is taken. The actual rules are:\n\n|Prefix |Postfix |`self` taken | `self` type |\n|-------|------------|-----------------------|--------------|\n|`as_` | none |`&self` or `&mut self` | any |\n|`from_`| none | none | any |\n|`into_`| none |`self` | any |\n|`is_` | none |`&self` or none | any |\n|`to_` | `_mut` |`&mut self` | any |\n|`to_` | not `_mut` |`self` | `Copy` |\n|`to_` | not `_mut` |`&self` | not `Copy` |\n\nNote: Clippy doesn't trigger methods with `to_` prefix in:\n- Traits definition.\nClippy can not tell if a type that implements a trait is `Copy` or not.\n- Traits implementation, when `&self` is taken.\nThe method signature is controlled by the trait and often `&self` is required for all types that implement the trait\n(see e.g. the `std::string::ToString` trait).\n\nPlease find more info here:\nhttps://rust-lang.github.io/api-guidelines/naming.html#ad-hoc-conversions-follow-as_-to_-into_-conventions-c-conv"##,
6869 },
6870 Lint {
6871 label: "clippy::wrong_transmute",
6872 description: r##"Checks for transmutes that can't ever be correct on any\narchitecture."##,
6873 },
6874 Lint { label: "clippy::zero_divided_by_zero", description: r##"Checks for `0.0 / 0.0`."## },
6875 Lint {
6876 label: "clippy::zero_prefixed_literal",
6877 description: r##"Warns if an integral constant literal starts with `0`."##,
6878 },
6879 Lint {
6880 label: "clippy::zero_ptr",
6881 description: r##"Catch casts from `0` to some pointer type"##,
6882 },
6883 Lint {
6884 label: "clippy::zero_sized_map_values",
6885 description: r##"Checks for maps with zero-sized value types anywhere in the code."##,
6886 },
6887 Lint {
6888 label: "clippy::zst_offset",
6889 description: r##"Checks for `offset(_)`, `wrapping_`{`add`, `sub`}, etc. on raw pointers to\nzero-sized types"##,
6890 },
6891];