Skip to content

Commit a1947b3

Browse files
committed
Auto merge of rust-lang#76574 - flip1995:clippyup, r=Manishearth
Update Clippy Biweekly Clippy update r? `@Manishearth`
2 parents ad3a6f7 + ca6c695 commit a1947b3

Some content is hidden

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

54 files changed

+1360
-416
lines changed

src/tools/clippy/CHANGELOG.md

+107-3
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,113 @@ document.
66

77
## Unreleased / In Rust Nightly
88

9-
[c2c07fa...master](https://github.com/rust-lang/rust-clippy/compare/c2c07fa...master)
9+
[09bd400...master](https://github.com/rust-lang/rust-clippy/compare/09bd400...master)
10+
11+
## Rust 1.47
12+
13+
Current beta, release 2020-10-08
14+
15+
[c2c07fa...09bd400](https://github.com/rust-lang/rust-clippy/compare/c2c07fa...09bd400)
16+
17+
### New lints
18+
19+
* [`derive_ord_xor_partial_ord`] [#5848](https://github.com/rust-lang/rust-clippy/pull/5848)
20+
* [`trait_duplication_in_bounds`] [#5852](https://github.com/rust-lang/rust-clippy/pull/5852)
21+
* [`map_identity`] [#5694](https://github.com/rust-lang/rust-clippy/pull/5694)
22+
* [`unit_return_expecting_ord`] [#5737](https://github.com/rust-lang/rust-clippy/pull/5737)
23+
* [`pattern_type_mismatch`] [#4841](https://github.com/rust-lang/rust-clippy/pull/4841)
24+
* [`repeat_once`] [#5773](https://github.com/rust-lang/rust-clippy/pull/5773)
25+
* [`same_item_push`] [#5825](https://github.com/rust-lang/rust-clippy/pull/5825)
26+
* [`needless_arbitrary_self_type`] [#5869](https://github.com/rust-lang/rust-clippy/pull/5869)
27+
* [`match_like_matches_macro`] [#5769](https://github.com/rust-lang/rust-clippy/pull/5769)
28+
* [`stable_sort_primitive`] [#5809](https://github.com/rust-lang/rust-clippy/pull/5809)
29+
* [`blanket_clippy_restriction_lints`] [#5750](https://github.com/rust-lang/rust-clippy/pull/5750)
30+
* [`option_if_let_else`] [#5301](https://github.com/rust-lang/rust-clippy/pull/5301)
31+
32+
### Moves and Deprecations
33+
34+
* Deprecate [`regex_macro`] lint
35+
[#5760](https://github.com/rust-lang/rust-clippy/pull/5760)
36+
* Move [`range_minus_one`] to `pedantic`
37+
[#5752](https://github.com/rust-lang/rust-clippy/pull/5752)
38+
39+
### Enhancements
40+
41+
* Improve [`needless_collect`] by catching `collect` calls followed by `iter` or `into_iter` calls
42+
[#5837](https://github.com/rust-lang/rust-clippy/pull/5837)
43+
* [`panic`], [`todo`], [`unimplemented`] and [`unreachable`] now detect calls with formatting
44+
[#5811](https://github.com/rust-lang/rust-clippy/pull/5811)
45+
* Detect more cases of [`suboptimal_flops`] and [`imprecise_flops`]
46+
[#5443](https://github.com/rust-lang/rust-clippy/pull/5443)
47+
* Handle asymmetrical implementations of `PartialEq` in [`cmp_owned`]
48+
[#5701](https://github.com/rust-lang/rust-clippy/pull/5701)
49+
* Make it possible to allow [`unsafe_derive_deserialize`]
50+
[#5870](https://github.com/rust-lang/rust-clippy/pull/5870)
51+
* Catch `ord.min(a).max(b)` where a < b in [`min_max`]
52+
[#5871](https://github.com/rust-lang/rust-clippy/pull/5871)
53+
* Make [`clone_on_copy`] suggestion machine applicable
54+
[#5745](https://github.com/rust-lang/rust-clippy/pull/5745)
55+
* Enable [`len_zero`] on ranges now that `is_empty` is stable on them
56+
[#5961](https://github.com/rust-lang/rust-clippy/pull/5961)
57+
58+
### False Positive Fixes
59+
60+
* Avoid triggering [`or_fun_call`] with const fns that take no arguments
61+
[#5889](https://github.com/rust-lang/rust-clippy/pull/5889)
62+
* Fix [`redundant_closure_call`] false positive for closures that have multiple calls
63+
[#5800](https://github.com/rust-lang/rust-clippy/pull/5800)
64+
* Don't lint cases involving `ManuallyDrop` in [`redundant_clone`]
65+
[#5824](https://github.com/rust-lang/rust-clippy/pull/5824)
66+
* Treat a single expression the same as a single statement in the 2nd arm of a match in [`single_match_else`]
67+
[#5771](https://github.com/rust-lang/rust-clippy/pull/5771)
68+
* Don't trigger [`unnested_or_patterns`] if the feature `or_patterns` is not enabled
69+
[#5758](https://github.com/rust-lang/rust-clippy/pull/5758)
70+
* Avoid linting if key borrows in [`unnecessary_sort_by`]
71+
[#5756](https://github.com/rust-lang/rust-clippy/pull/5756)
72+
* Consider `Try` impl for `Poll` when generating suggestions in [`try_err`]
73+
[#5857](https://github.com/rust-lang/rust-clippy/pull/5857)
74+
* Take input lifetimes into account in `manual_async_fn`
75+
[#5859](https://github.com/rust-lang/rust-clippy/pull/5859)
76+
* Fix multiple false positives in [`type_repetition_in_bounds`] and add a configuration option
77+
[#5761](https://github.com/rust-lang/rust-clippy/pull/5761)
78+
* Limit the [`suspicious_arithmetic_impl`] lint to one binary operation
79+
[#5820](https://github.com/rust-lang/rust-clippy/pull/5820)
80+
81+
### Suggestion Fixes/Improvements
82+
83+
* Improve readability of [`shadow_unrelated`] suggestion by truncating the RHS snippet
84+
[#5788](https://github.com/rust-lang/rust-clippy/pull/5788)
85+
* Suggest `filter_map` instead of `flat_map` when mapping to `Option` in [`map_flatten`]
86+
[#5846](https://github.com/rust-lang/rust-clippy/pull/5846)
87+
* Ensure suggestion is shown correctly for long method call chains in [`iter_nth_zero`]
88+
[#5793](https://github.com/rust-lang/rust-clippy/pull/5793)
89+
* Drop borrow operator in suggestions of [`redundant_pattern_matching`]
90+
[#5815](https://github.com/rust-lang/rust-clippy/pull/5815)
91+
* Add suggestion for [`iter_skip_next`]
92+
[#5843](https://github.com/rust-lang/rust-clippy/pull/5843)
93+
* Improve [`collapsible_if`] fix suggestion
94+
[#5732](https://github.com/rust-lang/rust-clippy/pull/5732)
95+
96+
### ICE Fixes
97+
98+
* Fix ICE caused by [`needless_collect`]
99+
[#5877](https://github.com/rust-lang/rust-clippy/pull/5877)
100+
* Fix ICE caused by [`unnested_or_patterns`]
101+
[#5784](https://github.com/rust-lang/rust-clippy/pull/5784)
102+
103+
### Documentation Improvements
104+
105+
* Fix grammar of [`await_holding_lock`] documentation
106+
[#5748](https://github.com/rust-lang/rust-clippy/pull/5748)
107+
108+
### Others
109+
110+
* Make lints adhere to the rustc dev guide
111+
[#5888](https://github.com/rust-lang/rust-clippy/pull/5888)
10112

11113
## Rust 1.46
12114

13-
Current beta, release 2020-08-27
115+
Current stable, released 2020-08-27
14116

15117
[7ea7cd1...c2c07fa](https://github.com/rust-lang/rust-clippy/compare/7ea7cd1...c2c07fa)
16118

@@ -72,7 +174,7 @@ Current beta, release 2020-08-27
72174

73175
## Rust 1.45
74176

75-
Current stable, released 2020-07-16
177+
Released 2020-07-16
76178

77179
[891e1a8...7ea7cd1](https://github.com/rust-lang/rust-clippy/compare/891e1a8...7ea7cd1)
78180

@@ -1410,6 +1512,7 @@ Released 2018-09-13
14101512
[`assertions_on_constants`]: https://rust-lang.github.io/rust-clippy/master/index.html#assertions_on_constants
14111513
[`assign_op_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#assign_op_pattern
14121514
[`assign_ops`]: https://rust-lang.github.io/rust-clippy/master/index.html#assign_ops
1515+
[`async_yields_async`]: https://rust-lang.github.io/rust-clippy/master/index.html#async_yields_async
14131516
[`await_holding_lock`]: https://rust-lang.github.io/rust-clippy/master/index.html#await_holding_lock
14141517
[`bad_bit_mask`]: https://rust-lang.github.io/rust-clippy/master/index.html#bad_bit_mask
14151518
[`bind_instead_of_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#bind_instead_of_map
@@ -1444,6 +1547,7 @@ Released 2018-09-13
14441547
[`collapsible_if`]: https://rust-lang.github.io/rust-clippy/master/index.html#collapsible_if
14451548
[`comparison_chain`]: https://rust-lang.github.io/rust-clippy/master/index.html#comparison_chain
14461549
[`copy_iterator`]: https://rust-lang.github.io/rust-clippy/master/index.html#copy_iterator
1550+
[`create_dir`]: https://rust-lang.github.io/rust-clippy/master/index.html#create_dir
14471551
[`crosspointer_transmute`]: https://rust-lang.github.io/rust-clippy/master/index.html#crosspointer_transmute
14481552
[`dbg_macro`]: https://rust-lang.github.io/rust-clippy/master/index.html#dbg_macro
14491553
[`debug_assert_with_mut_call`]: https://rust-lang.github.io/rust-clippy/master/index.html#debug_assert_with_mut_call
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
use crate::utils::{implements_trait, snippet, span_lint_and_then};
2+
use rustc_errors::Applicability;
3+
use rustc_hir::{AsyncGeneratorKind, Body, BodyId, ExprKind, GeneratorKind, QPath};
4+
use rustc_lint::{LateContext, LateLintPass};
5+
use rustc_session::{declare_lint_pass, declare_tool_lint};
6+
7+
declare_clippy_lint! {
8+
/// **What it does:** Checks for async blocks that yield values of types
9+
/// that can themselves be awaited.
10+
///
11+
/// **Why is this bad?** An await is likely missing.
12+
///
13+
/// **Known problems:** None.
14+
///
15+
/// **Example:**
16+
///
17+
/// ```rust
18+
/// async fn foo() {}
19+
///
20+
/// fn bar() {
21+
/// let x = async {
22+
/// foo()
23+
/// };
24+
/// }
25+
/// ```
26+
/// Use instead:
27+
/// ```rust
28+
/// async fn foo() {}
29+
///
30+
/// fn bar() {
31+
/// let x = async {
32+
/// foo().await
33+
/// };
34+
/// }
35+
/// ```
36+
pub ASYNC_YIELDS_ASYNC,
37+
correctness,
38+
"async blocks that return a type that can be awaited"
39+
}
40+
41+
declare_lint_pass!(AsyncYieldsAsync => [ASYNC_YIELDS_ASYNC]);
42+
43+
impl<'tcx> LateLintPass<'tcx> for AsyncYieldsAsync {
44+
fn check_body(&mut self, cx: &LateContext<'tcx>, body: &'tcx Body<'_>) {
45+
use AsyncGeneratorKind::{Block, Closure};
46+
// For functions, with explicitly defined types, don't warn.
47+
// XXXkhuey maybe we should?
48+
if let Some(GeneratorKind::Async(Block | Closure)) = body.generator_kind {
49+
if let Some(future_trait_def_id) = cx.tcx.lang_items().future_trait() {
50+
let body_id = BodyId {
51+
hir_id: body.value.hir_id,
52+
};
53+
let def_id = cx.tcx.hir().body_owner_def_id(body_id);
54+
let typeck_results = cx.tcx.typeck(def_id);
55+
let expr_ty = typeck_results.expr_ty(&body.value);
56+
57+
if implements_trait(cx, expr_ty, future_trait_def_id, &[]) {
58+
let return_expr_span = match &body.value.kind {
59+
// XXXkhuey there has to be a better way.
60+
ExprKind::Block(block, _) => block.expr.map(|e| e.span),
61+
ExprKind::Path(QPath::Resolved(_, path)) => Some(path.span),
62+
_ => None,
63+
};
64+
if let Some(return_expr_span) = return_expr_span {
65+
span_lint_and_then(
66+
cx,
67+
ASYNC_YIELDS_ASYNC,
68+
return_expr_span,
69+
"an async construct yields a type which is itself awaitable",
70+
|db| {
71+
db.span_label(body.value.span, "outer async construct");
72+
db.span_label(return_expr_span, "awaitable value not awaited");
73+
db.span_suggestion(
74+
return_expr_span,
75+
"consider awaiting this value",
76+
format!("{}.await", snippet(cx, return_expr_span, "..")),
77+
Applicability::MaybeIncorrect,
78+
);
79+
},
80+
);
81+
}
82+
}
83+
}
84+
}
85+
}
86+
}

src/tools/clippy/clippy_lints/src/attrs.rs

+22-16
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,9 @@ declare_clippy_lint! {
7171
/// **What it does:** Checks for `extern crate` and `use` items annotated with
7272
/// lint attributes.
7373
///
74-
/// This lint permits `#[allow(unused_imports)]`, `#[allow(deprecated)]` and
75-
/// `#[allow(unreachable_pub)]` on `use` items and `#[allow(unused_imports)]` on
74+
/// This lint permits `#[allow(unused_imports)]`, `#[allow(deprecated)]`,
75+
/// `#[allow(unreachable_pub)]`, `#[allow(clippy::wildcard_imports)]` and
76+
/// `#[allow(clippy::enum_glob_use)]` on `use` items and `#[allow(unused_imports)]` on
7677
/// `extern crate` items with a `#[macro_use]` attribute.
7778
///
7879
/// **Why is this bad?** Lint attributes have no effect on crate imports. Most
@@ -318,7 +319,8 @@ impl<'tcx> LateLintPass<'tcx> for Attributes {
318319
if let Some(ident) = attr.ident() {
319320
match &*ident.as_str() {
320321
"allow" | "warn" | "deny" | "forbid" => {
321-
// permit `unused_imports`, `deprecated` and `unreachable_pub` for `use` items
322+
// permit `unused_imports`, `deprecated`, `unreachable_pub`,
323+
// `clippy::wildcard_imports`, and `clippy::enum_glob_use` for `use` items
322324
// and `unused_imports` for `extern crate` items with `macro_use`
323325
for lint in lint_list {
324326
match item.kind {
@@ -327,6 +329,9 @@ impl<'tcx> LateLintPass<'tcx> for Attributes {
327329
|| is_word(lint, sym!(deprecated))
328330
|| is_word(lint, sym!(unreachable_pub))
329331
|| is_word(lint, sym!(unused))
332+
|| extract_clippy_lint(lint)
333+
.map_or(false, |s| s == "wildcard_imports")
334+
|| extract_clippy_lint(lint).map_or(false, |s| s == "enum_glob_use")
330335
{
331336
return;
332337
}
@@ -387,24 +392,25 @@ impl<'tcx> LateLintPass<'tcx> for Attributes {
387392
}
388393
}
389394

390-
fn check_clippy_lint_names(cx: &LateContext<'_>, ident: &str, items: &[NestedMetaItem]) {
391-
fn extract_name(lint: &NestedMetaItem) -> Option<SymbolStr> {
392-
if_chain! {
393-
if let Some(meta_item) = lint.meta_item();
394-
if meta_item.path.segments.len() > 1;
395-
if let tool_name = meta_item.path.segments[0].ident;
396-
if tool_name.as_str() == "clippy";
397-
let lint_name = meta_item.path.segments.last().unwrap().ident.name;
398-
then {
399-
return Some(lint_name.as_str());
400-
}
395+
/// Returns the lint name if it is clippy lint.
396+
fn extract_clippy_lint(lint: &NestedMetaItem) -> Option<SymbolStr> {
397+
if_chain! {
398+
if let Some(meta_item) = lint.meta_item();
399+
if meta_item.path.segments.len() > 1;
400+
if let tool_name = meta_item.path.segments[0].ident;
401+
if tool_name.as_str() == "clippy";
402+
let lint_name = meta_item.path.segments.last().unwrap().ident.name;
403+
then {
404+
return Some(lint_name.as_str());
401405
}
402-
None
403406
}
407+
None
408+
}
404409

410+
fn check_clippy_lint_names(cx: &LateContext<'_>, ident: &str, items: &[NestedMetaItem]) {
405411
let lint_store = cx.lints();
406412
for lint in items {
407-
if let Some(lint_name) = extract_name(lint) {
413+
if let Some(lint_name) = extract_clippy_lint(lint) {
408414
if let CheckLintNameResult::Tool(Err((None, _))) =
409415
lint_store.check_lint_name(&lint_name, Some(sym!(clippy)))
410416
{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
use crate::utils::{match_def_path, paths, snippet, span_lint_and_sugg};
2+
use if_chain::if_chain;
3+
use rustc_errors::Applicability;
4+
use rustc_hir::{Expr, ExprKind};
5+
use rustc_lint::{LateContext, LateLintPass};
6+
use rustc_session::{declare_lint_pass, declare_tool_lint};
7+
8+
declare_clippy_lint! {
9+
/// **What it does:** Checks usage of `std::fs::create_dir` and suggest using `std::fs::create_dir_all` instead.
10+
///
11+
/// **Why is this bad?** Sometimes `std::fs::crate_dir` is mistakenly chosen over `std::fs::create_dir_all`.
12+
///
13+
/// **Known problems:** None.
14+
///
15+
/// **Example:**
16+
///
17+
/// ```rust
18+
/// std::fs::create_dir("foo");
19+
/// ```
20+
/// Use instead:
21+
/// ```rust
22+
/// std::fs::create_dir_all("foo");
23+
/// ```
24+
pub CREATE_DIR,
25+
restriction,
26+
"calling `std::fs::create_dir` instead of `std::fs::create_dir_all`"
27+
}
28+
29+
declare_lint_pass!(CreateDir => [CREATE_DIR]);
30+
31+
impl LateLintPass<'_> for CreateDir {
32+
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
33+
if_chain! {
34+
if let ExprKind::Call(ref func, ref args) = expr.kind;
35+
if let ExprKind::Path(ref path) = func.kind;
36+
if let Some(def_id) = cx.qpath_res(path, func.hir_id).opt_def_id();
37+
if match_def_path(cx, def_id, &paths::STD_FS_CREATE_DIR);
38+
then {
39+
span_lint_and_sugg(
40+
cx,
41+
CREATE_DIR,
42+
expr.span,
43+
"calling `std::fs::create_dir` where there may be a better way",
44+
"consider calling `std::fs::create_dir_all` instead",
45+
format!("create_dir_all({})", snippet(cx, args[0].span, "..")),
46+
Applicability::MaybeIncorrect,
47+
)
48+
}
49+
}
50+
}
51+
}

0 commit comments

Comments
 (0)