1
Fork 0

Tweak assoc type obligation spans

* Point at RHS of associated type in obligation span
* Point at `impl` assoc type on projection error
* Reduce verbosity of recursive obligations
* Point at source of binding lifetime obligation
* Tweak "required bound" note
* Tweak "expected... found opaque (return) type" labels
* Point at set type in impl assoc type WF errors
This commit is contained in:
Esteban Kuber 2021-12-11 02:20:41 +00:00
parent f0448f44bc
commit 5e1972eba7
92 changed files with 503 additions and 257 deletions

View file

@ -1338,7 +1338,46 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
"type mismatch resolving `{}`",
predicate
);
self.note_type_err(&mut diag, &obligation.cause, None, values, err);
let secondary_span = match predicate.kind().skip_binder() {
ty::PredicateKind::Projection(proj) => self
.tcx
.opt_associated_item(proj.projection_ty.item_def_id)
.and_then(|trait_assoc_item| {
self.tcx
.trait_of_item(proj.projection_ty.item_def_id)
.map(|id| (trait_assoc_item, id))
})
.and_then(|(trait_assoc_item, id)| {
self.tcx.find_map_relevant_impl(
id,
proj.projection_ty.self_ty(),
|did| {
self.tcx
.associated_items(did)
.in_definition_order()
.filter(|assoc| assoc.ident == trait_assoc_item.ident)
.next()
},
)
})
.and_then(|item| match self.tcx.hir().get_if_local(item.def_id) {
Some(
hir::Node::TraitItem(hir::TraitItem {
kind: hir::TraitItemKind::Type(_, Some(ty)),
..
})
| hir::Node::ImplItem(hir::ImplItem {
kind: hir::ImplItemKind::TyAlias(ty),
..
}),
) => {
Some((ty.span, format!("type mismatch resolving `{}`", predicate)))
}
_ => None,
}),
_ => None,
};
self.note_type_err(&mut diag, &obligation.cause, secondary_span, values, err, true);
self.note_obligation_cause(&mut diag, obligation);
diag.emit();
}
@ -2095,10 +2134,21 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
) -> bool {
if let ObligationCauseCode::BuiltinDerivedObligation(ref data) = cause_code {
let parent_trait_ref = self.resolve_vars_if_possible(data.parent_trait_ref);
if obligated_types.iter().any(|ot| ot == &parent_trait_ref.skip_binder().self_ty()) {
let self_ty = parent_trait_ref.skip_binder().self_ty();
if obligated_types.iter().any(|ot| ot == &self_ty) {
return true;
}
if let ty::Adt(def, substs) = self_ty.kind() {
if let [arg] = &substs[..] {
if let ty::subst::GenericArgKind::Type(ty) = arg.unpack() {
if let ty::Adt(inner_def, _) = ty.kind() {
if inner_def == def {
return true;
}
}
}
}
}
}
false
}

View file

@ -2186,6 +2186,16 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
seen_requirements,
)
});
} else {
ensure_sufficient_stack(|| {
self.note_obligation_cause_code(
err,
&parent_predicate,
&cause_code.peel_derives(),
obligated_types,
seen_requirements,
)
});
}
}
ObligationCauseCode::ImplDerivedObligation(ref data) => {