Skip to content

Commit 3ea6f77

Browse files
committed
Merge remote-tracking branch 'upstream/master' into rustup
2 parents 6294300 + dd826b4 commit 3ea6f77

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+1839
-373
lines changed

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
Thank you for making Clippy better!
22

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

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

2929
---
3030

31-
*Please keep the line below*
32-
changelog: none
31+
*Please write a short comment explaining your change (or "none" for internal only changes)*
32+
changelog:

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1787,6 +1787,7 @@ Released 2018-09-13
17871787
[`len_without_is_empty`]: https://rust-lang.github.io/rust-clippy/master/index.html#len_without_is_empty
17881788
[`len_zero`]: https://rust-lang.github.io/rust-clippy/master/index.html#len_zero
17891789
[`let_and_return`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_and_return
1790+
[`let_underscore_drop`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_drop
17901791
[`let_underscore_lock`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_lock
17911792
[`let_underscore_must_use`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_must_use
17921793
[`let_unit_value`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_unit_value
@@ -1956,6 +1957,7 @@ Released 2018-09-13
19561957
[`string_add`]: https://rust-lang.github.io/rust-clippy/master/index.html#string_add
19571958
[`string_add_assign`]: https://rust-lang.github.io/rust-clippy/master/index.html#string_add_assign
19581959
[`string_extend_chars`]: https://rust-lang.github.io/rust-clippy/master/index.html#string_extend_chars
1960+
[`string_from_utf8_as_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#string_from_utf8_as_bytes
19591961
[`string_lit_as_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#string_lit_as_bytes
19601962
[`string_to_string`]: https://rust-lang.github.io/rust-clippy/master/index.html#string_to_string
19611963
[`struct_excessive_bools`]: https://rust-lang.github.io/rust-clippy/master/index.html#struct_excessive_bools

README.md

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,28 +7,22 @@ A collection of lints to catch common mistakes and improve your [Rust](https://g
77

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

10-
We have a bunch of lint categories to allow you to choose how much Clippy is supposed to ~~annoy~~ help you:
11-
12-
* `clippy::all` (everything that is on by default: all the categories below except for `nursery`, `pedantic`, and `cargo`)
13-
* `clippy::correctness` (code that is just **outright wrong** or **very very useless**, causes hard errors by default)
14-
* `clippy::style` (code that should be written in a more idiomatic way)
15-
* `clippy::complexity` (code that does something simple but in a complex way)
16-
* `clippy::perf` (code that can be written in a faster way)
17-
* `clippy::pedantic` (lints which are rather strict, off by default)
18-
* `clippy::nursery` (new lints that aren't quite ready yet, off by default)
19-
* `clippy::cargo` (checks against the cargo manifest, off by default)
10+
Lints are divided into categories, each with a default [lint level](https://doc.rust-lang.org/rustc/lints/levels.html).
11+
You can choose how much Clippy is supposed to ~~annoy~~ help you by changing the lint level by category.
12+
13+
Category | Description | Default level
14+
-- | -- | --
15+
`clippy::all` | all lints that are on by default (correctness, style, complexity, perf) | **warn/deny**
16+
`clippy::correctness` | code that is outright wrong or very useless | **deny**
17+
`clippy::style` | code that should be written in a more idiomatic way | **warn**
18+
`clippy::complexity` | code that does something simple but in a complex way | **warn**
19+
`clippy::perf` | code that can be written to run faster | **warn**
20+
`clippy::pedantic` | lints which are rather strict or might have false positives | allow
21+
`clippy::nursery` | new lints that are still under development | allow
22+
`clippy::cargo` | lints for the cargo manifest | allow
2023

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

23-
Only the following of those categories are enabled by default:
24-
25-
* `clippy::style`
26-
* `clippy::correctness`
27-
* `clippy::complexity`
28-
* `clippy::perf`
29-
30-
Other categories need to be enabled in order for their lints to be executed.
31-
3226
The [lint list](https://rust-lang.github.io/rust-clippy/master/index.html) also contains "restriction lints", which are
3327
for things which are usually not considered "bad", but may be useful to turn on in specific cases. These should be used
3428
very selectively, if at all.

clippy_lints/src/await_holding_invalid.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ declare_clippy_lint! {
6565
/// use std::cell::RefCell;
6666
///
6767
/// async fn foo(x: &RefCell<u32>) {
68-
/// let b = x.borrow_mut()();
69-
/// *ref += 1;
68+
/// let mut y = x.borrow_mut();
69+
/// *y += 1;
7070
/// bar.await;
7171
/// }
7272
/// ```
@@ -77,8 +77,8 @@ declare_clippy_lint! {
7777
///
7878
/// async fn foo(x: &RefCell<u32>) {
7979
/// {
80-
/// let b = x.borrow_mut();
81-
/// *ref += 1;
80+
/// let mut y = x.borrow_mut();
81+
/// *y += 1;
8282
/// }
8383
/// bar.await;
8484
/// }

clippy_lints/src/cargo_common_metadata.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,21 @@ declare_clippy_lint! {
2323
/// [package]
2424
/// name = "clippy"
2525
/// version = "0.0.212"
26+
/// description = "A bunch of helpful lints to avoid common pitfalls in Rust"
27+
/// repository = "https://github.com/rust-lang/rust-clippy"
28+
/// readme = "README.md"
29+
/// license = "MIT OR Apache-2.0"
30+
/// keywords = ["clippy", "lint", "plugin"]
31+
/// categories = ["development-tools", "development-tools::cargo-plugins"]
32+
/// ```
33+
///
34+
/// Should include an authors field like:
35+
///
36+
/// ```toml
37+
/// # This `Cargo.toml` includes all common metadata
38+
/// [package]
39+
/// name = "clippy"
40+
/// version = "0.0.212"
2641
/// authors = ["Someone <[email protected]>"]
2742
/// description = "A bunch of helpful lints to avoid common pitfalls in Rust"
2843
/// repository = "https://github.com/rust-lang/rust-clippy"

clippy_lints/src/future_not_send.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,8 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend {
9292
|db| {
9393
cx.tcx.infer_ctxt().enter(|infcx| {
9494
for FulfillmentError { obligation, .. } in send_errors {
95-
infcx.maybe_note_obligation_cause_for_async_await(
96-
db,
97-
&obligation,
98-
);
99-
if let Trait(trait_pred, _) =
100-
obligation.predicate.skip_binders()
101-
{
95+
infcx.maybe_note_obligation_cause_for_async_await(db, &obligation);
96+
if let Trait(trait_pred, _) = obligation.predicate.skip_binders() {
10297
db.note(&format!(
10398
"`{}` doesn't implement `{}`",
10499
trait_pred.self_ty(),

clippy_lints/src/let_underscore.rs

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use rustc_middle::lint::in_external_macro;
55
use rustc_middle::ty::subst::GenericArgKind;
66
use rustc_session::{declare_lint_pass, declare_tool_lint};
77

8-
use crate::utils::{is_must_use_func_call, is_must_use_ty, match_type, paths, span_lint_and_help};
8+
use crate::utils::{implements_trait, is_must_use_func_call, is_must_use_ty, match_type, paths, span_lint_and_help};
99

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

61-
declare_lint_pass!(LetUnderscore => [LET_UNDERSCORE_MUST_USE, LET_UNDERSCORE_LOCK]);
61+
declare_clippy_lint! {
62+
/// **What it does:** Checks for `let _ = <expr>`
63+
/// where expr has a type that implements `Drop`
64+
///
65+
/// **Why is this bad?** This statement immediately drops the initializer
66+
/// expression instead of extending its lifetime to the end of the scope, which
67+
/// is often not intended. To extend the expression's lifetime to the end of the
68+
/// scope, use an underscore-prefixed name instead (i.e. _var). If you want to
69+
/// explicitly drop the expression, `std::mem::drop` conveys your intention
70+
/// better and is less error-prone.
71+
///
72+
/// **Known problems:** None.
73+
///
74+
/// **Example:**
75+
///
76+
/// Bad:
77+
/// ```rust,ignore
78+
/// struct Droppable;
79+
/// impl Drop for Droppable {
80+
/// fn drop(&mut self) {}
81+
/// }
82+
/// {
83+
/// let _ = Droppable;
84+
/// // ^ dropped here
85+
/// /* more code */
86+
/// }
87+
/// ```
88+
///
89+
/// Good:
90+
/// ```rust,ignore
91+
/// {
92+
/// let _droppable = Droppable;
93+
/// /* more code */
94+
/// // dropped at end of scope
95+
/// }
96+
/// ```
97+
pub LET_UNDERSCORE_DROP,
98+
pedantic,
99+
"non-binding let on a type that implements `Drop`"
100+
}
101+
102+
declare_lint_pass!(LetUnderscore => [LET_UNDERSCORE_MUST_USE, LET_UNDERSCORE_LOCK, LET_UNDERSCORE_DROP]);
62103

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

85126
GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => false,
86127
});
128+
let implements_drop = cx.tcx.lang_items().drop_trait().map_or(false, |drop_trait|
129+
init_ty.walk().any(|inner| match inner.unpack() {
130+
GenericArgKind::Type(inner_ty) => {
131+
implements_trait(cx, inner_ty, drop_trait, &[])
132+
},
133+
134+
GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => false,
135+
})
136+
);
87137
if contains_sync_guard {
88138
span_lint_and_help(
89139
cx,
@@ -94,6 +144,16 @@ impl<'tcx> LateLintPass<'tcx> for LetUnderscore {
94144
"consider using an underscore-prefixed named \
95145
binding or dropping explicitly with `std::mem::drop`"
96146
)
147+
} else if implements_drop {
148+
span_lint_and_help(
149+
cx,
150+
LET_UNDERSCORE_DROP,
151+
local.span,
152+
"non-binding `let` on a type that implements `Drop`",
153+
None,
154+
"consider using an underscore-prefixed named \
155+
binding or dropping explicitly with `std::mem::drop`"
156+
)
97157
} else if is_must_use_ty(cx, cx.typeck_results().expr_ty(init)) {
98158
span_lint_and_help(
99159
cx,

clippy_lints/src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
622622
&len_zero::LEN_WITHOUT_IS_EMPTY,
623623
&len_zero::LEN_ZERO,
624624
&let_if_seq::USELESS_LET_IF_SEQ,
625+
&let_underscore::LET_UNDERSCORE_DROP,
625626
&let_underscore::LET_UNDERSCORE_LOCK,
626627
&let_underscore::LET_UNDERSCORE_MUST_USE,
627628
&lifetimes::EXTRA_UNUSED_LIFETIMES,
@@ -832,6 +833,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
832833
&stable_sort_primitive::STABLE_SORT_PRIMITIVE,
833834
&strings::STRING_ADD,
834835
&strings::STRING_ADD_ASSIGN,
836+
&strings::STRING_FROM_UTF8_AS_BYTES,
835837
&strings::STRING_LIT_AS_BYTES,
836838
&suspicious_trait_impl::SUSPICIOUS_ARITHMETIC_IMPL,
837839
&suspicious_trait_impl::SUSPICIOUS_OP_ASSIGN_IMPL,
@@ -1239,6 +1241,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
12391241
LintId::of(&infinite_iter::MAYBE_INFINITE_ITER),
12401242
LintId::of(&items_after_statements::ITEMS_AFTER_STATEMENTS),
12411243
LintId::of(&large_stack_arrays::LARGE_STACK_ARRAYS),
1244+
LintId::of(&let_underscore::LET_UNDERSCORE_DROP),
12421245
LintId::of(&literal_representation::LARGE_DIGIT_GROUPS),
12431246
LintId::of(&literal_representation::UNREADABLE_LITERAL),
12441247
LintId::of(&loops::EXPLICIT_INTO_ITER_LOOP),
@@ -1527,6 +1530,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
15271530
LintId::of(&single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS),
15281531
LintId::of(&slow_vector_initialization::SLOW_VECTOR_INITIALIZATION),
15291532
LintId::of(&stable_sort_primitive::STABLE_SORT_PRIMITIVE),
1533+
LintId::of(&strings::STRING_FROM_UTF8_AS_BYTES),
15301534
LintId::of(&suspicious_trait_impl::SUSPICIOUS_ARITHMETIC_IMPL),
15311535
LintId::of(&suspicious_trait_impl::SUSPICIOUS_OP_ASSIGN_IMPL),
15321536
LintId::of(&swap::ALMOST_SWAPPED),
@@ -1752,6 +1756,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
17521756
LintId::of(&reference::DEREF_ADDROF),
17531757
LintId::of(&reference::REF_IN_DEREF),
17541758
LintId::of(&repeat_once::REPEAT_ONCE),
1759+
LintId::of(&strings::STRING_FROM_UTF8_AS_BYTES),
17551760
LintId::of(&swap::MANUAL_SWAP),
17561761
LintId::of(&temporary_assignment::TEMPORARY_ASSIGNMENT),
17571762
LintId::of(&transmute::CROSSPOINTER_TRANSMUTE),

clippy_lints/src/loops.rs

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ use crate::utils::sugg::Sugg;
44
use crate::utils::usage::{is_unused, mutated_variables};
55
use crate::utils::{
66
contains_name, get_enclosing_block, get_parent_expr, get_trait_def_id, has_iter_method, higher, implements_trait,
7-
indent_of, is_integer_const, is_no_std_crate, is_refutable, is_type_diagnostic_item, last_path_segment,
8-
match_trait_method, match_type, match_var, multispan_sugg, qpath_res, single_segment_path, snippet,
9-
snippet_with_applicability, snippet_with_macro_callsite, span_lint, span_lint_and_help, span_lint_and_sugg,
10-
span_lint_and_then, sugg, SpanlessEq,
7+
indent_of, is_in_panic_handler, is_integer_const, is_no_std_crate, is_refutable, is_type_diagnostic_item,
8+
last_path_segment, match_trait_method, match_type, match_var, multispan_sugg, qpath_res, single_segment_path,
9+
snippet, snippet_with_applicability, snippet_with_macro_callsite, span_lint, span_lint_and_help,
10+
span_lint_and_sugg, span_lint_and_then, sugg, SpanlessEq,
1111
};
1212
use if_chain::if_chain;
1313
use rustc_ast::ast;
@@ -543,17 +543,15 @@ impl<'tcx> LateLintPass<'tcx> for Loops {
543543
// (also matches an explicit "match" instead of "if let")
544544
// (even if the "match" or "if let" is used for declaration)
545545
if let ExprKind::Loop(ref block, _, LoopSource::Loop) = expr.kind {
546-
// also check for empty `loop {}` statements
547-
// TODO(issue #6161): Enable for no_std crates (outside of #[panic_handler])
548-
if block.stmts.is_empty() && block.expr.is_none() && !is_no_std_crate(cx.tcx.hir().krate()) {
549-
span_lint_and_help(
550-
cx,
551-
EMPTY_LOOP,
552-
expr.span,
553-
"empty `loop {}` wastes CPU cycles",
554-
None,
555-
"You should either use `panic!()` or add `std::thread::sleep(..);` to the loop body.",
556-
);
546+
// also check for empty `loop {}` statements, skipping those in #[panic_handler]
547+
if block.stmts.is_empty() && block.expr.is_none() && !is_in_panic_handler(cx, expr) {
548+
let msg = "empty `loop {}` wastes CPU cycles";
549+
let help = if is_no_std_crate(cx.tcx.hir().krate()) {
550+
"you should either use `panic!()` or add a call pausing or sleeping the thread to the loop body"
551+
} else {
552+
"you should either use `panic!()` or add `std::thread::sleep(..);` to the loop body"
553+
};
554+
span_lint_and_help(cx, EMPTY_LOOP, expr.span, msg, None, help);
557555
}
558556

559557
// extract the expression from the first statement (if any) in a block

clippy_lints/src/manual_async_fn.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::utils::paths::FUTURE_FROM_GENERATOR;
2-
use crate::utils::{match_function_call, snippet_block, snippet_opt, span_lint_and_then};
2+
use crate::utils::{match_function_call, position_before_rarrow, snippet_block, snippet_opt, span_lint_and_then};
33
use if_chain::if_chain;
44
use rustc_errors::Applicability;
55
use rustc_hir::intravisit::FnKind;
@@ -69,7 +69,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualAsyncFn {
6969
|diag| {
7070
if_chain! {
7171
if let Some(header_snip) = snippet_opt(cx, header_span);
72-
if let Some(ret_pos) = header_snip.rfind("->");
72+
if let Some(ret_pos) = position_before_rarrow(header_snip.clone());
7373
if let Some((ret_sugg, ret_snip)) = suggested_ret(cx, output);
7474
then {
7575
let help = format!("make the function `async` and {}", ret_sugg);
@@ -194,7 +194,7 @@ fn suggested_ret(cx: &LateContext<'_>, output: &Ty<'_>) -> Option<(&'static str,
194194
},
195195
_ => {
196196
let sugg = "return the output of the future directly";
197-
snippet_opt(cx, output.span).map(|snip| (sugg, format!("-> {}", snip)))
197+
snippet_opt(cx, output.span).map(|snip| (sugg, format!(" -> {}", snip)))
198198
},
199199
}
200200
}

clippy_lints/src/map_clone.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,11 @@ impl<'tcx> LateLintPass<'tcx> for MapClone {
8080
&& match_trait_method(cx, closure_expr, &paths::CLONE_TRAIT) {
8181

8282
let obj_ty = cx.typeck_results().expr_ty(&obj[0]);
83-
if let ty::Ref(_, ty, _) = obj_ty.kind() {
84-
let copy = is_copy(cx, ty);
85-
lint(cx, e.span, args[0].span, copy);
83+
if let ty::Ref(_, ty, mutability) = obj_ty.kind() {
84+
if matches!(mutability, Mutability::Not) {
85+
let copy = is_copy(cx, ty);
86+
lint(cx, e.span, args[0].span, copy);
87+
}
8688
} else {
8789
lint_needless_cloning(cx, e.span, args[0].span);
8890
}

0 commit comments

Comments
 (0)