about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_trait_selection/src/traits/fulfill.rs14
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs9
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs12
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
     //