about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs120
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_name.rs2
-rw-r--r--compiler/rustc_hir/src/hir.rs19
-rw-r--r--compiler/rustc_hir/src/intravisit.rs9
-rw-r--r--compiler/rustc_hir/src/target.rs9
-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.rs2
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs3
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs18
-rw-r--r--compiler/rustc_middle/src/ty/diagnostics.rs2
-rw-r--r--compiler/rustc_passes/src/dead.rs2
-rw-r--r--compiler/rustc_passes/src/reachable.rs1
-rw-r--r--compiler/rustc_privacy/src/lib.rs11
-rw-r--r--compiler/rustc_resolve/src/late/lifetimes.rs6
-rw-r--r--compiler/rustc_save_analysis/src/dump_visitor.rs2
-rw-r--r--compiler/rustc_save_analysis/src/sig.rs15
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs2
-rw-r--r--compiler/rustc_typeck/src/astconv/mod.rs13
-rw-r--r--compiler/rustc_typeck/src/check/compare_method.rs27
-rw-r--r--compiler/rustc_typeck/src/collect.rs25
-rw-r--r--compiler/rustc_typeck/src/collect/item_bounds.rs41
-rw-r--r--compiler/rustc_typeck/src/collect/type_of.rs11
-rw-r--r--src/librustdoc/clean/mod.rs12
-rw-r--r--src/librustdoc/visit_ast.rs1
-rw-r--r--src/test/ui/impl-trait/in-trait/opaque-in-impl.rs36
25 files changed, 170 insertions, 223 deletions
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index eecf01c92fb..1a987c6e2d7 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -252,11 +252,10 @@ enum ImplTraitContext {
     ReturnPositionOpaqueTy {
         /// Origin: Either OpaqueTyOrigin::FnReturn or OpaqueTyOrigin::AsyncFn,
         origin: hir::OpaqueTyOrigin,
+        in_trait: bool,
     },
     /// Impl trait in type aliases.
     TypeAliasesOpaqueTy,
-    /// Return-position `impl Trait` in trait definition
-    InTrait,
     /// `impl Trait` is not accepted in this position.
     Disallowed(ImplTraitPosition),
 }
@@ -1343,9 +1342,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             TyKind::ImplTrait(def_node_id, ref bounds) => {
                 let span = t.span;
                 match itctx {
-                    ImplTraitContext::ReturnPositionOpaqueTy { origin } => {
-                        self.lower_opaque_impl_trait(span, *origin, def_node_id, bounds, itctx)
-                    }
+                    ImplTraitContext::ReturnPositionOpaqueTy { origin, in_trait } => self
+                        .lower_opaque_impl_trait(
+                            span,
+                            *origin,
+                            def_node_id,
+                            bounds,
+                            *in_trait,
+                            itctx,
+                        ),
                     ImplTraitContext::TypeAliasesOpaqueTy => {
                         let mut nested_itctx = ImplTraitContext::TypeAliasesOpaqueTy;
                         self.lower_opaque_impl_trait(
@@ -1353,14 +1358,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             hir::OpaqueTyOrigin::TyAlias,
                             def_node_id,
                             bounds,
-                            &mut nested_itctx,
+                            false,
+                            nested_itctx,
                         )
                     }
-                    ImplTraitContext::InTrait => {
-                        self.lower_impl_trait_in_trait(span, def_node_id, |lctx| {
-                            lctx.lower_param_bounds(bounds, ImplTraitContext::InTrait)
-                        })
-                    }
                     ImplTraitContext::Universal => {
                         let span = t.span;
                         let ident = Ident::from_str_and_span(&pprust::ty_to_string(t), span);
@@ -1430,6 +1431,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         origin: hir::OpaqueTyOrigin,
         opaque_ty_node_id: NodeId,
         bounds: &GenericBounds,
+        in_trait: bool,
         itctx: &mut ImplTraitContext,
     ) -> hir::TyKind<'hir> {
         // Make sure we know that some funky desugaring has been going on here.
@@ -1518,6 +1520,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     }),
                     bounds: hir_bounds,
                     origin,
+                    in_trait,
                 };
                 debug!(?opaque_ty_item);
 
@@ -1544,30 +1547,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         debug!(?lifetimes);
 
         // `impl Trait` now just becomes `Foo<'a, 'b, ..>`.
-        hir::TyKind::OpaqueDef(hir::ItemId { def_id: opaque_ty_def_id }, lifetimes)
-    }
-
-    #[instrument(level = "debug", skip(self, lower_bounds))]
-    fn lower_impl_trait_in_trait(
-        &mut self,
-        span: Span,
-        opaque_ty_node_id: NodeId,
-        lower_bounds: impl FnOnce(&mut Self) -> hir::GenericBounds<'hir>,
-    ) -> hir::TyKind<'hir> {
-        let opaque_ty_def_id = self.local_def_id(opaque_ty_node_id);
-        self.with_hir_id_owner(opaque_ty_node_id, |lctx| {
-            let hir_bounds = lower_bounds(lctx);
-            let rpitit_placeholder = hir::ImplTraitPlaceholder { bounds: hir_bounds };
-            let rpitit_item = hir::Item {
-                def_id: opaque_ty_def_id,
-                ident: Ident::empty(),
-                kind: hir::ItemKind::ImplTraitPlaceholder(rpitit_placeholder),
-                span: lctx.lower_span(span),
-                vis_span: lctx.lower_span(span.shrink_to_lo()),
-            };
-            hir::OwnerNode::Item(lctx.arena.alloc(rpitit_item))
-        });
-        hir::TyKind::ImplTraitInTrait(hir::ItemId { def_id: opaque_ty_def_id })
+        hir::TyKind::OpaqueDef(hir::ItemId { def_id: opaque_ty_def_id }, lifetimes, in_trait)
     }
 
     /// Registers a new opaque type with the proper `NodeId`s and
