From 7a82867105bbb125212cc7519199cc907210e5cb Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Mon, 21 Oct 2019 12:27:48 +0300 Subject: [PATCH] rustc: avoid checking Trait's predicates for WF(::X). --- src/librustc/ty/wf.rs | 58 +++++++++------- ...associated-types-overridden-binding.stderr | 11 +-- .../ui/issues/issue-20831-debruijn.stderr | 67 +------------------ 3 files changed, 37 insertions(+), 99 deletions(-) diff --git a/src/librustc/ty/wf.rs b/src/librustc/ty/wf.rs index 276fc8c1dec0f..1a7f358610e59 100644 --- a/src/librustc/ty/wf.rs +++ b/src/librustc/ty/wf.rs @@ -53,7 +53,7 @@ pub fn trait_obligations<'a, 'tcx>( item: Option<&'tcx hir::Item>, ) -> Vec> { let mut wf = WfPredicates { infcx, param_env, body_id, span, out: vec![], item }; - wf.compute_trait_ref(trait_ref, Elaborate::All); + wf.compute_trait_ref(trait_ref, Elaborate::All, false); wf.normalize() } @@ -69,7 +69,7 @@ pub fn predicate_obligations<'a, '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, Elaborate::None); // (*) + wf.compute_trait_ref(&t.skip_binder().trait_ref, Elaborate::None, false); // (*) } ty::Predicate::RegionOutlives(..) => { } @@ -163,14 +163,18 @@ impl<'a, 'tcx> WfPredicates<'a, '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>, elaborate: Elaborate) { + fn compute_trait_ref( + &mut self, + trait_ref: &ty::TraitRef<'tcx>, + elaborate: Elaborate, + is_proj: bool, + ) { let tcx = self.infcx.tcx; - 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 item = &self.item; + let item = self.item; let extend_cause_with_original_assoc_item_obligation = | cause: &mut traits::ObligationCause<'_>, pred: &ty::Predicate<'_>, @@ -313,26 +317,30 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { } }; - if let Elaborate::All = elaborate { - let trait_assoc_items = tcx.associated_items(trait_ref.def_id); - - let predicates = obligations.iter() - .map(|obligation| obligation.predicate.clone()) - .collect(); - let implied_obligations = traits::elaborate_predicates(tcx, predicates); - let implied_obligations = implied_obligations.map(|pred| { - let mut cause = cause.clone(); - extend_cause_with_original_assoc_item_obligation( - &mut cause, - &pred, - trait_assoc_items.clone(), - ); - traits::Obligation::new(cause, param_env, pred) - }); - self.out.extend(implied_obligations); - } + if !is_proj { + let obligations = self.nominal_obligations(trait_ref.def_id, trait_ref.substs); + + if let Elaborate::All = elaborate { + let trait_assoc_items = tcx.associated_items(trait_ref.def_id); + + let predicates = obligations.iter() + .map(|obligation| obligation.predicate.clone()) + .collect(); + let implied_obligations = traits::elaborate_predicates(tcx, predicates); + let implied_obligations = implied_obligations.map(|pred| { + let mut cause = cause.clone(); + extend_cause_with_original_assoc_item_obligation( + &mut cause, + &pred, + trait_assoc_items.clone(), + ); + traits::Obligation::new(cause, param_env, pred) + }); + self.out.extend(implied_obligations); + } - self.out.extend(obligations); + self.out.extend(obligations); + } self.out.extend(trait_ref.substs.types() .filter(|ty| !ty.has_escaping_bound_vars()) @@ -350,7 +358,7 @@ impl<'a, 'tcx> WfPredicates<'a, '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, Elaborate::None); + self.compute_trait_ref(&trait_ref, Elaborate::None, true); if !data.has_escaping_bound_vars() { let predicate = trait_ref.to_predicate(); diff --git a/src/test/ui/associated-types/associated-types-overridden-binding.stderr b/src/test/ui/associated-types/associated-types-overridden-binding.stderr index 5ef1b23cbcd21..8f3fe41a7a174 100644 --- a/src/test/ui/associated-types/associated-types-overridden-binding.stderr +++ b/src/test/ui/associated-types/associated-types-overridden-binding.stderr @@ -6,13 +6,6 @@ LL | trait Foo: Iterator {} LL | trait Bar: Foo {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0282]: type annotations needed - --> $DIR/associated-types-overridden-binding.rs:7:1 - | -LL | trait U32Iterator = I32Iterator; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type - -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0282, E0284. -For more information about an error, try `rustc --explain E0282`. +For more information about this error, try `rustc --explain E0284`. diff --git a/src/test/ui/issues/issue-20831-debruijn.stderr b/src/test/ui/issues/issue-20831-debruijn.stderr index 13c9c09461eae..724727d0c35f9 100644 --- a/src/test/ui/issues/issue-20831-debruijn.stderr +++ b/src/test/ui/issues/issue-20831-debruijn.stderr @@ -1,65 +1,3 @@ -error[E0308]: mismatched types - --> $DIR/issue-20831-debruijn.rs:28:5 - | -LL | / fn subscribe(&mut self, t : Box::Output> + 'a>) { -LL | | // Not obvious, but there is an implicit lifetime here -------^ -LL | | -LL | | -... | -LL | | self.sub = t; -LL | | } - | |_____^ lifetime mismatch - | - = note: expected type `'a` - found type `'_` -note: the anonymous lifetime #2 defined on the method body at 28:5... - --> $DIR/issue-20831-debruijn.rs:28:5 - | -LL | / fn subscribe(&mut self, t : Box::Output> + 'a>) { -LL | | // Not obvious, but there is an implicit lifetime here -------^ -LL | | -LL | | -... | -LL | | self.sub = t; -LL | | } - | |_____^ -note: ...does not necessarily outlive the lifetime `'a` as defined on the impl at 26:6 - --> $DIR/issue-20831-debruijn.rs:26:6 - | -LL | impl<'a> Publisher<'a> for MyStruct<'a> { - | ^^ - -error[E0308]: mismatched types - --> $DIR/issue-20831-debruijn.rs:28:5 - | -LL | / fn subscribe(&mut self, t : Box::Output> + 'a>) { -LL | | // Not obvious, but there is an implicit lifetime here -------^ -LL | | -LL | | -... | -LL | | self.sub = t; -LL | | } - | |_____^ lifetime mismatch - | - = note: expected type `'a` - found type `'_` -note: the lifetime `'a` as defined on the impl at 26:6... - --> $DIR/issue-20831-debruijn.rs:26:6 - | -LL | impl<'a> Publisher<'a> for MyStruct<'a> { - | ^^ -note: ...does not necessarily outlive the anonymous lifetime #2 defined on the method body at 28:5 - --> $DIR/issue-20831-debruijn.rs:28:5 - | -LL | / fn subscribe(&mut self, t : Box::Output> + 'a>) { -LL | | // Not obvious, but there is an implicit lifetime here -------^ -LL | | -LL | | -... | -LL | | self.sub = t; -LL | | } - | |_____^ - error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements --> $DIR/issue-20831-debruijn.rs:28:5 | @@ -92,7 +30,6 @@ LL | impl<'a> Publisher<'a> for MyStruct<'a> { expected Publisher<'_> found Publisher<'_> -error: aborting due to 3 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0308, E0495. -For more information about an error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0495`.