-> Vec<traits::PredicateObligation<'tcx>>
{
let mut wf = WfPredicates { infcx, param_env, body_id, span, out: vec![] };
- wf.compute_trait_ref(trait_ref);
+ wf.compute_trait_ref(trait_ref, Elaborate::All);
wf.normalize()
}
// (*) ok to skip binders, because wf code is prepared for it
match *predicate {
ty::Predicate::Trait(ref t) => {
- wf.compute_trait_ref(&t.skip_binder().trait_ref); // (*)
+ wf.compute_trait_ref(&t.skip_binder().trait_ref, Elaborate::None); // (*)
}
ty::Predicate::Equate(ref t) => {
wf.compute(t.skip_binder().0);
out: Vec<traits::PredicateObligation<'tcx>>,
}
+#[derive(Debug, PartialEq, Eq, Copy, Clone)]
+enum Elaborate {
+ All,
+ None,
+}
+
impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
fn cause(&mut self, code: traits::ObligationCauseCode<'tcx>) -> traits::ObligationCause<'tcx> {
traits::ObligationCause::new(self.span, self.body_id, code)
/// Pushes the obligations required for `trait_ref` to be WF into
/// `self.out`.
- fn compute_trait_ref(&mut self, trait_ref: &ty::TraitRef<'tcx>) {
+ fn compute_trait_ref(&mut self, trait_ref: &ty::TraitRef<'tcx>, elaborate: Elaborate) {
let obligations = self.nominal_obligations(trait_ref.def_id, trait_ref.substs);
let cause = self.cause(traits::MiscObligation);
let param_env = self.param_env;
- let predicates = obligations.iter()
- .map(|obligation| obligation.predicate.clone())
- .collect();
- let implied_obligations = traits::elaborate_predicates(self.infcx.tcx, predicates);
- let implied_obligations = implied_obligations.map(|pred| {
- traits::Obligation::new(cause.clone(), param_env, pred)
- });
+ if let Elaborate::All = elaborate {
+ let predicates = obligations.iter()
+ .map(|obligation| obligation.predicate.clone())
+ .collect();
+ let implied_obligations = traits::elaborate_predicates(self.infcx.tcx, predicates);
+ let implied_obligations = implied_obligations.map(|pred| {
+ traits::Obligation::new(cause.clone(), param_env, pred)
+ });
+ self.out.extend(implied_obligations);
+ }
- self.out.extend(implied_obligations.chain(obligations));
+ self.out.extend(obligations);
self.out.extend(
trait_ref.substs.types()
// WF and (b) the trait-ref holds. (It may also be
// normalizable and be WF that way.)
let trait_ref = data.trait_ref(self.infcx.tcx);
- self.compute_trait_ref(&trait_ref);
+ self.compute_trait_ref(&trait_ref, Elaborate::All);
if !data.has_escaping_regions() {
let predicate = trait_ref.to_predicate();