Uplift some feeding out of associated_type_for_impl_trait_in_impl and into queries
This commit is contained in:
parent
7606c13961
commit
ebc45c8505
5 changed files with 85 additions and 60 deletions
|
@ -14,6 +14,43 @@ use rustc_span::Span;
|
|||
pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
|
||||
use rustc_hir::*;
|
||||
|
||||
// For an RPITIT, synthesize generics which are equal to the opaque's generics
|
||||
// and parent fn's generics compressed into one list.
|
||||
if let Some(ty::ImplTraitInTraitData::Trait { fn_def_id, opaque_def_id }) =
|
||||
tcx.opt_rpitit_info(def_id.to_def_id())
|
||||
{
|
||||
let trait_def_id = tcx.parent(fn_def_id);
|
||||
let opaque_ty_generics = tcx.generics_of(opaque_def_id);
|
||||
let opaque_ty_parent_count = opaque_ty_generics.parent_count;
|
||||
let mut params = opaque_ty_generics.params.clone();
|
||||
|
||||
let parent_generics = tcx.generics_of(trait_def_id);
|
||||
let parent_count = parent_generics.parent_count + parent_generics.params.len();
|
||||
|
||||
let mut trait_fn_params = tcx.generics_of(fn_def_id).params.clone();
|
||||
|
||||
for param in &mut params {
|
||||
param.index = param.index + parent_count as u32 + trait_fn_params.len() as u32
|
||||
- opaque_ty_parent_count as u32;
|
||||
}
|
||||
|
||||
trait_fn_params.extend(params);
|
||||
params = trait_fn_params;
|
||||
|
||||
let param_def_id_to_index =
|
||||
params.iter().map(|param| (param.def_id, param.index)).collect();
|
||||
|
||||
return ty::Generics {
|
||||
parent: Some(trait_def_id),
|
||||
parent_count,
|
||||
params,
|
||||
param_def_id_to_index,
|
||||
has_self: opaque_ty_generics.has_self,
|
||||
has_late_bound_regions: opaque_ty_generics.has_late_bound_regions,
|
||||
host_effect_index: parent_generics.host_effect_index,
|
||||
};
|
||||
}
|
||||
|
||||
let hir_id = tcx.local_def_id_to_hir_id(def_id);
|
||||
|
||||
let node = tcx.hir_node(hir_id);
|
||||
|
|
|
@ -5,7 +5,7 @@ use rustc_hir::HirId;
|
|||
use rustc_middle::query::plumbing::CyclePlaceholder;
|
||||
use rustc_middle::ty::print::with_forced_trimmed_paths;
|
||||
use rustc_middle::ty::util::IntTypeExt;
|
||||
use rustc_middle::ty::{self, ImplTraitInTraitData, IsSuggestable, Ty, TyCtxt, TypeVisitableExt};
|
||||
use rustc_middle::ty::{self, IsSuggestable, Ty, TyCtxt, TypeVisitableExt};
|
||||
use rustc_span::symbol::Ident;
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
|
||||
|
@ -350,22 +350,31 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
|
|||
// If we are computing `type_of` the synthesized associated type for an RPITIT in the impl
|
||||
// side, use `collect_return_position_impl_trait_in_trait_tys` to infer the value of the
|
||||
// associated type in the impl.
|
||||
if let Some(ImplTraitInTraitData::Impl { fn_def_id, .. }) =
|
||||
tcx.opt_rpitit_info(def_id.to_def_id())
|
||||
{
|
||||
match tcx.collect_return_position_impl_trait_in_trait_tys(fn_def_id) {
|
||||
Ok(map) => {
|
||||
let assoc_item = tcx.associated_item(def_id);
|
||||
return map[&assoc_item.trait_item_def_id.unwrap()];
|
||||
}
|
||||
Err(_) => {
|
||||
return ty::EarlyBinder::bind(Ty::new_error_with_message(
|
||||
tcx,
|
||||
DUMMY_SP,
|
||||
"Could not collect return position impl trait in trait tys",
|
||||
));
|
||||
match tcx.opt_rpitit_info(def_id.to_def_id()) {
|
||||
Some(ty::ImplTraitInTraitData::Impl { fn_def_id }) => {
|
||||
match tcx.collect_return_position_impl_trait_in_trait_tys(fn_def_id) {
|
||||
Ok(map) => {
|
||||
let assoc_item = tcx.associated_item(def_id);
|
||||
return map[&assoc_item.trait_item_def_id.unwrap()];
|
||||
}
|
||||
Err(_) => {
|
||||
return ty::EarlyBinder::bind(Ty::new_error_with_message(
|
||||
tcx,
|
||||
DUMMY_SP,
|
||||
"Could not collect return position impl trait in trait tys",
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
// For an RPITIT in a trait, just return the corresponding opaque.
|
||||
Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) => {
|
||||
return ty::EarlyBinder::bind(Ty::new_opaque(
|
||||
tcx,
|
||||
opaque_def_id,
|
||||
ty::GenericArgs::identity_for_item(tcx, opaque_def_id),
|
||||
));
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
|
||||
let hir_id = tcx.local_def_id_to_hir_id(def_id);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue