about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-01-13 01:40:41 +0000
committerbors <bors@rust-lang.org>2021-01-13 01:40:41 +0000
commit150d1fee04856ff158e34e8d687a7fe59e97ef33 (patch)
treeff41418d95d6a5e8d493980c14fa249f59fc1099 /compiler
parent058a71016553f267ae80b90276ef79956457d51a (diff)
parenta8ff647deb102f4669025be3ba45ae2990ef0c08 (diff)
downloadrust-150d1fee04856ff158e34e8d687a7fe59e97ef33.tar.gz
rust-150d1fee04856ff158e34e8d687a7fe59e97ef33.zip
Auto merge of #79322 - jyn514:refactor-impl, r=estebank
Separate out a `hir::Impl` struct

This makes it possible to pass the `Impl` directly to functions, instead
of having to pass each of the many fields one at a time. It also
simplifies matches in many cases.

See `rustc_save_analysis::dump_visitor::process_impl` or `rustdoc::clean::clean_impl` for a good example of how this makes `impl`s easier to work with.

r? `@petrochenkov` maybe?
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs6
-rw-r--r--compiler/rustc_hir/src/hir.rs37
-rw-r--r--compiler/rustc_hir/src/intravisit.rs4
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs4
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs9
-rw-r--r--compiler/rustc_lint/src/builtin.rs2
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs2
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs2
-rw-r--r--compiler/rustc_middle/src/ty/error.rs3
-rw-r--r--compiler/rustc_mir/src/const_eval/fn_queries.rs2
-rw-r--r--compiler/rustc_mir/src/monomorphize/collector.rs6
-rw-r--r--compiler/rustc_passes/src/check_attr.rs4
-rw-r--r--compiler/rustc_passes/src/dead.rs2
-rw-r--r--compiler/rustc_passes/src/reachable.rs4
-rw-r--r--compiler/rustc_passes/src/stability.rs9
-rw-r--r--compiler/rustc_privacy/src/lib.rs44
-rw-r--r--compiler/rustc_resolve/src/late/lifetimes.rs8
-rw-r--r--compiler/rustc_save_analysis/src/dump_visitor.rs21
-rw-r--r--compiler/rustc_save_analysis/src/lib.rs4
-rw-r--r--compiler/rustc_save_analysis/src/sig.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/wf.rs6
-rw-r--r--compiler/rustc_ty_utils/src/ty.rs17
-rw-r--r--compiler/rustc_typeck/src/astconv/mod.rs4
-rw-r--r--compiler/rustc_typeck/src/check/check.rs10
-rw-r--r--compiler/rustc_typeck/src/check/wfcheck.rs23
-rw-r--r--compiler/rustc_typeck/src/coherence/builtin.rs10
-rw-r--r--compiler/rustc_typeck/src/coherence/inherent_impls.rs4
-rw-r--r--compiler/rustc_typeck/src/coherence/orphan.rs5
-rw-r--r--compiler/rustc_typeck/src/coherence/unsafety.rs9
-rw-r--r--compiler/rustc_typeck/src/collect.rs45
-rw-r--r--compiler/rustc_typeck/src/collect/type_of.rs5
-rw-r--r--compiler/rustc_typeck/src/impl_wf_check.rs6
33 files changed, 174 insertions, 151 deletions
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index eef6d38aa05..4e9f9d66c5b 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -134,7 +134,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
         let old_len = self.in_scope_lifetimes.len();
 
         let parent_generics = match self.items.get(&parent_hir_id).unwrap().kind {
-            hir::ItemKind::Impl { ref generics, .. }
+            hir::ItemKind::Impl(hir::Impl { ref generics, .. })
             | hir::ItemKind::Trait(_, _, ref generics, ..) => &generics.params[..],
             _ => &[],
         };
@@ -431,7 +431,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 // to not cause an assertion failure inside the `lower_defaultness` function.
                 let has_val = true;
                 let (defaultness, defaultness_span) = self.lower_defaultness(defaultness, has_val);
-                hir::ItemKind::Impl {
+                hir::ItemKind::Impl(hir::Impl {
                     unsafety: self.lower_unsafety(unsafety),
                     polarity,
                     defaultness,
@@ -441,7 +441,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     of_trait: trait_ref,
                     self_ty: lowered_ty,
                     items: new_impl_items,
-                }
+                })
             }
             ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref items) => {
                 let bounds = self.lower_param_bounds(bounds, ImplTraitContext::disallowed());
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index acd254ae85c..98c02d57410 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -2562,22 +2562,25 @@ pub enum ItemKind<'hir> {
     TraitAlias(Generics<'hir>, GenericBounds<'hir>),
 
     /// An implementation, e.g., `impl<A> Trait for Foo { .. }`.
-    Impl {
-        unsafety: Unsafety,
-        polarity: ImplPolarity,
-        defaultness: Defaultness,
-        // We do not put a `Span` in `Defaultness` because it breaks foreign crate metadata
-        // decoding as `Span`s cannot be decoded when a `Session` is not available.
-        defaultness_span: Option<Span>,
-        constness: Constness,
-        generics: Generics<'hir>,
-
-        /// The trait being implemented, if any.
-        of_trait: Option<TraitRef<'hir>>,
-
-        self_ty: &'hir Ty<'hir>,
-        items: &'hir [ImplItemRef<'hir>],
-    },
+    Impl(Impl<'hir>),
+}
+
+#[derive(Debug, HashStable_Generic)]
+pub struct Impl<'hir> {
+    pub unsafety: Unsafety,
+    pub polarity: ImplPolarity,
+    pub defaultness: Defaultness,
+    // We do not put a `Span` in `Defaultness` because it breaks foreign crate metadata
+    // decoding as `Span`s cannot be decoded when a `Session` is not available.
+    pub defaultness_span: Option<Span>,
+    pub constness: Constness,
+    pub generics: Generics<'hir>,
+
+    /// The trait being implemented, if any.
+    pub of_trait: Option<TraitRef<'hir>>,
+
+    pub self_ty: &'hir Ty<'hir>,
+    pub items: &'hir [ImplItemRef<'hir>],
 }
 
 impl ItemKind<'_> {
@@ -2590,7 +2593,7 @@ impl ItemKind<'_> {
             | ItemKind::Struct(_, ref generics)
             | ItemKind::Union(_, ref generics)
             | ItemKind::Trait(_, _, ref generics, _, _)
-            | ItemKind::Impl { ref generics, .. } => generics,
+            | ItemKind::Impl(Impl { ref generics, .. }) => generics,
             _ => return None,
         })
     }
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index b0e82214cf9..d01906bc17e 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -611,7 +611,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) {
             // `visit_enum_def()` takes care of visiting the `Item`'s `HirId`.
             visitor.visit_enum_def(enum_definition, generics, item.hir_id, item.span)
         }
