Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into rustup
Browse files Browse the repository at this point in the history
  • Loading branch information
ebroto committed Nov 10, 2020
2 parents 6294300 + dd826b4 commit 3ea6f77
Show file tree
Hide file tree
Showing 73 changed files with 1,839 additions and 373 deletions.
8 changes: 4 additions & 4 deletions .github/PULL_REQUEST_TEMPLATE.md
@@ -1,8 +1,8 @@
Thank you for making Clippy better!

We're collecting our changelog from pull request descriptions.
If your PR only updates to the latest nightly, you can leave the
`changelog` entry as `none`. Otherwise, please write a short comment
If your PR only includes internal changes, you can just write
`changelog: none`. Otherwise, please write a short comment
explaining your change.

If your PR fixes an issue, you can add "fixes #issue_number" into this
Expand All @@ -28,5 +28,5 @@ Delete this line and everything above before opening your PR.

---

*Please keep the line below*
changelog: none
*Please write a short comment explaining your change (or "none" for internal only changes)*
changelog:
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -1787,6 +1787,7 @@ Released 2018-09-13
[`len_without_is_empty`]: https://rust-lang.github.io/rust-clippy/master/index.html#len_without_is_empty
[`len_zero`]: https://rust-lang.github.io/rust-clippy/master/index.html#len_zero
[`let_and_return`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_and_return
[`let_underscore_drop`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_drop
[`let_underscore_lock`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_lock
[`let_underscore_must_use`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_must_use
[`let_unit_value`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_unit_value
Expand Down Expand Up @@ -1956,6 +1957,7 @@ Released 2018-09-13
[`string_add`]: https://rust-lang.github.io/rust-clippy/master/index.html#string_add
[`string_add_assign`]: https://rust-lang.github.io/rust-clippy/master/index.html#string_add_assign
[`string_extend_chars`]: https://rust-lang.github.io/rust-clippy/master/index.html#string_extend_chars
[`string_from_utf8_as_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#string_from_utf8_as_bytes
[`string_lit_as_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#string_lit_as_bytes
[`string_to_string`]: https://rust-lang.github.io/rust-clippy/master/index.html#string_to_string
[`struct_excessive_bools`]: https://rust-lang.github.io/rust-clippy/master/index.html#struct_excessive_bools
Expand Down
32 changes: 13 additions & 19 deletions README.md
Expand Up @@ -7,28 +7,22 @@ A collection of lints to catch common mistakes and improve your [Rust](https://g

[There are over 400 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)

We have a bunch of lint categories to allow you to choose how much Clippy is supposed to ~~annoy~~ help you:

* `clippy::all` (everything that is on by default: all the categories below except for `nursery`, `pedantic`, and `cargo`)
* `clippy::correctness` (code that is just **outright wrong** or **very very useless**, causes hard errors by default)
* `clippy::style` (code that should be written in a more idiomatic way)
* `clippy::complexity` (code that does something simple but in a complex way)
* `clippy::perf` (code that can be written in a faster way)
* `clippy::pedantic` (lints which are rather strict, off by default)
* `clippy::nursery` (new lints that aren't quite ready yet, off by default)
* `clippy::cargo` (checks against the cargo manifest, off by default)
Lints are divided into categories, each with a default [lint level](https://doc.rust-lang.org/rustc/lints/levels.html).
You can choose how much Clippy is supposed to ~~annoy~~ help you by changing the lint level by category.

Category | Description | Default level
-- | -- | --
`clippy::all` | all lints that are on by default (correctness, style, complexity, perf) | **warn/deny**
`clippy::correctness` | code that is outright wrong or very useless | **deny**
`clippy::style` | code that should be written in a more idiomatic way | **warn**
`clippy::complexity` | code that does something simple but in a complex way | **warn**
`clippy::perf` | code that can be written to run faster | **warn**
`clippy::pedantic` | lints which are rather strict or might have false positives | allow
`clippy::nursery` | new lints that are still under development | allow
`clippy::cargo` | lints for the cargo manifest | allow

More to come, please [file an issue](https://github.com/rust-lang/rust-clippy/issues) if you have ideas!

Only the following of those categories are enabled by default:

* `clippy::style`
* `clippy::correctness`
* `clippy::complexity`
* `clippy::perf`

Other categories need to be enabled in order for their lints to be executed.

The [lint list](https://rust-lang.github.io/rust-clippy/master/index.html) also contains "restriction lints", which are
for things which are usually not considered "bad", but may be useful to turn on in specific cases. These should be used
very selectively, if at all.
Expand Down
8 changes: 4 additions & 4 deletions clippy_lints/src/await_holding_invalid.rs
Expand Up @@ -65,8 +65,8 @@ declare_clippy_lint! {
/// use std::cell::RefCell;
///
/// async fn foo(x: &RefCell<u32>) {
/// let b = x.borrow_mut()();
/// *ref += 1;
/// let mut y = x.borrow_mut();
/// *y += 1;
/// bar.await;
/// }
/// ```
Expand All @@ -77,8 +77,8 @@ declare_clippy_lint! {
///
/// async fn foo(x: &RefCell<u32>) {
/// {
/// let b = x.borrow_mut();
/// *ref += 1;
/// let mut y = x.borrow_mut();
/// *y += 1;
/// }
/// bar.await;
/// }
Expand Down
15 changes: 15 additions & 0 deletions clippy_lints/src/cargo_common_metadata.rs
Expand Up @@ -23,6 +23,21 @@ declare_clippy_lint! {
/// [package]
/// name = "clippy"
/// version = "0.0.212"
/// description = "A bunch of helpful lints to avoid common pitfalls in Rust"
/// repository = "https://github.com/rust-lang/rust-clippy"
/// readme = "README.md"
/// license = "MIT OR Apache-2.0"
/// keywords = ["clippy", "lint", "plugin"]
/// categories = ["development-tools", "development-tools::cargo-plugins"]
/// ```
///
/// Should include an authors field like:
///
/// ```toml
/// # This `Cargo.toml` includes all common metadata
/// [package]
/// name = "clippy"
/// version = "0.0.212"
/// authors = ["Someone <someone@rust-lang.org>"]
/// description = "A bunch of helpful lints to avoid common pitfalls in Rust"
/// repository = "https://github.com/rust-lang/rust-clippy"
Expand Down
9 changes: 2 additions & 7 deletions clippy_lints/src/future_not_send.rs
Expand Up @@ -92,13 +92,8 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend {
|db| {
cx.tcx.infer_ctxt().enter(|infcx| {
for FulfillmentError { obligation, .. } in send_errors {
infcx.maybe_note_obligation_cause_for_async_await(
db,
&obligation,
);
if let Trait(trait_pred, _) =
obligation.predicate.skip_binders()
{
infcx.maybe_note_obligation_cause_for_async_await(db, &obligation);
if let Trait(trait_pred, _) = obligation.predicate.skip_binders() {
db.note(&format!(
"`{}` doesn't implement `{}`",
trait_pred.self_ty(),
Expand Down
64 changes: 62 additions & 2 deletions clippy_lints/src/let_underscore.rs
Expand Up @@ -5,7 +5,7 @@ use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::subst::GenericArgKind;
use rustc_session::{declare_lint_pass, declare_tool_lint};

use crate::utils::{is_must_use_func_call, is_must_use_ty, match_type, paths, span_lint_and_help};
use crate::utils::{implements_trait, is_must_use_func_call, is_must_use_ty, match_type, paths, span_lint_and_help};

declare_clippy_lint! {
/// **What it does:** Checks for `let _ = <expr>`
Expand Down Expand Up @@ -58,7 +58,48 @@ declare_clippy_lint! {
"non-binding let on a synchronization lock"
}

declare_lint_pass!(LetUnderscore => [LET_UNDERSCORE_MUST_USE, LET_UNDERSCORE_LOCK]);
declare_clippy_lint! {
/// **What it does:** Checks for `let _ = <expr>`
/// where expr has a type that implements `Drop`
///
/// **Why is this bad?** This statement immediately drops the initializer
/// expression instead of extending its lifetime to the end of the scope, which
/// is often not intended. To extend the expression's lifetime to the end of the
/// scope, use an underscore-prefixed name instead (i.e. _var). If you want to
/// explicitly drop the expression, `std::mem::drop` conveys your intention
/// better and is less error-prone.
///
/// **Known problems:** None.
///
/// **Example:**
///
/// Bad:
/// ```rust,ignore
/// struct Droppable;
/// impl Drop for Droppable {
/// fn drop(&mut self) {}
/// }
/// {
/// let _ = Droppable;
/// // ^ dropped here
/// /* more code */
/// }
/// ```
///
/// Good:
/// ```rust,ignore
/// {
/// let _droppable = Droppable;
/// /* more code */
/// // dropped at end of scope
/// }
/// ```
pub LET_UNDERSCORE_DROP,
pedantic,
"non-binding let on a type that implements `Drop`"
}

declare_lint_pass!(LetUnderscore => [LET_UNDERSCORE_MUST_USE, LET_UNDERSCORE_LOCK, LET_UNDERSCORE_DROP]);

const SYNC_GUARD_PATHS: [&[&str]; 3] = [
&paths::MUTEX_GUARD,
Expand All @@ -84,6 +125,15 @@ impl<'tcx> LateLintPass<'tcx> for LetUnderscore {

GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => false,
});
let implements_drop = cx.tcx.lang_items().drop_trait().map_or(false, |drop_trait|
init_ty.walk().any(|inner| match inner.unpack() {
GenericArgKind::Type(inner_ty) => {
implements_trait(cx, inner_ty, drop_trait, &[])
},

GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => false,
})
);
if contains_sync_guard {
span_lint_and_help(
cx,
Expand All @@ -94,6 +144,16 @@ impl<'tcx> LateLintPass<'tcx> for LetUnderscore {
"consider using an underscore-prefixed named \
binding or dropping explicitly with `std::mem::drop`"
)
} else if implements_drop {
span_lint_and_help(
cx,
LET_UNDERSCORE_DROP,
local.span,
"non-binding `let` on a type that implements `Drop`",
None,
"consider using an underscore-prefixed named \
binding or dropping explicitly with `std::mem::drop`"
)
} else if is_must_use_ty(cx, cx.typeck_results().expr_ty(init)) {
span_lint_and_help(
cx,
Expand Down
5 changes: 5 additions & 0 deletions clippy_lints/src/lib.rs
Expand Up @@ -622,6 +622,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
&len_zero::LEN_WITHOUT_IS_EMPTY,
&len_zero::LEN_ZERO,
&let_if_seq::USELESS_LET_IF_SEQ,
&let_underscore::LET_UNDERSCORE_DROP,
&let_underscore::LET_UNDERSCORE_LOCK,
&let_underscore::LET_UNDERSCORE_MUST_USE,
&lifetimes::EXTRA_UNUSED_LIFETIMES,
Expand Down Expand Up @@ -832,6 +833,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
&stable_sort_primitive::STABLE_SORT_PRIMITIVE,
&strings::STRING_ADD,
&strings::STRING_ADD_ASSIGN,
&strings::STRING_FROM_UTF8_AS_BYTES,
&strings::STRING_LIT_AS_BYTES,
&suspicious_trait_impl::SUSPICIOUS_ARITHMETIC_IMPL,
&suspicious_trait_impl::SUSPICIOUS_OP_ASSIGN_IMPL,
Expand Down Expand Up @@ -1239,6 +1241,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
LintId::of(&infinite_iter::MAYBE_INFINITE_ITER),
LintId::of(&items_after_statements::ITEMS_AFTER_STATEMENTS),
LintId::of(&large_stack_arrays::LARGE_STACK_ARRAYS),
LintId::of(&let_underscore::LET_UNDERSCORE_DROP),
LintId::of(&literal_representation::LARGE_DIGIT_GROUPS),
LintId::of(&literal_representation::UNREADABLE_LITERAL),
LintId::of(&loops::EXPLICIT_INTO_ITER_LOOP),
Expand Down Expand Up @@ -1527,6 +1530,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
LintId::of(&single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS),
LintId::of(&slow_vector_initialization::SLOW_VECTOR_INITIALIZATION),
LintId::of(&stable_sort_primitive::STABLE_SORT_PRIMITIVE),
LintId::of(&strings::STRING_FROM_UTF8_AS_BYTES),
LintId::of(&suspicious_trait_impl::SUSPICIOUS_ARITHMETIC_IMPL),
LintId::of(&suspicious_trait_impl::SUSPICIOUS_OP_ASSIGN_IMPL),
LintId::of(&swap::ALMOST_SWAPPED),
Expand Down Expand Up @@ -1752,6 +1756,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
LintId::of(&reference::DEREF_ADDROF),
LintId::of(&reference::REF_IN_DEREF),
LintId::of(&repeat_once::REPEAT_ONCE),
LintId::of(&strings::STRING_FROM_UTF8_AS_BYTES),
LintId::of(&swap::MANUAL_SWAP),
LintId::of(&temporary_assignment::TEMPORARY_ASSIGNMENT),
LintId::of(&transmute::CROSSPOINTER_TRANSMUTE),
Expand Down
28 changes: 13 additions & 15 deletions clippy_lints/src/loops.rs
Expand Up @@ -4,10 +4,10 @@ use crate::utils::sugg::Sugg;
use crate::utils::usage::{is_unused, mutated_variables};
use crate::utils::{
contains_name, get_enclosing_block, get_parent_expr, get_trait_def_id, has_iter_method, higher, implements_trait,
indent_of, is_integer_const, is_no_std_crate, is_refutable, is_type_diagnostic_item, last_path_segment,
match_trait_method, match_type, match_var, multispan_sugg, qpath_res, single_segment_path, snippet,
snippet_with_applicability, snippet_with_macro_callsite, span_lint, span_lint_and_help, span_lint_and_sugg,
span_lint_and_then, sugg, SpanlessEq,
indent_of, is_in_panic_handler, is_integer_const, is_no_std_crate, is_refutable, is_type_diagnostic_item,
last_path_segment, match_trait_method, match_type, match_var, multispan_sugg, qpath_res, single_segment_path,
snippet, snippet_with_applicability, snippet_with_macro_callsite, span_lint, span_lint_and_help,
span_lint_and_sugg, span_lint_and_then, sugg, SpanlessEq,
};
use if_chain::if_chain;
use rustc_ast::ast;
Expand Down Expand Up @@ -543,17 +543,15 @@ impl<'tcx> LateLintPass<'tcx> for Loops {
// (also matches an explicit "match" instead of "if let")
// (even if the "match" or "if let" is used for declaration)
if let ExprKind::Loop(ref block, _, LoopSource::Loop) = expr.kind {
// also check for empty `loop {}` statements
// TODO(issue #6161): Enable for no_std crates (outside of #[panic_handler])
if block.stmts.is_empty() && block.expr.is_none() && !is_no_std_crate(cx.tcx.hir().krate()) {
span_lint_and_help(
cx,
EMPTY_LOOP,
expr.span,
"empty `loop {}` wastes CPU cycles",
None,
"You should either use `panic!()` or add `std::thread::sleep(..);` to the loop body.",
);
// also check for empty `loop {}` statements, skipping those in #[panic_handler]
if block.stmts.is_empty() && block.expr.is_none() && !is_in_panic_handler(cx, expr) {
let msg = "empty `loop {}` wastes CPU cycles";
let help = if is_no_std_crate(cx.tcx.hir().krate()) {
"you should either use `panic!()` or add a call pausing or sleeping the thread to the loop body"
} else {
"you should either use `panic!()` or add `std::thread::sleep(..);` to the loop body"
};
span_lint_and_help(cx, EMPTY_LOOP, expr.span, msg, None, help);
}

// extract the expression from the first statement (if any) in a block
Expand Down
6 changes: 3 additions & 3 deletions clippy_lints/src/manual_async_fn.rs
@@ -1,5 +1,5 @@
use crate::utils::paths::FUTURE_FROM_GENERATOR;
use crate::utils::{match_function_call, snippet_block, snippet_opt, span_lint_and_then};
use crate::utils::{match_function_call, position_before_rarrow, snippet_block, snippet_opt, span_lint_and_then};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::intravisit::FnKind;
Expand Down Expand Up @@ -69,7 +69,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualAsyncFn {
|diag| {
if_chain! {
if let Some(header_snip) = snippet_opt(cx, header_span);
if let Some(ret_pos) = header_snip.rfind("->");
if let Some(ret_pos) = position_before_rarrow(header_snip.clone());
if let Some((ret_sugg, ret_snip)) = suggested_ret(cx, output);
then {
let help = format!("make the function `async` and {}", ret_sugg);
Expand Down Expand Up @@ -194,7 +194,7 @@ fn suggested_ret(cx: &LateContext<'_>, output: &Ty<'_>) -> Option<(&'static str,
},
_ => {
let sugg = "return the output of the future directly";
snippet_opt(cx, output.span).map(|snip| (sugg, format!("-> {}", snip)))
snippet_opt(cx, output.span).map(|snip| (sugg, format!(" -> {}", snip)))
},
}
}
8 changes: 5 additions & 3 deletions clippy_lints/src/map_clone.rs
Expand Up @@ -80,9 +80,11 @@ impl<'tcx> LateLintPass<'tcx> for MapClone {
&& match_trait_method(cx, closure_expr, &paths::CLONE_TRAIT) {

let obj_ty = cx.typeck_results().expr_ty(&obj[0]);
if let ty::Ref(_, ty, _) = obj_ty.kind() {
let copy = is_copy(cx, ty);
lint(cx, e.span, args[0].span, copy);
if let ty::Ref(_, ty, mutability) = obj_ty.kind() {
if matches!(mutability, Mutability::Not) {
let copy = is_copy(cx, ty);
lint(cx, e.span, args[0].span, copy);
}
} else {
lint_needless_cloning(cx, e.span, args[0].span);
}
Expand Down

0 comments on commit 3ea6f77

Please sign in to comment.