diff --git a/Cargo.toml b/Cargo.toml
index 0954b758cf6..ba3ed3053ac 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -21,37 +21,35 @@ name = "clippy-driver"
 path = "src/driver.rs"
 
 [dependencies]
-# begin automatic update
-clippy_lints = { version = "0.1.50", path = "clippy_lints" }
-# end automatic update
+clippy_lints = { version = "0.1", path = "clippy_lints" }
 semver = "0.11"
-rustc_tools_util = { version = "0.2.0", path = "rustc_tools_util" }
-tempfile = { version = "3.1.0", optional = true }
+rustc_tools_util = { version = "0.2", path = "rustc_tools_util" }
+tempfile = { version = "3.2", optional = true }
 
 [dev-dependencies]
 cargo_metadata = "0.12"
-compiletest_rs = { version = "0.6.0", features = ["tmp"] }
+compiletest_rs = { version = "0.7", features = ["tmp"] }
 tester = "0.9"
-regex = "1.4"
+regex = "1.5"
 # This is used by the `collect-metadata` alias.
 filetime = "0.2"
 
 # A noop dependency that changes in the Rust repository, it's a bit of a hack.
 # See the `src/tools/rustc-workspace-hack/README.md` file in `rust-lang/rust`
 # for more information.
-rustc-workspace-hack = "1.0.0"
+rustc-workspace-hack = "1.0"
 
 # UI test dependencies
 clippy_utils = { path = "clippy_utils" }
 derive-new = "0.5"
 if_chain = "1.0"
-itertools = "0.10.1"
-quote = "1"
+itertools = "0.10"
+quote = "1.0"
 serde = { version = "1.0", features = ["derive"] }
-syn = { version = "1", features = ["full"] }
+syn = { version = "1.0", features = ["full"] }
 
 [build-dependencies]
-rustc_tools_util = { version = "0.2.0", path = "rustc_tools_util" }
+rustc_tools_util = { version = "0.2", path = "rustc_tools_util" }
 
 [features]
 deny-warnings = ["clippy_lints/deny-warnings"]
diff --git a/clippy_dev/Cargo.toml b/clippy_dev/Cargo.toml
index 8bdb77a44f3..4a13a452409 100644
--- a/clippy_dev/Cargo.toml
+++ b/clippy_dev/Cargo.toml
@@ -6,11 +6,11 @@ edition = "2021"
 [dependencies]
 bytecount = "0.6"
 clap = "2.33"
-itertools = "0.9"
+itertools = "0.10"
 opener = "0.5"
-regex = "1"
+regex = "1.5"
 shell-escape = "0.1"
-walkdir = "2"
+walkdir = "2.3"
 
 [features]
 deny-warnings = []
diff --git a/clippy_dummy/Cargo.toml b/clippy_dummy/Cargo.toml
index a1707bad5c2..c206a1eb07b 100644
--- a/clippy_dummy/Cargo.toml
+++ b/clippy_dummy/Cargo.toml
@@ -13,4 +13,4 @@ keywords = ["clippy", "lint", "plugin"]
 categories = ["development-tools", "development-tools::cargo-plugins"]
 
 [build-dependencies]
-term = "0.6"
+term = "0.7"
diff --git a/clippy_lints/Cargo.toml b/clippy_lints/Cargo.toml
index e3c30573c20..7900dc6d041 100644
--- a/clippy_lints/Cargo.toml
+++ b/clippy_lints/Cargo.toml
@@ -11,21 +11,21 @@ edition = "2021"
 [dependencies]
 cargo_metadata = "0.12"
 clippy_utils = { path = "../clippy_utils" }
-if_chain = "1.0.0"
-itertools = "0.9"
+if_chain = "1.0"
+itertools = "0.10"
 pulldown-cmark = { version = "0.8", default-features = false }
-quine-mc_cluskey = "0.2.2"
+quine-mc_cluskey = "0.2"
 regex-syntax = "0.6"
 serde = { version = "1.0", features = ["derive"] }
 serde_json = { version = "1.0", optional = true }
-toml = "0.5.3"
+toml = "0.5"
 unicode-normalization = "0.1"
-unicode-script = { version = "0.5.3", default-features = false }
+unicode-script = { version = "0.5", default-features = false }
 semver = "0.11"
-rustc-semver = "1.1.0"
+rustc-semver = "1.1"
 # NOTE: cargo requires serde feat in its url dep
 # see <https://github.com/rust-lang/rust/pull/63587#issuecomment-522343864>
-url = { version = "2.1.0", features = ["serde"] }
+url = { version = "2.2", features = ["serde"] }
 
 [features]
 deny-warnings = ["clippy_utils/deny-warnings"]
diff --git a/clippy_lints/src/attrs.rs b/clippy_lints/src/attrs.rs
index c9ff468874b..2ef7dcc1775 100644
--- a/clippy_lints/src/attrs.rs
+++ b/clippy_lints/src/attrs.rs
@@ -527,8 +527,8 @@ fn check_empty_line_after_outer_attr(cx: &EarlyContext<'_>, item: &rustc_ast::It
                 return;
             }
 
