about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md5
-rw-r--r--README.md2
-rw-r--r--clippy_lints/src/asm_syntax.rs125
-rw-r--r--clippy_lints/src/disallowed_method.rs73
-rw-r--r--clippy_lints/src/lib.rs24
-rw-r--r--clippy_lints/src/lifetimes.rs169
-rw-r--r--clippy_lints/src/loops.rs12
-rw-r--r--clippy_lints/src/missing_const_for_fn.rs2
-rw-r--r--clippy_lints/src/needless_arbitrary_self_type.rs30
-rw-r--r--clippy_lints/src/non_copy_const.rs28
-rw-r--r--clippy_lints/src/types.rs15
-rw-r--r--clippy_lints/src/unicode.rs23
-rw-r--r--clippy_lints/src/utils/conf.rs2
-rw-r--r--clippy_lints/src/utils/mod.rs11
-rw-r--r--clippy_lints/src/utils/numeric_literal.rs19
-rw-r--r--clippy_lints/src/utils/paths.rs3
-rw-r--r--clippy_lints/src/utils/qualify_min_const_fn.rs193
-rw-r--r--clippy_lints/src/write.rs17
-rw-r--r--clippy_workspace_tests/build.rs7
-rw-r--r--src/lintlist/mod.rs39
-rw-r--r--tests/compile-test.rs2
-rw-r--r--tests/ui-toml/toml_disallowed_method/clippy.toml1
-rw-r--r--tests/ui-toml/toml_disallowed_method/conf_disallowed_method.rs13
-rw-r--r--tests/ui-toml/toml_disallowed_method/conf_disallowed_method.stderr16
-rw-r--r--tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr2
-rw-r--r--tests/ui/asm_syntax.rs31
-rw-r--r--tests/ui/asm_syntax.stderr44
-rw-r--r--tests/ui/auxiliary/proc_macro_attr.rs62
-rw-r--r--tests/ui/auxiliary/proc_macro_derive.rs1
-rw-r--r--tests/ui/crashes/associated-constant-ice.rs2
-rw-r--r--tests/ui/crashes/auxiliary/proc_macro_crash.rs1
-rw-r--r--tests/ui/crashes/cc_seme.rs2
-rw-r--r--tests/ui/crashes/enum-glob-import-crate.rs2
-rw-r--r--tests/ui/crashes/ice-1588.rs2
-rw-r--r--tests/ui/crashes/ice-1782.rs2
-rw-r--r--tests/ui/crashes/ice-1969.rs2
-rw-r--r--tests/ui/crashes/ice-2499.rs2
-rw-r--r--tests/ui/crashes/ice-2594.rs2
-rw-r--r--tests/ui/crashes/ice-2727.rs2
-rw-r--r--tests/ui/crashes/ice-2760.rs2
-rw-r--r--tests/ui/crashes/ice-2774.rs2
-rw-r--r--tests/ui/crashes/ice-2774.stderr10
-rw-r--r--tests/ui/crashes/ice-2862.rs2
-rw-r--r--tests/ui/crashes/ice-2865.rs2
-rw-r--r--tests/ui/crashes/ice-3151.rs2
-rw-r--r--tests/ui/crashes/ice-3462.rs2
-rw-r--r--tests/ui/crashes/ice-3741.rs1
-rw-r--r--tests/ui/crashes/ice-3747.rs2
-rw-r--r--tests/ui/crashes/ice-4727.rs2
-rw-r--r--tests/ui/crashes/ice-4760.rs1
-rw-r--r--tests/ui/crashes/ice-700.rs2
-rw-r--r--tests/ui/crashes/ice_exacte_size.rs2
-rw-r--r--tests/ui/crashes/if_same_then_else.rs2
-rw-r--r--tests/ui/crashes/issue-825.rs2
-rw-r--r--tests/ui/crashes/issues_loop_mut_cond.rs2
-rw-r--r--tests/ui/crashes/match_same_arms_const.rs2
-rw-r--r--tests/ui/crashes/mut_mut_macro.rs2
-rw-r--r--tests/ui/crashes/needless_borrow_fp.rs2
-rw-r--r--tests/ui/crashes/needless_lifetimes_impl_trait.rs2
-rw-r--r--tests/ui/crashes/needless_lifetimes_impl_trait.stderr14
-rw-r--r--tests/ui/crashes/procedural_macro.rs2
-rw-r--r--tests/ui/crashes/regressions.rs2
-rw-r--r--tests/ui/crashes/returns.rs2
-rw-r--r--tests/ui/crashes/single-match-else.rs2
-rw-r--r--tests/ui/crashes/trivial_bounds.rs2
-rw-r--r--tests/ui/crashes/used_underscore_binding_macro.rs2
-rw-r--r--tests/ui/explicit_counter_loop.rs29
-rw-r--r--tests/ui/inconsistent_digit_grouping.fixed4
-rw-r--r--tests/ui/inconsistent_digit_grouping.rs4
-rw-r--r--tests/ui/needless_arbitrary_self_type_unfixable.rs45
-rw-r--r--tests/ui/needless_arbitrary_self_type_unfixable.stderr10
-rw-r--r--tests/ui/needless_lifetimes.rs98
-rw-r--r--tests/ui/needless_lifetimes.stderr50
-rw-r--r--tests/ui/needless_range_loop2.rs14
-rw-r--r--tests/ui/or_fun_call.fixed25
-rw-r--r--tests/ui/or_fun_call.rs25
-rw-r--r--tests/ui/or_fun_call.stderr20
-rw-r--r--tests/ui/print_stdout_build_script.rs12
-rw-r--r--tests/ui/temporary_assignment.rs1
-rw-r--r--tests/ui/temporary_assignment.stderr8
-rw-r--r--tests/ui/unicode.rs6
-rw-r--r--tests/ui/unicode.stderr22
-rwxr-xr-xutil/dev7
83 files changed, 1028 insertions, 414 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d1dfe36ffd8..617bf32f463 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1559,6 +1559,7 @@ Released 2018-09-13
 [`deref_addrof`]: https://rust-lang.github.io/rust-clippy/master/index.html#deref_addrof
 [`derive_hash_xor_eq`]: https://rust-lang.github.io/rust-clippy/master/index.html#derive_hash_xor_eq
 [`derive_ord_xor_partial_ord`]: https://rust-lang.github.io/rust-clippy/master/index.html#derive_ord_xor_partial_ord
