about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-05-05 13:12:09 +0000
committerbors <bors@rust-lang.org>2022-05-05 13:12:09 +0000
commit7c21f91b15b7604f818565646b686d90f99d1baf (patch)
treef99733e7e345d24567effd0df3f50a75051bf64c
parentc7a705a842fc30c4725b003c1b8b3443f2d0c07d (diff)
parent006282964f1e741a58c72d8e12f872bf5c227af9 (diff)
downloadrust-7c21f91b15b7604f818565646b686d90f99d1baf.tar.gz
rust-7c21f91b15b7604f818565646b686d90f99d1baf.zip
Auto merge of #8788 - flip1995:rustup, r=xFrednet,flip1995
Rustup

r? `@ghost`

changelog: move trait_duplication_in_bounds and type_repetition_in_bounds to nursery temporarily. This could already be reverted before the release. Check the Clippy in the Rust repo beta branch when writing this changelog.
-rw-r--r--clippy_dev/Cargo.toml2
-rw-r--r--clippy_lints/src/attrs.rs6
-rw-r--r--clippy_lints/src/case_sensitive_file_extension_comparisons.rs5
-rw-r--r--clippy_lints/src/cognitive_complexity.rs2
-rw-r--r--clippy_lints/src/doc.rs4
-rw-r--r--clippy_lints/src/enum_variants.rs2
-rw-r--r--clippy_lints/src/exhaustive_items.rs5
-rw-r--r--clippy_lints/src/functions/must_use.rs9
-rw-r--r--clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs4
-rw-r--r--clippy_lints/src/functions/result_unit_err.rs2
-rw-r--r--clippy_lints/src/functions/too_many_arguments.rs3
-rw-r--r--clippy_lints/src/implicit_hasher.rs4
-rw-r--r--clippy_lints/src/inherent_impl.rs2
-rw-r--r--clippy_lints/src/lib.register_nursery.rs2
-rw-r--r--clippy_lints/src/lib.register_pedantic.rs2
-rw-r--r--clippy_lints/src/lifetimes.rs71
-rw-r--r--clippy_lints/src/loops/needless_range_loop.rs4
-rw-r--r--clippy_lints/src/loops/never_loop.rs10
-rw-r--r--clippy_lints/src/manual_non_exhaustive.rs5
-rw-r--r--clippy_lints/src/matches/overlapping_arms.rs2
-rw-r--r--clippy_lints/src/matches/redundant_pattern_match.rs2
-rw-r--r--clippy_lints/src/methods/bind_instead_of_map.rs8
-rw-r--r--clippy_lints/src/methods/chars_cmp.rs2
-rw-r--r--clippy_lints/src/methods/option_map_or_none.rs2
-rw-r--r--clippy_lints/src/missing_doc.rs6
-rw-r--r--clippy_lints/src/missing_inline.rs2
-rw-r--r--clippy_lints/src/needless_pass_by_value.rs6
-rw-r--r--clippy_lints/src/neg_multiply.rs2
-rw-r--r--clippy_lints/src/new_without_default.rs4
-rw-r--r--clippy_lints/src/partialeq_ne_impl.rs2
-rw-r--r--clippy_lints/src/pass_by_ref_or_value.rs2
-rw-r--r--clippy_lints/src/redundant_pub_crate.rs10
-rw-r--r--clippy_lints/src/return_self_not_must_use.rs2
-rw-r--r--clippy_lints/src/same_name_method.rs197
-rw-r--r--clippy_lints/src/serde_api.rs2
-rw-r--r--clippy_lints/src/shadow.rs4
-rw-r--r--clippy_lints/src/trait_bounds.rs40
-rw-r--r--clippy_lints/src/types/borrowed_box.rs4
-rw-r--r--clippy_lints/src/undocumented_unsafe_blocks.rs6
-rw-r--r--clippy_lints/src/unit_types/let_unit_value.rs2
-rw-r--r--clippy_lints/src/unused_async.rs2
-rw-r--r--clippy_lints/src/wildcard_imports.rs4
-rw-r--r--clippy_lints/src/write.rs5
-rw-r--r--clippy_utils/src/ast_utils.rs3
-rw-r--r--clippy_utils/src/consts.rs4
-rw-r--r--clippy_utils/src/hir_utils.rs6
-rw-r--r--clippy_utils/src/lib.rs4
-rw-r--r--clippy_utils/src/paths.rs2
-rw-r--r--clippy_utils/src/qualify_min_const_fn.rs4
-rw-r--r--clippy_utils/src/sugg.rs1
-rw-r--r--rust-toolchain2
-rw-r--r--src/driver.rs2
-rw-r--r--tests/ui/crashes/ice-96721.rs10
-rw-r--r--tests/ui/crashes/ice-96721.stderr8
-rw-r--r--tests/ui/extra_unused_lifetimes.stderr8
-rw-r--r--tests/ui/needless_lifetimes.stderr8
-rw-r--r--tests/ui/same_name_method.stderr26
-rw-r--r--tests/ui/trait_duplication_in_bounds.rs3
-rw-r--r--tests/ui/trait_duplication_in_bounds.stderr10
-rw-r--r--tests/ui/type_repetition_in_bounds.rs3
-rw-r--r--tests/ui/type_repetition_in_bounds.stderr10
-rw-r--r--tests/ui/unused_unit.stderr16
62 files changed, 316 insertions, 276 deletions
diff --git a/clippy_dev/Cargo.toml b/clippy_dev/Cargo.toml
index fe380239fa6..2cfbcea5034 100644
--- a/clippy_dev/Cargo.toml
+++ b/clippy_dev/Cargo.toml
@@ -10,7 +10,7 @@ indoc = "1.0"
 itertools = "0.10.1"
 opener = "0.5"
 shell-escape = "0.1"
-tempfile = "3.3"
+tempfile = "3.2"
 walkdir = "2.3"
 
 [features]
diff --git a/clippy_lints/src/attrs.rs b/clippy_lints/src/attrs.rs
index e880876218e..8b0e11cb802 100644
--- a/clippy_lints/src/attrs.rs
+++ b/clippy_lints/src/attrs.rs
@@ -6,7 +6,7 @@ use clippy_utils::msrvs;
 use clippy_utils::source::{first_line_of_span, is_present_in_source, snippet_opt, without_block_comments};
 use clippy_utils::{extract_msrv_attr, meets_msrv};
 use if_chain::if_chain;
-use rustc_ast::{AttrKind, AttrStyle, Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem};
+use rustc_ast::{AttrKind, AttrStyle, Attribute, Lit, LitKind, MacArgs, MacArgsEq, MetaItemKind, NestedMetaItem};
 use rustc_errors::Applicability;
 use rustc_hir::{
     Block, Expr, ExprKind, ImplItem, ImplItemKind, Item, ItemKind, StmtKind, TraitFn, TraitItem, TraitItemKind,
@@ -593,6 +593,10 @@ fn check_empty_line_after_outer_attr(cx: &EarlyContext<'_>, item: &rustc_ast::It
         };
 
         if attr.style == AttrStyle::Outer {
+            if let MacArgs::Eq(_, MacArgsEq::Ast(expr)) = &attr_item.args
+                && !matches!(expr.kind, rustc_ast::ExprKind::Lit(..)) {
+                return;
+            }
             if attr_item.args.inner_tokens().is_empty() || !is_present_in_source(cx, attr.span) {
                 return;
             }
diff --git a/clippy_lints/src/case_sensitive_file_extension_comparisons.rs b/clippy_lints/src/case_sensitive_file_extension_comparisons.rs
index e3e31c5863e..7af200708ff 100644
--- a/clippy_lints/src/case_sensitive_file_extension_comparisons.rs
+++ b/clippy_lints/src/case_sensitive_file_extension_comparisons.rs
@@ -1,7 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_help;
 use if_chain::if_chain;
 use rustc_ast::ast::LitKind;
-use rustc_data_structures::intern::Interned;
 use rustc_hir::{Expr, ExprKind, PathSegment};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty;
@@ -56,8 +55,8 @@ fn check_case_sensitive_file_extension_comparison(ctx: &LateContext<'_>, expr: &
                 ty::Str => {
                     return Some(span);
                 },
-                ty::Adt(ty::AdtDef(Interned(&ty::AdtDefData { did, .. }, _)), _) => {
-                    if ctx.tcx.is_diagnostic_item(sym::String, did) {
+                ty::Adt(def, _) => {
+                    if ctx.tcx.is_diagnostic_item(sym::String, def.did()) {
                         return Some(span);
                     }
                 },
diff --git a/clippy_lints/src/cognitive_complexity.rs b/clippy_lints/src/cognitive_complexity.rs
index 85f95237549..2bf7f868905 100644
--- a/clippy_lints/src/cognitive_complexity.rs
+++ b/clippy_lints/src/cognitive_complexity.rs
@@ -82,7 +82,7 @@ impl CognitiveComplexity {
 
         if rust_cc > self.limit.limit() {
             let fn_span = match kind {
-                FnKind::ItemFn(ident, _, _, _) | FnKind::Method(ident, _, _) => ident.span,
+                FnKind::ItemFn(ident, _, _) | FnKind::Method(ident, _) => ident.span,
                 FnKind::Closure => {
                     let header_span = body_span.with_hi(decl.output.span().lo());
                     let pos = snippet_opt(cx, header_span).and_then(|snip| {
diff --git a/clippy_lints/src/doc.rs b/clippy_lints/src/doc.rs
index e72031e4877..b3fd8af4730 100644
--- a/clippy_lints/src/doc.rs
+++ b/clippy_lints/src/doc.rs
@@ -240,7 +240,7 @@ impl<'tcx> LateLintPass<'tcx> for DocMarkdown {
                     lint_for_missing_headers(cx, item.def_id, item.span, sig, headers, Some(body_id), fpu.panic_span);
                 }
             },
-            hir::ItemKind::Impl(ref impl_) => {
+            hir::ItemKind::Impl(impl_) => {
                 self.in_trait_impl = impl_.of_trait.is_some();
             },
             hir::ItemKind::Trait(_, unsafety, ..) => {
@@ -622,7 +622,7 @@ fn check_code(cx: &LateContext<'_>, text: &str, edition: Edition, span: Span) {
 
                 let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
                 let fallback_bundle =
-                    rustc_errors::fallback_fluent_bundle(false).expect("failed to load fallback fluent bundle");
+                    rustc_errors::fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false);
                 let emitter = EmitterWriter::new(
                     Box::new(io::sink()),
                     None,
diff --git a/clippy_lints/src/enum_variants.rs b/clippy_lints/src/enum_variants.rs
index 1f4353fa4f7..346d03ca556 100644
--- a/clippy_lints/src/enum_variants.rs
+++ b/clippy_lints/src/enum_variants.rs
@@ -260,7 +260,7 @@ impl LateLintPass<'_> for EnumVariantNames {
                     }
                     // The `module_name_repetitions` lint should only trigger if the item has the module in its
                     // name. Having the same name is accepted.
-                    if item.vis.node.is_pub() && item_camel.len() > mod_camel.len() {
+                    if cx.tcx.visibility(item.def_id).is_public() && item_camel.len() > mod_camel.len() {
                         let matching = count_match_start(mod_camel, &item_camel);
                         let rmatching = count_match_end(mod_camel, &item_camel);
                         let nchars = mod_camel.chars().count();
diff --git a/clippy_lints/src/exhaustive_items.rs b/clippy_lints/src/exhaustive_items.rs
index b0f50b5c144..173d41b4b05 100644
--- a/clippy_lints/src/exhaustive_items.rs
+++ b/clippy_lints/src/exhaustive_items.rs
@@ -78,7 +78,10 @@ impl LateLintPass<'_> for ExhaustiveItems {
             if !attrs.iter().any(|a| a.has_name(sym::non_exhaustive));
             then {
                 let (lint, msg) = if let ItemKind::Struct(ref v, ..) = item.kind {
-                    if v.fields().iter().any(|f| !f.vis.node.is_pub()) {
+                    if v.fields().iter().any(|f| {
+                        let def_id = cx.tcx.hir().local_def_id(f.hir_id);
+                        !cx.tcx.visibility(def_id).is_public()
+                    }) {
                         // skip structs with private fields
                         return;
                     }
diff --git a/clippy_lints/src/functions/must_use.rs b/clippy_lints/src/functions/must_use.rs
index 0709580c8ad..38e943d2eb8 100644
--- a/clippy_lints/src/functions/must_use.rs
+++ b/clippy_lints/src/functions/must_use.rs
@@ -20,7 +20,7 @@ use super::{DOUBLE_MUST_USE, MUST_USE_CANDIDATE, MUST_USE_UNIT};
 pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
     let attrs = cx.tcx.hir().attrs(item.hir_id());
     let attr = must_use_attr(attrs);
-    if let hir::ItemKind::Fn(ref sig, ref _generics, ref body_id) = item.kind {
+    if let hir::ItemKind::Fn(ref sig, _generics, ref body_id) = item.kind {
         let is_public = cx.access_levels.is_exported(item.def_id);
         let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
         if let Some(attr) = attr {
@@ -105,12 +105,7 @@ fn check_needless_must_use(
             fn_header_span,
             "this unit-returning function has a `#[must_use]` attribute",
             |diag| {
-                diag.span_suggestion(
-                    attr.span,
-                    "remove the attribute",
-                    "".into(),
-                    Applicability::MachineApplicable,
-                );
+                diag.span_suggestion(attr.span, "remove the attribute", "", Applicability::MachineApplicable);
             },
         );
     } else if attr.value_str().is_none() && is_must_use_ty(cx, return_ty(cx, item_id)) {
diff --git a/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs b/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs
index 830e3b32cfa..565a1c871d7 100644
--- a/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs
+++ b/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs
@@ -17,8 +17,8 @@ pub(super) fn check_fn<'tcx>(
     hir_id: hir::HirId,
 ) {
     let unsafety = match kind {
-        intravisit::FnKind::ItemFn(_, _, hir::FnHeader { unsafety, .. }, _) => unsafety,
-        intravisit::FnKind::Method(_, sig, _) => sig.header.unsafety,
+        intravisit::FnKind::ItemFn(_, _, hir::FnHeader { unsafety, .. }) => unsafety,
+        intravisit::FnKind::Method(_, sig) => sig.header.unsafety,
         intravisit::FnKind::Closure => return,
     };
 
diff --git a/clippy_lints/src/functions/result_unit_err.rs b/clippy_lints/src/functions/result_unit_err.rs
index 120fcb2619c..2e63a1f920d 100644
--- a/clippy_lints/src/functions/result_unit_err.rs
+++ b/clippy_lints/src/functions/result_unit_err.rs
@@ -14,7 +14,7 @@ use clippy_utils::ty::is_type_diagnostic_item;
 use super::RESULT_UNIT_ERR;
 
 pub(super) fn check_item(cx: &LateContext<'_>, item: &hir::Item<'_>) {
-    if let hir::ItemKind::Fn(ref sig, ref _generics, _) = item.kind {
+    if let hir::ItemKind::Fn(ref sig, _generics, _) = item.kind {
         let is_public = cx.access_levels.is_exported(item.def_id);
         let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
         if is_public {
diff --git a/clippy_lints/src/functions/too_many_arguments.rs b/clippy_lints/src/functions/too_many_arguments.rs
index 3af960491ed..5c8d8b8e755 100644
--- a/clippy_lints/src/functions/too_many_arguments.rs
+++ b/clippy_lints/src/functions/too_many_arguments.rs
@@ -26,9 +26,8 @@ pub(super) fn check_fn(
                     header: hir::FnHeader { abi: Abi::Rust, .. },
                     ..
                 },
-                _,
             )
-            | intravisit::FnKind::ItemFn(_, _, hir::FnHeader { abi: Abi::Rust, .. }, _) => check_arg_number(
+            | intravisit::FnKind::ItemFn(_, _, hir::FnHeader { abi: Abi::Rust, .. }) => check_arg_number(
                 cx,
                 decl,
                 span.with_hi(decl.output.span().hi()),
diff --git a/clippy_lints/src/implicit_hasher.rs b/clippy_lints/src/implicit_hasher.rs
index d5430a8c917..feb1b1014b1 100644
--- a/clippy_lints/src/implicit_hasher.rs
+++ b/clippy_lints/src/implicit_hasher.rs
@@ -117,7 +117,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitHasher {
         }
 
         match item.kind {
-            ItemKind::Impl(ref impl_) => {
+            ItemKind::Impl(impl_) => {
                 let mut vis = ImplicitHasherTypeVisitor::new(cx);
                 vis.visit_ty(impl_.self_ty);
 
@@ -155,7 +155,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitHasher {
                     );
                 }
             },
-            ItemKind::Fn(ref sig, ref generics, body_id) => {
+            ItemKind::Fn(ref sig, generics, body_id) => {
                 let body = cx.tcx.hir().body(body_id);
 
                 for ty in sig.decl.inputs {
diff --git a/clippy_lints/src/inherent_impl.rs b/clippy_lints/src/inherent_impl.rs
index 254d3f8a4d0..6a031a627df 100644
--- a/clippy_lints/src/inherent_impl.rs
+++ b/clippy_lints/src/inherent_impl.rs
@@ -119,7 +119,7 @@ impl<'tcx> LateLintPass<'tcx> for MultipleInherentImpl {
 fn get_impl_span(cx: &LateContext<'_>, id: LocalDefId) -> Option<Span> {
     let id = cx.tcx.hir().local_def_id_to_hir_id(id);
     if let Node::Item(&Item {
-        kind: ItemKind::Impl(ref impl_item),
+        kind: ItemKind::Impl(impl_item),
         span,
         ..
     }) = cx.tcx.hir().get(id)
diff --git a/clippy_lints/src/lib.register_nursery.rs b/clippy_lints/src/lib.register_nursery.rs
index 18904a94538..ec187563b3f 100644
--- a/clippy_lints/src/lib.register_nursery.rs
+++ b/clippy_lints/src/lib.register_nursery.rs
@@ -28,6 +28,8 @@ store.register_group(true, "clippy::nursery", Some("clippy_nursery"), vec![
     LintId::of(strings::STRING_LIT_AS_BYTES),
     LintId::of(suspicious_operation_groupings::SUSPICIOUS_OPERATION_GROUPINGS),
     LintId::of(trailing_empty_array::TRAILING_EMPTY_ARRAY),
+    LintId::of(trait_bounds::TRAIT_DUPLICATION_IN_BOUNDS),
+    LintId::of(trait_bounds::TYPE_REPETITION_IN_BOUNDS),
     LintId::of(transmute::TRANSMUTE_UNDEFINED_REPR),
     LintId::of(transmute::USELESS_TRANSMUTE),
     LintId::of(use_self::USE_SELF),
diff --git a/clippy_lints/src/lib.register_pedantic.rs b/clippy_lints/src/lib.register_pedantic.rs
index 63232fd4113..2ee2c6e3358 100644
--- a/clippy_lints/src/lib.register_pedantic.rs
+++ b/clippy_lints/src/lib.register_pedantic.rs
@@ -84,8 +84,6 @@ store.register_group(true, "clippy::pedantic", Some("clippy_pedantic"), vec![
     LintId::of(semicolon_if_nothing_returned::SEMICOLON_IF_NOTHING_RETURNED),
     LintId::of(stable_sort_primitive::STABLE_SORT_PRIMITIVE),
     LintId::of(strings::STRING_ADD_ASSIGN),
-    LintId::of(trait_bounds::TRAIT_DUPLICATION_IN_BOUNDS),
-    LintId::of(trait_bounds::TYPE_REPETITION_IN_BOUNDS),
     LintId::of(transmute::TRANSMUTE_PTR_TO_PTR),
     LintId::of(types::LINKEDLIST),
     LintId::of(types::OPTION_OPTION),
diff --git a/clippy_lints/src/lifetimes.rs b/clippy_lints/src/lifetimes.rs
index 54b80bf3b27..ab5d3fa7b6d 100644
--- a/clippy_lints/src/lifetimes.rs
+++ b/clippy_lints/src/lifetimes.rs
@@ -10,7 +10,7 @@ use rustc_hir::FnRetTy::Return;
 use rustc_hir::{
     BareFnTy, BodyId, FnDecl, GenericArg, GenericBound, GenericParam, GenericParamKind, Generics, Impl, ImplItem,
     ImplItemKind, Item, ItemKind, LangItem, Lifetime, LifetimeName, ParamName, PolyTraitRef, TraitBoundModifier,
-    TraitFn, TraitItem, TraitItemKind, Ty, TyKind, WhereClause, WherePredicate,
+    TraitFn, TraitItem, TraitItemKind, Ty, TyKind, WherePredicate,
 };
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::hir::nested_filter as middle_nested_filter;
@@ -85,9 +85,9 @@ declare_lint_pass!(Lifetimes => [NEEDLESS_LIFETIMES, EXTRA_UNUSED_LIFETIMES]);
 
 impl<'tcx> LateLintPass<'tcx> for Lifetimes {
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
-        if let ItemKind::Fn(ref sig, ref generics, id) = item.kind {
+        if let ItemKind::Fn(ref sig, generics, id) = item.kind {
             check_fn_inner(cx, sig.decl, Some(id), None, generics, item.span, true);
-        } else if let ItemKind::Impl(ref impl_) = item.kind {
+        } else if let ItemKind::Impl(impl_) = item.kind {
             report_extra_impl_lifetimes(cx, impl_);
         }
     }
@@ -100,7 +100,7 @@ impl<'tcx> LateLintPass<'tcx> for Lifetimes {
                 sig.decl,
                 Some(id),
                 None,
-                &item.generics,
+                item.generics,
                 item.span,
                 report_extra_lifetimes,
             );
@@ -113,7 +113,7 @@ impl<'tcx> LateLintPass<'tcx> for Lifetimes {
                 TraitFn::Required(sig) => (None, Some(sig)),
                 TraitFn::Provided(id) => (Some(id), None),
             };
-            check_fn_inner(cx, sig.decl, body, trait_sig, &item.generics, item.span, true);
+            check_fn_inner(cx, sig.decl, body, trait_sig, item.generics, item.span, true);
         }
     }
 }
@@ -135,7 +135,7 @@ fn check_fn_inner<'tcx>(
     span: Span,
     report_extra_lifetimes: bool,
 ) {
-    if span.from_expansion() || has_where_lifetimes(cx, &generics.where_clause) {
+    if span.from_expansion() || has_where_lifetimes(cx, generics) {
         return;
     }
 
@@ -144,28 +144,35 @@ fn check_fn_inner<'tcx>(
         .iter()
         .filter(|param| matches!(param.kind, GenericParamKind::Type { .. }));
     for typ in types {
-        for bound in typ.bounds {
-            let mut visitor = RefVisitor::new(cx);
-            walk_param_bound(&mut visitor, bound);
-            if visitor.lts.iter().any(|lt| matches!(lt, RefLt::Named(_))) {
-                return;
+        for pred in generics.bounds_for_param(cx.tcx.hir().local_def_id(typ.hir_id)) {
+            if pred.in_where_clause {
+                // has_where_lifetimes checked that this predicate contains no lifetime.
+                continue;
             }
-            if let GenericBound::Trait(ref trait_ref, _) = *bound {
-                let params = &trait_ref
-                    .trait_ref
-                    .path
-                    .segments
-                    .last()
-                    .expect("a path must have at least one segment")
-                    .args;
-                if let Some(params) = *params {
-                    let lifetimes = params.args.iter().filter_map(|arg| match arg {
-                        GenericArg::Lifetime(lt) => Some(lt),
-                        _ => None,
-                    });
-                    for bound in lifetimes {
-                        if bound.name != LifetimeName::Static && !bound.is_elided() {
-                            return;
+
+            for bound in pred.bounds {
+                let mut visitor = RefVisitor::new(cx);
+                walk_param_bound(&mut visitor, bound);
+                if visitor.lts.iter().any(|lt| matches!(lt, RefLt::Named(_))) {
+                    return;
+                }
+                if let GenericBound::Trait(ref trait_ref, _) = *bound {
+                    let params = &trait_ref
+                        .trait_ref
+                        .path
+                        .segments
+                        .last()
+                        .expect("a path must have at least one segment")
+                        .args;
+                    if let Some(params) = *params {
+                        let lifetimes = params.args.iter().filter_map(|arg| match arg {
+                            GenericArg::Lifetime(lt) => Some(lt),
+                            _ => None,
+                        });
+                        for bound in lifetimes {
+                            if bound.name != LifetimeName::Static && !bound.is_elided() {
+                                return;
+                            }
                         }
                     }
                 }
@@ -326,9 +333,7 @@ fn allowed_lts_from(named_generics: &[GenericParam<'_>]) -> FxHashSet<RefLt> {
     let mut allowed_lts = FxHashSet::default();
     for par in named_generics.iter() {
         if let GenericParamKind::Lifetime { .. } = par.kind {
-            if par.bounds.is_empty() {
-                allowed_lts.insert(RefLt::Named(par.name.ident().name));
-            }
+            allowed_lts.insert(RefLt::Named(par.name.ident().name));
         }
     }
     allowed_lts.insert(RefLt::Unnamed);
@@ -449,8 +454,8 @@ impl<'a, 'tcx> Visitor<'tcx> for RefVisitor<'a, 'tcx> {
 
 /// Are any lifetimes mentioned in the `where` clause? If so, we don't try to
 /// reason about elision.
-fn has_where_lifetimes<'tcx>(cx: &LateContext<'tcx>, where_clause: &'tcx WhereClause<'_>) -> bool {
-    for predicate in where_clause.predicates {
+fn has_where_lifetimes<'tcx>(cx: &LateContext<'tcx>, generics: &'tcx Generics<'_>) -> bool {
+    for predicate in generics.predicates {
         match *predicate {
             WherePredicate::RegionPredicate(..) => return true,
             WherePredicate::BoundPredicate(ref pred) => {
@@ -565,7 +570,7 @@ fn report_extra_impl_lifetimes<'tcx>(cx: &LateContext<'tcx>, impl_: &'tcx Impl<'
         .collect();
     let mut checker = LifetimeChecker::<middle_nested_filter::All>::new(cx, hs);
 
-    walk_generics(&mut checker, &impl_.generics);
+    walk_generics(&mut checker, impl_.generics);
     if let Some(ref trait_ref) = impl_.of_trait {
         walk_trait_ref(&mut checker, trait_ref);
     }
diff --git a/clippy_lints/src/loops/needless_range_loop.rs b/clippy_lints/src/loops/needless_range_loop.rs
index 72e86804ed2..6ed141fa4a5 100644
--- a/clippy_lints/src/loops/needless_range_loop.rs
+++ b/clippy_lints/src/loops/needless_range_loop.rs
@@ -59,7 +59,7 @@ pub(super) fn check<'tcx>(
                 if let Some(indexed_extent) = indexed_extent {
                     let parent_def_id = cx.tcx.hir().get_parent_item(expr.hir_id);
                     let region_scope_tree = cx.tcx.region_scope_tree(parent_def_id);
-                    let pat_extent = region_scope_tree.var_scope(pat.hir_id.local_id);
+                    let pat_extent = region_scope_tree.var_scope(pat.hir_id.local_id).unwrap();
                     if region_scope_tree.is_subscope_of(indexed_extent, pat_extent) {
                         return;
                     }
@@ -262,7 +262,7 @@ impl<'a, 'tcx> VarVisitor<'a, 'tcx> {
                 match res {
                     Res::Local(hir_id) => {
                         let parent_def_id = self.cx.tcx.hir().get_parent_item(expr.hir_id);
-                        let extent = self.cx.tcx.region_scope_tree(parent_def_id).var_scope(hir_id.local_id);
+                        let extent = self.cx.tcx.region_scope_tree(parent_def_id).var_scope(hir_id.local_id).unwrap();
                         if index_used_directly {
                             self.indexed_directly.insert(
                                 seqvar.segments[0].ident.name,
diff --git a/clippy_lints/src/loops/never_loop.rs b/clippy_lints/src/loops/never_loop.rs
index a0b2302662e..70a118d6b35 100644
--- a/clippy_lints/src/loops/never_loop.rs
+++ b/clippy_lints/src/loops/never_loop.rs
@@ -168,14 +168,16 @@ fn never_loop_expr(expr: &Expr<'_>, main_loop_id: HirId) -> NeverLoopResult {
             .operands
             .iter()
             .map(|(o, _)| match o {
-                InlineAsmOperand::In { expr, .. }
-                | InlineAsmOperand::InOut { expr, .. }
-                | InlineAsmOperand::Sym { expr } => never_loop_expr(expr, main_loop_id),
+                InlineAsmOperand::In { expr, .. } | InlineAsmOperand::InOut { expr, .. } => {
+                    never_loop_expr(expr, main_loop_id)
+                },
                 InlineAsmOperand::Out { expr, .. } => never_loop_expr_all(&mut expr.iter(), main_loop_id),
                 InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => {
                     never_loop_expr_all(&mut once(in_expr).chain(out_expr.iter()), main_loop_id)
                 },
-                InlineAsmOperand::Const { .. } => NeverLoopResult::Otherwise,
+                InlineAsmOperand::Const { .. }
+                | InlineAsmOperand::SymFn { .. }
+                | InlineAsmOperand::SymStatic { .. } => NeverLoopResult::Otherwise,
             })
             .fold(NeverLoopResult::Otherwise, combine_both),
         ExprKind::Struct(_, _, None)
diff --git a/clippy_lints/src/manual_non_exhaustive.rs b/clippy_lints/src/manual_non_exhaustive.rs
index 2501dd5bed4..b8d620d8171 100644
--- a/clippy_lints/src/manual_non_exhaustive.rs
+++ b/clippy_lints/src/manual_non_exhaustive.rs
@@ -177,9 +177,10 @@ impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustiveEnum {
             && let [.., name] = p.segments
             && let Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Const), id) = p.res
             && name.ident.as_str().starts_with('_')
-            && let Some(variant_id) = cx.tcx.parent(id)
-            && let Some(enum_id) = cx.tcx.parent(variant_id)
         {
+            let variant_id = cx.tcx.parent(id);
+            let enum_id = cx.tcx.parent(variant_id);
+
             self.constructed_enum_variants.insert((enum_id, variant_id));
         }
     }
diff --git a/clippy_lints/src/matches/overlapping_arms.rs b/clippy_lints/src/matches/overlapping_arms.rs
index 7e658126690..c0b3e95b185 100644
--- a/clippy_lints/src/matches/overlapping_arms.rs
+++ b/clippy_lints/src/matches/overlapping_arms.rs
@@ -40,10 +40,8 @@ fn all_ranges<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>], ty: Ty<'tcx>)
                         Some(rhs) => constant(cx, cx.typeck_results(), rhs)?.0,
                         None => miri_to_const(ty.numeric_max_val(cx.tcx)?)?,
                     };
-
                     let lhs_val = lhs_const.int_value(cx, ty)?;
                     let rhs_val = rhs_const.int_value(cx, ty)?;
-
                     let rhs_bound = match range_end {
                         RangeEnd::Included => EndBound::Included(rhs_val),
                         RangeEnd::Excluded => EndBound::Excluded(rhs_val),
diff --git a/clippy_lints/src/matches/redundant_pattern_match.rs b/clippy_lints/src/matches/redundant_pattern_match.rs
index a34ed58c9c3..37b67647efe 100644
--- a/clippy_lints/src/matches/redundant_pattern_match.rs
+++ b/clippy_lints/src/matches/redundant_pattern_match.rs
@@ -139,7 +139,7 @@ fn find_sugg_for_if_let<'tcx>(
         PatKind::TupleStruct(ref qpath, [sub_pat], _) => {
             if let PatKind::Wild = sub_pat.kind {
                 let res = cx.typeck_results().qpath_res(qpath, check_pat.hir_id);
-                let Some(id) = res.opt_def_id().and_then(|ctor_id| cx.tcx.parent(ctor_id)) else { return };
+                let Some(id) = res.opt_def_id().map(|ctor_id| cx.tcx.parent(ctor_id)) else { return };
                 let lang_items = cx.tcx.lang_items();
                 if Some(id) == lang_items.result_ok_variant() {
                     ("is_ok()", try_get_generic_ty(op_ty, 0).unwrap_or(op_ty))
diff --git a/clippy_lints/src/methods/bind_instead_of_map.rs b/clippy_lints/src/methods/bind_instead_of_map.rs
index eec232e6d09..b88ec0963f2 100644
--- a/clippy_lints/src/methods/bind_instead_of_map.rs
+++ b/clippy_lints/src/methods/bind_instead_of_map.rs
@@ -42,7 +42,7 @@ pub(crate) trait BindInsteadOfMap {
 
     fn no_op_msg(cx: &LateContext<'_>) -> Option<String> {
         let variant_id = cx.tcx.lang_items().require(Self::VARIANT_LANG_ITEM).ok()?;
-        let item_id = cx.tcx.parent(variant_id)?;
+        let item_id = cx.tcx.parent(variant_id);
         Some(format!(
             "using `{}.{}({})`, which is a no-op",
             cx.tcx.item_name(item_id),
@@ -53,7 +53,7 @@ pub(crate) trait BindInsteadOfMap {
 
     fn lint_msg(cx: &LateContext<'_>) -> Option<String> {
         let variant_id = cx.tcx.lang_items().require(Self::VARIANT_LANG_ITEM).ok()?;
-        let item_id = cx.tcx.parent(variant_id)?;
+        let item_id = cx.tcx.parent(variant_id);
         Some(format!(
             "using `{}.{}(|x| {}(y))`, which is more succinctly expressed as `{}(|x| y)`",
             cx.tcx.item_name(item_id),
@@ -145,7 +145,7 @@ pub(crate) trait BindInsteadOfMap {
         if_chain! {
             if let Some(adt) = cx.typeck_results().expr_ty(recv).ty_adt_def();
             if let Ok(vid) = cx.tcx.lang_items().require(Self::VARIANT_LANG_ITEM);
-            if Some(adt.did()) == cx.tcx.parent(vid);
+            if adt.did() == cx.tcx.parent(vid);
             then {} else { return false; }
         }
 
@@ -182,7 +182,7 @@ pub(crate) trait BindInsteadOfMap {
     fn is_variant(cx: &LateContext<'_>, res: Res) -> bool {
         if let Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Fn), id) = res {
             if let Ok(variant_id) = cx.tcx.lang_items().require(Self::VARIANT_LANG_ITEM) {
-                return cx.tcx.parent(id) == Some(variant_id);
+                return cx.tcx.parent(id) == variant_id;
             }
         }
         false
diff --git a/clippy_lints/src/methods/chars_cmp.rs b/clippy_lints/src/methods/chars_cmp.rs
index 2cf2c5641bf..f7b79f0839b 100644
--- a/clippy_lints/src/methods/chars_cmp.rs
+++ b/clippy_lints/src/methods/chars_cmp.rs
@@ -19,7 +19,7 @@ pub(super) fn check(
     if_chain! {
         if let Some(args) = method_chain_args(info.chain, chain_methods);
         if let hir::ExprKind::Call(fun, [arg_char]) = info.other.kind;
-        if let Some(id) = path_def_id(cx, fun).and_then(|ctor_id| cx.tcx.parent(ctor_id));
+        if let Some(id) = path_def_id(cx, fun).map(|ctor_id| cx.tcx.parent(ctor_id));
         if Some(id) == cx.tcx.lang_items().option_some_variant();
         then {
             let mut applicability = Applicability::MachineApplicable;
diff --git a/clippy_lints/src/methods/option_map_or_none.rs b/clippy_lints/src/methods/option_map_or_none.rs
index 2a5ab6e625c..76bc9466ed8 100644
--- a/clippy_lints/src/methods/option_map_or_none.rs
+++ b/clippy_lints/src/methods/option_map_or_none.rs
@@ -75,7 +75,7 @@ pub(super) fn check<'tcx>(
             let arg_snippet = snippet(cx, span, "..");
             let body = cx.tcx.hir().body(id);
                 if let Some((func, [arg_char])) = reduce_unit_expression(&body.value);
-                if let Some(id) = path_def_id(cx, func).and_then(|ctor_id| cx.tcx.parent(ctor_id));
+                if let Some(id) = path_def_id(cx, func).map(|ctor_id| cx.tcx.parent(ctor_id));
                 if Some(id) == cx.tcx.lang_items().option_some_variant();
                 then {
                     let func_snippet = snippet(cx, arg_char.span, "..");
diff --git a/clippy_lints/src/missing_doc.rs b/clippy_lints/src/missing_doc.rs
index db6aab0671b..b99052e66ba 100644
--- a/clippy_lints/src/missing_doc.rs
+++ b/clippy_lints/src/missing_doc.rs
@@ -11,7 +11,7 @@ use if_chain::if_chain;
 use rustc_ast::ast::{self, MetaItem, MetaItemKind};
 use rustc_hir as hir;
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::ty;
+use rustc_middle::ty::{self, DefIdTree};
 use rustc_session::{declare_tool_lint, impl_lint_pass};
 use rustc_span::def_id::CRATE_DEF_ID;
 use rustc_span::source_map::Span;
@@ -131,8 +131,8 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
             hir::ItemKind::Fn(..) => {
                 // ignore main()
                 if it.ident.name == sym::main {
-                    let def_key = cx.tcx.hir().def_key(it.def_id);
-                    if def_key.parent == Some(hir::def_id::CRATE_DEF_INDEX) {
+                    let at_root = cx.tcx.local_parent(it.def_id) == CRATE_DEF_ID;
+                    if at_root {
                         return;
                     }
                 }
diff --git a/clippy_lints/src/missing_inline.rs b/clippy_lints/src/missing_inline.rs
index 6e6ad1ebbce..0d953299189 100644
--- a/clippy_lints/src/missing_inline.rs
+++ b/clippy_lints/src/missing_inline.rs
@@ -97,7 +97,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
                 let attrs = cx.tcx.hir().attrs(it.hir_id());
                 check_missing_inline_attrs(cx, attrs, it.span, desc);
             },
-            hir::ItemKind::Trait(ref _is_auto, ref _unsafe, ref _generics, _bounds, trait_items) => {
+            hir::ItemKind::Trait(ref _is_auto, ref _unsafe, _generics, _bounds, trait_items) => {
                 // note: we need to check if the trait is exported so we can't use
                 // `LateLintPass::check_trait_item` here.
                 for tit in trait_items {
diff --git a/clippy_lints/src/needless_pass_by_value.rs b/clippy_lints/src/needless_pass_by_value.rs
index d29d07da7b0..4034079a90c 100644
--- a/clippy_lints/src/needless_pass_by_value.rs
+++ b/clippy_lints/src/needless_pass_by_value.rs
@@ -85,7 +85,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
         }
 
         match kind {
-            FnKind::ItemFn(.., header, _) => {
+            FnKind::ItemFn(.., header) => {
                 let attrs = cx.tcx.hir().attrs(hir_id);
                 if header.abi != Abi::Rust || requires_exact_signature(attrs) {
                     return;
@@ -241,7 +241,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
                                                 |x| Cow::from(format!("change `{}` to", x)),
                                             )
                                             .as_ref(),
-                                        suggestion.into(),
+                                        suggestion,
                                         Applicability::Unspecified,
                                     );
                                 }
@@ -271,7 +271,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
                                                 |x| Cow::from(format!("change `{}` to", x))
                                             )
                                             .as_ref(),
-                                        suggestion.into(),
+                                        suggestion,
                                         Applicability::Unspecified,
                                     );
                                 }
diff --git a/clippy_lints/src/neg_multiply.rs b/clippy_lints/src/neg_multiply.rs
index 0d05c83ffe4..6ba9ba0753d 100644
--- a/clippy_lints/src/neg_multiply.rs
+++ b/clippy_lints/src/neg_multiply.rs
@@ -53,7 +53,7 @@ impl<'tcx> LateLintPass<'tcx> for NegMultiply {
 fn check_mul(cx: &LateContext<'_>, span: Span, lit: &Expr<'_>, exp: &Expr<'_>) {
     if_chain! {
         if let ExprKind::Lit(ref l) = lit.kind;
-        if consts::lit_to_constant(&l.node, cx.typeck_results().expr_ty_opt(lit)) == Constant::Int(1);
+        if consts::lit_to_mir_constant(&l.node, cx.typeck_results().expr_ty_opt(lit)) == Constant::Int(1);
         if cx.typeck_results().expr_ty(exp).is_integral();
 
         then {
diff --git a/clippy_lints/src/new_without_default.rs b/clippy_lints/src/new_without_default.rs
index 9419056be14..2f733f221d5 100644
--- a/clippy_lints/src/new_without_default.rs
+++ b/clippy_lints/src/new_without_default.rs
@@ -62,13 +62,13 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault {
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
         if let hir::ItemKind::Impl(hir::Impl {
             of_trait: None,
-            ref generics,
+            generics,
             self_ty: impl_self_ty,
             items,
             ..
         }) = item.kind
         {
-            for assoc_item in items {
+            for assoc_item in *items {
                 if assoc_item.kind == (hir::AssocItemKind::Fn { has_self: false }) {
                     let impl_item = cx.tcx.hir().impl_item(assoc_item.id);
                     if in_external_macro(cx.sess(), impl_item.span) {
diff --git a/clippy_lints/src/partialeq_ne_impl.rs b/clippy_lints/src/partialeq_ne_impl.rs
index e827cdaae87..1469cb434c0 100644
--- a/clippy_lints/src/partialeq_ne_impl.rs
+++ b/clippy_lints/src/partialeq_ne_impl.rs
@@ -42,7 +42,7 @@ impl<'tcx> LateLintPass<'tcx> for PartialEqNeImpl {
             if let Some(eq_trait) = cx.tcx.lang_items().eq_trait();
             if trait_ref.path.res.def_id() == eq_trait;
             then {
-                for impl_item in impl_items {
+                for impl_item in *impl_items {
                     if impl_item.ident.name == sym::ne {
                         span_lint_hir(
                             cx,
diff --git a/clippy_lints/src/pass_by_ref_or_value.rs b/clippy_lints/src/pass_by_ref_or_value.rs
index d59249d7f13..9af3059a37f 100644
--- a/clippy_lints/src/pass_by_ref_or_value.rs
+++ b/clippy_lints/src/pass_by_ref_or_value.rs
@@ -251,7 +251,7 @@ impl<'tcx> LateLintPass<'tcx> for PassByRefOrValue {
         }
 
         match kind {
-            FnKind::ItemFn(.., header, _) => {
+            FnKind::ItemFn(.., header) => {
                 if header.abi != Abi::Rust {
                     return;
                 }
diff --git a/clippy_lints/src/redundant_pub_crate.rs b/clippy_lints/src/redundant_pub_crate.rs
index 3e6086d56f0..323326381d4 100644
--- a/clippy_lints/src/redundant_pub_crate.rs
+++ b/clippy_lints/src/redundant_pub_crate.rs
@@ -1,9 +1,11 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use rustc_errors::Applicability;
 use rustc_hir::def::{DefKind, Res};
-use rustc_hir::{Item, ItemKind, VisibilityKind};
+use rustc_hir::{Item, ItemKind};
 use rustc_lint::{LateContext, LateLintPass};
+use rustc_middle::ty;
 use rustc_session::{declare_tool_lint, impl_lint_pass};
+use rustc_span::def_id::CRATE_DEF_ID;
 use rustc_span::hygiene::MacroKind;
 
 declare_clippy_lint! {
@@ -44,7 +46,7 @@ impl_lint_pass!(RedundantPubCrate => [REDUNDANT_PUB_CRATE]);
 impl<'tcx> LateLintPass<'tcx> for RedundantPubCrate {
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
         if_chain! {
-            if let VisibilityKind::Crate { .. } = item.vis.node;
+            if cx.tcx.visibility(item.def_id) == ty::Visibility::Restricted(CRATE_DEF_ID.to_def_id());
             if !cx.access_levels.is_exported(item.def_id) && self.is_exported.last() == Some(&false);
             if is_not_macro_export(item);
             then {
@@ -57,7 +59,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantPubCrate {
                     &format!("pub(crate) {} inside private module", descr),
                     |diag| {
                         diag.span_suggestion(
-                            item.vis.span,
+                            item.vis_span,
                             "consider using",
                             "pub".to_string(),
                             Applicability::MachineApplicable,
@@ -84,6 +86,8 @@ fn is_not_macro_export<'tcx>(item: &'tcx Item<'tcx>) -> bool {
         if let Res::Def(DefKind::Macro(MacroKind::Bang), _) = path.res {
             return false;
         }
+    } else if let ItemKind::Macro(..) = item.kind {
+        return false;
     }
 
     true
diff --git a/clippy_lints/src/return_self_not_must_use.rs b/clippy_lints/src/return_self_not_must_use.rs
index 79f104eac0b..91e5e1e8b28 100644
--- a/clippy_lints/src/return_self_not_must_use.rs
+++ b/clippy_lints/src/return_self_not_must_use.rs
@@ -111,7 +111,7 @@ impl<'tcx> LateLintPass<'tcx> for ReturnSelfNotMustUse {
     ) {
         if_chain! {
             // We are only interested in methods, not in functions or associated functions.
-            if matches!(kind, FnKind::Method(_, _, _));
+            if matches!(kind, FnKind::Method(_, _));
             if let Some(fn_def) = cx.tcx.hir().opt_local_def_id(hir_id);
             if let Some(impl_def) = cx.tcx.impl_of_method(fn_def.to_def_id());
             // We don't want this method to be te implementation of a trait because the
diff --git a/clippy_lints/src/same_name_method.rs b/clippy_lints/src/same_name_method.rs
index 22b45896955..f63925a2f14 100644
--- a/clippy_lints/src/same_name_method.rs
+++ b/clippy_lints/src/same_name_method.rs
@@ -50,110 +50,111 @@ impl<'tcx> LateLintPass<'tcx> for SameNameMethod {
     fn check_crate_post(&mut self, cx: &LateContext<'tcx>) {
         let mut map = FxHashMap::<Res, ExistingName>::default();
 
-        for item in cx.tcx.hir().items() {
-            if let ItemKind::Impl(Impl {
-                items,
-                of_trait,
-                self_ty,
-                ..
-            }) = &item.kind
+        for id in cx.tcx.hir().items() {
+            if matches!(cx.tcx.hir().def_kind(id.def_id), DefKind::Impl)
+                && let item = cx.tcx.hir().item(id)
+                && let ItemKind::Impl(Impl {
+                    items,
+                    of_trait,
+                    self_ty,
+                    ..
+                }) = &item.kind
+                && let TyKind::Path(QPath::Resolved(_, Path { res, .. })) = self_ty.kind
             {
-                if let TyKind::Path(QPath::Resolved(_, Path { res, .. })) = self_ty.kind {
-                    if !map.contains_key(res) {
-                        map.insert(
-                            *res,
-                            ExistingName {
-                                impl_methods: BTreeMap::new(),
-                                trait_methods: BTreeMap::new(),
-                            },
-                        );
-                    }
-                    let existing_name = map.get_mut(res).unwrap();
-
-                    match of_trait {
-                        Some(trait_ref) => {
-                            let mut methods_in_trait: BTreeSet<Symbol> = if_chain! {
-                                if let Some(Node::TraitRef(TraitRef { path, .. })) =
-                                    cx.tcx.hir().find(trait_ref.hir_ref_id);
-                                if let Res::Def(DefKind::Trait, did) = path.res;
-                                then{
-                                    // FIXME: if
-                                    // `rustc_middle::ty::assoc::AssocItems::items` is public,
-                                    // we can iterate its keys instead of `in_definition_order`,
-                                    // which's more efficient
-                                    cx.tcx
-                                        .associated_items(did)
-                                        .in_definition_order()
-                                        .filter(|assoc_item| {
-                                            matches!(assoc_item.kind, AssocKind::Fn)
-                                        })
-                                        .map(|assoc_item| assoc_item.name)
-                                        .collect()
-                                }else{
-                                    BTreeSet::new()
-                                }
-                            };
-
-                            let mut check_trait_method = |method_name: Symbol, trait_method_span: Span| {
-                                if let Some(impl_span) = existing_name.impl_methods.get(&method_name) {
-                                    span_lint_and_then(
-                                        cx,
-                                        SAME_NAME_METHOD,
-                                        *impl_span,
-                                        "method's name is the same as an existing method in a trait",
-                                        |diag| {
-                                            diag.span_note(
-                                                trait_method_span,
-                                                &format!("existing `{}` defined here", method_name),
-                                            );
-                                        },
-                                    );
-                                }
-                                if let Some(v) = existing_name.trait_methods.get_mut(&method_name) {
-                                    v.push(trait_method_span);
-                                } else {
-                                    existing_name.trait_methods.insert(method_name, vec![trait_method_span]);
-                                }
-                            };
+                if !map.contains_key(res) {
+                    map.insert(
+                        *res,
+                        ExistingName {
+                            impl_methods: BTreeMap::new(),
+                            trait_methods: BTreeMap::new(),
+                        },
+                    );
+                }
+                let existing_name = map.get_mut(res).unwrap();
 
-                            for impl_item_ref in (*items).iter().filter(|impl_item_ref| {
-                                matches!(impl_item_ref.kind, rustc_hir::AssocItemKind::Fn { .. })
-                            }) {
-                                let method_name = impl_item_ref.ident.name;
-                                methods_in_trait.remove(&method_name);
-                                check_trait_method(method_name, impl_item_ref.span);
+                match of_trait {
+                    Some(trait_ref) => {
+                        let mut methods_in_trait: BTreeSet<Symbol> = if_chain! {
+                            if let Some(Node::TraitRef(TraitRef { path, .. })) =
+                                cx.tcx.hir().find(trait_ref.hir_ref_id);
+                            if let Res::Def(DefKind::Trait, did) = path.res;
+                            then{
+                                // FIXME: if
+                                // `rustc_middle::ty::assoc::AssocItems::items` is public,
+                                // we can iterate its keys instead of `in_definition_order`,
+                                // which's more efficient
+                                cx.tcx
+                                    .associated_items(did)
+                                    .in_definition_order()
+                                    .filter(|assoc_item| {
+                                        matches!(assoc_item.kind, AssocKind::Fn)
+                                    })
+                                    .map(|assoc_item| assoc_item.name)
+                                    .collect()
+                            }else{
+                                BTreeSet::new()
                             }
+                        };
 
-                            for method_name in methods_in_trait {
-                                check_trait_method(method_name, item.span);
+                        let mut check_trait_method = |method_name: Symbol, trait_method_span: Span| {
+                            if let Some(impl_span) = existing_name.impl_methods.get(&method_name) {
+                                span_lint_and_then(
+                                    cx,
+                                    SAME_NAME_METHOD,
+                                    *impl_span,
+                                    "method's name is the same as an existing method in a trait",
+                                    |diag| {
+                                        diag.span_note(
+                                            trait_method_span,
+                                            &format!("existing `{}` defined here", method_name),
+                                        );
+                                    },
+                                );
                             }
-                        },
-                        None => {
-                            for impl_item_ref in (*items).iter().filter(|impl_item_ref| {
-                                matches!(impl_item_ref.kind, rustc_hir::AssocItemKind::Fn { .. })
-                            }) {
-                                let method_name = impl_item_ref.ident.name;
-                                let impl_span = impl_item_ref.span;
-                                if let Some(trait_spans) = existing_name.trait_methods.get(&method_name) {
-                                    span_lint_and_then(
-                                        cx,
-                                        SAME_NAME_METHOD,
-                                        impl_span,
-                                        "method's name is the same as an existing method in a trait",
-                                        |diag| {
-                                            // TODO should we `span_note` on every trait?
-                                            // iterate on trait_spans?
-                                            diag.span_note(
-                                                trait_spans[0],
-                                                &format!("existing `{}` defined here", method_name),
-                                            );
-                                        },
-                                    );
-                                }
-                                existing_name.impl_methods.insert(method_name, impl_span);
+                            if let Some(v) = existing_name.trait_methods.get_mut(&method_name) {
+                                v.push(trait_method_span);
+                            } else {
+                                existing_name.trait_methods.insert(method_name, vec![trait_method_span]);
                             }
-                        },
-                    }
+                        };
+
+                        for impl_item_ref in (*items).iter().filter(|impl_item_ref| {
+                            matches!(impl_item_ref.kind, rustc_hir::AssocItemKind::Fn { .. })
+                        }) {
+                            let method_name = impl_item_ref.ident.name;
+                            methods_in_trait.remove(&method_name);
+                            check_trait_method(method_name, impl_item_ref.span);
+                        }
+
+                        for method_name in methods_in_trait {
+                            check_trait_method(method_name, item.span);
+                        }
+                    },
+                    None => {
+                        for impl_item_ref in (*items).iter().filter(|impl_item_ref| {
+                            matches!(impl_item_ref.kind, rustc_hir::AssocItemKind::Fn { .. })
+                        }) {
+                            let method_name = impl_item_ref.ident.name;
+                            let impl_span = impl_item_ref.span;
+                            if let Some(trait_spans) = existing_name.trait_methods.get(&method_name) {
+                                span_lint_and_then(
+                                    cx,
+                                    SAME_NAME_METHOD,
+                                    impl_span,
+                                    "method's name is the same as an existing method in a trait",
+                                    |diag| {
+                                        // TODO should we `span_note` on every trait?
+                                        // iterate on trait_spans?
+                                        diag.span_note(
+                                            trait_spans[0],
+                                            &format!("existing `{}` defined here", method_name),
+                                        );
+                                    },
+                                );
+                            }
+                            existing_name.impl_methods.insert(method_name, impl_span);
+                        }
+                    },
                 }
             }
         }
diff --git a/clippy_lints/src/serde_api.rs b/clippy_lints/src/serde_api.rs
index 398e2c200de..fc1c2af9257 100644
--- a/clippy_lints/src/serde_api.rs
+++ b/clippy_lints/src/serde_api.rs
@@ -36,7 +36,7 @@ impl<'tcx> LateLintPass<'tcx> for SerdeApi {
                 if did == visit_did {
                     let mut seen_str = None;
                     let mut seen_string = None;
-                    for item in items {
+                    for item in *items {
                         match item.ident.as_str() {
                             "visit_str" => seen_str = Some(item.span),
                             "visit_string" => seen_string = Some(item.span),
diff --git a/clippy_lints/src/shadow.rs b/clippy_lints/src/shadow.rs
index 11882585044..1ab7f52110c 100644
--- a/clippy_lints/src/shadow.rs
+++ b/clippy_lints/src/shadow.rs
@@ -160,8 +160,8 @@ impl<'tcx> LateLintPass<'tcx> for Shadow {
 
 fn is_shadow(cx: &LateContext<'_>, owner: LocalDefId, first: ItemLocalId, second: ItemLocalId) -> bool {
     let scope_tree = cx.tcx.region_scope_tree(owner.to_def_id());
-    let first_scope = scope_tree.var_scope(first);
-    let second_scope = scope_tree.var_scope(second);
+    let first_scope = scope_tree.var_scope(first).unwrap();
+    let second_scope = scope_tree.var_scope(second).unwrap();
     scope_tree.is_subscope_of(second_scope, first_scope)
 }
 
diff --git a/clippy_lints/src/trait_bounds.rs b/clippy_lints/src/trait_bounds.rs
index 1551d0ecb74..78e388a49af 100644
--- a/clippy_lints/src/trait_bounds.rs
+++ b/clippy_lints/src/trait_bounds.rs
@@ -8,8 +8,7 @@ use rustc_data_structures::unhash::UnhashMap;
 use rustc_errors::Applicability;
 use rustc_hir::def::Res;
 use rustc_hir::{
-    GenericBound, Generics, Item, ItemKind, Node, ParamName, Path, PathSegment, QPath, TraitItem, Ty, TyKind,
-    WherePredicate,
+    GenericBound, Generics, Item, ItemKind, Node, Path, PathSegment, QPath, TraitItem, Ty, TyKind, WherePredicate,
 };
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::{declare_tool_lint, impl_lint_pass};
@@ -36,7 +35,7 @@ declare_clippy_lint! {
     /// ```
     #[clippy::version = "1.38.0"]
     pub TYPE_REPETITION_IN_BOUNDS,
-    pedantic,
+    nursery,
     "Types are repeated unnecessary in trait bounds use `+` instead of using `T: _, T: _`"
 }
 
@@ -66,7 +65,7 @@ declare_clippy_lint! {
     /// ```
     #[clippy::version = "1.47.0"]
     pub TRAIT_DUPLICATION_IN_BOUNDS,
-    pedantic,
+    nursery,
     "Check if the same trait bounds are specified twice during a function declaration"
 }
 
@@ -91,10 +90,9 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds {
     }
 
     fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'tcx>) {
-        let Generics { where_clause, .. } = &item.generics;
         let mut self_bounds_map = FxHashMap::default();
 
-        for predicate in where_clause.predicates {
+        for predicate in item.generics.predicates {
             if_chain! {
                 if let WherePredicate::BoundPredicate(ref bound_predicate) = predicate;
                 if !bound_predicate.span.from_expansion();
@@ -167,7 +165,7 @@ impl TraitBounds {
         }
         let mut map: UnhashMap<SpanlessTy<'_, '_>, Vec<&GenericBound<'_>>> = UnhashMap::default();
         let mut applicability = Applicability::MaybeIncorrect;
-        for bound in gen.where_clause.predicates {
+        for bound in gen.predicates {
             if_chain! {
                 if let WherePredicate::BoundPredicate(ref p) = bound;
                 if p.bounds.len() as u64 <= self.max_trait_bounds;
@@ -217,34 +215,23 @@ impl TraitBounds {
 }
 
 fn check_trait_bound_duplication(cx: &LateContext<'_>, gen: &'_ Generics<'_>) {
-    if gen.span.from_expansion() || gen.params.is_empty() || gen.where_clause.predicates.is_empty() {
+    if gen.span.from_expansion() || gen.params.is_empty() || gen.predicates.is_empty() {
         return;
     }
 
-    let mut map = FxHashMap::default();
-    for param in gen.params {
-        if let ParamName::Plain(ref ident) = param.name {
-            let res = param
-                .bounds
-                .iter()
-                .filter_map(get_trait_info_from_bound)
-                .collect::<Vec<_>>();
-            map.insert(*ident, res);
-        }
-    }
-
-    for predicate in gen.where_clause.predicates {
+    let mut map = FxHashMap::<_, Vec<_>>::default();
+    for predicate in gen.predicates {
         if_chain! {
             if let WherePredicate::BoundPredicate(ref bound_predicate) = predicate;
             if !bound_predicate.span.from_expansion();
             if let TyKind::Path(QPath::Resolved(_, Path { segments, .. })) = bound_predicate.bounded_ty.kind;
             if let Some(segment) = segments.first();
-            if let Some(trait_resolutions_direct) = map.get(&segment.ident);
             then {
-                for (res_where, _,  _) in bound_predicate.bounds.iter().filter_map(get_trait_info_from_bound) {
-                    if let Some((_, _, span_direct)) = trait_resolutions_direct
+                for (res_where, _, span_where) in bound_predicate.bounds.iter().filter_map(get_trait_info_from_bound) {
+                    let trait_resolutions_direct = map.entry(segment.ident).or_default();
+                    if let Some((_, span_direct)) = trait_resolutions_direct
                                                 .iter()
-                                                .find(|(res_direct, _, _)| *res_direct == res_where) {
+                                                .find(|(res_direct, _)| *res_direct == res_where) {
                         span_lint_and_help(
                             cx,
                             TRAIT_DUPLICATION_IN_BOUNDS,
@@ -254,6 +241,9 @@ fn check_trait_bound_duplication(cx: &LateContext<'_>, gen: &'_ Generics<'_>) {
                             "consider removing this trait bound",
                         );
                     }
+                    else {
+                        trait_resolutions_direct.push((res_where, span_where));
+                    }
                 }
             }
         }
diff --git a/clippy_lints/src/types/borrowed_box.rs b/clippy_lints/src/types/borrowed_box.rs
index 7c06906293b..f35f44eda56 100644
--- a/clippy_lints/src/types/borrowed_box.rs
+++ b/clippy_lints/src/types/borrowed_box.rs
@@ -104,8 +104,10 @@ fn get_bounds_if_impl_trait<'tcx>(cx: &LateContext<'tcx>, qpath: &QPath<'_>, id:
         if let Some(Node::GenericParam(generic_param)) = cx.tcx.hir().get_if_local(did);
         if let GenericParamKind::Type { synthetic, .. } = generic_param.kind;
         if synthetic;
+        if let Some(generics) = cx.tcx.hir().get_generics(id.owner);
+        if let Some(pred) = generics.bounds_for_param(did.expect_local()).next();
         then {
-            Some(generic_param.bounds)
+            Some(pred.bounds)
         } else {
             None
         }
diff --git a/clippy_lints/src/undocumented_unsafe_blocks.rs b/clippy_lints/src/undocumented_unsafe_blocks.rs
index bc57e9b992c..465d8a914fb 100644
--- a/clippy_lints/src/undocumented_unsafe_blocks.rs
+++ b/clippy_lints/src/undocumented_unsafe_blocks.rs
@@ -1,13 +1,13 @@
 use clippy_utils::diagnostics::span_lint_and_help;
 use clippy_utils::is_lint_allowed;
 use clippy_utils::source::walk_span_to_context;
+use rustc_data_structures::sync::Lrc;
 use rustc_hir::{Block, BlockCheckMode, UnsafeSource};
 use rustc_lexer::{tokenize, TokenKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::{BytePos, Pos, SyntaxContext};
-use std::rc::Rc;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -117,7 +117,7 @@ fn block_has_safety_comment(cx: &LateContext<'_>, block: &Block<'_>) -> bool {
         //     ^--------------------------------------------^
         if let Ok(unsafe_line) = source_map.lookup_line(block.span.lo())
             && let Ok(macro_line) = source_map.lookup_line(ctxt.outer_expn_data().def_site.lo())
-            && Rc::ptr_eq(&unsafe_line.sf, &macro_line.sf)
+            && Lrc::ptr_eq(&unsafe_line.sf, &macro_line.sf)
             && let Some(src) = unsafe_line.sf.src.as_deref()
         {
             macro_line.line < unsafe_line.line && text_has_safety_comment(
@@ -133,7 +133,7 @@ fn block_has_safety_comment(cx: &LateContext<'_>, block: &Block<'_>) -> bool {
         && let Some(body) = cx.enclosing_body
         && let Some(body_span) = walk_span_to_context(cx.tcx.hir().body(body).value.span, SyntaxContext::root())
         && let Ok(body_line) = source_map.lookup_line(body_span.lo())
-        && Rc::ptr_eq(&unsafe_line.sf, &body_line.sf)
+        && Lrc::ptr_eq(&unsafe_line.sf, &body_line.sf)
         && let Some(src) = unsafe_line.sf.src.as_deref()
     {
         // Get the text from the start of function body to the unsafe block.
diff --git a/clippy_lints/src/unit_types/let_unit_value.rs b/clippy_lints/src/unit_types/let_unit_value.rs
index 96858fc7f27..f3f1f53aac5 100644
--- a/clippy_lints/src/unit_types/let_unit_value.rs
+++ b/clippy_lints/src/unit_types/let_unit_value.rs
@@ -34,7 +34,7 @@ pub(super) fn check(cx: &LateContext<'_>, stmt: &Stmt<'_>) {
                             diag.span_suggestion(
                                 local.pat.span,
                                 "use a wild (`_`) binding",
-                                "_".into(),
+                                "_",
                                 Applicability::MaybeIncorrect, // snippet
                             );
                     },
diff --git a/clippy_lints/src/unused_async.rs b/clippy_lints/src/unused_async.rs
index 2b89398ecd6..41333bb2add 100644
--- a/clippy_lints/src/unused_async.rs
+++ b/clippy_lints/src/unused_async.rs
@@ -67,7 +67,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedAsync {
         span: Span,
         hir_id: HirId,
     ) {
-        if let FnKind::ItemFn(_, _, FnHeader { asyncness, .. }, _) = &fn_kind {
+        if let FnKind::ItemFn(_, _, FnHeader { asyncness, .. }) = &fn_kind {
             if matches!(asyncness, IsAsync::Async) {
                 let mut visitor = AsyncFnVisitor { cx, found_await: false };
                 walk_fn(&mut visitor, fn_kind, fn_decl, body.id(), span, hir_id);
diff --git a/clippy_lints/src/wildcard_imports.rs b/clippy_lints/src/wildcard_imports.rs
index 832da66a536..2f74eaf3cf5 100644
--- a/clippy_lints/src/wildcard_imports.rs
+++ b/clippy_lints/src/wildcard_imports.rs
@@ -8,6 +8,7 @@ use rustc_hir::{
     Item, ItemKind, PathSegment, UseKind,
 };
 use rustc_lint::{LateContext, LateLintPass};
+use rustc_middle::ty;
 use rustc_session::{declare_tool_lint, impl_lint_pass};
 use rustc_span::symbol::kw;
 use rustc_span::{sym, BytePos};
@@ -115,7 +116,8 @@ impl LateLintPass<'_> for WildcardImports {
         if is_test_module_or_function(cx.tcx, item) {
             self.test_modules_deep = self.test_modules_deep.saturating_add(1);
         }
-        if item.vis.node.is_pub() || item.vis.node.is_pub_restricted() {
+        let module = cx.tcx.parent_module_from_def_id(item.def_id);
+        if cx.tcx.visibility(item.def_id) != ty::Visibility::Restricted(module.to_def_id()) {
             return;
         }
         if_chain! {
diff --git a/clippy_lints/src/write.rs b/clippy_lints/src/write.rs
index f3d818cc348..54b93a20a05 100644
--- a/clippy_lints/src/write.rs
+++ b/clippy_lints/src/write.rs
@@ -13,7 +13,7 @@ use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
 use rustc_parse::parser;
 use rustc_session::{declare_tool_lint, impl_lint_pass};
 use rustc_span::symbol::{kw, Symbol};
-use rustc_span::{sym, BytePos, Span, DUMMY_SP};
+use rustc_span::{sym, BytePos, InnerSpan, Span, DUMMY_SP};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -454,6 +454,7 @@ impl SimpleFormatArgs {
                 }
             },
             ArgumentNamed(n, _) => {
+                let n = Symbol::intern(n);
                 if let Some(x) = self.named.iter_mut().find(|x| x.0 == n) {
                     match x.1.as_slice() {
                         // A non-empty format string has been seen already.
@@ -495,7 +496,7 @@ impl Write {
             let span = parser
                 .arg_places
                 .last()
-                .map_or(DUMMY_SP, |&x| str_lit.span.from_inner(x));
+                .map_or(DUMMY_SP, |&x| str_lit.span.from_inner(InnerSpan::new(x.start, x.end)));
 
             if !self.in_debug_impl && arg.format.ty == "?" {
                 // FIXME: modify rustc's fmt string parser to give us the current span
diff --git a/clippy_utils/src/ast_utils.rs b/clippy_utils/src/ast_utils.rs
index 3fce4987679..7919800483f 100644
--- a/clippy_utils/src/ast_utils.rs
+++ b/clippy_utils/src/ast_utils.rs
@@ -688,7 +688,8 @@ pub fn eq_mac_args(l: &MacArgs, r: &MacArgs) -> bool {
     match (l, r) {
         (Empty, Empty) => true,
         (Delimited(_, ld, lts), Delimited(_, rd, rts)) => ld == rd && lts.eq_unspanned(rts),
-        (Eq(_, lt), Eq(_, rt)) => lt.kind == rt.kind,
+        (Eq(_, MacArgsEq::Ast(le)), Eq(_, MacArgsEq::Ast(re))) => eq_expr(le, re),
+        (Eq(_, MacArgsEq::Hir(ll)), Eq(_, MacArgsEq::Hir(rl))) => ll.kind == rl.kind,
         _ => false,
     }
 }
diff --git a/clippy_utils/src/consts.rs b/clippy_utils/src/consts.rs
index 0e916ca8164..fdb822c3e5b 100644
--- a/clippy_utils/src/consts.rs
+++ b/clippy_utils/src/consts.rs
@@ -179,7 +179,7 @@ impl Constant {
 }
 
 /// Parses a `LitKind` to a `Constant`.
-pub fn lit_to_constant(lit: &LitKind, ty: Option<Ty<'_>>) -> Constant {
+pub fn lit_to_mir_constant(lit: &LitKind, ty: Option<Ty<'_>>) -> Constant {
     match *lit {
         LitKind::Str(ref is, _) => Constant::Str(is.to_string()),
         LitKind::Byte(b) => Constant::Int(u128::from(b)),
@@ -301,7 +301,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
                 if is_direct_expn_of(e.span, "cfg").is_some() {
                     None
                 } else {
-                    Some(lit_to_constant(&lit.node, self.typeck_results.expr_ty_opt(e)))
+                    Some(lit_to_mir_constant(&lit.node, self.typeck_results.expr_ty_opt(e)))
                 }
             },
             ExprKind::Array(vec) => self.multi(vec).map(Constant::Vec),
diff --git a/clippy_utils/src/hir_utils.rs b/clippy_utils/src/hir_utils.rs
index 20206ce82a7..f4da625f1e3 100644
--- a/clippy_utils/src/hir_utils.rs
+++ b/clippy_utils/src/hir_utils.rs
@@ -681,8 +681,10 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
                                 self.hash_expr(out_expr);
                             }
                         },
-                        InlineAsmOperand::Const { anon_const } => self.hash_body(anon_const.body),
-                        InlineAsmOperand::Sym { expr } => self.hash_expr(expr),
+                        InlineAsmOperand::Const { anon_const } | InlineAsmOperand::SymFn { anon_const } => {
+                            self.hash_body(anon_const.body);
+                        },
+                        InlineAsmOperand::SymStatic { path, def_id: _ } => self.hash_qpath(path),
                     }
                 }
             },
diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs
index a275bac4ce6..7d46952d971 100644
--- a/clippy_utils/src/lib.rs
+++ b/clippy_utils/src/lib.rs
@@ -235,7 +235,7 @@ pub fn is_lang_ctor(cx: &LateContext<'_>, qpath: &QPath<'_>, lang_item: LangItem
     if let QPath::Resolved(_, path) = qpath {
         if let Res::Def(DefKind::Ctor(..), ctor_id) = path.res {
             if let Ok(item_id) = cx.tcx.lang_items().require(lang_item) {
-                return cx.tcx.parent(ctor_id) == Some(item_id);
+                return cx.tcx.parent(ctor_id) == item_id;
             }
         }
     }
@@ -1690,7 +1690,7 @@ pub fn if_sequence<'tcx>(mut expr: &'tcx Expr<'tcx>) -> (Vec<&'tcx Expr<'tcx>>,
 
 /// Checks if the given function kind is an async function.
 pub fn is_async_fn(kind: FnKind<'_>) -> bool {
-    matches!(kind, FnKind::ItemFn(_, _, header, _) if header.asyncness == IsAsync::Async)
+    matches!(kind, FnKind::ItemFn(_, _, header) if header.asyncness == IsAsync::Async)
 }
 
 /// Peels away all the compiler generated code surrounding the body of an async function,
diff --git a/clippy_utils/src/paths.rs b/clippy_utils/src/paths.rs
index 4291a5e2299..60971fb716d 100644
--- a/clippy_utils/src/paths.rs
+++ b/clippy_utils/src/paths.rs
@@ -23,7 +23,7 @@ pub const BTREEMAP_ENTRY: [&str; 6] = ["alloc", "collections", "btree", "map", "
 pub const BTREEMAP_INSERT: [&str; 6] = ["alloc", "collections", "btree", "map", "BTreeMap", "insert"];
 pub const CLONE_TRAIT_METHOD: [&str; 4] = ["core", "clone", "Clone", "clone"];
 pub const COW: [&str; 3] = ["alloc", "borrow", "Cow"];
-pub const CSTRING_AS_C_STR: [&str; 5] = ["std", "ffi", "c_str", "CString", "as_c_str"];
+pub const CSTRING_AS_C_STR: [&str; 5] = ["alloc", "ffi", "c_str", "CString", "as_c_str"];
 pub const DEFAULT_TRAIT_METHOD: [&str; 4] = ["core", "default", "Default", "default"];
 pub const DEREF_MUT_TRAIT_METHOD: [&str; 5] = ["core", "ops", "deref", "DerefMut", "deref_mut"];
 /// Preferably use the diagnostic item `sym::deref_method` where possible
diff --git a/clippy_utils/src/qualify_min_const_fn.rs b/clippy_utils/src/qualify_min_const_fn.rs
index 891531951c1..75808b1b174 100644
--- a/clippy_utils/src/qualify_min_const_fn.rs
+++ b/clippy_utils/src/qualify_min_const_fn.rs
@@ -211,7 +211,9 @@ fn check_statement<'tcx>(
 
         StatementKind::FakeRead(box (_, place)) => check_place(tcx, *place, span, body),
         // just an assignment
-        StatementKind::SetDiscriminant { place, .. } => check_place(tcx, **place, span, body),
+        StatementKind::SetDiscriminant { place, .. } | StatementKind::Deinit(place) => {
+            check_place(tcx, **place, span, body)
+        },
 
         StatementKind::CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping { dst, src, count }) => {
             check_operand(tcx, dst, span, body)?;
diff --git a/clippy_utils/src/sugg.rs b/clippy_utils/src/sugg.rs
index ffd2b5aabcf..18915553e61 100644
--- a/clippy_utils/src/sugg.rs
+++ b/clippy_utils/src/sugg.rs
@@ -214,6 +214,7 @@ impl<'a> Sugg<'a> {
             | ast::ExprKind::Path(..)
             | ast::ExprKind::Repeat(..)
             | ast::ExprKind::Ret(..)
+            | ast::ExprKind::Yeet(..)
             | ast::ExprKind::Struct(..)
             | ast::ExprKind::Try(..)
             | ast::ExprKind::TryBlock(..)
diff --git a/rust-toolchain b/rust-toolchain
index bb29c71e9f4..03acb51306d 100644
--- a/rust-toolchain
+++ b/rust-toolchain
@@ -1,3 +1,3 @@
 [toolchain]
-channel = "nightly-2022-04-07"
+channel = "nightly-2022-05-05"
 components = ["cargo", "llvm-tools-preview", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
diff --git a/src/driver.rs b/src/driver.rs
index 00dc916b217..7de40fe63ac 100644
--- a/src/driver.rs
+++ b/src/driver.rs
@@ -165,7 +165,7 @@ fn report_clippy_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) {
     // Separate the output with an empty line
     eprintln!();
 
-    let fallback_bundle = rustc_errors::fallback_fluent_bundle(false).expect("failed to load fallback fluent bundle");
+    let fallback_bundle = rustc_errors::fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false);
     let emitter = Box::new(rustc_errors::emitter::EmitterWriter::stderr(
         rustc_errors::ColorConfig::Auto,
         None,
diff --git a/tests/ui/crashes/ice-96721.rs b/tests/ui/crashes/ice-96721.rs
new file mode 100644
index 00000000000..4b3fb764010
--- /dev/null
+++ b/tests/ui/crashes/ice-96721.rs
@@ -0,0 +1,10 @@
+macro_rules! foo {
+    () => {
+        "bar.rs"
+    };
+}
+
+#[path = foo!()] //~ ERROR malformed `path` attribute
+mod abc {}
+
+fn main() {}
diff --git a/tests/ui/crashes/ice-96721.stderr b/tests/ui/crashes/ice-96721.stderr
new file mode 100644
index 00000000000..78c567b8e77
--- /dev/null
+++ b/tests/ui/crashes/ice-96721.stderr
@@ -0,0 +1,8 @@
+error: malformed `path` attribute input
+  --> $DIR/ice-96721.rs:7:1
+   |
+LL | #[path = foo!()] //~ ERROR malformed `path` attribute
+   | ^^^^^^^^^^^^^^^^ help: must be of the form: `#[path = "file"]`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/extra_unused_lifetimes.stderr b/tests/ui/extra_unused_lifetimes.stderr
index 68f02c7ad0f..fcc12d4ce14 100644
--- a/tests/ui/extra_unused_lifetimes.stderr
+++ b/tests/ui/extra_unused_lifetimes.stderr
@@ -7,12 +7,6 @@ LL | fn unused_lt<'a>(x: u8) {}
    = note: `-D clippy::extra-unused-lifetimes` implied by `-D warnings`
 
 error: this lifetime isn't used in the function definition
-  --> $DIR/extra_unused_lifetimes.rs:16:25
-   |
-LL | fn unused_lt_transitive<'a, 'b: 'a>(x: &'b u8) {
-   |                         ^^
-
-error: this lifetime isn't used in the function definition
   --> $DIR/extra_unused_lifetimes.rs:41:10
    |
 LL |     fn x<'a>(&self) {}
@@ -42,5 +36,5 @@ error: this lifetime isn't used in the function definition
 LL |         pub fn something<'c>() -> Self {
    |                          ^^
 
-error: aborting due to 7 previous errors
+error: aborting due to 6 previous errors
 
diff --git a/tests/ui/needless_lifetimes.stderr b/tests/ui/needless_lifetimes.stderr
index ffa152427a9..a488bc01fff 100644
--- a/tests/ui/needless_lifetimes.stderr
+++ b/tests/ui/needless_lifetimes.stderr
@@ -109,12 +109,6 @@ 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:307: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:310:5
    |
 LL |     fn impl_trait_elidable_nested_anonymous_lifetimes<'a>(i: &'a i32, f: impl Fn(&i32) -> &i32) -> &'a i32 {
@@ -192,5 +186,5 @@ error: explicit lifetimes given in parameter types where they could be elided (o
 LL |         fn lifetime_elsewhere_provided<'a>(self: Box<Self>, here: &'a ()) -> &'a () {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 32 previous errors
+error: aborting due to 31 previous errors
 
diff --git a/tests/ui/same_name_method.stderr b/tests/ui/same_name_method.stderr
index c32c3dd9880..cf06eb32e0c 100644
--- a/tests/ui/same_name_method.stderr
+++ b/tests/ui/same_name_method.stderr
@@ -12,6 +12,19 @@ LL |             fn foo() {}
    |             ^^^^^^^^^^^
 
 error: method's name is the same as an existing method in a trait
+  --> $DIR/same_name_method.rs:34:13
+   |
+LL |             fn clone() {}
+   |             ^^^^^^^^^^^^^
+   |
+note: existing `clone` defined here
+  --> $DIR/same_name_method.rs:30:18
+   |
+LL |         #[derive(Clone)]
+   |                  ^^^^^
+   = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: method's name is the same as an existing method in a trait
   --> $DIR/same_name_method.rs:44:13
    |
 LL |             fn foo() {}
@@ -47,18 +60,5 @@ note: existing `foo` defined here
 LL |         impl T1 for S {}
    |         ^^^^^^^^^^^^^^^^
 
-error: method's name is the same as an existing method in a trait
-  --> $DIR/same_name_method.rs:34:13
-   |
-LL |             fn clone() {}
-   |             ^^^^^^^^^^^^^
-   |
-note: existing `clone` defined here
-  --> $DIR/same_name_method.rs:30:18
-   |
-LL |         #[derive(Clone)]
-   |                  ^^^^^
-   = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
-
 error: aborting due to 5 previous errors
 
diff --git a/tests/ui/trait_duplication_in_bounds.rs b/tests/ui/trait_duplication_in_bounds.rs
index f5ca91143af..a21d4c5d637 100644
--- a/tests/ui/trait_duplication_in_bounds.rs
+++ b/tests/ui/trait_duplication_in_bounds.rs
@@ -95,4 +95,7 @@ trait FooIter: Iterator<Item = Foo> {
     }
 }
 
+// This should not lint
+fn impl_trait(_: impl AsRef<str>, _: impl AsRef<str>) {}
+
 fn main() {}
diff --git a/tests/ui/trait_duplication_in_bounds.stderr b/tests/ui/trait_duplication_in_bounds.stderr
index 6f8c8e47dfb..d0a4cfb8837 100644
--- a/tests/ui/trait_duplication_in_bounds.stderr
+++ b/tests/ui/trait_duplication_in_bounds.stderr
@@ -67,5 +67,13 @@ LL |         Self: Iterator<Item = Foo>,
    |
    = help: consider removing this trait bound
 
-error: aborting due to 8 previous errors
+error: this trait bound is already specified in the where clause
+  --> $DIR/trait_duplication_in_bounds.rs:99:23
+   |
+LL | fn impl_trait(_: impl AsRef<str>, _: impl AsRef<str>) {}
+   |                       ^^^^^^^^^^
+   |
+   = help: consider removing this trait bound
+
+error: aborting due to 9 previous errors
 
diff --git a/tests/ui/type_repetition_in_bounds.rs b/tests/ui/type_repetition_in_bounds.rs
index fc740ee11d6..d11432f9046 100644
--- a/tests/ui/type_repetition_in_bounds.rs
+++ b/tests/ui/type_repetition_in_bounds.rs
@@ -79,4 +79,7 @@ where
     u: U,
 }
 
+// This should not lint
+fn impl_trait(_: impl AsRef<str>, _: impl AsRef<str>) {}
+
 fn main() {}
diff --git a/tests/ui/type_repetition_in_bounds.stderr b/tests/ui/type_repetition_in_bounds.stderr
index 148c19c7d07..abc25e59496 100644
--- a/tests/ui/type_repetition_in_bounds.stderr
+++ b/tests/ui/type_repetition_in_bounds.stderr
@@ -19,5 +19,13 @@ LL |     Self: Copy + Default + Ord,
    |
    = help: consider combining the bounds: `Self: Clone + Copy + Default + Ord`
 
-error: aborting due to 2 previous errors
+error: this type has already been used as a bound predicate
+  --> $DIR/type_repetition_in_bounds.rs:83:43
+   |
+LL | fn impl_trait(_: impl AsRef<str>, _: impl AsRef<str>) {}
+   |                                           ^^^^^^^^^^
+   |
+   = help: consider combining the bounds: `impl AsRef<str>: AsRef<str> + AsRef<str>`
+
+error: aborting due to 3 previous errors
 
diff --git a/tests/ui/unused_unit.stderr b/tests/ui/unused_unit.stderr
index 02038b5fb6b..0d2cb77855b 100644
--- a/tests/ui/unused_unit.stderr
+++ b/tests/ui/unused_unit.stderr
@@ -1,8 +1,8 @@
 error: unneeded unit return type
-  --> $DIR/unused_unit.rs:19:28
+  --> $DIR/unused_unit.rs:19:58
    |
 LL |     pub fn get_unit<F: Fn() -> (), G>(&self, f: F, _g: G) -> ()
-   |                            ^^^^^^ help: remove the `-> ()`
+   |                                                          ^^^^^^ help: remove the `-> ()`
    |
 note: the lint level is defined here
   --> $DIR/unused_unit.rs:12:9
@@ -11,16 +11,16 @@ LL | #![deny(clippy::unused_unit)]
    |         ^^^^^^^^^^^^^^^^^^^
 
 error: unneeded unit return type
-  --> $DIR/unused_unit.rs:20:18
+  --> $DIR/unused_unit.rs:19:28
    |
-LL |     where G: Fn() -> () {
-   |                  ^^^^^^ help: remove the `-> ()`
+LL |     pub fn get_unit<F: Fn() -> (), G>(&self, f: F, _g: G) -> ()
+   |                            ^^^^^^ help: remove the `-> ()`
 
 error: unneeded unit return type
-  --> $DIR/unused_unit.rs:19:58
+  --> $DIR/unused_unit.rs:20:18
    |
-LL |     pub fn get_unit<F: Fn() -> (), G>(&self, f: F, _g: G) -> ()
-   |                                                          ^^^^^^ help: remove the `-> ()`
+LL |     where G: Fn() -> () {
+   |                  ^^^^^^ help: remove the `-> ()`
 
 error: unneeded unit return type
   --> $DIR/unused_unit.rs:21:26