Skip to content

Commit

Permalink
Merge commit '5034d47f721ff4c3a3ff2aca9ef2ef3e1d067f9f' into clippyup
Browse files Browse the repository at this point in the history
  • Loading branch information
flip1995 committed Sep 10, 2020
1 parent 961f183 commit a12828a
Show file tree
Hide file tree
Showing 54 changed files with 1,360 additions and 416 deletions.
110 changes: 107 additions & 3 deletions CHANGELOG.md
Expand Up @@ -6,11 +6,113 @@ document.

## Unreleased / In Rust Nightly

[c2c07fa...master](https://github.com/rust-lang/rust-clippy/compare/c2c07fa...master)
[09bd400...master](https://github.com/rust-lang/rust-clippy/compare/09bd400...master)

## Rust 1.47

Current beta, release 2020-10-08

[c2c07fa...09bd400](https://github.com/rust-lang/rust-clippy/compare/c2c07fa...09bd400)

### New lints

* [`derive_ord_xor_partial_ord`] [#5848](https://github.com/rust-lang/rust-clippy/pull/5848)
* [`trait_duplication_in_bounds`] [#5852](https://github.com/rust-lang/rust-clippy/pull/5852)
* [`map_identity`] [#5694](https://github.com/rust-lang/rust-clippy/pull/5694)
* [`unit_return_expecting_ord`] [#5737](https://github.com/rust-lang/rust-clippy/pull/5737)
* [`pattern_type_mismatch`] [#4841](https://github.com/rust-lang/rust-clippy/pull/4841)
* [`repeat_once`] [#5773](https://github.com/rust-lang/rust-clippy/pull/5773)
* [`same_item_push`] [#5825](https://github.com/rust-lang/rust-clippy/pull/5825)
* [`needless_arbitrary_self_type`] [#5869](https://github.com/rust-lang/rust-clippy/pull/5869)
* [`match_like_matches_macro`] [#5769](https://github.com/rust-lang/rust-clippy/pull/5769)
* [`stable_sort_primitive`] [#5809](https://github.com/rust-lang/rust-clippy/pull/5809)
* [`blanket_clippy_restriction_lints`] [#5750](https://github.com/rust-lang/rust-clippy/pull/5750)
* [`option_if_let_else`] [#5301](https://github.com/rust-lang/rust-clippy/pull/5301)

### Moves and Deprecations

* Deprecate [`regex_macro`] lint
[#5760](https://github.com/rust-lang/rust-clippy/pull/5760)
* Move [`range_minus_one`] to `pedantic`
[#5752](https://github.com/rust-lang/rust-clippy/pull/5752)

### Enhancements

* Improve [`needless_collect`] by catching `collect` calls followed by `iter` or `into_iter` calls
[#5837](https://github.com/rust-lang/rust-clippy/pull/5837)
* [`panic`], [`todo`], [`unimplemented`] and [`unreachable`] now detect calls with formatting
[#5811](https://github.com/rust-lang/rust-clippy/pull/5811)
* Detect more cases of [`suboptimal_flops`] and [`imprecise_flops`]
[#5443](https://github.com/rust-lang/rust-clippy/pull/5443)
* Handle asymmetrical implementations of `PartialEq` in [`cmp_owned`]
[#5701](https://github.com/rust-lang/rust-clippy/pull/5701)
* Make it possible to allow [`unsafe_derive_deserialize`]
[#5870](https://github.com/rust-lang/rust-clippy/pull/5870)
* Catch `ord.min(a).max(b)` where a < b in [`min_max`]
[#5871](https://github.com/rust-lang/rust-clippy/pull/5871)
* Make [`clone_on_copy`] suggestion machine applicable
[#5745](https://github.com/rust-lang/rust-clippy/pull/5745)
* Enable [`len_zero`] on ranges now that `is_empty` is stable on them
[#5961](https://github.com/rust-lang/rust-clippy/pull/5961)

### False Positive Fixes

* Avoid triggering [`or_fun_call`] with const fns that take no arguments
[#5889](https://github.com/rust-lang/rust-clippy/pull/5889)
* Fix [`redundant_closure_call`] false positive for closures that have multiple calls
[#5800](https://github.com/rust-lang/rust-clippy/pull/5800)
* Don't lint cases involving `ManuallyDrop` in [`redundant_clone`]
[#5824](https://github.com/rust-lang/rust-clippy/pull/5824)
* Treat a single expression the same as a single statement in the 2nd arm of a match in [`single_match_else`]
[#5771](https://github.com/rust-lang/rust-clippy/pull/5771)
* Don't trigger [`unnested_or_patterns`] if the feature `or_patterns` is not enabled
[#5758](https://github.com/rust-lang/rust-clippy/pull/5758)
* Avoid linting if key borrows in [`unnecessary_sort_by`]
[#5756](https://github.com/rust-lang/rust-clippy/pull/5756)
* Consider `Try` impl for `Poll` when generating suggestions in [`try_err`]
[#5857](https://github.com/rust-lang/rust-clippy/pull/5857)
* Take input lifetimes into account in `manual_async_fn`
[#5859](https://github.com/rust-lang/rust-clippy/pull/5859)
* Fix multiple false positives in [`type_repetition_in_bounds`] and add a configuration option
[#5761](https://github.com/rust-lang/rust-clippy/pull/5761)
* Limit the [`suspicious_arithmetic_impl`] lint to one binary operation
[#5820](https://github.com/rust-lang/rust-clippy/pull/5820)

### Suggestion Fixes/Improvements

* Improve readability of [`shadow_unrelated`] suggestion by truncating the RHS snippet
[#5788](https://github.com/rust-lang/rust-clippy/pull/5788)
* Suggest `filter_map` instead of `flat_map` when mapping to `Option` in [`map_flatten`]
[#5846](https://github.com/rust-lang/rust-clippy/pull/5846)
* Ensure suggestion is shown correctly for long method call chains in [`iter_nth_zero`]
[#5793](https://github.com/rust-lang/rust-clippy/pull/5793)
* Drop borrow operator in suggestions of [`redundant_pattern_matching`]
[#5815](https://github.com/rust-lang/rust-clippy/pull/5815)
* Add suggestion for [`iter_skip_next`]
[#5843](https://github.com/rust-lang/rust-clippy/pull/5843)
* Improve [`collapsible_if`] fix suggestion
[#5732](https://github.com/rust-lang/rust-clippy/pull/5732)

### ICE Fixes

* Fix ICE caused by [`needless_collect`]
[#5877](https://github.com/rust-lang/rust-clippy/pull/5877)
* Fix ICE caused by [`unnested_or_patterns`]
[#5784](https://github.com/rust-lang/rust-clippy/pull/5784)

### Documentation Improvements

* Fix grammar of [`await_holding_lock`] documentation
[#5748](https://github.com/rust-lang/rust-clippy/pull/5748)

### Others

* Make lints adhere to the rustc dev guide
[#5888](https://github.com/rust-lang/rust-clippy/pull/5888)

## Rust 1.46

Current beta, release 2020-08-27
Current stable, released 2020-08-27

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

Expand Down Expand Up @@ -72,7 +174,7 @@ Current beta, release 2020-08-27

## Rust 1.45

Current stable, released 2020-07-16
Released 2020-07-16

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

Expand Down Expand Up @@ -1410,6 +1512,7 @@ Released 2018-09-13
[`assertions_on_constants`]: https://rust-lang.github.io/rust-clippy/master/index.html#assertions_on_constants
[`assign_op_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#assign_op_pattern
[`assign_ops`]: https://rust-lang.github.io/rust-clippy/master/index.html#assign_ops
[`async_yields_async`]: https://rust-lang.github.io/rust-clippy/master/index.html#async_yields_async
[`await_holding_lock`]: https://rust-lang.github.io/rust-clippy/master/index.html#await_holding_lock
[`bad_bit_mask`]: https://rust-lang.github.io/rust-clippy/master/index.html#bad_bit_mask
[`bind_instead_of_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#bind_instead_of_map
Expand Down Expand Up @@ -1444,6 +1547,7 @@ Released 2018-09-13
[`collapsible_if`]: https://rust-lang.github.io/rust-clippy/master/index.html#collapsible_if
[`comparison_chain`]: https://rust-lang.github.io/rust-clippy/master/index.html#comparison_chain
[`copy_iterator`]: https://rust-lang.github.io/rust-clippy/master/index.html#copy_iterator
[`create_dir`]: https://rust-lang.github.io/rust-clippy/master/index.html#create_dir
[`crosspointer_transmute`]: https://rust-lang.github.io/rust-clippy/master/index.html#crosspointer_transmute
[`dbg_macro`]: https://rust-lang.github.io/rust-clippy/master/index.html#dbg_macro
[`debug_assert_with_mut_call`]: https://rust-lang.github.io/rust-clippy/master/index.html#debug_assert_with_mut_call
Expand Down
86 changes: 86 additions & 0 deletions clippy_lints/src/async_yields_async.rs
@@ -0,0 +1,86 @@
use crate::utils::{implements_trait, snippet, span_lint_and_then};
use rustc_errors::Applicability;
use rustc_hir::{AsyncGeneratorKind, Body, BodyId, ExprKind, GeneratorKind, QPath};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};

declare_clippy_lint! {
/// **What it does:** Checks for async blocks that yield values of types
/// that can themselves be awaited.
///
/// **Why is this bad?** An await is likely missing.
///
/// **Known problems:** None.
///
/// **Example:**
///
/// ```rust
/// async fn foo() {}
///
/// fn bar() {
/// let x = async {
/// foo()
/// };
/// }
/// ```
/// Use instead:
/// ```rust
/// async fn foo() {}
///
/// fn bar() {
/// let x = async {
/// foo().await
/// };
/// }
/// ```
pub ASYNC_YIELDS_ASYNC,
correctness,
"async blocks that return a type that can be awaited"
}

declare_lint_pass!(AsyncYieldsAsync => [ASYNC_YIELDS_ASYNC]);

impl<'tcx> LateLintPass<'tcx> for AsyncYieldsAsync {
fn check_body(&mut self, cx: &LateContext<'tcx>, body: &'tcx Body<'_>) {
use AsyncGeneratorKind::{Block, Closure};
// For functions, with explicitly defined types, don't warn.
// XXXkhuey maybe we should?
if let Some(GeneratorKind::Async(Block | Closure)) = body.generator_kind {
if let Some(future_trait_def_id) = cx.tcx.lang_items().future_trait() {
let body_id = BodyId {
hir_id: body.value.hir_id,
};
let def_id = cx.tcx.hir().body_owner_def_id(body_id);
let typeck_results = cx.tcx.typeck(def_id);
let expr_ty = typeck_results.expr_ty(&body.value);

if implements_trait(cx, expr_ty, future_trait_def_id, &[]) {
let return_expr_span = match &body.value.kind {
// XXXkhuey there has to be a better way.
ExprKind::Block(block, _) => block.expr.map(|e| e.span),
ExprKind::Path(QPath::Resolved(_, path)) => Some(path.span),
_ => None,
};
if let Some(return_expr_span) = return_expr_span {
span_lint_and_then(
cx,
ASYNC_YIELDS_ASYNC,
return_expr_span,
"an async construct yields a type which is itself awaitable",
|db| {
db.span_label(body.value.span, "outer async construct");
db.span_label(return_expr_span, "awaitable value not awaited");
db.span_suggestion(
return_expr_span,
"consider awaiting this value",
format!("{}.await", snippet(cx, return_expr_span, "..")),
Applicability::MaybeIncorrect,
);
},
);
}
}
}
}
}
}
38 changes: 22 additions & 16 deletions clippy_lints/src/attrs.rs
Expand Up @@ -71,8 +71,9 @@ declare_clippy_lint! {
/// **What it does:** Checks for `extern crate` and `use` items annotated with
/// lint attributes.
///
/// This lint permits `#[allow(unused_imports)]`, `#[allow(deprecated)]` and
/// `#[allow(unreachable_pub)]` on `use` items and `#[allow(unused_imports)]` on
/// This lint permits `#[allow(unused_imports)]`, `#[allow(deprecated)]`,
/// `#[allow(unreachable_pub)]`, `#[allow(clippy::wildcard_imports)]` and
/// `#[allow(clippy::enum_glob_use)]` on `use` items and `#[allow(unused_imports)]` on
/// `extern crate` items with a `#[macro_use]` attribute.
///
/// **Why is this bad?** Lint attributes have no effect on crate imports. Most
Expand Down Expand Up @@ -318,7 +319,8 @@ impl<'tcx> LateLintPass<'tcx> for Attributes {
if let Some(ident) = attr.ident() {
match &*ident.as_str() {
"allow" | "warn" | "deny" | "forbid" => {
// permit `unused_imports`, `deprecated` and `unreachable_pub` for `use` items
// permit `unused_imports`, `deprecated`, `unreachable_pub`,
// `clippy::wildcard_imports`, and `clippy::enum_glob_use` for `use` items
// and `unused_imports` for `extern crate` items with `macro_use`
for lint in lint_list {
match item.kind {
Expand All @@ -327,6 +329,9 @@ impl<'tcx> LateLintPass<'tcx> for Attributes {
|| is_word(lint, sym!(deprecated))
|| is_word(lint, sym!(unreachable_pub))
|| is_word(lint, sym!(unused))
|| extract_clippy_lint(lint)
.map_or(false, |s| s == "wildcard_imports")
|| extract_clippy_lint(lint).map_or(false, |s| s == "enum_glob_use")
{
return;
}
Expand Down Expand Up @@ -387,24 +392,25 @@ impl<'tcx> LateLintPass<'tcx> for Attributes {
}
}

fn check_clippy_lint_names(cx: &LateContext<'_>, ident: &str, items: &[NestedMetaItem]) {
fn extract_name(lint: &NestedMetaItem) -> Option<SymbolStr> {
if_chain! {
if let Some(meta_item) = lint.meta_item();
if meta_item.path.segments.len() > 1;
if let tool_name = meta_item.path.segments[0].ident;
if tool_name.as_str() == "clippy";
let lint_name = meta_item.path.segments.last().unwrap().ident.name;
then {
return Some(lint_name.as_str());
}
/// Returns the lint name if it is clippy lint.
fn extract_clippy_lint(lint: &NestedMetaItem) -> Option<SymbolStr> {
if_chain! {
if let Some(meta_item) = lint.meta_item();
if meta_item.path.segments.len() > 1;
if let tool_name = meta_item.path.segments[0].ident;
if tool_name.as_str() == "clippy";
let lint_name = meta_item.path.segments.last().unwrap().ident.name;
then {
return Some(lint_name.as_str());
}
None
}
None
}

fn check_clippy_lint_names(cx: &LateContext<'_>, ident: &str, items: &[NestedMetaItem]) {
let lint_store = cx.lints();
for lint in items {
if let Some(lint_name) = extract_name(lint) {
if let Some(lint_name) = extract_clippy_lint(lint) {
if let CheckLintNameResult::Tool(Err((None, _))) =
lint_store.check_lint_name(&lint_name, Some(sym!(clippy)))
{
Expand Down
51 changes: 51 additions & 0 deletions clippy_lints/src/create_dir.rs
@@ -0,0 +1,51 @@
use crate::utils::{match_def_path, paths, snippet, span_lint_and_sugg};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};

declare_clippy_lint! {
/// **What it does:** Checks usage of `std::fs::create_dir` and suggest using `std::fs::create_dir_all` instead.
///
/// **Why is this bad?** Sometimes `std::fs::crate_dir` is mistakenly chosen over `std::fs::create_dir_all`.
///
/// **Known problems:** None.
///
/// **Example:**
///
/// ```rust
/// std::fs::create_dir("foo");
/// ```
/// Use instead:
/// ```rust
/// std::fs::create_dir_all("foo");
/// ```
pub CREATE_DIR,
restriction,
"calling `std::fs::create_dir` instead of `std::fs::create_dir_all`"
}

declare_lint_pass!(CreateDir => [CREATE_DIR]);

impl LateLintPass<'_> for CreateDir {
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
if_chain! {
if let ExprKind::Call(ref func, ref args) = expr.kind;
if let ExprKind::Path(ref path) = func.kind;
if let Some(def_id) = cx.qpath_res(path, func.hir_id).opt_def_id();
if match_def_path(cx, def_id, &paths::STD_FS_CREATE_DIR);
then {
span_lint_and_sugg(
cx,
CREATE_DIR,
expr.span,
"calling `std::fs::create_dir` where there may be a better way",
"consider calling `std::fs::create_dir_all` instead",
format!("create_dir_all({})", snippet(cx, args[0].span, "..")),
Applicability::MaybeIncorrect,
)
}
}
}
}

0 comments on commit a12828a

Please sign in to comment.