about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md109
-rw-r--r--clippy_lints/src/async_yields_async.rs86
-rw-r--r--clippy_lints/src/default_trait_access.rs4
-rw-r--r--clippy_lints/src/lib.rs5
-rw-r--r--clippy_lints/src/methods/mod.rs10
-rw-r--r--clippy_lints/src/transmute.rs6
-rw-r--r--clippy_lints/src/utils/mod.rs2
-rw-r--r--clippy_lints/src/utils/sugg.rs6
-rw-r--r--src/lintlist/mod.rs7
-rw-r--r--tests/ui/async_yields_async.fixed68
-rw-r--r--tests/ui/async_yields_async.rs68
-rw-r--r--tests/ui/async_yields_async.stderr96
-rw-r--r--tests/ui/collapsible_if.fixed3
-rw-r--r--tests/ui/collapsible_if.rs5
-rw-r--r--tests/ui/collapsible_if.stderr10
-rw-r--r--tests/ui/default_trait_access.fixed106
-rw-r--r--tests/ui/default_trait_access.rs5
-rw-r--r--tests/ui/default_trait_access.stderr26
-rw-r--r--tests/ui/or_fun_call.fixed17
-rw-r--r--tests/ui/or_fun_call.rs17
-rw-r--r--tests/ui/or_fun_call.stderr20
-rw-r--r--tests/ui/transmute_ptr_to_ptr.rs8
-rwxr-xr-xutil/dev7
23 files changed, 629 insertions, 62 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 137b561028a..99a8b1a6293 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -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)
 
@@ -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)
 
