1
Fork 0

Add query to avoid name comparison in leaf_def

This commit is contained in:
Matthew Jasper 2021-11-18 22:29:07 +00:00 committed by Noah Lev
parent 1b057a33bd
commit 3b7d496f72
8 changed files with 114 additions and 89 deletions

View file

@ -1883,7 +1883,6 @@ fn assoc_ty_def(
assoc_ty_def_id: DefId,
) -> Result<specialization_graph::LeafDef, ErrorReported> {
let tcx = selcx.tcx();
let assoc_ty_name = tcx.associated_item(assoc_ty_def_id).ident;
let trait_def_id = tcx.impl_trait_ref(impl_def_id).unwrap().def_id;
let trait_def = tcx.trait_def(trait_def_id);
@ -1893,21 +1892,18 @@ fn assoc_ty_def(
// 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.
let impl_node = specialization_graph::Node::Impl(impl_def_id);
for item in impl_node.items(tcx) {
if matches!(item.kind, ty::AssocKind::Type)
&& tcx.hygienic_eq(item.ident, assoc_ty_name, trait_def_id)
{
return Ok(specialization_graph::LeafDef {
item: *item,
defining_node: impl_node,
finalizing_node: if item.defaultness.is_default() { None } else { Some(impl_node) },
});
}
if let Some(&impl_item_id) = tcx.impl_item_implementor_ids(impl_def_id).get(&assoc_ty_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.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_ty_name, ty::AssocKind::Type) {
if let Some(assoc_item) = ancestors.leaf_def(tcx, assoc_ty_def_id) {
Ok(assoc_item)
} else {
// This is saying that neither the trait nor
@ -1916,7 +1912,11 @@ fn assoc_ty_def(
// 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 {}", assoc_ty_name, tcx.def_path_str(impl_def_id))
bug!(
"No associated type `{}` for {}",
tcx.item_name(assoc_ty_def_id),
tcx.def_path_str(impl_def_id)
)
}
}

View file

@ -197,14 +197,13 @@ fn extend_cause_with_original_assoc_item_obligation<'tcx>(
item: Option<&hir::Item<'tcx>>,
cause: &mut traits::ObligationCause<'tcx>,
pred: &ty::Predicate<'tcx>,
mut trait_assoc_items: impl Iterator<Item = &'tcx ty::AssocItem>,
) {
debug!(
"extended_cause_with_original_assoc_item_obligation {:?} {:?} {:?} {:?}",
trait_ref, item, cause, pred
);
let items = match item {
Some(hir::Item { kind: hir::ItemKind::Impl(impl_), .. }) => impl_.items,
let (items, impl_def_id) = match item {
Some(hir::Item { kind: hir::ItemKind::Impl(impl_), def_id, .. }) => (impl_.items, *def_id),
_ => return,
};
let fix_span =
@ -222,11 +221,16 @@ fn extend_cause_with_original_assoc_item_obligation<'tcx>(
// `src/test/ui/associated-types/point-at-type-on-obligation-failure.rs` and
// `traits-assoc-type-in-supertrait-bad.rs`.
if let ty::Projection(projection_ty) = proj.ty.kind() {
let trait_assoc_item = tcx.associated_item(projection_ty.item_def_id);
if let Some(impl_item_span) =
items.iter().find(|item| item.ident == trait_assoc_item.ident).map(fix_span)
if let Some(&impl_item_id) =
tcx.impl_item_implementor_ids(impl_def_id).get(&projection_ty.item_def_id)
{
cause.span = impl_item_span;
if let Some(impl_item_span) = items
.iter()
.find(|item| item.id.def_id.to_def_id() == impl_item_id)
.map(fix_span)
{
cause.span = impl_item_span;
}
}
}
}
@ -235,13 +239,16 @@ fn extend_cause_with_original_assoc_item_obligation<'tcx>(
// can be seen in `ui/associated-types/point-at-type-on-obligation-failure-2.rs`.
debug!("extended_cause_with_original_assoc_item_obligation trait proj {:?}", pred);
if let ty::Projection(ty::ProjectionTy { item_def_id, .. }) = *pred.self_ty().kind() {
if let Some(impl_item_span) = trait_assoc_items
.find(|i| i.def_id == item_def_id)
.and_then(|trait_assoc_item| {
items.iter().find(|i| i.ident == trait_assoc_item.ident).map(fix_span)
})
if let Some(&impl_item_id) =
tcx.impl_item_implementor_ids(impl_def_id).get(&item_def_id)
{
cause.span = impl_item_span;
if let Some(impl_item_span) = items
.iter()
.find(|item| item.id.def_id.to_def_id() == impl_item_id)
.map(fix_span)
{
cause.span = impl_item_span;
}
}
}
}
@ -312,7 +319,6 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
item,
&mut cause,
&obligation.predicate,
tcx.associated_items(trait_ref.def_id).in_definition_order(),
);
traits::Obligation::with_depth(cause, depth, param_env, obligation.predicate)
};