@@ -1728,30 +1708,28 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             )
                             .emit();
                     }
-                    self.lower_async_fn_ret_ty_in_trait(
+                    self.lower_async_fn_ret_ty(
                         &decl.output,
                         fn_node_id.expect("`make_ret_async` but no `fn_def_id`"),
                         ret_id,
+                        true,
                     )
                 }
                 _ => {
                     if !kind.impl_trait_return_allowed(self.tcx) {
-                        if kind == FnDeclKind::Impl {
-                            self.tcx
-                                .sess
-                                .create_feature_err(
-                                    TraitFnAsync { fn_span, span },
-                                    sym::return_position_impl_trait_in_trait,
-                                )
-                                .emit();
-                        } else {
-                            self.tcx.sess.emit_err(TraitFnAsync { fn_span, span });
-                        }
+                        self.tcx
+                            .sess
+                            .create_feature_err(
+                                TraitFnAsync { fn_span, span },
+                                sym::return_position_impl_trait_in_trait,
+                            )
+                            .emit();
                     }
                     self.lower_async_fn_ret_ty(
                         &decl.output,
                         fn_node_id.expect("`make_ret_async` but no `fn_def_id`"),
                         ret_id,
+                        false,
                     )
                 }
             }
@@ -1763,10 +1741,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             let fn_def_id = self.local_def_id(fn_node_id);
                             ImplTraitContext::ReturnPositionOpaqueTy {
                                 origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
+                                in_trait: false,
                             }
                         }
-                        Some(_) if kind.impl_trait_in_trait_allowed(self.tcx) => {
-                            ImplTraitContext::InTrait
+                        Some(fn_node_id) if kind.impl_trait_in_trait_allowed(self.tcx) => {
+                            let fn_def_id = self.local_def_id(fn_node_id);
+                            ImplTraitContext::ReturnPositionOpaqueTy {
+                                origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
+                                in_trait: true,
+                            }
                         }
                         _ => ImplTraitContext::Disallowed(match kind {
                             FnDeclKind::Fn | FnDeclKind::Inherent => {
@@ -1829,6 +1812,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         output: &FnRetTy,
         fn_node_id: NodeId,
         opaque_ty_node_id: NodeId,
+        in_trait: bool,
     ) -> hir::FnRetTy<'hir> {
         let span = output.span();
 
@@ -1960,6 +1944,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     span,
                     ImplTraitContext::ReturnPositionOpaqueTy {
                         origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
+                        in_trait,
                     },
                 );
 
@@ -1999,6 +1984,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     }),
                     bounds: arena_vec![this; future_bound],
                     origin: hir::OpaqueTyOrigin::AsyncFn(fn_def_id),
+                    in_trait,
                 };
 
                 trace!("exist ty from async fn def id: {:#?}", opaque_ty_def_id);
@@ -2043,41 +2029,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         // Foo = impl Trait` is, internally, created as a child of the
         // async fn, so the *type parameters* are inherited.  It's
         // only the lifetime parameters that we must supply.
-        let opaque_ty_ref =
-            hir::TyKind::OpaqueDef(hir::ItemId { def_id: opaque_ty_def_id }, generic_args);
+        let opaque_ty_ref = hir::TyKind::OpaqueDef(
+            hir::ItemId { def_id: opaque_ty_def_id },
+            generic_args,
+            in_trait,
+        );
         let opaque_ty = self.ty(opaque_ty_span, opaque_ty_ref);
         hir::FnRetTy::Return(self.arena.alloc(opaque_ty))
     }
 
-    // Transforms `-> T` for `async fn` into `-> OpaqueTy { .. }`
-    // combined with the following definition of `OpaqueTy`:
-    //
-    //     type OpaqueTy<generics_from_parent_fn> = impl Future<Output = T>;
-    //
-    // `output`: unlowered output type (`T` in `-> T`)
-    // `fn_def_id`: `DefId` of the parent function (used to create child impl trait definition)
-    // `opaque_ty_node_id`: `NodeId` of the opaque `impl Trait` type that should be created
-    #[instrument(level = "debug", skip(self))]
-    fn lower_async_fn_ret_ty_in_trait(
-        &mut self,
-        output: &FnRetTy,
-        fn_node_id: NodeId,
-        opaque_ty_node_id: NodeId,
-    ) -> hir::FnRetTy<'hir> {
-        let kind = self.lower_impl_trait_in_trait(output.span(), opaque_ty_node_id, |lctx| {
-            let bound = lctx.lower_async_fn_output_type_to_future_bound(
-                output,
-                output.span(),
-                ImplTraitContext::InTrait,
-            );
-            arena_vec![lctx; bound]
-        });
-
-        let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::Async, output.span(), None);
-        let opaque_ty = self.ty(opaque_ty_span, kind);
-        hir::FnRetTy::Return(self.arena.alloc(opaque_ty))
-    }
-
     /// Transforms `-> T` into `Future<Output = T>`.
     fn lower_async_fn_output_type_to_future_bound(
         &mut self,
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
index 75fde53b6cd..0707ff5ed02 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
@@ -772,7 +772,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
     fn get_future_inner_return_ty(&self, hir_ty: &'tcx hir::Ty<'tcx>) -> &'tcx hir::Ty<'tcx> {
         let hir = self.infcx.tcx.hir();
 
-        let hir::TyKind::OpaqueDef(id, _) = hir_ty.kind else {
+        let hir::TyKind::OpaqueDef(id, _, _) = hir_ty.kind else {
             span_bug!(
                 hir_ty.span,
                 "lowered return type of async fn is not OpaqueDef: {:?}",
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 8b1ebe34cb0..a57fdc3bfb1 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -2505,6 +2505,7 @@ pub struct OpaqueTy<'hir> {
     pub generics: &'hir Generics<'hir>,
     pub bounds: GenericBounds<'hir>,
     pub origin: OpaqueTyOrigin,
+    pub in_trait: bool,
 }
 
 /// From whence the opaque type came.
@@ -2518,12 +2519,6 @@ pub enum OpaqueTyOrigin {
     TyAlias,
 }
 
-/// Placeholder representation of an `impl Trait` in a trait. Since this never gets lowered into a `ty::Opaque` of its own, we just keep this as
-#[derive(Debug, HashStable_Generic)]
-pub struct ImplTraitPlaceholder<'hir> {
-    pub bounds: GenericBounds<'hir>,
-}
-
 /// The various kinds of types recognized by the compiler.
 #[derive(Debug, HashStable_Generic)]
 pub enum TyKind<'hir> {
@@ -2550,12 +2545,9 @@ pub enum TyKind<'hir> {
     ///
     /// The generic argument list contains the lifetimes (and in the future
     /// possibly parameters) that are actually bound on the `impl Trait`.
-    OpaqueDef(ItemId, &'hir [GenericArg<'hir>]),
-    /// A type that represents an `impl Trait` in a trait function. This is
-    /// not an opaque type, since it acts more like an associated type than
-    /// an opaque, and since it needs no generics since it inherits those
-    /// from the item's parent.
-    ImplTraitInTrait(ItemId),
+    ///
+    /// The last parameter specifies whether this opaque appears in a trait definition.
+    OpaqueDef(ItemId, &'hir [GenericArg<'hir>], bool),
     /// A trait object type `Bound1 + Bound2 + Bound3`
     /// where `Bound` is a trait or a lifetime.
     TraitObject(&'hir [PolyTraitRef<'hir>], &'hir Lifetime, TraitObjectSyntax),
@@ -3011,8 +3003,6 @@ pub enum ItemKind<'hir> {
     TyAlias(&'hir Ty<'hir>, &'hir Generics<'hir>),
     /// An opaque `impl Trait` type alias, e.g., `type Foo = impl Bar;`.
     OpaqueTy(OpaqueTy<'hir>),
-    /// An `impl Trait` in a trait
-    ImplTraitPlaceholder(ImplTraitPlaceholder<'hir>),
     /// An enum definition, e.g., `enum Foo<A, B> {C<A>, D<B>}`.
     Enum(EnumDef<'hir>, &'hir Generics<'hir>),
     /// A struct definition, e.g., `struct Foo<A> {x: A}`.
@@ -3081,7 +3071,6 @@ impl ItemKind<'_> {
             ItemKind::Trait(..) => "trait",
             ItemKind::TraitAlias(..) => "trait alias",
             ItemKind::Impl(..) => "implementation",
-            ItemKind::ImplTraitPlaceholder(..) => "opaque type in trait",
         }
     }
 }
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index 3e9ab10b1f7..bf4ab06638b 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -562,10 +562,6 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) {
             walk_generics(visitor, generics);
             walk_list!(visitor, visit_param_bound, bounds);
         }