@@ -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
diff --git a/clippy_lints/src/async_yields_async.rs b/clippy_lints/src/async_yields_async.rs
new file mode 100644
index 00000000000..88d9d3b5a26
--- /dev/null
+++ b/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,
+                                );
+                            },
+                        );
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/clippy_lints/src/default_trait_access.rs b/clippy_lints/src/default_trait_access.rs
index 067ea903bdd..0b0a1307876 100644
--- a/clippy_lints/src/default_trait_access.rs
+++ b/clippy_lints/src/default_trait_access.rs
@@ -55,8 +55,8 @@ impl<'tcx> LateLintPass<'tcx> for DefaultTraitAccess {
                         // TODO: Work out a way to put "whatever the imported way of referencing
                         // this type in this file" rather than a fully-qualified type.
                         let expr_ty = cx.typeck_results().expr_ty(expr);
-                        if let ty::Adt(..) = expr_ty.kind {
-                            let replacement = format!("{}::default()", expr_ty);
+                        if let ty::Adt(def, ..) = expr_ty.kind {
+                            let replacement = format!("{}::default()", cx.tcx.def_path_str(def.did));
                             span_lint_and_sugg(
                                 cx,
                                 DEFAULT_TRAIT_ACCESS,
diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs
index 577ce6523b4..0eb1d331366 100644
--- a/clippy_lints/src/lib.rs
+++ b/clippy_lints/src/lib.rs
@@ -154,6 +154,7 @@ mod arithmetic;
 mod as_conversions;
 mod assertions_on_constants;
 mod assign_ops;
+mod async_yields_async;
 mod atomic_ordering;
 mod attrs;
 mod await_holding_lock;
@@ -483,6 +484,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         &assertions_on_constants::ASSERTIONS_ON_CONSTANTS,
         &assign_ops::ASSIGN_OP_PATTERN,
         &assign_ops::MISREFACTORED_ASSIGN_OP,
+        &async_yields_async::ASYNC_YIELDS_ASYNC,
         &atomic_ordering::INVALID_ATOMIC_ORDERING,
         &attrs::BLANKET_CLIPPY_RESTRICTION_LINTS,
         &attrs::DEPRECATED_CFG_ATTR,
@@ -1099,6 +1101,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     store.register_late_pass(|| box unwrap_in_result::UnwrapInResult);
     store.register_late_pass(|| box self_assignment::SelfAssignment);
     store.register_late_pass(|| box float_equality_without_abs::FloatEqualityWithoutAbs);
+    store.register_late_pass(|| box async_yields_async::AsyncYieldsAsync);
 
     store.register_group(true, "clippy::restriction", Some("clippy_restriction"), vec![
         LintId::of(&arithmetic::FLOAT_ARITHMETIC),
@@ -1232,6 +1235,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         LintId::of(&assertions_on_constants::ASSERTIONS_ON_CONSTANTS),
         LintId::of(&assign_ops::ASSIGN_OP_PATTERN),
         LintId::of(&assign_ops::MISREFACTORED_ASSIGN_OP),
+        LintId::of(&async_yields_async::ASYNC_YIELDS_ASYNC),
         LintId::of(&atomic_ordering::INVALID_ATOMIC_ORDERING),
         LintId::of(&attrs::BLANKET_CLIPPY_RESTRICTION_LINTS),
         LintId::of(&attrs::DEPRECATED_CFG_ATTR),
@@ -1675,6 +1679,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
 
     store.register_group(true, "clippy::correctness", Some("clippy_correctness"), vec![
         LintId::of(&approx_const::APPROX_CONSTANT),
+        LintId::of(&async_yields_async::ASYNC_YIELDS_ASYNC),
         LintId::of(&atomic_ordering::INVALID_ATOMIC_ORDERING),
         LintId::of(&attrs::DEPRECATED_SEMVER),
         LintId::of(&attrs::MISMATCHED_TARGET_OS),
diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs
index 9996df69470..7c4a78cbdcd 100644
--- a/clippy_lints/src/methods/mod.rs
+++ b/clippy_lints/src/methods/mod.rs
@@ -1324,20 +1324,20 @@ declare_clippy_lint! {
 }
 
 declare_clippy_lint! {
-    /// **What it does:** Warns when using push_str with a single-character string literal,
-    /// and push with a char would work fine.
+    /// **What it does:** Warns when using `push_str` with a single-character string literal,
+    /// and `push` with a `char` would work fine.
     ///
-    /// **Why is this bad?** It's less clear that we are pushing a single character
+    /// **Why is this bad?** It's less clear that we are pushing a single character.
     ///
     /// **Known problems:** None
     ///
     /// **Example:**
-    /// ```
+    /// ```rust
     /// let mut string = String::new();
     /// string.push_str("R");
     /// ```
     /// Could be written as
-    /// ```
+    /// ```rust
     /// let mut string = String::new();
     /// string.push('R');
     /// ```
diff --git a/clippy_lints/src/transmute.rs b/clippy_lints/src/transmute.rs
index 50d9c93f9d4..789d124eae2 100644
--- a/clippy_lints/src/transmute.rs
+++ b/clippy_lints/src/transmute.rs
@@ -331,8 +331,9 @@ impl<'tcx> LateLintPass<'tcx> for Transmute {
             if let Some(def_id) = cx.qpath_res(qpath, path_expr.hir_id).opt_def_id();
             if match_def_path(cx, def_id, &paths::TRANSMUTE);
             then {
-                // Avoid suggesting from/to bits in const contexts.
+                // Avoid suggesting from/to bits and dereferencing raw pointers in const contexts.
                 // See https://github.com/rust-lang/rust/issues/73736 for progress on making them `const fn`.
+                // And see https://github.com/rust-lang/rust/issues/51911 for dereferencing raw pointers.
                 let const_context = in_constant(cx, e.hir_id);
 
                 let from_ty = cx.typeck_results().expr_ty(&args[0]);
@@ -486,7 +487,8 @@ impl<'tcx> LateLintPass<'tcx> for Transmute {
                                     Applicability::Unspecified,
                                 );
                             } else {
-                                if cx.tcx.erase_regions(&from_ty) != cx.tcx.erase_regions(&to_ty) {
+                                if (cx.tcx.erase_regions(&from_ty) != cx.tcx.erase_regions(&to_ty))
+                                    && !const_context {
                                     span_lint_and_then(
                                         cx,
                                         TRANSMUTE_PTR_TO_PTR,
diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs
index 82005257115..fe2ee093157 100644
--- a/clippy_lints/src/utils/mod.rs
+++ b/clippy_lints/src/utils/mod.rs
@@ -899,7 +899,7 @@ pub fn is_ctor_or_promotable_const_function(cx: &LateContext<'_>, expr: &Expr<'_
             return match res {
                 def::Res::Def(DefKind::Variant | DefKind::Ctor(..), ..) => true,
                 // FIXME: check the constness of the arguments, see https://github.com/rust-lang/rust-clippy/pull/5682#issuecomment-638681210
-                def::Res::Def(DefKind::Fn, def_id) if has_no_arguments(cx, def_id) => {
+                def::Res::Def(DefKind::Fn | DefKind::AssocFn, def_id) if has_no_arguments(cx, def_id) => {
                     const_eval::is_const_fn(cx.tcx, def_id)
                 },
                 def::Res::Def(_, def_id) => cx.tcx.is_promotable_const_fn(def_id),
diff --git a/clippy_lints/src/utils/sugg.rs b/clippy_lints/src/utils/sugg.rs
index 2955f8d8e59..811fde388d1 100644
--- a/clippy_lints/src/utils/sugg.rs
+++ b/clippy_lints/src/utils/sugg.rs
@@ -132,7 +132,11 @@ impl<'a> Sugg<'a> {
     pub fn ast(cx: &EarlyContext<'_>, expr: &ast::Expr, default: &'a str) -> Self {
         use rustc_ast::ast::RangeLimits;
 
-        let snippet = snippet(cx, expr.span, default);
+        let snippet = if expr.span.from_expansion() {
+            snippet_with_macro_callsite(cx, expr.span, default)
+        } else {
+            snippet(cx, expr.span, default)
+        };
 
         match expr.kind {
             ast::ExprKind::AddrOf(..)
diff --git a/src/lintlist/mod.rs b/src/lintlist/mod.rs
index 687fac7baa8..dff19ef440f 100644
--- a/src/lintlist/mod.rs
+++ b/src/lintlist/mod.rs
@@ -53,6 +53,13 @@ pub static ref ALL_LINTS: Vec<Lint> = vec![
         module: "assign_ops",
     },
     Lint {
+        name: "async_yields_async",
+        group: "correctness",
+        desc: "async blocks that return a type that can be awaited",
+        deprecation: None,
+        module: "async_yields_async",
+    },
+    Lint {
         name: "await_holding_lock",
         group: "pedantic",
         desc: "Inside an async function, holding a MutexGuard while calling await",
diff --git a/tests/ui/async_yields_async.fixed b/tests/ui/async_yields_async.fixed
new file mode 100644
index 00000000000..9b1a7ac3ba9
--- /dev/null
+++ b/tests/ui/async_yields_async.fixed
@@ -0,0 +1,68 @@
+// run-rustfix
+// edition:2018
+
+#![feature(async_closure)]
+#![warn(clippy::async_yields_async)]
+
+use core::future::Future;
+use core::pin::Pin;
+use core::task::{Context, Poll};
+
+struct CustomFutureType;
+
+impl Future for CustomFutureType {
+    type Output = u8;
+
+    fn poll(self: Pin<&mut Self>, _: &mut Context) -> Poll<Self::Output> {
+        Poll::Ready(3)
+    }
+}
+
+fn custom_future_type_ctor() -> CustomFutureType {
+    CustomFutureType
+}
+
+async fn f() -> CustomFutureType {
+    // Don't warn for functions since you have to explicitly declare their
+    // return types.
+    CustomFutureType
+}
+
+#[rustfmt::skip]
+fn main() {
+    let _f = {
+        3
+    };
+    let _g = async {
+        3
+    };
+    let _h = async {
+        async {
+            3
+        }.await
+    };
+    let _i = async {
+        CustomFutureType.await
+    };
+    let _i = async || {
+        3
+    };
+    let _j = async || {
+        async {
+            3
+        }.await
+    };
+    let _k = async || {
+        CustomFutureType.await
+    };
+    let _l = async || CustomFutureType.await;
+    let _m = async || {
+        println!("I'm bored");
+        // Some more stuff
+
+        // Finally something to await
+        CustomFutureType.await
+    };
+    let _n = async || custom_future_type_ctor();
+    let _o = async || f();
+}
diff --git a/tests/ui/async_yields_async.rs b/tests/ui/async_yields_async.rs
new file mode 100644
index 00000000000..731c094edb4
--- /dev/null
+++ b/tests/ui/async_yields_async.rs
@@ -0,0 +1,68 @@
+// run-rustfix
+// edition:2018
+
+#![feature(async_closure)]
+#![warn(clippy::async_yields_async)]
+
+use core::future::Future;
+use core::pin::Pin;
+use core::task::{Context, Poll};
+
+struct CustomFutureType;
+
+impl Future for CustomFutureType {
+    type Output = u8;
+
+    fn poll(self: Pin<&mut Self>, _: &mut Context) -> Poll<Self::Output> {
+        Poll::Ready(3)
+    }
+}
+
+fn custom_future_type_ctor() -> CustomFutureType {
+    CustomFutureType
+}
+
+async fn f() -> CustomFutureType {
+    // Don't warn for functions since you have to explicitly declare their
+    // return types.
+    CustomFutureType
+}
+
+#[rustfmt::skip]
+fn main() {
+    let _f = {
+        3
+    };
+    let _g = async {
+        3
+    };
+    let _h = async {
+        async {
+            3
+        }
+    };
+    let _i = async {
+        CustomFutureType
+    };
+    let _i = async || {
+        3
+    };
+    let _j = async || {
+        async {
+            3
+        }
+    };
+    let _k = async || {
+        CustomFutureType
+    };
+    let _l = async || CustomFutureType;
+    let _m = async || {
+        println!("I'm bored");
+        // Some more stuff
+
+        // Finally something to await
+        CustomFutureType
+    };
+    let _n = async || custom_future_type_ctor();
+    let _o = async || f();
+}
diff --git a/tests/ui/async_yields_async.stderr b/tests/ui/async_yields_async.stderr
new file mode 100644
index 00000000000..17d0c375106
--- /dev/null
+++ b/tests/ui/async_yields_async.stderr
@@ -0,0 +1,96 @@
+error: an async construct yields a type which is itself awaitable
+  --> $DIR/async_yields_async.rs:40:9
+   |
+LL |        let _h = async {
+   |   ____________________-
+LL |  |         async {
+   |  |_________^
+LL | ||             3
+LL | ||         }
+   | ||_________^ awaitable value not awaited
+LL |  |     };
+   |  |_____- outer async construct
+   |
+   = note: `-D clippy::async-yields-async` implied by `-D warnings`
+help: consider awaiting this value
+   |
+LL |         async {
+LL |             3
+LL |         }.await
+   |
+
+error: an async construct yields a type which is itself awaitable
+  --> $DIR/async_yields_async.rs:45:9
+   |
+LL |       let _i = async {
+   |  ____________________-
+LL | |         CustomFutureType
+   | |         ^^^^^^^^^^^^^^^^
+   | |         |
+   | |         awaitable value not awaited
+   | |         help: consider awaiting this value: `CustomFutureType.await`
+LL | |     };
+   | |_____- outer async construct
+
+error: an async construct yields a type which is itself awaitable
+  --> $DIR/async_yields_async.rs:51:9
+   |
+LL |        let _j = async || {
+   |   _______________________-
+LL |  |         async {
+   |  |_________^
+LL | ||             3
+LL | ||         }
+   | ||_________^ awaitable value not awaited
+LL |  |     };
+   |  |_____- outer async construct
+   |
+help: consider awaiting this value
+   |
+LL |         async {
+LL |             3
+LL |         }.await
+   |
+
+error: an async construct yields a type which is itself awaitable
+  --> $DIR/async_yields_async.rs:56:9
+   |
+LL |       let _k = async || {
+   |  _______________________-
+LL | |         CustomFutureType
+   | |         ^^^^^^^^^^^^^^^^
+   | |         |
+   | |         awaitable value not awaited
+   | |         help: consider awaiting this value: `CustomFutureType.await`
+LL | |     };
+   | |_____- outer async construct
+
+error: an async construct yields a type which is itself awaitable
+  --> $DIR/async_yields_async.rs:58:23
+   |
+LL |     let _l = async || CustomFutureType;
+   |                       ^^^^^^^^^^^^^^^^
+   |                       |
+   |                       outer async construct
+   |                       awaitable value not awaited
+   |                       help: consider awaiting this value: `CustomFutureType.await`
+
+error: an async construct yields a type which is itself awaitable
+  --> $DIR/async_yields_async.rs:64:9
+   |
+LL |       let _m = async || {
+   |  _______________________-
+LL | |         println!("I'm bored");
+LL | |         // Some more stuff
+LL | |
+LL | |         // Finally something to await
+LL | |         CustomFutureType
+   | |         ^^^^^^^^^^^^^^^^
+   | |         |
+   | |         awaitable value not awaited
+   | |         help: consider awaiting this value: `CustomFutureType.await`
+LL | |     };
+   | |_____- outer async construct
+
+error: aborting due to 6 previous errors
+
diff --git a/tests/ui/collapsible_if.fixed b/tests/ui/collapsible_if.fixed
index 561283fc8e7..efd4187947b 100644
--- a/tests/ui/collapsible_if.fixed
+++ b/tests/ui/collapsible_if.fixed
@@ -135,4 +135,7 @@ fn main() {
             if truth() {}
         }
     }
+
+    // Fix #5962
+    if matches!(true, true) && matches!(true, true) {}
 }
diff --git a/tests/ui/collapsible_if.rs b/tests/ui/collapsible_if.rs
index dc9d9b451c0..657f32d38a3 100644
--- a/tests/ui/collapsible_if.rs
+++ b/tests/ui/collapsible_if.rs
@@ -149,4 +149,9 @@ fn main() {
             if truth() {}
         }
     }
+
+    // Fix #5962
+    if matches!(true, true) {
+        if matches!(true, true) {}
+    }
 }
diff --git a/tests/ui/collapsible_if.stderr b/tests/ui/collapsible_if.stderr
index f56dd65b9dd..acd1ec3f2ca 100644
--- a/tests/ui/collapsible_if.stderr
+++ b/tests/ui/collapsible_if.stderr
@@ -118,5 +118,13 @@ LL |         println!("Hello world!");
 LL |     }
    |
 
-error: aborting due to 7 previous errors
+error: this `if` statement can be collapsed
+  --> $DIR/collapsible_if.rs:154:5
+   |
+LL | /     if matches!(true, true) {
+LL | |         if matches!(true, true) {}
+LL | |     }
+   | |_____^ help: collapse nested if block: `if matches!(true, true) && matches!(true, true) {}`
+
+error: aborting due to 8 previous errors
 
diff --git a/tests/ui/default_trait_access.fixed b/tests/ui/default_trait_access.fixed
new file mode 100644
index 00000000000..d05567a3f82
--- /dev/null
+++ b/tests/ui/default_trait_access.fixed
@@ -0,0 +1,106 @@
+// run-rustfix
+
+#![allow(unused_imports)]
+#![deny(clippy::default_trait_access)]
+
+use std::default;
+use std::default::Default as D2;
+use std::string;
+
+fn main() {
+    let s1: String = std::string::String::default();
+
+    let s2 = String::default();
+
+    let s3: String = std::string::String::default();
+
+    let s4: String = std::string::String::default();
+
+    let s5 = string::String::default();
+
+    let s6: String = std::string::String::default();
+
+    let s7 = std::string::String::default();
+
+    let s8: String = DefaultFactory::make_t_badly();
+
+    let s9: String = DefaultFactory::make_t_nicely();
+
+    let s10 = DerivedDefault::default();
+
+    let s11: GenericDerivedDefault<String> = GenericDerivedDefault::default();
+
+    let s12 = GenericDerivedDefault::<String>::default();
+
+    let s13 = TupleDerivedDefault::default();
+
+    let s14: TupleDerivedDefault = TupleDerivedDefault::default();
+
+    let s15: ArrayDerivedDefault = ArrayDerivedDefault::default();
+
+    let s16 = ArrayDerivedDefault::default();
+
+    let s17: TupleStructDerivedDefault = TupleStructDerivedDefault::default();
+
+    let s18 = TupleStructDerivedDefault::default();
+
+    let s19 = <DerivedDefault as Default>::default();
+
+    println!(
+        "[{}] [{}] [{}] [{}] [{}] [{}] [{}] [{}] [{}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}] [{:?}], [{:?}]",
+        s1,
+        s2,
+        s3,
+        s4,
+        s5,
+        s6,
+        s7,
+        s8,
+        s9,
+        s10,
+        s11,
+        s12,
+        s13,
+        s14,
+        s15,
+        s16,
+        s17,
+        s18,
+        s19,
+    );
+}
+
+struct DefaultFactory;
+
+impl DefaultFactory {
+    pub fn make_t_badly<T: Default>() -> T {
+        Default::default()
+    }
+
+    pub fn make_t_nicely<T: Default>() -> T {
+        T::default()
+    }
+}
+
+#[derive(Debug, Default)]
+struct DerivedDefault {
+    pub s: String,
+}
+
+#[derive(Debug, Default)]
+struct GenericDerivedDefault<T: Default + std::fmt::Debug> {
+    pub s: T,
+}
+
+#[derive(Debug, Default)]
+struct TupleDerivedDefault {
+    pub s: (String, String),
+}
+
+#[derive(Debug, Default)]
+struct ArrayDerivedDefault {
+    pub s: [String; 10],
+}
+
+#[derive(Debug, Default)]
+struct TupleStructDerivedDefault(String);
diff --git a/tests/ui/default_trait_access.rs b/tests/ui/default_trait_access.rs
index 2f1490a7036..447e70c0bbb 100644
--- a/tests/ui/default_trait_access.rs
+++ b/tests/ui/default_trait_access.rs
@@ -1,4 +1,7 @@
-#![warn(clippy::default_trait_access)]
+// run-rustfix
+
+#![allow(unused_imports)]
+#![deny(clippy::default_trait_access)]
 
 use std::default;
 use std::default::Default as D2;
diff --git a/tests/ui/default_trait_access.stderr b/tests/ui/default_trait_access.stderr
index 26b2057548b..df8a5b94ddc 100644
--- a/tests/ui/default_trait_access.stderr
+++ b/tests/ui/default_trait_access.stderr
@@ -1,49 +1,53 @@
 error: calling `std::string::String::default()` is more clear than this expression
-  --> $DIR/default_trait_access.rs:8:22
+  --> $DIR/default_trait_access.rs:11:22
    |
 LL |     let s1: String = Default::default();
    |                      ^^^^^^^^^^^^^^^^^^ help: try: `std::string::String::default()`
    |
-   = note: `-D clippy::default-trait-access` implied by `-D warnings`
+note: the lint level is defined here
+  --> $DIR/default_trait_access.rs:4:9
+   |
+LL | #![deny(clippy::default_trait_access)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: calling `std::string::String::default()` is more clear than this expression
-  --> $DIR/default_trait_access.rs:12:22
+  --> $DIR/default_trait_access.rs:15:22
    |
 LL |     let s3: String = D2::default();
    |                      ^^^^^^^^^^^^^ help: try: `std::string::String::default()`
 
 error: calling `std::string::String::default()` is more clear than this expression
-  --> $DIR/default_trait_access.rs:14:22
+  --> $DIR/default_trait_access.rs:17:22
    |
 LL |     let s4: String = std::default::Default::default();
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::string::String::default()`
 
 error: calling `std::string::String::default()` is more clear than this expression
-  --> $DIR/default_trait_access.rs:18:22
+  --> $DIR/default_trait_access.rs:21:22
    |
 LL |     let s6: String = default::Default::default();
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::string::String::default()`
 
-error: calling `GenericDerivedDefault<std::string::String>::default()` is more clear than this expression
-  --> $DIR/default_trait_access.rs:28:46
+error: calling `GenericDerivedDefault::default()` is more clear than this expression
+  --> $DIR/default_trait_access.rs:31:46
    |
 LL |     let s11: GenericDerivedDefault<String> = Default::default();
-   |                                              ^^^^^^^^^^^^^^^^^^ help: try: `GenericDerivedDefault<std::string::String>::default()`
+   |                                              ^^^^^^^^^^^^^^^^^^ help: try: `GenericDerivedDefault::default()`
 
 error: calling `TupleDerivedDefault::default()` is more clear than this expression
-  --> $DIR/default_trait_access.rs:34:36
+  --> $DIR/default_trait_access.rs:37:36
    |
 LL |     let s14: TupleDerivedDefault = Default::default();
    |                                    ^^^^^^^^^^^^^^^^^^ help: try: `TupleDerivedDefault::default()`
 
 error: calling `ArrayDerivedDefault::default()` is more clear than this expression
-  --> $DIR/default_trait_access.rs:36:36
+  --> $DIR/default_trait_access.rs:39:36
    |
 LL |     let s15: ArrayDerivedDefault = Default::default();
    |                                    ^^^^^^^^^^^^^^^^^^ help: try: `ArrayDerivedDefault::default()`
 
 error: calling `TupleStructDerivedDefault::default()` is more clear than this expression
-  --> $DIR/default_trait_access.rs:40:42
+  --> $DIR/default_trait_access.rs:43:42
    |
 LL |     let s17: TupleStructDerivedDefault = Default::default();
    |                                          ^^^^^^^^^^^^^^^^^^ help: try: `TupleStructDerivedDefault::default()`
diff --git a/tests/ui/or_fun_call.fixed b/tests/ui/or_fun_call.fixed
index 67faa8bd4a0..5fb568672d3 100644
--- a/tests/ui/or_fun_call.fixed
+++ b/tests/ui/or_fun_call.fixed
@@ -58,12 +58,6 @@ fn or_fun_call() {
     let without_default = Some(Foo);
     without_default.unwrap_or_else(Foo::new);
 
-    let mut map = HashMap::<u64, String>::new();
-    map.entry(42).or_insert_with(String::new);
-
-    let mut btree = BTreeMap::<u64, String>::new();
-    btree.entry(42).or_insert_with(String::new);
-
     let stringy = Some(String::from(""));
     let _ = stringy.unwrap_or_else(|| "".to_owned());
 
@@ -122,6 +116,17 @@ pub fn skip_const_fn_with_no_args() {
         Some(42)
     }
     let _ = None.or(foo());
+
+    // See issue #5693.
+    let mut map = std::collections::HashMap::new();
+    map.insert(1, vec![1]);
+    map.entry(1).or_insert(vec![]);
+
+    let mut map = HashMap::<u64, String>::new();
+    map.entry(42).or_insert(String::new());
+
+    let mut btree = BTreeMap::<u64, String>::new();
+    btree.entry(42).or_insert(String::new());
 }
 
 fn main() {}
diff --git a/tests/ui/or_fun_call.rs b/tests/ui/or_fun_call.rs
index 9867e2eedcf..737b0f7e55b 100644
--- a/tests/ui/or_fun_call.rs
+++ b/tests/ui/or_fun_call.rs
@@ -58,12 +58,6 @@ fn or_fun_call() {
     let without_default = Some(Foo);
     without_default.unwrap_or(Foo::new());
 
-    let mut map = HashMap::<u64, String>::new();
-    map.entry(42).or_insert(String::new());
-
-    let mut btree = BTreeMap::<u64, String>::new();
-    btree.entry(42).or_insert(String::new());
-
     let stringy = Some(String::from(""));
     let _ = stringy.unwrap_or("".to_owned());
 
@@ -122,6 +116,17 @@ pub fn skip_const_fn_with_no_args() {
         Some(42)
     }
     let _ = None.or(foo());
+
+    // See issue #5693.
+    let mut map = std::collections::HashMap::new();
+    map.insert(1, vec![1]);
+    map.entry(1).or_insert(vec![]);
+
+    let mut map = HashMap::<u64, String>::new();
+    map.entry(42).or_insert(String::new());
+
+    let mut btree = BTreeMap::<u64, String>::new();
+    btree.entry(42).or_insert(String::new());
 }
 
 fn main() {}
diff --git a/tests/ui/or_fun_call.stderr b/tests/ui/or_fun_call.stderr
index bc5978b538f..b8a436993f3 100644
--- a/tests/ui/or_fun_call.stderr
+++ b/tests/ui/or_fun_call.stderr
@@ -60,35 +60,23 @@ error: use of `unwrap_or` followed by a function call
 LL |     without_default.unwrap_or(Foo::new());
    |                     ^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(Foo::new)`
 
-error: use of `or_insert` followed by a function call
-  --> $DIR/or_fun_call.rs:62:19
-   |
-LL |     map.entry(42).or_insert(String::new());
-   |                   ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `or_insert_with(String::new)`
-
-error: use of `or_insert` followed by a function call
-  --> $DIR/or_fun_call.rs:65:21
-   |
-LL |     btree.entry(42).or_insert(String::new());
-   |                     ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `or_insert_with(String::new)`
-
 error: use of `unwrap_or` followed by a function call
-  --> $DIR/or_fun_call.rs:68:21
+  --> $DIR/or_fun_call.rs:62:21
    |
 LL |     let _ = stringy.unwrap_or("".to_owned());
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `unwrap_or_else(|| "".to_owned())`
 
 error: use of `or` followed by a function call
-  --> $DIR/or_fun_call.rs:93:35
+  --> $DIR/or_fun_call.rs:87:35
    |
 LL |     let _ = Some("a".to_string()).or(Some("b".to_string()));
    |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `or_else(|| Some("b".to_string()))`
 
 error: use of `or` followed by a function call
-  --> $DIR/or_fun_call.rs:97:10
+  --> $DIR/or_fun_call.rs:91:10
    |
 LL |         .or(Some(Bar(b, Duration::from_secs(2))));
    |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `or_else(|| Some(Bar(b, Duration::from_secs(2))))`
 
-error: aborting due to 15 previous errors
+error: aborting due to 13 previous errors
 
diff --git a/tests/ui/transmute_ptr_to_ptr.rs b/tests/ui/transmute_ptr_to_ptr.rs
index 0d8a322f2b2..26b03bdc740 100644
--- a/tests/ui/transmute_ptr_to_ptr.rs
+++ b/tests/ui/transmute_ptr_to_ptr.rs
@@ -51,4 +51,12 @@ fn transmute_ptr_to_ptr() {
     let _: &GenericParam<&LifetimeParam<'static>> = unsafe { std::mem::transmute(&GenericParam { t: &lp }) };
 }
 
+// dereferencing raw pointers in const contexts, should not lint as it's unstable (issue 5959)
+const _: &() = {
+    struct ZST;
+    let zst = &ZST;
+
+    unsafe { std::mem::transmute::<&'static ZST, &'static ()>(zst) }
+};
+
 fn main() {}
diff --git a/util/dev b/util/dev
deleted file mode 100755
index 319de217e0d..00000000000
--- a/util/dev
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/sh
-CARGO_TARGET_DIR=$(pwd)/target/
-export CARGO_TARGET_DIR
-
-echo 'Deprecated! `util/dev` usage is deprecated, please use `cargo dev` instead.'
-
-cd clippy_dev && cargo run -- "$@"