Skip to content

Commit 94703ce

Browse files
committed
Do not elaborate trait obligations in where clauses
1 parent e3b28b4 commit 94703ce

File tree

1 file changed

+21
-12
lines changed

1 file changed

+21
-12
lines changed

src/librustc/ty/wf.rs

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ pub fn trait_obligations<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
5858
-> Vec<traits::PredicateObligation<'tcx>>
5959
{
6060
let mut wf = WfPredicates { infcx, param_env, body_id, span, out: vec![] };
61-
wf.compute_trait_ref(trait_ref);
61+
wf.compute_trait_ref(trait_ref, Elaborate::All);
6262
wf.normalize()
6363
}
6464

@@ -74,7 +74,7 @@ pub fn predicate_obligations<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
7474
// (*) ok to skip binders, because wf code is prepared for it
7575
match *predicate {
7676
ty::Predicate::Trait(ref t) => {
77-
wf.compute_trait_ref(&t.skip_binder().trait_ref); // (*)
77+
wf.compute_trait_ref(&t.skip_binder().trait_ref, Elaborate::None); // (*)
7878
}
7979
ty::Predicate::Equate(ref t) => {
8080
wf.compute(t.skip_binder().0);
@@ -114,6 +114,12 @@ struct WfPredicates<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
114114
out: Vec<traits::PredicateObligation<'tcx>>,
115115
}
116116

117+
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
118+
enum Elaborate {
119+
All,
120+
None,
121+
}
122+
117123
impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
118124
fn cause(&mut self, code: traits::ObligationCauseCode<'tcx>) -> traits::ObligationCause<'tcx> {
119125
traits::ObligationCause::new(self.span, self.body_id, code)
@@ -135,21 +141,24 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
135141

136142
/// Pushes the obligations required for `trait_ref` to be WF into
137143
/// `self.out`.
138-
fn compute_trait_ref(&mut self, trait_ref: &ty::TraitRef<'tcx>) {
144+
fn compute_trait_ref(&mut self, trait_ref: &ty::TraitRef<'tcx>, elaborate: Elaborate) {
139145
let obligations = self.nominal_obligations(trait_ref.def_id, trait_ref.substs);
140146

141147
let cause = self.cause(traits::MiscObligation);
142148
let param_env = self.param_env;
143149

144-
let predicates = obligations.iter()
145-
.map(|obligation| obligation.predicate.clone())
146-
.collect();
147-
let implied_obligations = traits::elaborate_predicates(self.infcx.tcx, predicates);
148-
let implied_obligations = implied_obligations.map(|pred| {
149-
traits::Obligation::new(cause.clone(), param_env, pred)
150-
});
150+
if let Elaborate::All = elaborate {
151+
let predicates = obligations.iter()
152+
.map(|obligation| obligation.predicate.clone())
153+
.collect();
154+
let implied_obligations = traits::elaborate_predicates(self.infcx.tcx, predicates);
155+
let implied_obligations = implied_obligations.map(|pred| {
156+
traits::Obligation::new(cause.clone(), param_env, pred)
157+
});
158+
self.out.extend(implied_obligations);
159+
}
151160

152-
self.out.extend(implied_obligations.chain(obligations));
161+
self.out.extend(obligations);
153162

154163
self.out.extend(
155164
trait_ref.substs.types()
@@ -166,7 +175,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
166175
// WF and (b) the trait-ref holds. (It may also be
167176
// normalizable and be WF that way.)
168177
let trait_ref = data.trait_ref(self.infcx.tcx);
169-
self.compute_trait_ref(&trait_ref);
178+
self.compute_trait_ref(&trait_ref, Elaborate::All);
170179

171180
if !data.has_escaping_regions() {
172181
let predicate = trait_ref.to_predicate();

0 commit comments

Comments
 (0)