about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTyler Mandry <tmandry@gmail.com>2020-01-17 17:28:14 -0800
committerGitHub <noreply@github.com>2020-01-17 17:28:14 -0800
commitfca3264406c5c8d08c061f6f68ac69c84b0a8a75 (patch)
tree64c1dd239156b936843b7e69e3dc6463476aba6a
parentbafe089d1f033471164e4fb999b8f1abd70923ca (diff)
parent4743995ed3f7a60e5e0b66eb6a095483883d8c90 (diff)
downloadrust-fca3264406c5c8d08c061f6f68ac69c84b0a8a75.tar.gz
rust-fca3264406c5c8d08c061f6f68ac69c84b0a8a75.zip
Rollup merge of #68204 - ecstatic-morse:item-kind-impl, r=oli-obk
Use named fields for `{ast,hir}::ItemKind::Impl`

Currently, the widely used `ItemKind::Impl` variant is a tuple with seven fields. I want to add an eighth in #68140, which means I have to update most matches on this variant anyways. Giving a name to each field improves readability and makes future changes of this nature much simpler.

This change will cause several tools to break. I will fix them once this is merged.
-rw-r--r--src/librustc/hir/check_attr.rs4
-rw-r--r--src/librustc/hir/map/mod.rs8
-rw-r--r--src/librustc/infer/error_reporting/mod.rs2
-rw-r--r--src/librustc/traits/error_reporting/suggestions.rs5
-rw-r--r--src/librustc/traits/util.rs2
-rw-r--r--src/librustc/traits/wf.rs8
-rw-r--r--src/librustc_ast_lowering/item.rs35
-rw-r--r--src/librustc_ast_passes/ast_validation.rs24
-rw-r--r--src/librustc_ast_passes/feature_gate.rs2
-rw-r--r--src/librustc_builtin_macros/deriving/generic/mod.rs16
-rw-r--r--src/librustc_builtin_macros/deriving/mod.rs16
-rw-r--r--src/librustc_hir/hir.rs25
-rw-r--r--src/librustc_hir/intravisit.rs16
-rw-r--r--src/librustc_hir/print.rs16
-rw-r--r--src/librustc_incremental/persist/dirty_clean.rs2
-rw-r--r--src/librustc_lint/builtin.rs6
-rw-r--r--src/librustc_lint/internal.rs2
-rw-r--r--src/librustc_metadata/rmeta/encoder.rs14
-rw-r--r--src/librustc_mir/monomorphize/collector.rs6
-rw-r--r--src/librustc_parse/parser/item.rs20
-rw-r--r--src/librustc_passes/dead.rs8
-rw-r--r--src/librustc_passes/reachable.rs10
-rw-r--r--src/librustc_passes/stability.rs10
-rw-r--r--src/librustc_privacy/lib.rs44
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs2
-rw-r--r--src/librustc_resolve/def_collector.rs2
-rw-r--r--src/librustc_resolve/late.rs16
-rw-r--r--src/librustc_resolve/lifetimes.rs10
-rw-r--r--src/librustc_save_analysis/dump_visitor.rs4
-rw-r--r--src/librustc_save_analysis/lib.rs16
-rw-r--r--src/librustc_save_analysis/sig.rs14
-rw-r--r--src/librustc_traits/lowering/environment.rs4
-rw-r--r--src/librustc_ty/ty.rs8
-rw-r--r--src/librustc_typeck/check/mod.rs10
-rw-r--r--src/librustc_typeck/check/wfcheck.rs6
-rw-r--r--src/librustc_typeck/coherence/builtin.rs9
-rw-r--r--src/librustc_typeck/coherence/inherent_impls.rs2
-rw-r--r--src/librustc_typeck/coherence/orphan.rs4
-rw-r--r--src/librustc_typeck/coherence/unsafety.rs2
-rw-r--r--src/librustc_typeck/collect.rs36
-rw-r--r--src/librustc_typeck/impl_wf_check.rs6
-rw-r--r--src/librustdoc/clean/inline.rs8
-rw-r--r--src/librustdoc/test.rs4
-rw-r--r--src/librustdoc/visit_ast.rs18
-rw-r--r--src/libsyntax/ast.rs23
-rw-r--r--src/libsyntax/mut_visit.rs14
-rw-r--r--src/libsyntax/print/pprust.rs16
-rw-r--r--src/libsyntax/visit.rs16
48 files changed, 296 insertions, 255 deletions
diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs
index 5a99e796553..5a4d7ceea27 100644
--- a/src/librustc/hir/check_attr.rs
+++ b/src/librustc/hir/check_attr.rs
@@ -112,7 +112,7 @@ impl Target {
             ItemKind::Union(..) => Target::Union,
             ItemKind::Trait(..) => Target::Trait,
             ItemKind::TraitAlias(..) => Target::TraitAlias,
-            ItemKind::Impl(..) => Target::Impl,
+            ItemKind::Impl { .. } => Target::Impl,
         }
     }
 
