about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2025-06-25 10:10:21 +0000
committerbors <bors@rust-lang.org>2025-06-25 10:10:21 +0000
commit2801f9aaf9b7580d9b230b532b0700709857cc88 (patch)
treef4c9c96cb627a103e248ca1bd0c44ecbe4fbde5b
parenta17780db7b8eebbf42a1cbe6bc9cc83013820ba5 (diff)
parent24ea06cbe8e5b735a4807d08da14b5925db896cc (diff)
downloadrust-2801f9aaf9b7580d9b230b532b0700709857cc88.tar.gz
rust-2801f9aaf9b7580d9b230b532b0700709857cc88.zip
Auto merge of #142746 - compiler-errors:super-implied-outlives, r=lcnr
Apply `impl_super_outlives` optimization to new trait solver

I never did rust-lang/rust#128746 for the new solver.

r? lcnr
-rw-r--r--compiler/rustc_middle/src/ty/context.rs7
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/trait_goals.rs15
-rw-r--r--compiler/rustc_type_ir/src/interner.rs7
3 files changed, 20 insertions, 9 deletions
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index c5f4b95cbbe..aa5355551ce 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -432,6 +432,13 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
         self.explicit_implied_predicates_of(def_id).map_bound(|preds| preds.into_iter().copied())
     }
 
+    fn impl_super_outlives(
+        self,
+        impl_def_id: DefId,
+    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
+        self.impl_super_outlives(impl_def_id)
+    }
+
     fn impl_is_const(self, def_id: DefId) -> bool {
         debug_assert_matches!(self.def_kind(def_id), DefKind::Impl { of_trait: true });
         self.is_conditionally_const(def_id)
diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
index 8ee116b090d..8aaa8e9ca87 100644
--- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
@@ -103,15 +103,12 @@ where
             // We currently elaborate all supertrait outlives obligations from impls.
             // This can be removed when we actually do coinduction correctly, and prove
             // all supertrait obligations unconditionally.
-            let goal_clause: I::Clause = goal.predicate.upcast(cx);
-            for clause in elaborate::elaborate(cx, [goal_clause]) {
-                if matches!(
-                    clause.kind().skip_binder(),
-                    ty::ClauseKind::TypeOutlives(..) | ty::ClauseKind::RegionOutlives(..)
-                ) {
-                    ecx.add_goal(GoalSource::Misc, goal.with(cx, clause));
-                }
-            }
+            ecx.add_goals(
+                GoalSource::Misc,
+                cx.impl_super_outlives(impl_def_id)
+                    .iter_instantiated(cx, impl_args)
+                    .map(|pred| goal.with(cx, pred)),
+            );
 
             ecx.evaluate_added_goals_and_make_canonical_response(maximal_certainty)
         })
diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs
index 033d2579678..ffc2903ad1c 100644
--- a/compiler/rustc_type_ir/src/interner.rs
+++ b/compiler/rustc_type_ir/src/interner.rs
@@ -271,6 +271,13 @@ pub trait Interner:
         def_id: Self::DefId,
     ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = (Self::Clause, Self::Span)>>;
 
+    /// This is equivalent to computing the super-predicates of the trait for this impl
+    /// and filtering them to the outlives predicates. This is purely for performance.
+    fn impl_super_outlives(
+        self,
+        impl_def_id: Self::DefId,
+    ) -> ty::EarlyBinder<Self, impl IntoIterator<Item = Self::Clause>>;
+
     fn impl_is_const(self, def_id: Self::DefId) -> bool;
     fn fn_is_const(self, def_id: Self::DefId) -> bool;
     fn alias_has_const_conditions(self, def_id: Self::DefId) -> bool;