-        ItemKind::ImplTraitPlaceholder(ImplTraitPlaceholder { bounds }) => {
-            visitor.visit_id(item.hir_id());
-            walk_list!(visitor, visit_param_bound, bounds);
-        }
         ItemKind::Enum(ref enum_definition, ref generics) => {
             visitor.visit_generics(generics);
             // `visit_enum_def()` takes care of visiting the `Item`'s `HirId`.
@@ -674,13 +670,10 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) {
         TyKind::Path(ref qpath) => {
             visitor.visit_qpath(qpath, typ.hir_id, typ.span);
         }
-        TyKind::OpaqueDef(item_id, lifetimes) => {
+        TyKind::OpaqueDef(item_id, lifetimes, _in_trait) => {
             visitor.visit_nested_item(item_id);
             walk_list!(visitor, visit_generic_arg, lifetimes);
         }
-        TyKind::ImplTraitInTrait(item_id) => {
-            visitor.visit_nested_item(item_id);
-        }
         TyKind::Array(ref ty, ref length) => {
             visitor.visit_ty(ty);
             visitor.visit_array_length(length)
diff --git a/compiler/rustc_hir/src/target.rs b/compiler/rustc_hir/src/target.rs
index 0e9b05729d2..5917d5e346e 100644
--- a/compiler/rustc_hir/src/target.rs
+++ b/compiler/rustc_hir/src/target.rs
@@ -80,8 +80,13 @@ impl Target {
             ItemKind::ForeignMod { .. } => Target::ForeignMod,
             ItemKind::GlobalAsm(..) => Target::GlobalAsm,
             ItemKind::TyAlias(..) => Target::TyAlias,
-            ItemKind::OpaqueTy(..) => Target::OpaqueTy,
-            ItemKind::ImplTraitPlaceholder(..) => Target::ImplTraitPlaceholder,
+            ItemKind::OpaqueTy(ref opaque) => {
+                if opaque.in_trait {
+                    Target::ImplTraitPlaceholder
+                } else {
+                    Target::OpaqueTy
+                }
+            }
             ItemKind::Enum(..) => Target::Enum,
             ItemKind::Struct(..) => Target::Struct,
             ItemKind::Union(..) => Target::Union,
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index 01f445c8a52..35a58296e37 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -327,7 +327,6 @@ impl<'a> State<'a> {
                 self.print_ty_fn(f.abi, f.unsafety, f.decl, None, f.generic_params, f.param_names);
             }
             hir::TyKind::OpaqueDef(..) => self.word("/*impl Trait*/"),
-            hir::TyKind::ImplTraitInTrait(..) => self.word("/*impl Trait*/"),
             hir::TyKind::Path(ref qpath) => self.print_qpath(qpath, false),
             hir::TyKind::TraitObject(bounds, ref lifetime, syntax) => {
                 if syntax == ast::TraitObjectSyntax::Dyn {
@@ -609,9 +608,6 @@ impl<'a> State<'a> {
                     state.print_bounds("= impl", real_bounds);
                 });
             }
-            hir::ItemKind::ImplTraitPlaceholder(..) => {
-                unreachable!("FIXME(RPITIT): I don't think this ever gets called here...");
-            }
             hir::ItemKind::Enum(ref enum_definition, params) => {
                 self.print_enum_def(enum_definition, params, item.ident.name, item.span);
             }
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 f804569b074..b115ac8b3df 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
@@ -300,7 +300,7 @@ pub fn suggest_new_region_bound(
             continue;
         }
         match fn_return.kind {
-            TyKind::OpaqueDef(item_id, _) => {
+            TyKind::OpaqueDef(item_id, _, _) => {
                 let item = tcx.hir().item(item_id);
                 let ItemKind::OpaqueTy(opaque) = &item.kind else {
                     return;
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index d45d814c3b0..f967ac9a4dc 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -1500,9 +1500,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             hir::ItemKind::OpaqueTy(..) => {
                 self.encode_explicit_item_bounds(def_id);
             }
-            hir::ItemKind::ImplTraitPlaceholder(..) => {
-                self.encode_explicit_item_bounds(def_id);
-            }
             hir::ItemKind::Enum(..) => {
                 let adt_def = self.tcx.adt_def(def_id);
                 record!(self.tables.repr_options[def_id] <- adt_def.repr());
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index 1a0bea68293..5a65ec9a476 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -212,8 +212,13 @@ impl<'hir> Map<'hir> {
                 ItemKind::Fn(..) => DefKind::Fn,
                 ItemKind::Macro(_, macro_kind) => DefKind::Macro(macro_kind),
                 ItemKind::Mod(..) => DefKind::Mod,
-                ItemKind::OpaqueTy(..) => DefKind::OpaqueTy,
-                ItemKind::ImplTraitPlaceholder(..) => DefKind::ImplTraitPlaceholder,
+                ItemKind::OpaqueTy(ref opaque) => {
+                    if opaque.in_trait {
+                        DefKind::ImplTraitPlaceholder
+                    } else {
+                        DefKind::OpaqueTy
+                    }
+                }
                 ItemKind::TyAlias(..) => DefKind::TyAlias,
                 ItemKind::Enum(..) => DefKind::Enum,
                 ItemKind::Struct(..) => DefKind::Struct,
@@ -1188,8 +1193,13 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
                 ItemKind::ForeignMod { .. } => "foreign mod",
                 ItemKind::GlobalAsm(..) => "global asm",
                 ItemKind::TyAlias(..) => "ty",
-                ItemKind::OpaqueTy(..) => "opaque type",
-                ItemKind::ImplTraitPlaceholder(..) => "opaque type in trait",
+                ItemKind::OpaqueTy(ref opaque) => {
+                    if opaque.in_trait {
+                        "opaque type in trait"
+                    } else {
+                        "opaque type"
+                    }
+                }
                 ItemKind::Enum(..) => "enum",
                 ItemKind::Struct(..) => "struct",
                 ItemKind::Union(..) => "union",
diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs
index e4ad96b659b..648f5f7161f 100644
--- a/compiler/rustc_middle/src/ty/diagnostics.rs
+++ b/compiler/rustc_middle/src/ty/diagnostics.rs
@@ -408,7 +408,7 @@ impl<'v> hir::intravisit::Visitor<'v> for TraitObjectVisitor<'v> {
             ) => {
                 self.0.push(ty);
             }
-            hir::TyKind::OpaqueDef(item_id, _) => {
+            hir::TyKind::OpaqueDef(item_id, _, _) => {
                 self.0.push(ty);
                 let item = self.1.item(item_id);
                 hir::intravisit::walk_item(self, item);
diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs
index a7ce0f312af..f141d7beeb9 100644
--- a/compiler/rustc_passes/src/dead.rs
+++ b/compiler/rustc_passes/src/dead.rs
@@ -447,7 +447,7 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> {
     }
 
     fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
-        if let TyKind::OpaqueDef(item_id, _) = ty.kind {
+        if let TyKind::OpaqueDef(item_id, _, _) = ty.kind {
             let item = self.tcx.hir().item(item_id);
             intravisit::walk_item(self, item);
         }
diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs
index 74c5ccf9cd2..f7e3fac6b2e 100644
--- a/compiler/rustc_passes/src/reachable.rs
+++ b/compiler/rustc_passes/src/reachable.rs
@@ -235,7 +235,6 @@ impl<'tcx> ReachableContext<'tcx> {
                     hir::ItemKind::ExternCrate(_)
                     | hir::ItemKind::Use(..)
                     | hir::ItemKind::OpaqueTy(..)
-                    | hir::ItemKind::ImplTraitPlaceholder(..)
                     | hir::ItemKind::TyAlias(..)
                     | hir::ItemKind::Macro(..)
                     | hir::ItemKind::Mod(..)
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index 3657fb21340..afd423dc5fa 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -686,7 +686,6 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
             }
 
             hir::ItemKind::OpaqueTy(..)
-            | hir::ItemKind::ImplTraitPlaceholder(..)
             | hir::ItemKind::Use(..)
             | hir::ItemKind::Static(..)
             | hir::ItemKind::Const(..)
@@ -708,12 +707,12 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
             hir::ItemKind::Use(..) => {}
             // The interface is empty.
             hir::ItemKind::GlobalAsm(..) => {}
-            hir::ItemKind::OpaqueTy(..) => {
+            hir::ItemKind::OpaqueTy(ref opaque) => {
                 // HACK(jynelson): trying to infer the type of `impl trait` breaks `async-std` (and `pub async fn` in general)
                 // Since rustdoc never needs to do codegen and doesn't care about link-time reachability,
                 // mark this as unreachable.
                 // See https://github.com/rust-lang/rust/issues/75100
-                if !self.tcx.sess.opts.actually_rustdoc {
+                if !opaque.in_trait && !self.tcx.sess.opts.actually_rustdoc {
                     // FIXME: This is some serious pessimization intended to workaround deficiencies
                     // in the reachability pass (`middle/reachable.rs`). Types are marked as link-time
                     // reachable if they are returned via `impl Trait`, even from private functions.
@@ -722,9 +721,6 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
                     self.reach(item.def_id, exist_level).generics().predicates().ty();
                 }
             }
-            hir::ItemKind::ImplTraitPlaceholder(..) => {
-                // FIXME(RPITIT): Do we need to do anything here?
-            }
             // Visit everything.
             hir::ItemKind::Const(..)
             | hir::ItemKind::Static(..)
@@ -2039,8 +2035,7 @@ fn local_visibility(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Visibility {
                 //   query failing on some items, we provide it for opaque types as well.
                 | Node::Item(hir::Item {
                     kind: hir::ItemKind::Use(_, hir::UseKind::ListStem)
-                        | hir::ItemKind::OpaqueTy(..)
-                        | hir::ItemKind::ImplTraitPlaceholder(..),
+                        | hir::ItemKind::OpaqueTy(..),
                     ..
                 }) => ty::Visibility::Restricted(tcx.parent_module(hir_id)),
                 // Visibilities of trait impl items are inherited from their traits
diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs
index e9e4f8fc483..6ff56f9a891 100644
--- a/compiler/rustc_resolve/src/late/lifetimes.rs
+++ b/compiler/rustc_resolve/src/late/lifetimes.rs
@@ -596,10 +596,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                     }
                 }
             }
-            hir::ItemKind::ImplTraitPlaceholder(..) => {
-                // FIXME(RPITIT): We don't need to do anything special here, right?
-                intravisit::walk_item(self, item);
-            }
             hir::ItemKind::TyAlias(_, ref generics)
             | hir::ItemKind::Enum(_, ref generics)
             | hir::ItemKind::Struct(_, ref generics)
@@ -719,7 +715,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                 };
                 self.with(scope, |this| this.visit_ty(&mt.ty));
             }
-            hir::TyKind::OpaqueDef(item_id, lifetimes) => {
+            hir::TyKind::OpaqueDef(item_id, lifetimes, _in_trait) => {
                 // Resolve the lifetimes in the bounds to the lifetime defs in the generics.
                 // `fn foo<'a>() -> impl MyTrait<'a> { ... }` desugars to
                 // `type MyAnonTy<'b> = impl MyTrait<'b>;`
diff --git a/compiler/rustc_save_analysis/src/dump_visitor.rs b/compiler/rustc_save_analysis/src/dump_visitor.rs
index 6658892881d..94f222251d3 100644
--- a/compiler/rustc_save_analysis/src/dump_visitor.rs
+++ b/compiler/rustc_save_analysis/src/dump_visitor.rs
@@ -1321,7 +1321,7 @@ impl<'tcx> Visitor<'tcx> for DumpVisitor<'tcx> {
                         }),
                 }
             }
-            hir::TyKind::OpaqueDef(item_id, _) => {
+            hir::TyKind::OpaqueDef(item_id, _, _) => {
                 let item = self.tcx.hir().item(item_id);
                 self.nest_typeck_results(item_id.def_id, |v| v.visit_item(item));
             }
diff --git a/compiler/rustc_save_analysis/src/sig.rs b/compiler/rustc_save_analysis/src/sig.rs
index ea9c82b3597..bae1828cd18 100644
--- a/compiler/rustc_save_analysis/src/sig.rs
+++ b/compiler/rustc_save_analysis/src/sig.rs
@@ -316,11 +316,7 @@ impl<'hir> Sig for hir::Ty<'hir> {
                 let text = format!("[{}; {}]", nested_ty.text, expr);
                 Ok(replace_text(nested_ty, text))
             }
-            hir::TyKind::OpaqueDef(item_id, _) => {
-                let item = scx.tcx.hir().item(item_id);
-                item.make(offset, Some(item_id.hir_id()), scx)
-            }
-            hir::TyKind::ImplTraitInTrait(item_id) => {
+            hir::TyKind::OpaqueDef(item_id, _, _) => {
                 let item = scx.tcx.hir().item(item_id);
                 item.make(offset, Some(item_id.hir_id()), scx)
             }
@@ -565,8 +561,13 @@ impl<'hir> Sig for hir::Item<'hir> {
             hir::ItemKind::ForeignMod { .. } => Err("extern mod"),
             hir::ItemKind::GlobalAsm(_) => Err("global asm"),
             hir::ItemKind::ExternCrate(_) => Err("extern crate"),
-            hir::ItemKind::OpaqueTy(..) => Err("opaque type"),
-            hir::ItemKind::ImplTraitPlaceholder(..) => Err("opaque type in trait"),
+            hir::ItemKind::OpaqueTy(ref opaque) => {
+                if opaque.in_trait {
+                    Err("opaque type in trait")
+                } else {
+                    Err("opaque type")
+                }
+            }
             // FIXME should implement this (e.g., pub use).
             hir::ItemKind::Use(..) => Err("import"),
         }
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index 7253ab21b3a..8a65262a007 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -2165,7 +2165,7 @@ fn confirm_impl_trait_in_trait_candidate<'tcx>(
     let tcx = selcx.tcx();
     let mut obligations = data.nested;
 
-    let trait_fn_def_id = tcx.parent(obligation.predicate.item_def_id);
+    let trait_fn_def_id = tcx.impl_trait_in_trait_parent(obligation.predicate.item_def_id);
     let Ok(leaf_def) = assoc_def(selcx, data.impl_def_id, trait_fn_def_id) else {
         return Progress { term: tcx.ty_error().into(), obligations };
     };
diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs
index 6eec2c57639..d9789d5aaf0 100644
--- a/compiler/rustc_typeck/src/astconv/mod.rs
+++ b/compiler/rustc_typeck/src/astconv/mod.rs
@@ -2360,7 +2360,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
 
         let span = path.span;
         match path.res {
-            Res::Def(DefKind::OpaqueTy, did) => {
+            Res::Def(DefKind::OpaqueTy | DefKind::ImplTraitPlaceholder, did) => {
                 // Check for desugared `impl Trait`.
                 assert!(ty::is_impl_trait_defn(tcx, did).is_none());
                 let item_segment = path.segments.split_last().unwrap();
@@ -2627,21 +2627,17 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 let opt_self_ty = maybe_qself.as_ref().map(|qself| self.ast_ty_to_ty(qself));
                 self.res_to_ty(opt_self_ty, path, false)
             }
-            hir::TyKind::OpaqueDef(item_id, lifetimes) => {
+            hir::TyKind::OpaqueDef(item_id, lifetimes, in_trait) => {
                 let opaque_ty = tcx.hir().item(item_id);
                 let def_id = item_id.def_id.to_def_id();
 
                 match opaque_ty.kind {
                     hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => {
-                        self.impl_trait_ty_to_ty(def_id, lifetimes, origin)
+                        self.impl_trait_ty_to_ty(def_id, lifetimes, origin, in_trait)
                     }
                     ref i => bug!("`impl Trait` pointed to non-opaque type?? {:#?}", i),
                 }
             }
-            hir::TyKind::ImplTraitInTrait(item_id) => {
-                let def_id = item_id.def_id.to_def_id();
-                tcx.mk_projection(def_id, InternalSubsts::identity_for_item(tcx, def_id))
-            }
             hir::TyKind::Path(hir::QPath::TypeRelative(ref qself, ref segment)) => {
                 debug!(?qself, ?segment);
                 let ty = self.ast_ty_to_ty_inner(qself, false, true);
@@ -2707,6 +2703,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         def_id: DefId,
         lifetimes: &[hir::GenericArg<'_>],
         origin: OpaqueTyOrigin,
+        in_trait: bool,
     ) -> Ty<'tcx> {
         debug!("impl_trait_ty_to_ty(def_id={:?}, lifetimes={:?})", def_id, lifetimes);
         let tcx = self.tcx();
@@ -2750,7 +2747,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         });
         debug!("impl_trait_ty_to_ty: substs={:?}", substs);
 
-        tcx.mk_opaque(def_id, substs)
+        if in_trait { tcx.mk_projection(def_id, substs) } else { tcx.mk_opaque(def_id, substs) }
     }
 
     pub fn ty_of_arg(&self, ty: &hir::Ty<'_>, expected_ty: Option<Ty<'tcx>>) -> Ty<'tcx> {
diff --git a/compiler/rustc_typeck/src/check/compare_method.rs b/compiler/rustc_typeck/src/check/compare_method.rs
index da45469863e..a6c8dbb2555 100644
--- a/compiler/rustc_typeck/src/check/compare_method.rs
+++ b/compiler/rustc_typeck/src/check/compare_method.rs
@@ -423,9 +423,28 @@ pub(super) fn compare_predicates_and_trait_impl_trait_tys<'tcx>(
         );
 
         let mut collected_tys = FxHashMap::default();
-        for (def_id, ty) in collector.types {
+        for (def_id, (ty, substs)) in collector.types {
             match infcx.fully_resolve(ty) {
                 Ok(ty) => {
+                    // `ty` contains free regions that we created earlier while liberating the
+                    // trait fn signature.  However, projection normalization expects `ty` to
+                    // contains `def_id`'s early-bound regions.
+                    let id_substs = InternalSubsts::identity_for_item(tcx, def_id);
+                    debug!(?id_substs, ?substs);
+                    let map: FxHashMap<ty::GenericArg<'tcx>, ty::GenericArg<'tcx>> = substs
+                        .iter()
+                        .enumerate()
+                        .map(|(index, arg)| (arg, id_substs[index]))
+                        .collect();
+                    debug!(?map);
+
+                    let ty = tcx.fold_regions(ty, |region, _| {
+                        if let ty::ReFree(_) = region.kind() {
+                            map[&region.into()].expect_region()
+                        } else {
+                            region
+                        }
+                    });
                     collected_tys.insert(def_id, ty);
                 }
                 Err(err) => {
@@ -444,7 +463,7 @@ pub(super) fn compare_predicates_and_trait_impl_trait_tys<'tcx>(
 
 struct ImplTraitInTraitCollector<'a, 'tcx> {
     ocx: &'a ObligationCtxt<'a, 'tcx>,
-    types: FxHashMap<DefId, Ty<'tcx>>,
+    types: FxHashMap<DefId, (Ty<'tcx>, ty::SubstsRef<'tcx>)>,
     span: Span,
     param_env: ty::ParamEnv<'tcx>,
     body_id: hir::HirId,
@@ -470,7 +489,7 @@ impl<'tcx> TypeFolder<'tcx> for ImplTraitInTraitCollector<'_, 'tcx> {
         if let ty::Projection(proj) = ty.kind()
             && self.tcx().def_kind(proj.item_def_id) == DefKind::ImplTraitPlaceholder
         {
-            if let Some(ty) = self.types.get(&proj.item_def_id) {
+            if let Some((ty, _)) = self.types.get(&proj.item_def_id) {
                 return *ty;
             }
             //FIXME(RPITIT): Deny nested RPITIT in substs too
@@ -482,7 +501,7 @@ impl<'tcx> TypeFolder<'tcx> for ImplTraitInTraitCollector<'_, 'tcx> {
                 span: self.span,
                 kind: TypeVariableOriginKind::MiscVariable,
             });
-            self.types.insert(proj.item_def_id, infer_ty);
+            self.types.insert(proj.item_def_id, (infer_ty, proj.substs));
             // Recurse into bounds
             for pred in self.tcx().bound_explicit_item_bounds(proj.item_def_id).transpose_iter() {
                 let pred_span = pred.0.1;
diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs
index e5e82a4ff6b..ceb5684fdf0 100644
--- a/compiler/rustc_typeck/src/collect.rs
+++ b/compiler/rustc_typeck/src/collect.rs
@@ -815,11 +815,6 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
             tcx.ensure().predicates_of(def_id);
             tcx.ensure().explicit_item_bounds(def_id);
         }
-        hir::ItemKind::ImplTraitPlaceholder(..) => {
-            tcx.ensure().generics_of(def_id);
-            tcx.ensure().predicates_of(def_id);
-            tcx.ensure().explicit_item_bounds(def_id);
-        }
         hir::ItemKind::TyAlias(..)
         | hir::ItemKind::Static(..)
         | hir::ItemKind::Const(..)
@@ -1590,8 +1585,16 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
             ItemKind::OpaqueTy(hir::OpaqueTy {
                 origin:
                     hir::OpaqueTyOrigin::FnReturn(fn_def_id) | hir::OpaqueTyOrigin::AsyncFn(fn_def_id),
+                in_trait,
                 ..
-            }) => Some(fn_def_id.to_def_id()),
+            }) => {
+                if in_trait {
+                    assert!(matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn))
+                } else {
+                    assert!(matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn | DefKind::Fn))
+                }
+                Some(fn_def_id.to_def_id())
+            }
             ItemKind::OpaqueTy(hir::OpaqueTy { origin: hir::OpaqueTyOrigin::TyAlias, .. }) => {
                 let parent_id = tcx.hir().get_parent_item(hir_id);
                 assert_ne!(parent_id, CRATE_DEF_ID);
@@ -1600,14 +1603,6 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
                 // inherit the generics of the item.
                 Some(parent_id.to_def_id())
             }
-            ItemKind::ImplTraitPlaceholder(_) => {
-                let parent_id = tcx.hir().get_parent_item(hir_id).to_def_id();
-                assert!(matches!(
-                    tcx.def_kind(parent_id),
-                    DefKind::AssocFn | DefKind::ImplTraitPlaceholder
-                ));
-                Some(parent_id)
-            }
             _ => None,
         },
         _ => None,
@@ -1800,7 +1795,7 @@ fn is_suggestable_infer_ty(ty: &hir::Ty<'_>) -> bool {
         }
         Tup(tys) => tys.iter().any(is_suggestable_infer_ty),
         Ptr(mut_ty) | Rptr(_, mut_ty) => is_suggestable_infer_ty(mut_ty.ty),
-        OpaqueDef(_, generic_args) => are_suggestable_generic_args(generic_args),
+        OpaqueDef(_, generic_args, _) => are_suggestable_generic_args(generic_args),
         Path(hir::QPath::TypeRelative(ty, segment)) => {
             is_suggestable_infer_ty(ty) || are_suggestable_generic_args(segment.args().args)
         }
diff --git a/compiler/rustc_typeck/src/collect/item_bounds.rs b/compiler/rustc_typeck/src/collect/item_bounds.rs
index fe8d8f54f04..0d34a8bfee3 100644
--- a/compiler/rustc_typeck/src/collect/item_bounds.rs
+++ b/compiler/rustc_typeck/src/collect/item_bounds.rs
@@ -59,10 +59,15 @@ fn opaque_type_bounds<'tcx>(
     opaque_def_id: DefId,
     ast_bounds: &'tcx [hir::GenericBound<'tcx>],
     span: Span,
+    in_trait: bool,
 ) -> &'tcx [(ty::Predicate<'tcx>, Span)] {
     ty::print::with_no_queries!({
-        let item_ty =
-            tcx.mk_opaque(opaque_def_id, InternalSubsts::identity_for_item(tcx, opaque_def_id));
+        let substs = InternalSubsts::identity_for_item(tcx, opaque_def_id);
+        let item_ty = if in_trait {
+            tcx.mk_projection(opaque_def_id, substs)
+        } else {
+            tcx.mk_opaque(opaque_def_id, substs)
+        };
 
         let icx = ItemCtxt::new(tcx, opaque_def_id);
         let mut bounds = <dyn AstConv<'_>>::compute_bounds(&icx, item_ty, ast_bounds);
@@ -74,29 +79,6 @@ fn opaque_type_bounds<'tcx>(
     })
 }
 
-/// Opaque types don't inherit bounds from their parent: for return position
-/// impl trait it isn't possible to write a suitable predicate on the
-/// containing function and for type-alias impl trait we don't have a backwards
-/// compatibility issue.
-fn impl_trait_in_trait_item_bounds<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    opaque_def_id: DefId,
-    ast_bounds: &'tcx [hir::GenericBound<'tcx>],
-    span: Span,
-) -> &'tcx [(ty::Predicate<'tcx>, Span)] {
-    ty::print::with_no_queries!({
-        // FIXME(RPITIT): DRY-er code please
-        let item_ty =
-            tcx.mk_projection(opaque_def_id, InternalSubsts::identity_for_item(tcx, opaque_def_id));
-
-        let icx = ItemCtxt::new(tcx, opaque_def_id);
-        let mut bounds = <dyn AstConv<'_>>::compute_bounds(&icx, item_ty, ast_bounds);
-        // RPITITs are implicitly sized unless a `?Sized` bound is found
-        <dyn AstConv<'_>>::add_implicitly_sized(&icx, &mut bounds, ast_bounds, None, span);
-        tcx.arena.alloc_from_iter(bounds.predicates(tcx, item_ty))
-    })
-}
-
 pub(super) fn explicit_item_bounds(
     tcx: TyCtxt<'_>,
     def_id: DefId,
@@ -109,15 +91,10 @@ pub(super) fn explicit_item_bounds(
             ..
         }) => associated_type_bounds(tcx, def_id, bounds, *span),
         hir::Node::Item(hir::Item {
-            kind: hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, .. }),
-            span,
-            ..
-        }) => opaque_type_bounds(tcx, def_id, bounds, *span),
-        hir::Node::Item(hir::Item {
-            kind: hir::ItemKind::ImplTraitPlaceholder(hir::ImplTraitPlaceholder { bounds }),
+            kind: hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, in_trait, .. }),
             span,
             ..
-        }) => impl_trait_in_trait_item_bounds(tcx, def_id, bounds, *span),
+        }) => opaque_type_bounds(tcx, def_id, bounds, *span, *in_trait),
         _ => bug!("item_bounds called on {:?}", def_id),
     }
 }
diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs
index ded2ac1308e..a26e26cb389 100644
--- a/compiler/rustc_typeck/src/collect/type_of.rs
+++ b/compiler/rustc_typeck/src/collect/type_of.rs
@@ -333,11 +333,12 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
                     find_opaque_ty_constraints_for_tait(tcx, def_id)
                 }
                 // Opaque types desugared from `impl Trait`.
-                ItemKind::OpaqueTy(OpaqueTy { origin: hir::OpaqueTyOrigin::FnReturn(owner) | hir::OpaqueTyOrigin::AsyncFn(owner), .. }) => {
-                    find_opaque_ty_constraints_for_rpit(tcx, def_id, owner)
-                }
-                ItemKind::ImplTraitPlaceholder(..) => {
-                    span_bug!(item.span, "not yet implemented")
+                ItemKind::OpaqueTy(OpaqueTy { origin: hir::OpaqueTyOrigin::FnReturn(owner) | hir::OpaqueTyOrigin::AsyncFn(owner), in_trait, .. }) => {
+                    if in_trait {
+                        span_bug!(item.span, "impl-trait in trait has no default")
+                    } else {
+                        find_opaque_ty_constraints_for_rpit(tcx, def_id, owner)
+                    }
                 }
                 ItemKind::Trait(..)
                 | ItemKind::TraitAlias(..)
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 03752c9b6db..08b696e65eb 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1492,7 +1492,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T
             Array(Box::new(clean_ty(ty, cx)), length)
         }
         TyKind::Tup(tys) => Tuple(tys.iter().map(|ty| clean_ty(ty, cx)).collect()),
