Skip to content

Commit

Permalink
Auto merge of #69793 - estebank:predicate-obligations-4, r=nikomatsakis
Browse files Browse the repository at this point in the history
 Maintain chain of derived obligations

When evaluating the derived obligations from super traits, maintain a
reference to the original obligation in order to give more actionable
context in the output.

Continuation (and built on) #69745, subset of #69709.

r? @eddyb
  • Loading branch information
bors committed Apr 19, 2020
2 parents a0e52b1 + d9a5419 commit e7497a8
Show file tree
Hide file tree
Showing 55 changed files with 287 additions and 313 deletions.
16 changes: 6 additions & 10 deletions src/librustc_middle/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,8 @@ pub enum ObligationCauseCode<'tcx> {

ImplDerivedObligation(DerivedObligationCause<'tcx>),

DerivedObligation(DerivedObligationCause<'tcx>),

/// Error derived when matching traits/impls; see ObligationCause for more details
CompareImplMethodObligation {
item_name: ast::Name,
Expand Down Expand Up @@ -257,28 +259,22 @@ pub enum ObligationCauseCode<'tcx> {

/// #[feature(trivial_bounds)] is not enabled
TrivialBound,

AssocTypeBound(Box<AssocTypeBoundData>),
}

impl ObligationCauseCode<'_> {
// Return the base obligation, ignoring derived obligations.
pub fn peel_derives(&self) -> &Self {
let mut base_cause = self;
while let BuiltinDerivedObligation(cause) | ImplDerivedObligation(cause) = base_cause {
while let BuiltinDerivedObligation(cause)
| ImplDerivedObligation(cause)
| DerivedObligation(cause) = base_cause
{
base_cause = &cause.parent_code;
}
base_cause
}
}

#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct AssocTypeBoundData {
pub impl_span: Option<Span>,
pub original: Span,
pub bounds: Vec<Span>,
}

// `ObligationCauseCode` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(target_arch = "x86_64")]
static_assert_size!(ObligationCauseCode<'_>, 32);
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_middle/traits/structural_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,7 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> {
super::ImplDerivedObligation(ref cause) => {
tcx.lift(cause).map(super::ImplDerivedObligation)
}
super::DerivedObligation(ref cause) => tcx.lift(cause).map(super::DerivedObligation),
super::CompareImplMethodObligation {
item_name,
impl_item_def_id,
Expand Down Expand Up @@ -501,7 +502,6 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> {
super::MethodReceiver => Some(super::MethodReceiver),
super::BlockTailExpression(id) => Some(super::BlockTailExpression(id)),
super::TrivialBound => Some(super::TrivialBound),
super::AssocTypeBound(ref data) => Some(super::AssocTypeBound(data.clone())),
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {

match obligation.cause.code {
ObligationCauseCode::BuiltinDerivedObligation(..)
| ObligationCauseCode::ImplDerivedObligation(..) => {}
| ObligationCauseCode::ImplDerivedObligation(..)
| ObligationCauseCode::DerivedObligation(..) => {}
_ => {
// this is a "direct", user-specified, rather than derived,
// obligation.
Expand Down
26 changes: 14 additions & 12 deletions src/librustc_trait_selection/traits/error_reporting/suggestions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1135,7 +1135,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
while let Some(code) = next_code {
debug!("maybe_note_obligation_cause_for_async_await: code={:?}", code);
match code {
ObligationCauseCode::BuiltinDerivedObligation(derived_obligation)
ObligationCauseCode::DerivedObligation(derived_obligation)
| ObligationCauseCode::BuiltinDerivedObligation(derived_obligation)
| ObligationCauseCode::ImplDerivedObligation(derived_obligation) => {
let ty = derived_obligation.parent_trait_ref.self_ty();
debug!(
Expand Down Expand Up @@ -1531,14 +1532,14 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
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) {
let sm = self.tcx.sess.source_map();
let sm = tcx.sess.source_map();
let same_line =
match (sm.lookup_line(ident.span.hi()), sm.lookup_line(span.lo())) {
(Ok(l), Ok(r)) => l.line == r.line,
_ => true,
};
if !ident.span.overlaps(span) && !same_line {
err.span_label(ident.span, "");
err.span_label(ident.span, "required by a bound in this");
}
}
if span != DUMMY_SP {
Expand Down Expand Up @@ -1661,6 +1662,16 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
obligated_types,
);
}
ObligationCauseCode::DerivedObligation(ref data) => {
let parent_trait_ref = self.resolve_vars_if_possible(&data.parent_trait_ref);
let parent_predicate = parent_trait_ref.without_const().to_predicate();
self.note_obligation_cause_code(
err,
&parent_predicate,
&data.parent_code,
obligated_types,
);
}
ObligationCauseCode::CompareImplMethodObligation { .. } => {
err.note(&format!(
"the requirement `{}` appears on the impl method \
Expand All @@ -1684,15 +1695,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
err.help("add `#![feature(trivial_bounds)]` to the crate attributes to enable");
}
}
ObligationCauseCode::AssocTypeBound(ref data) => {
err.span_label(data.original, "associated type defined here");
if let Some(sp) = data.impl_span {
err.span_label(sp, "in this `impl` item");
}
for sp in &data.bounds {
err.span_label(*sp, "restricted in this bound");
}
}
}
}

Expand Down
Loading

0 comments on commit e7497a8

Please sign in to comment.