diff options
3 files changed, 24 insertions, 11 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 4c5d8b5ec79..7048f0dbedc 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -649,7 +649,12 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { if obligation.predicate.is_global() { // no type variables present, can use evaluation for better caching. // FIXME: consider caching errors too. - if infcx.predicate_must_hold_considering_regions(obligation) { + // + // If the predicate is considered const, then we cannot use this because + // it will cause false negatives in the ui tests. + if !self.selcx.is_predicate_const(obligation.predicate) + && infcx.predicate_must_hold_considering_regions(obligation) + { debug!( "selecting trait at depth {} evaluated to holds", obligation.recursion_depth @@ -703,7 +708,12 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { if obligation.predicate.is_global() { // no type variables present, can use evaluation for better caching. // FIXME: consider caching errors too. - if self.selcx.infcx().predicate_must_hold_considering_regions(obligation) { + // + // If the predicate is considered const, then we cannot use this because + // it will cause false negatives in the ui tests. + if !self.selcx.is_predicate_const(obligation.predicate) + && self.selcx.infcx().predicate_must_hold_considering_regions(obligation) + { return ProcessResult::Changed(vec![]); } else { tracing::debug!("Does NOT hold: {:?}", obligation); diff --git a/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs b/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs index 8cc57f952ad..2dc48e47efc 100644 --- a/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs +++ b/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs @@ -1,6 +1,3 @@ -use rustc_hir as hir; -use rustc_middle::ty::PredicateKind; - use crate::infer::canonical::OriginalQueryValues; use crate::infer::InferCtxt; use crate::traits::{ @@ -49,12 +46,6 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> { &self, obligation: &PredicateObligation<'tcx>, ) -> bool { - if let PredicateKind::Trait(pred) = obligation.predicate.kind().skip_binder() { - if let hir::Constness::Const = pred.constness { - // do not evaluate to holds when we have a const predicate. - return false; - } - } self.evaluate_obligation_no_overflow(obligation).must_apply_considering_regions() } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 4c7ee5382d0..dcf5ac63b78 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -316,6 +316,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { self.infcx.tcx } + /// returns `true` if the predicate is considered `const` to + /// this selection context. + pub fn is_predicate_const(&self, pred: ty::Predicate<'_>) -> bool { + match pred.kind().skip_binder() { + ty::PredicateKind::Trait(ty::TraitPredicate { + constness: hir::Constness::Const, + .. + }) if self.const_impls_required => true, + _ => false, + } + } + /////////////////////////////////////////////////////////////////////////// // Selection // |
