Skip to content

Commit 45b0d9d

Browse files
committed
Make associated_items_for_impl_trait_in_trait handle impl traits on impls
1 parent b7dd609 commit 45b0d9d

File tree

1 file changed

+60
-18
lines changed

1 file changed

+60
-18
lines changed

compiler/rustc_ty_utils/src/assoc.rs

+60-18
Original file line numberDiff line numberDiff line change
@@ -119,29 +119,58 @@ fn associated_item_from_impl_item_ref(impl_item_ref: &hir::ImplItemRef) -> ty::A
119119
}
120120

121121
fn associated_items_for_impl_trait_in_trait(tcx: TyCtxt<'_>, fn_def_id: DefId) -> &'_ [DefId] {
122-
struct RPITVisitor {
123-
rpits: Vec<LocalDefId>,
124-
}
122+
let parent_def_id = tcx.parent(fn_def_id);
125123

126-
impl<'v> Visitor<'v> for RPITVisitor {
127-
fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) {
128-
if let hir::TyKind::OpaqueDef(item_id, _, _) = ty.kind {
129-
self.rpits.push(item_id.owner_id.def_id)
124+
match tcx.def_kind(parent_def_id) {
125+
DefKind::Trait => {
126+
struct RPITVisitor {
127+
rpits: Vec<LocalDefId>,
130128
}
131-
intravisit::walk_ty(self, ty)
132-
}
133-
}
134129

135-
let mut visitor = RPITVisitor { rpits: Vec::new() };
130+
impl<'v> Visitor<'v> for RPITVisitor {
131+
fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) {
132+
if let hir::TyKind::OpaqueDef(item_id, _, _) = ty.kind {
133+
self.rpits.push(item_id.owner_id.def_id)
134+
}
135+
intravisit::walk_ty(self, ty)
136+
}
137+
}
136138

137-
if let Some(output) = tcx.hir().get_fn_output(fn_def_id.expect_local()) {
138-
visitor.visit_fn_ret_ty(output);
139+
let mut visitor = RPITVisitor { rpits: Vec::new() };
139140

140-
tcx.arena.alloc_from_iter(visitor.rpits.iter().map(|opaque_ty_def_id| {
141-
tcx.associated_item_for_impl_trait_in_trait(opaque_ty_def_id).to_def_id()
142-
}))
143-
} else {
144-
&[]
141+
if let Some(output) = tcx.hir().get_fn_output(fn_def_id.expect_local()) {
142+
visitor.visit_fn_ret_ty(output);
143+
144+
tcx.arena.alloc_from_iter(visitor.rpits.iter().map(|opaque_ty_def_id| {
145+
tcx.associated_item_for_impl_trait_in_trait(opaque_ty_def_id).to_def_id()
146+
}))
147+
} else {
148+
&[]
149+
}
150+
}
151+
152+
DefKind::Impl { .. } => {
153+
let Some(trait_fn_def_id) = tcx.associated_item(fn_def_id).trait_item_def_id else { return &[] };
154+
155+
tcx.arena.alloc_from_iter(
156+
tcx.associated_items_for_impl_trait_in_trait(trait_fn_def_id).iter().map(
157+
move |trait_assoc_def_id| {
158+
impl_associated_item_for_impl_trait_in_trait(
159+
tcx,
160+
trait_assoc_def_id.expect_local(),
161+
fn_def_id.expect_local(),
162+
)
163+
.to_def_id()
164+
},
165+
),
166+
)
167+
}
168+
169+
def_kind => bug!(
170+
"associated_items_for_impl_trait_in_trait: {:?} should be Trait or Impl but is {:?}",
171+
parent_def_id,
172+
def_kind
173+
),
145174
}
146175
}
147176

@@ -158,3 +187,16 @@ fn associated_item_for_impl_trait_in_trait(
158187
tcx.at(span).create_def(trait_def_id.expect_local(), DefPathData::ImplTraitAssocTy);
159188
trait_assoc_ty.def_id()
160189
}
190+
191+
fn impl_associated_item_for_impl_trait_in_trait(
192+
tcx: TyCtxt<'_>,
193+
trait_assoc_def_id: LocalDefId,
194+
impl_fn_def_id: LocalDefId,
195+
) -> LocalDefId {
196+
let impl_def_id = tcx.local_parent(impl_fn_def_id);
197+
198+
let span = tcx.def_span(trait_assoc_def_id);
199+
let impl_assoc_ty = tcx.at(span).create_def(impl_def_id, DefPathData::ImplTraitAssocTy);
200+
201+
impl_assoc_ty.def_id()
202+
}

0 commit comments

Comments
 (0)