about summary refs log tree commit diff
path: root/compiler/rustc_hir/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_hir/src')
-rw-r--r--compiler/rustc_hir/src/def_path_hash_map.rs2
-rw-r--r--compiler/rustc_hir/src/definitions.rs5
-rw-r--r--compiler/rustc_hir/src/hir.rs136
-rw-r--r--compiler/rustc_hir/src/hir/tests.rs4
-rw-r--r--compiler/rustc_hir/src/intravisit.rs122
-rw-r--r--compiler/rustc_hir/src/lang_items.rs9
-rw-r--r--compiler/rustc_hir/src/lib.rs1
-rw-r--r--compiler/rustc_hir/src/stable_hash_impls.rs4
-rw-r--r--compiler/rustc_hir/src/target.rs2
-rw-r--r--compiler/rustc_hir/src/tests.rs2
10 files changed, 149 insertions, 138 deletions
diff --git a/compiler/rustc_hir/src/def_path_hash_map.rs b/compiler/rustc_hir/src/def_path_hash_map.rs
index 9a6dee1e511..35c6e57b877 100644
--- a/compiler/rustc_hir/src/def_path_hash_map.rs
+++ b/compiler/rustc_hir/src/def_path_hash_map.rs
@@ -1,4 +1,4 @@
-use rustc_data_structures::stable_hasher::Hash64;
+use rustc_hashes::Hash64;
 use rustc_span::def_id::DefIndex;
 
 #[derive(Clone, Default)]
diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs
index dc527240f74..c4c309e77e1 100644
--- a/compiler/rustc_hir/src/definitions.rs
+++ b/compiler/rustc_hir/src/definitions.rs
@@ -7,8 +7,9 @@
 use std::fmt::{self, Write};
 use std::hash::Hash;
 
-use rustc_data_structures::stable_hasher::{Hash64, StableHasher};
+use rustc_data_structures::stable_hasher::StableHasher;
 use rustc_data_structures::unord::UnordMap;
+use rustc_hashes::Hash64;
 use rustc_index::IndexVec;
 use rustc_macros::{Decodable, Encodable};
 use rustc_span::{Symbol, kw, sym};
@@ -92,7 +93,7 @@ impl DefPathTable {
 
     pub fn enumerated_keys_and_path_hashes(
         &self,
-    ) -> impl Iterator<Item = (DefIndex, &DefKey, DefPathHash)> + ExactSizeIterator + '_ {
+    ) -> impl Iterator<Item = (DefIndex, &DefKey, DefPathHash)> + ExactSizeIterator {
         self.index_to_key
             .iter_enumerated()
             .map(move |(index, key)| (index, key, self.def_path_hash(index)))
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 1c87a0eb1a7..61f64e62058 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -206,7 +206,7 @@ pub type UsePath<'hir> = Path<'hir, SmallVec<[Res; 3]>>;
 
 impl Path<'_> {
     pub fn is_global(&self) -> bool {
-        !self.segments.is_empty() && self.segments[0].ident.name == kw::PathRoot
+        self.segments.first().is_some_and(|segment| segment.ident.name == kw::PathRoot)
     }
 }
 