@@ -144,7 +144,7 @@ impl Target {
                 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(_, _, _, _, tr, _, _) => tr.is_some(),
+                    hir::ItemKind::Impl { ref of_trait, .. } => of_trait.is_some(),
                     _ => bug!("parent of an ImplItem must be an Impl"),
                 };
                 if containing_impl_is_for_trait {
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index 46c5ee272d2..6d7f53133a6 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -341,7 +341,7 @@ impl<'hir> Map<'hir> {
                 | ItemKind::Use(..)
                 | ItemKind::ForeignMod(..)
                 | ItemKind::GlobalAsm(..)
-                | ItemKind::Impl(..) => return None,
+                | ItemKind::Impl { .. } => return None,
             },
             Node::ForeignItem(item) => match item.kind {
                 ForeignItemKind::Fn(..) => DefKind::Fn,
@@ -604,7 +604,7 @@ impl<'hir> Map<'hir> {
                 | ItemKind::Union(_, ref generics)
                 | ItemKind::Trait(_, _, ref generics, ..)
                 | ItemKind::TraitAlias(ref generics, _)
-                | ItemKind::Impl(_, _, _, ref generics, ..) => Some(generics),
+                | ItemKind::Impl { ref generics, .. } => Some(generics),
                 _ => None,
             },
             _ => None,
@@ -821,7 +821,7 @@ impl<'hir> Map<'hir> {
                     | ItemKind::Struct(..)
                     | ItemKind::Union(..)
                     | ItemKind::Trait(..)
-                    | ItemKind::Impl(..) => true,
+                    | ItemKind::Impl { .. } => true,
                     _ => false,
                 },
                 Node::ForeignItem(fi) => match fi.kind {
@@ -1332,7 +1332,7 @@ fn hir_id_to_string(map: &Map<'_>, id: HirId, include_id: bool) -> String {
                 ItemKind::Union(..) => "union",
                 ItemKind::Trait(..) => "trait",
                 ItemKind::TraitAlias(..) => "trait alias",
-                ItemKind::Impl(..) => "impl",
+                ItemKind::Impl { .. } => "impl",
             };
             format!("{} {}{}", item_str, path_str(), id_str)
         }
diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs
index febf4f21a67..a2009461fa5 100644
--- a/src/librustc/infer/error_reporting/mod.rs
+++ b/src/librustc/infer/error_reporting/mod.rs
@@ -254,7 +254,7 @@ fn emit_msg_span(
 
 fn item_scope_tag(item: &hir::Item<'_>) -> &'static str {
     match item.kind {
-        hir::ItemKind::Impl(..) => "impl",
+        hir::ItemKind::Impl { .. } => "impl",
         hir::ItemKind::Struct(..) => "struct",
         hir::ItemKind::Union(..) => "union",
         hir::ItemKind::Enum(..) => "enum",
diff --git a/src/librustc/traits/error_reporting/suggestions.rs b/src/librustc/traits/error_reporting/suggestions.rs
index bf6891214ac..c09fd307973 100644
--- a/src/librustc/traits/error_reporting/suggestions.rs
+++ b/src/librustc/traits/error_reporting/suggestions.rs
@@ -88,8 +88,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     ..
                 })
                 | hir::Node::Item(hir::Item {
-                    kind: hir::ItemKind::Impl(_, _, _, generics, ..),
-                    ..
+                    kind: hir::ItemKind::Impl { generics, .. }, ..
                 }) if projection.is_some() => {
                     // Missing associated type bound.
                     suggest_restriction(&generics, "the associated type", err);
@@ -115,7 +114,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     ..
                 })
                 | hir::Node::Item(hir::Item {
-                    kind: hir::ItemKind::Impl(_, _, _, generics, ..),
+                    kind: hir::ItemKind::Impl { generics, .. },
                     span,
                     ..
                 })
diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs
index 65fd809657b..f058a4d2df2 100644
--- a/src/librustc/traits/util.rs
+++ b/src/librustc/traits/util.rs
@@ -651,7 +651,7 @@ pub fn impl_is_default(tcx: TyCtxt<'_>, node_item_def_id: DefId) -> bool {
     match tcx.hir().as_local_hir_id(node_item_def_id) {
         Some(hir_id) => {
             let item = tcx.hir().expect_item(hir_id);
-            if let hir::ItemKind::Impl(_, _, defaultness, ..) = item.kind {
+            if let hir::ItemKind::Impl { defaultness, .. } = item.kind {
                 defaultness.is_default()
             } else {
                 false
diff --git a/src/librustc/traits/wf.rs b/src/librustc/traits/wf.rs
index 2301395f557..869ba5315c1 100644
--- a/src/librustc/traits/wf.rs
+++ b/src/librustc/traits/wf.rs
@@ -229,9 +229,9 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
                         //      |
                         //      = note: expected type `u32`
                         //                 found type `()`
-                        if let Some(hir::ItemKind::Impl(.., impl_items)) = item.map(|i| &i.kind) {
+                        if let Some(hir::ItemKind::Impl { items, .. }) = item.map(|i| &i.kind) {
                             let trait_assoc_item = tcx.associated_item(proj.projection_def_id());
-                            if let Some(impl_item) = impl_items
+                            if let Some(impl_item) = items
                                 .iter()
                                 .filter(|item| item.ident == trait_assoc_item.ident)
                                 .next()
@@ -279,14 +279,14 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
                         //      |     ^^^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `bool`
                         if let (
                             ty::Projection(ty::ProjectionTy { item_def_id, .. }),
-                            Some(hir::ItemKind::Impl(.., impl_items)),
+                            Some(hir::ItemKind::Impl { items, .. }),
                         ) = (&proj.skip_binder().self_ty().kind, item.map(|i| &i.kind))
                         {
                             if let Some((impl_item, trait_assoc_item)) = trait_assoc_items
                                 .filter(|i| i.def_id == *item_def_id)
                                 .next()
                                 .and_then(|trait_assoc_item| {
-                                    impl_items
+                                    items
                                         .iter()
                                         .filter(|i| i.ident == trait_assoc_item.ident)
                                         .next()
diff --git a/src/librustc_ast_lowering/item.rs b/src/librustc_ast_lowering/item.rs
index beb53a19ac4..6da2d457f3c 100644
--- a/src/librustc_ast_lowering/item.rs
+++ b/src/librustc_ast_lowering/item.rs
@@ -67,14 +67,15 @@ impl<'a> Visitor<'a> for ItemLowerer<'a, '_, '_> {
         if let Some(hir_id) = item_hir_id {
             self.lctx.with_parent_item_lifetime_defs(hir_id, |this| {
                 let this = &mut ItemLowerer { lctx: this };
-                if let ItemKind::Impl(.., ref opt_trait_ref, _, _) = item.kind {
-                    if opt_trait_ref.as_ref().map(|tr| tr.constness.is_some()).unwrap_or(false) {
+                if let ItemKind::Impl { ref of_trait, .. } = item.kind {
+                    if of_trait.as_ref().map(|tr| tr.constness.is_some()).unwrap_or(false) {
+                        this.with_trait_impl_ref(of_trait, |this| visit::walk_item(this, item));
                         this.lctx
                             .diagnostic()
                             .span_err(item.span, "const trait impls are not yet implemented");
                     }
 
-                    this.with_trait_impl_ref(opt_trait_ref, |this| visit::walk_item(this, item));
+                    this.with_trait_impl_ref(of_trait, |this| visit::walk_item(this, item));
                 } else {
                     visit::walk_item(this, item);
                 }
@@ -118,7 +119,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 { ref generics, .. }
             | hir::ItemKind::Trait(_, _, ref generics, ..) => &generics.params[..],
             _ => &[],
         };
@@ -173,7 +174,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 vec
             }
             ItemKind::MacroDef(..) => SmallVec::new(),
-            ItemKind::Fn(..) | ItemKind::Impl(.., None, _, _) => smallvec![i.id],
+            ItemKind::Fn(..) | ItemKind::Impl { of_trait: None, .. } => smallvec![i.id],
             ItemKind::Static(ref ty, ..) => {
                 let mut ids = smallvec![i.id];
                 if self.sess.features_untracked().impl_trait_in_bindings {
@@ -361,15 +362,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     self.lower_generics(generics, ImplTraitContext::disallowed()),
                 )
             }
-            ItemKind::Impl(
+            ItemKind::Impl {
                 unsafety,
                 polarity,
                 defaultness,
-                ref ast_generics,
-                ref trait_ref,
-                ref ty,
-                ref impl_items,
-            ) => {
+                generics: ref ast_generics,
+                of_trait: ref trait_ref,
+                self_ty: ref ty,
+                items: ref impl_items,
+            } => {
                 let def_id = self.resolver.definitions().local_def_id(id);
 
                 // Lower the "impl header" first. This ordering is important
@@ -417,15 +418,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         )
                     });
 
-                hir::ItemKind::Impl(
+                hir::ItemKind::Impl {
                     unsafety,
                     polarity,
-                    self.lower_defaultness(defaultness, true /* [1] */),
+                    defaultness: self.lower_defaultness(defaultness, true /* [1] */),
                     generics,
-                    trait_ref,
-                    lowered_ty,
-                    new_impl_items,
-                )
+                    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/src/librustc_ast_passes/ast_validation.rs b/src/librustc_ast_passes/ast_validation.rs
index c915b7ba216..23701459025 100644
--- a/src/librustc_ast_passes/ast_validation.rs
+++ b/src/librustc_ast_passes/ast_validation.rs
@@ -612,9 +612,17 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
         }
 
         match item.kind {
-            ItemKind::Impl(unsafety, polarity, _, _, Some(..), ref ty, ref impl_items) => {
+            ItemKind::Impl {
+                unsafety,
+                polarity,
+                defaultness: _,
+                generics: _,
+                of_trait: Some(_),
+                ref self_ty,
+                ref items,
+            } => {
                 self.invalid_visibility(&item.vis, None);
-                if let TyKind::Err = ty.kind {
+                if let TyKind::Err = self_ty.kind {
                     self.err_handler()
                         .struct_span_err(item.span, "`impl Trait for .. {}` is an obsolete syntax")
                         .help("use `auto trait Trait {}` instead")
@@ -629,7 +637,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                     )
                     .emit();
                 }
-                for impl_item in impl_items {
+                for impl_item in items {
                     self.invalid_visibility(&impl_item.vis, None);
                     if let AssocItemKind::Fn(ref sig, _) = impl_item.kind {
                         self.check_trait_fn_not_const(sig.header.constness);
@@ -637,7 +645,15 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                     }
                 }
             }
-            ItemKind::Impl(unsafety, polarity, defaultness, _, None, _, _) => {
+            ItemKind::Impl {
+                unsafety,
+                polarity,
+                defaultness,
+                generics: _,
+                of_trait: None,
+                self_ty: _,
+                items: _,
+            } => {
                 self.invalid_visibility(
                     &item.vis,
                     Some("place qualifiers on individual impl items instead"),
diff --git a/src/librustc_ast_passes/feature_gate.rs b/src/librustc_ast_passes/feature_gate.rs
index 1e4b1ae0777..71cd66ddef4 100644
--- a/src/librustc_ast_passes/feature_gate.rs
+++ b/src/librustc_ast_passes/feature_gate.rs
@@ -339,7 +339,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
                 }
             }
 
-            ast::ItemKind::Impl(_, polarity, defaultness, ..) => {
+            ast::ItemKind::Impl { polarity, defaultness, .. } => {
                 if polarity == ast::ImplPolarity::Negative {
                     gate_feature_post!(
                         &self,
diff --git a/src/librustc_builtin_macros/deriving/generic/mod.rs b/src/librustc_builtin_macros/deriving/generic/mod.rs
index 9226f458165..d346dbc8b4e 100644
--- a/src/librustc_builtin_macros/deriving/generic/mod.rs
+++ b/src/librustc_builtin_macros/deriving/generic/mod.rs
@@ -705,15 +705,15 @@ impl<'a> TraitDef<'a> {
             self.span,
             Ident::invalid(),
             a,
-            ast::ItemKind::Impl(
+            ast::ItemKind::Impl {
                 unsafety,
-                ast::ImplPolarity::Positive,
-                ast::Defaultness::Final,
-                trait_generics,
-                opt_trait_ref,
-                self_type,
-                methods.into_iter().chain(associated_types).collect(),
-            ),
+                polarity: ast::ImplPolarity::Positive,
+                defaultness: ast::Defaultness::Final,
+                generics: trait_generics,
+                of_trait: opt_trait_ref,
+                self_ty: self_type,
+                items: methods.into_iter().chain(associated_types).collect(),
+            },
         )
     }
 
diff --git a/src/librustc_builtin_macros/deriving/mod.rs b/src/librustc_builtin_macros/deriving/mod.rs
index 4d83a6635ab..9aa7623dc9f 100644
--- a/src/librustc_builtin_macros/deriving/mod.rs
+++ b/src/librustc_builtin_macros/deriving/mod.rs
@@ -156,15 +156,15 @@ fn inject_impl_of_structural_trait(
         span,
         ast::Ident::invalid(),
         attrs,
-        ItemKind::Impl(
-            ast::Unsafety::Normal,
-            ast::ImplPolarity::Positive,
-            ast::Defaultness::Final,
+        ItemKind::Impl {
+            unsafety: ast::Unsafety::Normal,
+            polarity: ast::ImplPolarity::Positive,
+            defaultness: ast::Defaultness::Final,
             generics,
-            Some(trait_ref),
-            self_type,
-            Vec::new(),
-        ),
+            of_trait: Some(trait_ref),
+            self_ty: self_type,
+            items: Vec::new(),
+        },
     );
 
     push(Annotatable::Item(newitem));
diff --git a/src/librustc_hir/hir.rs b/src/librustc_hir/hir.rs
index 5c1d600c837..1fef871b514 100644
--- a/src/librustc_hir/hir.rs
+++ b/src/librustc_hir/hir.rs
@@ -2436,15 +2436,18 @@ pub enum ItemKind<'hir> {
     TraitAlias(Generics<'hir>, GenericBounds<'hir>),
 
     /// An implementation, e.g., `impl<A> Trait for Foo { .. }`.
-    Impl(
-        Unsafety,
-        ImplPolarity,
-        Defaultness,
-        Generics<'hir>,
-        Option<TraitRef<'hir>>, // (optional) trait this impl implements
-        &'hir Ty<'hir>,         // self
-        &'hir [ImplItemRef<'hir>],
-    ),
+    Impl {
+        unsafety: Unsafety,
+        polarity: ImplPolarity,
+        defaultness: Defaultness,
+        generics: Generics<'hir>,
+
+        /// The trait being implemented, if any.
+        of_trait: Option<TraitRef<'hir>>,
+
+        self_ty: &'hir Ty<'hir>,
+        items: &'hir [ImplItemRef<'hir>],
+    },
 }
 
 impl ItemKind<'_> {
@@ -2465,7 +2468,7 @@ impl ItemKind<'_> {
             ItemKind::Union(..) => "union",
             ItemKind::Trait(..) => "trait",
             ItemKind::TraitAlias(..) => "trait alias",
-            ItemKind::Impl(..) => "impl",
+            ItemKind::Impl { .. } => "impl",
         }
     }
 
@@ -2478,7 +2481,7 @@ impl ItemKind<'_> {
             | ItemKind::Struct(_, ref generics)
             | ItemKind::Union(_, ref generics)
             | ItemKind::Trait(_, _, ref generics, _, _)
-            | ItemKind::Impl(_, _, _, ref generics, _, _, _) => generics,
+            | ItemKind::Impl { ref generics, .. } => generics,
             _ => return None,
         })
     }
diff --git a/src/librustc_hir/intravisit.rs b/src/librustc_hir/intravisit.rs
index 3dbc5253a9a..1a73e41db9d 100644
--- a/src/librustc_hir/intravisit.rs
+++ b/src/librustc_hir/intravisit.rs
@@ -566,12 +566,20 @@ 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(.., ref generics, ref opt_trait_reference, ref typ, impl_item_refs) => {
+        ItemKind::Impl {
+            unsafety: _,
+            defaultness: _,
+            polarity: _,
+            ref generics,
+            ref of_trait,
+            ref self_ty,
+            items,
+        } => {
             visitor.visit_id(item.hir_id);
             visitor.visit_generics(generics);
-            walk_list!(visitor, visit_trait_ref, opt_trait_reference);
-            visitor.visit_ty(typ);
-            walk_list!(visitor, visit_impl_item_ref, impl_item_refs);
+            walk_list!(visitor, visit_trait_ref, of_trait);
+            visitor.visit_ty(self_ty);
+            walk_list!(visitor, visit_impl_item_ref, items);
         }
         ItemKind::Struct(ref struct_definition, ref generics)
         | ItemKind::Union(ref struct_definition, ref generics) => {
diff --git a/src/librustc_hir/print.rs b/src/librustc_hir/print.rs
index 759f423070a..6c7d4193953 100644
--- a/src/librustc_hir/print.rs
+++ b/src/librustc_hir/print.rs
@@ -627,15 +627,15 @@ 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 {
                 unsafety,
                 polarity,
                 defaultness,
                 ref generics,
-                ref opt_trait,
-                ref ty,
-                impl_items,
-            ) => {
+                ref of_trait,
+                ref self_ty,
+                items,
+            } => {
                 self.head("");
                 self.print_visibility(&item.vis);
                 self.print_defaultness(defaultness);
@@ -651,19 +651,19 @@ impl<'a> State<'a> {
                     self.s.word("!");
                 }
 
-                if let Some(ref t) = opt_trait {
+                if let Some(ref t) = of_trait {
                     self.print_trait_ref(t);
                     self.s.space();
                     self.word_space("for");
                 }
 
-                self.print_type(&ty);
+                self.print_type(&self_ty);
                 self.print_where_clause(&generics.where_clause);
 
                 self.s.space();
                 self.bopen();
                 self.print_inner_attributes(&item.attrs);
-                for impl_item in impl_items {
+                for impl_item in items {
                     self.ann.nested(self, Nested::ImplItem(impl_item.id));
                 }
                 self.bclose(item.span);
diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs
index ddfed53fa33..c5e74868bda 100644
--- a/src/librustc_incremental/persist/dirty_clean.rs
+++ b/src/librustc_incremental/persist/dirty_clean.rs
@@ -315,7 +315,7 @@ impl DirtyCleanVisitor<'tcx> {
                     //HirItem::Trait(..) => ("ItemTrait", LABELS_TRAIT),
 
                     // An implementation, eg `impl<A> Trait for Foo { .. }`
-                    HirItem::Impl(..) => ("ItemKind::Impl", LABELS_IMPL),
+                    HirItem::Impl { .. } => ("ItemKind::Impl", LABELS_IMPL),
 
                     _ => self.tcx.sess.span_fatal(
                         attr.span,
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index 6314c2b9953..c8d3d5f9c83 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -251,7 +251,7 @@ impl EarlyLintPass for UnsafeCode {
                 self.report_unsafe(cx, it.span, "declaration of an `unsafe` trait")
             }
 
-            ast::ItemKind::Impl(ast::Unsafety::Unsafe, ..) => {
+            ast::ItemKind::Impl { unsafety: ast::Unsafety::Unsafe, .. } => {
                 self.report_unsafe(cx, it.span, "implementation of an `unsafe` trait")
             }
 
@@ -431,7 +431,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc {
                 "a trait"
             }
             hir::ItemKind::TyAlias(..) => "a type alias",
-            hir::ItemKind::Impl(.., Some(ref trait_ref), _, impl_item_refs) => {
+            hir::ItemKind::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();
@@ -439,7 +439,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc {
                     match cx.tcx.hir().find(hir_id) {
                         Some(Node::Item(item)) => {
                             if let hir::VisibilityKind::Inherited = item.vis.node {
-                                for impl_item_ref in impl_item_refs {
+                                for impl_item_ref in items {
                                     self.private_traits.insert(impl_item_ref.id.hir_id);
                                 }
                             }
diff --git a/src/librustc_lint/internal.rs b/src/librustc_lint/internal.rs
index 5a5aedc2e97..91aeccbb5e3 100644
--- a/src/librustc_lint/internal.rs
+++ b/src/librustc_lint/internal.rs
@@ -221,7 +221,7 @@ declare_lint_pass!(LintPassImpl => [LINT_PASS_IMPL_WITHOUT_MACRO]);
 
 impl EarlyLintPass for LintPassImpl {
     fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
-        if let ItemKind::Impl(_, _, _, _, Some(lint_pass), _, _) = &item.kind {
+        if let ItemKind::Impl { of_trait: Some(lint_pass), .. } = &item.kind {
             if let Some(last) = lint_pass.path.segments.last() {
                 if last.ident.name == sym::LintPass {
                     let expn_data = lint_pass.path.span.ctxt().outer_expn_data();
diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs
index 8ad92ce75a8..9d2bea28c8c 100644
--- a/src/librustc_metadata/rmeta/encoder.rs
+++ b/src/librustc_metadata/rmeta/encoder.rs
@@ -1073,7 +1073,7 @@ impl EncodeContext<'tcx> {
                     ctor: None,
                 }), adt_def.repr)
             }
-            hir::ItemKind::Impl(_, _, defaultness, ..) => {
+            hir::ItemKind::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 {
@@ -1149,7 +1149,7 @@ impl EncodeContext<'tcx> {
                     })
                 )
             }
-            hir::ItemKind::Impl(..) | hir::ItemKind::Trait(..) => {
+            hir::ItemKind::Impl { .. } | hir::ItemKind::Trait(..) => {
                 let associated_item_def_ids = self.tcx.associated_item_def_ids(def_id);
                 record!(self.per_def.children[def_id] <-
                     associated_item_def_ids.iter().map(|&def_id| {
@@ -1172,13 +1172,13 @@ impl EncodeContext<'tcx> {
             | hir::ItemKind::Enum(..)
             | hir::ItemKind::Struct(..)
             | hir::ItemKind::Union(..)
-            | hir::ItemKind::Impl(..) => self.encode_item_type(def_id),
+            | hir::ItemKind::Impl { .. } => self.encode_item_type(def_id),
             _ => {}
         }
         if let hir::ItemKind::Fn(..) = item.kind {
             record!(self.per_def.fn_sig[def_id] <- tcx.fn_sig(def_id));
         }
-        if let hir::ItemKind::Impl(..) = item.kind {
+        if let hir::ItemKind::Impl { .. } = item.kind {
             if let Some(trait_ref) = self.tcx.impl_trait_ref(def_id) {
                 record!(self.per_def.impl_trait_ref[def_id] <- trait_ref);
             }
@@ -1199,7 +1199,7 @@ impl EncodeContext<'tcx> {
             | hir::ItemKind::Enum(..)
             | hir::ItemKind::Struct(..)
             | hir::ItemKind::Union(..)
-            | hir::ItemKind::Impl(..)
+            | hir::ItemKind::Impl { .. }
             | hir::ItemKind::OpaqueTy(..)
             | hir::ItemKind::Trait(..)
             | hir::ItemKind::TraitAlias(..) => {
@@ -1645,7 +1645,7 @@ impl EncodeContext<'tcx> {
             hir::ItemKind::Union(..) => {
                 self.encode_fields(def_id);
             }
-            hir::ItemKind::Impl(..) => {
+            hir::ItemKind::Impl { .. } => {
                 for &trait_item_def_id in self.tcx.associated_item_def_ids(def_id).iter() {
                     self.encode_info_for_impl_item(trait_item_def_id);
                 }
@@ -1666,7 +1666,7 @@ struct ImplVisitor<'tcx> {
 
 impl<'tcx, 'v> ItemLikeVisitor<'v> for ImplVisitor<'tcx> {
     fn visit_item(&mut self, item: &hir::Item<'_>) {
-        if let hir::ItemKind::Impl(..) = item.kind {
+        if let hir::ItemKind::Impl { .. } = item.kind {
             let impl_id = self.tcx.hir().local_def_id(item.hir_id);
             if let Some(trait_ref) = self.tcx.impl_trait_ref(impl_id) {
                 self.impls.entry(trait_ref.def_id).or_default().push(impl_id.index);
diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs
index 85377180bea..f4611c32e0a 100644
--- a/src/librustc_mir/monomorphize/collector.rs
+++ b/src/librustc_mir/monomorphize/collector.rs
@@ -954,7 +954,7 @@ impl ItemLikeVisitor<'v> for RootCollector<'_, 'v> {
                 // Nothing to do, just keep recursing.
             }
 
-            hir::ItemKind::Impl(..) => {
+            hir::ItemKind::Impl { .. } => {
                 if self.mode == MonoItemCollectionMode::Eager {
                     create_mono_items_for_default_impls(self.tcx, item, self.output);
                 }
@@ -1098,7 +1098,7 @@ fn create_mono_items_for_default_impls<'tcx>(
     output: &mut Vec<MonoItem<'tcx>>,
 ) {
     match item.kind {
-        hir::ItemKind::Impl(_, _, _, ref generics, .., ref impl_item_refs) => {
+        hir::ItemKind::Impl { ref generics, ref items, .. } => {
             for param in generics.params {
                 match param.kind {
                     hir::GenericParamKind::Lifetime { .. } => {}
@@ -1119,7 +1119,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<_> =
-                    impl_item_refs.iter().map(|iiref| iiref.ident.modern()).collect();
+                    items.iter().map(|iiref| iiref.ident.modern()).collect();
                 for method in tcx.provided_trait_methods(trait_ref.def_id) {
                     if overridden_methods.contains(&method.ident.modern()) {
                         continue;
diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs
index d4756dff49a..1921a6c8506 100644
--- a/src/librustc_parse/parser/item.rs
+++ b/src/librustc_parse/parser/item.rs
@@ -634,15 +634,15 @@ impl<'a> Parser<'a> {
                 let constness = constness.map(|c| c.node);
                 let trait_ref = TraitRef { path, constness, ref_id: ty_first.id };
 
-                ItemKind::Impl(
+                ItemKind::Impl {
                     unsafety,
                     polarity,
                     defaultness,
                     generics,
-                    Some(trait_ref),
-                    ty_second,
-                    impl_items,
-                )
+                    of_trait: Some(trait_ref),
+                    self_ty: ty_second,
+                    items: impl_items,
+                }
             }
             None => {
                 // Reject `impl const Type {}` here
@@ -653,15 +653,15 @@ impl<'a> Parser<'a> {
                 }
 
                 // impl Type
-                ItemKind::Impl(
+                ItemKind::Impl {
                     unsafety,
                     polarity,
                     defaultness,
                     generics,
-                    None,
-                    ty_first,
-                    impl_items,
-                )
+                    of_trait: None,
+                    self_ty: ty_first,
+                    items: impl_items,
+                }
             }
         };
 
diff --git a/src/librustc_passes/dead.rs b/src/librustc_passes/dead.rs
index f2778b2aa6b..2ff9d744f2c 100644
--- a/src/librustc_passes/dead.rs
+++ b/src/librustc_passes/dead.rs
@@ -405,10 +405,10 @@ impl<'v, 'k, 'tcx> ItemLikeVisitor<'v> for LifeSeeder<'k, 'tcx> {
                     }
                 }
             }
-            hir::ItemKind::Impl(.., ref opt_trait, _, impl_item_refs) => {
-                for impl_item_ref in impl_item_refs {
+            hir::ItemKind::Impl { ref of_trait, items, .. } => {
+                for impl_item_ref in items {
                     let impl_item = self.krate.impl_item(impl_item_ref.id);
-                    if opt_trait.is_some()
+                    if of_trait.is_some()
                         || has_allow_dead_code_or_lang_attr(
                             self.tcx,
                             impl_item.hir_id,
@@ -586,7 +586,7 @@ impl Visitor<'tcx> for DeadVisitor<'tcx> {
                 | hir::ItemKind::Struct(..)
                 | hir::ItemKind::Union(..)
                 | hir::ItemKind::Trait(..)
-                | hir::ItemKind::Impl(..) => {
+                | hir::ItemKind::Impl { .. } => {
                     // FIXME(66095): Because item.span is annotated with things
                     // like expansion data, and ident.span isn't, we use the
                     // def_span method if it's part of a macro invocation
diff --git a/src/librustc_passes/reachable.rs b/src/librustc_passes/reachable.rs
index 5ce677f52ce..667898046ac 100644
--- a/src/librustc_passes/reachable.rs
+++ b/src/librustc_passes/reachable.rs
@@ -35,7 +35,7 @@ fn item_might_be_inlined(tcx: TyCtxt<'tcx>, item: &hir::Item<'_>, attrs: Codegen
         hir::ItemKind::Fn(ref sig, ..) if sig.header.is_const() => {
             return true;
         }
-        hir::ItemKind::Impl(..) | hir::ItemKind::Fn(..) => {
+        hir::ItemKind::Impl { .. } | hir::ItemKind::Fn(..) => {
             let generics = tcx.generics_of(tcx.hir().local_def_id(item.hir_id));
             generics.requires_monomorphization(tcx)
         }
@@ -181,7 +181,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
                             // does too.
                             let impl_hir_id = self.tcx.hir().as_local_hir_id(impl_did).unwrap();
                             match self.tcx.hir().expect_item(impl_hir_id).kind {
-                                hir::ItemKind::Impl(..) => {
+                                hir::ItemKind::Impl { .. } => {
                                     let generics = self.tcx.generics_of(impl_did);
                                     generics.requires_monomorphization(self.tcx)
                                 }
@@ -266,7 +266,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
                     | hir::ItemKind::Static(..)
                     | hir::ItemKind::Mod(..)
                     | hir::ItemKind::ForeignMod(..)
-                    | hir::ItemKind::Impl(..)
+                    | hir::ItemKind::Impl { .. }
                     | hir::ItemKind::Trait(..)
                     | hir::ItemKind::TraitAlias(..)
                     | hir::ItemKind::Struct(..)
@@ -349,9 +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(.., Some(ref trait_ref), _, ref impl_item_refs) = item.kind {
+        if let hir::ItemKind::Impl { of_trait: Some(ref trait_ref), ref items, .. } = item.kind {
             if !self.access_levels.is_reachable(item.hir_id) {
-                self.worklist.extend(impl_item_refs.iter().map(|ii_ref| ii_ref.id.hir_id));
+                self.worklist.extend(items.iter().map(|ii_ref| ii_ref.id.hir_id));
 
                 let trait_def_id = match trait_ref.path.res {
                     Res::Def(DefKind::Trait, def_id) => def_id,
diff --git a/src/librustc_passes/stability.rs b/src/librustc_passes/stability.rs
index 5ec7e73f873..b649f36f2fc 100644
--- a/src/librustc_passes/stability.rs
+++ b/src/librustc_passes/stability.rs
@@ -219,11 +219,11 @@ 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(.., None, _, _) | hir::ItemKind::ForeignMod(..) => {
+            hir::ItemKind::Impl { of_trait: None, .. } | hir::ItemKind::ForeignMod(..) => {
                 self.in_trait_impl = false;
                 kind = AnnotationKind::Container;
             }
-            hir::ItemKind::Impl(.., Some(_), _, _) => {
+            hir::ItemKind::Impl { of_trait: Some(_), .. } => {
                 self.in_trait_impl = true;
             }
             hir::ItemKind::Struct(ref sd, _) => {
@@ -308,7 +308,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'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(.., None, _, _) | hir::ItemKind::ForeignMod(..) => {}
+            hir::ItemKind::Impl { of_trait: None, .. } | hir::ItemKind::ForeignMod(..) => {}
 
             _ => self.check_missing_stability(i.hir_id, i.span, i.kind.descriptive_variant()),
         }
@@ -463,9 +463,9 @@ 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(.., Some(ref t), _, impl_item_refs) => {
+            hir::ItemKind::Impl { of_trait: Some(ref t), items, .. } => {
                 if let Res::Def(DefKind::Trait, trait_did) = t.path.res {
-                    for impl_item_ref in impl_item_refs {
+                    for impl_item_ref in items {
                         let impl_item = self.tcx.hir().impl_item(impl_item_ref.id);
                         let trait_item_def_id = self
                             .tcx
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index 70d4841ec24..90a422a4dcf 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -255,8 +255,8 @@ fn def_id_visibility<'tcx>(
                 Node::ImplItem(impl_item) => {
                     match tcx.hir().get(tcx.hir().get_parent_item(hir_id)) {
                         Node::Item(item) => match &item.kind {
-                            hir::ItemKind::Impl(.., None, _, _) => &impl_item.vis,
-                            hir::ItemKind::Impl(.., Some(trait_ref), _, _) => {
+                            hir::ItemKind::Impl { of_trait: None, .. } => &impl_item.vis,
+                            hir::ItemKind::Impl { of_trait: Some(trait_ref), .. } => {
                                 return def_id_visibility(tcx, trait_ref.path.res.def_id());
                             }
                             kind => bug!("unexpected item kind: {:?}", kind),
@@ -686,7 +686,7 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> {
 
     fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
         let inherited_item_level = match item.kind {
-            hir::ItemKind::Impl(..) => {
+            hir::ItemKind::Impl { .. } => {
                 Option::<AccessLevel>::of_impl(item.hir_id, self.tcx, &self.access_levels)
             }
             // Foreign modules inherit level from parents.
@@ -730,9 +730,9 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> {
                     }
                 }
             }
-            hir::ItemKind::Impl(.., ref trait_ref, _, impl_item_refs) => {
-                for impl_item_ref in impl_item_refs {
-                    if trait_ref.is_some() || impl_item_ref.vis.node.is_pub() {
+            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() {
                         self.update(impl_item_ref.id.hir_id, item_level);
                     }
                 }
@@ -827,11 +827,11 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> {
                 }
             }
             // Visit everything except for private impl items.
-            hir::ItemKind::Impl(.., impl_item_refs) => {
+            hir::ItemKind::Impl { items, .. } => {
                 if item_level.is_some() {
                     self.reach(item.hir_id, item_level).generics().predicates().ty().trait_ref();
 
-                    for impl_item_ref in impl_item_refs {
+                    for impl_item_ref in 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)
@@ -1510,7 +1510,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(.., ref g, ref trait_ref, ref self_, impl_item_refs) => {
+            hir::ItemKind::Impl { generics: ref g, ref of_trait, ref self_ty, items, .. } => {
                 // `impl [... for] Private` is never visible.
                 let self_contains_private;
                 // `impl [... for] Public<...>`, but not `impl [... for]
@@ -1525,7 +1525,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
                         at_outer_type: true,
                         outer_type_is_public_path: false,
                     };
-                    visitor.visit_ty(&self_);
+                    visitor.visit_ty(&self_ty);
                     self_contains_private = visitor.contains_private;
                     self_is_public_path = visitor.outer_type_is_public_path;
                 }
@@ -1533,7 +1533,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 = trait_ref.as_ref().map_or(
+                let not_private_trait = of_trait.as_ref().map_or(
                     true, // no trait counts as public trait
                     |tr| {
                         let did = tr.path.res.def_id();
@@ -1554,8 +1554,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 = trait_ref.is_some()
-                    || impl_item_refs.iter().any(|impl_item_ref| {
+                let trait_or_some_public_method = of_trait.is_some()
+                    || 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::Method(..) => {
@@ -1570,9 +1570,9 @@ 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);
 
-                    match *trait_ref {
+                    match of_trait {
                         None => {
-                            for impl_item_ref in impl_item_refs {
+                            for impl_item_ref in 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
@@ -1594,7 +1594,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
                                 }
                             }
                         }
-                        Some(ref tr) => {
+                        Some(tr) => {
                             // Any private types in a trait impl fall into three
                             // categories.
                             // 1. mentioned in the trait definition
@@ -1611,7 +1611,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 impl_item_refs {
+                            for impl_item_ref in 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);
@@ -1619,11 +1619,11 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
                             }
                         }
                     }
-                } else if trait_ref.is_none() && self_is_public_path {
+                } else if 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 impl_item_refs {
+                    for impl_item_ref in 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 {
@@ -1997,12 +1997,12 @@ 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 trait_ref, _, impl_item_refs) => {
+            hir::ItemKind::Impl { ref of_trait, items, .. } => {
                 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 impl_item_refs {
+                for impl_item_ref in items {
                     let impl_item = tcx.hir().impl_item(impl_item_ref.id);
-                    let impl_item_vis = if trait_ref.is_none() {
+                    let impl_item_vis = if of_trait.is_none() {
                         min(
                             ty::Visibility::from_hir(&impl_item.vis, item.hir_id, tcx),
                             impl_vis,
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index e8ed64a1870..40a89ef0674 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -815,7 +815,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
             }
 
             // These items do not add names to modules.
-            ItemKind::Impl(..) | ItemKind::ForeignMod(..) | ItemKind::GlobalAsm(..) => {}
+            ItemKind::Impl { .. } | ItemKind::ForeignMod(..) | ItemKind::GlobalAsm(..) => {}
 
             ItemKind::MacroDef(..) | ItemKind::Mac(_) => unreachable!(),
         }
diff --git a/src/librustc_resolve/def_collector.rs b/src/librustc_resolve/def_collector.rs
index f564ea644bd..696ba0e994c 100644
--- a/src/librustc_resolve/def_collector.rs
+++ b/src/librustc_resolve/def_collector.rs
@@ -104,7 +104,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
         // Pick the def data. This need not be unique, but the more
         // information we encapsulate into, the better
         let def_data = match &i.kind {
-            ItemKind::Impl(..) => DefPathData::Impl,
+            ItemKind::Impl { .. } => DefPathData::Impl,
             ItemKind::Mod(..) if i.ident.name == kw::Invalid => {
                 return visit::walk_item(self, i);
             }
diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs
index defca4944bc..08cd9c4d1d5 100644
--- a/src/librustc_resolve/late.rs
+++ b/src/librustc_resolve/late.rs
@@ -797,14 +797,14 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
                 self.resolve_adt(item, generics);
             }
 
-            ItemKind::Impl(.., ref generics, ref opt_trait_ref, ref self_type, ref impl_items) => {
-                self.resolve_implementation(
-                    generics,
-                    opt_trait_ref,
-                    &self_type,
-                    item.id,
-                    impl_items,
-                )
+            ItemKind::Impl {
+                ref generics,
+                ref of_trait,
+                ref self_ty,
+                items: ref impl_items,
+                ..
+            } => {
+                self.resolve_implementation(generics, of_trait, &self_ty, item.id, impl_items);
             }
 
             ItemKind::Trait(.., ref generics, ref bounds, ref trait_items) => {
diff --git a/src/librustc_resolve/lifetimes.rs b/src/librustc_resolve/lifetimes.rs
index d6143eec73c..5fae8f33187 100644
--- a/src/librustc_resolve/lifetimes.rs
+++ b/src/librustc_resolve/lifetimes.rs
@@ -416,11 +416,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 { ref generics, .. } => {
                 // Impls permit `'_` to be used and it is equivalent to "some fresh lifetime name".
                 // This is not true for other kinds of items.x
                 let track_lifetime_uses = match item.kind {
-                    hir::ItemKind::Impl(..) => true,
+                    hir::ItemKind::Impl { .. } => true,
                     _ => false,
                 };
                 // These kinds of items have only early-bound lifetime parameters.
@@ -1638,7 +1638,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
             }
             match parent.kind {
                 hir::ItemKind::Trait(_, _, ref generics, ..)
-                | hir::ItemKind::Impl(_, _, _, ref generics, ..) => {
+                | hir::ItemKind::Impl { ref generics, .. } => {
                     index += generics.params.len() as u32;
                 }
                 _ => {}
@@ -2067,12 +2067,12 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
             }
 
             Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Method(_, body), .. }) => {
-                if let hir::ItemKind::Impl(.., ref self_ty, ref impl_items) =
+                if let hir::ItemKind::Impl { ref self_ty, ref items, .. } =
                     self.tcx.hir().expect_item(self.tcx.hir().get_parent_item(parent)).kind
                 {
                     impl_self = Some(self_ty);
                     assoc_item_kind =
-                        impl_items.iter().find(|ii| ii.id.hir_id == parent).map(|ii| ii.kind);
+                        items.iter().find(|ii| ii.id.hir_id == parent).map(|ii| ii.kind);
                 }
                 Some(body)
             }
diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs
index 2f2ba560fa2..d252fc542c3 100644
--- a/src/librustc_save_analysis/dump_visitor.rs
+++ b/src/librustc_save_analysis/dump_visitor.rs
@@ -1300,8 +1300,8 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> {
                 self.process_struct(item, def, ty_params)
             }
             Enum(ref def, ref ty_params) => self.process_enum(item, def, ty_params),
-            Impl(.., ref ty_params, ref trait_ref, ref typ, ref impl_items) => {
-                self.process_impl(item, ty_params, trait_ref, &typ, impl_items)
+            Impl { ref generics, ref of_trait, ref self_ty, ref items, .. } => {
+                self.process_impl(item, generics, of_trait, &self_ty, items)
             }
             Trait(_, _, ref generics, ref trait_refs, ref methods) => {
                 self.process_trait(item, generics, trait_refs, methods)
diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs
index c3221d925bc..537fe198a0c 100644
--- a/src/librustc_save_analysis/lib.rs
+++ b/src/librustc_save_analysis/lib.rs
@@ -305,8 +305,8 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
                     attributes: lower_attributes(item.attrs.clone(), self),
                 }))
             }
-            ast::ItemKind::Impl(.., ref trait_ref, ref typ, ref impls) => {
-                if let ast::TyKind::Path(None, ref path) = typ.kind {
+            ast::ItemKind::Impl { ref of_trait, ref self_ty, ref items, .. } => {
+                if let ast::TyKind::Path(None, ref path) = self_ty.kind {
                     // Common case impl for a struct or something basic.
                     if generated_code(path.span) {
                         return None;
@@ -317,14 +317,14 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
                     let impl_id = self.next_impl_id();
                     let span = self.span_from_span(sub_span);
 
-                    let type_data = self.lookup_def_id(typ.id);
+                    let type_data = self.lookup_def_id(self_ty.id);
                     type_data.map(|type_data| {
                         Data::RelationData(
                             Relation {
                                 kind: RelationKind::Impl { id: impl_id },
                                 span: span.clone(),
                                 from: id_from_def_id(type_data),
-                                to: trait_ref
+                                to: of_trait
                                     .as_ref()
                                     .and_then(|t| self.lookup_def_id(t.ref_id))
                                     .map(id_from_def_id)
@@ -332,14 +332,14 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
                             },
                             Impl {
                                 id: impl_id,
-                                kind: match *trait_ref {
+                                kind: match *of_trait {
                                     Some(_) => ImplKind::Direct,
                                     None => ImplKind::Inherent,
                                 },
                                 span: span,
                                 value: String::new(),
                                 parent: None,
-                                children: impls
+                                children: items
                                     .iter()
                                     .map(|i| id_from_node_id(i.id, self))
                                     .collect(),
@@ -405,9 +405,9 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
         {
             Some(impl_id) => match self.tcx.hir().get_if_local(impl_id) {
                 Some(Node::Item(item)) => match item.kind {
-                    hir::ItemKind::Impl(.., ref ty, _) => {
+                    hir::ItemKind::Impl { ref self_ty, .. } => {
                         let mut qualname = String::from("<");
-                        qualname.push_str(&self.tcx.hir().hir_to_pretty_string(ty.hir_id));
+                        qualname.push_str(&self.tcx.hir().hir_to_pretty_string(self_ty.hir_id));
 
                         let trait_id = self.tcx.trait_id_of_impl(impl_id);
                         let mut decl_id = None;
diff --git a/src/librustc_save_analysis/sig.rs b/src/librustc_save_analysis/sig.rs
index e7b86cfba4f..779d3f55018 100644
--- a/src/librustc_save_analysis/sig.rs
+++ b/src/librustc_save_analysis/sig.rs
@@ -482,15 +482,15 @@ impl Sig for ast::Item {
 
                 Ok(sig)
             }
-            ast::ItemKind::Impl(
+            ast::ItemKind::Impl {
                 unsafety,
                 polarity,
                 defaultness,
                 ref generics,
-                ref opt_trait,
-                ref ty,
-                _,
-            ) => {
+                ref of_trait,
+                ref self_ty,
+                items: _,
+            } => {
                 let mut text = String::new();
                 if let ast::Defaultness::Default = defaultness {
                     text.push_str("default ");
@@ -505,7 +505,7 @@ impl Sig for ast::Item {
 
                 text.push(' ');
 
-                let trait_sig = if let Some(ref t) = *opt_trait {
+                let trait_sig = if let Some(ref t) = *of_trait {
                     if polarity == ast::ImplPolarity::Negative {
                         text.push('!');
                     }
@@ -517,7 +517,7 @@ impl Sig for ast::Item {
                     text_sig(String::new())
                 };
 
-                let ty_sig = ty.make(offset + text.len(), id, scx)?;
+                let ty_sig = self_ty.make(offset + text.len(), id, scx)?;
                 text.push_str(&ty_sig.text);
 
                 text.push_str(" {}");
diff --git a/src/librustc_traits/lowering/environment.rs b/src/librustc_traits/lowering/environment.rs
index 315efe5cf71..7df27e67d5b 100644
--- a/src/librustc_traits/lowering/environment.rs
+++ b/src/librustc_traits/lowering/environment.rs
@@ -195,8 +195,8 @@ crate fn environment(tcx: TyCtxt<'_>, def_id: DefId) -> Environment<'_> {
         },
 
         Node::Item(item) => match item.kind {
-            ItemKind::Impl(.., Some(..), _, _) => NodeKind::TraitImpl,
-            ItemKind::Impl(.., None, _, _) => NodeKind::InherentImpl,
+            ItemKind::Impl { of_trait: Some(_), .. } => NodeKind::TraitImpl,
+            ItemKind::Impl { of_trait: None, .. } => NodeKind::InherentImpl,
             ItemKind::Fn(..) => NodeKind::Fn,
             _ => NodeKind::Other,
         },
diff --git a/src/librustc_ty/ty.rs b/src/librustc_ty/ty.rs
index fc8beb67e4a..d47e54366b5 100644
--- a/src/librustc_ty/ty.rs
+++ b/src/librustc_ty/ty.rs
@@ -128,8 +128,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 impl_item_refs) => {
-            if let Some(impl_item_ref) = impl_item_refs.iter().find(|i| i.id.hir_id == id) {
+        hir::ItemKind::Impl { ref items, .. } => {
+            if let Some(impl_item_ref) = 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);
@@ -194,8 +194,8 @@ 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)),
         ),
-        hir::ItemKind::Impl(.., ref impl_item_refs) => tcx.arena.alloc_from_iter(
-            impl_item_refs
+        hir::ItemKind::Impl { ref items, .. } => tcx.arena.alloc_from_iter(
+            items
                 .iter()
                 .map(|impl_item_ref| impl_item_ref.id)
                 .map(|id| tcx.hir().local_def_id(id.hir_id)),
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index dff68b9986c..4affdc4a9d6 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -1709,17 +1709,11 @@ 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 impl_item_refs) => {
+        hir::ItemKind::Impl { ref items, .. } => {
             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,
-                    impl_item_refs,
-                );
+                check_impl_items_against_trait(tcx, it.span, impl_def_id, impl_trait_ref, items);
                 let trait_def_id = impl_trait_ref.def_id;
                 check_on_unimplemented(tcx, trait_def_id, it);
             }
diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs
index a496a6e12ce..5e91e98a7df 100644
--- a/src/librustc_typeck/check/wfcheck.rs
+++ b/src/librustc_typeck/check/wfcheck.rs
@@ -97,7 +97,7 @@ pub fn check_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) {
         //
         // won't be allowed unless there's an *explicit* implementation of `Send`
         // for `T`
-        hir::ItemKind::Impl(_, _, defaultness, _, ref trait_ref, ref self_ty, _) => {
+        hir::ItemKind::Impl { defaultness, ref of_trait, ref self_ty, .. } => {
             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));
@@ -107,11 +107,11 @@ pub fn check_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) {
             }
             match polarity {
                 ty::ImplPolarity::Positive => {
-                    check_impl(tcx, item, self_ty, trait_ref);
+                    check_impl(tcx, item, self_ty, of_trait);
                 }
                 ty::ImplPolarity::Negative => {
                     // FIXME(#27579): what amount of WF checking do we need for neg impls?
-                    if trait_ref.is_some() && !is_auto {
+                    if of_trait.is_some() && !is_auto {
                         struct_span_err!(
                             tcx.sess,
                             item.span,
diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs
index 8b3db15c02b..516dc16d46b 100644
--- a/src/librustc_typeck/coherence/builtin.rs
+++ b/src/librustc_typeck/coherence/builtin.rs
@@ -57,7 +57,7 @@ fn visit_implementation_of_drop(tcx: TyCtxt<'_>, impl_did: DefId) {
 
     let impl_hir_id = tcx.hir().as_local_hir_id(impl_did).expect("foreign Drop impl on non-ADT");
     let sp = match tcx.hir().expect_item(impl_hir_id).kind {
-        ItemKind::Impl(.., ty, _) => ty.span,
+        ItemKind::Impl { self_ty, .. } => self_ty.span,
         _ => bug!("expected Drop impl item"),
     };
 
@@ -94,7 +94,7 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: DefId) {
         Ok(()) => {}
         Err(CopyImplementationError::InfrigingFields(fields)) => {
             let item = tcx.hir().expect_item(impl_hir_id);
-            let span = if let ItemKind::Impl(.., Some(ref tr), _, _) = item.kind {
+            let span = if let ItemKind::Impl { of_trait: Some(ref tr), .. } = item.kind {
                 tr.path.span
             } else {
                 span
@@ -113,7 +113,8 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: DefId) {
         }
         Err(CopyImplementationError::NotAnAdt) => {
             let item = tcx.hir().expect_item(impl_hir_id);
-            let span = if let ItemKind::Impl(.., ref ty, _) = item.kind { ty.span } else { span };
+            let span =
+                if let ItemKind::Impl { self_ty, .. } = item.kind { self_ty.span } else { span };
 
             struct_span_err!(
                 tcx.sess,
@@ -490,7 +491,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn
                     return err_info;
                 } else if diff_fields.len() > 1 {
                     let item = tcx.hir().expect_item(impl_hir_id);
-                    let span = if let ItemKind::Impl(.., Some(ref t), _, _) = item.kind {
+                    let span = if let ItemKind::Impl { of_trait: Some(ref t), .. } = item.kind {
                         t.path.span
                     } else {
                         tcx.hir().span(impl_hir_id)
diff --git a/src/librustc_typeck/coherence/inherent_impls.rs b/src/librustc_typeck/coherence/inherent_impls.rs
index 673c1bd9fd8..d313e32fc20 100644
--- a/src/librustc_typeck/coherence/inherent_impls.rs
+++ b/src/librustc_typeck/coherence/inherent_impls.rs
@@ -47,7 +47,7 @@ struct InherentCollect<'tcx> {
 impl ItemLikeVisitor<'v> for InherentCollect<'tcx> {
     fn visit_item(&mut self, item: &hir::Item<'_>) {
         let ty = match item.kind {
-            hir::ItemKind::Impl(.., None, ref ty, _) => ty,
+            hir::ItemKind::Impl { of_trait: None, ref self_ty, .. } => self_ty,
             _ => return,
         };
 
diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs
index 1878f9385a8..9ba8fa4247f 100644
--- a/src/librustc_typeck/coherence/orphan.rs
+++ b/src/librustc_typeck/coherence/orphan.rs
@@ -27,7 +27,7 @@ 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, Some(tr), impl_ty, _) = &item.kind {
+        if let hir::ItemKind::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)
@@ -72,7 +72,7 @@ impl ItemLikeVisitor<'v> for OrphanChecker<'tcx> {
                         let msg = format!("{} is not defined in the current crate{}", ty, postfix);
                         if *is_target_ty {
                             // Point at `D<A>` in `impl<A, B> for C<B> in D<A>`
-                            err.span_label(impl_ty.span, &msg);
+                            err.span_label(self_ty.span, &msg);
                         } else {
                             // Point at `C<B>` in `impl<A, B> for C<B> in D<A>`
                             err.span_label(tr.path.span, &msg);
diff --git a/src/librustc_typeck/coherence/unsafety.rs b/src/librustc_typeck/coherence/unsafety.rs
index 3f4035b0998..48b96886d3a 100644
--- a/src/librustc_typeck/coherence/unsafety.rs
+++ b/src/librustc_typeck/coherence/unsafety.rs
@@ -88,7 +88,7 @@ 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 {
+        if let hir::ItemKind::Impl { unsafety, polarity, ref generics, .. } = item.kind {
             self.check_unsafety_coherence(item, Some(generics), unsafety, polarity);
         }
     }
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index dca3289747e..a03b9f74737 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -184,7 +184,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 { generics, .. }
         | hir::ItemKind::Struct(_, generics) => (generics, true),
         hir::ItemKind::OpaqueTy(hir::OpaqueTy { generics, .. })
         | hir::ItemKind::TyAlias(_, generics) => (generics, false),
@@ -401,7 +401,7 @@ fn type_param_predicates(
         Node::Item(item) => {
             match item.kind {
                 ItemKind::Fn(.., ref generics, _)
-                | ItemKind::Impl(_, _, _, ref generics, ..)
+                | ItemKind::Impl { ref generics, .. }
                 | ItemKind::TyAlias(_, ref generics)
                 | ItemKind::OpaqueTy(OpaqueTy { ref generics, impl_trait_fn: None, .. })
                 | ItemKind::Enum(_, ref generics)
@@ -531,7 +531,7 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::HirId) {
             tcx.predicates_of(def_id);
             convert_enum_variant_types(tcx, def_id, &enum_definition.variants);
         }
-        hir::ItemKind::Impl(..) => {
+        hir::ItemKind::Impl { .. } => {
             tcx.generics_of(def_id);
             tcx.type_of(def_id);
             tcx.impl_trait_ref(def_id);
@@ -1052,9 +1052,7 @@ 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 { ref generics, .. } => generics,
 
                 ItemKind::TyAlias(_, ref generics)
                 | ItemKind::Enum(_, ref generics)
@@ -1338,7 +1336,9 @@ fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
                         icx.to_ty(ty)
                     }
                 }
-                ItemKind::TyAlias(ref ty, _) | ItemKind::Impl(.., ref ty, _) => icx.to_ty(ty),
+                ItemKind::TyAlias(ref self_ty, _) | ItemKind::Impl { ref self_ty, .. } => {
+                    icx.to_ty(self_ty)
+                }
                 ItemKind::Fn(..) => {
                     let substs = InternalSubsts::identity_for_item(tcx, def_id);
                     tcx.mk_fn_def(def_id, substs)
@@ -1956,12 +1956,10 @@ fn impl_trait_ref(tcx: TyCtxt<'_>, def_id: DefId) -> Option<ty::TraitRef<'_>> {
 
     let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
     match tcx.hir().expect_item(hir_id).kind {
-        hir::ItemKind::Impl(.., ref opt_trait_ref, _, _) => {
-            opt_trait_ref.as_ref().map(|ast_trait_ref| {
-                let selfty = tcx.type_of(def_id);
-                AstConv::instantiate_mono_trait_ref(&icx, ast_trait_ref, selfty)
-            })
-        }
+        hir::ItemKind::Impl { ref of_trait, .. } => 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)
+        }),
         _ => bug!(),
     }
 }
@@ -1971,19 +1969,21 @@ 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(_, hir::ImplPolarity::Negative, ..) => {
+        hir::ItemKind::Impl { polarity: hir::ImplPolarity::Negative, .. } => {
             if is_rustc_reservation {
                 tcx.sess.span_err(item.span, "reservation impls can't be negative");
             }
             ty::ImplPolarity::Negative
         }
-        hir::ItemKind::Impl(_, hir::ImplPolarity::Positive, _, _, None, _, _) => {
+        hir::ItemKind::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(_, hir::ImplPolarity::Positive, _, _, Some(_tr), _, _) => {
+        hir::ItemKind::Impl {
+            polarity: hir::ImplPolarity::Positive, of_trait: Some(_), ..
+        } => {
             if is_rustc_reservation {
                 ty::ImplPolarity::Reservation
             } else {
@@ -2142,7 +2142,7 @@ fn explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicat
 
         Node::Item(item) => {
             match item.kind {
-                ItemKind::Impl(_, _, defaultness, ref generics, ..) => {
+                ItemKind::Impl { defaultness, ref generics, .. } => {
                     if defaultness.is_default() {
                         is_default_impl_trait = tcx.impl_trait_ref(def_id);
                     }
@@ -2359,7 +2359,7 @@ fn explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicat
     // before uses of `U`.  This avoids false ambiguity errors
     // in trait checking. See `setup_constraining_predicates`
     // for details.
-    if let Node::Item(&Item { kind: ItemKind::Impl(..), .. }) = node {
+    if let Node::Item(&Item { kind: ItemKind::Impl { .. }, .. }) = node {
         let self_ty = tcx.type_of(def_id);
         let trait_ref = tcx.impl_trait_ref(def_id);
         cgp::setup_constraining_predicates(
diff --git a/src/librustc_typeck/impl_wf_check.rs b/src/librustc_typeck/impl_wf_check.rs
index fb87b285fa2..9ee4e7c4819 100644
--- a/src/librustc_typeck/impl_wf_check.rs
+++ b/src/librustc_typeck/impl_wf_check.rs
@@ -75,10 +75,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 impl_item_refs) = item.kind {
+        if let hir::ItemKind::Impl { ref items, .. } = 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, impl_item_refs);
-            enforce_impl_items_are_distinct(self.tcx, impl_item_refs);
+            enforce_impl_params_are_constrained(self.tcx, impl_def_id, items);
+            enforce_impl_items_are_distinct(self.tcx, items);
         }
     }
 
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index e54e716e042..8a6abe036dc 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -347,7 +347,7 @@ pub fn build_impl(
 
     let for_ = if let Some(hir_id) = tcx.hir().as_local_hir_id(did) {
         match tcx.hir().expect_item(hir_id).kind {
-            hir::ItemKind::Impl(.., ref t, _) => t.clean(cx),
+            hir::ItemKind::Impl { self_ty, .. } => self_ty.clean(cx),
             _ => panic!("did given to build_impl was not an impl"),
         }
     } else {
@@ -367,9 +367,9 @@ pub fn build_impl(
     let predicates = tcx.explicit_predicates_of(did);
     let (trait_items, generics) = if let Some(hir_id) = tcx.hir().as_local_hir_id(did) {
         match tcx.hir().expect_item(hir_id).kind {
-            hir::ItemKind::Impl(.., ref gen, _, _, ref item_ids) => (
-                item_ids.iter().map(|ii| tcx.hir().impl_item(ii.id).clean(cx)).collect::<Vec<_>>(),
-                gen.clean(cx),
+            hir::ItemKind::Impl { ref generics, ref items, .. } => (
+                items.iter().map(|item| tcx.hir().impl_item(item.id).clean(cx)).collect::<Vec<_>>(),
+                generics.clean(cx),
             ),
             _ => panic!("did given to build_impl was not an impl"),
         }
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index f899e722a56..05d41415689 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -905,8 +905,8 @@ impl<'a, 'hir> intravisit::Visitor<'hir> for HirCollector<'a, 'hir> {
     }
 
     fn visit_item(&mut self, item: &'hir hir::Item) {
-        let name = if let hir::ItemKind::Impl(.., ref ty, _) = item.kind {
-            self.map.hir_to_pretty_string(ty.hir_id)
+        let name = if let hir::ItemKind::Impl { ref self_ty, .. } = item.kind {
+            self.map.hir_to_pretty_string(self_ty.hir_id)
         } else {
             item.ident.to_string()
         };
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index 5fa9270959c..fdff18779e7 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -558,27 +558,27 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                 om.trait_aliases.push(t);
             }
 
-            hir::ItemKind::Impl(
+            hir::ItemKind::Impl {
                 unsafety,
                 polarity,
                 defaultness,
                 ref generics,
-                ref trait_,
-                for_,
-                ref item_ids,
-            ) => {
+                ref of_trait,
+                self_ty,
+                ref items,
+            } => {
                 // Don't duplicate impls when inlining or if it's implementing a trait, we'll pick
                 // them up regardless of where they're located.
-                if !self.inlining && trait_.is_none() {
+                if !self.inlining && of_trait.is_none() {
                     let items =
-                        item_ids.iter().map(|ii| self.cx.tcx.hir().impl_item(ii.id)).collect();
+                        items.iter().map(|item| self.cx.tcx.hir().impl_item(item.id)).collect();
                     let i = Impl {
                         unsafety,
                         polarity,
                         defaultness,
                         generics,
-                        trait_,
-                        for_,
+                        trait_: of_trait,
+                        for_: self_ty,
                         items,
                         attrs: &item.attrs,
                         id: item.hir_id,
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 331eb109ec0..a5a4eb1583b 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -2614,15 +2614,18 @@ pub enum ItemKind {
     /// An implementation.
     ///
     /// E.g., `impl<A> Foo<A> { .. }` or `impl<A> Trait for Foo<A> { .. }`.
-    Impl(
-        Unsafety,
-        ImplPolarity,
-        Defaultness,
-        Generics,
-        Option<TraitRef>, // (optional) trait this impl implements
-        P<Ty>,            // self
-        Vec<AssocItem>,
-    ),
+    Impl {
+        unsafety: Unsafety,
+        polarity: ImplPolarity,
+        defaultness: Defaultness,
+        generics: Generics,
+
+        /// The trait being implemented, if any.
+        of_trait: Option<TraitRef>,
+
+        self_ty: P<Ty>,
+        items: Vec<AssocItem>,
+    },
     /// A macro invocation.
     ///
     /// E.g., `foo!(..)`.
@@ -2649,7 +2652,7 @@ impl ItemKind {
             ItemKind::Union(..) => "union",
             ItemKind::Trait(..) => "trait",
             ItemKind::TraitAlias(..) => "trait alias",
-            ItemKind::Mac(..) | ItemKind::MacroDef(..) | ItemKind::Impl(..) => "item",
+            ItemKind::Mac(..) | ItemKind::MacroDef(..) | ItemKind::Impl { .. } => "item",
         }
     }
 }
diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs
index 58d4e46111b..750d054e8a0 100644
--- a/src/libsyntax/mut_visit.rs
+++ b/src/libsyntax/mut_visit.rs
@@ -918,10 +918,18 @@ pub fn noop_visit_item_kind<T: MutVisitor>(kind: &mut ItemKind, vis: &mut T) {
             vis.visit_variant_data(variant_data);
             vis.visit_generics(generics);
         }
-        ItemKind::Impl(_unsafety, _polarity, _defaultness, generics, trait_ref, ty, items) => {
+        ItemKind::Impl {
+            unsafety: _,
+            polarity: _,
+            defaultness: _,
+            generics,
+            of_trait,
+            self_ty,
+            items,
+        } => {
             vis.visit_generics(generics);
-            visit_opt(trait_ref, |trait_ref| vis.visit_trait_ref(trait_ref));
-            vis.visit_ty(ty);
+            visit_opt(of_trait, |trait_ref| vis.visit_trait_ref(trait_ref));
+            vis.visit_ty(self_ty);
             items.flat_map_in_place(|item| vis.flat_map_impl_item(item));
         }
         ItemKind::Trait(_is_auto, _unsafety, generics, bounds, items) => {
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 11c8cb8ef75..bc67980c454 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -1226,15 +1226,15 @@ impl<'a> State<'a> {
                 self.head(visibility_qualified(&item.vis, "union"));
                 self.print_struct(struct_def, generics, item.ident, item.span, true);
             }
-            ast::ItemKind::Impl(
+            ast::ItemKind::Impl {
                 unsafety,
                 polarity,
                 defaultness,
                 ref generics,
-                ref opt_trait,
-                ref ty,
-                ref impl_items,
-            ) => {
+                ref of_trait,
+                ref self_ty,
+                ref items,
+            } => {
                 self.head("");
                 self.print_visibility(&item.vis);
                 self.print_defaultness(defaultness);
@@ -1250,19 +1250,19 @@ impl<'a> State<'a> {
                     self.s.word("!");
                 }
 
-                if let Some(ref t) = *opt_trait {
+                if let Some(ref t) = *of_trait {
                     self.print_trait_ref(t);
                     self.s.space();
                     self.word_space("for");
                 }
 
-                self.print_type(ty);
+                self.print_type(self_ty);
                 self.print_where_clause(&generics.where_clause);
 
                 self.s.space();
                 self.bopen();
                 self.print_inner_attributes(&item.attrs);
-                for impl_item in impl_items {
+                for impl_item in items {
                     self.print_assoc_item(impl_item);
                 }
                 self.bclose(item.span);
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 3c2ebacbc4e..d03a9dfc167 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -308,11 +308,19 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
             visitor.visit_generics(generics);
             visitor.visit_enum_def(enum_definition, generics, item.id, item.span)
         }
-        ItemKind::Impl(_, _, _, ref generics, ref opt_trait_reference, ref typ, ref impl_items) => {
+        ItemKind::Impl {
+            unsafety: _,
+            polarity: _,
+            defaultness: _,
+            ref generics,
+            ref of_trait,
+            ref self_ty,
+            ref items,
+        } => {
             visitor.visit_generics(generics);
-            walk_list!(visitor, visit_trait_ref, opt_trait_reference);
-            visitor.visit_ty(typ);
-            walk_list!(visitor, visit_impl_item, impl_items);
+            walk_list!(visitor, visit_trait_ref, of_trait);
+            visitor.visit_ty(self_ty);
+            walk_list!(visitor, visit_impl_item, items);
         }
         ItemKind::Struct(ref struct_definition, ref generics)
         | ItemKind::Union(ref struct_definition, ref generics) => {