Add query to avoid name comparison in leaf_def
This commit is contained in:
parent
1b057a33bd
commit
3b7d496f72
8 changed files with 114 additions and 89 deletions
|
@ -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)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue