use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_errors::ErrorGuaranteed;
use rustc_hir::def::DefKind;
-use rustc_hir::def_id::DefId;
use rustc_hir::lang_items::LangItem;
use rustc_infer::infer::at::At;
use rustc_infer::infer::resolve::OpportunisticRegionResolver;
};
debug!(?normalized, ?obligations, "project_and_unify_type result");
let actual = obligation.predicate.term;
- // For an example where this is necessary see src/test/ui/impl-trait/nested-return-type2.rs
+ // For an example where this is necessary see tests/ui/impl-trait/nested-return-type2.rs
// This allows users to omit re-mentioning all bounds on an associated type and just use an
// `impl Trait` for the assoc type to add more bounds.
let InferOk { value: actual, obligations: new } =
// NOTE: This should be kept in sync with the similar code in
// `rustc_ty_utils::instance::resolve_associated_item()`.
let node_item =
- assoc_def(selcx, impl_data.impl_def_id, obligation.predicate.def_id)
+ specialization_graph::assoc_def(selcx.tcx(), impl_data.impl_def_id, obligation.predicate.def_id)
.map_err(|ErrorGuaranteed { .. }| ())?;
if node_item.is_final() {
let trait_def_id = tcx.trait_id_of_impl(impl_def_id).unwrap();
let param_env = obligation.param_env;
- let Ok(assoc_ty) = assoc_def(selcx, impl_def_id, assoc_item_id) else {
+ let Ok(assoc_ty) = specialization_graph::assoc_def(tcx, impl_def_id, assoc_item_id) else {
return Progress { term: tcx.ty_error().into(), obligations: nested };
};
let mut obligations = data.nested;
let trait_fn_def_id = tcx.impl_trait_in_trait_parent(obligation.predicate.def_id);
- let Ok(leaf_def) = assoc_def(selcx, data.impl_def_id, trait_fn_def_id) else {
+ let Ok(leaf_def) = specialization_graph::assoc_def(tcx, data.impl_def_id, trait_fn_def_id) else {
return Progress { term: tcx.ty_error().into(), obligations };
};
if !leaf_def.item.defaultness(tcx).has_value() {
obligation.param_env,
cause.clone(),
obligation.recursion_depth + 1,
- tcx.bound_trait_impl_trait_tys(impl_fn_def_id)
+ tcx.bound_return_position_impl_trait_in_trait_tys(impl_fn_def_id)
.map_bound(|tys| {
tys.map_or_else(|_| tcx.ty_error(), |tys| tys[&obligation.predicate.def_id])
})
}
}
-/// Locate the definition of an associated type in the specialization hierarchy,
-/// starting from the given impl.
-///
-/// Based on the "projection mode", this lookup may in fact only examine the
-/// topmost impl. See the comments for `Reveal` for more details.
-fn assoc_def(
- selcx: &SelectionContext<'_, '_>,
- impl_def_id: DefId,
- assoc_def_id: DefId,
-) -> Result<specialization_graph::LeafDef, ErrorGuaranteed> {
- let tcx = selcx.tcx();
- let trait_def_id = tcx.impl_trait_ref(impl_def_id).unwrap().def_id;
- let trait_def = tcx.trait_def(trait_def_id);
-
- // This function may be called while we are still building the
- // specialization graph that is queried below (via TraitDef::ancestors()),
- // so, in order to avoid unnecessary infinite recursion, we manually look
- // for the associated item at the given impl.
- // If there is no such item in that impl, this function will fail with a
- // cycle error if the specialization graph is currently being built.
- if let Some(&impl_item_id) = tcx.impl_item_implementor_ids(impl_def_id).get(&assoc_def_id) {
- let item = tcx.associated_item(impl_item_id);
- let impl_node = specialization_graph::Node::Impl(impl_def_id);
- return Ok(specialization_graph::LeafDef {
- item: *item,
- defining_node: impl_node,
- finalizing_node: if item.defaultness(tcx).is_default() {
- None
- } else {
- Some(impl_node)
- },
- });
- }
-
- let ancestors = trait_def.ancestors(tcx, impl_def_id)?;
- if let Some(assoc_item) = ancestors.leaf_def(tcx, assoc_def_id) {
- Ok(assoc_item)
- } else {
- // This is saying that neither the trait nor
- // the impl contain a definition for this
- // associated type. Normally this situation
- // could only arise through a compiler bug --
- // if the user wrote a bad item name, it
- // should have failed in astconv.
- bug!(
- "No associated type `{}` for {}",
- tcx.item_name(assoc_def_id),
- tcx.def_path_str(impl_def_id)
- )
- }
-}
-
pub(crate) trait ProjectionCacheKeyExt<'cx, 'tcx>: Sized {
fn from_poly_projection_predicate(
selcx: &mut SelectionContext<'cx, 'tcx>,