diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2023-03-02 23:05:31 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-03-02 23:05:31 +0100 |
| commit | e85df8d0fe169f8c9b25f2dfe775b62e22ccd20f (patch) | |
| tree | 5510959c6bc814d01b5f71f70a733a3f48351a8d | |
| parent | 8a21bcee254c9175345266dad9c1ac00399d73f9 (diff) | |
| parent | fa6bf2afdb68e498a970662b43028ea567c5ab02 (diff) | |
| download | rust-e85df8d0fe169f8c9b25f2dfe775b62e22ccd20f.tar.gz rust-e85df8d0fe169f8c9b25f2dfe775b62e22ccd20f.zip | |
Rollup merge of #108672 - spastorino:new-rpitit-impl-side, r=compiler-errors
Feed queries on impl side for RPITITs when using lower_impl_trait_in_trait_to_assoc_ty I've added a test for traits that were already working and what I think is probably the last bit of infrastructure work needed. In following PRs I'm going to start adding things TDD style, tests and code that make it work. r? `@compiler-errors`
| -rw-r--r-- | compiler/rustc_ty_utils/src/assoc.rs | 70 | ||||
| -rw-r--r-- | tests/ui/impl-trait/in-trait/new-lowering-strategy/simple-trait.rs | 11 |
2 files changed, 76 insertions, 5 deletions
diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index efbbfe6c24b..0648784b265 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -53,9 +53,37 @@ fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: DefId) -> &[DefId] { ) } } - hir::ItemKind::Impl(ref impl_) => tcx.arena.alloc_from_iter( - impl_.items.iter().map(|impl_item_ref| impl_item_ref.id.owner_id.to_def_id()), - ), + hir::ItemKind::Impl(ref impl_) => { + if tcx.sess.opts.unstable_opts.lower_impl_trait_in_trait_to_assoc_ty { + // We collect RPITITs for each trait method's return type, on the impl side too and + // create a corresponding associated item using + // associated_items_for_impl_trait_in_trait query. + tcx.arena.alloc_from_iter( + impl_ + .items + .iter() + .map(|impl_item_ref| impl_item_ref.id.owner_id.to_def_id()) + .chain(impl_.of_trait.iter().flat_map(|_| { + impl_ + .items + .iter() + .filter(|impl_item_ref| { + matches!(impl_item_ref.kind, hir::AssocItemKind::Fn { .. }) + }) + .flat_map(|impl_item_ref| { + let impl_fn_def_id = + impl_item_ref.id.owner_id.def_id.to_def_id(); + tcx.associated_items_for_impl_trait_in_trait(impl_fn_def_id) + }) + .map(|def_id| *def_id) + })), + ) + } else { + tcx.arena.alloc_from_iter( + impl_.items.iter().map(|impl_item_ref| impl_item_ref.id.owner_id.to_def_id()), + ) + } + } _ => span_bug!(item.span, "associated_item_def_ids: not impl or trait"), } } @@ -290,8 +318,40 @@ fn impl_associated_item_for_impl_trait_in_trait( ) -> LocalDefId { let impl_def_id = tcx.local_parent(impl_fn_def_id); - let span = tcx.def_span(trait_assoc_def_id); + // FIXME fix the span, we probably want the def_id of the return type of the function + let span = tcx.def_span(impl_fn_def_id); let impl_assoc_ty = tcx.at(span).create_def(impl_def_id, DefPathData::ImplTraitAssocTy); - impl_assoc_ty.def_id() + let local_def_id = impl_assoc_ty.def_id(); + let def_id = local_def_id.to_def_id(); + + impl_assoc_ty.opt_def_kind(Some(DefKind::AssocTy)); + + // There's no HIR associated with this new synthesized `def_id`, so feed + // `opt_local_def_id_to_hir_id` with `None`. + impl_assoc_ty.opt_local_def_id_to_hir_id(None); + + // Add the def_id of the function that generated this synthesized associated type. + impl_assoc_ty.opt_rpitit_info(Some(ImplTraitInTraitData::Impl { + fn_def_id: impl_fn_def_id.to_def_id(), + })); + + impl_assoc_ty.associated_item(ty::AssocItem { + name: kw::Empty, + kind: ty::AssocKind::Type, + def_id, + trait_item_def_id: Some(trait_assoc_def_id.to_def_id()), + container: ty::ImplContainer, + fn_has_self_parameter: false, + }); + + // Copy impl_defaultness of the containing function. + impl_assoc_ty.impl_defaultness(tcx.impl_defaultness(impl_fn_def_id)); + + // Copy generics_of the trait's associated item. + // FIXME: This is not correct, in particular the parent is going to be wrong. So we would need + // to copy from trait_assoc_def_id and adjust things. + impl_assoc_ty.generics_of(tcx.generics_of(trait_assoc_def_id).clone()); + + local_def_id } diff --git a/tests/ui/impl-trait/in-trait/new-lowering-strategy/simple-trait.rs b/tests/ui/impl-trait/in-trait/new-lowering-strategy/simple-trait.rs new file mode 100644 index 00000000000..dfce973d770 --- /dev/null +++ b/tests/ui/impl-trait/in-trait/new-lowering-strategy/simple-trait.rs @@ -0,0 +1,11 @@ +// check-pass +// compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty + +#![feature(return_position_impl_trait_in_trait)] +#![allow(incomplete_features)] + +trait Foo { + fn foo() -> impl Sized; +} + +fn main() {} |