-        ItemKind::Impl {
+        ItemKind::Impl(Impl {
             unsafety: _,
             defaultness: _,
             polarity: _,
@@ -621,7 +621,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) {
             ref of_trait,
             ref self_ty,
             items,
-        } => {
+        }) => {
             visitor.visit_id(item.hir_id);
             visitor.visit_generics(generics);
             walk_list!(visitor, visit_trait_ref, of_trait);
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index a9aa192bbcc..ad4bb78419e 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -684,7 +684,7 @@ impl<'a> State<'a> {
                 self.head(visibility_qualified(&item.vis, "union"));
                 self.print_struct(struct_def, generics, item.ident.name, item.span, true);
             }
-            hir::ItemKind::Impl {
+            hir::ItemKind::Impl(hir::Impl {
                 unsafety,
                 polarity,
                 defaultness,
@@ -694,7 +694,7 @@ impl<'a> State<'a> {
                 ref of_trait,
                 ref self_ty,
                 items,
-            } => {
+            }) => {
                 self.head("");
                 self.print_visibility(&item.vis);
                 self.print_defaultness(defaultness);
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs
index 5264854d8eb..c6ae71ba330 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs
@@ -345,9 +345,10 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
         match tcx.hir().get_if_local(def_id) {
             Some(Node::ImplItem(ImplItem { ident, hir_id, .. })) => {
                 match tcx.hir().find(tcx.hir().get_parent_item(*hir_id)) {
-                    Some(Node::Item(Item { kind: ItemKind::Impl { self_ty, .. }, .. })) => {
-                        Some((*ident, self_ty))
-                    }
+                    Some(Node::Item(Item {
+                        kind: ItemKind::Impl(hir::Impl { self_ty, .. }),
+                        ..
+                    })) => Some((*ident, self_ty)),
                     _ => None,
                 }
             }
@@ -367,7 +368,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
                                 let impl_did = tcx.hir().local_def_id(*impl_node);
                                 match tcx.hir().get_if_local(impl_did.to_def_id()) {
                                     Some(Node::Item(Item {
-                                        kind: ItemKind::Impl { self_ty, .. },
+                                        kind: ItemKind::Impl(hir::Impl { self_ty, .. }),
                                         ..
                                     })) if trait_objects.iter().all(|did| {
                                         // FIXME: we should check `self_ty` against the receiver
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 20e476b38cc..4e393df81fd 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -542,7 +542,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
                     return;
                 }
             }
-            hir::ItemKind::Impl { of_trait: Some(ref trait_ref), items, .. } => {
+            hir::ItemKind::Impl(hir::Impl { of_trait: Some(ref trait_ref), items, .. }) => {
                 // If the trait is private, add the impl items to `private_traits` so they don't get
                 // reported for missing docs.
                 let real_trait = trait_ref.path.res.def_id();
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index ccaee8608b6..99614a300a3 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -1283,7 +1283,7 @@ impl EncodeContext<'a, 'tcx> {
                     is_non_exhaustive: variant.is_field_list_non_exhaustive(),
                 }), adt_def.repr)
             }
-            hir::ItemKind::Impl { defaultness, .. } => {
+            hir::ItemKind::Impl(hir::Impl { defaultness, .. }) => {
                 let trait_ref = self.tcx.impl_trait_ref(def_id);
                 let polarity = self.tcx.impl_polarity(def_id);
                 let parent = if let Some(trait_ref) = trait_ref {
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index eb6aded9cb3..209d1838e3e 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -505,7 +505,7 @@ impl<'hir> Map<'hir> {
                     | ItemKind::Union(_, generics)
                     | ItemKind::Trait(_, _, generics, ..)
                     | ItemKind::TraitAlias(generics, _)
-                    | ItemKind::Impl { generics, .. },
+                    | ItemKind::Impl(Impl { generics, .. }),
                 ..
             }) => Some(generics),
             _ => None,
diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs
index fe20925b387..4a74b6a3c4d 100644
--- a/compiler/rustc_middle/src/ty/error.rs
+++ b/compiler/rustc_middle/src/ty/error.rs
@@ -829,7 +829,8 @@ fn foo(&self) -> Self::T { String::new() }
                 }
             }
             Some(hir::Node::Item(hir::Item {
-                kind: hir::ItemKind::Impl { items, .. }, ..
+                kind: hir::ItemKind::Impl(hir::Impl { items, .. }),
+                ..
             })) => {
                 for item in &items[..] {
                     if let hir::AssocItemKind::Type = item.kind {
diff --git a/compiler/rustc_mir/src/const_eval/fn_queries.rs b/compiler/rustc_mir/src/const_eval/fn_queries.rs
index aca822a05bd..8c18dfcb8d0 100644
--- a/compiler/rustc_mir/src/const_eval/fn_queries.rs
+++ b/compiler/rustc_mir/src/const_eval/fn_queries.rs
@@ -126,7 +126,7 @@ fn is_const_impl_raw(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
     matches!(
         node,
         hir::Node::Item(hir::Item {
-            kind: hir::ItemKind::Impl { constness: hir::Constness::Const, .. },
+            kind: hir::ItemKind::Impl(hir::Impl { constness: hir::Constness::Const, .. }),
             ..
         })
     )
diff --git a/compiler/rustc_mir/src/monomorphize/collector.rs b/compiler/rustc_mir/src/monomorphize/collector.rs
index 6370ead97e7..a8f2b4d60e1 100644
--- a/compiler/rustc_mir/src/monomorphize/collector.rs
+++ b/compiler/rustc_mir/src/monomorphize/collector.rs
@@ -1146,8 +1146,8 @@ fn create_mono_items_for_default_impls<'tcx>(
     output: &mut Vec<Spanned<MonoItem<'tcx>>>,
 ) {
     match item.kind {
-        hir::ItemKind::Impl { ref generics, ref items, .. } => {
-            for param in generics.params {
+        hir::ItemKind::Impl(ref impl_) => {
+            for param in impl_.generics.params {
                 match param.kind {
                     hir::GenericParamKind::Lifetime { .. } => {}
                     hir::GenericParamKind::Type { .. } | hir::GenericParamKind::Const { .. } => {
@@ -1167,7 +1167,7 @@ fn create_mono_items_for_default_impls<'tcx>(
                 let param_env = ty::ParamEnv::reveal_all();
                 let trait_ref = tcx.normalize_erasing_regions(param_env, trait_ref);
                 let overridden_methods: FxHashSet<_> =
-                    items.iter().map(|iiref| iiref.ident.normalize_to_macros_2_0()).collect();
+                    impl_.items.iter().map(|iiref| iiref.ident.normalize_to_macros_2_0()).collect();
                 for method in tcx.provided_trait_methods(trait_ref.def_id) {
                     if overridden_methods.contains(&method.ident.normalize_to_macros_2_0()) {
                         continue;
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index a6a61ffc5da..ac73ba7062e 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -32,7 +32,7 @@ pub(crate) fn target_from_impl_item<'tcx>(
             let parent_hir_id = tcx.hir().get_parent_item(impl_item.hir_id);
             let containing_item = tcx.hir().expect_item(parent_hir_id);
             let containing_impl_is_for_trait = match &containing_item.kind {
-                hir::ItemKind::Impl { ref of_trait, .. } => of_trait.is_some(),
+                hir::ItemKind::Impl(impl_) => impl_.of_trait.is_some(),
                 _ => bug!("parent of an ImplItem must be an Impl"),
             };
             if containing_impl_is_for_trait {
@@ -343,7 +343,7 @@ impl CheckAttrVisitor<'tcx> {
                 // We can't link to trait impl's consts.
                 let err = "associated constant in trait implementation block";
                 match containing_item.kind {
-                    ItemKind::Impl { of_trait: Some(_), .. } => Some(err),
+                    ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }) => Some(err),
                     _ => None,
                 }
             }
diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs
index c4fb0cf5b28..80a24c90421 100644
--- a/compiler/rustc_passes/src/dead.rs
+++ b/compiler/rustc_passes/src/dead.rs
@@ -396,7 +396,7 @@ impl<'v, 'k, 'tcx> ItemLikeVisitor<'v> for LifeSeeder<'k, 'tcx> {
                     }
                 }
             }
-            hir::ItemKind::Impl { ref of_trait, items, .. } => {
+            hir::ItemKind::Impl(hir::Impl { ref of_trait, items, .. }) => {
                 if of_trait.is_some() {
                     self.worklist.push(item.hir_id);
                 }
diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs
index fde83af99a5..b237671f8e2 100644
--- a/compiler/rustc_passes/src/reachable.rs
+++ b/compiler/rustc_passes/src/reachable.rs
@@ -349,7 +349,9 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, 'tcx
         }
 
         // We need only trait impls here, not inherent impls, and only non-exported ones
-        if let hir::ItemKind::Impl { of_trait: Some(ref trait_ref), ref items, .. } = item.kind {
+        if let hir::ItemKind::Impl(hir::Impl { of_trait: Some(ref trait_ref), ref items, .. }) =
+            item.kind
+        {
             if !self.access_levels.is_reachable(item.hir_id) {
                 // FIXME(#53488) remove `let`
                 let tcx = self.tcx;
diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs
index def2a501cf4..4a3d6ecf8cc 100644
--- a/compiler/rustc_passes/src/stability.rs
+++ b/compiler/rustc_passes/src/stability.rs
@@ -330,11 +330,12 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> {
             // they don't have their own stability. They still can be annotated as unstable
             // and propagate this unstability to children, but this annotation is completely
             // optional. They inherit stability from their parents when unannotated.
-            hir::ItemKind::Impl { of_trait: None, .. } | hir::ItemKind::ForeignMod { .. } => {
+            hir::ItemKind::Impl(hir::Impl { of_trait: None, .. })
+            | hir::ItemKind::ForeignMod { .. } => {
                 self.in_trait_impl = false;
                 kind = AnnotationKind::Container;
             }
-            hir::ItemKind::Impl { of_trait: Some(_), .. } => {
+            hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }) => {
                 self.in_trait_impl = true;
                 kind = AnnotationKind::DeprecationProhibited;
             }
@@ -503,7 +504,7 @@ impl<'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'tcx> {
         // optional. They inherit stability from their parents when unannotated.
         if !matches!(
             i.kind,
-            hir::ItemKind::Impl { of_trait: None, .. } | hir::ItemKind::ForeignMod { .. }
+            hir::ItemKind::Impl(hir::Impl { of_trait: None, .. }) | hir::ItemKind::ForeignMod { .. }
         ) {
             self.check_missing_stability(i.hir_id, i.span);
         }
@@ -672,7 +673,7 @@ impl Visitor<'tcx> for Checker<'tcx> {
             // For implementations of traits, check the stability of each item
             // individually as it's possible to have a stable trait with unstable
             // items.
-            hir::ItemKind::Impl { of_trait: Some(ref t), self_ty, items, .. } => {
+            hir::ItemKind::Impl(hir::Impl { of_trait: Some(ref t), self_ty, items, .. }) => {
                 if self.tcx.features().staged_api {
                     // If this impl block has an #[unstable] attribute, give an
                     // error if all involved types and traits are stable, because
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index c2db2c82fa1..fb007c406bc 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -632,9 +632,9 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> {
                     }
                 }
             }
-            hir::ItemKind::Impl { ref of_trait, items, .. } => {
-                for impl_item_ref in items {
-                    if of_trait.is_some() || impl_item_ref.vis.node.is_pub() {
+            hir::ItemKind::Impl(ref impl_) => {
+                for impl_item_ref in impl_.items {
+                    if impl_.of_trait.is_some() || impl_item_ref.vis.node.is_pub() {
                         self.update(impl_item_ref.id.hir_id, item_level);
                     }
                 }
@@ -736,11 +736,11 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> {
                 }
             }
             // Visit everything except for private impl items.
-            hir::ItemKind::Impl { items, .. } => {
+            hir::ItemKind::Impl(ref impl_) => {
                 if item_level.is_some() {
                     self.reach(item.hir_id, item_level).generics().predicates().ty().trait_ref();
 
-                    for impl_item_ref in items {
+                    for impl_item_ref in impl_.items {
                         let impl_item_level = self.get(impl_item_ref.id.hir_id);
                         if impl_item_level.is_some() {
                             self.reach(impl_item_ref.id.hir_id, impl_item_level)
@@ -1450,7 +1450,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
             // (i.e., we could just return here to not check them at
             // all, or some worse estimation of whether an impl is
             // publicly visible).
-            hir::ItemKind::Impl { generics: ref g, ref of_trait, ref self_ty, items, .. } => {
+            hir::ItemKind::Impl(ref impl_) => {
                 // `impl [... for] Private` is never visible.
                 let self_contains_private;
                 // `impl [... for] Public<...>`, but not `impl [... for]
@@ -1465,7 +1465,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
                         at_outer_type: true,
                         outer_type_is_public_path: false,
                     };
-                    visitor.visit_ty(&self_ty);
+                    visitor.visit_ty(&impl_.self_ty);
                     self_contains_private = visitor.contains_private;
                     self_is_public_path = visitor.outer_type_is_public_path;
                 }
@@ -1473,7 +1473,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
                 // Miscellaneous info about the impl:
 
                 // `true` iff this is `impl Private for ...`.
-                let not_private_trait = of_trait.as_ref().map_or(
+                let not_private_trait = impl_.of_trait.as_ref().map_or(
                     true, // no trait counts as public trait
                     |tr| {
                         let did = tr.path.res.def_id();
@@ -1494,8 +1494,8 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
                 // directly because we might have `impl<T: Foo<Private>> ...`,
                 // and we shouldn't warn about the generics if all the methods
                 // are private (because `T` won't be visible externally).
-                let trait_or_some_public_method = of_trait.is_some()
-                    || items.iter().any(|impl_item_ref| {
+                let trait_or_some_public_method = impl_.of_trait.is_some()
+                    || impl_.items.iter().any(|impl_item_ref| {
                         let impl_item = self.tcx.hir().impl_item(impl_item_ref.id);
                         match impl_item.kind {
                             hir::ImplItemKind::Const(..) | hir::ImplItemKind::Fn(..) => {
@@ -1506,11 +1506,11 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
                     });
 
                 if !self_contains_private && not_private_trait && trait_or_some_public_method {
-                    intravisit::walk_generics(self, g);
+                    intravisit::walk_generics(self, &impl_.generics);
 
-                    match of_trait {
+                    match impl_.of_trait {
                         None => {
-                            for impl_item_ref in items {
+                            for impl_item_ref in impl_.items {
                                 // This is where we choose whether to walk down
                                 // further into the impl to check its items. We
                                 // should only walk into public items so that we
@@ -1531,7 +1531,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
                                 }
                             }
                         }
-                        Some(tr) => {
+                        Some(ref tr) => {
                             // Any private types in a trait impl fall into three
                             // categories.
                             // 1. mentioned in the trait definition
@@ -1548,7 +1548,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
                             intravisit::walk_path(self, &tr.path);
 
                             // Those in 3. are warned with this call.
-                            for impl_item_ref in items {
+                            for impl_item_ref in impl_.items {
                                 let impl_item = self.tcx.hir().impl_item(impl_item_ref.id);
                                 if let hir::ImplItemKind::TyAlias(ref ty) = impl_item.kind {
                                     self.visit_ty(ty);
@@ -1556,11 +1556,11 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
                             }
                         }
                     }
-                } else if of_trait.is_none() && self_is_public_path {
+                } else if impl_.of_trait.is_none() && self_is_public_path {
                     // `impl Public<Private> { ... }`. Any public static
                     // methods will be visible as `Public::foo`.
                     let mut found_pub_static = false;
-                    for impl_item_ref in items {
+                    for impl_item_ref in impl_.items {
                         if self.item_is_public(&impl_item_ref.id.hir_id, &impl_item_ref.vis) {
                             let impl_item = self.tcx.hir().impl_item(impl_item_ref.id);
                             match impl_item_ref.kind {
@@ -1577,7 +1577,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
                         }
                     }
                     if found_pub_static {
-                        intravisit::walk_generics(self, g)
+                        intravisit::walk_generics(self, &impl_.generics)
                     }
                 }
                 return;
@@ -1970,11 +1970,11 @@ impl<'a, 'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'a, 'tcx>
             // Subitems of inherent impls have their own publicity.
             // A trait impl is public when both its type and its trait are public
             // Subitems of trait impls have inherited publicity.
-            hir::ItemKind::Impl { ref of_trait, items, .. } => {
+            hir::ItemKind::Impl(ref impl_) => {
                 let impl_vis = ty::Visibility::of_impl(item.hir_id, tcx, &Default::default());
                 self.check(item.hir_id, impl_vis).generics().predicates();
-                for impl_item_ref in items {
-                    let impl_item_vis = if of_trait.is_none() {
+                for impl_item_ref in impl_.items {
+                    let impl_item_vis = if impl_.of_trait.is_none() {
                         min(
                             tcx.visibility(tcx.hir().local_def_id(impl_item_ref.id.hir_id)),
                             impl_vis,
@@ -2032,7 +2032,7 @@ fn visibility(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Visibility {
                 Node::ImplItem(impl_item) => {
                     match tcx.hir().get(tcx.hir().get_parent_item(hir_id)) {
                         Node::Item(hir::Item {
-                            kind: hir::ItemKind::Impl { of_trait: Some(tr), .. },
+                            kind: hir::ItemKind::Impl(hir::Impl { of_trait: Some(tr), .. }),
                             ..
                         }) => tr.path.res.opt_def_id().map_or_else(
                             || {
diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs
index d5ba6f3b53b..2634abc704c 100644
--- a/compiler/rustc_resolve/src/late/lifetimes.rs
+++ b/compiler/rustc_resolve/src/late/lifetimes.rs
@@ -409,11 +409,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
             | hir::ItemKind::Union(_, ref generics)
             | hir::ItemKind::Trait(_, _, ref generics, ..)
             | hir::ItemKind::TraitAlias(ref generics, ..)
-            | hir::ItemKind::Impl { ref generics, .. } => {
+            | hir::ItemKind::Impl(hir::Impl { ref generics, .. }) => {
                 self.missing_named_lifetime_spots.push(generics.into());
 
                 // Impls permit `'_` to be used and it is equivalent to "some fresh lifetime name".
-                // This is not true for other kinds of items.x
+                // This is not true for other kinds of items.
                 let track_lifetime_uses = matches!(item.kind, hir::ItemKind::Impl { .. });
                 // These kinds of items have only early-bound lifetime parameters.
                 let mut index = if sub_items_have_self_param(&item.kind) {
@@ -1677,7 +1677,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
             }
             match parent.kind {
                 hir::ItemKind::Trait(_, _, ref generics, ..)
-                | hir::ItemKind::Impl { ref generics, .. } => {
+                | hir::ItemKind::Impl(hir::Impl { ref generics, .. }) => {
                     index += generics.params.len() as u32;
                 }
                 _ => {}
@@ -2102,7 +2102,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
             }
 
             Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(_, body), .. }) => {
-                if let hir::ItemKind::Impl { ref self_ty, ref items, .. } =
+                if let hir::ItemKind::Impl(hir::Impl { ref self_ty, ref items, .. }) =
                     self.tcx.hir().expect_item(self.tcx.hir().get_parent_item(parent)).kind
                 {
                     impl_self = Some(self_ty);
diff --git a/compiler/rustc_save_analysis/src/dump_visitor.rs b/compiler/rustc_save_analysis/src/dump_visitor.rs
index 617a28ed519..2834e7b6322 100644
--- a/compiler/rustc_save_analysis/src/dump_visitor.rs
+++ b/compiler/rustc_save_analysis/src/dump_visitor.rs
@@ -631,14 +631,7 @@ impl<'tcx> DumpVisitor<'tcx> {
         self.dumper.dump_def(&access, enum_data);
     }
 
-    fn process_impl(
-        &mut self,
-        item: &'tcx hir::Item<'tcx>,
-        generics: &'tcx hir::Generics<'tcx>,
-        trait_ref: &'tcx Option<hir::TraitRef<'tcx>>,
-        typ: &'tcx hir::Ty<'tcx>,
-        impl_items: &'tcx [hir::ImplItemRef<'tcx>],
-    ) {
+    fn process_impl(&mut self, item: &'tcx hir::Item<'tcx>, impl_: &'tcx hir::Impl<'tcx>) {
         if let Some(impl_data) = self.save_ctxt.get_item_data(item) {
             if !self.span.filter_generated(item.span) {
                 if let super::Data::RelationData(rel, imp) = impl_data {
@@ -652,12 +645,12 @@ impl<'tcx> DumpVisitor<'tcx> {
 
         let map = &self.tcx.hir();
         self.nest_typeck_results(map.local_def_id(item.hir_id), |v| {
-            v.visit_ty(&typ);
-            if let Some(trait_ref) = trait_ref {
+            v.visit_ty(&impl_.self_ty);
+            if let Some(trait_ref) = &impl_.of_trait {
                 v.process_path(trait_ref.hir_ref_id, &hir::QPath::Resolved(None, &trait_ref.path));
             }
-            v.process_generic_params(generics, "", item.hir_id);
-            for impl_item in impl_items {
+            v.process_generic_params(&impl_.generics, "", item.hir_id);
+            for impl_item in impl_.items {
                 v.process_impl_item(
                     map.impl_item(impl_item.id),
                     map.local_def_id(item.hir_id).to_def_id(),
@@ -1287,9 +1280,7 @@ impl<'tcx> Visitor<'tcx> for DumpVisitor<'tcx> {
                 self.process_struct(item, def, ty_params)
             }
             hir::ItemKind::Enum(ref def, ref ty_params) => self.process_enum(item, def, ty_params),
-            hir::ItemKind::Impl { ref generics, ref of_trait, ref self_ty, ref items, .. } => {
-                self.process_impl(item, generics, of_trait, &self_ty, items)
-            }
+            hir::ItemKind::Impl(ref impl_) => self.process_impl(item, impl_),
             hir::ItemKind::Trait(_, _, ref generics, ref trait_refs, methods) => {
                 self.process_trait(item, generics, trait_refs, methods)
             }
diff --git a/compiler/rustc_save_analysis/src/lib.rs b/compiler/rustc_save_analysis/src/lib.rs
index 056c0b3d9d5..c8cdff4f7e5 100644
--- a/compiler/rustc_save_analysis/src/lib.rs
+++ b/compiler/rustc_save_analysis/src/lib.rs
@@ -318,7 +318,7 @@ impl<'tcx> SaveContext<'tcx> {
                     attributes: lower_attributes(item.attrs.to_vec(), self),
                 }))
             }
-            hir::ItemKind::Impl { ref of_trait, ref self_ty, ref items, .. } => {
+            hir::ItemKind::Impl(hir::Impl { ref of_trait, ref self_ty, ref items, .. }) => {
                 if let hir::TyKind::Path(hir::QPath::Resolved(_, ref path)) = self_ty.kind {
                     // Common case impl for a struct or something basic.
                     if generated_code(path.span) {
@@ -410,7 +410,7 @@ impl<'tcx> SaveContext<'tcx> {
             match self.tcx.impl_of_method(def_id) {
                 Some(impl_id) => match self.tcx.hir().get_if_local(impl_id) {
                     Some(Node::Item(item)) => match item.kind {
-                        hir::ItemKind::Impl { ref self_ty, .. } => {
+                        hir::ItemKind::Impl(hir::Impl { ref self_ty, .. }) => {
                             let hir = self.tcx.hir();
 
                             let mut qualname = String::from("<");
diff --git a/compiler/rustc_save_analysis/src/sig.rs b/compiler/rustc_save_analysis/src/sig.rs
index ab3da270fe6..8ada7e34fe8 100644
--- a/compiler/rustc_save_analysis/src/sig.rs
+++ b/compiler/rustc_save_analysis/src/sig.rs
@@ -501,7 +501,7 @@ impl<'hir> Sig for hir::Item<'hir> {
 
                 Ok(sig)
             }
-            hir::ItemKind::Impl {
+            hir::ItemKind::Impl(hir::Impl {
                 unsafety,
                 polarity,
                 defaultness,
@@ -511,7 +511,7 @@ impl<'hir> Sig for hir::Item<'hir> {
                 ref of_trait,
                 ref self_ty,
                 items: _,
-            } => {
+            }) => {
                 let mut text = String::new();
                 if let hir::Defaultness::Default { .. } = defaultness {
                     text.push_str("default ");
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index 79fea83a667..de94c411c81 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -393,7 +393,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                 hir::Node::Item(hir::Item {
                     kind:
                         hir::ItemKind::Trait(_, _, generics, _, _)
-                        | hir::ItemKind::Impl { generics, .. },
+                        | hir::ItemKind::Impl(hir::Impl { generics, .. }),
                     ..
                 }) if projection.is_some() => {
                     // Missing restriction on associated type of type parameter (unmet projection).
@@ -416,7 +416,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                         | hir::ItemKind::Enum(_, generics)
                         | hir::ItemKind::Union(_, generics)
                         | hir::ItemKind::Trait(_, _, generics, ..)
-                        | hir::ItemKind::Impl { generics, .. }
+                        | hir::ItemKind::Impl(hir::Impl { generics, .. })
                         | hir::ItemKind::Fn(_, generics, _)
                         | hir::ItemKind::TyAlias(_, generics)
                         | hir::ItemKind::TraitAlias(generics, _)
diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs
index 3f58fd72f40..ef87071576d 100644
--- a/compiler/rustc_trait_selection/src/traits/wf.rs
+++ b/compiler/rustc_trait_selection/src/traits/wf.rs
@@ -199,7 +199,7 @@ fn extend_cause_with_original_assoc_item_obligation<'tcx>(
         trait_ref, item, cause, pred
     );
     let items = match item {
-        Some(hir::Item { kind: hir::ItemKind::Impl { items, .. }, .. }) => items,
+        Some(hir::Item { kind: hir::ItemKind::Impl(impl_), .. }) => impl_.items,
         _ => return,
     };
     let fix_span =
@@ -333,7 +333,9 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
                     let mut new_cause = cause.clone();
                     // The first subst is the self ty - use the correct span for it.
                     if i == 0 {
-                        if let Some(hir::ItemKind::Impl { self_ty, .. }) = item.map(|i| &i.kind) {
+                        if let Some(hir::ItemKind::Impl(hir::Impl { self_ty, .. })) =
+                            item.map(|i| &i.kind)
+                        {
                             new_cause.make_mut().span = self_ty.span;
                         }
                     }
diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs
index aa1de6d51cb..1e152d337db 100644
--- a/compiler/rustc_ty_utils/src/ty.rs
+++ b/compiler/rustc_ty_utils/src/ty.rs
@@ -129,8 +129,8 @@ fn associated_item(tcx: TyCtxt<'_>, def_id: DefId) -> ty::AssocItem {
     let parent_def_id = tcx.hir().local_def_id(parent_id);
     let parent_item = tcx.hir().expect_item(parent_id);
     match parent_item.kind {
-        hir::ItemKind::Impl { ref items, .. } => {
-            if let Some(impl_item_ref) = items.iter().find(|i| i.id.hir_id == id) {
+        hir::ItemKind::Impl(ref impl_) => {
+            if let Some(impl_item_ref) = impl_.items.iter().find(|i| i.id.hir_id == id) {
                 let assoc_item =
                     associated_item_from_impl_item_ref(tcx, parent_def_id, impl_item_ref);
                 debug_assert_eq!(assoc_item.def_id, def_id);
@@ -160,8 +160,8 @@ fn associated_item(tcx: TyCtxt<'_>, def_id: DefId) -> ty::AssocItem {
 fn impl_defaultness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::Defaultness {
     let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
     let item = tcx.hir().expect_item(hir_id);
-    if let hir::ItemKind::Impl { defaultness, .. } = item.kind {
-        defaultness
+    if let hir::ItemKind::Impl(impl_) = &item.kind {
+        impl_.defaultness
     } else {
         bug!("`impl_defaultness` called on {:?}", item);
     }
@@ -201,8 +201,9 @@ fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: DefId) -> &[DefId] {
                 .map(|trait_item_ref| trait_item_ref.id)
                 .map(|id| tcx.hir().local_def_id(id.hir_id).to_def_id()),
         ),
-        hir::ItemKind::Impl { ref items, .. } => tcx.arena.alloc_from_iter(
-            items
+        hir::ItemKind::Impl(ref impl_) => tcx.arena.alloc_from_iter(
+            impl_
+                .items
                 .iter()
                 .map(|impl_item_ref| impl_item_ref.id)
                 .map(|id| tcx.hir().local_def_id(id.hir_id).to_def_id()),
@@ -323,8 +324,8 @@ fn well_formed_types_in_env<'tcx>(
         },
 
         Node::Item(item) => match item.kind {
-            ItemKind::Impl { of_trait: Some(_), .. } => NodeKind::TraitImpl,
-            ItemKind::Impl { of_trait: None, .. } => NodeKind::InherentImpl,
+            ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }) => NodeKind::TraitImpl,
+            ItemKind::Impl(hir::Impl { of_trait: None, .. }) => NodeKind::InherentImpl,
             ItemKind::Fn(..) => NodeKind::Fn,
             _ => NodeKind::Other,
         },
diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs
index 405a88fd639..49489000e50 100644
--- a/compiler/rustc_typeck/src/astconv/mod.rs
+++ b/compiler/rustc_typeck/src/astconv/mod.rs
@@ -2011,11 +2011,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                         "generic `Self` types are currently not permitted in anonymous constants",
                     );
                     if let Some(hir::Node::Item(&hir::Item {
-                        kind: hir::ItemKind::Impl { self_ty, .. },
+                        kind: hir::ItemKind::Impl(ref impl_),
                         ..
                     })) = tcx.hir().get_if_local(def_id)
                     {
-                        err.span_note(self_ty.span, "not a concrete type");
+                        err.span_note(impl_.self_ty.span, "not a concrete type");
                     }
                     err.emit();
                     tcx.ty_error()
diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs
index 9bb4c9b3719..f1fb2b80023 100644
--- a/compiler/rustc_typeck/src/check/check.rs
+++ b/compiler/rustc_typeck/src/check/check.rs
@@ -692,11 +692,17 @@ pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item<'tcx>) {
             check_enum(tcx, it.span, &enum_definition.variants, it.hir_id);
         }
         hir::ItemKind::Fn(..) => {} // entirely within check_item_body
-        hir::ItemKind::Impl { ref items, .. } => {
+        hir::ItemKind::Impl(ref impl_) => {
             debug!("ItemKind::Impl {} with id {}", it.ident, it.hir_id);
             let impl_def_id = tcx.hir().local_def_id(it.hir_id);
             if let Some(impl_trait_ref) = tcx.impl_trait_ref(impl_def_id) {
-                check_impl_items_against_trait(tcx, it.span, impl_def_id, impl_trait_ref, items);
+                check_impl_items_against_trait(
+                    tcx,
+                    it.span,
+                    impl_def_id,
+                    impl_trait_ref,
+                    &impl_.items,
+                );
                 let trait_def_id = impl_trait_ref.def_id;
                 check_on_unimplemented(tcx, trait_def_id, it);
             }
diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs
index d81d83f60bd..fc3dff26542 100644
--- a/compiler/rustc_typeck/src/check/wfcheck.rs
+++ b/compiler/rustc_typeck/src/check/wfcheck.rs
@@ -103,35 +103,28 @@ pub fn check_item_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) {
         //
         // won't be allowed unless there's an *explicit* implementation of `Send`
         // for `T`
-        hir::ItemKind::Impl {
-            defaultness,
-            defaultness_span,
-            polarity,
-            ref of_trait,
-            ref self_ty,
-            ..
-        } => {
+        hir::ItemKind::Impl(ref impl_) => {
             let is_auto = tcx
                 .impl_trait_ref(tcx.hir().local_def_id(item.hir_id))
                 .map_or(false, |trait_ref| tcx.trait_is_auto(trait_ref.def_id));
-            if let (hir::Defaultness::Default { .. }, true) = (defaultness, is_auto) {
-                let sp = of_trait.as_ref().map(|t| t.path.span).unwrap_or(item.span);
+            if let (hir::Defaultness::Default { .. }, true) = (impl_.defaultness, is_auto) {
+                let sp = impl_.of_trait.as_ref().map(|t| t.path.span).unwrap_or(item.span);
                 let mut err =
                     tcx.sess.struct_span_err(sp, "impls of auto traits cannot be default");
-                err.span_labels(defaultness_span, "default because of this");
+                err.span_labels(impl_.defaultness_span, "default because of this");
                 err.span_label(sp, "auto trait");
                 err.emit();
             }
             // We match on both `ty::ImplPolarity` and `ast::ImplPolarity` just to get the `!` span.
-            match (tcx.impl_polarity(def_id), polarity) {
+            match (tcx.impl_polarity(def_id), impl_.polarity) {
                 (ty::ImplPolarity::Positive, _) => {
-                    check_impl(tcx, item, self_ty, of_trait);
+                    check_impl(tcx, item, impl_.self_ty, &impl_.of_trait);
                 }
                 (ty::ImplPolarity::Negative, ast::ImplPolarity::Negative(span)) => {
                     // FIXME(#27579): what amount of WF checking do we need for neg impls?
-                    if let hir::Defaultness::Default { .. } = defaultness {
+                    if let hir::Defaultness::Default { .. } = impl_.defaultness {
                         let mut spans = vec![span];
-                        spans.extend(defaultness_span);
+                        spans.extend(impl_.defaultness_span);
                         struct_span_err!(
                             tcx.sess,
                             spans,
diff --git a/compiler/rustc_typeck/src/coherence/builtin.rs b/compiler/rustc_typeck/src/coherence/builtin.rs
index 89270fb6c77..6726b9b4a4b 100644
--- a/compiler/rustc_typeck/src/coherence/builtin.rs
+++ b/compiler/rustc_typeck/src/coherence/builtin.rs
@@ -55,7 +55,7 @@ fn visit_implementation_of_drop(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
 
     let impl_hir_id = tcx.hir().local_def_id_to_hir_id(impl_did);
     let sp = match tcx.hir().expect_item(impl_hir_id).kind {
-        ItemKind::Impl { self_ty, .. } => self_ty.span,
+        ItemKind::Impl(ref impl_) => impl_.self_ty.span,
         _ => bug!("expected Drop impl item"),
     };
 
@@ -80,7 +80,7 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
         Ok(()) => {}
         Err(CopyImplementationError::InfrigingFields(fields)) => {
             let item = tcx.hir().expect_item(impl_hir_id);
-            let span = if let ItemKind::Impl { of_trait: Some(ref tr), .. } = item.kind {
+            let span = if let ItemKind::Impl(hir::Impl { of_trait: Some(ref tr), .. }) = item.kind {
                 tr.path.span
             } else {
                 span
@@ -100,7 +100,7 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
         Err(CopyImplementationError::NotAnAdt) => {
             let item = tcx.hir().expect_item(impl_hir_id);
             let span =
-                if let ItemKind::Impl { self_ty, .. } = item.kind { self_ty.span } else { span };
+                if let ItemKind::Impl(ref impl_) = item.kind { impl_.self_ty.span } else { span };
 
             tcx.sess.emit_err(CopyImplOnNonAdt { span });
         }
@@ -453,7 +453,9 @@ pub fn coerce_unsized_info(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUnsizedI
                     return err_info;
                 } else if diff_fields.len() > 1 {
                     let item = tcx.hir().expect_item(impl_hir_id);
-                    let span = if let ItemKind::Impl { of_trait: Some(ref t), .. } = item.kind {
+                    let span = if let ItemKind::Impl(hir::Impl { of_trait: Some(ref t), .. }) =
+                        item.kind
+                    {
                         t.path.span
                     } else {
                         tcx.hir().span(impl_hir_id)
diff --git a/compiler/rustc_typeck/src/coherence/inherent_impls.rs b/compiler/rustc_typeck/src/coherence/inherent_impls.rs
index 0c1578498b8..6b6c66932c8 100644
--- a/compiler/rustc_typeck/src/coherence/inherent_impls.rs
+++ b/compiler/rustc_typeck/src/coherence/inherent_impls.rs
@@ -45,7 +45,9 @@ struct InherentCollect<'tcx> {
 impl ItemLikeVisitor<'v> for InherentCollect<'tcx> {
     fn visit_item(&mut self, item: &hir::Item<'_>) {
         let (ty, assoc_items) = match item.kind {
-            hir::ItemKind::Impl { of_trait: None, ref self_ty, items, .. } => (self_ty, items),
+            hir::ItemKind::Impl(hir::Impl { of_trait: None, ref self_ty, items, .. }) => {
+                (self_ty, items)
+            }
             _ => return,
         };
 
diff --git a/compiler/rustc_typeck/src/coherence/orphan.rs b/compiler/rustc_typeck/src/coherence/orphan.rs
index 253dcf06e01..9333aac6018 100644
--- a/compiler/rustc_typeck/src/coherence/orphan.rs
+++ b/compiler/rustc_typeck/src/coherence/orphan.rs
@@ -26,7 +26,10 @@ impl ItemLikeVisitor<'v> for OrphanChecker<'tcx> {
     fn visit_item(&mut self, item: &hir::Item<'_>) {
         let def_id = self.tcx.hir().local_def_id(item.hir_id);
         // "Trait" impl
-        if let hir::ItemKind::Impl { generics, of_trait: Some(ref tr), self_ty, .. } = &item.kind {
+        if let hir::ItemKind::Impl(hir::Impl {
+            generics, of_trait: Some(ref tr), self_ty, ..
+        }) = &item.kind
+        {
             debug!(
                 "coherence2::orphan check: trait impl {}",
                 self.tcx.hir().node_to_string(item.hir_id)
diff --git a/compiler/rustc_typeck/src/coherence/unsafety.rs b/compiler/rustc_typeck/src/coherence/unsafety.rs
index 2d9128e7dc0..3a290b7756e 100644
--- a/compiler/rustc_typeck/src/coherence/unsafety.rs
+++ b/compiler/rustc_typeck/src/coherence/unsafety.rs
@@ -86,8 +86,13 @@ impl UnsafetyChecker<'tcx> {
 
 impl ItemLikeVisitor<'v> for UnsafetyChecker<'tcx> {
     fn visit_item(&mut self, item: &'v hir::Item<'v>) {
-        if let hir::ItemKind::Impl { unsafety, polarity, ref generics, .. } = item.kind {
-            self.check_unsafety_coherence(item, Some(generics), unsafety, polarity);
+        if let hir::ItemKind::Impl(ref impl_) = item.kind {
+            self.check_unsafety_coherence(
+                item,
+                Some(&impl_.generics),
+                impl_.unsafety,
+                impl_.polarity,
+            );
         }
     }
 
diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs
index ae97fa3f7e4..20804d55eeb 100644
--- a/compiler/rustc_typeck/src/collect.rs
+++ b/compiler/rustc_typeck/src/collect.rs
@@ -189,7 +189,7 @@ fn reject_placeholder_type_signatures_in_item(tcx: TyCtxt<'tcx>, item: &'tcx hir
         | hir::ItemKind::Enum(_, generics)
         | hir::ItemKind::TraitAlias(generics, _)
         | hir::ItemKind::Trait(_, _, generics, ..)
-        | hir::ItemKind::Impl { generics, .. }
+        | hir::ItemKind::Impl(hir::Impl { generics, .. })
         | hir::ItemKind::Struct(_, generics) => (generics, true),
         hir::ItemKind::OpaqueTy(hir::OpaqueTy { generics, .. })
         | hir::ItemKind::TyAlias(_, generics) => (generics, false),
@@ -531,7 +531,7 @@ fn type_param_predicates(
         Node::Item(item) => {
             match item.kind {
                 ItemKind::Fn(.., ref generics, _)
-                | ItemKind::Impl { ref generics, .. }
+                | ItemKind::Impl(hir::Impl { ref generics, .. })
                 | ItemKind::TyAlias(_, ref generics)
                 | ItemKind::OpaqueTy(OpaqueTy { ref generics, impl_trait_fn: None, .. })
                 | ItemKind::Enum(_, ref generics)
@@ -1310,7 +1310,8 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
 
         Node::Item(item) => {
             match item.kind {
-                ItemKind::Fn(.., ref generics, _) | ItemKind::Impl { ref generics, .. } => generics,
+                ItemKind::Fn(.., ref generics, _)
+                | ItemKind::Impl(hir::Impl { ref generics, .. }) => generics,
 
                 ItemKind::TyAlias(_, ref generics)
                 | ItemKind::Enum(_, ref generics)
@@ -1638,7 +1639,7 @@ fn impl_trait_ref(tcx: TyCtxt<'_>, def_id: DefId) -> Option<ty::TraitRef<'_>> {
 
     let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
     match tcx.hir().expect_item(hir_id).kind {
-        hir::ItemKind::Impl { ref of_trait, .. } => of_trait.as_ref().map(|ast_trait_ref| {
+        hir::ItemKind::Impl(ref impl_) => impl_.of_trait.as_ref().map(|ast_trait_ref| {
             let selfty = tcx.type_of(def_id);
             AstConv::instantiate_mono_trait_ref(&icx, ast_trait_ref, selfty)
         }),
@@ -1651,29 +1652,39 @@ fn impl_polarity(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ImplPolarity {
     let is_rustc_reservation = tcx.has_attr(def_id, sym::rustc_reservation_impl);
     let item = tcx.hir().expect_item(hir_id);
     match &item.kind {
-        hir::ItemKind::Impl { polarity: hir::ImplPolarity::Negative(span), of_trait, .. } => {
+        hir::ItemKind::Impl(hir::Impl {
+            polarity: hir::ImplPolarity::Negative(span),
+            of_trait,
+            ..
+        }) => {
             if is_rustc_reservation {
                 let span = span.to(of_trait.as_ref().map(|t| t.path.span).unwrap_or(*span));
                 tcx.sess.span_err(span, "reservation impls can't be negative");
             }
             ty::ImplPolarity::Negative
         }
-        hir::ItemKind::Impl { polarity: hir::ImplPolarity::Positive, of_trait: None, .. } => {
+        hir::ItemKind::Impl(hir::Impl {
+            polarity: hir::ImplPolarity::Positive,
+            of_trait: None,
+            ..
+        }) => {
             if is_rustc_reservation {
                 tcx.sess.span_err(item.span, "reservation impls can't be inherent");
             }
             ty::ImplPolarity::Positive
         }
-        hir::ItemKind::Impl {
-            polarity: hir::ImplPolarity::Positive, of_trait: Some(_), ..
-        } => {
+        hir::ItemKind::Impl(hir::Impl {
+            polarity: hir::ImplPolarity::Positive,
+            of_trait: Some(_),
+            ..
+        }) => {
             if is_rustc_reservation {
                 ty::ImplPolarity::Reservation
             } else {
                 ty::ImplPolarity::Positive
             }
         }
-        ref item => bug!("impl_polarity: {:?} not an impl", item),
+        item => bug!("impl_polarity: {:?} not an impl", item),
     }
 }
 
@@ -1777,11 +1788,11 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
 
         Node::Item(item) => {
             match item.kind {
-                ItemKind::Impl { defaultness, ref generics, .. } => {
-                    if defaultness.is_default() {
+                ItemKind::Impl(ref impl_) => {
+                    if impl_.defaultness.is_default() {
                         is_default_impl_trait = tcx.impl_trait_ref(def_id);
                     }
-                    generics
+                    &impl_.generics
                 }
                 ItemKind::Fn(.., ref generics, _)
                 | ItemKind::TyAlias(_, ref generics)
@@ -2113,14 +2124,14 @@ fn const_evaluatable_predicates_of<'tcx>(
 
     let mut collector = ConstCollector { tcx, preds: FxIndexSet::default() };
     if let hir::Node::Item(item) = node {
-        if let hir::ItemKind::Impl { ref of_trait, ref self_ty, .. } = item.kind {
-            if let Some(of_trait) = of_trait {
+        if let hir::ItemKind::Impl(ref impl_) = item.kind {
+            if let Some(of_trait) = &impl_.of_trait {
                 debug!("const_evaluatable_predicates_of({:?}): visit impl trait_ref", def_id);
                 collector.visit_trait_ref(of_trait);
             }
 
             debug!("const_evaluatable_predicates_of({:?}): visit_self_ty", def_id);
-            collector.visit_ty(self_ty);
+            collector.visit_ty(impl_.self_ty);
         }
     }
 
@@ -2952,7 +2963,7 @@ fn check_target_feature_trait_unsafe(tcx: TyCtxt<'_>, id: LocalDefId, attr_span:
     if let Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Fn(..), .. }) = node {
         let parent_id = tcx.hir().get_parent_item(hir_id);
         let parent_item = tcx.hir().expect_item(parent_id);
-        if let hir::ItemKind::Impl { of_trait: Some(_), .. } = parent_item.kind {
+        if let hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }) = parent_item.kind {
             tcx.sess
                 .struct_span_err(
                     attr_span,
diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs
index 3c97b55005c..e4eabca9c3b 100644
--- a/compiler/rustc_typeck/src/collect/type_of.rs
+++ b/compiler/rustc_typeck/src/collect/type_of.rs
@@ -243,9 +243,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
                         icx.to_ty(ty)
                     }
                 }
-                ItemKind::TyAlias(ref self_ty, _) | ItemKind::Impl { ref self_ty, .. } => {
-                    icx.to_ty(self_ty)
-                }
+                ItemKind::TyAlias(ref self_ty, _)
+                | ItemKind::Impl(hir::Impl { ref self_ty, .. }) => icx.to_ty(self_ty),
                 ItemKind::Fn(..) => {
                     let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
                     tcx.mk_fn_def(def_id.to_def_id(), substs)
diff --git a/compiler/rustc_typeck/src/impl_wf_check.rs b/compiler/rustc_typeck/src/impl_wf_check.rs
index 14daa97c2c5..0bdcbaac0e9 100644
--- a/compiler/rustc_typeck/src/impl_wf_check.rs
+++ b/compiler/rustc_typeck/src/impl_wf_check.rs
@@ -80,10 +80,10 @@ struct ImplWfCheck<'tcx> {
 
 impl ItemLikeVisitor<'tcx> for ImplWfCheck<'tcx> {
     fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
-        if let hir::ItemKind::Impl { ref items, .. } = item.kind {
+        if let hir::ItemKind::Impl(ref impl_) = item.kind {
             let impl_def_id = self.tcx.hir().local_def_id(item.hir_id);
-            enforce_impl_params_are_constrained(self.tcx, impl_def_id, items);
-            enforce_impl_items_are_distinct(self.tcx, items);
+            enforce_impl_params_are_constrained(self.tcx, impl_def_id, impl_.items);
+            enforce_impl_items_are_distinct(self.tcx, impl_.items);
             if self.min_specialization {
                 check_min_specialization(self.tcx, impl_def_id.to_def_id(), item.span);
             }