about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-12-30 13:22:47 +0000
committerbors <bors@rust-lang.org>2021-12-30 13:22:47 +0000
commit0eff589afc83e21a03a168497bbab6b4dfbb4ef6 (patch)
tree6f152609abd712912fd88ce0b0486dc267b0c183
parentc1cd64b9c6b29ed2a577fc174a50c76267a966e2 (diff)
parentb0f9894491a0d71e60d36871a7c6b45c96eb0a2b (diff)
downloadrust-0eff589afc83e21a03a168497bbab6b4dfbb4ef6.tar.gz
rust-0eff589afc83e21a03a168497bbab6b4dfbb4ef6.zip
Auto merge of #8196 - flip1995:rustup, r=flip1995
Rustup

r? `@ghost`

changelog: none
-rw-r--r--clippy_lints/src/approx_const.rs2
-rw-r--r--clippy_lints/src/attrs.rs18
-rw-r--r--clippy_lints/src/booleans.rs2
-rw-r--r--clippy_lints/src/checked_conversions.rs8
-rw-r--r--clippy_lints/src/doc.rs2
-rw-r--r--clippy_lints/src/duration_subsec.rs2
-rw-r--r--clippy_lints/src/enum_variants.rs10
-rw-r--r--clippy_lints/src/equatable_if_let.rs16
-rw-r--r--clippy_lints/src/float_literal.rs4
-rw-r--r--clippy_lints/src/floating_point_arithmetic.rs4
-rw-r--r--clippy_lints/src/implicit_saturating_sub.rs6
-rw-r--r--clippy_lints/src/iter_not_returning_iterator.rs2
-rw-r--r--clippy_lints/src/len_zero.rs2
-rw-r--r--clippy_lints/src/loops/mod.rs2
-rw-r--r--clippy_lints/src/loops/needless_collect.rs4
-rw-r--r--clippy_lints/src/loops/never_loop.rs2
-rw-r--r--clippy_lints/src/manual_assert.rs2
-rw-r--r--clippy_lints/src/match_str_case_mismatch.rs16
-rw-r--r--clippy_lints/src/matches.rs4
-rw-r--r--clippy_lints/src/methods/manual_saturating_arithmetic.rs2
-rw-r--r--clippy_lints/src/methods/mod.rs18
-rw-r--r--clippy_lints/src/methods/str_splitn.rs4
-rw-r--r--clippy_lints/src/methods/utils.rs2
-rw-r--r--clippy_lints/src/misc.rs4
-rw-r--r--clippy_lints/src/missing_enforced_import_rename.rs2
-rw-r--r--clippy_lints/src/multiple_crate_versions.rs4
-rw-r--r--clippy_lints/src/mut_reference.rs2
-rw-r--r--clippy_lints/src/needless_option_as_deref.rs2
-rw-r--r--clippy_lints/src/non_expressive_names.rs8
-rw-r--r--clippy_lints/src/nonstandard_macro_braces.rs2
-rw-r--r--clippy_lints/src/open_options.rs2
-rw-r--r--clippy_lints/src/path_buf_push_overwrite.rs2
-rw-r--r--clippy_lints/src/pattern_type_mismatch.rs6
-rw-r--r--clippy_lints/src/regex.rs2
-rw-r--r--clippy_lints/src/serde_api.rs2
-rw-r--r--clippy_lints/src/shadow.rs4
-rw-r--r--clippy_lints/src/stable_sort_primitive.rs2
-rw-r--r--clippy_lints/src/strings.rs2
-rw-r--r--clippy_lints/src/tabs_in_doc_comments.rs2
-rw-r--r--clippy_lints/src/unit_types/unit_cmp.rs2
-rw-r--r--clippy_lints/src/unsafe_removed_from_name.rs2
-rw-r--r--clippy_lints/src/unused_io_amount.rs6
-rw-r--r--clippy_lints/src/unused_unit.rs2
-rw-r--r--clippy_lints/src/unwrap.rs4
-rw-r--r--clippy_lints/src/upper_case_acronyms.rs4
-rw-r--r--clippy_lints/src/useless_conversion.rs2
-rw-r--r--clippy_lints/src/utils/author.rs17
-rw-r--r--clippy_lints/src/utils/inspector.rs7
-rw-r--r--clippy_lints/src/utils/internal_lints.rs20
-rw-r--r--clippy_lints/src/write.rs10
-rw-r--r--clippy_utils/src/attrs.rs2
-rw-r--r--clippy_utils/src/consts.rs4
-rw-r--r--clippy_utils/src/eager_or_lazy.rs2
-rw-r--r--clippy_utils/src/higher.rs14
-rw-r--r--clippy_utils/src/hir_utils.rs13
-rw-r--r--clippy_utils/src/lib.rs4
-rw-r--r--clippy_utils/src/qualify_min_const_fn.rs2
-rw-r--r--rust-toolchain2
-rw-r--r--tests/ui/author/if.stdout6
-rw-r--r--tests/ui/missing_panics_doc.stderr2
60 files changed, 168 insertions, 141 deletions
diff --git a/clippy_lints/src/approx_const.rs b/clippy_lints/src/approx_const.rs
index 12435eefbc4..5061c9d1eaf 100644
--- a/clippy_lints/src/approx_const.rs
+++ b/clippy_lints/src/approx_const.rs
@@ -87,7 +87,7 @@ impl ApproxConstant {
         let s = s.as_str();
         if s.parse::<f64>().is_ok() {
             for &(constant, name, min_digits, msrv) in &KNOWN_CONSTS {
-                if is_approx_const(constant, &s, min_digits)
+                if is_approx_const(constant, s, min_digits)
                     && msrv.as_ref().map_or(true, |msrv| meets_msrv(self.msrv.as_ref(), msrv))
                 {
                     span_lint_and_help(
diff --git a/clippy_lints/src/attrs.rs b/clippy_lints/src/attrs.rs
index 1edb7c950e7..0629674307b 100644
--- a/clippy_lints/src/attrs.rs
+++ b/clippy_lints/src/attrs.rs
@@ -17,7 +17,7 @@ use rustc_semver::RustcVersion;
 use rustc_session::{declare_lint_pass, declare_tool_lint, impl_lint_pass};
 use rustc_span::source_map::Span;
 use rustc_span::sym;
-use rustc_span::symbol::{Symbol, SymbolStr};
+use rustc_span::symbol::Symbol;
 use semver::Version;
 
 static UNIX_SYSTEMS: &[&str] = &[
@@ -310,8 +310,10 @@ impl<'tcx> LateLintPass<'tcx> for Attributes {
                                             || is_word(lint, sym::deprecated)
                                             || is_word(lint, sym!(unreachable_pub))
                                             || is_word(lint, sym!(unused))
-                                            || extract_clippy_lint(lint).map_or(false, |s| s == "wildcard_imports")
-                                            || extract_clippy_lint(lint).map_or(false, |s| s == "enum_glob_use")
+                                            || extract_clippy_lint(lint)
+                                                .map_or(false, |s| s.as_str() == "wildcard_imports")
+                                            || extract_clippy_lint(lint)
+                                                .map_or(false, |s| s.as_str() == "enum_glob_use")
                                         {
                                             return;
                                         }
@@ -370,7 +372,7 @@ impl<'tcx> LateLintPass<'tcx> for Attributes {
 }
 
 /// Returns the lint name if it is clippy lint.
-fn extract_clippy_lint(lint: &NestedMetaItem) -> Option<SymbolStr> {
+fn extract_clippy_lint(lint: &NestedMetaItem) -> Option<Symbol> {
     if_chain! {
         if let Some(meta_item) = lint.meta_item();
         if meta_item.path.segments.len() > 1;
@@ -378,7 +380,7 @@ fn extract_clippy_lint(lint: &NestedMetaItem) -> Option<SymbolStr> {
         if tool_name.name == sym::clippy;
         then {
             let lint_name = meta_item.path.segments.last().unwrap().ident.name;
-            return Some(lint_name.as_str());
+            return Some(lint_name);
         }
     }
     None
@@ -387,7 +389,7 @@ fn extract_clippy_lint(lint: &NestedMetaItem) -> Option<SymbolStr> {
 fn check_clippy_lint_names(cx: &LateContext<'_>, name: Symbol, items: &[NestedMetaItem]) {
     for lint in items {
         if let Some(lint_name) = extract_clippy_lint(lint) {
-            if lint_name == "restriction" && name != sym::allow {
+            if lint_name.as_str() == "restriction" && name != sym::allow {
                 span_lint_and_help(
                     cx,
                     BLANKET_CLIPPY_RESTRICTION_LINTS,
@@ -486,7 +488,7 @@ fn check_attrs(cx: &LateContext<'_>, span: Span, name: Symbol, attrs: &[Attribut
 
 fn check_semver(cx: &LateContext<'_>, span: Span, lit: &Lit) {
     if let LitKind::Str(is, _) = lit.kind {
-        if Version::parse(&is.as_str()).is_ok() {
+        if Version::parse(is.as_str()).is_ok() {
             return;
         }
     }
@@ -619,7 +621,7 @@ fn check_mismatched_target_os(cx: &EarlyContext<'_>, attr: &Attribute) {
                     MetaItemKind::Word => {
                         if_chain! {
                             if let Some(ident) = meta.ident();
-                            if let Some(os) = find_os(&*ident.name.as_str());
+                            if let Some(os) = find_os(ident.name.as_str());
                             then {
                                 mismatched.push((os, ident.span));
                             }
diff --git a/clippy_lints/src/booleans.rs b/clippy_lints/src/booleans.rs
index 51835ee7488..43ad0f7605c 100644
--- a/clippy_lints/src/booleans.rs
+++ b/clippy_lints/src/booleans.rs
@@ -272,7 +272,7 @@ fn simplify_not(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<String> {
                 .copied()
                 .flat_map(|(a, b)| vec![(a, b), (b, a)])
                 .find(|&(a, _)| {
-                    let path: &str = &path.ident.name.as_str();
+                    let path: &str = path.ident.name.as_str();
                     a == path
                 })
                 .and_then(|(_, neg_method)| Some(format!("{}.{}()", snippet_opt(cx, args[0].span)?, neg_method)))
diff --git a/clippy_lints/src/checked_conversions.rs b/clippy_lints/src/checked_conversions.rs
index ffe6340bd77..31cc3698592 100644
--- a/clippy_lints/src/checked_conversions.rs
+++ b/clippy_lints/src/checked_conversions.rs
@@ -321,8 +321,8 @@ fn get_implementing_type<'a>(path: &QPath<'_>, candidates: &'a [&str], function:
         if let TyKind::Path(QPath::Resolved(None, tp)) = &ty.kind;
         if let [int] = &*tp.segments;
         then {
-            let name = &int.ident.name.as_str();
-            candidates.iter().find(|c| name == *c).copied()
+            let name = int.ident.name.as_str();
+            candidates.iter().find(|c| &name == *c).copied()
         } else {
             None
         }
@@ -335,8 +335,8 @@ fn int_ty_to_sym<'tcx>(path: &QPath<'_>) -> Option<&'tcx str> {
         if let QPath::Resolved(_, path) = *path;
         if let [ty] = &*path.segments;
         then {
-            let name = &ty.ident.name.as_str();
-            INTS.iter().find(|c| name == *c).copied()
+            let name = ty.ident.name.as_str();
+            INTS.iter().find(|c| &name == *c).copied()
         } else {
             None
         }
diff --git a/clippy_lints/src/doc.rs b/clippy_lints/src/doc.rs
index 2cdd59c5691..3650e4f91a0 100644
--- a/clippy_lints/src/doc.rs
+++ b/clippy_lints/src/doc.rs
@@ -437,7 +437,7 @@ fn check_attrs<'a>(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, attrs
 
     for attr in attrs {
         if let AttrKind::DocComment(comment_kind, comment) = attr.kind {
-            let (comment, current_spans) = strip_doc_comment_decoration(&comment.as_str(), comment_kind, attr.span);
+            let (comment, current_spans) = strip_doc_comment_decoration(comment.as_str(), comment_kind, attr.span);
             spans.extend_from_slice(&current_spans);
             doc.push_str(&comment);
         } else if attr.has_name(sym::doc) {
diff --git a/clippy_lints/src/duration_subsec.rs b/clippy_lints/src/duration_subsec.rs
index 3070d105014..50dd0d84fda 100644
--- a/clippy_lints/src/duration_subsec.rs
+++ b/clippy_lints/src/duration_subsec.rs
@@ -49,7 +49,7 @@ impl<'tcx> LateLintPass<'tcx> for DurationSubsec {
             if match_type(cx, cx.typeck_results().expr_ty(&args[0]).peel_refs(), &paths::DURATION);
             if let Some((Constant::Int(divisor), _)) = constant(cx, cx.typeck_results(), right);
             then {
-                let suggested_fn = match (method_path.ident.as_str().as_ref(), divisor) {
+                let suggested_fn = match (method_path.ident.as_str(), divisor) {
                     ("subsec_micros", 1_000) | ("subsec_nanos", 1_000_000) => "subsec_millis",
                     ("subsec_nanos", 1_000) => "subsec_micros",
                     _ => return,
diff --git a/clippy_lints/src/enum_variants.rs b/clippy_lints/src/enum_variants.rs
index 6e1fa836b8f..4f89e567430 100644
--- a/clippy_lints/src/enum_variants.rs
+++ b/clippy_lints/src/enum_variants.rs
@@ -130,7 +130,7 @@ fn check_enum_start(cx: &LateContext<'_>, item_name: &str, variant: &Variant<'_>
     let name = variant.ident.name.as_str();
     let item_name_chars = item_name.chars().count();
 
-    if count_match_start(item_name, &name).char_count == item_name_chars
+    if count_match_start(item_name, name).char_count == item_name_chars
         && name.chars().nth(item_name_chars).map_or(false, |c| !c.is_lowercase())
         && name.chars().nth(item_name_chars + 1).map_or(false, |c| !c.is_numeric())
     {
@@ -147,7 +147,7 @@ fn check_enum_end(cx: &LateContext<'_>, item_name: &str, variant: &Variant<'_>)
     let name = variant.ident.name.as_str();
     let item_name_chars = item_name.chars().count();
 
-    if count_match_end(item_name, &name).char_count == item_name_chars {
+    if count_match_end(item_name, name).char_count == item_name_chars {
         span_lint(
             cx,
             ENUM_VARIANT_NAMES,
@@ -171,7 +171,7 @@ fn check_variant(cx: &LateContext<'_>, threshold: u64, def: &EnumDef<'_>, item_n
         check_enum_end(cx, item_name, var);
         let name = var.ident.name.as_str();
 
-        let variant_split = camel_case_split(&name);
+        let variant_split = camel_case_split(name);
 
         pre = pre
             .iter()
@@ -240,7 +240,7 @@ impl LateLintPass<'_> for EnumVariantNames {
     #[allow(clippy::similar_names)]
     fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
         let item_name = item.ident.name.as_str();
-        let item_camel = to_camel_case(&item_name);
+        let item_camel = to_camel_case(item_name);
         if !item.span.from_expansion() && is_present_in_source(cx, item.span) {
             if let Some(&(ref mod_name, ref mod_camel)) = self.modules.last() {
                 // constants don't have surrounding modules
@@ -289,7 +289,7 @@ impl LateLintPass<'_> for EnumVariantNames {
         }
         if let ItemKind::Enum(ref def, _) = item.kind {
             if !(self.avoid_breaking_exported_api && cx.access_levels.is_exported(item.def_id)) {
-                check_variant(cx, self.threshold, def, &item_name, item.span);
+                check_variant(cx, self.threshold, def, item_name, item.span);
             }
         }
         self.modules.push((item.ident.name, item_camel));
diff --git a/clippy_lints/src/equatable_if_let.rs b/clippy_lints/src/equatable_if_let.rs
index 8905cc0de45..06d128f5527 100644
--- a/clippy_lints/src/equatable_if_let.rs
+++ b/clippy_lints/src/equatable_if_let.rs
@@ -67,20 +67,20 @@ fn is_structural_partial_eq(cx: &LateContext<'tcx>, ty: Ty<'tcx>, other: Ty<'tcx
 impl<'tcx> LateLintPass<'tcx> for PatternEquality {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
         if_chain! {
-            if let ExprKind::Let(pat, exp, _) = expr.kind;
-            if unary_pattern(pat);
-            let exp_ty = cx.typeck_results().expr_ty(exp);
-            let pat_ty = cx.typeck_results().pat_ty(pat);
+            if let ExprKind::Let(let_expr) = expr.kind;
+            if unary_pattern(let_expr.pat);
+            let exp_ty = cx.typeck_results().expr_ty(let_expr.init);
+            let pat_ty = cx.typeck_results().pat_ty(let_expr.pat);
             if is_structural_partial_eq(cx, exp_ty, pat_ty);
             then {
 
                 let mut applicability = Applicability::MachineApplicable;
-                let pat_str = match pat.kind {
+                let pat_str = match let_expr.pat.kind {
                     PatKind::Struct(..) => format!(
                         "({})",
-                        snippet_with_context(cx, pat.span, expr.span.ctxt(), "..", &mut applicability).0,
+                        snippet_with_context(cx, let_expr.pat.span, expr.span.ctxt(), "..", &mut applicability).0,
                     ),
-                    _ => snippet_with_context(cx, pat.span, expr.span.ctxt(), "..", &mut applicability).0.to_string(),
+                    _ => snippet_with_context(cx, let_expr.pat.span, expr.span.ctxt(), "..", &mut applicability).0.to_string(),
                 };
                 span_lint_and_sugg(
                     cx,
@@ -90,7 +90,7 @@ impl<'tcx> LateLintPass<'tcx> for PatternEquality {
                     "try",
                     format!(
                         "{} == {}",
-                        snippet_with_context(cx, exp.span, expr.span.ctxt(), "..", &mut applicability).0,
+                        snippet_with_context(cx, let_expr.init.span, expr.span.ctxt(), "..", &mut applicability).0,
                         pat_str,
                     ),
                     applicability,
diff --git a/clippy_lints/src/float_literal.rs b/clippy_lints/src/float_literal.rs
index d30dede833c..7a4397a7b74 100644
--- a/clippy_lints/src/float_literal.rs
+++ b/clippy_lints/src/float_literal.rs
@@ -68,12 +68,12 @@ impl<'tcx> LateLintPass<'tcx> for FloatLiteral {
             if let LitKind::Float(sym, lit_float_ty) = lit.node;
             then {
                 let sym_str = sym.as_str();
-                let formatter = FloatFormat::new(&sym_str);
+                let formatter = FloatFormat::new(sym_str);
                 // Try to bail out if the float is for sure fine.
                 // If its within the 2 decimal digits of being out of precision we
                 // check if the parsed representation is the same as the string
                 // since we'll need the truncated string anyway.
-                let digits = count_digits(&sym_str);
+                let digits = count_digits(sym_str);
                 let max = max_digits(fty);
                 let type_suffix = match lit_float_ty {
                     LitFloatType::Suffixed(ast::FloatTy::F32) => Some("f32"),
diff --git a/clippy_lints/src/floating_point_arithmetic.rs b/clippy_lints/src/floating_point_arithmetic.rs
index 4fefd9fd18a..6dcbaf68dfd 100644
--- a/clippy_lints/src/floating_point_arithmetic.rs
+++ b/clippy_lints/src/floating_point_arithmetic.rs
@@ -595,7 +595,7 @@ fn are_same_base_logs(cx: &LateContext<'_>, expr_a: &Expr<'_>, expr_b: &Expr<'_>
             return method_name_a.as_str() == method_name_b.as_str() &&
                 args_a.len() == args_b.len() &&
                 (
-                    ["ln", "log2", "log10"].contains(&&*method_name_a.as_str()) ||
+                    ["ln", "log2", "log10"].contains(&method_name_a.as_str()) ||
                     method_name_a.as_str() == "log" && args_a.len() == 2 && eq_expr_value(cx, &args_a[1], &args_b[1])
                 );
         }
@@ -718,7 +718,7 @@ impl<'tcx> LateLintPass<'tcx> for FloatingPointArithmetic {
             let recv_ty = cx.typeck_results().expr_ty(&args[0]);
 
             if recv_ty.is_floating_point() {
-                match &*path.ident.name.as_str() {
+                match path.ident.name.as_str() {
                     "ln" => check_ln1p(cx, expr, args),
                     "log" => check_log_base(cx, expr, args),
                     "powf" => check_powf(cx, expr, args),
diff --git a/clippy_lints/src/implicit_saturating_sub.rs b/clippy_lints/src/implicit_saturating_sub.rs
index 26a196aab59..6515975fbff 100644
--- a/clippy_lints/src/implicit_saturating_sub.rs
+++ b/clippy_lints/src/implicit_saturating_sub.rs
@@ -96,7 +96,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingSub {
                         if let LitKind::Int(0, _) = cond_lit.node {
                             if cx.typeck_results().expr_ty(cond_left).is_signed() {
                             } else {
-                                print_lint_and_sugg(cx, &var_name, expr);
+                                print_lint_and_sugg(cx, var_name, expr);
                             };
                         }
                     },
@@ -108,7 +108,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingSub {
                             let mut int_ids = INT_TYPES.iter().filter_map(|&ty| cx.tcx.lang_items().require(ty).ok());
                             if int_ids.any(|int_id| int_id == impl_id);
                             then {
-                                print_lint_and_sugg(cx, &var_name, expr)
+                                print_lint_and_sugg(cx, var_name, expr)
                             }
                         }
                     },
@@ -121,7 +121,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingSub {
                             let mut int_ids = INT_TYPES.iter().filter_map(|&ty| cx.tcx.lang_items().require(ty).ok());
                             if int_ids.any(|int_id| int_id == impl_id);
                             then {
-                                print_lint_and_sugg(cx, &var_name, expr)
+                                print_lint_and_sugg(cx, var_name, expr)
                             }
                         }
                     },
diff --git a/clippy_lints/src/iter_not_returning_iterator.rs b/clippy_lints/src/iter_not_returning_iterator.rs
index 968bbc524b2..0af6b3b7d46 100644
--- a/clippy_lints/src/iter_not_returning_iterator.rs
+++ b/clippy_lints/src/iter_not_returning_iterator.rs
@@ -42,7 +42,7 @@ declare_lint_pass!(IterNotReturningIterator => [ITER_NOT_RETURNING_ITERATOR]);
 
 impl LateLintPass<'_> for IterNotReturningIterator {
     fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx ImplItem<'tcx>) {
-        let name: &str = &impl_item.ident.name.as_str();
+        let name = impl_item.ident.name.as_str();
         if_chain! {
             if let ImplItemKind::Fn(fn_sig, _) = &impl_item.kind;
             let ret_ty = return_ty(cx, impl_item.hir_id());
diff --git a/clippy_lints/src/len_zero.rs b/clippy_lints/src/len_zero.rs
index 09cd0d22d8b..20e6220ec7d 100644
--- a/clippy_lints/src/len_zero.rs
+++ b/clippy_lints/src/len_zero.rs
@@ -441,7 +441,7 @@ fn is_empty_string(expr: &Expr<'_>) -> bool {
     if let ExprKind::Lit(ref lit) = expr.kind {
         if let LitKind::Str(lit, _) = lit.node {
             let lit = lit.as_str();
-            return lit == "";
+            return lit.is_empty();
         }
     }
     false
diff --git a/clippy_lints/src/loops/mod.rs b/clippy_lints/src/loops/mod.rs
index e2f9aee063d..b03445b8cd6 100644
--- a/clippy_lints/src/loops/mod.rs
+++ b/clippy_lints/src/loops/mod.rs
@@ -659,7 +659,7 @@ fn check_for_loop_arg(cx: &LateContext<'_>, pat: &Pat<'_>, arg: &Expr<'_>) {
     let mut next_loop_linted = false; // whether or not ITER_NEXT_LOOP lint was used
 
     if let ExprKind::MethodCall(method, _, [self_arg], _) = arg.kind {
-        let method_name = &*method.ident.as_str();
+        let method_name = method.ident.as_str();
         // check for looping over x.iter() or x.iter_mut(), could use &x or &mut x
         match method_name {
             "iter" | "iter_mut" => explicit_iter_loop::check(cx, self_arg, arg, method_name),
diff --git a/clippy_lints/src/loops/needless_collect.rs b/clippy_lints/src/loops/needless_collect.rs
index 6f3acb45ba4..ba895f35faa 100644
--- a/clippy_lints/src/loops/needless_collect.rs
+++ b/clippy_lints/src/loops/needless_collect.rs
@@ -31,7 +31,7 @@ fn check_needless_collect_direct_usage<'tcx>(expr: &'tcx Expr<'_>, cx: &LateCont
             let ty = cx.typeck_results().expr_ty(&args[0]);
             let mut applicability = Applicability::MaybeIncorrect;
             let is_empty_sugg = "next().is_none()".to_string();
-            let method_name = &*method.ident.name.as_str();
+            let method_name = method.ident.name.as_str();
             let sugg = if is_type_diagnostic_item(cx, ty, sym::Vec) ||
                         is_type_diagnostic_item(cx, ty, sym::VecDeque) ||
                         is_type_diagnostic_item(cx, ty, sym::LinkedList) ||
@@ -210,7 +210,7 @@ impl<'tcx> Visitor<'tcx> for IterFunctionVisitor<'_, 'tcx> {
                     if let Some(hir_id) = self.current_statement_hir_id {
                         self.hir_id_uses_map.insert(hir_id, self.uses.len());
                     }
-                    match &*method_name.ident.name.as_str() {
+                    match method_name.ident.name.as_str() {
                         "into_iter" => self.uses.push(Some(IterFunction {
                             func: IterFunctionKind::IntoIter,
                             span: expr.span,
diff --git a/clippy_lints/src/loops/never_loop.rs b/clippy_lints/src/loops/never_loop.rs
index 68ffcd1abfb..a3aa6be6afd 100644
--- a/clippy_lints/src/loops/never_loop.rs
+++ b/clippy_lints/src/loops/never_loop.rs
@@ -115,12 +115,12 @@ fn never_loop_expr(expr: &Expr<'_>, main_loop_id: HirId) -> NeverLoopResult {
         | ExprKind::Unary(_, e)
         | ExprKind::Cast(e, _)
         | ExprKind::Type(e, _)
-        | ExprKind::Let(_, e, _)
         | ExprKind::Field(e, _)
         | ExprKind::AddrOf(_, _, e)
         | ExprKind::Struct(_, _, Some(e))
         | ExprKind::Repeat(e, _)
         | ExprKind::DropTemps(e) => never_loop_expr(e, main_loop_id),
+        ExprKind::Let(let_expr) => never_loop_expr(let_expr.init, main_loop_id),
         ExprKind::Array(es) | ExprKind::MethodCall(_, _, es, _) | ExprKind::Tup(es) => {
             never_loop_expr_all(&mut es.iter(), main_loop_id)
         },
diff --git a/clippy_lints/src/manual_assert.rs b/clippy_lints/src/manual_assert.rs
index ed3166086f7..5a2a965716c 100644
--- a/clippy_lints/src/manual_assert.rs
+++ b/clippy_lints/src/manual_assert.rs
@@ -50,7 +50,7 @@ impl LateLintPass<'_> for ManualAssert {
                 ..
             } = &expr;
             if is_expn_of(stmt.span, "panic").is_some();
-            if !matches!(cond.kind, ExprKind::Let(_, _, _));
+            if !matches!(cond.kind, ExprKind::Let(_));
             if let StmtKind::Semi(semi) = stmt.kind;
             if !cx.tcx.sess.source_map().is_multiline(cond.span);
 
diff --git a/clippy_lints/src/match_str_case_mismatch.rs b/clippy_lints/src/match_str_case_mismatch.rs
index 3316ebf4051..2c0fc218ca0 100644
--- a/clippy_lints/src/match_str_case_mismatch.rs
+++ b/clippy_lints/src/match_str_case_mismatch.rs
@@ -9,7 +9,7 @@ use rustc_middle::hir::map::Map;
 use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty;
 use rustc_session::{declare_lint_pass, declare_tool_lint};
-use rustc_span::symbol::SymbolStr;
+use rustc_span::symbol::Symbol;
 use rustc_span::{sym, Span};
 
 declare_clippy_lint! {
@@ -71,8 +71,8 @@ impl LateLintPass<'_> for MatchStrCaseMismatch {
                 visitor.visit_expr(match_expr);
 
                 if let Some(case_method) = visitor.case_method {
-                    if let Some((bad_case_span, bad_case_str)) = verify_case(&case_method, arms) {
-                        lint(cx, &case_method, bad_case_span, &bad_case_str);
+                    if let Some((bad_case_span, bad_case_sym)) = verify_case(&case_method, arms) {
+                        lint(cx, &case_method, bad_case_span, bad_case_sym.as_str());
                     }
                 }
             }
@@ -94,8 +94,8 @@ impl<'a, 'tcx> Visitor<'tcx> for MatchExprVisitor<'a, 'tcx> {
 
     fn visit_expr(&mut self, ex: &'tcx Expr<'_>) {
         match ex.kind {
-            ExprKind::MethodCall(segment, _, [receiver], _)
-                if self.case_altered(&*segment.ident.as_str(), receiver) => {},
+            ExprKind::MethodCall(segment, _, [receiver], _) if self.case_altered(segment.ident.as_str(), receiver) => {
+            },
             _ => walk_expr(self, ex),
         }
     }
@@ -126,7 +126,7 @@ fn get_case_method(segment_ident_str: &str) -> Option<CaseMethod> {
     }
 }
 
-fn verify_case<'a>(case_method: &'a CaseMethod, arms: &'a [Arm<'_>]) -> Option<(Span, SymbolStr)> {
+fn verify_case<'a>(case_method: &'a CaseMethod, arms: &'a [Arm<'_>]) -> Option<(Span, Symbol)> {
     let case_check = match case_method {
         CaseMethod::LowerCase => |input: &str| -> bool { input.chars().all(|c| c.to_lowercase().next() == Some(c)) },
         CaseMethod::AsciiLowerCase => |input: &str| -> bool { !input.chars().any(|c| c.is_ascii_uppercase()) },
@@ -142,9 +142,9 @@ fn verify_case<'a>(case_method: &'a CaseMethod, arms: &'a [Arm<'_>]) -> Option<(
                             }) = arm.pat.kind;
             if let LitKind::Str(symbol, _) = lit.node;
             let input = symbol.as_str();
-            if !case_check(&input);
+            if !case_check(input);
             then {
-                return Some((lit.span, input));
+                return Some((lit.span, symbol));
             }
         }
     }
diff --git a/clippy_lints/src/matches.rs b/clippy_lints/src/matches.rs
index acac0887226..22970507f96 100644
--- a/clippy_lints/src/matches.rs
+++ b/clippy_lints/src/matches.rs
@@ -966,7 +966,7 @@ fn check_wild_err_arm<'tcx>(cx: &LateContext<'tcx>, ex: &Expr<'tcx>, arms: &[Arm
                         for pat in inner.iter() {
                             if let PatKind::Binding(_, id, ident, None) = pat.kind {
                                 if ident.as_str().starts_with('_') && !is_local_used(cx, arm.body, id) {
-                                    ident_bind_name = (&ident.name.as_str()).to_string();
+                                    ident_bind_name = ident.name.as_str().to_string();
                                     matching_wild = true;
                                 }
                             }
@@ -1127,7 +1127,7 @@ fn check_wild_enum_match(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>])
             if let CommonPrefixSearcher::Path(path_prefix) = path_prefix {
                 let mut s = String::new();
                 for seg in path_prefix {
-                    s.push_str(&seg.ident.as_str());
+                    s.push_str(seg.ident.as_str());
                     s.push_str("::");
                 }
                 s
diff --git a/clippy_lints/src/methods/manual_saturating_arithmetic.rs b/clippy_lints/src/methods/manual_saturating_arithmetic.rs
index 7ecafa1f3ba..4307cbf0050 100644
--- a/clippy_lints/src/methods/manual_saturating_arithmetic.rs
+++ b/clippy_lints/src/methods/manual_saturating_arithmetic.rs
@@ -81,7 +81,7 @@ fn is_min_or_max<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>) -> Option<M
         if args.is_empty();
         if let hir::ExprKind::Path(hir::QPath::TypeRelative(_, segment)) = &func.kind;
         then {
-            match &*segment.ident.as_str() {
+            match segment.ident.as_str() {
                 "max_value" => return Some(MinMax::Max),
                 "min_value" => return Some(MinMax::Min),
                 _ => {}
diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs
index 3c43671dd34..4e33b2ff14c 100644
--- a/clippy_lints/src/methods/mod.rs
+++ b/clippy_lints/src/methods/mod.rs
@@ -80,7 +80,7 @@ use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::{self, TraitRef, Ty, TyS};
 use rustc_semver::RustcVersion;
 use rustc_session::{declare_tool_lint, impl_lint_pass};
-use rustc_span::symbol::SymbolStr;
+use rustc_span::symbol::Symbol;
 use rustc_span::{sym, Span};
 use rustc_typeck::hir_ty_to_ty;
 
@@ -1997,21 +1997,21 @@ impl_lint_pass!(Methods => [
 ]);
 
 /// Extracts a method call name, args, and `Span` of the method name.
-fn method_call<'tcx>(recv: &'tcx hir::Expr<'tcx>) -> Option<(SymbolStr, &'tcx [hir::Expr<'tcx>], Span)> {
+fn method_call<'tcx>(recv: &'tcx hir::Expr<'tcx>) -> Option<(Symbol, &'tcx [hir::Expr<'tcx>], Span)> {
     if let ExprKind::MethodCall(path, span, args, _) = recv.kind {
         if !args.iter().any(|e| e.span.from_expansion()) {
-            return Some((path.ident.name.as_str(), args, span));
+            return Some((path.ident.name, args, span));
         }
     }
     None
 }
 
-/// Same as `method_call` but the `SymbolStr` is dereferenced into a temporary `&str`
+/// Same as `method_call` but the `Symbol` is dereferenced into a temporary `&str`
 macro_rules! method_call {
     ($expr:expr) => {
         method_call($expr)
             .as_ref()
-            .map(|&(ref name, args, span)| (&**name, args, span))
+            .map(|&(ref name, args, span)| (name.as_str(), args, span))
     };
 }
 
@@ -2028,8 +2028,8 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
                 from_iter_instead_of_collect::check(cx, expr, args, func);
             },
             hir::ExprKind::MethodCall(method_call, ref method_span, args, _) => {
-                or_fun_call::check(cx, expr, *method_span, &method_call.ident.as_str(), args);
-                expect_fun_call::check(cx, expr, *method_span, &method_call.ident.as_str(), args);
+                or_fun_call::check(cx, expr, *method_span, method_call.ident.as_str(), args);
+                expect_fun_call::check(cx, expr, *method_span, method_call.ident.as_str(), args);
                 clone_on_copy::check(cx, expr, method_call.ident.name, args);
                 clone_on_ref_ptr::check(cx, expr, method_call.ident.name, args);
                 inefficient_to_string::check(cx, expr, method_call.ident.name, args);
@@ -2112,7 +2112,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
                 {
                     wrong_self_convention::check(
                         cx,
-                        &name,
+                        name,
                         self_ty,
                         first_arg_ty,
                         first_arg.pat.span,
@@ -2184,7 +2184,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
                 let self_ty = TraitRef::identity(cx.tcx, item.def_id.to_def_id()).self_ty().skip_binder();
                 wrong_self_convention::check(
                     cx,
-                    &item.ident.name.as_str(),
+                    item.ident.name.as_str(),
                     self_ty,
                     first_arg_ty,
                     first_arg_span,
diff --git a/clippy_lints/src/methods/str_splitn.rs b/clippy_lints/src/methods/str_splitn.rs
index e5fafdb075c..70f20da1d6d 100644
--- a/clippy_lints/src/methods/str_splitn.rs
+++ b/clippy_lints/src/methods/str_splitn.rs
@@ -140,7 +140,7 @@ fn parse_iter_usage(
             let did = cx.typeck_results().type_dependent_def_id(e.hir_id)?;
             let iter_id = cx.tcx.get_diagnostic_item(sym::Iterator)?;
 
-            match (&*name.ident.as_str(), args) {
+            match (name.ident.as_str(), args) {
                 ("next", []) if cx.tcx.trait_of_item(did) == Some(iter_id) => {
                     if reverse {
                         (IterUsageKind::Second, e.span)
@@ -298,7 +298,7 @@ fn check_iter(
                 if let Some(did) = cx.typeck_results().type_dependent_def_id(e.hir_id);
                 if let Some(iter_id) = cx.tcx.get_diagnostic_item(sym::Iterator);
                 then {
-                    match (&*name.ident.as_str(), args) {
+                    match (name.ident.as_str(), args) {
                         ("next", []) if cx.tcx.trait_of_item(did) == Some(iter_id) => {
                             return true;
                         },
diff --git a/clippy_lints/src/methods/utils.rs b/clippy_lints/src/methods/utils.rs
index 11ad881ee7b..24b44f819f4 100644
--- a/clippy_lints/src/methods/utils.rs
+++ b/clippy_lints/src/methods/utils.rs
@@ -57,7 +57,7 @@ pub(super) fn get_hint_if_single_char_arg(
         let string = r.as_str();
         if string.chars().count() == 1;
         then {
-            let snip = snippet_with_applicability(cx, arg.span, &string, applicability);
+            let snip = snippet_with_applicability(cx, arg.span, string, applicability);
             let ch = if let ast::StrStyle::Raw(nhash) = style {
                 let nhash = nhash as usize;
                 // for raw string: r##"a"##
diff --git a/clippy_lints/src/misc.rs b/clippy_lints/src/misc.rs
index 2299a099910..401dc27811d 100644
--- a/clippy_lints/src/misc.rs
+++ b/clippy_lints/src/misc.rs
@@ -407,6 +407,7 @@ impl<'tcx> LateLintPass<'tcx> for MiscLints {
             // Don't lint things expanded by #[derive(...)], etc or `await` desugaring
             return;
         }
+        let sym;
         let binding = match expr.kind {
             ExprKind::Path(ref qpath) if !matches!(qpath, hir::QPath::LangItem(..)) => {
                 let binding = last_path_segment(qpath).ident.as_str();
@@ -423,7 +424,8 @@ impl<'tcx> LateLintPass<'tcx> for MiscLints {
                 }
             },
             ExprKind::Field(_, ident) => {
-                let name = ident.as_str();
+                sym = ident.name;
+                let name = sym.as_str();
                 if name.starts_with('_') && !name.starts_with("__") {
                     Some(name)
                 } else {
diff --git a/clippy_lints/src/missing_enforced_import_rename.rs b/clippy_lints/src/missing_enforced_import_rename.rs
index 68d49e0f150..566e15ab2a6 100644
--- a/clippy_lints/src/missing_enforced_import_rename.rs
+++ b/clippy_lints/src/missing_enforced_import_rename.rs
@@ -75,7 +75,7 @@ impl LateLintPass<'_> for ImportRename {
             if let Some(import) = match snip.split_once(" as ") {
                 None => Some(snip.as_str()),
                 Some((import, rename)) => {
-                    if rename.trim() == &*name.as_str() {
+                    if rename.trim() == name.as_str() {
                         None
                     } else {
                         Some(import.trim())
diff --git a/clippy_lints/src/multiple_crate_versions.rs b/clippy_lints/src/multiple_crate_versions.rs
index e45cc86d417..1f9db39cf8c 100644
--- a/clippy_lints/src/multiple_crate_versions.rs
+++ b/clippy_lints/src/multiple_crate_versions.rs
@@ -48,7 +48,7 @@ impl LateLintPass<'_> for MultipleCrateVersions {
         }
 
         let metadata = unwrap_cargo_metadata!(cx, MULTIPLE_CRATE_VERSIONS, true);
-        let local_name = cx.tcx.crate_name(LOCAL_CRATE).as_str();
+        let local_name = cx.tcx.crate_name(LOCAL_CRATE);
         let mut packages = metadata.packages;
         packages.sort_by(|a, b| a.name.cmp(&b.name));
 
@@ -56,7 +56,7 @@ impl LateLintPass<'_> for MultipleCrateVersions {
             if let Some(resolve) = &metadata.resolve;
             if let Some(local_id) = packages
                 .iter()
-                .find_map(|p| if p.name == *local_name { Some(&p.id) } else { None });
+                .find_map(|p| if p.name == local_name.as_str() { Some(&p.id) } else { None });
             then {
                 for (name, group) in &packages.iter().group_by(|p| p.name.clone()) {
                     let group: Vec<&Package> = group.collect();
diff --git a/clippy_lints/src/mut_reference.rs b/clippy_lints/src/mut_reference.rs
index 63a1cf7b7d5..22834cf61ee 100644
--- a/clippy_lints/src/mut_reference.rs
+++ b/clippy_lints/src/mut_reference.rs
@@ -49,7 +49,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryMutPassed {
                 let def_id = cx.typeck_results().type_dependent_def_id(e.hir_id).unwrap();
                 let substs = cx.typeck_results().node_substs(e.hir_id);
                 let method_type = cx.tcx.type_of(def_id).subst(cx.tcx, substs);
-                check_arguments(cx, arguments, method_type, &path.ident.as_str(), "method");
+                check_arguments(cx, arguments, method_type, path.ident.as_str(), "method");
             },
             _ => (),
         }
diff --git a/clippy_lints/src/needless_option_as_deref.rs b/clippy_lints/src/needless_option_as_deref.rs
index a28b08c33ec..0931fec149e 100644
--- a/clippy_lints/src/needless_option_as_deref.rs
+++ b/clippy_lints/src/needless_option_as_deref.rs
@@ -48,7 +48,7 @@ impl<'tcx> LateLintPass<'tcx> for OptionNeedlessDeref {
             if is_type_diagnostic_item(cx,outer_ty,sym::Option);
             if let ExprKind::MethodCall(path, _, [sub_expr], _) = expr.kind;
             let symbol = path.ident.as_str();
-            if symbol=="as_deref" || symbol=="as_deref_mut";
+            if symbol == "as_deref" || symbol == "as_deref_mut";
             if TyS::same_type( outer_ty, typeck.expr_ty(sub_expr) );
             then{
                 span_lint_and_sugg(
diff --git a/clippy_lints/src/non_expressive_names.rs b/clippy_lints/src/non_expressive_names.rs
index 5559fac0a8a..39a37e3e378 100644
--- a/clippy_lints/src/non_expressive_names.rs
+++ b/clippy_lints/src/non_expressive_names.rs
@@ -218,20 +218,20 @@ impl<'a, 'tcx, 'b> SimilarNamesNameVisitor<'a, 'tcx, 'b> {
             return;
         }
         for existing_name in &self.0.names {
-            if allowed_to_be_similar(&interned_name, existing_name.exemptions) {
+            if allowed_to_be_similar(interned_name, existing_name.exemptions) {
                 continue;
             }
             match existing_name.len.cmp(&count) {
                 Ordering::Greater => {
                     if existing_name.len - count != 1
-                        || levenstein_not_1(&interned_name, &existing_name.interned.as_str())
+                        || levenstein_not_1(interned_name, existing_name.interned.as_str())
                     {
                         continue;
                     }
                 },
                 Ordering::Less => {
                     if count - existing_name.len != 1
-                        || levenstein_not_1(&existing_name.interned.as_str(), &interned_name)
+                        || levenstein_not_1(existing_name.interned.as_str(), interned_name)
                     {
                         continue;
                     }
@@ -298,7 +298,7 @@ impl<'a, 'tcx, 'b> SimilarNamesNameVisitor<'a, 'tcx, 'b> {
             return;
         }
         self.0.names.push(ExistingName {
-            exemptions: get_exemptions(&interned_name).unwrap_or(&[]),
+            exemptions: get_exemptions(interned_name).unwrap_or(&[]),
             interned: ident.name,
             span: ident.span,
             len: count,
diff --git a/clippy_lints/src/nonstandard_macro_braces.rs b/clippy_lints/src/nonstandard_macro_braces.rs
index a04d589f880..4722c031006 100644
--- a/clippy_lints/src/nonstandard_macro_braces.rs
+++ b/clippy_lints/src/nonstandard_macro_braces.rs
@@ -104,7 +104,7 @@ fn is_offending_macro<'a>(cx: &EarlyContext<'_>, span: Span, mac_braces: &'a Mac
     };
     if_chain! {
         if let ExpnKind::Macro(MacroKind::Bang, mac_name) = span.ctxt().outer_expn_data().kind;
-        let name = &*mac_name.as_str();
+        let name = mac_name.as_str();
         if let Some(braces) = mac_braces.macro_braces.get(name);
         if let Some(snip) = snippet_opt(cx, span.ctxt().outer_expn_data().call_site);
         // we must check only invocation sites
diff --git a/clippy_lints/src/open_options.rs b/clippy_lints/src/open_options.rs
index 2c77100bdcf..1b9285c2298 100644
--- a/clippy_lints/src/open_options.rs
+++ b/clippy_lints/src/open_options.rs
@@ -82,7 +82,7 @@ fn get_open_options(cx: &LateContext<'_>, argument: &Expr<'_>, options: &mut Vec
                 _ => Argument::Unknown,
             };
 
-            match &*path.ident.as_str() {
+            match path.ident.as_str() {
                 "create" => {
                     options.push((OpenOption::Create, argument_option));
                 },
diff --git a/clippy_lints/src/path_buf_push_overwrite.rs b/clippy_lints/src/path_buf_push_overwrite.rs
index 8ebee9bd04d..e58ca95fa04 100644
--- a/clippy_lints/src/path_buf_push_overwrite.rs
+++ b/clippy_lints/src/path_buf_push_overwrite.rs
@@ -53,7 +53,7 @@ impl<'tcx> LateLintPass<'tcx> for PathBufPushOverwrite {
             if let Some(get_index_arg) = args.get(1);
             if let ExprKind::Lit(ref lit) = get_index_arg.kind;
             if let LitKind::Str(ref path_lit, _) = lit.node;
-            if let pushed_path = Path::new(&*path_lit.as_str());
+            if let pushed_path = Path::new(path_lit.as_str());
             if let Some(pushed_path_lit) = pushed_path.to_str();
             if pushed_path.has_root();
             if let Some(root) = pushed_path.components().next();
diff --git a/clippy_lints/src/pattern_type_mismatch.rs b/clippy_lints/src/pattern_type_mismatch.rs
index c7d77d30927..be319ee110d 100644
--- a/clippy_lints/src/pattern_type_mismatch.rs
+++ b/clippy_lints/src/pattern_type_mismatch.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_help;
 use rustc_hir::{
-    intravisit, Body, Expr, ExprKind, FnDecl, HirId, LocalSource, Mutability, Pat, PatKind, Stmt, StmtKind,
+    intravisit, Body, Expr, ExprKind, FnDecl, HirId, Let, LocalSource, Mutability, Pat, PatKind, Stmt, StmtKind,
 };
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
@@ -104,8 +104,8 @@ impl<'tcx> LateLintPass<'tcx> for PatternTypeMismatch {
                 }
             }
         }
-        if let ExprKind::Let(let_pat, ..) = expr.kind {
-            apply_lint(cx, let_pat, DerefPossible::Possible);
+        if let ExprKind::Let(Let { pat, .. }) = expr.kind {
+            apply_lint(cx, pat, DerefPossible::Possible);
         }
     }
 
diff --git a/clippy_lints/src/regex.rs b/clippy_lints/src/regex.rs
index 8e5983b4773..b6d04334de9 100644
--- a/clippy_lints/src/regex.rs
+++ b/clippy_lints/src/regex.rs
@@ -150,7 +150,7 @@ fn check_regex<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, utf8: bool) {
 
     if let ExprKind::Lit(ref lit) = expr.kind {
         if let LitKind::Str(ref r, style) = lit.node {
-            let r = &r.as_str();
+            let r = r.as_str();
             let offset = if let StrStyle::Raw(n) = style { 2 + n } else { 1 };
             match parser.parse(r) {
                 Ok(r) => {
diff --git a/clippy_lints/src/serde_api.rs b/clippy_lints/src/serde_api.rs
index a38b3c4ab69..398e2c200de 100644
--- a/clippy_lints/src/serde_api.rs
+++ b/clippy_lints/src/serde_api.rs
@@ -37,7 +37,7 @@ impl<'tcx> LateLintPass<'tcx> for SerdeApi {
                     let mut seen_str = None;
                     let mut seen_string = None;
                     for item in items {
-                        match &*item.ident.as_str() {
+                        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 516cb939c15..ce05c5a6164 100644
--- a/clippy_lints/src/shadow.rs
+++ b/clippy_lints/src/shadow.rs
@@ -5,7 +5,7 @@ use rustc_data_structures::fx::FxHashMap;
 use rustc_hir::def::Res;
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::hir_id::ItemLocalId;
-use rustc_hir::{Block, Body, BodyOwnerKind, Expr, ExprKind, HirId, Node, Pat, PatKind, QPath, UnOp};
+use rustc_hir::{Block, Body, BodyOwnerKind, Expr, ExprKind, HirId, Let, Node, Pat, PatKind, QPath, UnOp};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::{declare_tool_lint, impl_lint_pass};
 use rustc_span::{Span, Symbol};
@@ -227,7 +227,7 @@ fn find_init<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option<&'tcx Expr<'
         let init = match node {
             Node::Arm(_) | Node::Pat(_) => continue,
             Node::Expr(expr) => match expr.kind {
-                ExprKind::Match(e, _, _) | ExprKind::Let(_, e, _) => Some(e),
+                ExprKind::Match(e, _, _) | ExprKind::Let(&Let { init: e, .. }) => Some(e),
                 _ => None,
             },
             Node::Local(local) => local.init,
diff --git a/clippy_lints/src/stable_sort_primitive.rs b/clippy_lints/src/stable_sort_primitive.rs
index 953d21e07a3..20e38dc564e 100644
--- a/clippy_lints/src/stable_sort_primitive.rs
+++ b/clippy_lints/src/stable_sort_primitive.rs
@@ -89,7 +89,7 @@ fn detect_stable_sort_primitive(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option
     if_chain! {
         if let ExprKind::MethodCall(method_name, _, args, _) = &expr.kind;
         if let Some(slice) = &args.get(0);
-        if let Some(method) = SortingKind::from_stable_name(&method_name.ident.name.as_str());
+        if let Some(method) = SortingKind::from_stable_name(method_name.ident.name.as_str());
         if let Some(slice_type) = is_slice_of_primitives(cx, slice);
         then {
             let args_str = args.iter().skip(1).map(|arg| Sugg::hir(cx, arg, "..").to_string()).collect::<Vec<String>>().join(", ");
diff --git a/clippy_lints/src/strings.rs b/clippy_lints/src/strings.rs
index 73600a8a087..ad8e72ad764 100644
--- a/clippy_lints/src/strings.rs
+++ b/clippy_lints/src/strings.rs
@@ -327,7 +327,7 @@ impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes {
             if let ExprKind::MethodCall(path, _, [recv], _) = &e.kind;
             if path.ident.name == sym!(into_bytes);
             if let ExprKind::MethodCall(path, _, [recv], _) = &recv.kind;
-            if matches!(&*path.ident.name.as_str(), "to_owned" | "to_string");
+            if matches!(path.ident.name.as_str(), "to_owned" | "to_string");
             if let ExprKind::Lit(lit) = &recv.kind;
             if let LitKind::Str(lit_content, _) = &lit.node;
 
diff --git a/clippy_lints/src/tabs_in_doc_comments.rs b/clippy_lints/src/tabs_in_doc_comments.rs
index c9b4b245f4c..15543b6a262 100644
--- a/clippy_lints/src/tabs_in_doc_comments.rs
+++ b/clippy_lints/src/tabs_in_doc_comments.rs
@@ -64,7 +64,7 @@ impl TabsInDocComments {
         if let ast::AttrKind::DocComment(_, comment) = attr.kind {
             let comment = comment.as_str();
 
-            for (lo, hi) in get_chunks_of_tabs(&comment) {
+            for (lo, hi) in get_chunks_of_tabs(comment) {
                 // +3 skips the opening delimiter
                 let new_span = Span::new(
                     attr.span.lo() + BytePos(3 + lo),
diff --git a/clippy_lints/src/unit_types/unit_cmp.rs b/clippy_lints/src/unit_types/unit_cmp.rs
index 85257f3113c..6d9aff47421 100644
--- a/clippy_lints/src/unit_types/unit_cmp.rs
+++ b/clippy_lints/src/unit_types/unit_cmp.rs
@@ -12,7 +12,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>) {
                 if let ExprKind::Binary(ref cmp, left, _) = expr.kind {
                     let op = cmp.node;
                     if op.is_comparison() && cx.typeck_results().expr_ty(left).is_unit() {
-                        let result = match &*symbol.as_str() {
+                        let result = match symbol.as_str() {
                             "assert_eq" | "debug_assert_eq" => "succeed",
                             "assert_ne" | "debug_assert_ne" => "fail",
                             _ => return,
diff --git a/clippy_lints/src/unsafe_removed_from_name.rs b/clippy_lints/src/unsafe_removed_from_name.rs
index 44b1989dbc6..64f7a055cd9 100644
--- a/clippy_lints/src/unsafe_removed_from_name.rs
+++ b/clippy_lints/src/unsafe_removed_from_name.rs
@@ -60,7 +60,7 @@ fn check_use_tree(use_tree: &UseTree, cx: &EarlyContext<'_>, span: Span) {
 fn unsafe_to_safe_check(old_name: Ident, new_name: Ident, cx: &EarlyContext<'_>, span: Span) {
     let old_str = old_name.name.as_str();
     let new_str = new_name.name.as_str();
-    if contains_unsafe(&old_str) && !contains_unsafe(&new_str) {
+    if contains_unsafe(old_str) && !contains_unsafe(new_str) {
         span_lint(
             cx,
             UNSAFE_REMOVED_FROM_NAME,
diff --git a/clippy_lints/src/unused_io_amount.rs b/clippy_lints/src/unused_io_amount.rs
index 111413e5193..004530db086 100644
--- a/clippy_lints/src/unused_io_amount.rs
+++ b/clippy_lints/src/unused_io_amount.rs
@@ -57,7 +57,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedIoAmount {
                     check_map_error(cx, res, expr);
                 }
             },
-            hir::ExprKind::MethodCall(path, _, [ref arg_0, ..], _) => match &*path.ident.as_str() {
+            hir::ExprKind::MethodCall(path, _, [ref arg_0, ..], _) => match path.ident.as_str() {
                 "expect" | "unwrap" | "unwrap_or" | "unwrap_or_else" => {
                     check_map_error(cx, arg_0, expr);
                 },
@@ -71,7 +71,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedIoAmount {
 fn check_map_error(cx: &LateContext<'_>, call: &hir::Expr<'_>, expr: &hir::Expr<'_>) {
     let mut call = call;
     while let hir::ExprKind::MethodCall(path, _, args, _) = call.kind {
-        if matches!(&*path.ident.as_str(), "or" | "or_else" | "ok") {
+        if matches!(path.ident.as_str(), "or" | "or_else" | "ok") {
             call = &args[0];
         } else {
             break;
@@ -82,7 +82,7 @@ fn check_map_error(cx: &LateContext<'_>, call: &hir::Expr<'_>, expr: &hir::Expr<
 
 fn check_method_call(cx: &LateContext<'_>, call: &hir::Expr<'_>, expr: &hir::Expr<'_>) {
     if let hir::ExprKind::MethodCall(path, _, _, _) = call.kind {
-        let symbol = &*path.ident.as_str();
+        let symbol = path.ident.as_str();
         let read_trait = match_trait_method(cx, call, &paths::IO_READ);
         let write_trait = match_trait_method(cx, call, &paths::IO_WRITE);
 
diff --git a/clippy_lints/src/unused_unit.rs b/clippy_lints/src/unused_unit.rs
index 48c17fa2a40..bfd17a68749 100644
--- a/clippy_lints/src/unused_unit.rs
+++ b/clippy_lints/src/unused_unit.rs
@@ -94,7 +94,7 @@ impl EarlyLintPass for UnusedUnit {
 
         if_chain! {
             if segments.len() == 1;
-            if ["Fn", "FnMut", "FnOnce"].contains(&&*segments[0].ident.name.as_str());
+            if ["Fn", "FnMut", "FnOnce"].contains(&segments[0].ident.name.as_str());
             if let Some(args) = &segments[0].args;
             if let ast::GenericArgs::Parenthesized(generic_args) = &**args;
             if let ast::FnRetTy::Ty(ty) = &generic_args.output;
diff --git a/clippy_lints/src/unwrap.rs b/clippy_lints/src/unwrap.rs
index 71771aae44b..918fa5f7dc1 100644
--- a/clippy_lints/src/unwrap.rs
+++ b/clippy_lints/src/unwrap.rs
@@ -158,10 +158,10 @@ fn collect_unwrap_info<'tcx>(
             if let Some(local_id) = path_to_local(&args[0]);
             let ty = cx.typeck_results().expr_ty(&args[0]);
             let name = method_name.ident.as_str();
-            if is_relevant_option_call(cx, ty, &name) || is_relevant_result_call(cx, ty, &name);
+            if is_relevant_option_call(cx, ty, name) || is_relevant_result_call(cx, ty, name);
             then {
                 assert!(args.len() == 1);
-                let unwrappable = match name.as_ref() {
+                let unwrappable = match name {
                     "is_some" | "is_ok" => true,
                     "is_err" | "is_none" => false,
                     _ => unreachable!(),
diff --git a/clippy_lints/src/upper_case_acronyms.rs b/clippy_lints/src/upper_case_acronyms.rs
index 4773e350760..7286d0a7bf9 100644
--- a/clippy_lints/src/upper_case_acronyms.rs
+++ b/clippy_lints/src/upper_case_acronyms.rs
@@ -79,7 +79,7 @@ fn correct_ident(ident: &str) -> String {
 
 fn check_ident(cx: &LateContext<'_>, ident: &Ident, be_aggressive: bool) {
     let span = ident.span;
-    let ident = &ident.as_str();
+    let ident = ident.as_str();
     let corrected = correct_ident(ident);
     // warn if we have pure-uppercase idents
     // assume that two-letter words are some kind of valid abbreviation like FP for false positive
@@ -87,7 +87,7 @@ fn check_ident(cx: &LateContext<'_>, ident: &Ident, be_aggressive: bool) {
     if (ident.chars().all(|c| c.is_ascii_uppercase()) && ident.len() > 2)
     // otherwise, warn if we have SOmeTHING lIKE THIs but only warn with the aggressive
     // upper-case-acronyms-aggressive config option enabled
-    || (be_aggressive && ident != &corrected)
+    || (be_aggressive && ident != corrected)
     {
         span_lint_and_sugg(
             cx,
diff --git a/clippy_lints/src/useless_conversion.rs b/clippy_lints/src/useless_conversion.rs
index 0e4b32541c9..abd8a362370 100644
--- a/clippy_lints/src/useless_conversion.rs
+++ b/clippy_lints/src/useless_conversion.rs
@@ -64,7 +64,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion {
             },
 
             ExprKind::MethodCall(name, .., args, _) => {
-                if is_trait_method(cx, e, sym::Into) && &*name.ident.as_str() == "into" {
+                if is_trait_method(cx, e, sym::Into) && name.ident.as_str() == "into" {
                     let a = cx.typeck_results().expr_ty(e);
                     let b = cx.typeck_results().expr_ty(&args[0]);
                     if same_type_and_consts(a, b) {
diff --git a/clippy_lints/src/utils/author.rs b/clippy_lints/src/utils/author.rs
index f186e1f05a0..c1b811c2174 100644
--- a/clippy_lints/src/utils/author.rs
+++ b/clippy_lints/src/utils/author.rs
@@ -373,11 +373,18 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
         }
 
         match expr.value.kind {
-            ExprKind::Let(pat, expr, _) => {
-                bind!(self, pat, expr);
-                kind!("Let({pat}, {expr}, _)");
-                self.pat(pat);
-                self.expr(expr);
+            ExprKind::Let(let_expr) => {
+                bind!(self, let_expr);
+                kind!("Let({let_expr})");
+                self.pat(field!(let_expr.pat));
+                // Does what ExprKind::Cast does, only adds a clause for the type
+                // if it's a path
+                if let Some(TyKind::Path(ref qpath)) = let_expr.value.ty.as_ref().map(|ty| &ty.kind) {
+                    bind!(self, qpath);
+                    out!("if let TyKind::Path(ref {qpath}) = {let_expr}.ty.kind;");
+                    self.qpath(qpath);
+                }
+                self.expr(field!(let_expr.init));
             },
             ExprKind::Box(inner) => {
                 bind!(self, inner);
diff --git a/clippy_lints/src/utils/inspector.rs b/clippy_lints/src/utils/inspector.rs
index 43590cc7862..abf4826a069 100644
--- a/clippy_lints/src/utils/inspector.rs
+++ b/clippy_lints/src/utils/inspector.rs
@@ -142,9 +142,12 @@ fn print_expr(cx: &LateContext<'_>, expr: &hir::Expr<'_>, indent: usize) {
                 print_expr(cx, arg, indent + 1);
             }
         },
-        hir::ExprKind::Let(pat, expr, _) => {
+        hir::ExprKind::Let(hir::Let { pat, init, ty, .. }) => {
             print_pat(cx, pat, indent + 1);
-            print_expr(cx, expr, indent + 1);
+            if let Some(ty) = ty {
+                println!("{}  type annotation: {:?}", ind, ty);
+            }
+            print_expr(cx, init, indent + 1);
         },
         hir::ExprKind::MethodCall(path, _, args, _) => {
             println!("{}MethodCall", ind);
diff --git a/clippy_lints/src/utils/internal_lints.rs b/clippy_lints/src/utils/internal_lints.rs
index 81e9c2e15c9..e98dcd3cf98 100644
--- a/clippy_lints/src/utils/internal_lints.rs
+++ b/clippy_lints/src/utils/internal_lints.rs
@@ -28,7 +28,7 @@ use rustc_middle::ty;
 use rustc_semver::RustcVersion;
 use rustc_session::{declare_lint_pass, declare_tool_lint, impl_lint_pass};
 use rustc_span::source_map::Spanned;
-use rustc_span::symbol::{Symbol, SymbolStr};
+use rustc_span::symbol::Symbol;
 use rustc_span::{sym, BytePos, Span};
 use rustc_typeck::hir_ty_to_ty;
 
@@ -344,11 +344,11 @@ impl EarlyLintPass for ClippyLintsInternal {
             if let ItemKind::Mod(_, ModKind::Loaded(ref items, ..)) = utils.kind {
                 if let Some(paths) = items.iter().find(|item| item.ident.name.as_str() == "paths") {
                     if let ItemKind::Mod(_, ModKind::Loaded(ref items, ..)) = paths.kind {
-                        let mut last_name: Option<SymbolStr> = None;
+                        let mut last_name: Option<&str> = None;
                         for item in items {
                             let name = item.ident.as_str();
-                            if let Some(ref last_name) = last_name {
-                                if **last_name > *name {
+                            if let Some(last_name) = last_name {
+                                if *last_name > *name {
                                     span_lint(
                                         cx,
                                         CLIPPY_LINTS_INTERNAL,
@@ -608,8 +608,7 @@ impl<'tcx> LateLintPass<'tcx> for OuterExpnDataPass {
         }
 
         let (method_names, arg_lists, spans) = method_calls(expr, 2);
-        let method_names: Vec<SymbolStr> = method_names.iter().map(|s| s.as_str()).collect();
-        let method_names: Vec<&str> = method_names.iter().map(|s| &**s).collect();
+        let method_names: Vec<&str> = method_names.iter().map(Symbol::as_str).collect();
         if_chain! {
             if let ["expn_data", "outer_expn"] = method_names.as_slice();
             let args = arg_lists[1];
@@ -839,7 +838,7 @@ impl<'tcx> LateLintPass<'tcx> for MatchTypeOnDiagItem {
             if is_expr_path_def_path(cx, fn_path, &["clippy_utils", "ty", "match_type"]);
             // Extract the path to the matched type
             if let Some(segments) = path_to_matched_type(cx, ty_path);
-            let segments: Vec<&str> = segments.iter().map(|sym| &**sym).collect();
+            let segments: Vec<&str> = segments.iter().map(Symbol::as_str).collect();
             if let Some(ty_did) = path_to_res(cx, &segments[..]).opt_def_id();
             // Check if the matched type is a diagnostic item
             if let Some(item_name) = cx.tcx.get_diagnostic_name(ty_did);
@@ -862,7 +861,7 @@ impl<'tcx> LateLintPass<'tcx> for MatchTypeOnDiagItem {
     }
 }
 
-fn path_to_matched_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option<Vec<SymbolStr>> {
+fn path_to_matched_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option<Vec<Symbol>> {
     use rustc_hir::ItemKind;
 
     match &expr.kind {
@@ -887,12 +886,12 @@ fn path_to_matched_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option<Ve
             _ => {},
         },
         ExprKind::Array(exprs) => {
-            let segments: Vec<SymbolStr> = exprs
+            let segments: Vec<Symbol> = exprs
                 .iter()
                 .filter_map(|expr| {
                     if let ExprKind::Lit(lit) = &expr.kind {
                         if let LitKind::Str(sym, _) = lit.node {
-                            return Some(sym.as_str());
+                            return Some(sym);
                         }
                     }
 
@@ -1076,7 +1075,6 @@ impl InterningDefinedSymbol {
             &paths::SYMBOL_TO_IDENT_STRING,
             &paths::TO_STRING_METHOD,
         ];
-        // SymbolStr might be de-referenced: `&*symbol.as_str()`
         let call = if_chain! {
             if let ExprKind::AddrOf(_, _, e) = expr.kind;
             if let ExprKind::Unary(UnOp::Deref, e) = e.kind;
diff --git a/clippy_lints/src/write.rs b/clippy_lints/src/write.rs
index 5bf0cffdbad..f9add927b49 100644
--- a/clippy_lints/src/write.rs
+++ b/clippy_lints/src/write.rs
@@ -371,9 +371,9 @@ impl EarlyLintPass for Write {
 /// Return this and a boolean indicating whether it only consisted of a newline.
 fn newline_span(fmtstr: &StrLit) -> (Span, bool) {
     let sp = fmtstr.span;
-    let contents = &fmtstr.symbol.as_str();
+    let contents = fmtstr.symbol.as_str();
 
-    if *contents == r"\n" {
+    if contents == r"\n" {
         return (sp, true);
     }
 
@@ -484,7 +484,7 @@ impl Write {
             StrStyle::Raw(n) => Some(n as usize),
         };
 
-        let mut parser = Parser::new(&str_sym, style, snippet_opt(cx, str_lit.span), false, ParseMode::Format);
+        let mut parser = Parser::new(str_sym, style, snippet_opt(cx, str_lit.span), false, ParseMode::Format);
         let mut args = SimpleFormatArgs::default();
 
         while let Some(arg) = parser.next() {
@@ -589,7 +589,7 @@ impl Write {
                     lit.token.symbol.as_str().replace('{', "{{").replace('}', "}}")
                 },
                 LitKind::StrRaw(_) | LitKind::Str | LitKind::ByteStrRaw(_) | LitKind::ByteStr => continue,
-                LitKind::Byte | LitKind::Char => match &*lit.token.symbol.as_str() {
+                LitKind::Byte | LitKind::Char => match lit.token.symbol.as_str() {
                     "\"" if matches!(fmtstr.style, StrStyle::Cooked) => "\\\"",
                     "\"" if matches!(fmtstr.style, StrStyle::Raw(0)) => continue,
                     "\\\\" if matches!(fmtstr.style, StrStyle::Raw(_)) => "\\",
@@ -671,7 +671,7 @@ fn check_newlines(fmtstr: &StrLit) -> bool {
     let mut last_was_cr = false;
     let mut should_lint = false;
 
-    let contents = &fmtstr.symbol.as_str();
+    let contents = fmtstr.symbol.as_str();
 
     let mut cb = |r: Range<usize>, c: Result<char, EscapeError>| {
         let c = c.unwrap();
diff --git a/clippy_utils/src/attrs.rs b/clippy_utils/src/attrs.rs
index 7ae9615d560..25a84d16650 100644
--- a/clippy_utils/src/attrs.rs
+++ b/clippy_utils/src/attrs.rs
@@ -113,7 +113,7 @@ pub fn get_attr<'a>(
 fn parse_attrs<F: FnMut(u64)>(sess: &Session, attrs: &[ast::Attribute], name: &'static str, mut f: F) {
     for attr in get_attr(sess, attrs, name) {
         if let Some(ref value) = attr.value_str() {
-            if let Ok(value) = FromStr::from_str(&value.as_str()) {
+            if let Ok(value) = FromStr::from_str(value.as_str()) {
                 f(value);
             } else {
                 sess.span_err(attr.span, "not a number");
diff --git a/clippy_utils/src/consts.rs b/clippy_utils/src/consts.rs
index 1cf8f9721b5..5c024612f8e 100644
--- a/clippy_utils/src/consts.rs
+++ b/clippy_utils/src/consts.rs
@@ -327,8 +327,8 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
                     if let ExprKind::Path(qpath) = &callee.kind;
                     let res = self.typeck_results.qpath_res(qpath, callee.hir_id);
                     if let Some(def_id) = res.opt_def_id();
-                    let def_path: Vec<_> = self.lcx.get_def_path(def_id).into_iter().map(Symbol::as_str).collect();
-                    let def_path: Vec<&str> = def_path.iter().take(4).map(|s| &**s).collect();
+                    let def_path = self.lcx.get_def_path(def_id);
+                    let def_path: Vec<&str> = def_path.iter().take(4).map(Symbol::as_str).collect();
                     if let ["core", "num", int_impl, "max_value"] = *def_path;
                     then {
                        let value = match int_impl {
diff --git a/clippy_utils/src/eager_or_lazy.rs b/clippy_utils/src/eager_or_lazy.rs
index c2645ac730a..61e529a6079 100644
--- a/clippy_utils/src/eager_or_lazy.rs
+++ b/clippy_utils/src/eager_or_lazy.rs
@@ -47,7 +47,7 @@ impl ops::BitOrAssign for EagernessSuggestion {
 /// Determine the eagerness of the given function call.
 fn fn_eagerness(cx: &LateContext<'tcx>, fn_id: DefId, name: Symbol, args: &'tcx [Expr<'_>]) -> EagernessSuggestion {
     use EagernessSuggestion::{Eager, Lazy, NoChange};
-    let name = &*name.as_str();
+    let name = name.as_str();
 
     let ty = match cx.tcx.impl_of_method(fn_id) {
         Some(id) => cx.tcx.type_of(id),
diff --git a/clippy_utils/src/higher.rs b/clippy_utils/src/higher.rs
index fc32e49420e..c764c35d444 100644
--- a/clippy_utils/src/higher.rs
+++ b/clippy_utils/src/higher.rs
@@ -101,7 +101,12 @@ impl<'hir> IfLet<'hir> {
     pub fn hir(cx: &LateContext<'_>, expr: &Expr<'hir>) -> Option<Self> {
         if let ExprKind::If(
             Expr {
-                kind: ExprKind::Let(let_pat, let_expr, _),
+                kind:
+                    ExprKind::Let(hir::Let {
+                        pat: let_pat,
+                        init: let_expr,
+                        ..
+                    }),
                 ..
             },
             if_then,
@@ -368,7 +373,12 @@ impl<'hir> WhileLet<'hir> {
                         kind:
                             ExprKind::If(
                                 Expr {
-                                    kind: ExprKind::Let(let_pat, let_expr, _),
+                                    kind:
+                                        ExprKind::Let(hir::Let {
+                                            pat: let_pat,
+                                            init: let_expr,
+                                            ..
+                                        }),
                                     ..
                                 },
                                 if_then,
diff --git a/clippy_utils/src/hir_utils.rs b/clippy_utils/src/hir_utils.rs
index b8e53e47ed9..ad50759effa 100644
--- a/clippy_utils/src/hir_utils.rs
+++ b/clippy_utils/src/hir_utils.rs
@@ -7,7 +7,7 @@ use rustc_hir::def::Res;
 use rustc_hir::HirIdMap;
 use rustc_hir::{
     BinOpKind, Block, BodyId, Expr, ExprField, ExprKind, FnRetTy, GenericArg, GenericArgs, Guard, HirId,
-    InlineAsmOperand, Lifetime, LifetimeName, ParamName, Pat, PatField, PatKind, Path, PathSegment, QPath, Stmt,
+    InlineAsmOperand, Let, Lifetime, LifetimeName, ParamName, Pat, PatField, PatKind, Path, PathSegment, QPath, Stmt,
     StmtKind, Ty, TyKind, TypeBinding,
 };
 use rustc_lexer::{tokenize, TokenKind};
@@ -234,7 +234,9 @@ impl HirEqInterExpr<'_, '_, '_> {
             (&ExprKind::If(lc, lt, ref le), &ExprKind::If(rc, rt, ref re)) => {
                 self.eq_expr(lc, rc) && self.eq_expr(&**lt, &**rt) && both(le, re, |l, r| self.eq_expr(l, r))
             },
-            (&ExprKind::Let(lp, le, _), &ExprKind::Let(rp, re, _)) => self.eq_pat(lp, rp) && self.eq_expr(le, re),
+            (&ExprKind::Let(l), &ExprKind::Let(r)) => {
+                self.eq_pat(l.pat, r.pat) && both(&l.ty, &r.ty, |l, r| self.eq_ty(l, r)) && self.eq_expr(l.init, r.init)
+            },
             (&ExprKind::Lit(ref l), &ExprKind::Lit(ref r)) => l.node == r.node,
             (&ExprKind::Loop(lb, ref ll, ref lls, _), &ExprKind::Loop(rb, ref rl, ref rls, _)) => {
                 lls == rls && self.eq_block(lb, rb) && both(ll, rl, |l, r| l.ident.name == r.ident.name)
@@ -668,8 +670,11 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
                     }
                 }
             },
-            ExprKind::Let(pat, expr, _) => {
-                self.hash_expr(expr);
+            ExprKind::Let(Let { pat, init, ty, .. }) => {
+                self.hash_expr(init);
+                if let Some(ty) = ty {
+                    self.hash_ty(ty);
+                }
                 self.hash_pat(pat);
             },
             ExprKind::LlvmInlineAsm(..) | ExprKind::Err => {},
diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs
index 51bb2681e74..54d470ca738 100644
--- a/clippy_utils/src/lib.rs
+++ b/clippy_utils/src/lib.rs
@@ -887,8 +887,8 @@ pub fn capture_local_usage(cx: &LateContext<'tcx>, e: &Expr<'_>) -> CaptureKind
                         capture_expr_ty = e;
                     }
                 },
-                ExprKind::Let(pat, ..) => {
-                    let mutability = match pat_capture_kind(cx, pat) {
+                ExprKind::Let(let_expr) => {
+                    let mutability = match pat_capture_kind(cx, let_expr.pat) {
                         CaptureKind::Value => Mutability::Not,
                         CaptureKind::Ref(m) => m,
                     };
diff --git a/clippy_utils/src/qualify_min_const_fn.rs b/clippy_utils/src/qualify_min_const_fn.rs
index e6d8ba3f02e..1a4da1627b7 100644
--- a/clippy_utils/src/qualify_min_const_fn.rs
+++ b/clippy_utils/src/qualify_min_const_fn.rs
@@ -372,7 +372,7 @@ fn is_const_fn(tcx: TyCtxt<'_>, def_id: DefId, msrv: Option<&RustcVersion>) -> b
                 // as a part of an unimplemented MSRV check https://github.com/rust-lang/rust/issues/65262.
                 crate::meets_msrv(
                     msrv,
-                    &RustcVersion::parse(&since.as_str())
+                    &RustcVersion::parse(since.as_str())
                         .expect("`rustc_attr::StabilityLevel::Stable::since` is ill-formatted"),
                 )
             } else {
diff --git a/rust-toolchain b/rust-toolchain
index 3a5dfa6a8c7..471ae40f1ac 100644
--- a/rust-toolchain
+++ b/rust-toolchain
@@ -1,3 +1,3 @@
 [toolchain]
-channel = "nightly-2021-12-17"
+channel = "nightly-2021-12-30"
 components = ["cargo", "llvm-tools-preview", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
diff --git a/tests/ui/author/if.stdout b/tests/ui/author/if.stdout
index 75ff3faf29a..8d92849b366 100644
--- a/tests/ui/author/if.stdout
+++ b/tests/ui/author/if.stdout
@@ -32,11 +32,11 @@ if_chain! {
 }
 if_chain! {
     if let ExprKind::If(cond, then, Some(else_expr)) = expr.kind;
-    if let ExprKind::Let(pat, expr1, _) = cond.kind;
-    if let PatKind::Lit(lit_expr) = pat.kind;
+    if let ExprKind::Let(let_expr) = cond.kind;
+    if let PatKind::Lit(lit_expr) = let_expr.pat.kind;
     if let ExprKind::Lit(ref lit) = lit_expr.kind;
     if let LitKind::Bool(true) = lit.node;
-    if let ExprKind::Path(ref qpath) = expr1.kind;
+    if let ExprKind::Path(ref qpath) = let_expr.init.kind;
     if match_qpath(qpath, &["a"]);
     if let ExprKind::Block(block, None) = then.kind;
     if block.stmts.is_empty();
diff --git a/tests/ui/missing_panics_doc.stderr b/tests/ui/missing_panics_doc.stderr
index 60282939ef0..8bccbaefe23 100644
--- a/tests/ui/missing_panics_doc.stderr
+++ b/tests/ui/missing_panics_doc.stderr
@@ -42,7 +42,7 @@ note: first possible panic found here
    |
 LL |     todo!()
    |     ^^^^^^^
-   = note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
+   = note: this error originates in the macro `todo` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: docs for function which may panic missing `# Panics` section
   --> $DIR/missing_panics_doc.rs:22:1