Skip to content

Commit edeb9c4

Browse files
committed
ty::wf: Add Self: Trait predicate back in
1 parent f52d4de commit edeb9c4

File tree

1 file changed

+35
-3
lines changed

1 file changed

+35
-3
lines changed

src/librustc/ty/wf.rs

+35-3
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use middle::const_val::ConstVal;
1313
use infer::InferCtxt;
1414
use ty::subst::Substs;
1515
use traits;
16-
use ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable};
16+
use ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable};
1717
use std::iter::once;
1818
use syntax::ast;
1919
use syntax_pos::Span;
@@ -170,10 +170,11 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
170170
/// Pushes the obligations required for `trait_ref` to be WF into
171171
/// `self.out`.
172172
fn compute_trait_ref(&mut self, trait_ref: &ty::TraitRef<'tcx>, elaborate: Elaborate) {
173-
let obligations = self.nominal_obligations(trait_ref.def_id, trait_ref.substs);
173+
let param_env = self.param_env;
174+
175+
let obligations = self.nominal_trait_obligations(trait_ref);
174176

175177
let cause = self.cause(traits::MiscObligation);
176-
let param_env = self.param_env;
177178

178179
if let Elaborate::All = elaborate {
179180
let predicates = obligations.iter()
@@ -449,6 +450,37 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
449450
.collect()
450451
}
451452

453+
fn nominal_trait_obligations(&mut self,
454+
trait_ref: &ty::TraitRef<'tcx>)
455+
-> Vec<traits::PredicateObligation<'tcx>>
456+
{
457+
let mut predicates = self.infcx.tcx.predicates_of(trait_ref.def_id);
458+
459+
// Add in a predicate that `Self:Trait` (where `Trait` is the
460+
// current trait).
461+
// trait_ref can probably be added in as a predicate directly after
462+
// instantiation, rather than erasing the substituted type and then
463+
// re-instantiating this bound.
464+
let identity_trait_ref = ty::TraitRef {
465+
def_id: trait_ref.def_id,
466+
substs: Substs::identity_for_item(self.infcx.tcx, trait_ref.def_id)
467+
};
468+
predicates.predicates.push(identity_trait_ref.to_poly_trait_ref().to_predicate());
469+
470+
debug!("nominal_trait_obligations: trait_ref={:?} predicates={:?}",
471+
trait_ref, predicates.predicates);
472+
473+
let cause = self.cause(traits::ItemObligation(trait_ref.def_id));
474+
predicates.instantiate(self.infcx.tcx, trait_ref.substs)
475+
.predicates
476+
.into_iter()
477+
.map(|pred| traits::Obligation::new(cause.clone(),
478+
self.param_env,
479+
pred))
480+
.filter(|pred| !pred.has_escaping_regions())
481+
.collect()
482+
}
483+
452484
fn from_object_ty(&mut self, ty: Ty<'tcx>,
453485
data: ty::Binder<&'tcx ty::Slice<ty::ExistentialPredicate<'tcx>>>,
454486
region: ty::Region<'tcx>) {

0 commit comments

Comments
 (0)