about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_trait_selection/src/solve/delegate.rs22
-rw-r--r--compiler/rustc_trait_selection/src/traits/fulfill.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/util.rs20
-rw-r--r--compiler/rustc_traits/src/evaluate_obligation.rs2
6 files changed, 30 insertions, 20 deletions
diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs
index 17429e15cce..7426504e139 100644
--- a/compiler/rustc_trait_selection/src/solve/delegate.rs
+++ b/compiler/rustc_trait_selection/src/solve/delegate.rs
@@ -12,11 +12,11 @@ use rustc_infer::traits::solve::Goal;
 use rustc_middle::traits::query::NoSolution;
 use rustc_middle::traits::solve::Certainty;
 use rustc_middle::ty::{
-    self, SizedTraitKind, Ty, TyCtxt, TypeFlags, TypeFoldable, TypeVisitableExt as _, TypingMode,
+    self, Ty, TyCtxt, TypeFlags, TypeFoldable, TypeVisitableExt as _, TypingMode,
 };
 use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span};
 
-use crate::traits::{EvaluateConstErr, ObligationCause, specialization_graph};
+use crate::traits::{EvaluateConstErr, ObligationCause, sizedness_fast_path, specialization_graph};
 
 #[repr(transparent)]
 pub struct SolverDelegate<'tcx>(InferCtxt<'tcx>);
@@ -76,19 +76,11 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
 
             if trait_pred.polarity() == ty::PredicatePolarity::Positive {
                 match self.0.tcx.as_lang_item(trait_pred.def_id()) {
-                    Some(LangItem::Sized)
-                        if self
-                            .resolve_vars_if_possible(trait_pred.self_ty().skip_binder())
-                            .has_trivial_sizedness(self.0.tcx, SizedTraitKind::Sized) =>
-                    {
-                        return Some(Certainty::Yes);
-                    }
-                    Some(LangItem::MetaSized)
-                        if self
-                            .resolve_vars_if_possible(trait_pred.self_ty().skip_binder())
-                            .has_trivial_sizedness(self.0.tcx, SizedTraitKind::MetaSized) =>
-                    {
-                        return Some(Certainty::Yes);
+                    Some(LangItem::Sized) | Some(LangItem::MetaSized) => {
+                        let predicate = self.resolve_vars_if_possible(goal.predicate);
+                        if sizedness_fast_path(self.tcx, predicate, goal.param_env) {
+                            return Some(Certainty::Yes);
+                        }
                     }
                     Some(LangItem::Copy | LangItem::Clone) => {
                         let self_ty =
diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs
index e35f89358e9..6b884b36080 100644
--- a/compiler/rustc_trait_selection/src/traits/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs
@@ -363,7 +363,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
 
         let infcx = self.selcx.infcx;
 
-        if sizedness_fast_path(infcx.tcx, obligation.predicate) {
+        if sizedness_fast_path(infcx.tcx, obligation.predicate, obligation.param_env) {
             return ProcessResult::Changed(thin_vec![]);
         }
 
diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs
index 22eeb285b37..f24214145ba 100644
--- a/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs
@@ -15,7 +15,7 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ProvePredicate<'tcx> {
         tcx: TyCtxt<'tcx>,
         key: &ParamEnvAnd<'tcx, Self>,
     ) -> Option<Self::QueryResponse> {
-        if sizedness_fast_path(tcx, key.value.predicate) {
+        if sizedness_fast_path(tcx, key.value.predicate, key.param_env) {
             return Some(());
         }
 
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 2b563c5b8d5..f90316f520b 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -597,7 +597,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             None => self.check_recursion_limit(&obligation, &obligation)?,
         }
 
-        if sizedness_fast_path(self.tcx(), obligation.predicate) {
+        if sizedness_fast_path(self.tcx(), obligation.predicate, obligation.param_env) {
             return Ok(EvaluatedToOk);
         }
 
diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs
index 0c14b124e25..c3d60ec45c4 100644
--- a/compiler/rustc_trait_selection/src/traits/util.rs
+++ b/compiler/rustc_trait_selection/src/traits/util.rs
@@ -365,7 +365,11 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for PlaceholderReplacer<'_, 'tcx> {
     }
 }
 
-pub fn sizedness_fast_path<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tcx>) -> bool {
+pub fn sizedness_fast_path<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    predicate: ty::Predicate<'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
+) -> bool {
     // Proving `Sized`/`MetaSized`, very often on "obviously sized" types like
     // `&T`, accounts for about 60% percentage of the predicates we have to prove. No need to
     // canonicalize and all that for such cases.
@@ -390,6 +394,20 @@ pub fn sizedness_fast_path<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tc
             debug!("fast path -- trivial sizedness");
             return true;
         }
+
+        if matches!(trait_pred.self_ty().kind(), ty::Param(_) | ty::Placeholder(_)) {
+            for clause in param_env.caller_bounds() {
+                if let ty::ClauseKind::Trait(clause_pred) = clause.kind().skip_binder()
+                    && clause_pred.polarity == ty::PredicatePolarity::Positive
+                    && clause_pred.self_ty() == trait_pred.self_ty()
+                    && (clause_pred.def_id() == trait_pred.def_id()
+                        || (sizedness == SizedTraitKind::MetaSized
+                            && tcx.is_lang_item(clause_pred.def_id(), LangItem::Sized)))
+                {
+                    return true;
+                }
+            }
+        }
     }
 
     false
diff --git a/compiler/rustc_traits/src/evaluate_obligation.rs b/compiler/rustc_traits/src/evaluate_obligation.rs
index 7771db855d7..819b8e3231c 100644
--- a/compiler/rustc_traits/src/evaluate_obligation.rs
+++ b/compiler/rustc_traits/src/evaluate_obligation.rs
@@ -24,7 +24,7 @@ fn evaluate_obligation<'tcx>(
     debug!("evaluate_obligation: goal={:#?}", goal);
     let ParamEnvAnd { param_env, value: predicate } = goal;
 
-    if sizedness_fast_path(tcx, predicate) {
+    if sizedness_fast_path(tcx, predicate, param_env) {
         return Ok(EvaluationResult::EvaluatedToOk);
     }