On obligation errors point at the unfulfilled binding when possible
This commit is contained in:
parent
4ff32c07da
commit
b370c111fd
141 changed files with 588 additions and 512 deletions
|
|
@ -2750,3 +2750,16 @@ pub enum Node<'hir> {
|
|||
|
||||
Crate,
|
||||
}
|
||||
|
||||
impl<'hir> Node<'hir> {
|
||||
pub fn ident(&self) -> Option<Ident> {
|
||||
|
||||
match self {
|
||||
Node::TraitItem(TraitItem { ident, .. }) |
|
||||
Node::ImplItem(ImplItem { ident, .. }) |
|
||||
Node::ForeignItem(ForeignItem { ident, .. }) |
|
||||
Node::Item(Item { ident, .. }) => Some(*ident),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,10 +40,12 @@ use syntax::symbol::{sym, kw};
|
|||
use syntax_pos::{DUMMY_SP, Span, ExpnKind};
|
||||
|
||||
impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
pub fn report_fulfillment_errors(&self,
|
||||
errors: &[FulfillmentError<'tcx>],
|
||||
body_id: Option<hir::BodyId>,
|
||||
fallback_has_occurred: bool) {
|
||||
pub fn report_fulfillment_errors(
|
||||
&self,
|
||||
errors: &[FulfillmentError<'tcx>],
|
||||
body_id: Option<hir::BodyId>,
|
||||
fallback_has_occurred: bool,
|
||||
) {
|
||||
#[derive(Debug)]
|
||||
struct ErrorDescriptor<'tcx> {
|
||||
predicate: ty::Predicate<'tcx>,
|
||||
|
|
@ -1651,6 +1653,18 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
err.note(&msg);
|
||||
}
|
||||
}
|
||||
ObligationCauseCode::BindingObligation(item_def_id, span) => {
|
||||
let item_name = tcx.def_path_str(item_def_id);
|
||||
let msg = format!("required by this bound in `{}`", item_name);
|
||||
if let Some(ident) = tcx.opt_item_name(item_def_id) {
|
||||
err.span_label(ident.span, "");
|
||||
}
|
||||
if span != DUMMY_SP {
|
||||
err.span_label(span, &msg);
|
||||
} else {
|
||||
err.note(&msg);
|
||||
}
|
||||
}
|
||||
ObligationCauseCode::ObjectCastObligation(object_ty) => {
|
||||
err.note(&format!("required for the cast to the object type `{}`",
|
||||
self.ty_to_string(object_ty)));
|
||||
|
|
|
|||
|
|
@ -176,6 +176,9 @@ pub enum ObligationCauseCode<'tcx> {
|
|||
/// also implement all supertraits of `X`.
|
||||
ItemObligation(DefId),
|
||||
|
||||
/// Like `ItemObligation`, but with extra detail on the source of the obligation.
|
||||
BindingObligation(DefId, Span),
|
||||
|
||||
/// A type like `&'a T` is WF only if `T: 'a`.
|
||||
ReferenceOutlivesReferent(Ty<'tcx>),
|
||||
|
||||
|
|
|
|||
|
|
@ -472,6 +472,7 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> {
|
|||
super::TupleElem => Some(super::TupleElem),
|
||||
super::ProjectionWf(proj) => tcx.lift(&proj).map(super::ProjectionWf),
|
||||
super::ItemObligation(def_id) => Some(super::ItemObligation(def_id)),
|
||||
super::BindingObligation(def_id, span) => Some(super::BindingObligation(def_id, span)),
|
||||
super::ReferenceOutlivesReferent(ty) => {
|
||||
tcx.lift(&ty).map(super::ReferenceOutlivesReferent)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2797,6 +2797,10 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn opt_item_name(self, def_id: DefId) -> Option<Ident> {
|
||||
self.hir().as_local_hir_id(def_id).and_then(|hir_id| self.hir().get(hir_id).ident())
|
||||
}
|
||||
|
||||
pub fn opt_associated_item(self, def_id: DefId) -> Option<AssocItem> {
|
||||
let is_associated_item = if let Some(hir_id) = self.hir().as_local_hir_id(def_id) {
|
||||
match self.hir().get(hir_id) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue