Skip to content

compute all rpitit of a trait #143783

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,9 @@ pub(crate) fn check_trait_item<'tcx>(
let mut res = Ok(());

if matches!(tcx.def_kind(def_id), DefKind::AssocFn) {
for &assoc_ty_def_id in tcx.associated_types_for_impl_traits_in_associated_fn(def_id) {
for &assoc_ty_def_id in
tcx.associated_types_for_impl_traits_in_associated_fn(def_id.to_def_id())
{
res = res.and(check_associated_item(tcx, assoc_ty_def_id.expect_local()));
}
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2602,7 +2602,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
// do a linear search to map this to the synthetic associated type that
// it will be lowered to.
let def_id = if let Some(parent_def_id) = in_trait {
*tcx.associated_types_for_impl_traits_in_associated_fn(parent_def_id)
*tcx.associated_types_for_impl_traits_in_associated_fn(parent_def_id.to_def_id())
.iter()
.find(|rpitit| match tcx.opt_rpitit_info(**rpitit) {
Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) => {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ provide! { tcx, def_id, other, cdata,
.process_decoded(tcx, || panic!("{def_id:?} does not have trait_impl_trait_tys")))
}

associated_types_for_impl_traits_in_associated_fn => { table_defaulted_array }
associated_types_for_impl_traits_in_trait_or_impl => { table }

visibility => { cdata.get_visibility(def_id.index) }
adt_def => { cdata.get_adt_def(def_id.index, tcx) }
Expand Down
17 changes: 3 additions & 14 deletions compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1382,17 +1382,6 @@ fn should_encode_const(def_kind: DefKind) -> bool {
}
}

fn should_encode_fn_impl_trait_in_trait<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
if let Some(assoc_item) = tcx.opt_associated_item(def_id)
&& assoc_item.container == ty::AssocItemContainer::Trait
&& assoc_item.is_fn()
{
true
} else {
false
}
}

impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
fn encode_attrs(&mut self, def_id: LocalDefId) {
let tcx = self.tcx;
Expand Down Expand Up @@ -1617,9 +1606,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
{
record!(self.tables.trait_impl_trait_tys[def_id] <- table);
}
if should_encode_fn_impl_trait_in_trait(tcx, def_id) {
let table = tcx.associated_types_for_impl_traits_in_associated_fn(def_id);
record_defaulted_array!(self.tables.associated_types_for_impl_traits_in_associated_fn[def_id] <- table);
if let DefKind::Impl { .. } | DefKind::Trait = def_kind {
let table = tcx.associated_types_for_impl_traits_in_trait_or_impl(def_id);
record!(self.tables.associated_types_for_impl_traits_in_trait_or_impl[def_id] <- table);
}
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_metadata/src/rmeta/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,6 @@ define_tables! {
explicit_implied_predicates_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
explicit_implied_const_bounds: Table<DefIndex, LazyArray<(ty::PolyTraitRef<'static>, Span)>>,
inherent_impls: Table<DefIndex, LazyArray<DefIndex>>,
associated_types_for_impl_traits_in_associated_fn: Table<DefIndex, LazyArray<DefId>>,
opt_rpitit_info: Table<DefIndex, Option<LazyValue<ty::ImplTraitInTraitData>>>,
// Reexported names are not associated with individual `DefId`s,
// e.g. a glob import can introduce a lot of names, all with the same `DefId`.
Expand Down Expand Up @@ -482,6 +481,7 @@ define_tables! {
assumed_wf_types_for_rpitit: Table<DefIndex, LazyArray<(Ty<'static>, Span)>>,
opaque_ty_origin: Table<DefIndex, LazyValue<hir::OpaqueTyOrigin<DefId>>>,
anon_const_kind: Table<DefIndex, LazyValue<ty::AnonConstKind>>,
associated_types_for_impl_traits_in_trait_or_impl: Table<DefIndex, LazyValue<DefIdMap<Vec<DefId>>>>,
}

#[derive(TyEncodable, TyDecodable)]
Expand Down
14 changes: 5 additions & 9 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1079,15 +1079,11 @@ rustc_queries! {
desc { |tcx| "comparing impl items against trait for `{}`", tcx.def_path_str(impl_id) }
}

/// Given `fn_def_id` of a trait or of an impl that implements a given trait:
/// if `fn_def_id` is the def id of a function defined inside a trait, then it creates and returns
/// the associated items that correspond to each impl trait in return position for that trait.
/// if `fn_def_id` is the def id of a function defined inside an impl that implements a trait, then it
/// creates and returns the associated items that correspond to each impl trait in return position
/// of the implemented trait.
query associated_types_for_impl_traits_in_associated_fn(fn_def_id: DefId) -> &'tcx [DefId] {
desc { |tcx| "creating associated items for opaque types returned by `{}`", tcx.def_path_str(fn_def_id) }
cache_on_disk_if { fn_def_id.is_local() }
/// Given the `item_def_id` of a trait or impl, return a mapping from associated fn def id
/// to its associated type items that correspond to the RPITITs in its signature.
query associated_types_for_impl_traits_in_trait_or_impl(item_def_id: DefId) -> &'tcx DefIdMap<Vec<DefId>> {
arena_cache
desc { |tcx| "synthesizing RPITIT items for the opaque types for methods in `{}`", tcx.def_path_str(item_def_id) }
separate_provide_extern
}

Expand Down
19 changes: 19 additions & 0 deletions compiler/rustc_middle/src/ty/assoc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -285,3 +285,22 @@ impl AssocItems {
.find(|item| tcx.hygienic_eq(ident, item.ident(tcx), parent_def_id))
}
}

impl<'tcx> TyCtxt<'tcx> {
/// Given an `fn_def_id` of a trait or a trait implementation:
///
/// if `fn_def_id` is a function defined inside a trait, then it synthesizes
/// a new def id corresponding to a new associated type for each return-
/// position `impl Trait` in the signature.
///
/// if `fn_def_id` is a function inside of an impl, then for each synthetic
/// associated type generated for the corresponding trait function described
/// above, synthesize a corresponding associated type in the impl.
pub fn associated_types_for_impl_traits_in_associated_fn(
self,
fn_def_id: DefId,
) -> &'tcx [DefId] {
let parent_def_id = self.parent(fn_def_id);
&self.associated_types_for_impl_traits_in_trait_or_impl(parent_def_id)[&fn_def_id]
}
}
4 changes: 4 additions & 0 deletions compiler/rustc_middle/src/ty/parameterized.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ impl<A: ParameterizedOverTcx, B: ParameterizedOverTcx> ParameterizedOverTcx for
type Value<'tcx> = (A::Value<'tcx>, B::Value<'tcx>);
}

impl<T: ParameterizedOverTcx> ParameterizedOverTcx for Vec<T> {
type Value<'tcx> = Vec<T::Value<'tcx>>;
}

impl<I: Idx + 'static, T: ParameterizedOverTcx> ParameterizedOverTcx for IndexVec<I, T> {
type Value<'tcx> = IndexVec<I, T::Value<'tcx>>;
}
Expand Down
Loading
Loading