@@ -1061,10 +1061,7 @@ impl Attribute {
 
     pub fn value_lit(&self) -> Option<&MetaItemLit> {
         match &self.kind {
-            AttrKind::Normal(n) => match n.as_ref() {
-                AttrItem { args: AttrArgs::Eq { expr, .. }, .. } => Some(expr),
-                _ => None,
-            },
+            AttrKind::Normal(box AttrItem { args: AttrArgs::Eq { expr, .. }, .. }) => Some(expr),
             _ => None,
         }
     }
@@ -1077,12 +1074,9 @@ impl AttributeExt for Attribute {
 
     fn meta_item_list(&self) -> Option<ThinVec<ast::MetaItemInner>> {
         match &self.kind {
-            AttrKind::Normal(n) => match n.as_ref() {
-                AttrItem { args: AttrArgs::Delimited(d), .. } => {
-                    ast::MetaItemKind::list_from_tokens(d.tokens.clone())
-                }
-                _ => None,
-            },
+            AttrKind::Normal(box AttrItem { args: AttrArgs::Delimited(d), .. }) => {
+                ast::MetaItemKind::list_from_tokens(d.tokens.clone())
+            }
             _ => None,
         }
     }
@@ -1098,23 +1092,16 @@ impl AttributeExt for Attribute {
     /// For a single-segment attribute, returns its name; otherwise, returns `None`.
     fn ident(&self) -> Option<Ident> {
         match &self.kind {
-            AttrKind::Normal(n) => {
-                if let [ident] = n.path.segments.as_ref() {
-                    Some(*ident)
-                } else {
-                    None
-                }
-            }
-            AttrKind::DocComment(..) => None,
+            AttrKind::Normal(box AttrItem {
+                path: AttrPath { segments: box [ident], .. }, ..
+            }) => Some(*ident),
+            _ => None,
         }
     }
 
     fn path_matches(&self, name: &[Symbol]) -> bool {
         match &self.kind {
-            AttrKind::Normal(n) => {
-                n.path.segments.len() == name.len()
-                    && n.path.segments.iter().zip(name).all(|(s, n)| s.name == *n)
-            }
+            AttrKind::Normal(n) => n.path.segments.iter().map(|segment| &segment.name).eq(name),
             AttrKind::DocComment(..) => false,
         }
     }
@@ -1128,12 +1115,7 @@ impl AttributeExt for Attribute {
     }
 
     fn is_word(&self) -> bool {
-        match &self.kind {
-            AttrKind::Normal(n) => {
-                matches!(n.args, AttrArgs::Empty)
-            }
-            AttrKind::DocComment(..) => false,
-        }
+        matches!(self.kind, AttrKind::Normal(box AttrItem { args: AttrArgs::Empty, .. }))
     }
 
     fn ident_path(&self) -> Option<SmallVec<[Ident; 1]>> {
@@ -1931,13 +1913,18 @@ pub enum BodyOwnerKind {
 
     /// Initializer of a `static` item.
     Static(Mutability),
+
+    /// Fake body for a global asm to store its const-like value types.
+    GlobalAsm,
 }
 
 impl BodyOwnerKind {
     pub fn is_fn_or_closure(self) -> bool {
         match self {
             BodyOwnerKind::Fn | BodyOwnerKind::Closure => true,
-            BodyOwnerKind::Const { .. } | BodyOwnerKind::Static(_) => false,
+            BodyOwnerKind::Const { .. } | BodyOwnerKind::Static(_) | BodyOwnerKind::GlobalAsm => {
+                false
+            }
         }
     }
 }
@@ -1990,7 +1977,7 @@ impl fmt::Display for ConstContext {
 }
 
 // NOTE: `IntoDiagArg` impl for `ConstContext` lives in `rustc_errors`
-// due to a cyclical dependency between hir that crate.
+// due to a cyclical dependency between hir and that crate.
 
 /// A literal.
 pub type Lit = Spanned<LitKind>;
@@ -3119,10 +3106,10 @@ impl<'hir> Ty<'hir> {
             fn visit_ty(&mut self, t: &'v Ty<'v, AmbigArg>) {
                 if matches!(
                     &t.kind,
-                    TyKind::Path(QPath::Resolved(_, Path {
-                        res: crate::def::Res::SelfTyAlias { .. },
-                        ..
-                    },))
+                    TyKind::Path(QPath::Resolved(
+                        _,
+                        Path { res: crate::def::Res::SelfTyAlias { .. }, .. },
+                    ))
                 ) {
                     self.0.push(t.span);
                     return;
@@ -3438,7 +3425,7 @@ pub enum InlineAsmOperand<'hir> {
         anon_const: &'hir AnonConst,
     },
     SymFn {
-        anon_const: &'hir AnonConst,
+        expr: &'hir Expr<'hir>,
     },
     SymStatic {
         path: QPath<'hir>,
@@ -3464,11 +3451,10 @@ impl<'hir> InlineAsmOperand<'hir> {
     }
 
     pub fn is_clobber(&self) -> bool {
-        matches!(self, InlineAsmOperand::Out {
-            reg: InlineAsmRegOrRegClass::Reg(_),
-            late: _,
-            expr: None
-        })
+        matches!(
+            self,
+            InlineAsmOperand::Out { reg: InlineAsmRegOrRegClass::Reg(_), late: _, expr: None }
+        )
     }
 }
 
@@ -3604,10 +3590,10 @@ impl<'hir> FnRetTy<'hir> {
     }
 
     pub fn is_suggestable_infer_ty(&self) -> Option<&'hir Ty<'hir>> {
-        if let Self::Return(ty) = self {
-            if ty.is_suggestable_infer_ty() {
-                return Some(*ty);
-            }
+        if let Self::Return(ty) = self
+            && ty.is_suggestable_infer_ty()
+        {
+            return Some(*ty);
         }
         None
     }
@@ -3867,7 +3853,7 @@ impl<'hir> Item<'hir> {
         expect_foreign_mod, (ExternAbi, &'hir [ForeignItemRef]),
             ItemKind::ForeignMod { abi, items }, (*abi, items);
 
-        expect_global_asm, &'hir InlineAsm<'hir>, ItemKind::GlobalAsm(asm), asm;
+        expect_global_asm, &'hir InlineAsm<'hir>, ItemKind::GlobalAsm { asm, .. }, asm;
 
         expect_ty_alias, (&'hir Ty<'hir>, &'hir Generics<'hir>),
             ItemKind::TyAlias(ty, generics), (ty, generics);
@@ -3976,11 +3962,11 @@ pub struct FnHeader {
 
 impl FnHeader {
     pub fn is_async(&self) -> bool {
-        matches!(&self.asyncness, IsAsync::Async(_))
+        matches!(self.asyncness, IsAsync::Async(_))
     }
 
     pub fn is_const(&self) -> bool {
-        matches!(&self.constness, Constness::Const)
+        matches!(self.constness, Constness::Const)
     }
 
     pub fn is_unsafe(&self) -> bool {
@@ -4034,7 +4020,15 @@ pub enum ItemKind<'hir> {
     /// An external module, e.g. `extern { .. }`.
     ForeignMod { abi: ExternAbi, items: &'hir [ForeignItemRef] },
     /// Module-level inline assembly (from `global_asm!`).
-    GlobalAsm(&'hir InlineAsm<'hir>),
+    GlobalAsm {
+        asm: &'hir InlineAsm<'hir>,
+        /// A fake body which stores typeck results for the global asm's sym_fn
+        /// operands, which are represented as path expressions. This body contains
+        /// a single [`ExprKind::InlineAsm`] which points to the asm in the field
+        /// above, and which is typechecked like a inline asm expr just for the
+        /// typeck results.
+        fake_body: BodyId,
+    },
     /// A type alias, e.g., `type Foo = Bar<u8>`.
     TyAlias(&'hir Ty<'hir>, &'hir Generics<'hir>),
     /// An enum definition, e.g., `enum Foo<A, B> {C<A>, D<B>}`.
@@ -4076,16 +4070,16 @@ pub struct Impl<'hir> {
 
 impl ItemKind<'_> {
     pub fn generics(&self) -> Option<&Generics<'_>> {
-        Some(match *self {
-            ItemKind::Fn { ref generics, .. }
-            | ItemKind::TyAlias(_, ref generics)
-            | ItemKind::Const(_, ref generics, _)
-            | ItemKind::Enum(_, ref generics)
-            | ItemKind::Struct(_, ref generics)
-            | ItemKind::Union(_, ref generics)
-            | ItemKind::Trait(_, _, ref generics, _, _)
-            | ItemKind::TraitAlias(ref generics, _)
-            | ItemKind::Impl(Impl { ref generics, .. }) => generics,
+        Some(match self {
+            ItemKind::Fn { generics, .. }
+            | ItemKind::TyAlias(_, generics)
+            | ItemKind::Const(_, generics, _)
+            | ItemKind::Enum(_, generics)
+            | ItemKind::Struct(_, generics)
+            | ItemKind::Union(_, generics)
+            | ItemKind::Trait(_, _, generics, _, _)
+            | ItemKind::TraitAlias(generics, _)
+            | ItemKind::Impl(Impl { generics, .. }) => generics,
             _ => return None,
         })
     }
@@ -4100,7 +4094,7 @@ impl ItemKind<'_> {
             ItemKind::Macro(..) => "macro",
             ItemKind::Mod(..) => "module",
             ItemKind::ForeignMod { .. } => "extern block",
-            ItemKind::GlobalAsm(..) => "global asm item",
+            ItemKind::GlobalAsm { .. } => "global asm item",
             ItemKind::TyAlias(..) => "type alias",
             ItemKind::Enum(..) => "enum",
             ItemKind::Struct(..) => "struct",
@@ -4484,16 +4478,14 @@ impl<'hir> Node<'hir> {
 
     /// Get a `hir::Impl` if the node is an impl block for the given `trait_def_id`.
     pub fn impl_block_of_trait(self, trait_def_id: DefId) -> Option<&'hir Impl<'hir>> {
-        match self {
-            Node::Item(Item { kind: ItemKind::Impl(impl_block), .. })
-                if impl_block
-                    .of_trait
-                    .and_then(|trait_ref| trait_ref.trait_def_id())
-                    .is_some_and(|trait_id| trait_id == trait_def_id) =>
-            {
-                Some(impl_block)
-            }
-            _ => None,
+        if let Node::Item(Item { kind: ItemKind::Impl(impl_block), .. }) = self
+            && let Some(trait_ref) = impl_block.of_trait
+            && let Some(trait_id) = trait_ref.trait_def_id()
+            && trait_id == trait_def_id
+        {
+            Some(impl_block)
+        } else {
+            None
         }
     }
 
@@ -4561,6 +4553,10 @@ impl<'hir> Node<'hir> {
                 ..
             }) => Some((owner_id.def_id, *body)),
 
+            Node::Item(Item {
+                owner_id, kind: ItemKind::GlobalAsm { asm: _, fake_body }, ..
+            }) => Some((owner_id.def_id, *fake_body)),
+
             Node::Expr(Expr { kind: ExprKind::Closure(Closure { def_id, body, .. }), .. }) => {
                 Some((*def_id, *body))
             }
diff --git a/compiler/rustc_hir/src/hir/tests.rs b/compiler/rustc_hir/src/hir/tests.rs
index 300d4435530..f75b9662132 100644
--- a/compiler/rustc_hir/src/hir/tests.rs
+++ b/compiler/rustc_hir/src/hir/tests.rs
@@ -9,11 +9,11 @@ macro_rules! define_tests {
             let unambig = $kind::$variant::<'_, ()> { $($init)* };
             let unambig_to_ambig = unsafe { std::mem::transmute::<_, $kind<'_, AmbigArg>>(unambig) };
 
-            assert!(matches!(&unambig_to_ambig, $kind::$variant { $($init)* }));
+            assert!(matches!(&unambig_to_ambig, &$kind::$variant { $($init)* }));
 
             let ambig_to_unambig = unsafe { std::mem::transmute::<_, $kind<'_, ()>>(unambig_to_ambig) };
 
-            assert!(matches!(&ambig_to_unambig, $kind::$variant { $($init)* }));
+            assert!(matches!(&ambig_to_unambig, &$kind::$variant { $($init)* }));
         }
     )*};
 }
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index 6519552d604..d5fa7ec366b 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -18,8 +18,8 @@
 //!    within one another.
 //!    - Example: Examine each expression to look for its type and do some check or other.
 //!    - How: Implement `intravisit::Visitor` and override the `NestedFilter` type to
-//!      `nested_filter::OnlyBodies` (and implement `nested_visit_map`), and use
-//!      `tcx.hir().visit_all_item_likes_in_crate(&mut visitor)`. Within your
+//!      `nested_filter::OnlyBodies` (and implement `maybe_tcx`), and use
+//!      `tcx.hir_visit_all_item_likes_in_crate(&mut visitor)`. Within your
 //!      `intravisit::Visitor` impl, implement methods like `visit_expr()` (don't forget to invoke
 //!      `intravisit::walk_expr()` to keep walking the subparts).
 //!    - Pro: Visitor methods for any kind of HIR node, not just item-like things.
@@ -30,8 +30,8 @@
 //!    - Example: Lifetime resolution, which wants to bring lifetimes declared on the
 //!      impl into scope while visiting the impl-items, and then back out again.
 //!    - How: Implement `intravisit::Visitor` and override the `NestedFilter` type to
-//!      `nested_filter::All` (and implement `nested_visit_map`). Walk your crate with
-//!      `tcx.hir().walk_toplevel_module(visitor)` invoked on `tcx.hir().krate()`.
+//!      `nested_filter::All` (and implement `maybe_tcx`). Walk your crate with
+//!      `tcx.hir_walk_toplevel_module(visitor)`.
 //!    - Pro: Visitor methods for any kind of HIR node, not just item-like things.
 //!    - Pro: Preserves nesting information
 //!    - Con: Does not integrate well into dependency tracking.
@@ -106,45 +106,43 @@ impl<'a> FnKind<'a> {
     }
 }
 
-/// An abstract representation of the HIR `rustc_middle::hir::map::Map`.
-pub trait Map<'hir> {
+/// HIR things retrievable from `TyCtxt`, avoiding an explicit dependence on
+/// `TyCtxt`. The only impls are for `!` (where these functions are never
+/// called) and `TyCtxt` (in `rustc_middle`).
+pub trait HirTyCtxt<'hir> {
     /// Retrieves the `Node` corresponding to `id`.
     fn hir_node(&self, hir_id: HirId) -> Node<'hir>;
-    fn hir_node_by_def_id(&self, def_id: LocalDefId) -> Node<'hir>;
-    fn body(&self, id: BodyId) -> &'hir Body<'hir>;
-    fn item(&self, id: ItemId) -> &'hir Item<'hir>;
-    fn trait_item(&self, id: TraitItemId) -> &'hir TraitItem<'hir>;
-    fn impl_item(&self, id: ImplItemId) -> &'hir ImplItem<'hir>;
-    fn foreign_item(&self, id: ForeignItemId) -> &'hir ForeignItem<'hir>;
+    fn hir_body(&self, id: BodyId) -> &'hir Body<'hir>;
+    fn hir_item(&self, id: ItemId) -> &'hir Item<'hir>;
+    fn hir_trait_item(&self, id: TraitItemId) -> &'hir TraitItem<'hir>;
+    fn hir_impl_item(&self, id: ImplItemId) -> &'hir ImplItem<'hir>;
+    fn hir_foreign_item(&self, id: ForeignItemId) -> &'hir ForeignItem<'hir>;
 }
 
-// Used when no map is actually available, forcing manual implementation of nested visitors.
-impl<'hir> Map<'hir> for ! {
+// Used when no tcx is actually available, forcing manual implementation of nested visitors.
+impl<'hir> HirTyCtxt<'hir> for ! {
     fn hir_node(&self, _: HirId) -> Node<'hir> {
-        *self;
+        unreachable!();
     }
-    fn hir_node_by_def_id(&self, _: LocalDefId) -> Node<'hir> {
-        *self;
+    fn hir_body(&self, _: BodyId) -> &'hir Body<'hir> {
+        unreachable!();
     }
-    fn body(&self, _: BodyId) -> &'hir Body<'hir> {
-        *self;
+    fn hir_item(&self, _: ItemId) -> &'hir Item<'hir> {
+        unreachable!();
     }
-    fn item(&self, _: ItemId) -> &'hir Item<'hir> {
-        *self;
+    fn hir_trait_item(&self, _: TraitItemId) -> &'hir TraitItem<'hir> {
+        unreachable!();
     }
-    fn trait_item(&self, _: TraitItemId) -> &'hir TraitItem<'hir> {
-        *self;
+    fn hir_impl_item(&self, _: ImplItemId) -> &'hir ImplItem<'hir> {
+        unreachable!();
     }
-    fn impl_item(&self, _: ImplItemId) -> &'hir ImplItem<'hir> {
-        *self;
-    }
-    fn foreign_item(&self, _: ForeignItemId) -> &'hir ForeignItem<'hir> {
-        *self;
+    fn hir_foreign_item(&self, _: ForeignItemId) -> &'hir ForeignItem<'hir> {
+        unreachable!();
     }
 }
 
 pub mod nested_filter {
-    use super::Map;
+    use super::HirTyCtxt;
 
     /// Specifies what nested things a visitor wants to visit. By "nested
     /// things", we are referring to bits of HIR that are not directly embedded
@@ -159,7 +157,7 @@ pub mod nested_filter {
     /// See the comments at [`rustc_hir::intravisit`] for more details on the overall
     /// visit strategy.
     pub trait NestedFilter<'hir> {
-        type Map: Map<'hir>;
+        type MaybeTyCtxt: HirTyCtxt<'hir>;
 
         /// Whether the visitor visits nested "item-like" things.
         /// E.g., item, impl-item.
@@ -175,10 +173,10 @@ pub mod nested_filter {
     ///
     /// Use this if you are only walking some particular kind of tree
     /// (i.e., a type, or fn signature) and you don't want to thread a
-    /// HIR map around.
+    /// `tcx` around.
     pub struct None(());
     impl NestedFilter<'_> for None {
-        type Map = !;
+        type MaybeTyCtxt = !;
         const INTER: bool = false;
         const INTRA: bool = false;
     }
@@ -195,7 +193,7 @@ use nested_filter::NestedFilter;
 /// (this is why the module is called `intravisit`, to distinguish it
 /// from the AST's `visit` module, which acts differently). If you
 /// simply want to visit all items in the crate in some order, you
-/// should call `tcx.hir().visit_all_item_likes_in_crate`. Otherwise, see the comment
+/// should call `tcx.hir_visit_all_item_likes_in_crate`. Otherwise, see the comment
 /// on `visit_nested_item` for details on how to visit nested items.
 ///
 /// If you want to ensure that your code handles every variant
@@ -203,18 +201,18 @@ use nested_filter::NestedFilter;
 /// to monitor future changes to `Visitor` in case a new method with a
 /// new default implementation gets introduced.)
 pub trait Visitor<'v>: Sized {
-    // this type should not be overridden, it exists for convenient usage as `Self::Map`
-    type Map: Map<'v> = <Self::NestedFilter as NestedFilter<'v>>::Map;
+    // This type should not be overridden, it exists for convenient usage as `Self::MaybeTyCtxt`.
+    type MaybeTyCtxt: HirTyCtxt<'v> = <Self::NestedFilter as NestedFilter<'v>>::MaybeTyCtxt;
 
     ///////////////////////////////////////////////////////////////////////////
     // Nested items.
 
     /// Override this type to control which nested HIR are visited; see
     /// [`NestedFilter`] for details. If you override this type, you
-    /// must also override [`nested_visit_map`](Self::nested_visit_map).
+    /// must also override [`maybe_tcx`](Self::maybe_tcx).
     ///
     /// **If for some reason you want the nested behavior, but don't
-    /// have a `Map` at your disposal:** then override the
+    /// have a `tcx` at your disposal:** then override the
     /// `visit_nested_XXX` methods. If a new `visit_nested_XXX` variant is
     /// added in the future, it will cause a panic which can be detected
     /// and fixed appropriately.
@@ -226,9 +224,9 @@ pub trait Visitor<'v>: Sized {
 
     /// If `type NestedFilter` is set to visit nested items, this method
     /// must also be overridden to provide a map to retrieve nested items.
-    fn nested_visit_map(&mut self) -> Self::Map {
+    fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt {
         panic!(
-            "nested_visit_map must be implemented or consider using \
+            "maybe_tcx must be implemented or consider using \
             `type NestedFilter = nested_filter::None` (the default)"
         );
     }
@@ -240,10 +238,10 @@ pub trait Visitor<'v>: Sized {
     /// "deep" visit patterns described at
     /// [`rustc_hir::intravisit`]. The only reason to override
     /// this method is if you want a nested pattern but cannot supply a
-    /// [`Map`]; see `nested_visit_map` for advice.
+    /// `TyCtxt`; see `maybe_tcx` for advice.
     fn visit_nested_item(&mut self, id: ItemId) -> Self::Result {
         if Self::NestedFilter::INTER {
-            let item = self.nested_visit_map().item(id);
+            let item = self.maybe_tcx().hir_item(id);
             try_visit!(self.visit_item(item));
         }
         Self::Result::output()
@@ -254,7 +252,7 @@ pub trait Visitor<'v>: Sized {
     /// method.
     fn visit_nested_trait_item(&mut self, id: TraitItemId) -> Self::Result {
         if Self::NestedFilter::INTER {
-            let item = self.nested_visit_map().trait_item(id);
+            let item = self.maybe_tcx().hir_trait_item(id);
             try_visit!(self.visit_trait_item(item));
         }
         Self::Result::output()
@@ -265,7 +263,7 @@ pub trait Visitor<'v>: Sized {
     /// method.
     fn visit_nested_impl_item(&mut self, id: ImplItemId) -> Self::Result {
         if Self::NestedFilter::INTER {
-            let item = self.nested_visit_map().impl_item(id);
+            let item = self.maybe_tcx().hir_impl_item(id);
             try_visit!(self.visit_impl_item(item));
         }
         Self::Result::output()
@@ -276,7 +274,7 @@ pub trait Visitor<'v>: Sized {
     /// method.
     fn visit_nested_foreign_item(&mut self, id: ForeignItemId) -> Self::Result {
         if Self::NestedFilter::INTER {
-            let item = self.nested_visit_map().foreign_item(id);
+            let item = self.maybe_tcx().hir_foreign_item(id);
             try_visit!(self.visit_foreign_item(item));
         }
         Self::Result::output()
@@ -287,7 +285,7 @@ pub trait Visitor<'v>: Sized {
     /// `Self::NestedFilter`.
     fn visit_nested_body(&mut self, id: BodyId) -> Self::Result {
         if Self::NestedFilter::INTRA {
-            let body = self.nested_visit_map().body(id);
+            let body = self.maybe_tcx().hir_body(id);
             try_visit!(self.visit_body(body));
         }
         Self::Result::output()
@@ -345,6 +343,9 @@ pub trait Visitor<'v>: Sized {
     fn visit_pat_expr(&mut self, expr: &'v PatExpr<'v>) -> Self::Result {
         walk_pat_expr(self, expr)
     }
+    fn visit_lit(&mut self, _hir_id: HirId, _lit: &'v Lit, _negated: bool) -> Self::Result {
+        Self::Result::output()
+    }
     fn visit_anon_const(&mut self, c: &'v AnonConst) -> Self::Result {
         walk_anon_const(self, c)
     }
@@ -572,9 +573,13 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V::
             try_visit!(visitor.visit_id(item.hir_id()));
             walk_list!(visitor, visit_foreign_item_ref, items);
         }
-        ItemKind::GlobalAsm(asm) => {
+        ItemKind::GlobalAsm { asm: _, fake_body } => {
             try_visit!(visitor.visit_id(item.hir_id()));
-            try_visit!(visitor.visit_inline_asm(asm, item.hir_id()));
+            // Visit the fake body, which contains the asm statement.
+            // Therefore we should not visit the asm statement again
+            // outside of the body, or some visitors won't have their
+            // typeck results set correctly.
+            try_visit!(visitor.visit_nested_body(fake_body));
         }
         ItemKind::TyAlias(ref ty, ref generics) => {
             try_visit!(visitor.visit_id(item.hir_id()));
@@ -592,9 +597,9 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V::
             defaultness: _,
             polarity: _,
             defaultness_span: _,
-            ref generics,
-            ref of_trait,
-            ref self_ty,
+            generics,
+            of_trait,
+            self_ty,
             items,
         }) => {
             try_visit!(visitor.visit_id(item.hir_id()));
@@ -764,7 +769,7 @@ pub fn walk_pat_field<'v, V: Visitor<'v>>(visitor: &mut V, field: &'v PatField<'
 pub fn walk_pat_expr<'v, V: Visitor<'v>>(visitor: &mut V, expr: &'v PatExpr<'v>) -> V::Result {
     try_visit!(visitor.visit_id(expr.hir_id));
     match &expr.kind {
-        PatExprKind::Lit { .. } => V::Result::output(),
+        PatExprKind::Lit { lit, negated } => visitor.visit_lit(expr.hir_id, lit, *negated),
         PatExprKind::ConstBlock(c) => visitor.visit_inline_const(c),
         PatExprKind::Path(qpath) => visitor.visit_qpath(qpath, expr.hir_id, expr.span),
     }
@@ -912,7 +917,8 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>)
             try_visit!(visitor.visit_expr(expr));
             visit_opt!(visitor, visit_ty_unambig, ty);
         }
-        ExprKind::Lit(_) | ExprKind::Err(_) => {}
+        ExprKind::Lit(lit) => try_visit!(visitor.visit_lit(expression.hir_id, lit, false)),
+        ExprKind::Err(_) => {}
     }
     V::Result::output()
 }
@@ -1043,7 +1049,7 @@ pub fn walk_generic_param<'v, V: Visitor<'v>>(
         }
         GenericParamKind::Const { ref ty, ref default, synthetic: _ } => {
             try_visit!(visitor.visit_ty_unambig(ty));
-            if let Some(ref default) = default {
+            if let Some(default) = default {
                 try_visit!(visitor.visit_const_param_default(param.hir_id, default));
             }
         }
@@ -1399,8 +1405,8 @@ pub fn walk_assoc_item_constraint<'v, V: Visitor<'v>>(
     try_visit!(visitor.visit_generic_args(constraint.gen_args));
     match constraint.kind {
         AssocItemConstraintKind::Equality { ref term } => match term {
-            Term::Ty(ref ty) => try_visit!(visitor.visit_ty_unambig(ty)),
-            Term::Const(ref c) => try_visit!(visitor.visit_const_arg_unambig(c)),
+            Term::Ty(ty) => try_visit!(visitor.visit_ty_unambig(ty)),
+            Term::Const(c) => try_visit!(visitor.visit_const_arg_unambig(c)),
         },
         AssocItemConstraintKind::Bound { bounds } => {
             walk_list!(visitor, visit_param_bound, bounds)
@@ -1440,10 +1446,12 @@ pub fn walk_inline_asm<'v, V: Visitor<'v>>(
                 try_visit!(visitor.visit_expr(in_expr));
                 visit_opt!(visitor, visit_expr, out_expr);
             }
-            InlineAsmOperand::Const { anon_const, .. }
-            | InlineAsmOperand::SymFn { anon_const, .. } => {
+            InlineAsmOperand::Const { anon_const, .. } => {
                 try_visit!(visitor.visit_anon_const(anon_const));
             }
+            InlineAsmOperand::SymFn { expr, .. } => {
+                try_visit!(visitor.visit_expr(expr));
+            }
             InlineAsmOperand::SymStatic { path, .. } => {
                 try_visit!(visitor.visit_qpath(path, id, *op_sp));
             }
diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs
index b6689c95c4b..f5626937ec4 100644
--- a/compiler/rustc_hir/src/lang_items.rs
+++ b/compiler/rustc_hir/src/lang_items.rs
@@ -60,7 +60,7 @@ impl LanguageItems {
         self.reverse_items.get(&def_id).copied()
     }
 
-    pub fn iter(&self) -> impl Iterator<Item = (LangItem, DefId)> + '_ {
+    pub fn iter(&self) -> impl Iterator<Item = (LangItem, DefId)> {
         self.items
             .iter()
             .enumerate()
@@ -351,6 +351,7 @@ language_item_table! {
     PhantomData,             sym::phantom_data,        phantom_data,               Target::Struct,         GenericRequirement::Exact(1);
 
     ManuallyDrop,            sym::manually_drop,       manually_drop,              Target::Struct,         GenericRequirement::None;
+    BikeshedGuaranteedNoDrop, sym::bikeshed_guaranteed_no_drop, bikeshed_guaranteed_no_drop, Target::Trait, GenericRequirement::Exact(0);
 
     MaybeUninit,             sym::maybe_uninit,        maybe_uninit,               Target::Union,          GenericRequirement::None;
 
@@ -370,6 +371,8 @@ language_item_table! {
 
     PointerLike,             sym::pointer_like,        pointer_like,               Target::Trait,          GenericRequirement::Exact(0);
 
+    CoercePointeeValidated, sym::coerce_pointee_validated, coerce_pointee_validated_trait, Target::Trait,     GenericRequirement::Exact(0);
+
     ConstParamTy,            sym::const_param_ty,      const_param_ty_trait,       Target::Trait,          GenericRequirement::Exact(0);
     UnsizedConstParamTy,     sym::unsized_const_param_ty, unsized_const_param_ty_trait, Target::Trait, GenericRequirement::Exact(0);
 
@@ -429,9 +432,13 @@ language_item_table! {
     ContractCheckRequires,     sym::contract_check_requires,      contract_check_requires_fn,      Target::Fn, GenericRequirement::None;
 }
 
+/// The requirement imposed on the generics of a lang item
 pub enum GenericRequirement {
+    /// No restriction on the generics
     None,
+    /// A minimum number of generics that is demanded on a lang item
     Minimum(usize),
+    /// The number of generics must match precisely as stipulated
     Exact(usize),
 }
 
diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs
index 705c167e258..270d4fbec30 100644
--- a/compiler/rustc_hir/src/lib.rs
+++ b/compiler/rustc_hir/src/lib.rs
@@ -5,6 +5,7 @@
 // tidy-alphabetical-start
 #![allow(internal_features)]
 #![feature(associated_type_defaults)]
+#![feature(box_patterns)]
 #![feature(closure_track_caller)]
 #![feature(debug_closure_helpers)]
 #![feature(exhaustive_patterns)]
diff --git a/compiler/rustc_hir/src/stable_hash_impls.rs b/compiler/rustc_hir/src/stable_hash_impls.rs
index db0d0fcf3b9..d7c8a3d5c0a 100644
--- a/compiler/rustc_hir/src/stable_hash_impls.rs
+++ b/compiler/rustc_hir/src/stable_hash_impls.rs
@@ -10,9 +10,7 @@ use crate::hir_id::{HirId, ItemLocalId};
 /// Requirements for a `StableHashingContext` to be used in this crate.
 /// This is a hack to allow using the `HashStable_Generic` derive macro
 /// instead of implementing everything in `rustc_middle`.
-pub trait HashStableContext:
-    rustc_ast::HashStableContext + rustc_target::HashStableContext
-{
+pub trait HashStableContext: rustc_ast::HashStableContext + rustc_abi::HashStableContext {
     fn hash_attr(&mut self, _: &Attribute, hasher: &mut StableHasher);
 }
 
diff --git a/compiler/rustc_hir/src/target.rs b/compiler/rustc_hir/src/target.rs
index f3e8f059c9e..70e95a84e68 100644
--- a/compiler/rustc_hir/src/target.rs
+++ b/compiler/rustc_hir/src/target.rs
@@ -110,7 +110,7 @@ impl Target {
             ItemKind::Macro(..) => Target::MacroDef,
             ItemKind::Mod(..) => Target::Mod,
             ItemKind::ForeignMod { .. } => Target::ForeignMod,
-            ItemKind::GlobalAsm(..) => Target::GlobalAsm,
+            ItemKind::GlobalAsm { .. } => Target::GlobalAsm,
             ItemKind::TyAlias(..) => Target::TyAlias,
             ItemKind::Enum(..) => Target::Enum,
             ItemKind::Struct(..) => Target::Struct,
diff --git a/compiler/rustc_hir/src/tests.rs b/compiler/rustc_hir/src/tests.rs
index e0e63d183c6..0837444ffdb 100644
--- a/compiler/rustc_hir/src/tests.rs
+++ b/compiler/rustc_hir/src/tests.rs
@@ -1,6 +1,6 @@
 #![allow(rustc::symbol_intern_string_literal)]
 
-use rustc_data_structures::stable_hasher::Hash64;
+use rustc_hashes::Hash64;
 use rustc_span::def_id::{DefPathHash, StableCrateId};
 use rustc_span::edition::Edition;
 use rustc_span::{Symbol, create_session_globals_then};