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