Skip to content

Commit fa9ae7b

Browse files
Elaborate supertraits in dyn candidates
1 parent 6a891ec commit fa9ae7b

File tree

3 files changed

+15
-6
lines changed

3 files changed

+15
-6
lines changed

Diff for: compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs

+11-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use rustc_type_ir::data_structures::HashMap;
77
use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
88
use rustc_type_ir::inherent::*;
99
use rustc_type_ir::lang_items::TraitSolverLangItem;
10-
use rustc_type_ir::{self as ty, Interner, Upcast as _};
10+
use rustc_type_ir::{self as ty, elaborate, Interner, Upcast as _};
1111
use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic};
1212
use tracing::instrument;
1313

@@ -671,11 +671,19 @@ where
671671
{
672672
let cx = ecx.cx();
673673
let mut requirements = vec![];
674-
requirements.extend(
674+
// Elaborating all supertrait outlives obligations here is not soundness critical,
675+
// since if we just used the unelaborated set, then the transitive supertraits would
676+
// be reachable when proving the former. However, since we elaborate all supertrait
677+
// outlives obligations when confirming impls, we would end up with a different set
678+
// of outlives obligations here if we didn't do the same, leading to ambiguity.
679+
// FIXME(-Znext-solver=coinductive): Adding supertraits here can be removed once we
680+
// make impls coinductive always, since they'll always need to prove their supertraits.
681+
requirements.extend(elaborate::elaborate(
682+
cx,
675683
cx.explicit_super_predicates_of(trait_ref.def_id)
676684
.iter_instantiated(cx, trait_ref.args)
677685
.map(|(pred, _)| pred),
678-
);
686+
));
679687

680688
// FIXME(associated_const_equality): Also add associated consts to
681689
// the requirements here.

Diff for: compiler/rustc_next_trait_solver/src/solve/trait_goals.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,9 @@ where
8787
.map(|pred| goal.with(cx, pred));
8888
ecx.add_goals(GoalSource::ImplWhereBound, where_clause_bounds);
8989

90-
// We currently elaborate all supertrait obligations from impls. This
91-
// can be removed when we actually do coinduction correctly and just
92-
// register that the impl header must be WF.
90+
// We currently elaborate all supertrait outlives obligations from impls.
91+
// This can be removed when we actually do coinduction correctly, and prove
92+
// all supertrait obligations unconditionally.
9393
let goal_clause: I::Clause = goal.predicate.upcast(cx);
9494
for clause in elaborate::elaborate(cx, [goal_clause]) {
9595
if matches!(

Diff for: compiler/rustc_trait_selection/src/traits/select/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -2800,6 +2800,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
28002800
});
28012801
}
28022802

2803+
// Register any outlives obligations from the trait here, cc #124336.
28032804
if matches!(self.tcx().def_kind(def_id), DefKind::Impl { of_trait: true })
28042805
&& let Some(header) = self.tcx().impl_trait_header(def_id)
28052806
{

0 commit comments

Comments
 (0)