+[`disallowed_method`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_method
 [`diverging_sub_expression`]: https://rust-lang.github.io/rust-clippy/master/index.html#diverging_sub_expression
 [`doc_markdown`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_markdown
 [`double_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#double_comparisons
@@ -1634,6 +1635,8 @@ Released 2018-09-13
 [`inherent_to_string`]: https://rust-lang.github.io/rust-clippy/master/index.html#inherent_to_string
 [`inherent_to_string_shadow_display`]: https://rust-lang.github.io/rust-clippy/master/index.html#inherent_to_string_shadow_display
 [`inline_always`]: https://rust-lang.github.io/rust-clippy/master/index.html#inline_always
+[`inline_asm_x86_att_syntax`]: https://rust-lang.github.io/rust-clippy/master/index.html#inline_asm_x86_att_syntax
+[`inline_asm_x86_intel_syntax`]: https://rust-lang.github.io/rust-clippy/master/index.html#inline_asm_x86_intel_syntax
 [`inline_fn_without_body`]: https://rust-lang.github.io/rust-clippy/master/index.html#inline_fn_without_body
 [`int_plus_one`]: https://rust-lang.github.io/rust-clippy/master/index.html#int_plus_one
 [`integer_arithmetic`]: https://rust-lang.github.io/rust-clippy/master/index.html#integer_arithmetic
@@ -1644,6 +1647,7 @@ Released 2018-09-13
 [`invalid_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#invalid_ref
 [`invalid_regex`]: https://rust-lang.github.io/rust-clippy/master/index.html#invalid_regex
 [`invalid_upcast_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#invalid_upcast_comparisons
+[`invisible_characters`]: https://rust-lang.github.io/rust-clippy/master/index.html#invisible_characters
 [`items_after_statements`]: https://rust-lang.github.io/rust-clippy/master/index.html#items_after_statements
 [`iter_cloned_collect`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_cloned_collect
 [`iter_next_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_next_loop
@@ -1919,6 +1923,5 @@ Released 2018-09-13
 [`zero_divided_by_zero`]: https://rust-lang.github.io/rust-clippy/master/index.html#zero_divided_by_zero
 [`zero_prefixed_literal`]: https://rust-lang.github.io/rust-clippy/master/index.html#zero_prefixed_literal
 [`zero_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#zero_ptr
-[`zero_width_space`]: https://rust-lang.github.io/rust-clippy/master/index.html#zero_width_space
 [`zst_offset`]: https://rust-lang.github.io/rust-clippy/master/index.html#zst_offset
 <!-- end autogenerated links to lint list -->
diff --git a/README.md b/README.md
index a2984d73641..62a8be0abf2 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@
 
 A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code.
 
-[There are over 350 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
+[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:
 
diff --git a/clippy_lints/src/asm_syntax.rs b/clippy_lints/src/asm_syntax.rs
new file mode 100644
index 00000000000..ef1f1a14afc
--- /dev/null
+++ b/clippy_lints/src/asm_syntax.rs
@@ -0,0 +1,125 @@
+use std::fmt;
+
+use crate::utils::span_lint_and_help;
+use rustc_ast::ast::{Expr, ExprKind, InlineAsmOptions};
+use rustc_lint::{EarlyContext, EarlyLintPass, Lint};
+use rustc_session::{declare_lint_pass, declare_tool_lint};
+
+#[derive(Clone, Copy, PartialEq, Eq)]
+enum AsmStyle {
+    Intel,
+    Att,
+}
+
+impl fmt::Display for AsmStyle {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self {
+            AsmStyle::Intel => f.write_str("Intel"),
+            AsmStyle::Att => f.write_str("AT&T"),
+        }
+    }
+}
+
+impl std::ops::Not for AsmStyle {
+    type Output = AsmStyle;
+
+    fn not(self) -> AsmStyle {
+        match self {
+            AsmStyle::Intel => AsmStyle::Att,
+            AsmStyle::Att => AsmStyle::Intel,
+        }
+    }
+}
+
+fn check_expr_asm_syntax(lint: &'static Lint, cx: &EarlyContext<'_>, expr: &Expr, check_for: AsmStyle) {
+    if let ExprKind::InlineAsm(ref inline_asm) = expr.kind {
+        let style = if inline_asm.options.contains(InlineAsmOptions::ATT_SYNTAX) {
+            AsmStyle::Att
+        } else {
+            AsmStyle::Intel
+        };
+
+        if style == check_for {
+            span_lint_and_help(
+                cx,
+                lint,
+                expr.span,
+                &format!("{} x86 assembly syntax used", style),
+                None,
+                &format!("use {} x86 assembly syntax", !style),
+            );
+        }
+    }
+}
+
+declare_clippy_lint! {
+    /// **What it does:** Checks for usage of Intel x86 assembly syntax.
+    ///
+    /// **Why is this bad?** The lint has been enabled to indicate a preference
+    /// for AT&T x86 assembly syntax.
+    ///
+    /// **Known problems:** None.
+    ///
+    /// **Example:**
+    ///
+    /// ```rust,no_run
+    /// # #![feature(asm)]
+    /// # unsafe { let ptr = "".as_ptr();
+    /// asm!("lea {}, [{}]", lateout(reg) _, in(reg) ptr);
+    /// # }
+    /// ```
+    /// Use instead:
+    /// ```rust,no_run
+    /// # #![feature(asm)]
+    /// # unsafe { let ptr = "".as_ptr();
+    /// asm!("lea ({}), {}", in(reg) ptr, lateout(reg) _, options(att_syntax));
+    /// # }
+    /// ```
+    pub INLINE_ASM_X86_INTEL_SYNTAX,
+    restriction,
+    "prefer AT&T x86 assembly syntax"
+}
+
+declare_lint_pass!(InlineAsmX86IntelSyntax => [INLINE_ASM_X86_INTEL_SYNTAX]);
+
+impl EarlyLintPass for InlineAsmX86IntelSyntax {
+    fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
+        check_expr_asm_syntax(Self::get_lints()[0], cx, expr, AsmStyle::Intel);
+    }
+}
+
+declare_clippy_lint! {
+    /// **What it does:** Checks for usage of AT&T x86 assembly syntax.
+    ///
+    /// **Why is this bad?** The lint has been enabled to indicate a preference
+    /// for Intel x86 assembly syntax.
+    ///
+    /// **Known problems:** None.
+    ///
+    /// **Example:**
+    ///
+    /// ```rust,no_run
+    /// # #![feature(asm)]
+    /// # unsafe { let ptr = "".as_ptr();
+    /// asm!("lea ({}), {}", in(reg) ptr, lateout(reg) _, options(att_syntax));
+    /// # }
+    /// ```
+    /// Use instead:
+    /// ```rust,no_run
+    /// # #![feature(asm)]
+    /// # unsafe { let ptr = "".as_ptr();
+    /// asm!("lea {}, [{}]", lateout(reg) _, in(reg) ptr);
+    /// # }
+    /// ```
+    pub INLINE_ASM_X86_ATT_SYNTAX,
+    restriction,
+    "prefer Intel x86 assembly syntax"
+}
+
+declare_lint_pass!(InlineAsmX86AttSyntax => [INLINE_ASM_X86_ATT_SYNTAX]);
+
+impl EarlyLintPass for InlineAsmX86AttSyntax {
+    fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
+        check_expr_asm_syntax(Self::get_lints()[0], cx, expr, AsmStyle::Att);
+    }
+}
diff --git a/clippy_lints/src/disallowed_method.rs b/clippy_lints/src/disallowed_method.rs
new file mode 100644
index 00000000000..581c3242e37
--- /dev/null
+++ b/clippy_lints/src/disallowed_method.rs
@@ -0,0 +1,73 @@
+use crate::utils::span_lint;
+
+use rustc_data_structures::fx::FxHashSet;
+use rustc_hir::{Expr, ExprKind};
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_session::{declare_tool_lint, impl_lint_pass};
+use rustc_span::Symbol;
+
+declare_clippy_lint! {
+    /// **What it does:** Lints for specific trait methods defined in clippy.toml
+    ///
+    /// **Why is this bad?** Some methods are undesirable in certain contexts,
+    /// and it would be beneficial to lint for them as needed.
+    ///
+    /// **Known problems:** None.
+    ///
+    /// **Example:**
+    ///
+    /// ```rust,ignore
+    /// // example code where clippy issues a warning
+    /// foo.bad_method(); // Foo::bad_method is disallowed in the configuration
+    /// ```
+    /// Use instead:
+    /// ```rust,ignore
+    /// // example code which does not raise clippy warning
+    /// goodStruct.bad_method(); // GoodStruct::bad_method is not disallowed
+    /// ```
+    pub DISALLOWED_METHOD,
+    nursery,
+    "use of a disallowed method call"
+}
+
+#[derive(Clone, Debug)]
+pub struct DisallowedMethod {
+    disallowed: FxHashSet<Vec<Symbol>>,
+}
+
+impl DisallowedMethod {
+    pub fn new(disallowed: &FxHashSet<String>) -> Self {
+        Self {
+            disallowed: disallowed
+                .iter()
+                .map(|s| s.split("::").map(|seg| Symbol::intern(seg)).collect::<Vec<_>>())
+                .collect(),
+        }
+    }
+}
+
+impl_lint_pass!(DisallowedMethod => [DISALLOWED_METHOD]);
+
+impl<'tcx> LateLintPass<'tcx> for DisallowedMethod {
+    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
+        if let ExprKind::MethodCall(_path, _, _args, _) = &expr.kind {
+            let def_id = cx.typeck_results().type_dependent_def_id(expr.hir_id).unwrap();
+
+            let method_call = cx.get_def_path(def_id);
+            if self.disallowed.contains(&method_call) {
+                let method = method_call
+                    .iter()
+                    .map(|s| s.to_ident_string())
+                    .collect::<Vec<_>>()
+                    .join("::");
+
+                span_lint(
+                    cx,
+                    DISALLOWED_METHOD,
+                    expr.span,
+                    &format!("use of a disallowed method `{}`", method),
+                );
+            }
+        }
+    }
+}
diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs
index 70efdaeb9c6..72ad8d12e6d 100644
--- a/clippy_lints/src/lib.rs
+++ b/clippy_lints/src/lib.rs
@@ -153,6 +153,7 @@ mod utils;
 mod approx_const;
 mod arithmetic;
 mod as_conversions;
+mod asm_syntax;
 mod assertions_on_constants;
 mod assign_ops;
 mod async_yields_async;
@@ -176,6 +177,7 @@ mod dbg_macro;
 mod default_trait_access;
 mod dereference;
 mod derive;
+mod disallowed_method;
 mod doc;
 mod double_comparison;
 mod double_parens;
@@ -489,6 +491,8 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         &arithmetic::FLOAT_ARITHMETIC,
         &arithmetic::INTEGER_ARITHMETIC,
         &as_conversions::AS_CONVERSIONS,
+        &asm_syntax::INLINE_ASM_X86_ATT_SYNTAX,
+        &asm_syntax::INLINE_ASM_X86_INTEL_SYNTAX,
         &assertions_on_constants::ASSERTIONS_ON_CONSTANTS,
         &assign_ops::ASSIGN_OP_PATTERN,
         &assign_ops::MISREFACTORED_ASSIGN_OP,
@@ -529,6 +533,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         &derive::DERIVE_ORD_XOR_PARTIAL_ORD,
         &derive::EXPL_IMPL_CLONE_ON_COPY,
         &derive::UNSAFE_DERIVE_DESERIALIZE,
+        &disallowed_method::DISALLOWED_METHOD,
         &doc::DOC_MARKDOWN,
         &doc::MISSING_ERRORS_DOC,
         &doc::MISSING_SAFETY_DOC,
@@ -851,9 +856,9 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         &types::UNIT_CMP,
         &types::UNNECESSARY_CAST,
         &types::VEC_BOX,
+        &unicode::INVISIBLE_CHARACTERS,
         &unicode::NON_ASCII_LITERAL,
         &unicode::UNICODE_NOT_NFC,
-        &unicode::ZERO_WIDTH_SPACE,
         &unit_return_expecting_ord::UNIT_RETURN_EXPECTING_ORD,
         &unnamed_address::FN_ADDRESS_COMPARISONS,
         &unnamed_address::VTABLE_ADDRESS_COMPARISONS,
@@ -1120,11 +1125,18 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     store.register_late_pass(|| box async_yields_async::AsyncYieldsAsync);
     store.register_late_pass(|| box manual_strip::ManualStrip);
     store.register_late_pass(|| box utils::internal_lints::MatchTypeOnDiagItem);
+    let disallowed_methods = conf.disallowed_methods.iter().cloned().collect::<FxHashSet<_>>();
+    store.register_late_pass(move || box disallowed_method::DisallowedMethod::new(&disallowed_methods));
+    store.register_early_pass(|| box asm_syntax::InlineAsmX86AttSyntax);
+    store.register_early_pass(|| box asm_syntax::InlineAsmX86IntelSyntax);
+
 
     store.register_group(true, "clippy::restriction", Some("clippy_restriction"), vec![
         LintId::of(&arithmetic::FLOAT_ARITHMETIC),
         LintId::of(&arithmetic::INTEGER_ARITHMETIC),
         LintId::of(&as_conversions::AS_CONVERSIONS),
+        LintId::of(&asm_syntax::INLINE_ASM_X86_ATT_SYNTAX),
+        LintId::of(&asm_syntax::INLINE_ASM_X86_INTEL_SYNTAX),
         LintId::of(&create_dir::CREATE_DIR),
         LintId::of(&dbg_macro::DBG_MACRO),
         LintId::of(&else_if_without_else::ELSE_IF_WITHOUT_ELSE),
@@ -1499,7 +1511,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         LintId::of(&types::UNIT_CMP),
         LintId::of(&types::UNNECESSARY_CAST),
         LintId::of(&types::VEC_BOX),
-        LintId::of(&unicode::ZERO_WIDTH_SPACE),
+        LintId::of(&unicode::INVISIBLE_CHARACTERS),
         LintId::of(&unit_return_expecting_ord::UNIT_RETURN_EXPECTING_ORD),
         LintId::of(&unnamed_address::FN_ADDRESS_COMPARISONS),
         LintId::of(&unnamed_address::VTABLE_ADDRESS_COMPARISONS),
@@ -1592,6 +1604,8 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         LintId::of(&mut_reference::UNNECESSARY_MUT_PASSED),
         LintId::of(&neg_multiply::NEG_MULTIPLY),
         LintId::of(&new_without_default::NEW_WITHOUT_DEFAULT),
+        LintId::of(&non_copy_const::BORROW_INTERIOR_MUTABLE_CONST),
+        LintId::of(&non_copy_const::DECLARE_INTERIOR_MUTABLE_CONST),
         LintId::of(&non_expressive_names::JUST_UNDERSCORES_AND_DIGITS),
         LintId::of(&non_expressive_names::MANY_SINGLE_CHAR_NAMES),
         LintId::of(&panic_unimplemented::PANIC_PARAMS),
@@ -1747,8 +1761,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         LintId::of(&misc::FLOAT_CMP),
         LintId::of(&misc::MODULO_ONE),
         LintId::of(&mut_key::MUTABLE_KEY_TYPE),
-        LintId::of(&non_copy_const::BORROW_INTERIOR_MUTABLE_CONST),
-        LintId::of(&non_copy_const::DECLARE_INTERIOR_MUTABLE_CONST),
         LintId::of(&open_options::NONSENSICAL_OPEN_OPTIONS),
         LintId::of(&option_env_unwrap::OPTION_ENV_UNWRAP),
         LintId::of(&ptr::MUT_FROM_REF),
@@ -1766,7 +1778,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         LintId::of(&types::ABSURD_EXTREME_COMPARISONS),
         LintId::of(&types::CAST_REF_TO_MUT),
         LintId::of(&types::UNIT_CMP),
-        LintId::of(&unicode::ZERO_WIDTH_SPACE),
+        LintId::of(&unicode::INVISIBLE_CHARACTERS),
         LintId::of(&unit_return_expecting_ord::UNIT_RETURN_EXPECTING_ORD),
         LintId::of(&unnamed_address::FN_ADDRESS_COMPARISONS),
         LintId::of(&unnamed_address::VTABLE_ADDRESS_COMPARISONS),
@@ -1807,6 +1819,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     store.register_group(true, "clippy::nursery", Some("clippy_nursery"), vec![
         LintId::of(&attrs::EMPTY_LINE_AFTER_OUTER_ATTR),
         LintId::of(&cognitive_complexity::COGNITIVE_COMPLEXITY),
+        LintId::of(&disallowed_method::DISALLOWED_METHOD),
         LintId::of(&fallible_impl_from::FALLIBLE_IMPL_FROM),
         LintId::of(&floating_point_arithmetic::IMPRECISE_FLOPS),
         LintId::of(&floating_point_arithmetic::SUBOPTIMAL_FLOPS),
@@ -1896,6 +1909,7 @@ pub fn register_renamed(ls: &mut rustc_lint::LintStore) {
     ls.register_renamed("clippy::for_loop_over_option", "clippy::for_loops_over_fallibles");
     ls.register_renamed("clippy::for_loop_over_result", "clippy::for_loops_over_fallibles");
     ls.register_renamed("clippy::identity_conversion", "clippy::useless_conversion");
+    ls.register_renamed("clippy::zero_width_space", "clippy::invisible_characters");
 }
 
 // only exists to let the dogfood integration test works.
diff --git a/clippy_lints/src/lifetimes.rs b/clippy_lints/src/lifetimes.rs
index 4df6827d77f..d7043e7bd8f 100644
--- a/clippy_lints/src/lifetimes.rs
+++ b/clippy_lints/src/lifetimes.rs
@@ -1,21 +1,22 @@
+use crate::utils::paths;
+use crate::utils::{get_trait_def_id, in_macro, span_lint, trait_ref_of_method};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
-use rustc_hir::def::{DefKind, Res};
 use rustc_hir::intravisit::{
-    walk_fn_decl, walk_generic_param, walk_generics, walk_param_bound, walk_ty, NestedVisitorMap, Visitor,
+    walk_fn_decl, walk_generic_param, walk_generics, walk_item, walk_param_bound, walk_poly_trait_ref, walk_ty,
+    NestedVisitorMap, Visitor,
 };
 use rustc_hir::FnRetTy::Return;
 use rustc_hir::{
-    BodyId, FnDecl, GenericArg, GenericBound, GenericParam, GenericParamKind, Generics, ImplItem, ImplItemKind, Item,
-    ItemKind, Lifetime, LifetimeName, ParamName, QPath, TraitBoundModifier, TraitFn, TraitItem, TraitItemKind, Ty,
-    TyKind, WhereClause, WherePredicate,
+    BareFnTy, BodyId, FnDecl, GenericArg, GenericBound, GenericParam, GenericParamKind, Generics, ImplItem,
+    ImplItemKind, Item, ItemKind, Lifetime, LifetimeName, ParamName, PolyTraitRef, TraitBoundModifier, TraitFn,
+    TraitItem, TraitItemKind, Ty, TyKind, WhereClause, WherePredicate,
 };
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::hir::map::Map;
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::source_map::Span;
 use rustc_span::symbol::{kw, Symbol};
-
-use crate::utils::{in_macro, last_path_segment, span_lint, trait_ref_of_method};
+use std::iter::FromIterator;
 
 declare_clippy_lint! {
     /// **What it does:** Checks for lifetime annotations which can be removed by
@@ -25,8 +26,11 @@ declare_clippy_lint! {
     /// complicated, while there is nothing out of the ordinary going on. Removing
     /// them leads to more readable code.
     ///
-    /// **Known problems:** Potential false negatives: we bail out if the function
-    /// has a `where` clause where lifetimes are mentioned.
+    /// **Known problems:**
+    /// - We bail out if the function has a `where` clause where lifetimes
+    /// are mentioned due to potenial false positives.
+    /// - Lifetime bounds such as `impl Foo + 'a` and `T: 'a` must be elided with the
+    /// placeholder notation `'_` because the fully elided notation leaves the type bound to `'static`.
     ///
     /// **Example:**
     /// ```rust
@@ -108,7 +112,7 @@ impl<'tcx> LateLintPass<'tcx> for Lifetimes {
 }
 
 /// The lifetime of a &-reference.
-#[derive(PartialEq, Eq, Hash, Debug)]
+#[derive(PartialEq, Eq, Hash, Debug, Clone)]
 enum RefLt {
     Unnamed,
     Static,
@@ -127,7 +131,6 @@ fn check_fn_inner<'tcx>(
         return;
     }
 
-    let mut bounds_lts = Vec::new();
     let types = generics
         .params
         .iter()
@@ -156,13 +159,12 @@ fn check_fn_inner<'tcx>(
                         if bound.name != LifetimeName::Static && !bound.is_elided() {
                             return;
                         }
-                        bounds_lts.push(bound);
                     }
                 }
             }
         }
     }
-    if could_use_elision(cx, decl, body, &generics.params, bounds_lts) {
+    if could_use_elision(cx, decl, body, &generics.params) {
         span_lint(
             cx,
             NEEDLESS_LIFETIMES,
@@ -181,7 +183,6 @@ fn could_use_elision<'tcx>(
     func: &'tcx FnDecl<'_>,
     body: Option<BodyId>,
     named_generics: &'tcx [GenericParam<'_>],
-    bounds_lts: Vec<&'tcx Lifetime>,
 ) -> bool {
     // There are two scenarios where elision works:
     // * no output references, all input references have different LT
@@ -204,15 +205,31 @@ fn could_use_elision<'tcx>(
     if let Return(ref ty) = func.output {
         output_visitor.visit_ty(ty);
     }
+    for lt in named_generics {
+        input_visitor.visit_generic_param(lt)
+    }
+
+    if input_visitor.abort() || output_visitor.abort() {
+        return false;
+    }
 
-    let input_lts = match input_visitor.into_vec() {
-        Some(lts) => lts_from_bounds(lts, bounds_lts.into_iter()),
-        None => return false,
-    };
-    let output_lts = match output_visitor.into_vec() {
-        Some(val) => val,
-        None => return false,
-    };
+    if allowed_lts
+        .intersection(&FxHashSet::from_iter(
+            input_visitor
+                .nested_elision_site_lts
+                .iter()
+                .chain(output_visitor.nested_elision_site_lts.iter())
+                .cloned()
+                .filter(|v| matches!(v, RefLt::Named(_))),
+        ))
+        .next()
+        .is_some()
+    {
+        return false;
+    }
+
+    let input_lts = input_visitor.lts;
+    let output_lts = output_visitor.lts;
 
     if let Some(body_id) = body {
         let mut checker = BodyLifetimeChecker {
@@ -277,27 +294,20 @@ fn allowed_lts_from(named_generics: &[GenericParam<'_>]) -> FxHashSet<RefLt> {
     allowed_lts
 }
 
-fn lts_from_bounds<'a, T: Iterator<Item = &'a Lifetime>>(mut vec: Vec<RefLt>, bounds_lts: T) -> Vec<RefLt> {
-    for lt in bounds_lts {
-        if lt.name != LifetimeName::Static {
-            vec.push(RefLt::Named(lt.name.ident().name));
-        }
-    }
-
-    vec
-}
-
 /// Number of unique lifetimes in the given vector.
 #[must_use]
 fn unique_lifetimes(lts: &[RefLt]) -> usize {
     lts.iter().collect::<FxHashSet<_>>().len()
 }
 
+const CLOSURE_TRAIT_BOUNDS: [&[&str]; 3] = [&paths::FN, &paths::FN_MUT, &paths::FN_ONCE];
+
 /// A visitor usable for `rustc_front::visit::walk_ty()`.
 struct RefVisitor<'a, 'tcx> {
     cx: &'a LateContext<'tcx>,
     lts: Vec<RefLt>,
-    abort: bool,
+    nested_elision_site_lts: Vec<RefLt>,
+    unelided_trait_object_lifetime: bool,
 }
 
 impl<'a, 'tcx> RefVisitor<'a, 'tcx> {
@@ -305,7 +315,8 @@ impl<'a, 'tcx> RefVisitor<'a, 'tcx> {
         Self {
             cx,
             lts: Vec::new(),
-            abort: false,
+            nested_elision_site_lts: Vec::new(),
+            unelided_trait_object_lifetime: false,
         }
     }
 
@@ -325,40 +336,16 @@ impl<'a, 'tcx> RefVisitor<'a, 'tcx> {
         }
     }
 
-    fn into_vec(self) -> Option<Vec<RefLt>> {
-        if self.abort {
-            None
-        } else {
-            Some(self.lts)
-        }
+    fn all_lts(&self) -> Vec<RefLt> {
+        self.lts
+            .iter()
+            .chain(self.nested_elision_site_lts.iter())
+            .cloned()
+            .collect::<Vec<_>>()
     }
 
-    fn collect_anonymous_lifetimes(&mut self, qpath: &QPath<'_>, ty: &Ty<'_>) {
-        if let Some(ref last_path_segment) = last_path_segment(qpath).args {
-            if !last_path_segment.parenthesized
-                && !last_path_segment
-                    .args
-                    .iter()
-                    .any(|arg| matches!(arg, GenericArg::Lifetime(_)))
-            {
-                let hir_id = ty.hir_id;
-                match self.cx.qpath_res(qpath, hir_id) {
-                    Res::Def(DefKind::TyAlias | DefKind::Struct, def_id) => {
-                        let generics = self.cx.tcx.generics_of(def_id);
-                        for _ in generics.params.as_slice() {
-                            self.record(&None);
-                        }
-                    },
-                    Res::Def(DefKind::Trait, def_id) => {
-                        let trait_def = self.cx.tcx.trait_def(def_id);
-                        for _ in &self.cx.tcx.generics_of(trait_def.def_id).params {
-                            self.record(&None);
-                        }
-                    },
-                    _ => (),
-                }
-            }
-        }
+    fn abort(&self) -> bool {
+        self.unelided_trait_object_lifetime
     }
 }
 
@@ -370,30 +357,37 @@ impl<'a, 'tcx> Visitor<'tcx> for RefVisitor<'a, 'tcx> {
         self.record(&Some(*lifetime));
     }
 
+    fn visit_poly_trait_ref(&mut self, poly_tref: &'tcx PolyTraitRef<'tcx>, tbm: TraitBoundModifier) {
+        let trait_ref = &poly_tref.trait_ref;
+        if CLOSURE_TRAIT_BOUNDS
+            .iter()
+            .any(|trait_path| trait_ref.trait_def_id() == get_trait_def_id(self.cx, trait_path))
+        {
+            let mut sub_visitor = RefVisitor::new(self.cx);
+            sub_visitor.visit_trait_ref(trait_ref);
+            self.nested_elision_site_lts.append(&mut sub_visitor.all_lts());
+        } else {
+            walk_poly_trait_ref(self, poly_tref, tbm);
+        }
+    }
+
     fn visit_ty(&mut self, ty: &'tcx Ty<'_>) {
         match ty.kind {
-            TyKind::Rptr(ref lt, _) if lt.is_elided() => {
-                self.record(&None);
-            },
-            TyKind::Path(ref path) => {
-                self.collect_anonymous_lifetimes(path, ty);
-            },
             TyKind::OpaqueDef(item, _) => {
                 let map = self.cx.tcx.hir();
-                if let ItemKind::OpaqueTy(ref exist_ty) = map.expect_item(item.id).kind {
-                    for bound in exist_ty.bounds {
-                        if let GenericBound::Outlives(_) = *bound {
-                            self.record(&None);
-                        }
-                    }
-                } else {
-                    unreachable!()
-                }
+                let item = map.expect_item(item.id);
+                walk_item(self, item);
                 walk_ty(self, ty);
             },
+            TyKind::BareFn(&BareFnTy { decl, .. }) => {
+                let mut sub_visitor = RefVisitor::new(self.cx);
+                sub_visitor.visit_fn_decl(decl);
+                self.nested_elision_site_lts.append(&mut sub_visitor.all_lts());
+                return;
+            },
             TyKind::TraitObject(bounds, ref lt) => {
                 if !lt.is_elided() {
-                    self.abort = true;
+                    self.unelided_trait_object_lifetime = true;
                 }
                 for bound in bounds {
                     self.visit_poly_trait_ref(bound, TraitBoundModifier::None);
@@ -430,16 +424,7 @@ fn has_where_lifetimes<'tcx>(cx: &LateContext<'tcx>, where_clause: &'tcx WhereCl
                     walk_param_bound(&mut visitor, bound);
                 }
                 // and check that all lifetimes are allowed
-                match visitor.into_vec() {
-                    None => return false,
-                    Some(lts) => {
-                        for lt in lts {
-                            if !allowed_lts.contains(&lt) {
-                                return true;
-                            }
-                        }
-                    },
-                }
+                return visitor.all_lts().iter().any(|it| !allowed_lts.contains(it));
             },
             WherePredicate::EqPredicate(ref pred) => {
                 let mut visitor = RefVisitor::new(cx);
diff --git a/clippy_lints/src/loops.rs b/clippy_lints/src/loops.rs
index 3410341a1e3..61b63597b16 100644
--- a/clippy_lints/src/loops.rs
+++ b/clippy_lints/src/loops.rs
@@ -3,7 +3,7 @@ use crate::utils::paths;
 use crate::utils::sugg::Sugg;
 use crate::utils::usage::{is_unused, mutated_variables};
 use crate::utils::{
-    get_enclosing_block, get_parent_expr, get_trait_def_id, has_iter_method, higher, implements_trait,
+    contains_name, get_enclosing_block, get_parent_expr, get_trait_def_id, has_iter_method, higher, implements_trait,
     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, snippet, snippet_opt, snippet_with_applicability,
     snippet_with_macro_callsite, span_lint, span_lint_and_help, span_lint_and_sugg, span_lint_and_then, sugg,
@@ -1276,6 +1276,8 @@ fn check_for_loop_range<'tcx>(
 
                 let skip = if starts_at_zero {
                     String::new()
+                } else if visitor.indexed_mut.contains(&indexed) && contains_name(indexed, start) {
+                    return;
                 } else {
                     format!(".skip({})", snippet(cx, start.span, ".."))
                 };
@@ -1302,6 +1304,8 @@ fn check_for_loop_range<'tcx>(
 
                     if is_len_call(end, indexed) || is_end_eq_array_len(cx, end, limits, indexed_ty) {
                         String::new()
+                    } else if visitor.indexed_mut.contains(&indexed) && contains_name(indexed, take_expr) {
+                        return;
                     } else {
                         match limits {
                             ast::RangeLimits::Closed => {
@@ -2134,7 +2138,7 @@ enum VarState {
     DontWarn,
 }
 
-/// Scan a for loop for variables that are incremented exactly once.
+/// Scan a for loop for variables that are incremented exactly once and not used after that.
 struct IncrementVisitor<'a, 'tcx> {
     cx: &'a LateContext<'tcx>,          // context reference
     states: FxHashMap<HirId, VarState>, // incremented variables
@@ -2154,6 +2158,10 @@ impl<'a, 'tcx> Visitor<'tcx> for IncrementVisitor<'a, 'tcx> {
         if let Some(def_id) = var_def_id(self.cx, expr) {
             if let Some(parent) = get_parent_expr(self.cx, expr) {
                 let state = self.states.entry(def_id).or_insert(VarState::Initial);
+                if *state == VarState::IncrOnce {
+                    *state = VarState::DontWarn;
+                    return;
+                }
 
                 match parent.kind {
                     ExprKind::AssignOp(op, ref lhs, ref rhs) => {
diff --git a/clippy_lints/src/missing_const_for_fn.rs b/clippy_lints/src/missing_const_for_fn.rs
index 80da04fb7de..25245b3dbf0 100644
--- a/clippy_lints/src/missing_const_for_fn.rs
+++ b/clippy_lints/src/missing_const_for_fn.rs
@@ -1,10 +1,10 @@
+use crate::utils::qualify_min_const_fn::is_min_const_fn;
 use crate::utils::{fn_has_unsatisfiable_preds, has_drop, is_entrypoint_fn, span_lint, trait_ref_of_method};
 use rustc_hir as hir;
 use rustc_hir::intravisit::FnKind;
 use rustc_hir::{Body, Constness, FnDecl, GenericParamKind, HirId};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::lint::in_external_macro;
-use crate::utils::qualify_min_const_fn::is_min_const_fn;
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::Span;
 use rustc_typeck::hir_ty_to_ty;
diff --git a/clippy_lints/src/needless_arbitrary_self_type.rs b/clippy_lints/src/needless_arbitrary_self_type.rs
index 38bdd0f7ed2..7687962bdd9 100644
--- a/clippy_lints/src/needless_arbitrary_self_type.rs
+++ b/clippy_lints/src/needless_arbitrary_self_type.rs
@@ -1,4 +1,4 @@
-use crate::utils::span_lint_and_sugg;
+use crate::utils::{in_macro, span_lint_and_sugg};
 use if_chain::if_chain;
 use rustc_ast::ast::{BindingMode, Lifetime, Mutability, Param, PatKind, Path, TyKind};
 use rustc_errors::Applicability;
@@ -69,11 +69,30 @@ fn check_param_inner(cx: &EarlyContext<'_>, path: &Path, span: Span, binding_mod
         if let [segment] = &path.segments[..];
         if segment.ident.name == kw::SelfUpper;
         then {
+            // In case we have a named lifetime, we check if the name comes from expansion.
+            // If it does, at this point we know the rest of the parameter was written by the user,
+            // so let them decide what the name of the lifetime should be.
+            // See #6089 for more details.
+            let mut applicability = Applicability::MachineApplicable;
             let self_param = match (binding_mode, mutbl) {
                 (Mode::Ref(None), Mutability::Mut) => "&mut self".to_string(),
-                (Mode::Ref(Some(lifetime)), Mutability::Mut) => format!("&{} mut self", &lifetime.ident.name),
+                (Mode::Ref(Some(lifetime)), Mutability::Mut) => {
+                    if in_macro(lifetime.ident.span) {
+                        applicability = Applicability::HasPlaceholders;
+                        "&'_ mut self".to_string()
+                    } else {
+                        format!("&{} mut self", &lifetime.ident.name)
+                    }
+                },
                 (Mode::Ref(None), Mutability::Not) => "&self".to_string(),
-                (Mode::Ref(Some(lifetime)), Mutability::Not) => format!("&{} self", &lifetime.ident.name),
+                (Mode::Ref(Some(lifetime)), Mutability::Not) => {
+                    if in_macro(lifetime.ident.span) {
+                        applicability = Applicability::HasPlaceholders;
+                        "&'_ self".to_string()
+                    } else {
+                        format!("&{} self", &lifetime.ident.name)
+                    }
+                },
                 (Mode::Value, Mutability::Mut) => "mut self".to_string(),
                 (Mode::Value, Mutability::Not) => "self".to_string(),
             };
@@ -85,7 +104,7 @@ fn check_param_inner(cx: &EarlyContext<'_>, path: &Path, span: Span, binding_mod
                 "the type of the `self` parameter does not need to be arbitrary",
                 "consider to change this parameter to",
                 self_param,
-                Applicability::MachineApplicable,
+                applicability,
             )
         }
     }
@@ -93,7 +112,8 @@ fn check_param_inner(cx: &EarlyContext<'_>, path: &Path, span: Span, binding_mod
 
 impl EarlyLintPass for NeedlessArbitrarySelfType {
     fn check_param(&mut self, cx: &EarlyContext<'_>, p: &Param) {
-        if !p.is_self() {
+        // Bail out if the parameter it's not a receiver or was not written by the user
+        if !p.is_self() || in_macro(p.span) {
             return;
         }
 
diff --git a/clippy_lints/src/non_copy_const.rs b/clippy_lints/src/non_copy_const.rs
index bb44eeb6adc..7b662eae775 100644
--- a/clippy_lints/src/non_copy_const.rs
+++ b/clippy_lints/src/non_copy_const.rs
@@ -1,6 +1,6 @@
 //! Checks for uses of const which the type is not `Freeze` (`Cell`-free).
 //!
-//! This lint is **deny** by default.
+//! This lint is **warn** by default.
 
 use std::ptr;
 
@@ -17,6 +17,8 @@ use rustc_typeck::hir_ty_to_ty;
 use crate::utils::{in_constant, qpath_res, span_lint_and_then};
 use if_chain::if_chain;
 
+// FIXME: this is a correctness problem but there's no suitable
+// warn-by-default category.
 declare_clippy_lint! {
     /// **What it does:** Checks for declaration of `const` items which is interior
     /// mutable (e.g., contains a `Cell`, `Mutex`, `AtomicXxxx`, etc.).
@@ -34,6 +36,15 @@ declare_clippy_lint! {
     /// `std::sync::ONCE_INIT` constant). In this case the use of `const` is legit,
     /// and this lint should be suppressed.
     ///
+    /// When an enum has variants with interior mutability, use of its non interior mutable
+    /// variants can generate false positives. See issue
+    /// [#3962](https://github.com/rust-lang/rust-clippy/issues/3962)
+    ///
+    /// Types that have underlying or potential interior mutability trigger the lint whether
+    /// the interior mutable field is used or not. See issues
+    /// [#5812](https://github.com/rust-lang/rust-clippy/issues/5812) and
+    /// [#3825](https://github.com/rust-lang/rust-clippy/issues/3825)
+    ///
     /// **Example:**
     /// ```rust
     /// use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
@@ -49,10 +60,12 @@ declare_clippy_lint! {
     /// assert_eq!(STATIC_ATOM.load(SeqCst), 9); // use a `static` item to refer to the same instance
     /// ```
     pub DECLARE_INTERIOR_MUTABLE_CONST,
-    correctness,
+    style,
     "declaring `const` with interior mutability"
 }
 
+// FIXME: this is a correctness problem but there's no suitable
+// warn-by-default category.
 declare_clippy_lint! {
     /// **What it does:** Checks if `const` items which is interior mutable (e.g.,
     /// contains a `Cell`, `Mutex`, `AtomicXxxx`, etc.) has been borrowed directly.
@@ -64,7 +77,14 @@ declare_clippy_lint! {
     ///
     /// The `const` value should be stored inside a `static` item.
     ///
-    /// **Known problems:** None
+    /// **Known problems:** When an enum has variants with interior mutability, use of its non
+    /// interior mutable variants can generate false positives. See issue
+    /// [#3962](https://github.com/rust-lang/rust-clippy/issues/3962)
+    ///
+    /// Types that have underlying or potential interior mutability trigger the lint whether
+    /// the interior mutable field is used or not. See issues
+    /// [#5812](https://github.com/rust-lang/rust-clippy/issues/5812) and
+    /// [#3825](https://github.com/rust-lang/rust-clippy/issues/3825)
     ///
     /// **Example:**
     /// ```rust
@@ -81,7 +101,7 @@ declare_clippy_lint! {
     /// assert_eq!(STATIC_ATOM.load(SeqCst), 9); // use a `static` item to refer to the same instance
     /// ```
     pub BORROW_INTERIOR_MUTABLE_CONST,
-    correctness,
+    style,
     "referencing `const` with interior mutability"
 }
 
diff --git a/clippy_lints/src/types.rs b/clippy_lints/src/types.rs
index a29a199b8c3..17d950169fd 100644
--- a/clippy_lints/src/types.rs
+++ b/clippy_lints/src/types.rs
@@ -216,18 +216,19 @@ declare_clippy_lint! {
 }
 
 declare_clippy_lint! {
-    /// **What it does:** Checks for Rc<T> and Arc<T> when T is a mutable buffer type such as String or Vec
+    /// **What it does:** Checks for `Rc<T>` and `Arc<T>` when `T` is a mutable buffer type such as `String` or `Vec`.
     ///
-    /// **Why is this bad?** Expressions such as Rc<String> have no advantage over Rc<str>, since
-    /// it is larger and involves an extra level of indirection, and doesn't implement Borrow<str>.
+    /// **Why is this bad?** Expressions such as `Rc<String>` usually have no advantage over `Rc<str>`, since
+    /// it is larger and involves an extra level of indirection, and doesn't implement `Borrow<str>`.
     ///
-    /// While mutating a buffer type would still be possible with Rc::get_mut(), it only
-    /// works if there are no additional references yet, which defeats the purpose of
+    /// While mutating a buffer type would still be possible with `Rc::get_mut()`, it only
+    /// works if there are no additional references yet, which usually defeats the purpose of
     /// enclosing it in a shared ownership type. Instead, additionally wrapping the inner
-    /// type with an interior mutable container (such as RefCell or Mutex) would normally
+    /// type with an interior mutable container (such as `RefCell` or `Mutex`) would normally
     /// be used.
     ///
-    /// **Known problems:** None.
+    /// **Known problems:** This pattern can be desirable to avoid the overhead of a `RefCell` or `Mutex` for
+    /// cases where mutation only happens before there are any additional references.
     ///
     /// **Example:**
     /// ```rust,ignore
diff --git a/clippy_lints/src/unicode.rs b/clippy_lints/src/unicode.rs
index d8c57f0e7ae..93d59cc7fcd 100644
--- a/clippy_lints/src/unicode.rs
+++ b/clippy_lints/src/unicode.rs
@@ -8,18 +8,18 @@ use rustc_span::source_map::Span;
 use unicode_normalization::UnicodeNormalization;
 
 declare_clippy_lint! {
-    /// **What it does:** Checks for the Unicode zero-width space in the code.
+    /// **What it does:** Checks for invisible Unicode characters in the code.
     ///
     /// **Why is this bad?** Having an invisible character in the code makes for all
     /// sorts of April fools, but otherwise is very much frowned upon.
     ///
     /// **Known problems:** None.
     ///
-    /// **Example:** You don't see it, but there may be a zero-width space
-    /// somewhere in this text.
-    pub ZERO_WIDTH_SPACE,
+    /// **Example:** You don't see it, but there may be a zero-width space or soft hyphen
+    /// some­where in this text.
+    pub INVISIBLE_CHARACTERS,
     correctness,
-    "using a zero-width space in a string literal, which is confusing"
+    "using an invisible character in a string literal, which is confusing"
 }
 
 declare_clippy_lint! {
@@ -63,7 +63,7 @@ declare_clippy_lint! {
     "using a Unicode literal not in NFC normal form (see [Unicode tr15](http://www.unicode.org/reports/tr15/) for further information)"
 }
 
-declare_lint_pass!(Unicode => [ZERO_WIDTH_SPACE, NON_ASCII_LITERAL, UNICODE_NOT_NFC]);
+declare_lint_pass!(Unicode => [INVISIBLE_CHARACTERS, NON_ASCII_LITERAL, UNICODE_NOT_NFC]);
 
 impl LateLintPass<'_> for Unicode {
     fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'_ Expr<'_>) {
@@ -91,14 +91,17 @@ fn escape<T: Iterator<Item = char>>(s: T) -> String {
 
 fn check_str(cx: &LateContext<'_>, span: Span, id: HirId) {
     let string = snippet(cx, span, "");
-    if string.contains('\u{200B}') {
+    if string.chars().any(|c| ['\u{200B}', '\u{ad}', '\u{2060}'].contains(&c)) {
         span_lint_and_sugg(
             cx,
-            ZERO_WIDTH_SPACE,
+            INVISIBLE_CHARACTERS,
             span,
-            "zero-width space detected",
+            "invisible character detected",
             "consider replacing the string with",
-            string.replace("\u{200B}", "\\u{200B}"),
+            string
+                .replace("\u{200B}", "\\u{200B}")
+                .replace("\u{ad}", "\\u{AD}")
+                .replace("\u{2060}", "\\u{2060}"),
             Applicability::MachineApplicable,
         );
     }
diff --git a/clippy_lints/src/utils/conf.rs b/clippy_lints/src/utils/conf.rs
index 9c5a12ea9c8..03f8c5a2c07 100644
--- a/clippy_lints/src/utils/conf.rs
+++ b/clippy_lints/src/utils/conf.rs
@@ -164,6 +164,8 @@ define_Conf! {
     (max_fn_params_bools, "max_fn_params_bools": u64, 3),
     /// Lint: WILDCARD_IMPORTS. Whether to allow certain wildcard imports (prelude, super in tests).
     (warn_on_all_wildcard_imports, "warn_on_all_wildcard_imports": bool, false),
+    /// Lint: DISALLOWED_METHOD. The list of blacklisted methods to lint about. NB: `bar` is not here since it has legitimate uses
+    (disallowed_methods, "disallowed_methods": Vec<String>, Vec::<String>::new()),
 }
 
 impl Default for Conf {
diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs
index 96d9905027b..dfe2aadffc0 100644
--- a/clippy_lints/src/utils/mod.rs
+++ b/clippy_lints/src/utils/mod.rs
@@ -18,9 +18,9 @@ pub mod internal_lints;
 pub mod numeric_literal;
 pub mod paths;
 pub mod ptr;
+pub mod qualify_min_const_fn;
 pub mod sugg;
 pub mod usage;
-pub mod qualify_min_const_fn;
 
 pub use self::attrs::*;
 pub use self::diagnostics::*;
@@ -47,7 +47,6 @@ use rustc_lint::{LateContext, Level, Lint, LintContext};
 use rustc_middle::hir::map::Map;
 use rustc_middle::ty::subst::{GenericArg, GenericArgKind};
 use rustc_middle::ty::{self, layout::IntegerExt, Ty, TyCtxt, TypeFoldable};
-use rustc_mir::const_eval;
 use rustc_span::hygiene::{ExpnKind, MacroKind};
 use rustc_span::source_map::original_sp;
 use rustc_span::symbol::{self, kw, Symbol};
@@ -884,19 +883,11 @@ pub fn is_copy<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
 
 /// Checks if an expression is constructing a tuple-like enum variant or struct
 pub fn is_ctor_or_promotable_const_function(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
-    fn has_no_arguments(cx: &LateContext<'_>, def_id: DefId) -> bool {
-        cx.tcx.fn_sig(def_id).skip_binder().inputs().is_empty()
-    }
-
     if let ExprKind::Call(ref fun, _) = expr.kind {
         if let ExprKind::Path(ref qp) = fun.kind {
             let res = cx.qpath_res(qp, fun.hir_id);
             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 | 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),
                 _ => false,
             };
diff --git a/clippy_lints/src/utils/numeric_literal.rs b/clippy_lints/src/utils/numeric_literal.rs
index 5e8800d38eb..52d3c2c1daf 100644
--- a/clippy_lints/src/utils/numeric_literal.rs
+++ b/clippy_lints/src/utils/numeric_literal.rs
@@ -36,8 +36,9 @@ pub struct NumericLiteral<'a> {
     pub integer: &'a str,
     /// The fraction part of the number.
     pub fraction: Option<&'a str>,
-    /// The character used as exponent separator (b'e' or b'E') and the exponent part.
-    pub exponent: Option<(char, &'a str)>,
+    /// The exponent separator (b'e' or b'E') including preceding underscore if present
+    /// and the exponent part.
+    pub exponent: Option<(&'a str, &'a str)>,
 
     /// The type suffix, including preceding underscore if present.
     pub suffix: Option<&'a str>,
@@ -100,7 +101,7 @@ impl<'a> NumericLiteral<'a> {
         self.radix == Radix::Decimal
     }
 
-    pub fn split_digit_parts(digits: &str, float: bool) -> (&str, Option<&str>, Option<(char, &str)>) {
+    pub fn split_digit_parts(digits: &str, float: bool) -> (&str, Option<&str>, Option<(&str, &str)>) {
         let mut integer = digits;
         let mut fraction = None;
         let mut exponent = None;
@@ -113,12 +114,14 @@ impl<'a> NumericLiteral<'a> {
                         fraction = Some(&digits[i + 1..]);
                     },
                     'e' | 'E' => {
-                        if integer.len() > i {
-                            integer = &digits[..i];
+                        let exp_start = if digits[..i].ends_with('_') { i - 1 } else { i };
+
+                        if integer.len() > exp_start {
+                            integer = &digits[..exp_start];
                         } else {
-                            fraction = Some(&digits[integer.len() + 1..i]);
+                            fraction = Some(&digits[integer.len() + 1..exp_start]);
                         };
-                        exponent = Some((c, &digits[i + 1..]));
+                        exponent = Some((&digits[exp_start..=i], &digits[i + 1..]));
                         break;
                     },
                     _ => {},
@@ -153,7 +156,7 @@ impl<'a> NumericLiteral<'a> {
         }
 
         if let Some((separator, exponent)) = self.exponent {
-            output.push(separator);
+            output.push_str(separator);
             Self::group_digits(&mut output, exponent, group_size, true, false);
         }
 
diff --git a/clippy_lints/src/utils/paths.rs b/clippy_lints/src/utils/paths.rs
index be837a61dc0..277da9d3f3a 100644
--- a/clippy_lints/src/utils/paths.rs
+++ b/clippy_lints/src/utils/paths.rs
@@ -41,6 +41,9 @@ pub const FILE_TYPE: [&str; 3] = ["std", "fs", "FileType"];
 pub const FMT_ARGUMENTS_NEW_V1: [&str; 4] = ["core", "fmt", "Arguments", "new_v1"];
 pub const FMT_ARGUMENTS_NEW_V1_FORMATTED: [&str; 4] = ["core", "fmt", "Arguments", "new_v1_formatted"];
 pub const FMT_ARGUMENTV1_NEW: [&str; 4] = ["core", "fmt", "ArgumentV1", "new"];
+pub const FN: [&str; 3] = ["core", "ops", "Fn"];
+pub const FN_MUT: [&str; 3] = ["core", "ops", "FnMut"];
+pub const FN_ONCE: [&str; 3] = ["core", "ops", "FnOnce"];
 pub const FROM_FROM: [&str; 4] = ["core", "convert", "From", "from"];
 pub const FROM_TRAIT: [&str; 3] = ["core", "convert", "From"];
 pub const FUTURE_FROM_GENERATOR: [&str; 3] = ["core", "future", "from_generator"];
diff --git a/clippy_lints/src/utils/qualify_min_const_fn.rs b/clippy_lints/src/utils/qualify_min_const_fn.rs
index 19d890b4554..1b4f2034272 100644
--- a/clippy_lints/src/utils/qualify_min_const_fn.rs
+++ b/clippy_lints/src/utils/qualify_min_const_fn.rs
@@ -1,9 +1,12 @@
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
-use rustc_middle::mir::*;
+use rustc_middle::mir::{
+    Body, CastKind, NullOp, Operand, Place, ProjectionElem, Rvalue, Statement, StatementKind, Terminator,
+    TerminatorKind,
+};
 use rustc_middle::ty::subst::GenericArgKind;
 use rustc_middle::ty::{self, adjustment::PointerCast, Ty, TyCtxt};
-use rustc_span::symbol::{sym};
+use rustc_span::symbol::sym;
 use rustc_span::Span;
 use rustc_target::spec::abi::Abi::RustIntrinsic;
 use std::borrow::Cow;
@@ -24,15 +27,9 @@ pub fn is_min_const_fn(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>) -> McfResult {
                 | ty::PredicateAtom::ConstEvaluatable(..)
                 | ty::PredicateAtom::ConstEquate(..)
                 | ty::PredicateAtom::TypeWellFormedFromEnv(..) => continue,
-                ty::PredicateAtom::ObjectSafe(_) => {
-                    panic!("object safe predicate on function: {:#?}", predicate)
-                }
-                ty::PredicateAtom::ClosureKind(..) => {
-                    panic!("closure kind predicate on function: {:#?}", predicate)
-                }
-                ty::PredicateAtom::Subtype(_) => {
-                    panic!("subtype predicate on function: {:#?}", predicate)
-                }
+                ty::PredicateAtom::ObjectSafe(_) => panic!("object safe predicate on function: {:#?}", predicate),
+                ty::PredicateAtom::ClosureKind(..) => panic!("closure kind predicate on function: {:#?}", predicate),
+                ty::PredicateAtom::Subtype(_) => panic!("subtype predicate on function: {:#?}", predicate),
                 ty::PredicateAtom::Trait(pred, _) => {
                     if Some(pred.def_id()) == tcx.lang_items().sized_trait() {
                         continue;
@@ -48,12 +45,12 @@ pub fn is_min_const_fn(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>) -> McfResult {
                                  on const fn parameters are unstable"
                                     .into(),
                             ));
-                        }
+                        },
                         // other kinds of bounds are either tautologies
                         // or cause errors in other passes
                         _ => continue,
                     }
-                }
+                },
             }
         }
         match predicates.parent {
@@ -93,24 +90,23 @@ fn check_ty(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span) -> McfResult {
 
         match ty.kind() {
             ty::Ref(_, _, hir::Mutability::Mut) => {
-                    return Err((span, "mutable references in const fn are unstable".into()));
-            }
+                return Err((span, "mutable references in const fn are unstable".into()));
+            },
             ty::Opaque(..) => return Err((span, "`impl Trait` in const fn is unstable".into())),
             ty::FnPtr(..) => {
-                    return Err((span, "function pointers in const fn are unstable".into()));
-            }
+                return Err((span, "function pointers in const fn are unstable".into()));
+            },
             ty::Dynamic(preds, _) => {
                 for pred in preds.iter() {
                     match pred.skip_binder() {
-                        ty::ExistentialPredicate::AutoTrait(_)
-                        | ty::ExistentialPredicate::Projection(_) => {
+                        ty::ExistentialPredicate::AutoTrait(_) | ty::ExistentialPredicate::Projection(_) => {
                             return Err((
                                 span,
                                 "trait bounds other than `Sized` \
                                  on const fn parameters are unstable"
                                     .into(),
                             ));
-                        }
+                        },
                         ty::ExistentialPredicate::Trait(trait_ref) => {
                             if Some(trait_ref.def_id) != tcx.lang_items().sized_trait() {
                                 return Err((
@@ -120,34 +116,23 @@ fn check_ty(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span) -> McfResult {
                                         .into(),
                                 ));
                             }
-                        }
+                        },
                     }
                 }
-            }
-            _ => {}
+            },
+            _ => {},
         }
     }
     Ok(())
 }
 
-fn check_rvalue(
-    tcx: TyCtxt<'tcx>,
-    body: &Body<'tcx>,
-    def_id: DefId,
-    rvalue: &Rvalue<'tcx>,
-    span: Span,
-) -> McfResult {
+fn check_rvalue(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, def_id: DefId, rvalue: &Rvalue<'tcx>, span: Span) -> McfResult {
     match rvalue {
-        Rvalue::ThreadLocalRef(_) => {
-            Err((span, "cannot access thread local storage in const fn".into()))
-        }
-        Rvalue::Repeat(operand, _) | Rvalue::Use(operand) => {
-            check_operand(tcx, operand, span, body)
-        }
-        Rvalue::Len(place)
-        | Rvalue::Discriminant(place)
-        | Rvalue::Ref(_, _, place)
-        | Rvalue::AddressOf(_, place) => check_place(tcx, *place, span,  body),
+        Rvalue::ThreadLocalRef(_) => Err((span, "cannot access thread local storage in const fn".into())),
+        Rvalue::Repeat(operand, _) | Rvalue::Use(operand) => check_operand(tcx, operand, span, body),
+        Rvalue::Len(place) | Rvalue::Discriminant(place) | Rvalue::Ref(_, _, place) | Rvalue::AddressOf(_, place) => {
+            check_place(tcx, *place, span, body)
+        },
         Rvalue::Cast(CastKind::Misc, operand, cast_ty) => {
             use rustc_middle::ty::cast::CastTy;
             let cast_in = CastTy::from_ty(operand.ty(body, tcx)).expect("bad input type for cast");
@@ -155,20 +140,16 @@ fn check_rvalue(
             match (cast_in, cast_out) {
                 (CastTy::Ptr(_) | CastTy::FnPtr, CastTy::Int(_)) => {
                     Err((span, "casting pointers to ints is unstable in const fn".into()))
-                }
+                },
                 _ => check_operand(tcx, operand, span, body),
             }
-        }
-        Rvalue::Cast(
-            CastKind::Pointer(PointerCast::MutToConstPointer | PointerCast::ArrayToPointer),
-            operand,
-            _,
-        ) => check_operand(tcx, operand, span, body),
+        },
+        Rvalue::Cast(CastKind::Pointer(PointerCast::MutToConstPointer | PointerCast::ArrayToPointer), operand, _) => {
+            check_operand(tcx, operand, span, body)
+        },
         Rvalue::Cast(
             CastKind::Pointer(
-                PointerCast::UnsafeFnPointer
-                | PointerCast::ClosureFnPointer(_)
-                | PointerCast::ReifyFnPointer,
+                PointerCast::UnsafeFnPointer | PointerCast::ClosureFnPointer(_) | PointerCast::ReifyFnPointer,
             ),
             _,
             _,
@@ -178,10 +159,7 @@ fn check_rvalue(
                 deref_ty.ty
             } else {
                 // We cannot allow this for now.
-                return Err((
-                    span,
-                    "unsizing casts are only allowed for references right now".into(),
-                ));
+                return Err((span, "unsizing casts are only allowed for references right now".into()));
             };
             let unsized_ty = tcx.struct_tail_erasing_lifetimes(pointee_ty, tcx.param_env(def_id));
             if let ty::Slice(_) | ty::Str = unsized_ty.kind() {
@@ -192,7 +170,7 @@ fn check_rvalue(
                 // We just can't allow trait objects until we have figured out trait method calls.
                 Err((span, "unsizing casts are not allowed in const fn".into()))
             }
-        }
+        },
         // binops are fine on integers
         Rvalue::BinaryOp(_, lhs, rhs) | Rvalue::CheckedBinaryOp(_, lhs, rhs) => {
             check_operand(tcx, lhs, span, body)?;
@@ -201,13 +179,14 @@ fn check_rvalue(
             if ty.is_integral() || ty.is_bool() || ty.is_char() {
                 Ok(())
             } else {
-                Err((span, "only int, `bool` and `char` operations are stable in const fn".into()))
+                Err((
+                    span,
+                    "only int, `bool` and `char` operations are stable in const fn".into(),
+                ))
             }
-        }
+        },
         Rvalue::NullaryOp(NullOp::SizeOf, _) => Ok(()),
-        Rvalue::NullaryOp(NullOp::Box, _) => {
-            Err((span, "heap allocations are not allowed in const fn".into()))
-        }
+        Rvalue::NullaryOp(NullOp::Box, _) => Err((span, "heap allocations are not allowed in const fn".into())),
         Rvalue::UnaryOp(_, operand) => {
             let ty = operand.ty(body, tcx);
             if ty.is_integral() || ty.is_bool() {
@@ -215,39 +194,29 @@ fn check_rvalue(
             } else {
                 Err((span, "only int and `bool` operations are stable in const fn".into()))
             }
-        }
+        },
         Rvalue::Aggregate(_, operands) => {
             for operand in operands {
                 check_operand(tcx, operand, span, body)?;
             }
             Ok(())
-        }
+        },
     }
 }
 
-fn check_statement(
-    tcx: TyCtxt<'tcx>,
-    body: &Body<'tcx>,
-    def_id: DefId,
-    statement: &Statement<'tcx>,
-) -> McfResult {
+fn check_statement(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, def_id: DefId, statement: &Statement<'tcx>) -> McfResult {
     let span = statement.source_info.span;
     match &statement.kind {
         StatementKind::Assign(box (place, rval)) => {
-            check_place(tcx, *place, span,  body)?;
+            check_place(tcx, *place, span, body)?;
             check_rvalue(tcx, body, def_id, rval, span)
-        }
-
-        StatementKind::FakeRead(_, place) => check_place(tcx, **place, span, body),
+        },
 
+        StatementKind::FakeRead(_, place) |
         // just an assignment
-        StatementKind::SetDiscriminant { place, .. } => {
-            check_place(tcx, **place, span,  body)
-        }
+        StatementKind::SetDiscriminant { place, .. } => check_place(tcx, **place, span, body),
 
-        StatementKind::LlvmInlineAsm { .. } => {
-            Err((span, "cannot use inline assembly in const fn".into()))
-        }
+        StatementKind::LlvmInlineAsm { .. } => Err((span, "cannot use inline assembly in const fn".into())),
 
         // These are all NOPs
         StatementKind::StorageLive(_)
@@ -259,12 +228,7 @@ fn check_statement(
     }
 }
 
-fn check_operand(
-    tcx: TyCtxt<'tcx>,
-    operand: &Operand<'tcx>,
-    span: Span,
-    body: &Body<'tcx>,
-) -> McfResult {
+fn check_operand(tcx: TyCtxt<'tcx>, operand: &Operand<'tcx>, span: Span, body: &Body<'tcx>) -> McfResult {
     match operand {
         Operand::Move(place) | Operand::Copy(place) => check_place(tcx, *place, span, body),
         Operand::Constant(c) => match c.check_static_ptr(tcx) {
@@ -274,14 +238,9 @@ fn check_operand(
     }
 }
 
-fn check_place(
-    tcx: TyCtxt<'tcx>,
-    place: Place<'tcx>,
-    span: Span,
-    body: &Body<'tcx>,
-) -> McfResult {
+fn check_place(tcx: TyCtxt<'tcx>, place: Place<'tcx>, span: Span, body: &Body<'tcx>) -> McfResult {
     let mut cursor = place.projection.as_ref();
-    while let &[ref proj_base @ .., elem] = cursor {
+    while let [ref proj_base @ .., elem] = *cursor {
         cursor = proj_base;
         match elem {
             ProjectionElem::Field(..) => {
@@ -289,26 +248,22 @@ fn check_place(
                 if let Some(def) = base_ty.ty_adt_def() {
                     // No union field accesses in `const fn`
                     if def.is_union() {
-                            return Err((span, "accessing union fields is unstable".into()));
+                        return Err((span, "accessing union fields is unstable".into()));
                     }
                 }
-            }
+            },
             ProjectionElem::ConstantIndex { .. }
             | ProjectionElem::Downcast(..)
             | ProjectionElem::Subslice { .. }
             | ProjectionElem::Deref
-            | ProjectionElem::Index(_) => {}
+            | ProjectionElem::Index(_) => {},
         }
     }
 
     Ok(())
 }
 
-fn check_terminator(
-    tcx: TyCtxt<'tcx>,
-    body: &'a Body<'tcx>,
-    terminator: &Terminator<'tcx>,
-) -> McfResult {
+fn check_terminator(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, terminator: &Terminator<'tcx>) -> McfResult {
     let span = terminator.source_info.span;
     match &terminator.kind {
         TerminatorKind::FalseEdge { .. }
@@ -318,20 +273,23 @@ fn check_terminator(
         | TerminatorKind::Resume
         | TerminatorKind::Unreachable => Ok(()),
 
-        TerminatorKind::Drop { place, .. } => check_place(tcx, *place, span,  body),
+        TerminatorKind::Drop { place, .. } => check_place(tcx, *place, span, body),
         TerminatorKind::DropAndReplace { place, value, .. } => {
-            check_place(tcx, *place, span,  body)?;
+            check_place(tcx, *place, span, body)?;
             check_operand(tcx, value, span, body)
-        }
+        },
 
-        TerminatorKind::SwitchInt { discr, switch_ty: _, values: _, targets: _ } => {
-            check_operand(tcx, discr, span, body)
-        }
+        TerminatorKind::SwitchInt {
+            discr,
+            switch_ty: _,
+            values: _,
+            targets: _,
+        } => check_operand(tcx, discr, span, body),
 
         TerminatorKind::Abort => Err((span, "abort is not stable in const fn".into())),
         TerminatorKind::GeneratorDrop | TerminatorKind::Yield { .. } => {
             Err((span, "const fn generators are unstable".into()))
-        }
+        },
 
         TerminatorKind::Call {
             func,
@@ -343,8 +301,7 @@ fn check_terminator(
         } => {
             let fn_ty = func.ty(body, tcx);
             if let ty::FnDef(fn_def_id, _) = *fn_ty.kind() {
-                if !rustc_mir::const_eval::is_min_const_fn(tcx, fn_def_id)
-                {
+                if !rustc_mir::const_eval::is_min_const_fn(tcx, fn_def_id) {
                     return Err((
                         span,
                         format!(
@@ -360,9 +317,7 @@ fn check_terminator(
                 // within const fns. `transmute` is allowed in all other const contexts.
                 // This won't really scale to more intrinsics or functions. Let's allow const
                 // transmutes in const fn before we add more hacks to this.
-                if tcx.fn_sig(fn_def_id).abi() == RustIntrinsic
-                    && tcx.item_name(fn_def_id) == sym::transmute
-                {
+                if tcx.fn_sig(fn_def_id).abi() == RustIntrinsic && tcx.item_name(fn_def_id) == sym::transmute {
                     return Err((
                         span,
                         "can only call `transmute` from const items, not `const fn`".into(),
@@ -378,14 +333,16 @@ fn check_terminator(
             } else {
                 Err((span, "can only call other const fns within const fn".into()))
             }
-        }
+        },
 
-        TerminatorKind::Assert { cond, expected: _, msg: _, target: _, cleanup: _ } => {
-            check_operand(tcx, cond, span, body)
-        }
+        TerminatorKind::Assert {
+            cond,
+            expected: _,
+            msg: _,
+            target: _,
+            cleanup: _,
+        } => check_operand(tcx, cond, span, body),
 
-        TerminatorKind::InlineAsm { .. } => {
-            Err((span, "cannot use inline assembly in const fn".into()))
-        }
+        TerminatorKind::InlineAsm { .. } => Err((span, "cannot use inline assembly in const fn".into())),
     }
 }
diff --git a/clippy_lints/src/write.rs b/clippy_lints/src/write.rs
index fac63bcb993..d9d60fffcd7 100644
--- a/clippy_lints/src/write.rs
+++ b/clippy_lints/src/write.rs
@@ -235,8 +235,19 @@ impl EarlyLintPass for Write {
     }
 
     fn check_mac(&mut self, cx: &EarlyContext<'_>, mac: &MacCall) {
+        fn is_build_script(cx: &EarlyContext<'_>) -> bool {
+            // Cargo sets the crate name for build scripts to `build_script_build`
+            cx.sess
+                .opts
+                .crate_name
+                .as_ref()
+                .map_or(false, |crate_name| crate_name == "build_script_build")
+        }
+
         if mac.path == sym!(println) {
-            span_lint(cx, PRINT_STDOUT, mac.span(), "use of `println!`");
+            if !is_build_script(cx) {
+                span_lint(cx, PRINT_STDOUT, mac.span(), "use of `println!`");
+            }
             if let (Some(fmt_str), _) = self.check_tts(cx, mac.args.inner_tokens(), false) {
                 if fmt_str.symbol == Symbol::intern("") {
                     span_lint_and_sugg(
@@ -251,7 +262,9 @@ impl EarlyLintPass for Write {
                 }
             }
         } else if mac.path == sym!(print) {
-            span_lint(cx, PRINT_STDOUT, mac.span(), "use of `print!`");
+            if !is_build_script(cx) {
+                span_lint(cx, PRINT_STDOUT, mac.span(), "use of `print!`");
+            }
             if let (Some(fmt_str), _) = self.check_tts(cx, mac.args.inner_tokens(), false) {
                 if check_newlines(&fmt_str) {
                     span_lint_and_then(
diff --git a/clippy_workspace_tests/build.rs b/clippy_workspace_tests/build.rs
new file mode 100644
index 00000000000..3507168a3a9
--- /dev/null
+++ b/clippy_workspace_tests/build.rs
@@ -0,0 +1,7 @@
+#![deny(clippy::print_stdout)]
+
+fn main() {
+    // Test for #6041
+    println!("Hello");
+    print!("Hello");
+}
diff --git a/src/lintlist/mod.rs b/src/lintlist/mod.rs
index f6d529de9a3..0dba5a71c50 100644
--- a/src/lintlist/mod.rs
+++ b/src/lintlist/mod.rs
@@ -110,7 +110,7 @@ pub static ref ALL_LINTS: Vec<Lint> = vec![
     },
     Lint {
         name: "borrow_interior_mutable_const",
-        group: "correctness",
+        group: "style",
         desc: "referencing `const` with interior mutability",
         deprecation: None,
         module: "non_copy_const",
@@ -334,7 +334,7 @@ pub static ref ALL_LINTS: Vec<Lint> = vec![
     },
     Lint {
         name: "declare_interior_mutable_const",
-        group: "correctness",
+        group: "style",
         desc: "declaring `const` with interior mutability",
         deprecation: None,
         module: "non_copy_const",
@@ -382,6 +382,13 @@ pub static ref ALL_LINTS: Vec<Lint> = vec![
         module: "derive",
     },
     Lint {
+        name: "disallowed_method",
+        group: "nursery",
+        desc: "use of a disallowed method call",
+        deprecation: None,
+        module: "disallowed_method",
+    },
+    Lint {
         name: "diverging_sub_expression",
         group: "complexity",
         desc: "whether an expression contains a diverging sub expression",
@@ -886,6 +893,20 @@ pub static ref ALL_LINTS: Vec<Lint> = vec![
         module: "attrs",
     },
     Lint {
+        name: "inline_asm_x86_att_syntax",
+        group: "restriction",
+        desc: "prefer Intel x86 assembly syntax",
+        deprecation: None,
+        module: "asm_syntax",
+    },
+    Lint {
+        name: "inline_asm_x86_intel_syntax",
+        group: "restriction",
+        desc: "prefer AT&T x86 assembly syntax",
+        deprecation: None,
+        module: "asm_syntax",
+    },
+    Lint {
         name: "inline_fn_without_body",
         group: "correctness",
         desc: "use of `#[inline]` on trait methods without bodies",
@@ -942,6 +963,13 @@ pub static ref ALL_LINTS: Vec<Lint> = vec![
         module: "types",
     },
     Lint {
+        name: "invisible_characters",
+        group: "correctness",
+        desc: "using an invisible character in a string literal, which is confusing",
+        deprecation: None,
+        module: "unicode",
+    },
+    Lint {
         name: "items_after_statements",
         group: "pedantic",
         desc: "blocks where an item comes after a statement",
@@ -2783,13 +2811,6 @@ pub static ref ALL_LINTS: Vec<Lint> = vec![
         module: "misc",
     },
     Lint {
-        name: "zero_width_space",
-        group: "correctness",
-        desc: "using a zero-width space in a string literal, which is confusing",
-        deprecation: None,
-        module: "unicode",
-    },
-    Lint {
         name: "zst_offset",
         group: "correctness",
         desc: "Check for offset calculations on raw pointers to zero-sized types",
diff --git a/tests/compile-test.rs b/tests/compile-test.rs
index 697823712bf..f0d73e9b0e2 100644
--- a/tests/compile-test.rs
+++ b/tests/compile-test.rs
@@ -71,7 +71,7 @@ fn default_config() -> compiletest::Config {
     }
 
     config.target_rustcflags = Some(format!(
-        "-L {0} -L {1} -Dwarnings -Zui-testing {2}",
+        "--emit=metadata -L {0} -L {1} -Dwarnings -Zui-testing {2}",
         host_lib().join("deps").display(),
         cargo::TARGET_LIB.join("deps").display(),
         third_party_crates(),
diff --git a/tests/ui-toml/toml_disallowed_method/clippy.toml b/tests/ui-toml/toml_disallowed_method/clippy.toml
new file mode 100644
index 00000000000..a1f515e443d
--- /dev/null
+++ b/tests/ui-toml/toml_disallowed_method/clippy.toml
@@ -0,0 +1 @@
+disallowed-methods = ["core::iter::traits::iterator::Iterator::sum", "regex::re_unicode::Regex::is_match"]
diff --git a/tests/ui-toml/toml_disallowed_method/conf_disallowed_method.rs b/tests/ui-toml/toml_disallowed_method/conf_disallowed_method.rs
new file mode 100644
index 00000000000..3d3f0729abd
--- /dev/null
+++ b/tests/ui-toml/toml_disallowed_method/conf_disallowed_method.rs
@@ -0,0 +1,13 @@
+#![warn(clippy::disallowed_method)]
+
+extern crate regex;
+use regex::Regex;
+
+fn main() {
+    let a = vec![1, 2, 3, 4];
+    let re = Regex::new(r"ab.*c").unwrap();
+
+    re.is_match("abc");
+
+    a.iter().sum::<i32>();
+}
diff --git a/tests/ui-toml/toml_disallowed_method/conf_disallowed_method.stderr b/tests/ui-toml/toml_disallowed_method/conf_disallowed_method.stderr
new file mode 100644
index 00000000000..ed91b5a6796
--- /dev/null
+++ b/tests/ui-toml/toml_disallowed_method/conf_disallowed_method.stderr
@@ -0,0 +1,16 @@
+error: use of a disallowed method `regex::re_unicode::Regex::is_match`
+  --> $DIR/conf_disallowed_method.rs:10:5
+   |
+LL |     re.is_match("abc");
+   |     ^^^^^^^^^^^^^^^^^^
+   |
+   = note: `-D clippy::disallowed-method` implied by `-D warnings`
+
+error: use of a disallowed method `core::iter::traits::iterator::Iterator::sum`
+  --> $DIR/conf_disallowed_method.rs:12:5
+   |
+LL |     a.iter().sum::<i32>();
+   |     ^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
index 6fbba01416a..103ec27e7d7 100644
--- a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
+++ b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
@@ -1,4 +1,4 @@
-error: error reading Clippy's configuration file `$DIR/clippy.toml`: unknown field `foobar`, expected one of `blacklisted-names`, `cognitive-complexity-threshold`, `cyclomatic-complexity-threshold`, `doc-valid-idents`, `too-many-arguments-threshold`, `type-complexity-threshold`, `single-char-binding-names-threshold`, `too-large-for-stack`, `enum-variant-name-threshold`, `enum-variant-size-threshold`, `verbose-bit-mask-threshold`, `literal-representation-threshold`, `trivial-copy-size-limit`, `too-many-lines-threshold`, `array-size-threshold`, `vec-box-size-threshold`, `max-trait-bounds`, `max-struct-bools`, `max-fn-params-bools`, `warn-on-all-wildcard-imports`, `third-party` at line 5 column 1
+error: error reading Clippy's configuration file `$DIR/clippy.toml`: unknown field `foobar`, expected one of `blacklisted-names`, `cognitive-complexity-threshold`, `cyclomatic-complexity-threshold`, `doc-valid-idents`, `too-many-arguments-threshold`, `type-complexity-threshold`, `single-char-binding-names-threshold`, `too-large-for-stack`, `enum-variant-name-threshold`, `enum-variant-size-threshold`, `verbose-bit-mask-threshold`, `literal-representation-threshold`, `trivial-copy-size-limit`, `too-many-lines-threshold`, `array-size-threshold`, `vec-box-size-threshold`, `max-trait-bounds`, `max-struct-bools`, `max-fn-params-bools`, `warn-on-all-wildcard-imports`, `disallowed-methods`, `third-party` at line 5 column 1
 
 error: aborting due to previous error
 
diff --git a/tests/ui/asm_syntax.rs b/tests/ui/asm_syntax.rs
new file mode 100644
index 00000000000..658cae397e1
--- /dev/null
+++ b/tests/ui/asm_syntax.rs
@@ -0,0 +1,31 @@
+#![feature(asm)]
+// only-x86_64
+
+#[warn(clippy::inline_asm_x86_intel_syntax)]
+mod warn_intel {
+    pub(super) unsafe fn use_asm() {
+        asm!("");
+        asm!("", options());
+        asm!("", options(nostack));
+        asm!("", options(att_syntax));
+        asm!("", options(nostack, att_syntax));
+    }
+}
+
+#[warn(clippy::inline_asm_x86_att_syntax)]
+mod warn_att {
+    pub(super) unsafe fn use_asm() {
+        asm!("");
+        asm!("", options());
+        asm!("", options(nostack));
+        asm!("", options(att_syntax));
+        asm!("", options(nostack, att_syntax));
+    }
+}
+
+fn main() {
+    unsafe {
+        warn_att::use_asm();
+        warn_intel::use_asm();
+    }
+}
diff --git a/tests/ui/asm_syntax.stderr b/tests/ui/asm_syntax.stderr
new file mode 100644
index 00000000000..27b51166eac
--- /dev/null
+++ b/tests/ui/asm_syntax.stderr
@@ -0,0 +1,44 @@
+error: Intel x86 assembly syntax used
+  --> $DIR/asm_syntax.rs:7:9
+   |
+LL |         asm!("");
+   |         ^^^^^^^^^
+   |
+   = note: `-D clippy::inline-asm-x86-intel-syntax` implied by `-D warnings`
+   = help: use AT&T x86 assembly syntax
+
+error: Intel x86 assembly syntax used
+  --> $DIR/asm_syntax.rs:8:9
+   |
+LL |         asm!("", options());
+   |         ^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: use AT&T x86 assembly syntax
+
+error: Intel x86 assembly syntax used
+  --> $DIR/asm_syntax.rs:9:9
+   |
+LL |         asm!("", options(nostack));
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: use AT&T x86 assembly syntax
+
+error: AT&T x86 assembly syntax used
+  --> $DIR/asm_syntax.rs:21:9
+   |
+LL |         asm!("", options(att_syntax));
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `-D clippy::inline-asm-x86-att-syntax` implied by `-D warnings`
+   = help: use Intel x86 assembly syntax
+
+error: AT&T x86 assembly syntax used
+  --> $DIR/asm_syntax.rs:22:9
+   |
+LL |         asm!("", options(nostack, att_syntax));
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: use Intel x86 assembly syntax
+
+error: aborting due to 5 previous errors
+
diff --git a/tests/ui/auxiliary/proc_macro_attr.rs b/tests/ui/auxiliary/proc_macro_attr.rs
index e6626d57a77..de670cdfc31 100644
--- a/tests/ui/auxiliary/proc_macro_attr.rs
+++ b/tests/ui/auxiliary/proc_macro_attr.rs
@@ -1,7 +1,8 @@
+// compile-flags: --emit=link
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
-#![feature(repr128, proc_macro_hygiene, proc_macro_quote)]
+#![feature(repr128, proc_macro_hygiene, proc_macro_quote, box_patterns)]
 #![allow(clippy::useless_conversion)]
 
 extern crate proc_macro;
@@ -11,7 +12,11 @@ extern crate syn;
 use proc_macro::TokenStream;
 use quote::{quote, quote_spanned};
 use syn::parse_macro_input;
-use syn::{parse_quote, ItemTrait, TraitItem};
+use syn::spanned::Spanned;
+use syn::token::Star;
+use syn::{
+    parse_quote, FnArg, ImplItem, ItemImpl, ItemTrait, Lifetime, Pat, PatIdent, PatType, Signature, TraitItem, Type,
+};
 
 #[proc_macro_attribute]
 pub fn fake_async_trait(_args: TokenStream, input: TokenStream) -> TokenStream {
@@ -35,3 +40,56 @@ pub fn fake_async_trait(_args: TokenStream, input: TokenStream) -> TokenStream {
     }
     TokenStream::from(quote!(#item))
 }
+
+#[proc_macro_attribute]
+pub fn rename_my_lifetimes(_args: TokenStream, input: TokenStream) -> TokenStream {
+    fn make_name(count: usize) -> String {
+        format!("'life{}", count)
+    }
+
+    fn mut_receiver_of(sig: &mut Signature) -> Option<&mut FnArg> {
+        let arg = sig.inputs.first_mut()?;
+        if let FnArg::Typed(PatType { pat, .. }) = arg {
+            if let Pat::Ident(PatIdent { ident, .. }) = &**pat {
+                if ident == "self" {
+                    return Some(arg);
+                }
+            }
+        }
+        None
+    }
+
+    let mut elided = 0;
+    let mut item = parse_macro_input!(input as ItemImpl);
+
+    // Look for methods having arbitrary self type taken by &mut ref
+    for inner in &mut item.items {
+        if let ImplItem::Method(method) = inner {
+            if let Some(FnArg::Typed(pat_type)) = mut_receiver_of(&mut method.sig) {
+                if let box Type::Reference(reference) = &mut pat_type.ty {
+                    // Target only unnamed lifetimes
+                    let name = match &reference.lifetime {
+                        Some(lt) if lt.ident == "_" => make_name(elided),
+                        None => make_name(elided),
+                        _ => continue,
+                    };
+                    elided += 1;
+
+                    // HACK: Syn uses `Span` from the proc_macro2 crate, and does not seem to reexport it.
+                    // In order to avoid adding the dependency, get a default span from a non-existent token.
+                    // A default span is needed to mark the code as coming from expansion.
+                    let span = Star::default().span();
+
+                    // Replace old lifetime with the named one
+                    let lifetime = Lifetime::new(&name, span);
+                    reference.lifetime = Some(parse_quote!(#lifetime));
+
+                    // Add lifetime to the generics of the method
+                    method.sig.generics.params.push(parse_quote!(#lifetime));
+                }
+            }
+        }
+    }
+
+    TokenStream::from(quote!(#item))
+}
diff --git a/tests/ui/auxiliary/proc_macro_derive.rs b/tests/ui/auxiliary/proc_macro_derive.rs
index 05ffb55f620..3df8be6c232 100644
--- a/tests/ui/auxiliary/proc_macro_derive.rs
+++ b/tests/ui/auxiliary/proc_macro_derive.rs
@@ -1,3 +1,4 @@
+// compile-flags: --emit=link
 // no-prefer-dynamic
 
 #![crate_type = "proc-macro"]
diff --git a/tests/ui/crashes/associated-constant-ice.rs b/tests/ui/crashes/associated-constant-ice.rs
index 4bb833795bb..948deba3ea6 100644
--- a/tests/ui/crashes/associated-constant-ice.rs
+++ b/tests/ui/crashes/associated-constant-ice.rs
@@ -1,5 +1,3 @@
-// run-pass
-
 /// Test for https://github.com/rust-lang/rust-clippy/issues/1698
 
 pub trait Trait {
diff --git a/tests/ui/crashes/auxiliary/proc_macro_crash.rs b/tests/ui/crashes/auxiliary/proc_macro_crash.rs
index 086548e58ed..619d11cefc4 100644
--- a/tests/ui/crashes/auxiliary/proc_macro_crash.rs
+++ b/tests/ui/crashes/auxiliary/proc_macro_crash.rs
@@ -1,3 +1,4 @@
+// compile-flags: --emit=link
 // no-prefer-dynamic
 // ^ compiletest by default builds all aux files as dylibs, but we don't want that for proc-macro
 // crates. If we don't set this, compiletest will override the `crate_type` attribute below and
diff --git a/tests/ui/crashes/cc_seme.rs b/tests/ui/crashes/cc_seme.rs
index c48c7e9e6c6..98588be9cf8 100644
--- a/tests/ui/crashes/cc_seme.rs
+++ b/tests/ui/crashes/cc_seme.rs
@@ -1,5 +1,3 @@
-// run-pass
-
 #[allow(dead_code)]
 
 /// Test for https://github.com/rust-lang/rust-clippy/issues/478
diff --git a/tests/ui/crashes/enum-glob-import-crate.rs b/tests/ui/crashes/enum-glob-import-crate.rs
index db1fa871afe..dca32aa3b56 100644
--- a/tests/ui/crashes/enum-glob-import-crate.rs
+++ b/tests/ui/crashes/enum-glob-import-crate.rs
@@ -1,5 +1,3 @@
-// run-pass
-
 #![deny(clippy::all)]
 #![allow(unused_imports)]
 
diff --git a/tests/ui/crashes/ice-1588.rs b/tests/ui/crashes/ice-1588.rs
index 15d0f705b36..b0a3d11bce4 100644
--- a/tests/ui/crashes/ice-1588.rs
+++ b/tests/ui/crashes/ice-1588.rs
@@ -1,5 +1,3 @@
-// run-pass
-
 #![allow(clippy::all)]
 
 /// Test for https://github.com/rust-lang/rust-clippy/issues/1588
diff --git a/tests/ui/crashes/ice-1782.rs b/tests/ui/crashes/ice-1782.rs
index 1ca6b6976b3..81af88962a6 100644
--- a/tests/ui/crashes/ice-1782.rs
+++ b/tests/ui/crashes/ice-1782.rs
@@ -1,5 +1,3 @@
-// run-pass
-
 #![allow(dead_code, unused_variables)]
 
 /// Should not trigger an ICE in `SpanlessEq` / `consts::constant`
diff --git a/tests/ui/crashes/ice-1969.rs b/tests/ui/crashes/ice-1969.rs
index 837ec9df31a..96a8fe6c24d 100644
--- a/tests/ui/crashes/ice-1969.rs
+++ b/tests/ui/crashes/ice-1969.rs
@@ -1,5 +1,3 @@
-// run-pass
-
 #![allow(clippy::all)]
 
 /// Test for https://github.com/rust-lang/rust-clippy/issues/1969
diff --git a/tests/ui/crashes/ice-2499.rs b/tests/ui/crashes/ice-2499.rs
index ffef1631775..45b3b1869dd 100644
--- a/tests/ui/crashes/ice-2499.rs
+++ b/tests/ui/crashes/ice-2499.rs
@@ -1,5 +1,3 @@
-// run-pass
-
 #![allow(dead_code, clippy::char_lit_as_u8, clippy::needless_bool)]
 
 /// Should not trigger an ICE in `SpanlessHash` / `consts::constant`
diff --git a/tests/ui/crashes/ice-2594.rs b/tests/ui/crashes/ice-2594.rs
index ac19f1976e9..3f3986b6fc6 100644
--- a/tests/ui/crashes/ice-2594.rs
+++ b/tests/ui/crashes/ice-2594.rs
@@ -1,5 +1,3 @@
-// run-pass
-
 #![allow(dead_code, unused_variables)]
 
 /// Should not trigger an ICE in `SpanlessHash` / `consts::constant`
diff --git a/tests/ui/crashes/ice-2727.rs b/tests/ui/crashes/ice-2727.rs
index d832c286033..56024abc8f5 100644
--- a/tests/ui/crashes/ice-2727.rs
+++ b/tests/ui/crashes/ice-2727.rs
@@ -1,5 +1,3 @@
-// run-pass
-
 /// Test for https://github.com/rust-lang/rust-clippy/issues/2727
 
 pub fn f(new: fn()) {
diff --git a/tests/ui/crashes/ice-2760.rs b/tests/ui/crashes/ice-2760.rs
index 9e5e299c336..f1a229f3f4f 100644
--- a/tests/ui/crashes/ice-2760.rs
+++ b/tests/ui/crashes/ice-2760.rs
@@ -1,5 +1,3 @@
-// run-pass
-
 #![allow(
     unused_variables,
     clippy::blacklisted_name,
diff --git a/tests/ui/crashes/ice-2774.rs b/tests/ui/crashes/ice-2774.rs
index 47f8e3b18ee..d44b0fae820 100644
--- a/tests/ui/crashes/ice-2774.rs
+++ b/tests/ui/crashes/ice-2774.rs
@@ -1,5 +1,3 @@
-// run-pass
-
 use std::collections::HashSet;
 
 // See rust-lang/rust-clippy#2774.
diff --git a/tests/ui/crashes/ice-2774.stderr b/tests/ui/crashes/ice-2774.stderr
new file mode 100644
index 00000000000..0c2d48f938f
--- /dev/null
+++ b/tests/ui/crashes/ice-2774.stderr
@@ -0,0 +1,10 @@
+error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
+  --> $DIR/ice-2774.rs:15:1
+   |
+LL | pub fn add_barfoos_to_foos<'a>(bars: &HashSet<&'a Bar>) {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `-D clippy::needless-lifetimes` implied by `-D warnings`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/crashes/ice-2862.rs b/tests/ui/crashes/ice-2862.rs
index 47324ce1831..8326e3663b0 100644
--- a/tests/ui/crashes/ice-2862.rs
+++ b/tests/ui/crashes/ice-2862.rs
@@ -1,5 +1,3 @@
-// run-pass
-
 /// Test for https://github.com/rust-lang/rust-clippy/issues/2862
 
 pub trait FooMap {
diff --git a/tests/ui/crashes/ice-2865.rs b/tests/ui/crashes/ice-2865.rs
index c4f6c0fed68..6b1ceb50569 100644
--- a/tests/ui/crashes/ice-2865.rs
+++ b/tests/ui/crashes/ice-2865.rs
@@ -1,5 +1,3 @@
-// run-pass
-
 #[allow(dead_code)]
 
 /// Test for https://github.com/rust-lang/rust-clippy/issues/2865
diff --git a/tests/ui/crashes/ice-3151.rs b/tests/ui/crashes/ice-3151.rs
index ffad2d06b56..fef4d7db84d 100644
--- a/tests/ui/crashes/ice-3151.rs
+++ b/tests/ui/crashes/ice-3151.rs
@@ -1,5 +1,3 @@
-// run-pass
-
 /// Test for https://github.com/rust-lang/rust-clippy/issues/2865
 
 #[derive(Clone)]
diff --git a/tests/ui/crashes/ice-3462.rs b/tests/ui/crashes/ice-3462.rs
index 95c7dff9be3..7d62e315da2 100644
--- a/tests/ui/crashes/ice-3462.rs
+++ b/tests/ui/crashes/ice-3462.rs
@@ -1,5 +1,3 @@
-// run-pass
-
 #![warn(clippy::all)]
 #![allow(clippy::blacklisted_name)]
 #![allow(unused)]
diff --git a/tests/ui/crashes/ice-3741.rs b/tests/ui/crashes/ice-3741.rs
index a548415da62..1253ddcfaeb 100644
--- a/tests/ui/crashes/ice-3741.rs
+++ b/tests/ui/crashes/ice-3741.rs
@@ -1,5 +1,4 @@
 // aux-build:proc_macro_crash.rs
-// run-pass
 
 #![warn(clippy::suspicious_else_formatting)]
 
diff --git a/tests/ui/crashes/ice-3747.rs b/tests/ui/crashes/ice-3747.rs
index d0b44ebafee..cdf018cbc88 100644
--- a/tests/ui/crashes/ice-3747.rs
+++ b/tests/ui/crashes/ice-3747.rs
@@ -1,5 +1,3 @@
-// run-pass
-
 /// Test for https://github.com/rust-lang/rust-clippy/issues/3747
 
 macro_rules! a {
diff --git a/tests/ui/crashes/ice-4727.rs b/tests/ui/crashes/ice-4727.rs
index cdb59caec67..2a4bc83f58a 100644
--- a/tests/ui/crashes/ice-4727.rs
+++ b/tests/ui/crashes/ice-4727.rs
@@ -1,5 +1,3 @@
-// run-pass
-
 #![warn(clippy::use_self)]
 
 #[path = "auxiliary/ice-4727-aux.rs"]
diff --git a/tests/ui/crashes/ice-4760.rs b/tests/ui/crashes/ice-4760.rs
index ead67d5ed1b..08b06961760 100644
--- a/tests/ui/crashes/ice-4760.rs
+++ b/tests/ui/crashes/ice-4760.rs
@@ -1,4 +1,3 @@
-// run-pass
 const COUNT: usize = 2;
 struct Thing;
 trait Dummy {}
diff --git a/tests/ui/crashes/ice-700.rs b/tests/ui/crashes/ice-700.rs
index b06df83d51a..0cbceedbd6b 100644
--- a/tests/ui/crashes/ice-700.rs
+++ b/tests/ui/crashes/ice-700.rs
@@ -1,5 +1,3 @@
-// run-pass
-
 #![deny(clippy::all)]
 
 /// Test for https://github.com/rust-lang/rust-clippy/issues/700
diff --git a/tests/ui/crashes/ice_exacte_size.rs b/tests/ui/crashes/ice_exacte_size.rs
index e02eb28ab86..30e4b11ec0b 100644
--- a/tests/ui/crashes/ice_exacte_size.rs
+++ b/tests/ui/crashes/ice_exacte_size.rs
@@ -1,5 +1,3 @@
-// run-pass
-
 #![deny(clippy::all)]
 
 /// Test for https://github.com/rust-lang/rust-clippy/issues/1336
diff --git a/tests/ui/crashes/if_same_then_else.rs b/tests/ui/crashes/if_same_then_else.rs
index 4ef992b05e7..2f913292995 100644
--- a/tests/ui/crashes/if_same_then_else.rs
+++ b/tests/ui/crashes/if_same_then_else.rs
@@ -1,5 +1,3 @@
-// run-pass
-
 #![allow(clippy::comparison_chain)]
 #![deny(clippy::if_same_then_else)]
 
diff --git a/tests/ui/crashes/issue-825.rs b/tests/ui/crashes/issue-825.rs
index 3d4a88ab3c4..05696e3d7d5 100644
--- a/tests/ui/crashes/issue-825.rs
+++ b/tests/ui/crashes/issue-825.rs
@@ -1,5 +1,3 @@
-// run-pass
-
 #![allow(warnings)]
 
 /// Test for https://github.com/rust-lang/rust-clippy/issues/825
diff --git a/tests/ui/crashes/issues_loop_mut_cond.rs b/tests/ui/crashes/issues_loop_mut_cond.rs
index c4acd5cda1b..bb238c81ebc 100644
--- a/tests/ui/crashes/issues_loop_mut_cond.rs
+++ b/tests/ui/crashes/issues_loop_mut_cond.rs
@@ -1,5 +1,3 @@
-// run-pass
-
 #![allow(dead_code)]
 
 /// Issue: https://github.com/rust-lang/rust-clippy/issues/2596
diff --git a/tests/ui/crashes/match_same_arms_const.rs b/tests/ui/crashes/match_same_arms_const.rs
index 848f0ea52ca..94c939665e6 100644
--- a/tests/ui/crashes/match_same_arms_const.rs
+++ b/tests/ui/crashes/match_same_arms_const.rs
@@ -1,5 +1,3 @@
-// run-pass
-
 #![deny(clippy::match_same_arms)]
 
 /// Test for https://github.com/rust-lang/rust-clippy/issues/2427
diff --git a/tests/ui/crashes/mut_mut_macro.rs b/tests/ui/crashes/mut_mut_macro.rs
index d8fbaa54146..a238e7896fc 100644
--- a/tests/ui/crashes/mut_mut_macro.rs
+++ b/tests/ui/crashes/mut_mut_macro.rs
@@ -1,5 +1,3 @@
-// run-pass
-
 #![deny(clippy::mut_mut, clippy::zero_ptr, clippy::cmp_nan)]
 #![allow(dead_code)]
 
diff --git a/tests/ui/crashes/needless_borrow_fp.rs b/tests/ui/crashes/needless_borrow_fp.rs
index 48507efe1e9..4f61c76828d 100644
--- a/tests/ui/crashes/needless_borrow_fp.rs
+++ b/tests/ui/crashes/needless_borrow_fp.rs
@@ -1,5 +1,3 @@
-// run-pass
-
 #[deny(clippy::all)]
 #[derive(Debug)]
 pub enum Error {
diff --git a/tests/ui/crashes/needless_lifetimes_impl_trait.rs b/tests/ui/crashes/needless_lifetimes_impl_trait.rs
index bd1fa4a0b1e..676564b2445 100644
--- a/tests/ui/crashes/needless_lifetimes_impl_trait.rs
+++ b/tests/ui/crashes/needless_lifetimes_impl_trait.rs
@@ -1,5 +1,3 @@
-// run-pass
-
 #![deny(clippy::needless_lifetimes)]
 #![allow(dead_code)]
 
diff --git a/tests/ui/crashes/needless_lifetimes_impl_trait.stderr b/tests/ui/crashes/needless_lifetimes_impl_trait.stderr
new file mode 100644
index 00000000000..d68bbe78802
--- /dev/null
+++ b/tests/ui/crashes/needless_lifetimes_impl_trait.stderr
@@ -0,0 +1,14 @@
+error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
+  --> $DIR/needless_lifetimes_impl_trait.rs:15:5
+   |
+LL |     fn baz<'a>(&'a self) -> impl Foo + 'a {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/needless_lifetimes_impl_trait.rs:1:9
+   |
+LL | #![deny(clippy::needless_lifetimes)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/crashes/procedural_macro.rs b/tests/ui/crashes/procedural_macro.rs
index f79d9ab6460..c7468493380 100644
--- a/tests/ui/crashes/procedural_macro.rs
+++ b/tests/ui/crashes/procedural_macro.rs
@@ -1,5 +1,3 @@
-// run-pass
-
 #[macro_use]
 extern crate clippy_mini_macro_test;
 
diff --git a/tests/ui/crashes/regressions.rs b/tests/ui/crashes/regressions.rs
index 3d5063d1a3a..a41bcb33b44 100644
--- a/tests/ui/crashes/regressions.rs
+++ b/tests/ui/crashes/regressions.rs
@@ -1,5 +1,3 @@
-// run-pass
-
 #![allow(clippy::blacklisted_name)]
 
 pub fn foo(bar: *const u8) {
diff --git a/tests/ui/crashes/returns.rs b/tests/ui/crashes/returns.rs
index f2153efc388..8021ed4607d 100644
--- a/tests/ui/crashes/returns.rs
+++ b/tests/ui/crashes/returns.rs
@@ -1,5 +1,3 @@
-// run-pass
-
 /// Test for https://github.com/rust-lang/rust-clippy/issues/1346
 
 #[deny(warnings)]
diff --git a/tests/ui/crashes/single-match-else.rs b/tests/ui/crashes/single-match-else.rs
index 3a4bbe310cc..1ba7ac08213 100644
--- a/tests/ui/crashes/single-match-else.rs
+++ b/tests/ui/crashes/single-match-else.rs
@@ -1,5 +1,3 @@
-// run-pass
-
 #![warn(clippy::single_match_else)]
 
 //! Test for https://github.com/rust-lang/rust-clippy/issues/1588
diff --git a/tests/ui/crashes/trivial_bounds.rs b/tests/ui/crashes/trivial_bounds.rs
index 2bb95c18a39..60105a8213f 100644
--- a/tests/ui/crashes/trivial_bounds.rs
+++ b/tests/ui/crashes/trivial_bounds.rs
@@ -1,5 +1,3 @@
-// run-pass
-
 #![feature(trivial_bounds)]
 #![allow(unused, trivial_bounds)]
 
diff --git a/tests/ui/crashes/used_underscore_binding_macro.rs b/tests/ui/crashes/used_underscore_binding_macro.rs
index 265017c51d9..6d2124c12fe 100644
--- a/tests/ui/crashes/used_underscore_binding_macro.rs
+++ b/tests/ui/crashes/used_underscore_binding_macro.rs
@@ -1,5 +1,3 @@
-// run-pass
-
 #![allow(clippy::useless_attribute)] //issue #2910
 
 #[macro_use]
diff --git a/tests/ui/explicit_counter_loop.rs b/tests/ui/explicit_counter_loop.rs
index aa6ef162fe4..81d8221bd13 100644
--- a/tests/ui/explicit_counter_loop.rs
+++ b/tests/ui/explicit_counter_loop.rs
@@ -38,54 +38,54 @@ mod issue_1219 {
         let text = "banana";
         let mut count = 0;
         for ch in text.chars() {
+            println!("{}", count);
             if ch == 'a' {
                 continue;
             }
             count += 1;
-            println!("{}", count);
         }
 
         // should not trigger the lint because the count is conditional
         let text = "banana";
         let mut count = 0;
         for ch in text.chars() {
+            println!("{}", count);
             if ch == 'a' {
                 count += 1;
             }
-            println!("{}", count);
         }
 
         // should trigger the lint because the count is not conditional
         let text = "banana";
         let mut count = 0;
         for ch in text.chars() {
+            println!("{}", count);
             count += 1;
             if ch == 'a' {
                 continue;
             }
-            println!("{}", count);
         }
 
         // should trigger the lint because the count is not conditional
         let text = "banana";
         let mut count = 0;
         for ch in text.chars() {
+            println!("{}", count);
             count += 1;
             for i in 0..2 {
                 let _ = 123;
             }
-            println!("{}", count);
         }
 
         // should not trigger the lint because the count is incremented multiple times
         let text = "banana";
         let mut count = 0;
         for ch in text.chars() {
+            println!("{}", count);
             count += 1;
             for i in 0..2 {
                 count += 1;
             }
-            println!("{}", count);
         }
     }
 }
@@ -96,30 +96,30 @@ mod issue_3308 {
         let mut skips = 0;
         let erasures = vec![];
         for i in 0..10 {
+            println!("{}", skips);
             while erasures.contains(&(i + skips)) {
                 skips += 1;
             }
-            println!("{}", skips);
         }
 
         // should not trigger the lint because the count is incremented multiple times
         let mut skips = 0;
         for i in 0..10 {
+            println!("{}", skips);
             let mut j = 0;
             while j < 5 {
                 skips += 1;
                 j += 1;
             }
-            println!("{}", skips);
         }
 
         // should not trigger the lint because the count is incremented multiple times
         let mut skips = 0;
         for i in 0..10 {
+            println!("{}", skips);
             for j in 0..5 {
                 skips += 1;
             }
-            println!("{}", skips);
         }
     }
 }
@@ -145,3 +145,16 @@ mod issue_4732 {
         let _closure = || println!("index: {}", index);
     }
 }
+
+mod issue_4677 {
+    pub fn test() {
+        let slice = &[1, 2, 3];
+
+        // should not trigger the lint because the count is used after incremented
+        let mut count = 0;
+        for _i in slice {
+            count += 1;
+            println!("{}", count);
+        }
+    }
+}
diff --git a/tests/ui/inconsistent_digit_grouping.fixed b/tests/ui/inconsistent_digit_grouping.fixed
index b75f10917df..dd683e7f746 100644
--- a/tests/ui/inconsistent_digit_grouping.fixed
+++ b/tests/ui/inconsistent_digit_grouping.fixed
@@ -40,4 +40,8 @@ fn main() {
     // Ignore literals in macros
     let _ = mac1!();
     let _ = mac2!();
+
+    // Issue #6096
+    // Allow separating exponent with '_'
+    let _ = 1.025_011_10_E0;
 }
diff --git a/tests/ui/inconsistent_digit_grouping.rs b/tests/ui/inconsistent_digit_grouping.rs
index 79ce38be19b..d5d27c853c2 100644
--- a/tests/ui/inconsistent_digit_grouping.rs
+++ b/tests/ui/inconsistent_digit_grouping.rs
@@ -40,4 +40,8 @@ fn main() {
     // Ignore literals in macros
     let _ = mac1!();
     let _ = mac2!();
+
+    // Issue #6096
+    // Allow separating exponent with '_'
+    let _ = 1.025_011_10_E0;
 }
diff --git a/tests/ui/needless_arbitrary_self_type_unfixable.rs b/tests/ui/needless_arbitrary_self_type_unfixable.rs
new file mode 100644
index 00000000000..a39d96109f1
--- /dev/null
+++ b/tests/ui/needless_arbitrary_self_type_unfixable.rs
@@ -0,0 +1,45 @@
+// aux-build:proc_macro_attr.rs
+
+#![warn(clippy::needless_arbitrary_self_type)]
+
+#[macro_use]
+extern crate proc_macro_attr;
+
+mod issue_6089 {
+    // Check that we don't lint if the `self` parameter comes from expansion
+
+    macro_rules! test_from_expansion {
+        () => {
+            trait T1 {
+                fn test(self: &Self);
+            }
+
+            struct S1 {}
+
+            impl T1 for S1 {
+                fn test(self: &Self) {}
+            }
+        };
+    }
+
+    test_from_expansion!();
+
+    // If only the lifetime name comes from expansion we will lint, but the suggestion will have
+    // placeholders and will not be applied automatically, as we can't reliably know the original name.
+    // This specific case happened with async_trait.
+
+    trait T2 {
+        fn call_with_mut_self(&mut self);
+    }
+
+    struct S2 {}
+
+    // The method's signature will be expanded to:
+    //  fn call_with_mut_self<'life0>(self: &'life0 mut Self) {}
+    #[rename_my_lifetimes]
+    impl T2 for S2 {
+        fn call_with_mut_self(self: &mut Self) {}
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/needless_arbitrary_self_type_unfixable.stderr b/tests/ui/needless_arbitrary_self_type_unfixable.stderr
new file mode 100644
index 00000000000..44a0e6ddeac
--- /dev/null
+++ b/tests/ui/needless_arbitrary_self_type_unfixable.stderr
@@ -0,0 +1,10 @@
+error: the type of the `self` parameter does not need to be arbitrary
+  --> $DIR/needless_arbitrary_self_type_unfixable.rs:41:31
+   |
+LL |         fn call_with_mut_self(self: &mut Self) {}
+   |                               ^^^^^^^^^^^^^^^ help: consider to change this parameter to: `&'_ mut self`
+   |
+   = note: `-D clippy::needless-arbitrary-self-type` implied by `-D warnings`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/needless_lifetimes.rs b/tests/ui/needless_lifetimes.rs
index 913cd004f19..d482d466e44 100644
--- a/tests/ui/needless_lifetimes.rs
+++ b/tests/ui/needless_lifetimes.rs
@@ -259,4 +259,102 @@ mod issue4291 {
     }
 }
 
+mod issue2944 {
+    trait Foo {}
+    struct Bar {}
+    struct Baz<'a> {
+        bar: &'a Bar,
+    }
+
+    impl<'a> Foo for Baz<'a> {}
+    impl Bar {
+        fn baz<'a>(&'a self) -> impl Foo + 'a {
+            Baz { bar: self }
+        }
+    }
+}
+
+mod nested_elision_sites {
+    // issue #issue2944
+
+    // closure trait bounds subject to nested elision
+    // don't lint because they refer to outer lifetimes
+    fn trait_fn<'a>(i: &'a i32) -> impl Fn() -> &'a i32 {
+        move || i
+    }
+    fn trait_fn_mut<'a>(i: &'a i32) -> impl FnMut() -> &'a i32 {
+        move || i
+    }
+    fn trait_fn_once<'a>(i: &'a i32) -> impl FnOnce() -> &'a i32 {
+        move || i
+    }
+
+    // don't lint
+    fn impl_trait_in_input_position<'a>(f: impl Fn() -> &'a i32) -> &'a i32 {
+        f()
+    }
+    fn impl_trait_in_output_position<'a>(i: &'a i32) -> impl Fn() -> &'a i32 {
+        move || i
+    }
+    // lint
+    fn impl_trait_elidable_nested_named_lifetimes<'a>(i: &'a i32, f: impl for<'b> Fn(&'b i32) -> &'b i32) -> &'a i32 {
+        f(i)
+    }
+    fn impl_trait_elidable_nested_anonymous_lifetimes<'a>(i: &'a i32, f: impl Fn(&i32) -> &i32) -> &'a i32 {
+        f(i)
+    }
+
+    // don't lint
+    fn generics_not_elidable<'a, T: Fn() -> &'a i32>(f: T) -> &'a i32 {
+        f()
+    }
+    // lint
+    fn generics_elidable<'a, T: Fn(&i32) -> &i32>(i: &'a i32, f: T) -> &'a i32 {
+        f(i)
+    }
+
+    // don't lint
+    fn where_clause_not_elidable<'a, T>(f: T) -> &'a i32
+    where
+        T: Fn() -> &'a i32,
+    {
+        f()
+    }
+    // lint
+    fn where_clause_elidadable<'a, T>(i: &'a i32, f: T) -> &'a i32
+    where
+        T: Fn(&i32) -> &i32,
+    {
+        f(i)
+    }
+
+    // don't lint
+    fn pointer_fn_in_input_position<'a>(f: fn(&'a i32) -> &'a i32, i: &'a i32) -> &'a i32 {
+        f(i)
+    }
+    fn pointer_fn_in_output_position<'a>(_: &'a i32) -> fn(&'a i32) -> &'a i32 {
+        |i| i
+    }
+    // lint
+    fn pointer_fn_elidable<'a>(i: &'a i32, f: fn(&i32) -> &i32) -> &'a i32 {
+        f(i)
+    }
+
+    // don't lint
+    fn nested_fn_pointer_1<'a>(_: &'a i32) -> fn(fn(&'a i32) -> &'a i32) -> i32 {
+        |f| 42
+    }
+    fn nested_fn_pointer_2<'a>(_: &'a i32) -> impl Fn(fn(&'a i32)) {
+        |f| ()
+    }
+
+    // lint
+    fn nested_fn_pointer_3<'a>(_: &'a i32) -> fn(fn(&i32) -> &i32) -> i32 {
+        |f| 42
+    }
+    fn nested_fn_pointer_4<'a>(_: &'a i32) -> impl Fn(fn(&i32)) {
+        |f| ()
+    }
+}
+
 fn main() {}
diff --git a/tests/ui/needless_lifetimes.stderr b/tests/ui/needless_lifetimes.stderr
index d3a360ed8b5..c8a2e8b81c0 100644
--- a/tests/ui/needless_lifetimes.stderr
+++ b/tests/ui/needless_lifetimes.stderr
@@ -102,5 +102,53 @@ error: explicit lifetimes given in parameter types where they could be elided (o
 LL |         fn needless_lt<'a>(_x: &'a u8) {}
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 17 previous errors
+error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
+  --> $DIR/needless_lifetimes.rs:271:9
+   |
+LL |         fn baz<'a>(&'a self) -> impl Foo + 'a {
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
+  --> $DIR/needless_lifetimes.rs:300:5
+   |
+LL |     fn impl_trait_elidable_nested_named_lifetimes<'a>(i: &'a i32, f: impl for<'b> Fn(&'b i32) -> &'b i32) -> &'a i32 {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
+  --> $DIR/needless_lifetimes.rs:303:5
+   |
+LL |     fn impl_trait_elidable_nested_anonymous_lifetimes<'a>(i: &'a i32, f: impl Fn(&i32) -> &i32) -> &'a i32 {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
+  --> $DIR/needless_lifetimes.rs:312:5
+   |
+LL |     fn generics_elidable<'a, T: Fn(&i32) -> &i32>(i: &'a i32, f: T) -> &'a i32 {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
+  --> $DIR/needless_lifetimes.rs:324:5
+   |
+LL |     fn where_clause_elidadable<'a, T>(i: &'a i32, f: T) -> &'a i32
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
+  --> $DIR/needless_lifetimes.rs:339:5
+   |
+LL |     fn pointer_fn_elidable<'a>(i: &'a i32, f: fn(&i32) -> &i32) -> &'a i32 {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
+  --> $DIR/needless_lifetimes.rs:352:5
+   |
+LL |     fn nested_fn_pointer_3<'a>(_: &'a i32) -> fn(fn(&i32) -> &i32) -> i32 {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
+  --> $DIR/needless_lifetimes.rs:355:5
+   |
+LL |     fn nested_fn_pointer_4<'a>(_: &'a i32) -> impl Fn(fn(&i32)) {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 25 previous errors
 
diff --git a/tests/ui/needless_range_loop2.rs b/tests/ui/needless_range_loop2.rs
index a82b1159161..7633316e0f8 100644
--- a/tests/ui/needless_range_loop2.rs
+++ b/tests/ui/needless_range_loop2.rs
@@ -82,6 +82,20 @@ fn main() {
     for i in 1..3 {
         println!("{}", arr[i]);
     }
+
+    // Fix #5945
+    let mut vec = vec![1, 2, 3, 4];
+    for i in 0..vec.len() - 1 {
+        vec[i] += 1;
+    }
+    let mut vec = vec![1, 2, 3, 4];
+    for i in vec.len() - 3..vec.len() {
+        vec[i] += 1;
+    }
+    let mut vec = vec![1, 2, 3, 4];
+    for i in vec.len() - 3..vec.len() - 1 {
+        vec[i] += 1;
+    }
 }
 
 mod issue2277 {
diff --git a/tests/ui/or_fun_call.fixed b/tests/ui/or_fun_call.fixed
index 5fb568672d3..2045ffdb5f0 100644
--- a/tests/ui/or_fun_call.fixed
+++ b/tests/ui/or_fun_call.fixed
@@ -58,6 +58,12 @@ 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());
 
@@ -110,23 +116,4 @@ fn f() -> Option<()> {
     Some(())
 }
 
-// Issue 5886 - const fn (with no arguments)
-pub fn skip_const_fn_with_no_args() {
-    const fn foo() -> Option<i32> {
-        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 737b0f7e55b..522f31b72d0 100644
--- a/tests/ui/or_fun_call.rs
+++ b/tests/ui/or_fun_call.rs
@@ -58,6 +58,12 @@ 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());
 
@@ -110,23 +116,4 @@ fn f() -> Option<()> {
     Some(())
 }
 
-// Issue 5886 - const fn (with no arguments)
-pub fn skip_const_fn_with_no_args() {
-    const fn foo() -> Option<i32> {
-        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 b8a436993f3..bc5978b538f 100644
--- a/tests/ui/or_fun_call.stderr
+++ b/tests/ui/or_fun_call.stderr
@@ -60,23 +60,35 @@ 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:62:21
+  --> $DIR/or_fun_call.rs:68: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:87:35
+  --> $DIR/or_fun_call.rs:93: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:91:10
+  --> $DIR/or_fun_call.rs:97: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 13 previous errors
+error: aborting due to 15 previous errors
 
diff --git a/tests/ui/print_stdout_build_script.rs b/tests/ui/print_stdout_build_script.rs
new file mode 100644
index 00000000000..997ebef8a69
--- /dev/null
+++ b/tests/ui/print_stdout_build_script.rs
@@ -0,0 +1,12 @@
+// compile-flags: --crate-name=build_script_build
+
+#![warn(clippy::print_stdout)]
+
+fn main() {
+    // Fix #6041
+    //
+    // The `print_stdout` lint shouldn't emit in `build.rs`
+    // as these methods are used for the build script.
+    println!("Hello");
+    print!("Hello");
+}
diff --git a/tests/ui/temporary_assignment.rs b/tests/ui/temporary_assignment.rs
index b4a931043b0..ac4c1bc6597 100644
--- a/tests/ui/temporary_assignment.rs
+++ b/tests/ui/temporary_assignment.rs
@@ -1,5 +1,4 @@
 #![warn(clippy::temporary_assignment)]
-#![allow(const_item_mutation)]
 
 use std::ops::{Deref, DerefMut};
 
diff --git a/tests/ui/temporary_assignment.stderr b/tests/ui/temporary_assignment.stderr
index 4cc32c79f05..7d79901a28d 100644
--- a/tests/ui/temporary_assignment.stderr
+++ b/tests/ui/temporary_assignment.stderr
@@ -1,5 +1,5 @@
 error: assignment to temporary
-  --> $DIR/temporary_assignment.rs:48:5
+  --> $DIR/temporary_assignment.rs:47:5
    |
 LL |     Struct { field: 0 }.field = 1;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -7,7 +7,7 @@ LL |     Struct { field: 0 }.field = 1;
    = note: `-D clippy::temporary-assignment` implied by `-D warnings`
 
 error: assignment to temporary
-  --> $DIR/temporary_assignment.rs:49:5
+  --> $DIR/temporary_assignment.rs:48:5
    |
 LL | /     MultiStruct {
 LL | |         structure: Struct { field: 0 },
@@ -17,13 +17,13 @@ LL | |     .field = 1;
    | |______________^
 
 error: assignment to temporary
-  --> $DIR/temporary_assignment.rs:54:5
+  --> $DIR/temporary_assignment.rs:53:5
    |
 LL |     ArrayStruct { array: [0] }.array[0] = 1;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: assignment to temporary
-  --> $DIR/temporary_assignment.rs:55:5
+  --> $DIR/temporary_assignment.rs:54:5
    |
 LL |     (0, 0).0 = 1;
    |     ^^^^^^^^^^^^
diff --git a/tests/ui/unicode.rs b/tests/ui/unicode.rs
index 27db9594f3b..1f596c312fe 100644
--- a/tests/ui/unicode.rs
+++ b/tests/ui/unicode.rs
@@ -1,7 +1,11 @@
-#[warn(clippy::zero_width_space)]
+#[warn(clippy::invisible_characters)]
 fn zero() {
     print!("Here >​< is a ZWS, and ​another");
     print!("This\u{200B}is\u{200B}fine");
+    print!("Here >­< is a SHY, and ­another");
+    print!("This\u{ad}is\u{ad}fine");
+    print!("Here >⁠< is a WJ, and ⁠another");
+    print!("This\u{2060}is\u{2060}fine");
 }
 
 #[warn(clippy::unicode_not_nfc)]
diff --git a/tests/ui/unicode.stderr b/tests/ui/unicode.stderr
index 4575a132e5b..3fca463c620 100644
--- a/tests/ui/unicode.stderr
+++ b/tests/ui/unicode.stderr
@@ -1,13 +1,25 @@
-error: zero-width space detected
+error: invisible character detected
   --> $DIR/unicode.rs:3:12
    |
 LL |     print!("Here >​< is a ZWS, and ​another");
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider replacing the string with: `"Here >/u{200B}< is a ZWS, and /u{200B}another"`
    |
-   = note: `-D clippy::zero-width-space` implied by `-D warnings`
+   = note: `-D clippy::invisible-characters` implied by `-D warnings`
+
+error: invisible character detected
+  --> $DIR/unicode.rs:5:12
+   |
+LL |     print!("Here >­< is a SHY, and ­another");
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider replacing the string with: `"Here >/u{AD}< is a SHY, and /u{AD}another"`
+
+error: invisible character detected
+  --> $DIR/unicode.rs:7:12
+   |
+LL |     print!("Here >⁠< is a WJ, and ⁠another");
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider replacing the string with: `"Here >/u{2060}< is a WJ, and /u{2060}another"`
 
 error: non-NFC Unicode sequence detected
-  --> $DIR/unicode.rs:9:12
+  --> $DIR/unicode.rs:13:12
    |
 LL |     print!("̀àh?");
    |            ^^^^^ help: consider replacing the string with: `"̀àh?"`
@@ -15,12 +27,12 @@ LL |     print!("̀àh?");
    = note: `-D clippy::unicode-not-nfc` implied by `-D warnings`
 
 error: literal non-ASCII character detected
-  --> $DIR/unicode.rs:15:12
+  --> $DIR/unicode.rs:19:12
    |
 LL |     print!("Üben!");
    |            ^^^^^^^ help: consider replacing the string with: `"/u{dc}ben!"`
    |
    = note: `-D clippy::non-ascii-literal` implied by `-D warnings`
 
-error: aborting due to 3 previous errors
+error: aborting due to 5 previous errors
 
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 -- "$@"