introduce new origin for Trait+'b

This helps us to preserve the existing errors.
This commit is contained in:
Niko Matsakis 2016-10-14 10:09:59 -04:00
parent a20b062663
commit 61c777baec
4 changed files with 20 additions and 1 deletions

View file

@ -868,6 +868,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
err.note(&format!("required so that reference `{}` does not outlive its referent",
ref_ty));
}
ObligationCauseCode::ObjectTypeBound(object_ty, region) => {
err.note(&format!("required so that the lifetime bound of `{}` for `{}` \
is satisfied",
region, object_ty));
}
ObligationCauseCode::ItemObligation(item_def_id) => {
let item_name = tcx.item_path_str(item_def_id);
err.note(&format!("required by `{}`", item_name));

View file

@ -111,6 +111,9 @@ pub enum ObligationCauseCode<'tcx> {
/// A type like `&'a T` is WF only if `T: 'a`.
ReferenceOutlivesReferent(Ty<'tcx>),
/// A type like `Box<Foo<'a> + 'b>` is WF only if `'b: 'a`.
ObjectTypeBound(Ty<'tcx>, &'tcx ty::Region),
/// Obligation incurred due to an object cast.
ObjectCastObligation(/* Object type */ Ty<'tcx>),

View file

@ -175,6 +175,13 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> {
super::ReferenceOutlivesReferent(ty) => {
tcx.lift(&ty).map(super::ReferenceOutlivesReferent)
}
super::ObjectTypeBound(ty, r) => {
tcx.lift(&ty).and_then(|ty| {
tcx.lift(&r).and_then(|r| {
Some(super::ObjectTypeBound(ty, r))
})
})
}
super::ObjectCastObligation(ty) => {
tcx.lift(&ty).map(super::ObjectCastObligation)
}
@ -473,6 +480,9 @@ impl<'tcx> TypeFoldable<'tcx> for traits::ObligationCauseCode<'tcx> {
super::ReferenceOutlivesReferent(ty) => {
super::ReferenceOutlivesReferent(ty.fold_with(folder))
}
super::ObjectTypeBound(ty, r) => {
super::ObjectTypeBound(ty.fold_with(folder), r.fold_with(folder))
}
super::ObjectCastObligation(ty) => {
super::ObjectCastObligation(ty.fold_with(folder))
}
@ -504,6 +514,7 @@ impl<'tcx> TypeFoldable<'tcx> for traits::ObligationCauseCode<'tcx> {
super::ProjectionWf(proj) => proj.visit_with(visitor),
super::ReferenceOutlivesReferent(ty) => ty.visit_with(visitor),
super::ObjectTypeBound(ty, r) => ty.visit_with(visitor) || r.visit_with(visitor),
super::ObjectCastObligation(ty) => ty.visit_with(visitor),
super::BuiltinDerivedObligation(ref cause) => cause.visit_with(visitor),
super::ImplDerivedObligation(ref cause) => cause.visit_with(visitor)

View file

@ -498,7 +498,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
let explicit_bound = data.region_bound;
for implicit_bound in implicit_bounds {
let cause = self.cause(traits::ReferenceOutlivesReferent(ty));
let cause = self.cause(traits::ObjectTypeBound(ty, explicit_bound));
let outlives = ty::Binder(ty::OutlivesPredicate(explicit_bound, implicit_bound));
self.out.push(traits::Obligation::new(cause, outlives.to_predicate()));
}