-            let begin_of_attr_to_item = Span::new(attr.span.lo(), item.span.lo(), item.span.ctxt());
-            let end_of_attr_to_item = Span::new(attr.span.hi(), item.span.lo(), item.span.ctxt());
+            let begin_of_attr_to_item = Span::new(attr.span.lo(), item.span.lo(), item.span.ctxt(), item.span.parent());
+            let end_of_attr_to_item = Span::new(attr.span.hi(), item.span.lo(), item.span.ctxt(), item.span.parent());
 
             if let Some(snippet) = snippet_opt(cx, end_of_attr_to_item) {
                 let lines = snippet.split('\n').collect::<Vec<_>>();
diff --git a/clippy_lints/src/cargo_common_metadata.rs b/clippy_lints/src/cargo_common_metadata.rs
index bd5426ba707..162911b77d6 100644
--- a/clippy_lints/src/cargo_common_metadata.rs
+++ b/clippy_lints/src/cargo_common_metadata.rs
@@ -1,7 +1,5 @@
 //! lint on missing cargo common metadata
 
-use std::path::PathBuf;
-
 use clippy_utils::{diagnostics::span_lint, is_lint_allowed};
 use rustc_hir::{hir_id::CRATE_HIR_ID, Crate};
 use rustc_lint::{LateContext, LateLintPass};
@@ -69,12 +67,8 @@ fn missing_warning(cx: &LateContext<'_>, package: &cargo_metadata::Package, fiel
     span_lint(cx, CARGO_COMMON_METADATA, DUMMY_SP, &message);
 }
 
-fn is_empty_str(value: &Option<String>) -> bool {
-    value.as_ref().map_or(true, String::is_empty)
-}
-
-fn is_empty_path(value: &Option<PathBuf>) -> bool {
-    value.as_ref().and_then(|x| x.to_str()).map_or(true, str::is_empty)
+fn is_empty_str<T: AsRef<std::ffi::OsStr>>(value: &Option<T>) -> bool {
+    value.as_ref().map_or(true, |s| s.as_ref().is_empty())
 }
 
 fn is_empty_vec(value: &[String]) -> bool {
@@ -98,7 +92,7 @@ impl LateLintPass<'_> for CargoCommonMetadata {
                     missing_warning(cx, &package, "package.description");
                 }
 
-                if is_empty_str(&package.license) && is_empty_path(&package.license_file) {
+                if is_empty_str(&package.license) && is_empty_str(&package.license_file) {
                     missing_warning(cx, &package, "either package.license or package.license_file");
                 }
 
@@ -106,7 +100,7 @@ impl LateLintPass<'_> for CargoCommonMetadata {
                     missing_warning(cx, &package, "package.repository");
                 }
 
-                if is_empty_path(&package.readme) {
+                if is_empty_str(&package.readme) {
                     missing_warning(cx, &package, "package.readme");
                 }
 
diff --git a/clippy_lints/src/cognitive_complexity.rs b/clippy_lints/src/cognitive_complexity.rs
index 96c30d57ee1..2203d1c39f1 100644
--- a/clippy_lints/src/cognitive_complexity.rs
+++ b/clippy_lints/src/cognitive_complexity.rs
@@ -95,7 +95,7 @@ impl CognitiveComplexity {
                     });
 
                     if let Some((low, high)) = pos {
-                        Span::new(low, high, header_span.ctxt())
+                        Span::new(low, high, header_span.ctxt(), header_span.parent())
                     } else {
                         return;
                     }
diff --git a/clippy_lints/src/copies.rs b/clippy_lints/src/copies.rs
index d58e4949120..6ded2f233ef 100644
--- a/clippy_lints/src/copies.rs
+++ b/clippy_lints/src/copies.rs
@@ -472,7 +472,7 @@ fn emit_branches_sharing_code_lint(
 
         let mut span = moved_start.to(span_end);
         // Improve formatting if the inner block has indention (i.e. normal Rust formatting)
-        let test_span = Span::new(span.lo() - BytePos(4), span.lo(), span.ctxt());
+        let test_span = Span::new(span.lo() - BytePos(4), span.lo(), span.ctxt(), span.parent());
         if snippet_opt(cx, test_span)
             .map(|snip| snip == "    ")
             .unwrap_or_default()
diff --git a/clippy_lints/src/doc.rs b/clippy_lints/src/doc.rs
index cb2b7f5be70..0b61909ddd8 100644
--- a/clippy_lints/src/doc.rs
+++ b/clippy_lints/src/doc.rs
@@ -665,6 +665,7 @@ fn check_text(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, text: &str
             span.lo() + BytePos::from_usize(offset),
             span.lo() + BytePos::from_usize(offset + word.len()),
             span.ctxt(),
+            span.parent(),
         );
 
         check_word(cx, word, span);
diff --git a/clippy_lints/src/escape.rs b/clippy_lints/src/escape.rs
index 1ba241d3776..090be73af3b 100644
--- a/clippy_lints/src/escape.rs
+++ b/clippy_lints/src/escape.rs
@@ -91,8 +91,11 @@ impl<'tcx> LateLintPass<'tcx> for BoxedLocal {
                     if trait_item.id.hir_id() == hir_id {
                         // be sure we have `self` parameter in this function
                         if let AssocItemKind::Fn { has_self: true } = trait_item.kind {
-                            trait_self_ty =
-                                Some(TraitRef::identity(cx.tcx, trait_item.id.def_id.to_def_id()).self_ty());
+                            trait_self_ty = Some(
+                                TraitRef::identity(cx.tcx, trait_item.id.def_id.to_def_id())
+                                    .self_ty()
+                                    .skip_binder(),
+                            );
                         }
                     }
                 }
diff --git a/clippy_lints/src/fallible_impl_from.rs b/clippy_lints/src/fallible_impl_from.rs
index 7e4d1b3ef9f..f22f52b949e 100644
--- a/clippy_lints/src/fallible_impl_from.rs
+++ b/clippy_lints/src/fallible_impl_from.rs
@@ -65,7 +65,7 @@ impl<'tcx> LateLintPass<'tcx> for FallibleImplFrom {
     }
 }
 
-fn lint_impl_body<'tcx>(cx: &LateContext<'tcx>, impl_span: Span, impl_items: &[hir::ImplItemRef<'_>]) {
+fn lint_impl_body<'tcx>(cx: &LateContext<'tcx>, impl_span: Span, impl_items: &[hir::ImplItemRef]) {
     use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
     use rustc_hir::{Expr, ExprKind, ImplItemKind, QPath};
 
diff --git a/clippy_lints/src/implicit_hasher.rs b/clippy_lints/src/implicit_hasher.rs
index 6b407c7bb67..2fe32fcf665 100644
--- a/clippy_lints/src/implicit_hasher.rs
+++ b/clippy_lints/src/implicit_hasher.rs
@@ -130,7 +130,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitHasher {
                         let pos = snippet_opt(cx, item.span.until(target.span()))
                             .and_then(|snip| Some(item.span.lo() + BytePos(snip.find("impl")? as u32 + 4)));
                         if let Some(pos) = pos {
-                            Span::new(pos, pos, item.span.data().ctxt)
+                            Span::new(pos, pos, item.span.ctxt(), item.span.parent())
                         } else {
                             return;
                         }
@@ -173,7 +173,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitHasher {
                                     Some(item.span.lo() + BytePos((i + (&snip[i..]).find('(')?) as u32))
                                 })
                                 .expect("failed to create span for type parameters");
-                            Span::new(pos, pos, item.span.data().ctxt)
+                            Span::new(pos, pos, item.span.ctxt(), item.span.parent())
                         });
 
                         let mut ctr_vis = ImplicitHasherConstructorVisitor::new(cx, target);
diff --git a/clippy_lints/src/large_const_arrays.rs b/clippy_lints/src/large_const_arrays.rs
index 10281496c11..fe6814e35d0 100644
--- a/clippy_lints/src/large_const_arrays.rs
+++ b/clippy_lints/src/large_const_arrays.rs
@@ -63,6 +63,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeConstArrays {
                     hi_pos - BytePos::from_usize("const".len()),
                     hi_pos,
                     item.span.ctxt(),
+                    item.span.parent(),
                 );
                 span_lint_and_then(
                     cx,
diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs
index 92ebebd62bf..89724917482 100644
--- a/clippy_lints/src/lib.rs
+++ b/clippy_lints/src/lib.rs
@@ -31,7 +31,7 @@ extern crate rustc_infer;
 extern crate rustc_lexer;
 extern crate rustc_lint;
 extern crate rustc_middle;
-extern crate rustc_mir;
+extern crate rustc_mir_dataflow;
 extern crate rustc_parse;
 extern crate rustc_parse_format;
 extern crate rustc_session;
@@ -1961,7 +1961,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     store.register_late_pass(|| Box::new(empty_enum::EmptyEnum));
     store.register_late_pass(|| Box::new(absurd_extreme_comparisons::AbsurdExtremeComparisons));
     store.register_late_pass(|| Box::new(invalid_upcast_comparisons::InvalidUpcastComparisons));
-    store.register_late_pass(|| Box::new(regex::Regex::default()));
+    store.register_late_pass(|| Box::new(regex::Regex));
     store.register_late_pass(|| Box::new(copies::CopyAndPaste));
     store.register_late_pass(|| Box::new(copy_iterator::CopyIterator));
     store.register_late_pass(|| Box::new(format::UselessFormat));
diff --git a/clippy_lints/src/loops/for_kv_map.rs b/clippy_lints/src/loops/for_kv_map.rs
index 68bef2f4c8b..dd60e460d21 100644
--- a/clippy_lints/src/loops/for_kv_map.rs
+++ b/clippy_lints/src/loops/for_kv_map.rs
@@ -10,13 +10,7 @@ use rustc_middle::ty;
 use rustc_span::sym;
 
 /// Checks for the `FOR_KV_MAP` lint.
-pub(super) fn check<'tcx>(
-    cx: &LateContext<'tcx>,
-    pat: &'tcx Pat<'_>,
-    arg: &'tcx Expr<'_>,
-    body: &'tcx Expr<'_>,
-    expr: &'tcx Expr<'_>,
-) {
+pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>, arg: &'tcx Expr<'_>, body: &'tcx Expr<'_>) {
     let pat_span = pat.span;
 
     if let PatKind::Tuple(pat, _) = pat.kind {
@@ -43,7 +37,7 @@ pub(super) fn check<'tcx>(
                 span_lint_and_then(
                     cx,
                     FOR_KV_MAP,
-                    expr.span,
+                    arg_span,
                     &format!("you seem to want to iterate on a map's {}s", kind),
                     |diag| {
                         let map = sugg::Sugg::hir(cx, arg, "map");
diff --git a/clippy_lints/src/loops/iter_next_loop.rs b/clippy_lints/src/loops/iter_next_loop.rs
index 9148fbfd497..e640c62ebda 100644
--- a/clippy_lints/src/loops/iter_next_loop.rs
+++ b/clippy_lints/src/loops/iter_next_loop.rs
@@ -5,12 +5,12 @@ use rustc_hir::Expr;
 use rustc_lint::LateContext;
 use rustc_span::sym;
 
-pub(super) fn check(cx: &LateContext<'_>, arg: &Expr<'_>, expr: &Expr<'_>) -> bool {
+pub(super) fn check(cx: &LateContext<'_>, arg: &Expr<'_>) -> bool {
     if is_trait_method(cx, arg, sym::Iterator) {
         span_lint(
             cx,
             ITER_NEXT_LOOP,
-            expr.span,
+            arg.span,
             "you are iterating over `Iterator::next()` which is an Option; this will compile but is \
             probably not what you want",
         );
diff --git a/clippy_lints/src/loops/mod.rs b/clippy_lints/src/loops/mod.rs
index 2860cb68f42..5df1b796401 100644
--- a/clippy_lints/src/loops/mod.rs
+++ b/clippy_lints/src/loops/mod.rs
@@ -616,15 +616,15 @@ fn check_for_loop<'tcx>(
         needless_range_loop::check(cx, pat, arg, body, expr);
         explicit_counter_loop::check(cx, pat, arg, body, expr);
     }
-    check_for_loop_arg(cx, pat, arg, expr);
-    for_kv_map::check(cx, pat, arg, body, expr);
+    check_for_loop_arg(cx, pat, arg);
+    for_kv_map::check(cx, pat, arg, body);
     mut_range_bound::check(cx, arg, body);
     single_element_loop::check(cx, pat, arg, body, expr);
     same_item_push::check(cx, pat, arg, body, expr);
     manual_flatten::check(cx, pat, arg, body, span);
 }
 
-fn check_for_loop_arg(cx: &LateContext<'_>, pat: &Pat<'_>, arg: &Expr<'_>, expr: &Expr<'_>) {
+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 {
@@ -637,7 +637,7 @@ fn check_for_loop_arg(cx: &LateContext<'_>, pat: &Pat<'_>, arg: &Expr<'_>, expr:
                 explicit_into_iter_loop::check(cx, self_arg, arg);
             },
             "next" => {
-                next_loop_linted = iter_next_loop::check(cx, arg, expr);
+                next_loop_linted = iter_next_loop::check(cx, arg);
             },
             _ => {},
         }
diff --git a/clippy_lints/src/loops/needless_range_loop.rs b/clippy_lints/src/loops/needless_range_loop.rs
index e8f3550283a..7157b801185 100644
--- a/clippy_lints/src/loops/needless_range_loop.rs
+++ b/clippy_lints/src/loops/needless_range_loop.rs
@@ -144,7 +144,7 @@ pub(super) fn check<'tcx>(
                     span_lint_and_then(
                         cx,
                         NEEDLESS_RANGE_LOOP,
-                        expr.span,
+                        arg.span,
                         &format!("the loop variable `{}` is used to index `{}`", ident.name, indexed),
                         |diag| {
                             multispan_sugg(
@@ -170,7 +170,7 @@ pub(super) fn check<'tcx>(
                     span_lint_and_then(
                         cx,
                         NEEDLESS_RANGE_LOOP,
-                        expr.span,
+                        arg.span,
                         &format!("the loop variable `{}` is only used to index `{}`", ident.name, indexed),
                         |diag| {
                             multispan_sugg(
diff --git a/clippy_lints/src/loops/while_let_on_iterator.rs b/clippy_lints/src/loops/while_let_on_iterator.rs
index 9a3475c977e..b390476a664 100644
--- a/clippy_lints/src/loops/while_let_on_iterator.rs
+++ b/clippy_lints/src/loops/while_let_on_iterator.rs
@@ -69,8 +69,6 @@ pub(super) fn check(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
 struct IterExpr {
     /// The span of the whole expression, not just the path and fields stored here.
     span: Span,
-    /// The HIR id of the whole expression, not just the path and fields stored here.
-    hir_id: HirId,
     /// The fields used, in order of child to parent.
     fields: Vec<Symbol>,
     /// The path being used.
@@ -81,14 +79,12 @@ struct IterExpr {
 /// the expression might have side effects.
 fn try_parse_iter_expr(cx: &LateContext<'_>, mut e: &Expr<'_>) -> Option<IterExpr> {
     let span = e.span;
-    let hir_id = e.hir_id;
     let mut fields = Vec::new();
     loop {
         match e.kind {
             ExprKind::Path(ref path) => {
                 break Some(IterExpr {
                     span,
-                    hir_id,
                     fields,
                     path: cx.qpath_res(path, e.hir_id),
                 });
diff --git a/clippy_lints/src/macro_use.rs b/clippy_lints/src/macro_use.rs
index 7627e0fb289..0e682c5cded 100644
--- a/clippy_lints/src/macro_use.rs
+++ b/clippy_lints/src/macro_use.rs
@@ -29,8 +29,6 @@ declare_clippy_lint! {
     "#[macro_use] is no longer needed"
 }
 
-const BRACKETS: &[char] = &['<', '>'];
-
 #[derive(Clone, Debug, PartialEq, Eq)]
 struct PathAndSpan {
     path: String,
@@ -42,23 +40,11 @@ struct PathAndSpan {
 #[derive(Debug, Clone)]
 pub struct MacroRefData {
     name: String,
-    path: String,
 }
 
 impl MacroRefData {
-    pub fn new(name: String, callee: Span, cx: &LateContext<'_>) -> Self {
-        let sm = cx.sess().source_map();
-        let mut path = sm.filename_for_diagnostics(&sm.span_to_filename(callee)).to_string();
-
-        // std lib paths are <::std::module::file type>
-        // so remove brackets, space and type.
-        if path.contains('<') {
-            path = path.replace(BRACKETS, "");
-        }
-        if path.contains(' ') {
-            path = path.split(' ').next().unwrap().to_string();
-        }
-        Self { name, path }
+    pub fn new(name: String) -> Self {
+        Self { name }
     }
 }
 
@@ -78,29 +64,24 @@ impl MacroUseImports {
     fn push_unique_macro(&mut self, cx: &LateContext<'_>, span: Span) {
         let call_site = span.source_callsite();
         let name = snippet(cx, cx.sess().source_map().span_until_char(call_site, '!'), "_");
-        if let Some(callee) = span.source_callee() {
-            if !self.collected.contains(&call_site) {
-                let name = if name.contains("::") {
-                    name.split("::").last().unwrap().to_string()
-                } else {
-                    name.to_string()
-                };
+        if span.source_callee().is_some() && !self.collected.contains(&call_site) {
+            let name = if name.contains("::") {
+                name.split("::").last().unwrap().to_string()
+            } else {
+                name.to_string()
+            };
 
-                self.mac_refs.push(MacroRefData::new(name, callee.def_site, cx));
-                self.collected.insert(call_site);
-            }
+            self.mac_refs.push(MacroRefData::new(name));
+            self.collected.insert(call_site);
         }
     }
 
     fn push_unique_macro_pat_ty(&mut self, cx: &LateContext<'_>, span: Span) {
         let call_site = span.source_callsite();
         let name = snippet(cx, cx.sess().source_map().span_until_char(call_site, '!'), "_");
-        if let Some(callee) = span.source_callee() {
-            if !self.collected.contains(&call_site) {
-                self.mac_refs
-                    .push(MacroRefData::new(name.to_string(), callee.def_site, cx));
-                self.collected.insert(call_site);
-            }
+        if span.source_callee().is_some() && !self.collected.contains(&call_site) {
+            self.mac_refs.push(MacroRefData::new(name.to_string()));
+            self.collected.insert(call_site);
         }
     }
 }
diff --git a/clippy_lints/src/methods/manual_split_once.rs b/clippy_lints/src/methods/manual_split_once.rs
index 8440f291859..55688677e1d 100644
--- a/clippy_lints/src/methods/manual_split_once.rs
+++ b/clippy_lints/src/methods/manual_split_once.rs
@@ -180,7 +180,7 @@ fn parse_iter_usage(
                 },
                 _,
             ) => {
-                let parent_span = e.span.parent().unwrap();
+                let parent_span = e.span.parent_callsite().unwrap();
                 if parent_span.ctxt() == ctxt {
                     (Some(UnwrapKind::QuestionMark), parent_span)
                 } else {
diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs
index 486208f0fad..2025056ac94 100644
--- a/clippy_lints/src/methods/mod.rs
+++ b/clippy_lints/src/methods/mod.rs
@@ -997,7 +997,7 @@ declare_clippy_lint! {
 declare_clippy_lint! {
     /// ### What it does
     /// Checks for use of `.iter().nth()` (and the related
-    /// `.iter_mut().nth()`) on standard library types with O(1) element access.
+    /// `.iter_mut().nth()`) on standard library types with *O*(1) element access.
     ///
     /// ### Why is this bad?
     /// `.get()` and `.get_mut()` are more efficient and more
@@ -2063,7 +2063,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
             then {
                 let first_arg_span = first_arg_ty.span;
                 let first_arg_ty = hir_ty_to_ty(cx.tcx, first_arg_ty);
-                let self_ty = TraitRef::identity(cx.tcx, item.def_id.to_def_id()).self_ty();
+                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(),
@@ -2080,7 +2080,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
             if item.ident.name == sym::new;
             if let TraitItemKind::Fn(_, _) = item.kind;
             let ret_ty = return_ty(cx, item.hir_id());
-            let self_ty = TraitRef::identity(cx.tcx, item.def_id.to_def_id()).self_ty();
+            let self_ty = TraitRef::identity(cx.tcx, item.def_id.to_def_id()).self_ty().skip_binder();
             if !contains_ty(cx.tcx, ret_ty, self_ty);
 
             then {
diff --git a/clippy_lints/src/module_style.rs b/clippy_lints/src/module_style.rs
index 80a930d0c54..f351d0098b7 100644
--- a/clippy_lints/src/module_style.rs
+++ b/clippy_lints/src/module_style.rs
@@ -120,7 +120,7 @@ impl EarlyLintPass for ModStyle {
                     correct.push("mod.rs");
                     cx.struct_span_lint(
                         SELF_NAMED_MODULE_FILES,
-                        Span::new(file.start_pos, file.start_pos, SyntaxContext::root()),
+                        Span::new(file.start_pos, file.start_pos, SyntaxContext::root(), None),
                         |build| {
                             let mut lint =
                                 build.build(&format!("`mod.rs` files are required, found `{}`", path.display()));
@@ -167,7 +167,7 @@ fn check_self_named_mod_exists(cx: &EarlyContext<'_>, path: &Path, file: &Source
 
         cx.struct_span_lint(
             MOD_MODULE_FILES,
-            Span::new(file.start_pos, file.start_pos, SyntaxContext::root()),
+            Span::new(file.start_pos, file.start_pos, SyntaxContext::root(), None),
             |build| {
                 let mut lint = build.build(&format!("`mod.rs` files are not allowed, found `{}`", path.display()));
                 lint.help(&format!("move `{}` to `{}`", path.display(), mod_file.display(),));
diff --git a/clippy_lints/src/redundant_clone.rs b/clippy_lints/src/redundant_clone.rs
index cfa12ef3a32..7041e4f980e 100644
--- a/clippy_lints/src/redundant_clone.rs
+++ b/clippy_lints/src/redundant_clone.rs
@@ -15,7 +15,7 @@ use rustc_middle::mir::{
     Mutability,
 };
 use rustc_middle::ty::{self, fold::TypeVisitor, Ty, TyCtxt};
-use rustc_mir::dataflow::{Analysis, AnalysisDomain, GenKill, GenKillAnalysis, ResultsCursor};
+use rustc_mir_dataflow::{Analysis, AnalysisDomain, GenKill, GenKillAnalysis, ResultsCursor};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::source_map::{BytePos, Span};
 use rustc_span::sym;
diff --git a/clippy_lints/src/regex.rs b/clippy_lints/src/regex.rs
index eab09733730..5d08aee1e5f 100644
--- a/clippy_lints/src/regex.rs
+++ b/clippy_lints/src/regex.rs
@@ -3,10 +3,9 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_help};
 use clippy_utils::{match_def_path, paths};
 use if_chain::if_chain;
 use rustc_ast::ast::{LitKind, StrStyle};
-use rustc_data_structures::fx::FxHashSet;
-use rustc_hir::{BorrowKind, Expr, ExprKind, HirId};
+use rustc_hir::{BorrowKind, Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_session::{declare_tool_lint, impl_lint_pass};
+use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::source_map::{BytePos, Span};
 use std::convert::TryFrom;
 
@@ -52,13 +51,7 @@ declare_clippy_lint! {
     "trivial regular expressions"
 }
 
-#[derive(Clone, Default)]
-pub struct Regex {
-    spans: FxHashSet<Span>,
-    last: Option<HirId>,
-}
-
-impl_lint_pass!(Regex => [INVALID_REGEX, TRIVIAL_REGEX]);
+declare_lint_pass!(Regex => [INVALID_REGEX, TRIVIAL_REGEX]);
 
 impl<'tcx> LateLintPass<'tcx> for Regex {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
@@ -91,7 +84,7 @@ fn str_span(base: Span, c: regex_syntax::ast::Span, offset: u16) -> Span {
     let end = base.lo() + BytePos(u32::try_from(c.end.offset).expect("offset too large") + offset);
     let start = base.lo() + BytePos(u32::try_from(c.start.offset).expect("offset too large") + offset);
     assert!(start <= end);
-    Span::new(start, end, base.ctxt())
+    Span::new(start, end, base.ctxt(), base.parent())
 }
 
 fn const_str<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> Option<String> {
diff --git a/clippy_lints/src/tabs_in_doc_comments.rs b/clippy_lints/src/tabs_in_doc_comments.rs
index 6a73b94d87e..4a67cabf323 100644
--- a/clippy_lints/src/tabs_in_doc_comments.rs
+++ b/clippy_lints/src/tabs_in_doc_comments.rs
@@ -69,6 +69,7 @@ impl TabsInDocComments {
                     attr.span.lo() + BytePos(3 + lo),
                     attr.span.lo() + BytePos(3 + hi),
                     attr.span.ctxt(),
+                    attr.span.parent(),
                 );
                 span_lint_and_sugg(
                     cx,
diff --git a/clippy_lints/src/utils/internal_lints.rs b/clippy_lints/src/utils/internal_lints.rs
index 273684b8e86..3e2a4e9748d 100644
--- a/clippy_lints/src/utils/internal_lints.rs
+++ b/clippy_lints/src/utils/internal_lints.rs
@@ -892,7 +892,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidPaths {
                 }).collect();
             if !check_path(cx, &path[..]);
             then {
-                span_lint(cx, CLIPPY_LINTS_INTERNAL, item.span, "invalid path");
+                span_lint(cx, INVALID_PATHS, item.span, "invalid path");
             }
         }
     }
@@ -1222,5 +1222,10 @@ fn if_chain_local_span(cx: &LateContext<'_>, local: &Local<'_>, if_chain_span: S
     let sm = cx.sess().source_map();
     let span = sm.span_extend_to_prev_str(span, "let", false);
     let span = sm.span_extend_to_next_char(span, ';', false);
-    Span::new(span.lo() - BytePos(3), span.hi() + BytePos(1), span.ctxt())
+    Span::new(
+        span.lo() - BytePos(3),
+        span.hi() + BytePos(1),
+        span.ctxt(),
+        span.parent(),
+    )
 }
diff --git a/clippy_lints/src/utils/internal_lints/metadata_collector.rs b/clippy_lints/src/utils/internal_lints/metadata_collector.rs
index 188d0419c39..0d27874b7af 100644
--- a/clippy_lints/src/utils/internal_lints/metadata_collector.rs
+++ b/clippy_lints/src/utils/internal_lints/metadata_collector.rs
@@ -298,6 +298,7 @@ pub struct ClippyConfiguration {
     default: String,
     lints: Vec<String>,
     doc: String,
+    #[allow(dead_code)]
     deprecation_reason: Option<&'static str>,
 }
 
diff --git a/clippy_utils/Cargo.toml b/clippy_utils/Cargo.toml
index ca1908392b3..e7fca3ae5d4 100644
--- a/clippy_utils/Cargo.toml
+++ b/clippy_utils/Cargo.toml
@@ -5,8 +5,8 @@ edition = "2021"
 publish = false
 
 [dependencies]
-if_chain = "1.0.0"
-rustc-semver="1.1.0"
+if_chain = "1.0"
+rustc-semver = "1.1"
 
 [features]
 deny-warnings = []
diff --git a/clippy_utils/src/higher.rs b/clippy_utils/src/higher.rs
index 64bd4223c05..ba4d50bf744 100644
--- a/clippy_utils/src/higher.rs
+++ b/clippy_utils/src/higher.rs
@@ -105,8 +105,7 @@ impl<'hir> IfLet<'hir> {
             if_else,
         ) = expr.kind
         {
-            let hir = cx.tcx.hir();
-            let mut iter = hir.parent_iter(expr.hir_id);
+            let mut iter = cx.tcx.hir().parent_iter(expr.hir_id);
             if let Some((_, Node::Block(Block { stmts: [], .. }))) = iter.next() {
                 if let Some((
                     _,
@@ -524,28 +523,12 @@ impl FormatArgsExpn<'tcx> {
             if let ExpnKind::Macro(_, name) = expr.span.ctxt().outer_expn_data().kind;
             let name = name.as_str();
             if name.ends_with("format_args") || name.ends_with("format_args_nl");
-
-            if let ExprKind::Match(inner_match, [arm], _) = expr.kind;
-
-            // `match match`, if you will
-            if let ExprKind::Match(args, [inner_arm], _) = inner_match.kind;
-            if let ExprKind::Tup(value_args) = args.kind;
-            if let Some(value_args) = value_args
-                .iter()
-                .map(|e| match e.kind {
-                    ExprKind::AddrOf(_, _, e) => Some(e),
-                    _ => None,
-                })
-                .collect();
-            if let ExprKind::Array(args) = inner_arm.body.kind;
-
-            if let ExprKind::Block(Block { stmts: [], expr: Some(expr), .. }, _) = arm.body.kind;
-            if let ExprKind::Call(_, call_args) = expr.kind;
-            if let Some((strs_ref, fmt_expr)) = match call_args {
+            if let ExprKind::Call(_, args) = expr.kind;
+            if let Some((strs_ref, args, fmt_expr)) = match args {
                 // Arguments::new_v1
-                [strs_ref, _] => Some((strs_ref, None)),
+                [strs_ref, args] => Some((strs_ref, args, None)),
                 // Arguments::new_v1_formatted
-                [strs_ref, _, fmt_expr] => Some((strs_ref, Some(fmt_expr))),
+                [strs_ref, args, fmt_expr, _unsafe_arg] => Some((strs_ref, args, Some(fmt_expr))),
                 _ => None,
             };
             if let ExprKind::AddrOf(BorrowKind::Ref, _, strs_arr) = strs_ref.kind;
@@ -561,6 +544,17 @@ impl FormatArgsExpn<'tcx> {
                     None
                 })
                 .collect();
+            if let ExprKind::AddrOf(BorrowKind::Ref, _, args) = args.kind;
+            if let ExprKind::Match(args, [arm], _) = args.kind;
+            if let ExprKind::Tup(value_args) = args.kind;
+            if let Some(value_args) = value_args
+                .iter()
+                .map(|e| match e.kind {
+                    ExprKind::AddrOf(_, _, e) => Some(e),
+                    _ => None,
+                })
+                .collect();
+            if let ExprKind::Array(args) = arm.body.kind;
             then {
                 Some(FormatArgsExpn {
                     format_string_span: strs_ref.span,
diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs
index 757485d19d2..7f5a1bf9c07 100644
--- a/clippy_utils/src/lib.rs
+++ b/clippy_utils/src/lib.rs
@@ -18,6 +18,7 @@
 extern crate rustc_ast;
 extern crate rustc_ast_pretty;
 extern crate rustc_attr;
+extern crate rustc_const_eval;
 extern crate rustc_data_structures;
 extern crate rustc_errors;
 extern crate rustc_hir;
@@ -25,7 +26,6 @@ extern crate rustc_infer;
 extern crate rustc_lexer;
 extern crate rustc_lint;
 extern crate rustc_middle;
-extern crate rustc_mir;
 extern crate rustc_session;
 extern crate rustc_span;
 extern crate rustc_target;
@@ -520,7 +520,7 @@ pub fn path_to_res(cx: &LateContext<'_>, path: &[&str]) -> Res {
             }
         };
     }
-    fn item_child_by_name<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, name: &str) -> Option<&'tcx Export<HirId>> {
+    fn item_child_by_name<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, name: &str) -> Option<&'tcx Export> {
         tcx.item_children(def_id)
             .iter()
             .find(|item| item.ident.name.as_str() == name)
@@ -557,7 +557,7 @@ pub fn path_to_res(cx: &LateContext<'_>, path: &[&str]) -> Res {
                 None
             }
         });
-    try_res!(last).res
+    try_res!(last).res.expect_non_local()
 }
 
 /// Convenience function to get the `DefId` of a trait by path.
@@ -833,12 +833,11 @@ pub fn capture_local_usage(cx: &LateContext<'tcx>, e: &Expr<'_>) -> CaptureKind
         ExprKind::Path(QPath::Resolved(None, Path { res: Res::Local(_), .. }))
     ));
 
-    let map = cx.tcx.hir();
     let mut child_id = e.hir_id;
     let mut capture = CaptureKind::Value;
     let mut capture_expr_ty = e;
 
-    for (parent_id, parent) in map.parent_iter(e.hir_id) {
+    for (parent_id, parent) in cx.tcx.hir().parent_iter(e.hir_id) {
         if let [Adjustment {
             kind: Adjust::Deref(_) | Adjust::Borrow(AutoBorrow::Ref(..)),
             target,
@@ -1224,8 +1223,7 @@ pub fn get_enclosing_block<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Optio
 
 /// Gets the loop or closure enclosing the given expression, if any.
 pub fn get_enclosing_loop_or_closure(tcx: TyCtxt<'tcx>, expr: &Expr<'_>) -> Option<&'tcx Expr<'tcx>> {
-    let map = tcx.hir();
-    for (_, node) in map.parent_iter(expr.hir_id) {
+    for (_, node) in tcx.hir().parent_iter(expr.hir_id) {
         match node {
             Node::Expr(
                 e
@@ -1244,8 +1242,7 @@ pub fn get_enclosing_loop_or_closure(tcx: TyCtxt<'tcx>, expr: &Expr<'_>) -> Opti
 
 /// Gets the parent node if it's an impl block.
 pub fn get_parent_as_impl(tcx: TyCtxt<'_>, id: HirId) -> Option<&Impl<'_>> {
-    let map = tcx.hir();
-    match map.parent_iter(id).next() {
+    match tcx.hir().parent_iter(id).next() {
         Some((
             _,
             Node::Item(Item {
@@ -1259,8 +1256,7 @@ pub fn get_parent_as_impl(tcx: TyCtxt<'_>, id: HirId) -> Option<&Impl<'_>> {
 
 /// Checks if the given expression is the else clause of either an `if` or `if let` expression.
 pub fn is_else_clause(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> bool {
-    let map = tcx.hir();
-    let mut iter = map.parent_iter(expr.hir_id);
+    let mut iter = tcx.hir().parent_iter(expr.hir_id);
     match iter.next() {
         Some((
             _,
@@ -1794,9 +1790,8 @@ pub fn is_expr_identity_function(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool
 
 /// Gets the node where an expression is either used, or it's type is unified with another branch.
 pub fn get_expr_use_or_unification_node(tcx: TyCtxt<'tcx>, expr: &Expr<'_>) -> Option<Node<'tcx>> {
-    let map = tcx.hir();
     let mut child_id = expr.hir_id;
-    let mut iter = map.parent_iter(child_id);
+    let mut iter = tcx.hir().parent_iter(child_id);
     loop {
         match iter.next() {
             None => break None,
diff --git a/clippy_utils/src/paths.rs b/clippy_utils/src/paths.rs
index d7e46c2d3eb..7a8208c12c0 100644
--- a/clippy_utils/src/paths.rs
+++ b/clippy_utils/src/paths.rs
@@ -68,6 +68,7 @@ pub const IO_WRITE: [&str; 3] = ["std", "io", "Write"];
 pub const IPADDR_V4: [&str; 5] = ["std", "net", "ip", "IpAddr", "V4"];
 pub const IPADDR_V6: [&str; 5] = ["std", "net", "ip", "IpAddr", "V6"];
 pub const ITER_REPEAT: [&str; 5] = ["core", "iter", "sources", "repeat", "repeat"];
+#[allow(clippy::invalid_paths)] // internal lints do not know about all external crates
 pub const ITERTOOLS_NEXT_TUPLE: [&str; 3] = ["itertools", "Itertools", "next_tuple"];
 #[cfg(feature = "internal-lints")]
 pub const KW_MODULE: [&str; 3] = ["rustc_span", "symbol", "kw"];
@@ -104,7 +105,7 @@ pub const PARKING_LOT_RWLOCK_WRITE_GUARD: [&str; 2] = ["parking_lot", "RwLockWri
 pub const PATH_BUF_AS_PATH: [&str; 4] = ["std", "path", "PathBuf", "as_path"];
 pub const PATH_TO_PATH_BUF: [&str; 4] = ["std", "path", "Path", "to_path_buf"];
 pub const PERMISSIONS: [&str; 3] = ["std", "fs", "Permissions"];
-pub const PERMISSIONS_FROM_MODE: [&str; 7] = ["std", "os", "imp", "unix", "fs", "PermissionsExt", "from_mode"];
+pub const PERMISSIONS_FROM_MODE: [&str; 6] = ["std", "os", "unix", "fs", "PermissionsExt", "from_mode"];
 pub const POLL: [&str; 4] = ["core", "task", "poll", "Poll"];
 pub const POLL_PENDING: [&str; 5] = ["core", "task", "poll", "Poll", "Pending"];
 pub const POLL_READY: [&str; 5] = ["core", "task", "poll", "Poll", "Ready"];
diff --git a/clippy_utils/src/qualify_min_const_fn.rs b/clippy_utils/src/qualify_min_const_fn.rs
index 6cb2bd7f6ef..238728f090f 100644
--- a/clippy_utils/src/qualify_min_const_fn.rs
+++ b/clippy_utils/src/qualify_min_const_fn.rs
@@ -192,7 +192,7 @@ fn check_rvalue(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, def_id: DefId, rvalue: &Rv
                 ))
             }
         },
-        Rvalue::NullaryOp(NullOp::SizeOf, _) => Ok(()),
+        Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _) | Rvalue::ShallowInitBox(_, _) => Ok(()),
         Rvalue::NullaryOp(NullOp::Box, _) => Err((span, "heap allocations are not allowed in const fn".into())),
         Rvalue::UnaryOp(_, operand) => {
             let ty = operand.ty(body, tcx);
@@ -364,7 +364,7 @@ fn check_terminator(
 }
 
 fn is_const_fn(tcx: TyCtxt<'_>, def_id: DefId, msrv: Option<&RustcVersion>) -> bool {
-    rustc_mir::const_eval::is_const_fn(tcx, def_id)
+    rustc_const_eval::const_eval::is_const_fn(tcx, def_id)
         && tcx.lookup_const_stability(def_id).map_or(true, |const_stab| {
             if let rustc_attr::StabilityLevel::Stable { since } = const_stab.level {
                 // Checking MSRV is manually necessary because `rustc` has no such concept. This entire
diff --git a/lintcheck/Cargo.toml b/lintcheck/Cargo.toml
index ada033de6e3..f33f1b65eab 100644
--- a/lintcheck/Cargo.toml
+++ b/lintcheck/Cargo.toml
@@ -11,15 +11,15 @@ publish = false
 
 [dependencies]
 clap = "2.33"
-flate2 = {version = "1.0.19"}
-fs_extra = {version = "1.2.0"}
-rayon = {version = "1.5.0"}
-serde = {version = "1.0", features = ["derive"]}
-serde_json = {version = "1.0"}
-tar = {version = "0.4.30"}
-toml = {version = "0.5"}
-ureq = {version = "2.0.0-rc3"}
-walkdir = {version = "2.3.2"}
+flate2 = "1.0"
+fs_extra = "1.2"
+rayon = "1.5"
+serde = { version = "1.0", features = ["derive"] }
+serde_json = "1.0"
+tar = "0.4"
+toml = "0.5"
+ureq = "2.2"
+walkdir = "2.3"
 
 [features]
 deny-warnings = []
diff --git a/rust-toolchain b/rust-toolchain
index 92bde3423a2..660401ff28c 100644
--- a/rust-toolchain
+++ b/rust-toolchain
@@ -1,3 +1,3 @@
 [toolchain]
-channel = "nightly-2021-09-08"
+channel = "nightly-2021-09-28"
 components = ["llvm-tools-preview", "rustc-dev", "rust-src"]
diff --git a/tests/ui-internal/invalid_paths.stderr b/tests/ui-internal/invalid_paths.stderr
index bd69d661b71..20aa81b98a0 100644
--- a/tests/ui-internal/invalid_paths.stderr
+++ b/tests/ui-internal/invalid_paths.stderr
@@ -4,7 +4,7 @@ error: invalid path
 LL |     pub const BAD_CRATE_PATH: [&str; 2] = ["bad", "path"];
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::clippy-lints-internal` implied by `-D warnings`
+   = note: `-D clippy::invalid-paths` implied by `-D warnings`
 
 error: invalid path
   --> $DIR/invalid_paths.rs:20:5
diff --git a/tests/ui/default_trait_access.fixed b/tests/ui/default_trait_access.fixed
index 4c80cabc723..9114d8754dc 100644
--- a/tests/ui/default_trait_access.fixed
+++ b/tests/ui/default_trait_access.fixed
@@ -1,6 +1,6 @@
 // run-rustfix
 
-#![allow(unused_imports)]
+#![allow(unused_imports, dead_code)]
 #![deny(clippy::default_trait_access)]
 
 use std::default;
diff --git a/tests/ui/default_trait_access.rs b/tests/ui/default_trait_access.rs
index a68b6455c04..8a5f0d6a749 100644
--- a/tests/ui/default_trait_access.rs
+++ b/tests/ui/default_trait_access.rs
@@ -1,6 +1,6 @@
 // run-rustfix
 
-#![allow(unused_imports)]
+#![allow(unused_imports, dead_code)]
 #![deny(clippy::default_trait_access)]
 
 use std::default;