Skip to content

Commit f8aea8d

Browse files
Walk return-position impl trait in trait deeply in associated_item_def_ids
1 parent 75a9f5d commit f8aea8d

File tree

3 files changed

+45
-28
lines changed

3 files changed

+45
-28
lines changed

compiler/rustc_ty_utils/src/assoc.rs

+29-23
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use rustc_data_structures::fx::FxIndexSet;
12
use rustc_hir as hir;
23
use rustc_hir::def::DefKind;
34
use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId};
@@ -196,20 +197,26 @@ fn associated_types_for_impl_traits_in_associated_fn(
196197

197198
match tcx.def_kind(parent_def_id) {
198199
DefKind::Trait => {
199-
struct RPITVisitor {
200-
rpits: Vec<LocalDefId>,
200+
struct RPITVisitor<'tcx> {
201+
rpits: FxIndexSet<LocalDefId>,
202+
tcx: TyCtxt<'tcx>,
201203
}
202204

203-
impl<'v> Visitor<'v> for RPITVisitor {
204-
fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) {
205-
if let hir::TyKind::OpaqueDef(item_id, _, _) = ty.kind {
206-
self.rpits.push(item_id.owner_id.def_id)
205+
impl<'tcx> Visitor<'tcx> for RPITVisitor<'tcx> {
206+
fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
207+
if let hir::TyKind::OpaqueDef(item_id, _, _) = ty.kind
208+
&& self.rpits.insert(item_id.owner_id.def_id)
209+
{
210+
let opaque_item = self.tcx.hir().expect_item(item_id.owner_id.def_id).expect_opaque_ty();
211+
for bound in opaque_item.bounds {
212+
intravisit::walk_param_bound(self, bound);
213+
}
207214
}
208215
intravisit::walk_ty(self, ty)
209216
}
210217
}
211218

212-
let mut visitor = RPITVisitor { rpits: Vec::new() };
219+
let mut visitor = RPITVisitor { tcx, rpits: FxIndexSet::default() };
213220

214221
if let Some(output) = tcx.hir().get_fn_output(fn_def_id) {
215222
visitor.visit_fn_ret_ty(output);
@@ -227,13 +234,9 @@ fn associated_types_for_impl_traits_in_associated_fn(
227234

228235
tcx.arena.alloc_from_iter(
229236
tcx.associated_types_for_impl_traits_in_associated_fn(trait_fn_def_id).iter().map(
230-
move |trait_assoc_def_id| {
231-
associated_type_for_impl_trait_in_impl(
232-
tcx,
233-
trait_assoc_def_id.expect_local(),
234-
fn_def_id,
235-
)
236-
.to_def_id()
237+
move |&trait_assoc_def_id| {
238+
associated_type_for_impl_trait_in_impl(tcx, trait_assoc_def_id, fn_def_id)
239+
.to_def_id()
237240
},
238241
),
239242
)
@@ -254,13 +257,16 @@ fn associated_type_for_impl_trait_in_trait(
254257
tcx: TyCtxt<'_>,
255258
opaque_ty_def_id: LocalDefId,
256259
) -> LocalDefId {
257-
let fn_def_id = tcx.impl_trait_in_trait_parent_fn(opaque_ty_def_id.to_def_id());
258-
let trait_def_id = tcx.parent(fn_def_id);
260+
let (hir::OpaqueTyOrigin::FnReturn(fn_def_id) | hir::OpaqueTyOrigin::AsyncFn(fn_def_id)) =
261+
tcx.hir().expect_item(opaque_ty_def_id).expect_opaque_ty().origin
262+
else {
263+
bug!("expected opaque for {opaque_ty_def_id:?}");
264+
};
265+
let trait_def_id = tcx.local_parent(fn_def_id);
259266
assert_eq!(tcx.def_kind(trait_def_id), DefKind::Trait);
260267

261268
let span = tcx.def_span(opaque_ty_def_id);
262-
let trait_assoc_ty =
263-
tcx.at(span).create_def(trait_def_id.expect_local(), DefPathData::ImplTraitAssocTy);
269+
let trait_assoc_ty = tcx.at(span).create_def(trait_def_id, DefPathData::ImplTraitAssocTy);
264270

265271
let local_def_id = trait_assoc_ty.def_id();
266272
let def_id = local_def_id.to_def_id();
@@ -282,7 +288,7 @@ fn associated_type_for_impl_trait_in_trait(
282288
container: ty::TraitContainer,
283289
fn_has_self_parameter: false,
284290
opt_rpitit_info: Some(ImplTraitInTraitData::Trait {
285-
fn_def_id,
291+
fn_def_id: fn_def_id.to_def_id(),
286292
opaque_def_id: opaque_ty_def_id.to_def_id(),
287293
}),
288294
});
@@ -324,7 +330,7 @@ fn associated_type_for_impl_trait_in_trait(
324330
params.iter().map(|param| (param.def_id, param.index)).collect();
325331

326332
ty::Generics {
327-
parent: Some(trait_def_id),
333+
parent: Some(trait_def_id.to_def_id()),
328334
parent_count,
329335
params,
330336
param_def_id_to_index,
@@ -335,7 +341,7 @@ fn associated_type_for_impl_trait_in_trait(
335341

336342
// There are no predicates for the synthesized associated type.
337343
trait_assoc_ty.explicit_predicates_of(ty::GenericPredicates {
338-
parent: Some(trait_def_id),
344+
parent: Some(trait_def_id.to_def_id()),
339345
predicates: &[],
340346
});
341347

@@ -352,7 +358,7 @@ fn associated_type_for_impl_trait_in_trait(
352358
/// that inherits properties that we infer from the method and the associated type.
353359
fn associated_type_for_impl_trait_in_impl(
354360
tcx: TyCtxt<'_>,
355-
trait_assoc_def_id: LocalDefId,
361+
trait_assoc_def_id: DefId,
356362
impl_fn_def_id: LocalDefId,
357363
) -> LocalDefId {
358364
let impl_local_def_id = tcx.local_parent(impl_fn_def_id);
@@ -378,7 +384,7 @@ fn associated_type_for_impl_trait_in_impl(
378384
name: kw::Empty,
379385
kind: ty::AssocKind::Type,
380386
def_id,
381-
trait_item_def_id: Some(trait_assoc_def_id.to_def_id()),
387+
trait_item_def_id: Some(trait_assoc_def_id),
382388
container: ty::ImplContainer,
383389
fn_has_self_parameter: false,
384390
opt_rpitit_info: Some(ImplTraitInTraitData::Impl { fn_def_id: impl_fn_def_id.to_def_id() }),

tests/ui/impl-trait/in-trait/auxiliary/rpitit.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22

33
#![feature(return_position_impl_trait_in_trait)]
44

5+
use std::ops::Deref;
6+
57
pub trait Foo {
6-
fn bar() -> impl Sized;
8+
fn bar() -> impl Deref<Target = impl Sized>;
79
}
810

911
pub struct Foreign;
10-
1112
impl Foo for Foreign {
12-
fn bar() {}
13+
fn bar() -> &'static () { &() }
1314
}

tests/ui/impl-trait/in-trait/foreign.rs

+12-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,17 @@
55

66
extern crate rpitit;
77

8+
use std::sync::Arc;
9+
10+
// Implement an RPITIT from another crate.
11+
struct Local;
12+
impl rpitit::Foo for Local {
13+
fn bar() -> Arc<String> { Arc::new(String::new()) }
14+
}
15+
816
fn main() {
9-
// Witness an RPITIT from another crate
10-
let () = <rpitit::Foreign as rpitit::Foo>::bar();
17+
// Witness an RPITIT from another crate.
18+
let &() = <rpitit::Foreign as rpitit::Foo>::bar();
19+
20+
let x: Arc<String> = <Local as rpitit::Foo>::bar();
1121
}

0 commit comments

Comments
 (0)