diff --git a/current b/current index eade3ef47..5df164d60 120000 --- a/current +++ b/current @@ -1 +1 @@ -v0.0.142 \ No newline at end of file +v0.0.145 \ No newline at end of file diff --git a/v0.0.145/index.html b/v0.0.145/index.html new file mode 100644 index 000000000..04196eef3 --- /dev/null +++ b/v0.0.145/index.html @@ -0,0 +1,206 @@ + + + + + + + Clippy + + + + + + +
+ + + + +
+ + + + +
+
+
+
+
+ +
+
+
+
+
+ Filter: + + + + +
+
+
+
+ +
+
+ + +

+ {{lint.id}} + + Allow + Warn + Deny + Deprecated + + +

+
+ +
    +
  • +

    + {{title}} +

    +
    +
  • +
+
+
+
+ + + + + + + + + + + + diff --git a/v0.0.145/lints.json b/v0.0.145/lints.json new file mode 100644 index 000000000..216e632d3 --- /dev/null +++ b/v0.0.145/lints.json @@ -0,0 +1,2043 @@ +[ + { + "docs": { + "What it does": "Checks for `for` loops over `Option` values.", + "Why is this bad": "Readability. This is more clearly expressed as an `if let`.", + "Example": "```rust\nfor x in option { .. }\n```\nThis should be\n```rust\nif let Some(x) = option { .. }\n```", + "Known problems": "None." + }, + "id": "for_loop_over_option", + "level": "Warn" + }, + { + "docs": { + "What it does": "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 parentheses\n* a \"negative\" numeric literal (which is really a unary `-` followed by a numeric literal)\n followed by a method call", + "Why is this bad": "Not everyone knows the precedence of those operators by\nheart, so expressions like these may trip others trying to reason about the\ncode.", + "Example": "* `1 << 2 + 3` equals 32, while `(1 << 2) + 3` equals 7\n* `-1i32.abs()` equals -1, while `(-1i32).abs()` equals 1", + "Known problems": "None." + }, + "id": "precedence", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for usage of `.clone()` on an `&&T`.", + "Why is this bad": "Cloning an `&&T` copies the inner `&T`, instead of\ncloning the underlying `T`.", + "Example": "```rust\nfn main() {\n let x = vec![1];\n let y = &&x;\n let z = y.clone();\n println!(\"{:p} {:p}\",*y, z); // prints out the same pointer\n}\n```", + "Known problems": "None." + }, + "id": "clone_double_ref", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for explicit `Clone` implementations for `Copy`\ntypes.", + "Why is this bad": "To avoid surprising behaviour, these traits should\nagree and the behaviour of `Copy` cannot be overridden. In almost all\nsituations a `Copy` type should have a `Clone` implementation that does\nnothing more than copy the object, which is what `#[derive(Copy, Clone)]`\ngets you.", + "Example": "```rust\n#[derive(Copy)]\nstruct Foo;\nimpl Clone for Foo {\n ..\n}\n```", + "Known problems": "None." + }, + "id": "expl_impl_clone_on_copy", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for matches with a two arms where an `if let` will\nusually suffice.", + "Why is this bad": "Just readability \u2013 `if let` nests less than a `match`.", + "Example": "```rust\nmatch x {\n Some(ref foo) => bar(foo),\n _ => bar(other_ref),\n}\n```", + "Known problems": "Personal style preferences may differ." + }, + "id": "single_match_else", + "level": "Allow" + }, + { + "docs": { + "What it does": "Checks for incompatible bit masks in comparisons.\nThe formula for detecting if an expression of the type `_ m\n c` (where `` is one of {`&`, `|`} and `` is one of\n{`!=`, `>=`, `>`, `!=`, `>=`, `>`}) can be determined from the following\ntable:\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` |", + "Why is this bad": "If the bits that the comparison cares about are always\nset to zero or one by the bit mask, the comparison is constant `true` or\n`false` (depending on mask, compared value, and operators).\nSo the code is actively misleading, and the only reason someone would write\nthis intentionally is to win an underhanded Rust contest or create a\ntest-case for this lint.", + "Example": "```rust\nif (x & 1 == 2) { \u2026 }\n```", + "Known problems": "None." + }, + "id": "bad_bit_mask", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for calls to `std::mem::drop` with a reference\ninstead of an owned value.", + "Why is this bad": "Calling `drop` on a reference will only drop the\nreference itself, which is a no-op. It will not call the `drop` method (from\nthe `Drop` trait implementation) on the underlying referenced value, which\nis likely what was intended.", + "Example": "```rust\nlet mut lock_guard = mutex.lock();\nstd::mem::drop(&lock_guard) // Should have been drop(lock_guard), mutex still locked\noperation_that_requires_mutex_to_be_unlocked();\n```", + "Known problems": "None." + }, + "id": "drop_ref", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for matches where match expression is a `bool`. It\nsuggests to replace the expression with an `if...else` block.", + "Why is this bad": "It makes the code less readable.", + "Example": "```rust\nlet condition: bool = true;\nmatch condition {\n true => foo(),\n false => bar(),\n}\n```", + "Known problems": "None." + }, + "id": "match_bool", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for loops on `x.next()`.", + "Why is this bad": "`next()` returns either `Some(value)` if there was a\nvalue, or `None` otherwise. The insidious thing is that `Option<_>`\nimplements `IntoIterator`, so that possibly one value will be iterated,\nleading to some hard to find bugs. No one will want to write such code\n[except to win an Underhanded Rust\nContest](https://www.reddit.com/r/rust/comments/3hb0wm/underhanded_rust_contest/cu5yuhr).", + "Example": "```rust\nfor x in y.next() { .. }\n```", + "Known problems": "None." + }, + "id": "iter_next_loop", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for large size differences between variants on `enum`s.", + "Why is this bad": "Enum size is bounded by the largest variant. Having a large variant\ncan penalize the memory layout of that enum.", + "Example": "```rust\nenum Test {\n A(i32),\n B([i32; 8000]),\n}\n```", + "Known problems": "None." + }, + "id": "large_enum_variant", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for manual re-implementations of `PartialEq::ne`.", + "Why is this bad": "`PartialEq::ne` is required to always return the\nnegated result of `PartialEq::eq`, which is exactly what the default\nimplementation does. Therefore, there should never be any need to\nre-implement it.", + "Example": "```rust\nstruct Foo;\nimpl PartialEq for Foo {\n fn eq(&self, other: &Foo) -> bool { ... }\n fn ne(&self, other: &Foo) -> bool { !(self == other) }\n}\n```", + "Known problems": "None." + }, + "id": "partialeq_ne_impl", + "level": "Warn" + }, + { + "docs": { + "What it does": "Detects closures called in the same expression where they are defined.", + "Why is this bad": "It is unnecessarily adding to the expression's complexity.", + "Example": "```rust\n(|| 42)()\n```", + "Known problems": "None." + }, + "id": "redundant_closure_call", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for `#[deprecated]` annotations with a `since`\nfield that is not a valid semantic version.", + "Why is this bad": "For checking the version of the deprecation, it must be\na valid semver. Failing that, the contained information is useless.", + "Example": "```rust\n#[deprecated(since = \"forever\")]\nfn something_else(..) { ... }\n```", + "Known problems": "None." + }, + "id": "deprecated_semver", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for `.unwrap()` calls on `Option`s.", + "Why is this bad": "Usually it is better to handle the `None` case, or to\nat least call `.expect(_)` with a more helpful message. Still, for a lot of\nquick-and-dirty code, `unwrap` is a good choice, which is why this lint is\n`Allow` by default.", + "Example": "```rust\nx.unwrap()\n```", + "Known problems": "None." + }, + "id": "option_unwrap_used", + "level": "Allow" + }, + { + "docs": { + "What it does": "Checks for compound assignment operations (`+=` and similar).", + "Why is this bad": "Projects with many developers from languages without\nthose operations may find them unreadable and not worth their weight.", + "Example": "```rust\na += 1;\n```", + "Known problems": "Types implementing `OpAssign` don't necessarily implement `Op`." + }, + "id": "assign_ops", + "level": "Allow" + }, + { + "docs": { + "What it does": "Checks for the use of bindings with a single leading underscore.", + "Why is this bad": "A single leading underscore is usually used to indicate\nthat a binding will not be used. Using such a binding breaks this\nexpectation.", + "Example": "```rust\nlet _x = 0;\nlet y = _x + 1; // Here we are using `_x`, even though it has a leading underscore.\n // We should rename `_x` to `x`\n```", + "Known problems": "The lint does not work properly with desugaring and\nmacro, it has been allowed in the mean time." + }, + "id": "used_underscore_binding", + "level": "Allow" + }, + { + "docs": { + "What it does": "This lint checks for equality comparisons with `ptr::null`", + "Why is this bad": "It's easier and more readable to use the inherent `.is_null()`\nmethod instead", + "Example": "```rust\nif x == ptr::null { .. }\n```", + "Known problems": "None." + }, + "id": "cmp_null", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for public functions that dereferences raw pointer\narguments but are not marked unsafe.", + "Why is this bad": "The function should probably be marked `unsafe`, since\nfor an arbitrary raw pointer, there is no way of telling for sure if it is\nvalid.", + "Example": "```rust\npub fn foo(x: *const u8) { println!(\"{}\", unsafe { *x }); }\n```", + "Known problems": "* It does not check functions recursively so if the pointer is passed to a\nprivate non-`unsafe` function which does the dereferencing, the lint won't trigger.\n* It only checks for arguments whose type are raw pointers, not raw pointers\ngot from an argument in some other way (`fn foo(bar: &[*const u8])` or\n`some_argument.get_raw_ptr()`)." + }, + "id": "not_unsafe_ptr_arg_deref", + "level": "Warn" + }, + { + "docs": {}, + "id": "overflow_check_conditional", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for structure field patterns bound to wildcards.", + "Why is this bad": "Using `..` instead is shorter and leaves the focus on\nthe fields that are actually bound.", + "Example": "```rust\nlet { a: _, b: ref b, c: _ } = ..\n```", + "Known problems": "None." + }, + "id": "unneeded_field_pattern", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for types with a `fn new() -> Self` method\nand no implementation of\n[`Default`](https://doc.rust-lang.org/std/default/trait.Default.html),\nwhere the `Default` can be derived by `#[derive(Default)]`.", + "Why is this bad": "The user might expect to be able to use\n[`Default`](https://doc.rust-lang.org/std/default/trait.Default.html) as the\ntype can be constructed without arguments.", + "Example": "```rust,ignore\nstruct Foo;\nimpl Foo {\n fn new() -> Self {\n Foo\n }\n}\n```\nJust prepend `#[derive(Default)]` before the `struct` definition.", + "Known problems": "Hopefully none." + }, + "id": "new_without_default_derive", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for boolean expressions that contain terminals that\ncan be eliminated.", + "Why is this bad": "This is most likely a logic bug.", + "Example": "```rust\nif a && b || a { ... }\n```\nThe `b` is unnecessary, the expression is equivalent to `if a`.", + "Known problems": "Ignores short circuiting behavior." + }, + "id": "logic_bug", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for duplicate open options as well as combinations\nthat make no sense.", + "Why is this bad": "In the best case, the code will be harder to read than\nnecessary. I don't know the worst case.", + "Example": "```rust\nOpenOptions::new().read(true).truncate(true)\n```", + "Known problems": "None." + }, + "id": "nonsensical_open_options", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for transmutes from a pointer to a reference.", + "Why is this bad": "This can always be rewritten with `&` and `*`.", + "Example": "```rust\nlet _: &T = std::mem::transmute(p); // where p: *const T\n// can be written:\nlet _: &T = &*p;\n```", + "Known problems": "None." + }, + "id": "transmute_ptr_to_ref", + "level": "Warn" + }, + { + "docs": { + "What it does": "Catch casts from `0` to some pointer type", + "Why is this bad": "This generally means `null` and is better expressed as\n{`std`, `core`}`::ptr::`{`null`, `null_mut`}.", + "Example": "```rust\n0 as *const u32\n```", + "Known problems": "None." + }, + "id": "zero_ptr", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for usage of `.chars().next()` on a `str` to check\nif it starts with a given char.", + "Why is this bad": "Readability, this can be written more concisely as\n`_.starts_with(_)`.", + "Example": "```rust\nname.chars().next() == Some('_')\n```", + "Known problems": "None." + }, + "id": "chars_next_cmp", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for usages of `Mutex` where an atomic will do.", + "Why is this bad": "Using a mutex just to make access to a plain bool or\nreference sequential is shooting flies with cannons.\n`std::atomic::AtomicBool` and `std::atomic::AtomicPtr` are leaner and\nfaster.", + "Example": "```rust\nlet x = Mutex::new(&y);\n```", + "Known problems": "This lint cannot detect if the mutex is actually used\nfor waiting before a critical section." + }, + "id": "mutex_atomic", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for use of `.skip(x).next()` on iterators.", + "Why is this bad": "`.nth(x)` is cleaner", + "Example": "```rust\nlet some_vec = vec![0, 1, 2, 3];\nlet bad_vec = some_vec.iter().skip(3).next();\nlet bad_slice = &some_vec[..].iter().skip(3).next();\n```\nThe correct use would be:\n```rust\nlet some_vec = vec![0, 1, 2, 3];\nlet bad_vec = some_vec.iter().nth(3);\nlet bad_slice = &some_vec[..].iter().nth(3);\n```", + "Known problems": "None." + }, + "id": "iter_skip_next", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for usage of `Box` where an unboxed `T` would\nwork fine.", + "Why is this bad": "This is an unnecessary allocation, and bad for\nperformance. It is only necessary to allocate if you wish to move the box\ninto something.", + "Example": "```rust\nfn main() {\n let x = Box::new(1);\n foo(*x);\n println!(\"{}\", *x);\n}\n```", + "Known problems": "None." + }, + "id": "boxed_local", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for `foo = bar; bar = foo` sequences.", + "Why is this bad": "This looks like a failed attempt to swap.", + "Example": "```rust,ignore\na = b;\nb = a;\n```", + "Known problems": "None." + }, + "id": "almost_swapped", + "level": "Warn" + }, + { + "docs": { + "What it does": "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.", + "Why is this bad": "This could lead to unexpected results.", + "Example": "```rust,ignore\nlet a = &[\n -1, -2, -3 // <= no comma here\n -4, -5, -6\n];\n```", + "Known problems": "None." + }, + "id": "possible_missing_comma", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for usages of `Mutex` where `X` is an integral type.", + "Why is this bad": "Using a mutex just to make access to a plain integer sequential is\nshooting flies with cannons. `std::atomic::usize` is leaner and faster.", + "Example": "```rust\nlet x = Mutex::new(0usize);\n```", + "Known problems": "This lint cannot detect if the mutex is actually used\nfor waiting before a critical section." + }, + "id": "mutex_integer", + "level": "Allow" + }, + { + "docs": { + "What it does": "Checks for string appends of the form `x = x + y` (without\n`let`!).", + "Why is this bad": "It's not really bad, but some people think that the\n`.push_str(_)` method is more readable.", + "Example": "```rust\nlet mut x = \"Hello\".to_owned();\nx = x + \", World\";\n```", + "Known problems": "None." + }, + "id": "string_add_assign", + "level": "Allow" + }, + { + "docs": { + "What it does": "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.", + "Why is this bad": "Name shadowing can hurt readability, especially in\nlarge code bases, because it is easy to lose track of the active binding at\nany place in the code. This can be alleviated by either giving more specific\nnames to bindings ore introducing more scopes to contain the bindings.", + "Example": "```rust\nlet x = y; let x = z; // shadows the earlier binding\n```", + "Known problems": "This lint, as the other shadowing related lints,\ncurrently only catches very simple patterns." + }, + "id": "shadow_unrelated", + "level": "Allow" + }, + { + "docs": { + "What it does": "Checks for function arguments and let bindings denoted as `ref`.", + "Why is this bad": "The `ref` declaration makes the function take an owned\nvalue, but turns the argument into a reference (which means that the value\nis destroyed when exiting the function). This adds not much value: either\ntake a reference type, or take an owned value and create references in the\nbody.\nFor let bindings, `let x = &foo;` is preferred over `let ref x = foo`. The\ntype of `x` is more obvious with the former.", + "Example": "```rust\nfn foo(ref x: u8) -> bool { .. }\n```", + "Known problems": "If the argument is dereferenced within the function,\nremoving the `ref` will lead to errors. This can be fixed by removing the\ndereferences, e.g. changing `*x` to `x` within the function." + }, + "id": "toplevel_ref_arg", + "level": "Warn" + }, + { + "docs": { + "What it does": "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.", + "Why is this bad": "Possibly surprising results. You can activate this lint\nas a one-time check to see where numerical wrapping can arise.", + "Example": "```rust\nlet y: i8 = -1;\ny as u128 // will return 18446744073709551615\n```", + "Known problems": "None." + }, + "id": "cast_sign_loss", + "level": "Allow" + }, + { + "docs": { + "What it does": "Checks for usage of `regex!(_)` which (as of now) is\nusually slower than `Regex::new(_)` unless called in a loop (which is a bad\nidea anyway).", + "Why is this bad": "Performance, at least for now. The macro version is\nlikely to catch up long-term, but for now the dynamic version is faster.", + "Example": "```rust\nregex!(\"foo|bar\")\n```", + "Known problems": "None." + }, + "id": "regex_macro", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for `0.0 / 0.0`.", + "Why is this bad": "It's less readable than `std::f32::NAN` or `std::f64::NAN`.", + "Example": "```rust\n0.0f32 / 0.0\n```", + "Known problems": "None." + }, + "id": "zero_divided_by_zero", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for transmutes between a type `T` and `*T`.", + "Why is this bad": "It's easy to mistakenly transmute between a type and a\npointer to that type.", + "Example": "```rust\ncore::intrinsics::transmute(t)` // where the result type is the same as `*t` or `&t`'s\n```", + "Known problems": "None." + }, + "id": "crosspointer_transmute", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for transmutes that can't ever be correct on any\narchitecture.", + "Why is this bad": "It's basically guaranteed to be undefined behaviour.", + "Example": "```rust\nlet ptr: *const T = core::intrinsics::transmute('x')`\n```", + "Known problems": "When accessing C, users might want to store pointer\nsized objects in `extradata` arguments to save an allocation." + }, + "id": "wrong_transmute", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for `match` with identical arm bodies.", + "Why is this bad": "This is probably a copy & paste error. If arm bodies\nare the same on purpose, you can factor them\n[using `|`](https://doc.rust-lang.org/book/patterns.html#multiple-patterns).", + "Example": "```rust,ignore\nmatch foo {\n Bar => bar(),\n Quz => quz(),\n Baz => bar(), // <= oops\n}\n```\nThis should probably be\n```rust,ignore\nmatch foo {\n Bar => bar(),\n Quz => quz(),\n Baz => baz(), // <= fixed\n}\n```\nor if the original code was not a typo:\n```rust,ignore\nmatch foo {\n Bar | Baz => bar(), // <= shows the intent better\n Quz => quz(),\n}\n```", + "Known problems": "False positive possible with order dependent `match`\n(see issue [#860](https://github.com/Manishearth/rust-clippy/issues/860))." + }, + "id": "match_same_arms", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for use of `Box>` anywhere in the code.", + "Why is this bad": "`Vec` already keeps its contents in a separate area on\nthe heap. So if you `Box` it, you just add another level of indirection\nwithout any benefit whatsoever.", + "Example": "```rust\nstruct X {\n values: Box>,\n}\n```", + "Known problems": "None." + }, + "id": "box_vec", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for usage of `std::mem::forget(t)` where `t` is `Drop`.", + "Why is this bad": "`std::mem::forget(t)` prevents `t` from running its\ndestructor, possibly causing leaks.", + "Example": "```rust\nmem::forget(Rc::new(55)))\n```", + "Known problems": "None." + }, + "id": "mem_forget", + "level": "Allow" + }, + { + "docs": { + "What it does": "Checks [regex] creation (with `Regex::new`,\n`RegexBuilder::new` or `RegexSet::new`) for correct regex syntax.\n[regex]: https://crates.io/crates/regex", + "Why is this bad": "This will lead to a runtime panic.", + "Example": "```rust\nRegex::new(\"|\")\n```", + "Known problems": "None." + }, + "id": "invalid_regex", + "level": "Deny" + }, + { + "docs": { + "What it does": "Detects enumeration variants that are prefixed or suffixed\nby the same characters.", + "Why is this bad": "Enumeration variant names should specify their variant,\nnot repeat the enumeration name.", + "Example": "```rust\nenum Cake {\n BlackForestCake,\n HummingbirdCake,\n}\n```", + "Known problems": "None." + }, + "id": "pub_enum_variant_names", + "level": "Allow" + }, + { + "docs": { + "What it does": "Checks for use of `.get().unwrap()` (or\n`.get_mut().unwrap`) on a standard library type which implements `Index`", + "Why is this bad": "Using the Index trait (`[]`) is more clear and more\nconcise.", + "Example": "```rust\nlet some_vec = vec![0, 1, 2, 3];\nlet last = some_vec.get(3).unwrap();\n*some_vec.get_mut(0).unwrap() = 1;\n```\nThe correct use would be:\n```rust\nlet some_vec = vec![0, 1, 2, 3];\nlet last = some_vec[3];\nsome_vec[0] = 1;\n```", + "Known problems": "None." + }, + "id": "get_unwrap", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for mis-uses of the serde API.", + "Why is this bad": "Serde is very finnicky about how its API should be\nused, but the type system can't be used to enforce it (yet).", + "Example": "Implementing `Visitor::visit_string` but not `Visitor::visit_str`.", + "Known problems": "None." + }, + "id": "serde_api_misuse", + "level": "Warn" + }, + { + "docs": { + "What it does": "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.", + "Why is this bad": "Needlessly creating a closure adds code for no benefit\nand gives the optimizer more work.", + "Example": "```rust\nxs.map(|x| foo(x))\n```\nwhere `foo(_)` is a plain function that takes the exact argument type of `x`.", + "Known problems": "None." + }, + "id": "redundant_closure", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for equal operands to comparison, logical and\nbitwise, difference and division binary operators (`==`, `>`, etc., `&&`,\n`||`, `&`, `|`, `^`, `-` and `/`).", + "Why is this bad": "This is usually just a typo or a copy and paste error.", + "Example": "```rust\nx + 1 == x + 1\n```", + "Known problems": "False negatives: We had some false positives regarding\ncalls (notably [racer](https://github.com/phildawes/racer) had one instance\nof `x.pop() && x.pop()`), so we removed matching any function or method\ncalls. We may introduce a whitelist of known pure functions in the future." + }, + "id": "eq_op", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for zipping a collection with the range of `0.._.len()`.", + "Why is this bad": "The code is better expressed with `.enumerate()`.", + "Example": "```rust\nx.iter().zip(0..x.len())\n```", + "Known problems": "None." + }, + "id": "range_zip_with_len", + "level": "Warn" + }, + { + "docs": { + "What it does": "Nothing. This lint has been deprecated.", + "Deprecation reason": "This used to check for `Vec::as_mut_slice`, which was unstable with good\nstable alternatives. `Vec::as_mut_slice` has now been stabilized." + }, + "id": "unstable_as_mut_slice", + "level": "Deprecated" + }, + { + "docs": { + "What it does": "Checks for useless borrowed references.", + "Why is this bad": "It is completely useless and make the code look more complex than it\nactually is.", + "Example": "```rust\n let mut v = Vec::::new();\n let _ = v.iter_mut().filter(|&ref a| a.is_empty());\n```\nThis clojure takes a reference on something that has been matched as a reference and\nde-referenced.\nAs such, it could just be |a| a.is_empty()", + "Known problems": "None." + }, + "id": "needless_borrowed_reference", + "level": "Warn" + }, + { + "docs": { + "What it does": "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.", + "Why is this bad": "It just makes the code less readable. That reference\ndestructuring adds nothing to the code.", + "Example": "```rust\nmatch x {\n &A(ref y) => foo(y),\n &B => bar(),\n _ => frob(&x),\n}\n```", + "Known problems": "None." + }, + "id": "match_ref_pats", + "level": "Warn" + }, + { + "docs": { + "What it does": "This is the same as\n[`wrong_self_convention`](#wrong_self_convention), but for public items.", + "Why is this bad": "See [`wrong_self_convention`](#wrong_self_convention).", + "Example": "```rust\nimpl X {\n pub fn as_str(self) -> &str { .. }\n}\n```", + "Known problems": "Actually *renaming* the function may break clients if\nthe function is part of the public interface. In that case, be mindful of\nthe stability guarantees you've given your users." + }, + "id": "wrong_pub_self_convention", + "level": "Allow" + }, + { + "docs": { + "What it does": "This lint checks for function arguments of type `&String` or `&Vec` unless\nthe references are mutable.", + "Why is this bad": "Requiring the argument to be of the specific size makes the function less\nuseful for no benefit; slices in the form of `&[T]` or `&str` usually suffice and can be\nobtained from other types, too.", + "Example": "```rust\nfn foo(&Vec) { .. }\n```", + "Known problems": "None." + }, + "id": "ptr_arg", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for deriving `Hash` but implementing `PartialEq`\nexplicitly.", + "Why is this bad": "The implementation of these traits must agree (for\nexample for use with `HashMap`) so it\u2019s probably a bad idea to use a\ndefault-generated `Hash` implementation with an explicitly defined\n`PartialEq`. In particular, the following must hold for any type:\n```rust\nk1 == k2 \u21d2 hash(k1) == hash(k2)\n```", + "Example": "```rust\n#[derive(Hash)]\nstruct Foo;\nimpl PartialEq for Foo {\n ...\n}\n```", + "Known problems": "None." + }, + "id": "derive_hash_xor_eq", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for `extern crate` and `use` items annotated with lint attributes", + "Why is this bad": "Lint attributes have no effect on crate imports. Most likely a `!` was\nforgotten", + "Example": "```rust\n#[deny(dead_code)]\nextern crate foo;\n#[allow(unused_import)]\nuse foo::bar;\n```", + "Known problems": "Technically one might allow `unused_import` on a `use` item,\nbut it's easier to remove the unused item." + }, + "id": "useless_attribute", + "level": "Warn" + }, + { + "docs": { + "What it does": "Nothing. This lint has been deprecated.", + "Deprecation reason": "This used to check for `.to_string()` method calls on values\nof type `String`. This is not unidiomatic and with specialization coming, `to_string` could be\nspecialized to be as efficient as `clone`." + }, + "id": "string_to_string", + "level": "Deprecated" + }, + { + "docs": { + "What it does": "Checks for lifetimes in generics that are never used\nanywhere else.", + "Why is this bad": "The additional lifetimes make the code look more\ncomplicated, while there is nothing out of the ordinary going on. Removing\nthem leads to more readable code.", + "Example": "```rust\nfn unused_lifetime<'a>(x: u8) { .. }\n```", + "Known problems": "None." + }, + "id": "unused_lifetimes", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for usage of indexing or slicing.", + "Why is this bad": "Usually, this can be safely allowed. However, in some\ndomains such as kernel development, a panic can cause the whole operating\nsystem to crash.", + "Example": "```rust\n...\nx[2];\n&x[0..2];\n```", + "Known problems": "Hopefully none." + }, + "id": "indexing_slicing", + "level": "Allow" + }, + { + "docs": { + "What it does": "Checks for string methods that receive a single-character\n`str` as an argument, e.g. `_.split(\"x\")`.", + "Why is this bad": "Performing these methods using a `char` is faster than\nusing a `str`.", + "Example": "`_.split(\"x\")` could be `_.split('x')", + "Known problems": "Does not catch multi-byte unicode characters." + }, + "id": "single_char_pattern", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for lifetime annotations which can be removed by\nrelying on lifetime elision.", + "Why is this bad": "The additional lifetimes make the code look more\ncomplicated, while there is nothing out of the ordinary going on. Removing\nthem leads to more readable code.", + "Example": "```rust\nfn in_and_out<'a>(x: &'a u8, y: u8) -> &'a u8 { x }\n```", + "Known problems": "Potential false negatives: we bail out if the function\nhas a `where` clause where lifetimes are mentioned." + }, + "id": "needless_lifetimes", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for printing on *stdout*. The purpose of this lint\nis to catch debugging remnants.", + "Why is this bad": "People often print on *stdout* while debugging an\napplication and might forget to remove those prints afterward.", + "Example": "```rust\nprintln!(\"Hello world!\");\n```", + "Known problems": "Only catches `print!` and `println!` calls." + }, + "id": "print_stdout", + "level": "Allow" + }, + { + "docs": { + "What it does": "Checks for the use of short circuit boolean conditions as a\nstatement.", + "Why is this bad": "Using a short circuit boolean condition as a statement may\nhide the fact that the second part is executed or not depending on the outcome of\nthe first part.", + "Example": "```rust\nf() && g(); // We should write `if f() { g(); }`.\n```", + "Known problems": "None." + }, + "id": "short_circuit_statement", + "level": "Warn" + }, + { + "docs": { + "What it does": "Nothing. This lint has been deprecated.", + "Deprecation reason": "This used to check for `Vec::as_slice`, which was unstable with good\nstable alternatives. `Vec::as_slice` has now been stabilized." + }, + "id": "unstable_as_slice", + "level": "Deprecated" + }, + { + "docs": { + "What it does": "Detects enumeration variants that are prefixed or suffixed\nby the same characters.", + "Why is this bad": "Enumeration variant names should specify their variant,\nnot repeat the enumeration name.", + "Example": "```rust\nenum Cake {\n BlackForestCake,\n HummingbirdCake,\n}\n```", + "Known problems": "None." + }, + "id": "enum_variant_names", + "level": "Warn" + }, + { + "docs": { + "What it does": "Detects `loop + match` combinations that are easier\nwritten as a `while let` loop.", + "Why is this bad": "The `while let` loop is usually shorter and more readable.", + "Example": "```rust\nloop {\n let x = match y {\n Some(x) => x,\n None => break,\n }\n // .. do something with x\n}\n// is easier written as\nwhile let Some(x) = y {\n // .. do something with x\n}\n```", + "Known problems": "Sometimes the wrong binding is displayed (#383)." + }, + "id": "while_let_loop", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for `a = a op b` or `a = b commutative_op a` patterns.", + "Why is this bad": "These can be written as the shorter `a op= b`.", + "Example": "```rust\nlet mut a = 5;\n...\na = a + b;\n```", + "Known problems": "While forbidden by the spec, `OpAssign` traits may have\nimplementations that differ from the regular `Op` impl." + }, + "id": "assign_op_pattern", + "level": "Warn" + }, + { + "docs": { + "What it does": "Warns on hexadecimal literals with mixed-case letter digits.", + "Why is this bad": "It looks confusing.", + "Example": "```rust\nlet y = 0x1a9BAcD;\n```", + "Known problems": "None." + }, + "id": "mixed_case_hex_literals", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for usage of `_.map(_).unwrap_or_else(_)`.", + "Why is this bad": "Readability, this can be written more concisely as\n`_.map_or_else(_, _)`.", + "Example": "```rust\nx.map(|a| a + 1).unwrap_or_else(some_function)\n```", + "Known problems": "None." + }, + "id": "option_map_unwrap_or_else", + "level": "Allow" + }, + { + "docs": { + "What it does": "Checks for items declared after some statement in a block.", + "Why is this bad": "Items live for the entire scope they are declared\nin. But statements are processed in order. This might cause confusion as\nit's hard to figure out which item is meant in a statement.", + "Example": "```rust\nfn foo() {\n println!(\"cake\");\n}\nfn main() {\n foo(); // prints \"foo\"\n fn foo() {\n println!(\"foo\");\n }\n foo(); // prints \"foo\"\n}\n```", + "Known problems": "None." + }, + "id": "items_after_statements", + "level": "Allow" + }, + { + "docs": { + "What it does": "Checks for methods with certain name prefixes and which\ndoesn't match how self is taken. The actual rules are:\n|Prefix |`self` taken |\n|-------|----------------------|\n|`as_` |`&self` or `&mut self`|\n|`from_`| none |\n|`into_`|`self` |\n|`is_` |`&self` or none |\n|`to_` |`&self` |", + "Why is this bad": "Consistency breeds readability. If you follow the\nconventions, your users won't be surprised that they, e.g., need to supply a\nmutable reference to a `as_..` function.", + "Example": "```rust\nimpl X {\n fn as_str(self) -> &str { .. }\n}\n```", + "Known problems": "None." + }, + "id": "wrong_self_convention", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for usage of blacklisted names for variables, such\nas `foo`.", + "Why is this bad": "These names are usually placeholder names and should be\navoided.", + "Example": "```rust\nlet foo = 3.14;\n```", + "Known problems": "None." + }, + "id": "blacklisted_name", + "level": "Warn" + }, + { + "docs": { + "What it does": "Detects expressions of the form `--x`.", + "Why is this bad": "It can mislead C/C++ programmers to think `x` was\ndecremented.", + "Example": "```rust\n--x;\n```", + "Known problems": "None." + }, + "id": "double_neg", + "level": "Warn" + }, + { + "docs": { + "What it does": "Nothing. This lint has been deprecated.", + "Deprecation reason": "This used to check for `Vec::extend`, which was slower than\n`Vec::extend_from_slice`. Thanks to specialization, this is no longer true." + }, + "id": "extend_from_slice", + "level": "Deprecated" + }, + { + "docs": { + "What it does": "Checks for comparisons to unit.", + "Why is this bad": "Unit is always equal to itself, and thus is just a\nclumsily written constant. Mostly this happens when someone accidentally\nadds semicolons at the end of the operands.", + "Example": "```rust\nif { foo(); } == { bar(); } { baz(); }\n```\nis equal to\n```rust\n{ foo(); bar(); baz(); }\n```", + "Known problems": "None." + }, + "id": "unit_cmp", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for binding a unit value.", + "Why is this bad": "A unit value cannot usefully be used anywhere. So\nbinding one is kind of pointless.", + "Example": "```rust\nlet x = { 1; };\n```", + "Known problems": "None." + }, + "id": "let_unit_value", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for float arithmetic.", + "Why is this bad": "For some embedded systems or kernel development, it\ncan be useful to rule out floating-point numbers.", + "Example": "```rust\na + 1.0\n```", + "Known problems": "None." + }, + "id": "float_arithmetic", + "level": "Allow" + }, + { + "docs": { + "What it does": "Checks for `enum`s with no variants.", + "Why is this bad": "Enum's with no variants should be replaced with `!`, the uninhabited type,\nor a wrapper around it.", + "Example": "```rust\nenum Test {}\n```", + "Known problems": "None." + }, + "id": "empty_enum", + "level": "Allow" + }, + { + "docs": { + "What it does": "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.", + "Why is this bad": "Having explicit `else` blocks for `if` statements\ncontaining `continue` in their THEN branch adds unnecessary branching and\nnesting to the code. Having an else block containing just `continue` can\nalso be better written by grouping the statements following the whole `if`\nstatement within the THEN block and omitting the else block completely.", + "Example": "```rust\nwhile condition() {\n update_condition();\n if x {\n // ...\n } else {\n continue;\n }\n println!(\"Hello, world\");\n}\n```\nCould be rewritten as\n```rust\nwhile condition() {\n update_condition();\n if x {\n // ...\n println!(\"Hello, world\");\n }\n}\n```\nAs another example, the following code\n```rust\nloop {\n if waiting() {\n continue;\n } else {\n // Do something useful\n }\n}\n```\nCould be rewritten as\n```rust\nloop {\n if waiting() {\n continue;\n }\n // Do something useful\n}\n```", + "Known problems": "None" + }, + "id": "needless_continue", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for overlapping match arms.", + "Why is this bad": "It is likely to be an error and if not, makes the code\nless obvious.", + "Example": "```rust\nlet x = 5;\nmatch x {\n 1 ... 10 => println!(\"1 ... 10\"),\n 5 ... 15 => println!(\"5 ... 15\"),\n _ => (),\n}\n```", + "Known problems": "None." + }, + "id": "match_overlapping_arm", + "level": "Warn" + }, + { + "docs": { + "What it does": "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.", + "Why is this bad": "It's not bad in and of itself. However, this particular\n`Add` implementation is asymmetric (the other operand need not be `String`,\nbut `x` does), while addition as mathematically defined is symmetric, also\nthe `String::push_str(_)` function is a perfectly good replacement.\nTherefore some dislike it and wish not to have it in their code.\nThat said, other people think that string addition, having a long tradition\nin other languages is actually fine, which is why we decided to make this\nparticular lint `allow` by default.", + "Example": "```rust\nlet x = \"Hello\".to_owned();\nx + \", World\"\n```", + "Known problems": "None." + }, + "id": "string_add", + "level": "Allow" + }, + { + "docs": { + "What it does": "Checks for expression statements that can be reduced to a\nsub-expression.", + "Why is this bad": "Expressions by themselves often have no side-effects.\nHaving such expressions reduces readability.", + "Example": "```rust\ncompute_array()[0];\n```", + "Known problems": "None." + }, + "id": "unnecessary_operation", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for methods with high cyclomatic complexity.", + "Why is this bad": "Methods of high cyclomatic complexity tend to be badly\nreadable. Also LLVM will usually optimize small methods better.", + "Example": "No. You'll see it when you get the warning.", + "Known problems": "Sometimes it's hard to find a way to reduce the complexity." + }, + "id": "cyclomatic_complexity", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for function arguments having the similar names\ndiffering by an underscore.", + "Why is this bad": "It affects code readability.", + "Example": "```rust\nfn foo(a: i32, _a: i32) {}\n```", + "Known problems": "None." + }, + "id": "duplicate_underscore_argument", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for expressions where `std::cmp::min` and `max` are\nused to clamp values, but switched so that the result is constant.", + "Why is this bad": "This is in all probability not the intended outcome. At\nthe least it hurts readability of the code.", + "Example": "```rust\nmin(0, max(100, x))\n```\nIt will always be equal to `0`. Probably the author meant to clamp the value\nbetween 0 and 100, but has erroneously swapped `min` and `max`.", + "Known problems": "None" + }, + "id": "min_max", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for usage of `&vec![..]` when using `&[..]` would\nbe possible.", + "Why is this bad": "This is less efficient.", + "Example": "```rust,ignore\nfoo(&vec![1, 2])\n```", + "Known problems": "None." + }, + "id": "useless_vec", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for missing parameters in `panic!`.", + "Why is this bad": "Contrary to the `format!` family of macros, there are\ntwo forms of `panic!`: if there are no parameters given, the first argument\nis not a format string and used literally. So while `format!(\"{}\")` will\nfail to compile, `panic!(\"{}\")` will not.", + "Example": "```rust\npanic!(\"This `panic!` is probably missing a parameter there: {}\");\n```", + "Known problems": "Should you want to use curly brackets in `panic!`\nwithout any parameter, this lint will warn." + }, + "id": "panic_params", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for `while let` expressions on iterators.", + "Why is this bad": "Readability. A simple `for` loop is shorter and conveys\nthe intent better.", + "Example": "```rust\nwhile let Some(val) = iter() { .. }\n```", + "Known problems": "None." + }, + "id": "while_let_on_iterator", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for the presence of `_`, `::` or camel-case words\noutside ticks in documentation.", + "Why is this bad": "*Rustdoc* supports markdown formatting, `_`, `::` and\ncamel-case probably indicates some code which should be included between\nticks. `_` can also be used for empasis in markdown, this lint tries to\nconsider that.", + "Examples": "```rust\n/// Do something with the foo_bar parameter. See also that::other::module::foo.\n// ^ `foo_bar` and `that::other::module::foo` should be ticked.\nfn doit(foo_bar) { .. }\n```", + "Known problems": "Lots of bad docs won\u2019t be fixed, what the lint checks\nfor is limited, and there are still false positives." + }, + "id": "doc_markdown", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for `if` conditions that use blocks containing\nstatements, or conditions that use closures with blocks.", + "Why is this bad": "Using blocks in the condition makes it hard to read.", + "Example": "```rust\nif { let x = somefunc(); x } ..\n// or\nif somefunc(|x| { x == 47 }) ..\n```", + "Known problems": "None." + }, + "id": "block_in_if_condition_stmt", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for consecutive `if`s with the same condition.", + "Why is this bad": "This is probably a copy & paste error.", + "Example": "```rust\nif a == b {\n \u2026\n} else if a == b {\n \u2026\n}\n```\nNote that this lint ignores all conditions with a function call as it could\nhave side effects:\n```rust\nif foo() {\n \u2026\n} else if foo() { // not linted\n \u2026\n}\n```", + "Known problems": "Hopefully none." + }, + "id": "ifs_same_cond", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for transmutes to the original type of the object\nand transmutes that could be a cast.", + "Why is this bad": "Readability. The code tricks people into thinking that\nsomething complex is going on.", + "Example": "```rust\ncore::intrinsics::transmute(t) // where the result type is the same as `t`'s\n```", + "Known problems": "None." + }, + "id": "useless_transmute", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for conversions to owned values just for the sake\nof a comparison.", + "Why is this bad": "The comparison can operate on a reference, so creating\nan owned value effectively throws it away directly afterwards, which is\nneedlessly consuming code and heap space.", + "Example": "```rust\nx.to_owned() == y\n```", + "Known problems": "None." + }, + "id": "cmp_owned", + "level": "Warn" + }, + { + "docs": { + "What it does": "Warns if a generic shadows a built-in type.", + "Why is this bad": "This gives surprising type errors.", + "Example": "```rust\nimpl Foo {\n fn impl_func(&self) -> u32 {\n 42\n }\n}\n```", + "Known problems": "None." + }, + "id": "builtin_type_shadow", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for getting the remainder of a division by one.", + "Why is this bad": "The result can only ever be zero. No one will write\nsuch code deliberately, unless trying to win an Underhanded Rust\nContest. Even for that contest, it's probably a bad idea. Use something more\nunderhanded.", + "Example": "```rust\nx % 1\n```", + "Known problems": "None." + }, + "id": "modulo_one", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for manual swapping.", + "Why is this bad": "The `std::mem::swap` function exposes the intent better\nwithout deinitializing or copying either variable.", + "Example": "```rust,ignore\nlet t = b;\nb = a;\na = t;\n```", + "Known problems": "None." + }, + "id": "manual_swap", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for comparisons to NaN.", + "Why is this bad": "NaN does not compare meaningfully to anything \u2013 not\neven itself \u2013 so those comparisons are simply wrong.", + "Example": "```rust\nx == NAN\n```", + "Known problems": "None." + }, + "id": "cmp_nan", + "level": "Deny" + }, + { + "docs": { + "What it does": "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).", + "Why is this bad": "Floating point calculations are usually imprecise, so\nasking if two values are *exactly* equal is asking for trouble. For a good\nguide on what to do, see [the floating point\nguide](http://www.floating-point-gui.de/errors/comparison).", + "Example": "```rust\ny == 1.23f64\ny != x // where both are floats\n```", + "Known problems": "None." + }, + "id": "float_cmp", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for identity operations, e.g. `x + 0`.", + "Why is this bad": "This code can be removed without changing the\nmeaning. So it just obscures what's going on. Delete it mercilessly.", + "Example": "```rust\nx / 1 + 0 * 1 - 0 | 0\n```", + "Known problems": "None." + }, + "id": "identity_op", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for construction of a structure or tuple just to\nassign a value in it.", + "Why is this bad": "Readability. If the structure is only created to be\nupdated, why not write the structure you want in the first place?", + "Example": "```rust\n(0, 0).0 = 1\n```", + "Known problems": "None." + }, + "id": "temporary_assignment", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for multiplication by -1 as a form of negation.", + "Why is this bad": "It's more readable to just negate.", + "Example": "```rust\nx * -1\n```", + "Known problems": "This only catches integers (for now)." + }, + "id": "neg_multiply", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks `for` loops over slices with an explicit counter\nand suggests the use of `.enumerate()`.", + "Why is it bad": "Not only is the version using `.enumerate()` more\nreadable, the compiler is able to remove bounds checks which can lead to\nfaster code in some instances.", + "Example": "```rust\nfor i in 0..v.len() { foo(v[i]);\nfor i in 0..v.len() { bar(i, v[i]); }\n```", + "Known problems": "None." + }, + "id": "explicit_counter_loop", + "level": "Warn" + }, + { + "docs": { + "What it does": "Warns if there is missing doc for any documentable item (public or private).", + "Why is this bad": "Doc is good. *rustc* has a `MISSING_DOCS` allowed-by-default lint for\npublic members, but has no way to enforce documentation of private items. This lint fixes that.", + "Known problems": "None." + }, + "id": "missing_docs_in_private_items", + "level": "Allow" + }, + { + "docs": { + "What it does": "Checks for usage of `*&` and `*&mut` in expressions.", + "Why is this bad": "Immediately dereferencing a reference is no-op and\nmakes the code less clear.", + "Example": "```rust\nlet a = f(*&mut b);\nlet c = *&d;\n```", + "Known problems": "Multiple dereference/addrof pairs are not handled so\nthe suggested fix for `x = **&&y` is `x = *&y`, which is still incorrect." + }, + "id": "deref_addrof", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for needlessly including a base struct on update\nwhen all fields are changed anyway.", + "Why is this bad": "This will cost resources (because the base has to be\nsomewhere), and make the code less readable.", + "Example": "```rust\nPoint { x: 1, y: 0, ..zero_point }\n```", + "Known problems": "None." + }, + "id": "needless_update", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for on casts between numerical types that may\ntruncate large values. This is expected behavior, so the cast is `Allow` by\ndefault.", + "Why is this bad": "In some problem domains, it is good practice to avoid\ntruncation. This lint can be activated to help assess where additional\nchecks could be beneficial.", + "Example": "```rust\nfn as_u8(x: u64) -> u8 { x as u8 }\n```", + "Known problems": "None." + }, + "id": "cast_possible_truncation", + "level": "Allow" + }, + { + "docs": { + "What it does": "Checks for an iterator search (such as `find()`,\n`position()`, or `rposition()`) followed by a call to `is_some()`.", + "Why is this bad": "Readability, this can be written more concisely as\n`_.any(_)`.", + "Example": "```rust\niter.find(|x| x == 0).is_some()\n```", + "Known problems": "None." + }, + "id": "search_is_some", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for the use of `format!(\"string literal with no\nargument\")` and `format!(\"{}\", foo)` where `foo` is a string.", + "Why is this bad": "There is no point of doing that. `format!(\"too\")` can\nbe replaced by `\"foo\".to_owned()` if you really need a `String`. The even\nworse `&format!(\"foo\")` is often encountered in the wild. `format!(\"{}\",\nfoo)` can be replaced by `foo.clone()` if `foo: String` or `foo.to_owned()`\nif `foo: &str`.", + "Examples": "```rust\nformat!(\"foo\")\nformat!(\"{}\", foo)\n```", + "Known problems": "None." + }, + "id": "useless_format", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for plain integer arithmetic.", + "Why is this bad": "This is only checked against overflow in debug builds.\nIn some applications one wants explicitly checked, wrapping or saturating\narithmetic.", + "Example": "```rust\na + 1\n```", + "Known problems": "None." + }, + "id": "integer_arithmetic", + "level": "Allow" + }, + { + "docs": { + "What it does": "Checks for loops on `x.iter()` where `&x` will do, and\nsuggests the latter.", + "Why is this bad": "Readability.", + "Example": "```rust\n// with `y` a `Vec` or slice:\nfor x in y.iter() { .. }\n```", + "Known problems": "False negatives. We currently only warn on some known\ntypes." + }, + "id": "explicit_iter_loop", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for bindings that shadow other bindings already in\nscope, while just changing reference level or mutability.", + "Why is this bad": "Not much, in fact it's a very common pattern in Rust\ncode. Still, some may opt to avoid it in their code base, they can set this\nlint to `Warn`.", + "Example": "```rust\nlet x = &x;\n```", + "Known problems": "This lint, as the other shadowing related lints,\ncurrently only catches very simple patterns." + }, + "id": "shadow_same", + "level": "Allow" + }, + { + "docs": { + "What it does": "Checks for diverging calls that are not match arms or statements.", + "Why is this bad": "It is often confusing to read. In addition, the\nsub-expression evaluation order for Rust is not well documented.", + "Example": "```rust\nlet a = b() || panic!() || c();\n// `c()` is dead, `panic!()` is only called if `b()` returns `false`\nlet x = (a, b, c, panic!());\n// can simply be replaced by `panic!()`\n```", + "Known problems": "Someone might want to use `some_bool || panic!()` as a shorthand." + }, + "id": "diverging_sub_expression", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for use of `Debug` formatting. The purpose of this\nlint is to catch debugging remnants.", + "Why is this bad": "The purpose of the `Debug` trait is to facilitate\ndebugging Rust code. It should not be used in in user-facing output.", + "Example": "```rust\nprintln!(\"{:?}\", foo);\n```" + }, + "id": "use_debug", + "level": "Allow" + }, + { + "docs": { + "What it does": "Checks for matches with a single arm where an `if let`\nwill usually suffice.", + "Why is this bad": "Just readability \u2013 `if let` nests less than a `match`.", + "Example": "```rust\nmatch x {\n Some(ref foo) => bar(foo),\n _ => ()\n}\n```", + "Known problems": "None." + }, + "id": "single_match", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for arguments to `==` which have their address taken to satisfy a bound\nand suggests to dereference the other argument instead", + "Why is this bad": "It is more idiomatic to dereference the other argument.", + "Example": "```rust\n&x == y\n```", + "Known problems": "None" + }, + "id": "op_ref", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for iterating a map (`HashMap` or `BTreeMap`) and\nignoring either the keys or values.", + "Why is this bad": "Readability. There are `keys` and `values` methods that\ncan be used to express that don't need the values or keys.", + "Example": "```rust\nfor (k, _) in &map { .. }\n```\ncould be replaced by\n```rust\nfor k in map.keys() { .. }\n```", + "Known problems": "None." + }, + "id": "for_kv_map", + "level": "Warn" + }, + { + "docs": { + "What it does": "This lint warns when you using `print!()` with a format string that\nends in a newline.", + "Why is this bad": "You should use `println!()` instead, which appends the newline.", + "Example": "```rust\nprint!(\"Hello {}!\\n\", name);\n```", + "Known problems": "None." + }, + "id": "print_with_newline", + "level": "Warn" + }, + { + "docs": { + "What it does": "* Checks for unnecessary `ok()` in if let.", + "Why is this bad": "Calling `ok()` in if let is unnecessary, instead match on `Ok(pat)`", + "Example": "```rust\nfor result in iter {\n if let Some(bench) = try!(result).parse().ok() {\n vec.push(bench)\n }\n}\n```\nCould be written:\n```rust\nfor result in iter {\n if let Ok(bench) = try!(result).parse() {\n vec.push(bench)\n }\n}\n```", + "Known problems": "None." + }, + "id": "if_let_some_result", + "level": "Warn" + }, + { + "docs": { + "What it does": "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.", + "Why is this bad": "An expression like `let x : u8 = ...; (x as u32) > 300`\nwill mistakenly imply that it is possible for `x` to be outside the range of\n`u8`.", + "Example": "```rust\nlet x : u8 = ...; (x as u32) > 300\n```", + "Known problems": "https://github.com/Manishearth/rust-clippy/issues/886" + }, + "id": "invalid_upcast_comparisons", + "level": "Allow" + }, + { + "docs": { + "What it does": "Checks for use of `.iter().nth()` (and the related\n`.iter_mut().nth()`) on standard library types with O(1) element access.", + "Why is this bad": "`.get()` and `.get_mut()` are more efficient and more\nreadable.", + "Example": "```rust\nlet some_vec = vec![0, 1, 2, 3];\nlet bad_vec = some_vec.iter().nth(3);\nlet bad_slice = &some_vec[..].iter().nth(3);\n```\nThe correct use would be:\n```rust\nlet some_vec = vec![0, 1, 2, 3];\nlet bad_vec = some_vec.get(3);\nlet bad_slice = &some_vec[..].get(3);\n```", + "Known problems": "None." + }, + "id": "iter_nth", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for nested `if` statements which can be collapsed\nby `&&`-combining their conditions and for `else { if ... }` expressions that\ncan be collapsed to `else if ...`.", + "Why is this bad": "Each `if`-statement adds one level of nesting, which\nmakes code look more complex than it really is.", + "Example": "```rust,ignore\nif x {\n if y {\n \u2026\n }\n}\n// or\nif x {\n \u2026\n} else {\n if y {\n \u2026\n }\n}\n```\nShould be written:\n```rust.ignore\nif x && y {\n \u2026\n}\n// or\nif x {\n \u2026\n} else if y {\n \u2026\n}\n```", + "Known problems": "None." + }, + "id": "collapsible_if", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for items that implement `.len()` but not\n`.is_empty()`.", + "Why is this bad": "It is good custom to have both methods, because for\nsome data structures, asking about the length will be a costly operation,\nwhereas `.is_empty()` can usually answer in constant time. Also it used to\nlead to false positives on the [`len_zero`](#len_zero) lint \u2013 currently that\nlint will ignore such entities.", + "Example": "```rust\nimpl X {\n pub fn len(&self) -> usize { .. }\n}\n```", + "Known problems": "None." + }, + "id": "len_without_is_empty", + "level": "Warn" + }, + { + "docs": { + "What it does": "Warns if literal suffixes are not separated by an underscore.", + "Why is this bad": "It is much less readable.", + "Example": "```rust\nlet y = 123832i32;\n```", + "Known problems": "None." + }, + "id": "unseparated_literal_suffix", + "level": "Allow" + }, + { + "docs": { + "What it does": "Detects giving a mutable reference to a function that only\nrequires an immutable reference.", + "Why is this bad": "The immutable reference rules out all other references\nto the value. Also the code misleads about the intent of the call site.", + "Example": "```rust\nmy_vec.push(&mut value)\n```", + "Known problems": "None." + }, + "id": "unnecessary_mut_passed", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for variable declarations immediately followed by a\nconditional affectation.", + "Why is this bad": "This is not idiomatic Rust.", + "Example": "```rust,ignore\nlet foo;\nif bar() {\n foo = 42;\n} else {\n foo = 0;\n}\nlet mut baz = None;\nif bar() {\n baz = Some(42);\n}\n```\nshould be written\n```rust,ignore\nlet foo = if bar() {\n 42\n} else {\n 0\n};\nlet baz = if bar() {\n Some(42)\n} else {\n None\n};\n```", + "Known problems": "None." + }, + "id": "useless_let_if_seq", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for boolean expressions that can be written more\nconcisely.", + "Why is this bad": "Readability of boolean expressions suffers from\nunnecessary duplication.", + "Example": "```rust\nif a && true // should be: if a\nif !(a == b) // should be: if a != b\n```", + "Known problems": "Ignores short circuiting behavior of `||` and\n`&&`. Ignores `|`, `&` and `^`." + }, + "id": "nonminimal_bool", + "level": "Allow" + }, + { + "docs": { + "What it does": "Checks for `new` not returning `Self`.", + "Why is this bad": "As a convention, `new` methods are used to make a new\ninstance of a type.", + "Example": "```rust\nimpl Foo {\n fn new(..) -> NotAFoo {\n }\n}\n```", + "Known problems": "None." + }, + "id": "new_ret_no_self", + "level": "Warn" + }, + { + "docs": { + "What it does": "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.", + "Why is this bad": "Usually, the definition in the standard library is more\nprecise than what people come up with. If you find that your definition is\nactually more precise, please [file a Rust\nissue](https://github.com/rust-lang/rust/issues).", + "Example": "```rust\nlet x = 3.14;\n```", + "Known problems": "If you happen to have a value that is within 1/8192 of a\nknown constant, but is not *and should not* be the same, this lint will\nreport your value anyway. We have not yet noticed any false positives in\ncode we tested clippy with (this includes servo), but YMMV." + }, + "id": "approx_constant", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for uses of `contains_key` + `insert` on `HashMap`\nor `BTreeMap`.", + "Why is this bad": "Using `entry` is more efficient.", + "Example": "```rust\nif !m.contains_key(&k) { m.insert(k, v) }\n```\ncan be rewritten as:\n```rust\nm.entry(k).or_insert(v);\n```", + "Known problems": "Some false negatives, eg.:\n```rust\nlet k = &key;\nif !m.contains_key(k) { m.insert(k.clone(), v); }\n```" + }, + "id": "map_entry", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for usage of `!` or `!=` in an if condition with an\nelse branch.", + "Why is this bad": "Negations reduce the readability of statements.", + "Example": "```rust\nif !v.is_empty() {\n a()\n} else {\n b()\n}\n```\nCould be written:\n```rust\nif v.is_empty() {\n b()\n} else {\n a()\n}\n```", + "Known problems": "None." + }, + "id": "if_not_else", + "level": "Allow" + }, + { + "docs": { + "What it does": "Checks for usage of `_.filter(_).map(_)`,\n`_.filter(_).flat_map(_)`, `_.filter_map(_).flat_map(_)` and similar.", + "Why is this bad": "Readability, this can be written more concisely as a\nsingle method call.", + "Example": "```rust\niter.filter(|x| x == 0).map(|x| x * 2)\n```", + "Known problems": "Often requires a condition + Option/Iterator creation\ninside the closure." + }, + "id": "filter_map", + "level": "Allow" + }, + { + "docs": { + "What it does": "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.", + "Why is this bad": "An expression like `min <= x` may misleadingly imply\nthat is is possible for `x` to be less than the minimum. Expressions like\n`max < x` are probably mistakes.", + "Example": "```rust\nvec.len() <= 0\n100 > std::i32::MAX\n```", + "Known problems": "None." + }, + "id": "absurd_extreme_comparisons", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for formatting of `else if`. It lints if the `else`\nand `if` are not on the same line or the `else` seems to be missing.", + "Why is this bad": "This is probably some refactoring remnant, even if the\ncode is correct, it might look confusing.", + "Example": "```rust,ignore\nif foo {\n} if bar { // looks like an `else` is missing here\n}\nif foo {\n} else\nif bar { // this is the `else` block of the previous `if`, but should it be?\n}\n```", + "Known problems": "None." + }, + "id": "suspicious_else_formatting", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for imports that remove \"unsafe\" from an item's\nname.", + "Why is this bad": "Renaming makes it less clear which traits and\nstructures are unsafe.", + "Example": "```rust,ignore\nuse std::cell::{UnsafeCell as TotallySafeCell};\nextern crate crossbeam;\nuse crossbeam::{spawn_unsafe as spawn};\n```", + "Known problems": "None." + }, + "id": "unsafe_removed_from_name", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for expressions of the form `if c { true } else { false }`\n(or vice versa) and suggest using the condition directly.", + "Why is this bad": "Redundant code.", + "Example": "```rust\nif x { false } else { true }\n```", + "Known problems": "Maybe false positives: Sometimes, the two branches are\npainstakingly documented (which we of course do not detect), so they *may*\nhave some value. Even then, the documentation can be rewritten to match the\nshorter code." + }, + "id": "needless_bool", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for `let`-bindings, which are subsequently returned.", + "Why is this bad": "It is just extraneous code. Remove it to make your code\nmore rusty.", + "Example": "```rust\n{ let x = ..; x }\n```", + "Known problems": "None." + }, + "id": "let_and_return", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for return statements at the end of a block.", + "Why is this bad": "Removing the `return` and semicolon will make the code\nmore rusty.", + "Example": "```rust\nfn foo(x: usize) { return x; }\n```", + "Known problems": "None." + }, + "id": "needless_return", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for getting the length of something via `.len()`\njust to compare to zero, and suggests using `.is_empty()` where applicable.", + "Why is this bad": "Some structures can answer `.is_empty()` much faster\nthan calculating their length. So it is good to get into the habit of using\n`.is_empty()`, and having it is cheap. Besides, it makes the intent clearer\nthan a comparison.", + "Example": "```rust\nif x.len() == 0 { .. }\n```", + "Known problems": "None." + }, + "id": "len_zero", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for use of the non-existent `=*`, `=!` and `=-` operators.", + "Why is this bad": "This is either a typo of `*=`, `!=` or `-=` or confusing.", + "Example": "```rust,ignore\na =- 42; // confusing, should it be `a -= 42` or `a = -42`?\n```", + "Known problems": "None." + }, + "id": "suspicious_assignment_formatting", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for `a op= a op b` or `a op= b op a` patterns.", + "Why is this bad": "Most likely these are bugs where one meant to write `a op= b`.", + "Example": "```rust\nlet mut a = 5;\n...\na += a + b;\n```", + "Known problems": "Someone might actually mean `a op= a op b`, but that\nshould rather be written as `a = (2 * a) op b` where applicable." + }, + "id": "misrefactored_assign_op", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for items annotated with `#[inline(always)]`,\nunless the annotated function is empty or simply panics.", + "Why is this bad": "While there are valid uses of this annotation (and once\nyou know when to use it, by all means `allow` this lint), it's a common\nnewbie-mistake to pepper one's code with it.\nAs a rule of thumb, before slapping `#[inline(always)]` on a function,\nmeasure if that additional function call really affects your runtime profile\nsufficiently to make up for the increase in compile time.", + "Example": "```rust\n#[inline(always)]\nfn not_quite_hot_code(..) { ... }\n```", + "Known problems": "False positives, big time. This lint is meant to be\ndeactivated by everyone doing serious performance work. This means having\ndone the measurement." + }, + "id": "inline_always", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for calls to `std::mem::forget` with a value that\nderives the Copy trait", + "Why is this bad": "Calling `std::mem::forget` [does nothing for types that\nimplement Copy](https://doc.rust-lang.org/std/mem/fn.drop.html) since the\nvalue will be copied and moved into the function on invocation.\nAn alternative, but also valid, explanation is that Copy types do not implement\nthe Drop trait, which means they have no destructors. Without a destructor, there\nis nothing for `std::mem::forget` to ignore.", + "Example": "```rust\nlet x:i32 = 42; // i32 implements Copy\nstd::mem::forget(x) // A copy of x is passed to the function, leaving the original unaffected\n```", + "Known problems": "None." + }, + "id": "forget_copy", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for names that are very similar and thus confusing.", + "Why is this bad": "It's hard to distinguish between names that differ only\nby a single character.", + "Example": "```rust\nlet checked_exp = something;\nlet checked_expr = something_else;\n```", + "Known problems": "None?" + }, + "id": "similar_names", + "level": "Allow" + }, + { + "docs": { + "What it does": "Checks for empty `loop` expressions.", + "Why is this bad": "Those busy loops burn CPU cycles without doing\nanything. Think of the environment and either block on something or at least\nmake the thread sleep for some microseconds.", + "Example": "```rust\nloop {}\n```", + "Known problems": "None." + }, + "id": "empty_loop", + "level": "Warn" + }, + { + "docs": { + "What it does": "* Lint for redundant pattern matching over `Result` or `Option`", + "Why is this bad": "It's more concise and clear to just use the proper utility function", + "Example": "```rust\nif let Ok(_) = Ok::(42) {}\nif let Err(_) = Err::(42) {}\nif let None = None::<()> {}\nif let Some(_) = Some(42) {}\n```\nThe more idiomatic use would be:\n```rust\nif Ok::(42).is_ok() {}\nif Err::(42).is_err() {}\nif None::<()>.is_none() {}\nif Some(42).is_some() {}\n```", + "Known problems": "None." + }, + "id": "if_let_redundant_pattern_matching", + "level": "Warn" + }, + { + "docs": { + "What it does": "Warns if an integral constant literal starts with `0`.", + "Why is this bad": "In some languages (including the infamous C language and most of its\nfamilly), this marks an octal constant. In Rust however, this is a decimal constant. This could\nbe confusing for both the writer and a reader of the constant.", + "Example": "In Rust:\n```rust\nfn main() {\n let a = 0123;\n println!(\"{}\", a);\n}\n```\nprints `123`, while in C:\n```c\n#include \nint main() {\n int a = 0123;\n printf(\"%d\\n\", a);\n}\n```\nprints `83` (as `83 == 0o123` while `123 == 0o173`).", + "Known problems": "None." + }, + "id": "zero_prefixed_literal", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for bindings that shadow other bindings already in\nscope, while reusing the original value.", + "Why is this bad": "Not too much, in fact it's a common pattern in Rust\ncode. Still, some argue that name shadowing like this hurts readability,\nbecause a value may be bound to different things depending on position in\nthe code.", + "Example": "```rust\nlet x = x + 1;\n```", + "Known problems": "This lint, as the other shadowing related lints,\ncurrently only catches very simple patterns." + }, + "id": "shadow_reuse", + "level": "Allow" + }, + { + "docs": { + "What it does": "Checks for address of operations (`&`) that are going to\nbe dereferenced immediately by the compiler.", + "Why is this bad": "Suggests that the receiver of the expression borrows\nthe expression.", + "Example": "```rust\nlet x: &i32 = &&&&&&5;\n```", + "Known problems": "None." + }, + "id": "needless_borrow", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for expressions of the form `x == true` (or vice\nversa) and suggest using the variable directly.", + "Why is this bad": "Unnecessary code.", + "Example": "```rust\nif x == true { } // could be `if x { }`\n```", + "Known problems": "None." + }, + "id": "bool_comparison", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for loops that will always `break`, `return` or\n`continue` an outer loop.", + "Why is this bad": "This loop never loops, all it does is obfuscating the\ncode.", + "Example": "```rust\nloop { ..; break; }\n```", + "Known problems": "None" + }, + "id": "never_loop", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for the `as_bytes` method called on string literals\nthat contain only ASCII characters.", + "Why is this bad": "Byte string literals (e.g. `b\"foo\"`) can be used\ninstead. They are shorter but less discoverable than `as_bytes()`.", + "Example": "```rust\nlet bs = \"a byte string\".as_bytes();\n```", + "Known Problems": "None." + }, + "id": "string_lit_as_bytes", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for mapping `clone()` over an iterator.", + "Why is this bad": "It makes the code less readable than using the\n`.cloned()` adapter.", + "Example": "```rust\nx.map(|e| e.clone());\n```", + "Known problems": "None." + }, + "id": "map_clone", + "level": "Warn" + }, + { + "docs": { + "What it does": "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.", + "Why is this bad": "While such a cast is not bad in itself, the results can\nbe surprising when this is not the intended behavior, as demonstrated by the\nexample below.", + "Example": "```rust\nu32::MAX as i32 // will yield a value of `-1`\n```", + "Known problems": "None." + }, + "id": "cast_possible_wrap", + "level": "Allow" + }, + { + "docs": { + "What it does": "Checks for out of bounds array indexing with a constant index.", + "Why is this bad": "This will always panic at runtime.", + "Example": "```rust\nlet x = [1,2,3,4];\n...\nx[9];\n&x[2..9];\n```", + "Known problems": "Hopefully none." + }, + "id": "out_of_bounds_indexing", + "level": "Deny" + }, + { + "docs": { + "What it does": "Checks for calls to `std::mem::forget` with a reference\ninstead of an owned value.", + "Why is this bad": "Calling `forget` on a reference will only forget the\nreference itself, which is a no-op. It will not forget the underlying referenced\nvalue, which is likely what was intended.", + "Example": "```rust\nlet x = Box::new(1);\nstd::mem::forget(&x) // Should have been forget(x), x will still be dropped\n```", + "Known problems": "None." + }, + "id": "forget_ref", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for usage of `_.map(_).unwrap_or(_)`.", + "Why is this bad": "Readability, this can be written more concisely as\n`_.map_or(_, _)`.", + "Example": "```rust\nx.map(|a| a + 1).unwrap_or(0)\n```", + "Known problems": "None." + }, + "id": "option_map_unwrap_or", + "level": "Allow" + }, + { + "docs": { + "What it does": "Checks for usage of `_.filter(_).next()`.", + "Why is this bad": "Readability, this can be written more concisely as\n`_.find(_)`.", + "Example": "```rust\niter.filter(|x| x == 0).next()\n```", + "Known problems": "None." + }, + "id": "filter_next", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for getting the inner pointer of a temporary `CString`.", + "Why is this bad": "The inner pointer of a `CString` is only valid as long\nas the `CString` is alive.", + "Example": "```rust,ignore\nlet c_str = CString::new(\"foo\").unwrap().as_ptr();\nunsafe {\ncall_some_ffi_func(c_str);\n}\n```\nHere `c_str` point to a freed address. The correct use would be:\n```rust,ignore\nlet c_str = CString::new(\"foo\").unwrap();\nunsafe {\n call_some_ffi_func(c_str.as_ptr());\n}\n```", + "Known problems": "None." + }, + "id": "temporary_cstring_as_ptr", + "level": "Warn" + }, + { + "docs": { + "What it does": "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).", + "Why is this bad": "The user might expect to be able to use\n[`Default`](https://doc.rust-lang.org/std/default/trait.Default.html) as the\ntype can be constructed without arguments.", + "Example": "```rust,ignore\nstruct Foo(Bar);\nimpl Foo {\n fn new() -> Self {\n Foo(Bar::new())\n }\n}\n```\nInstead, use:\n```rust\nstruct Foo(Bar);\nimpl Default for Foo {\n fn default() -> Self {\n Foo(Bar::new())\n }\n}\n```\nYou can also have `new()` call `Default::default()`.", + "Known problems": "Hopefully none." + }, + "id": "new_without_default", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for `.unwrap()` calls on `Result`s.", + "Why is this bad": "`result.unwrap()` will let the thread panic on `Err`\nvalues. Normally, you want to implement more sophisticated error handling,\nand propagate errors upwards with `try!`.\nEven if you want to panic on errors, not all `Error`s implement good\nmessages on display. Therefore it may be beneficial to look at the places\nwhere they may get displayed. Activate this lint to do just that.", + "Example": "```rust\nx.unwrap()\n```", + "Known problems": "None." + }, + "id": "result_unwrap_used", + "level": "Allow" + }, + { + "docs": { + "What it does": "Checks for using `collect()` on an iterator without using\nthe result.", + "Why is this bad": "It is more idiomatic to use a `for` loop over the\niterator instead.", + "Example": "```rust\nvec.iter().map(|x| /* some operation returning () */).collect::>();\n```", + "Known problems": "None." + }, + "id": "unused_collect", + "level": "Warn" + }, + { + "docs": { + "What it does": "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.", + "Why is this bad": "Implementing the traits improve ergonomics for users of\nthe code, often with very little cost. Also people seeing a `mul(...)` method\nmay expect `*` to work equally, so you should have good reason to disappoint\nthem.", + "Example": "```rust\nstruct X;\nimpl X {\n fn add(&self, other: &X) -> X { .. }\n}\n```", + "Known problems": "None." + }, + "id": "should_implement_trait", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for usage of any `LinkedList`, suggesting to use a\n`Vec` or a `VecDeque` (formerly called `RingBuf`).", + "Why is this bad": "Gankro says:\n> The TL;DR of `LinkedList` is that it's built on a massive amount of pointers and indirection.\n> It wastes memory, it has terrible cache locality, and is all-around slow. `RingBuf`, while\n> \"only\" amortized for push/pop, should be faster in the general case for almost every possible\n> workload, and isn't even amortized at all if you can predict the capacity you need.\n>\n> `LinkedList`s are only really good if you're doing a lot of merging or splitting of lists.\n> This is because they can just mangle some pointers instead of actually copying the data. Even\n> if you're doing a lot of insertion in the middle of the list, `RingBuf` can still be better\n> because of how expensive it is to seek to the middle of a `LinkedList`.", + "Example": "```rust\nlet x = LinkedList::new();\n```", + "Known problems": "False positives \u2013 the instances where using a\n`LinkedList` makes sense are few and far between, but they can still happen." + }, + "id": "linkedlist", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for instances of `mut mut` references.", + "Why is this bad": "Multiple `mut`s don't add anything meaningful to the\nsource. This is either a copy'n'paste error, or it shows a fundamental\nmisunderstanding of references.", + "Example": "```rust\nlet x = &mut &mut y;\n```", + "Known problems": "None." + }, + "id": "mut_mut", + "level": "Allow" + }, + { + "docs": { + "What it does": "Checks for arm which matches all errors with `Err(_)`\nand take drastic actions like `panic!`.", + "Why is this bad": "It is generally a bad practice, just like\ncatching all exceptions in java with `catch(Exception)`", + "Example": "```rust\nlet x : Result(i32, &str) = Ok(3);\nmatch x {\n Ok(_) => println!(\"ok\"),\n Err(_) => panic!(\"err\"),\n}\n```", + "Known problems": "None." + }, + "id": "match_wild_err_arm", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for types used in structs, parameters and `let`\ndeclarations above a certain complexity threshold.", + "Why is this bad": "Too complex types make the code less readable. Consider\nusing a `type` definition to simplify them.", + "Example": "```rust\nstruct Foo { inner: Rc>>> }\n```", + "Known problems": "None." + }, + "id": "type_complexity", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for the use of `.cloned().collect()` on slice to create a `Vec`.", + "Why is this bad": "`.to_vec()` is clearer", + "Example": "```rust\nlet s = [1,2,3,4,5];\nlet s2 : Vec = s[..].iter().cloned().collect();\n```\nThe better use would be:\n```rust\nlet s = [1,2,3,4,5];\nlet s2 : Vec = s.to_vec();\n```", + "Known problems": "None." + }, + "id": "iter_cloned_collect", + "level": "Warn" + }, + { + "docs": { + "What it does": "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).", + "Why is this bad": "If such a string is compared to another, the results\nmay be surprising.", + "Example": "You may not see it, but \u201ca\u0300\u201d and \u201c\u00e0\u201d aren't the same string. The\nformer when escaped is actually `\"a\\u{300}\"` while the latter is `\"\\u{e0}\"`.", + "Known problems": "None." + }, + "id": "unicode_not_nfc", + "level": "Allow" + }, + { + "docs": { + "What it does": "Checks for loops over ranges `x..y` where both `x` and `y`\nare constant and `x` is greater or equal to `y`, unless the range is\nreversed or has a negative `.step_by(_)`.", + "Why is it bad": "Such loops will either be skipped or loop until\nwrap-around (in debug code, this may `panic!()`). Both options are probably\nnot intended.", + "Example": "```rust\nfor x in 5..10-5 { .. } // oops, stray `-`\n```", + "Known problems": "The lint cannot catch loops over dynamically defined\nranges. Doing this would require simulating all possible inputs and code\npaths through the program, which would be complex and error-prone." + }, + "id": "reverse_range_loop", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for modules that have the same name as their parent module", + "Why is this bad": "A typical beginner mistake is to have `mod foo;` and again `mod foo { ..\n}` in `foo.rs`.\nThe expectation is that items inside the inner `mod foo { .. }` are then\navailable\n through `foo::x`, but they are only available through `foo::foo::x`.\nIf this is done on purpose, it would be better to choose a more\nrepresentative module name.", + "Example": "```rust\n// lib.rs\nmod foo;\n// foo.rs\nmod foo {\n ...\n}\n```", + "Known problems": "None." + }, + "id": "module_inception", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for `assert!(x == y)` or `assert!(x != y)` which can be better written\nusing `assert_eq` or `assert_ne` if `x` and `y` implement `Debug` trait.", + "Why is this bad": "`assert_eq` and `assert_ne` provide better assertion failure reporting.", + "Example": "```rust\nlet (x, y) = (1, 2);\nassert!(x == y); // assertion failed: x == y\nassert_eq!(x, y); // assertion failed: `(left == right)` (left: `1`, right: `2`)\n```", + "Known problems": "Hopefully none." + }, + "id": "should_assert_eq", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for casts to the same type.", + "Why is this bad": "It's just unnecessary.", + "Example": "```rust\nlet _ = 2i32 as i32\n```", + "Known problems": "None." + }, + "id": "unnecessary_cast", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for unused labels.", + "Why is this bad": "Maybe the label should be used in which case there is\nan error in the code or it should be removed.", + "Example": "```rust,ignore\nfn unused_label() {\n 'label: for i in 1..2 {\n if i > 4 { continue }\n }\n```", + "Known problems": "Hopefully none." + }, + "id": "unused_label", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for too many variables whose name consists of a\nsingle character.", + "Why is this bad": "It's hard to memorize what a variable means without a\ndescriptive name.", + "Example": "```rust\nlet (a, b, c, d, e, f, g) = (...);\n```", + "Known problems": "None?" + }, + "id": "many_single_char_names", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for `use Enum::*`.", + "Why is this bad": "It is usually better style to use the prefixed name of\nan enumeration variant, rather than importing variants.", + "Example": "```rust\nuse std::cmp::Ordering::*;\n```", + "Known problems": "Old-style enumerations that prefix the variants are\nstill around." + }, + "id": "enum_glob_use", + "level": "Allow" + }, + { + "docs": { + "What it does": "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|Comparison| Bit Op |Example |equals |\n|----------|---------|-----------|-------|\n|`>` / `<=`|`|` / `^`|`x | 2 > 3`|`x > 3`|\n|`<` / `>=`|`|` / `^`|`x ^ 1 < 4`|`x < 4`|", + "Why is this bad": "Not equally evil as [`bad_bit_mask`](#bad_bit_mask),\nbut still a bit misleading, because the bit mask is ineffective.", + "Example": "```rust\nif (x | 1 > 3) { \u2026 }\n```", + "Known problems": "False negatives: This lint will only match instances\nwhere we have figured out the math (which is for a power-of-two compared\nvalue). This means things like `x | 1 >= 7` (which would be better written\nas `x >= 6`) will not be reported (but bit masks like this are fairly\nuncommon)." + }, + "id": "ineffective_bit_mask", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for usage of `.clone()` on a `Copy` type.", + "Why is this bad": "The only reason `Copy` types implement `Clone` is for\ngenerics, not for using the `clone` method on a concrete type.", + "Example": "```rust\n42u64.clone()\n```", + "Known problems": "None." + }, + "id": "clone_on_copy", + "level": "Warn" + }, + { + "docs": { + "What it does": "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.", + "Why is this bad": "It is often confusing to read. In addition, the\nsub-expression evaluation order for Rust is not well documented.", + "Example": "```rust\nlet mut x = 0;\nlet a = {x = 1; 1} + x;\n// Unclear whether a is 1 or 2.\n```", + "Known problems": "Code which intentionally depends on the evaluation\norder, or which is correct for any evaluation order." + }, + "id": "eval_order_dependence", + "level": "Warn" + }, + { + "docs": { + "What it does": "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.\nBasically, this warns on casting any integer with 32 or more bits to `f32`\nor any 64-bit integer to `f64`.", + "Why is this bad": "It's not bad at all. But in some applications it can be\nhelpful to know where precision loss can take place. This lint can help find\nthose places in the code.", + "Example": "```rust\nlet x = u64::MAX; x as f64\n```", + "Known problems": "None." + }, + "id": "cast_precision_loss", + "level": "Allow" + }, + { + "docs": { + "What it does": "Checks for the use of `.extend(s.chars())` where s is a\n`&str` or `String`.", + "Why is this bad": "`.push_str(s)` is clearer", + "Example": "```rust\nlet abc = \"abc\";\nlet def = String::from(\"def\");\nlet mut s = String::new();\ns.extend(abc.chars());\ns.extend(def.chars());\n```\nThe correct use would be:\n```rust\nlet abc = \"abc\";\nlet def = String::from(\"def\");\nlet mut s = String::new();\ns.push_str(abc);\ns.push_str(&def));\n```", + "Known problems": "None." + }, + "id": "string_extend_chars", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for looping over the range of `0..len` of some\ncollection just to get the values by index.", + "Why is this bad": "Just iterating the collection itself makes the intent\nmore clear and is probably faster.", + "Example": "```rust\nfor i in 0..vec.len() {\n println!(\"{}\", vec[i]);\n}\n```", + "Known problems": "None." + }, + "id": "needless_range_loop", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for calls to `std::mem::drop` with a value\nthat derives the Copy trait", + "Why is this bad": "Calling `std::mem::drop` [does nothing for types that\nimplement Copy](https://doc.rust-lang.org/std/mem/fn.drop.html), since the\nvalue will be copied and moved into the function on invocation.", + "Example": "```rust\nlet x:i32 = 42; // i32 implements Copy\nstd::mem::drop(x) // A copy of x is passed to the function, leaving the original unaffected\n```", + "Known problems": "None." + }, + "id": "drop_copy", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for functions taking arguments by value, but not consuming them in its\nbody.", + "Why is this bad": "Taking arguments by reference is more flexible and can sometimes avoid\nunnecessary allocations.", + "Example": "```rust\nfn foo(v: Vec) {\n assert_eq!(v.len(), 42);\n}\n```", + "Known problems": "Hopefully none." + }, + "id": "needless_pass_by_value", + "level": "Warn" + }, + { + "docs": { + "What it does": "Nothing. This lint has been deprecated.", + "Deprecation reason": "This used to check for `.to_string()` method calls on values\nof type `&str`. This is not unidiomatic and with specialization coming, `to_string` could be\nspecialized to be as efficient as `to_owned`." + }, + "id": "str_to_string", + "level": "Deprecated" + }, + { + "docs": { + "What it does": "Checks for unnecessary double parentheses.", + "Why is this bad": "This makes code harder to read and might indicate a\nmistake.", + "Example": "```rust\n((0))\nfoo((0))\n((1, 2))\n```", + "Known problems": "None." + }, + "id": "double_parens", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for the Unicode zero-width space in the code.", + "Why is this bad": "Having an invisible character in the code makes for all\nsorts of April fools, but otherwise is very much frowned upon.", + "Example": "You don't see it, but there may be a zero-width space somewhere in this text.", + "Known problems": "None." + }, + "id": "zero_width_space", + "level": "Deny" + }, + { + "docs": { + "What it does": "Checks for trivial [regex] creation (with `Regex::new`,\n`RegexBuilder::new` or `RegexSet::new`).\n[regex]: https://crates.io/crates/regex", + "Why is this bad": "Matching the regex can likely be replaced by `==` or\n`str::starts_with`, `str::ends_with` or `std::contains` or other `str`\nmethods.", + "Example": "```rust\nRegex::new(\"^foobar\")\n```", + "Known problems": "None." + }, + "id": "trivial_regex", + "level": "Warn" + }, + { + "docs": { + "What it does": "This lint checks for functions that take immutable references and return\nmutable ones.", + "Why is this bad": "This is trivially unsound, as one can create two mutable references\nfrom the same (immutable!) source. This [error](https://github.com/rust-lang/rust/issues/39465)\nactually lead to an interim Rust release 1.15.1.", + "Example": "```rust\nfn foo(&Foo) -> &mut Bar { .. }\n```", + "Known problems": "To be on the conservative side, if there's at least one mutable reference\nwith the output lifetime, this lint will not trigger. In practice, this case is unlikely anyway." + }, + "id": "mut_from_ref", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for functions with too many parameters.", + "Why is this bad": "Functions with lots of parameters are considered bad\nstyle and reduce readability (\u201cwhat does the 5th parameter mean?\u201d). Consider\ngrouping some parameters into a new type.", + "Example": "```rust\nfn foo(x: u32, y: u32, name: &str, c: Color, w: f32, h: f32, a: f32, b: f32) { .. }\n```", + "Known problems": "None." + }, + "id": "too_many_arguments", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for unused written/read amount.", + "Why is this bad": "`io::Write::write` and `io::Read::read` are not guaranteed to\nprocess the entire buffer. They return how many bytes were processed, which might be smaller\nthan a given buffer's length. If you don't need to deal with partial-write/read, use\n`write_all`/`read_exact` instead.", + "Example": "```rust,ignore\nuse std::io;\nfn foo(w: &mut W) -> io::Result<()> {\n // must be `w.write_all(b\"foo\")?;`\n w.write(b\"foo\")?;\n Ok(())\n}\n```", + "Known problems": "Detects only common patterns." + }, + "id": "unused_io_amount", + "level": "Deny" + }, + { + "docs": { + "What it does": "Checks for patterns in the form `name @ _`.", + "Why is this bad": "It's almost always more readable to just use direct bindings.", + "Example": "```rust\nmatch v {\n Some(x) => (),\n y @ _ => (), // easier written as `y`,\n}\n```", + "Known problems": "None." + }, + "id": "redundant_pattern", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for statements which have no effect.", + "Why is this bad": "Similar to dead code, these statements are actually\nexecuted. However, as they have no effect, all they do is make the code less\nreadable.", + "Example": "```rust\n0;\n```", + "Known problems": "None." + }, + "id": "no_effect", + "level": "Warn" + }, + { + "docs": { + "What it does": "Detects type names that are prefixed or suffixed by the\ncontaining module's name.", + "Why is this bad": "It requires the user to type the module name twice.", + "Example": "```rust\nmod cake {\n struct BlackForestCake;\n}\n```", + "Known problems": "None." + }, + "id": "stutter", + "level": "Allow" + }, + { + "docs": { + "What it does": "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.", + "Why is this bad": "The function will always be called and potentially\nallocate an object acting as the default.", + "Example": "```rust\nfoo.unwrap_or(String::new())\n```\nthis can instead be written:\n```rust\nfoo.unwrap_or_else(String::new)\n```\nor\n```rust\nfoo.unwrap_or_default()\n```", + "Known problems": "If the function has side-effects, not calling it will\nchange the semantic of the program, but you shouldn't rely on that anyway." + }, + "id": "or_fun_call", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for non-ASCII characters in string literals.", + "Why is this bad": "Yeah, we know, the 90's called and wanted their charset\nback. Even so, there still are editors and other programs out there that\ndon't work well with Unicode. So if the code is meant to be used\ninternationally, on multiple operating systems, or has other portability\nrequirements, activating this lint could be useful.", + "Example": "```rust\nlet x = \"H\u00e4?\"\n```", + "Known problems": "None." + }, + "id": "non_ascii_literal", + "level": "Allow" + }, + { + "docs": { + "What it does": "Nothing. This lint has been deprecated.", + "Deprecation reason": "`Range::step_by(0)` used to be linted since it's\nan infinite iterator, which is better expressed by `iter::repeat`,\nbut the method has been removed for `Iterator::step_by` which panics\nif given a zero" + }, + "id": "range_step_by_zero", + "level": "Deprecated" + }, + { + "docs": { + "What it does": "Checks for `if` conditions that use blocks to contain an\nexpression.", + "Why is this bad": "It isn't really Rust style, same as using parentheses\nto contain expressions.", + "Example": "```rust\nif { true } ..\n```", + "Known problems": "None." + }, + "id": "block_in_if_condition_expr", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for `if/else` with the same body as the *then* part\nand the *else* part.", + "Why is this bad": "This is probably a copy & paste error.", + "Example": "```rust\nlet foo = if \u2026 {\n 42\n} else {\n 42\n};\n```", + "Known problems": "Hopefully none." + }, + "id": "if_same_then_else", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for use of `&Box` anywhere in the code.", + "Why is this bad": "Any `&Box` can also be a `&T`, which is more general.", + "Example": "```rust\nfn foo(bar: &Box) { ... }\n```", + "Known problems": "None." + }, + "id": "borrowed_box", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for usage of `ok().expect(..)`.", + "Why is this bad": "Because you usually call `expect()` on the `Result`\ndirectly to get a better error message.", + "Example": "```rust\nx.ok().expect(\"why did I do this again?\")\n```", + "Known problems": "None." + }, + "id": "ok_expect", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for loops on `y.into_iter()` where `y` will do, and\nsuggests the latter.", + "Why is this bad": "Readability.", + "Example": "```rust\n// with `y` a `Vec` or slice:\nfor x in y.into_iter() { .. }\n```", + "Known problems": "None" + }, + "id": "explicit_into_iter_loop", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for calling `.step_by(0)` on iterators,\nwhich never terminates.", + "Why is this bad": "This very much looks like an oversight, since with\n`loop { .. }` there is an obvious better way to endlessly loop.", + "Example": "```rust\nfor x in (5..5).step_by(0) { .. }\n```", + "Known problems": "None." + }, + "id": "iterator_step_by_zero", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for expressions where a character literal is cast\nto `u8` and suggests using a byte literal instead.", + "Why is this bad": "In general, casting values to smaller types is\nerror-prone and should be avoided where possible. In the particular case of\nconverting a character literal to u8, it is easy to avoid by just using a\nbyte literal instead. As an added bonus, `b'a'` is even slightly shorter\nthan `'a' as u8`.", + "Example": "```rust\n'x' as u8\n```", + "Known problems": "None." + }, + "id": "char_lit_as_u8", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for C-like enumerations that are\n`repr(isize/usize)` and have values that don't fit into an `i32`.", + "Why is this bad": "This will truncate the variant value on 32 bit\narchitectures, but works fine on 64 bit.", + "Example": "```rust\n#[repr(usize)]\nenum NonPortable {\n X = 0x1_0000_0000,\n Y = 0\n}\n```", + "Known problems": "None." + }, + "id": "enum_clike_unportable_variant", + "level": "Warn" + }, + { + "docs": { + "What it does": "Checks for `for` loops over `Result` values.", + "Why is this bad": "Readability. This is more clearly expressed as an `if let`.", + "Example": "```rust\nfor x in result { .. }\n```\nThis should be\n```rust\nif let Ok(x) = result { .. }\n```", + "Known problems": "None." + }, + "id": "for_loop_over_result", + "level": "Warn" + } +] \ No newline at end of file