about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs14
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/trait_goals.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs1
3 files changed, 15 insertions, 6 deletions
diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs
index 60beaa0df84..e69d8d84d7d 100644
--- a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs
@@ -7,7 +7,7 @@ use rustc_type_ir::data_structures::HashMap;
 use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
 use rustc_type_ir::inherent::*;
 use rustc_type_ir::lang_items::TraitSolverLangItem;
-use rustc_type_ir::{self as ty, Interner, Upcast as _};
+use rustc_type_ir::{self as ty, elaborate, Interner, Upcast as _};
 use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic};
 use tracing::instrument;
 
@@ -671,11 +671,19 @@ where
 {
     let cx = ecx.cx();
     let mut requirements = vec![];
-    requirements.extend(
+    // Elaborating all supertrait outlives obligations here is not soundness critical,
+    // since if we just used the unelaborated set, then the transitive supertraits would
+    // be reachable when proving the former. However, since we elaborate all supertrait
+    // outlives obligations when confirming impls, we would end up with a different set
+    // of outlives obligations here if we didn't do the same, leading to ambiguity.
+    // FIXME(-Znext-solver=coinductive): Adding supertraits here can be removed once we
+    // make impls coinductive always, since they'll always need to prove their supertraits.
+    requirements.extend(elaborate::elaborate(
+        cx,
         cx.explicit_super_predicates_of(trait_ref.def_id)
             .iter_instantiated(cx, trait_ref.args)
             .map(|(pred, _)| pred),
-    );
+    ));
 
     // FIXME(associated_const_equality): Also add associated consts to
     // the requirements here.
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 77ce81e44a0..b1dba712f79 100644
--- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
@@ -87,9 +87,9 @@ where
                 .map(|pred| goal.with(cx, pred));
             ecx.add_goals(GoalSource::ImplWhereBound, where_clause_bounds);
 
-            // We currently elaborate all supertrait obligations from impls. This
-            // can be removed when we actually do coinduction correctly and just
-            // register that the impl header must be WF.
+            // 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!(
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 2bc2a8fe693..1d9a90f0300 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -2800,6 +2800,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
             });
         }
 
+        // Register any outlives obligations from the trait here, cc #124336.
         if matches!(self.tcx().def_kind(def_id), DefKind::Impl { of_trait: true })
             && let Some(header) = self.tcx().impl_trait_header(def_id)
         {