Do not elaborate trait obligations in where clauses
This commit is contained in:
parent
e3b28b4ae8
commit
94703ce3f7
1 changed files with 21 additions and 12 deletions
|
@ -58,7 +58,7 @@ pub fn trait_obligations<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
|
|||
-> 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()
|
||||
}
|
||||
|
||||
|
@ -74,7 +74,7 @@ pub fn predicate_obligations<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
|
|||
// (*) 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);
|
||||
|
@ -114,6 +114,12 @@ struct WfPredicates<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
|||
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)
|
||||
|
@ -135,21 +141,24 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
|
|||
|
||||
/// 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()
|
||||
|
@ -166,7 +175,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
|
|||
// 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();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue