diff options
| author | Santiago Pastorino <spastorino@gmail.com> | 2023-02-16 18:12:53 -0300 |
|---|---|---|
| committer | Santiago Pastorino <spastorino@gmail.com> | 2023-02-19 11:57:38 -0300 |
| commit | 45b0d9da6b463c73cf1f816e9cbe9483ebc84a6d (patch) | |
| tree | 8a1a7a764b80c9b69273f021be236b024bcc09fe /compiler/rustc_ty_utils | |
| parent | b7dd609d9c3a6a336091e502caee8a10948cc2c3 (diff) | |
| download | rust-45b0d9da6b463c73cf1f816e9cbe9483ebc84a6d.tar.gz rust-45b0d9da6b463c73cf1f816e9cbe9483ebc84a6d.zip | |
Make associated_items_for_impl_trait_in_trait handle impl traits on impls
Diffstat (limited to 'compiler/rustc_ty_utils')
| -rw-r--r-- | compiler/rustc_ty_utils/src/assoc.rs | 78 |
1 files changed, 60 insertions, 18 deletions
diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index ef725c48da6..0c3322d48f0 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -119,29 +119,58 @@ fn associated_item_from_impl_item_ref(impl_item_ref: &hir::ImplItemRef) -> ty::A } fn associated_items_for_impl_trait_in_trait(tcx: TyCtxt<'_>, fn_def_id: DefId) -> &'_ [DefId] { - struct RPITVisitor { - rpits: Vec<LocalDefId>, - } + let parent_def_id = tcx.parent(fn_def_id); - impl<'v> Visitor<'v> for RPITVisitor { - fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) { - if let hir::TyKind::OpaqueDef(item_id, _, _) = ty.kind { - self.rpits.push(item_id.owner_id.def_id) + match tcx.def_kind(parent_def_id) { + DefKind::Trait => { + struct RPITVisitor { + rpits: Vec<LocalDefId>, } - intravisit::walk_ty(self, ty) - } - } - let mut visitor = RPITVisitor { rpits: Vec::new() }; + impl<'v> Visitor<'v> for RPITVisitor { + fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) { + if let hir::TyKind::OpaqueDef(item_id, _, _) = ty.kind { + self.rpits.push(item_id.owner_id.def_id) + } + intravisit::walk_ty(self, ty) + } + } - if let Some(output) = tcx.hir().get_fn_output(fn_def_id.expect_local()) { - visitor.visit_fn_ret_ty(output); + let mut visitor = RPITVisitor { rpits: Vec::new() }; - tcx.arena.alloc_from_iter(visitor.rpits.iter().map(|opaque_ty_def_id| { - tcx.associated_item_for_impl_trait_in_trait(opaque_ty_def_id).to_def_id() - })) - } else { - &[] + if let Some(output) = tcx.hir().get_fn_output(fn_def_id.expect_local()) { + visitor.visit_fn_ret_ty(output); + + tcx.arena.alloc_from_iter(visitor.rpits.iter().map(|opaque_ty_def_id| { + tcx.associated_item_for_impl_trait_in_trait(opaque_ty_def_id).to_def_id() + })) + } else { + &[] + } + } + + DefKind::Impl { .. } => { + let Some(trait_fn_def_id) = tcx.associated_item(fn_def_id).trait_item_def_id else { return &[] }; + + tcx.arena.alloc_from_iter( + tcx.associated_items_for_impl_trait_in_trait(trait_fn_def_id).iter().map( + move |trait_assoc_def_id| { + impl_associated_item_for_impl_trait_in_trait( + tcx, + trait_assoc_def_id.expect_local(), + fn_def_id.expect_local(), + ) + .to_def_id() + }, + ), + ) + } + + def_kind => bug!( + "associated_items_for_impl_trait_in_trait: {:?} should be Trait or Impl but is {:?}", + parent_def_id, + def_kind + ), } } @@ -158,3 +187,16 @@ fn associated_item_for_impl_trait_in_trait( tcx.at(span).create_def(trait_def_id.expect_local(), DefPathData::ImplTraitAssocTy); trait_assoc_ty.def_id() } + +fn impl_associated_item_for_impl_trait_in_trait( + tcx: TyCtxt<'_>, + trait_assoc_def_id: LocalDefId, + impl_fn_def_id: LocalDefId, +) -> LocalDefId { + let impl_def_id = tcx.local_parent(impl_fn_def_id); + + let span = tcx.def_span(trait_assoc_def_id); + let impl_assoc_ty = tcx.at(span).create_def(impl_def_id, DefPathData::ImplTraitAssocTy); + + impl_assoc_ty.def_id() +} |
