From fa9ae7b9d3e78a6605199efe358c0f1383d2f166 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 18 Jul 2024 12:08:57 -0400 Subject: [PATCH] Elaborate supertraits in dyn candidates --- .../src/solve/assembly/structural_traits.rs | 14 +++++++++++--- .../src/solve/trait_goals.rs | 6 +++--- .../rustc_trait_selection/src/traits/select/mod.rs | 1 + 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 60beaa0df84c..e69d8d84d7d8 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::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 @@ pub(in crate::solve) fn predicates_for_object_candidate( { 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 77ce81e44a0b..b1dba712f797 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 @@ fn consider_impl_candidate( .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 2bc2a8fe693c..1d9a90f0300a 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 @@ fn impl_or_trait_obligations( }); } + // 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) {