-        TyKind::OpaqueDef(item_id, _) => {
+        TyKind::OpaqueDef(item_id, _, _) => {
             let item = cx.tcx.hir().item(item_id);
             if let hir::ItemKind::OpaqueTy(ref ty) = item.kind {
                 ImplTrait(ty.bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect())
@@ -1500,16 +1500,6 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T
                 unreachable!()
             }
         }
-        TyKind::ImplTraitInTrait(item_id) => {
-            let item = cx.tcx.hir().item(item_id);
-            if let hir::ItemKind::ImplTraitPlaceholder(hir::ImplTraitPlaceholder { bounds }) =
-                item.kind
-            {
-                ImplTrait(bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect())
-            } else {
-                unreachable!()
-            }
-        }
         TyKind::Path(_) => clean_qpath(ty, cx),
         TyKind::TraitObject(bounds, ref lifetime, _) => {
             let bounds = bounds.iter().map(|bound| clean_poly_trait_ref(bound, cx)).collect();
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index 7fe391f420f..ca7a20bf368 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -362,7 +362,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
             | hir::ItemKind::Union(..)
             | hir::ItemKind::TyAlias(..)
             | hir::ItemKind::OpaqueTy(..)
-            | hir::ItemKind::ImplTraitPlaceholder(..)
             | hir::ItemKind::Static(..)
             | hir::ItemKind::Trait(..)
             | hir::ItemKind::TraitAlias(..) => om.items.push((item, renamed)),
diff --git a/src/test/ui/impl-trait/in-trait/opaque-in-impl.rs b/src/test/ui/impl-trait/in-trait/opaque-in-impl.rs
index a777cbcd529..2e06629699a 100644
--- a/src/test/ui/impl-trait/in-trait/opaque-in-impl.rs
+++ b/src/test/ui/impl-trait/in-trait/opaque-in-impl.rs
@@ -3,18 +3,46 @@
 #![feature(return_position_impl_trait_in_trait)]
 #![allow(incomplete_features)]
 
-use std::fmt::Display;
+use std::fmt::Debug;
 
 trait Foo {
-    fn bar(&self) -> impl Display;
+    fn foo(&self) -> impl Debug;
 }
 
 impl Foo for () {
-    fn bar(&self) -> impl Display {
+    fn foo(&self) -> impl Debug {
         "Hello, world"
     }
 }
 
+impl<T: Default + Debug> Foo for std::marker::PhantomData<T> {
+    fn foo(&self) -> impl Debug {
+        T::default()
+    }
+}
+
+trait Bar {
+    fn bar<T>(&self) -> impl Debug;
+}
+
+impl Bar for () {
+    fn bar<T>(&self) -> impl Debug {
+        format!("Hello with generic {}", std::any::type_name::<T>())
+    }
+}
+
+trait Baz {
+    fn baz(&self) -> impl Debug + '_;
+}
+
+impl Baz for String {
+    fn baz(&self) -> impl Debug + '_ {
+        (self,)
+    }
+}
+
 fn main() {
-    println!("{}", ().bar());
+    println!("{:?}", ().foo());
+    println!("{:?}", ().bar::<u64>());
+    println!("{:?}", "hi".to_string().baz());
 }