Skip to content

Commit ef771b8

Browse files
committed
review
1 parent fe874cd commit ef771b8

File tree

6 files changed

+36
-22
lines changed

6 files changed

+36
-22
lines changed

Diff for: compiler/rustc_middle/src/ty/predicate.rs

-14
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use rustc_data_structures::intern::Interned;
44
use rustc_hir::def_id::DefId;
55
use rustc_macros::{HashStable, extension};
66
use rustc_type_ir as ir;
7-
use tracing::instrument;
87

98
use crate::ty::{
109
self, DebruijnIndex, EarlyBinder, PredicatePolarity, Ty, TyCtxt, TypeFlags, Upcast, UpcastFrom,
@@ -115,19 +114,6 @@ impl<'tcx> Predicate<'tcx> {
115114
Some(tcx.mk_predicate(kind))
116115
}
117116

118-
/// Only used by the old solver to decide whether a predicate is accepted
119-
/// in a coinductive trait solver cycle.
120-
#[instrument(level = "debug", skip(tcx), ret)]
121-
pub fn is_coinductive(self, tcx: TyCtxt<'tcx>) -> bool {
122-
match self.kind().skip_binder() {
123-
ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) => {
124-
tcx.trait_is_coinductive(data.def_id())
125-
}
126-
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(_)) => true,
127-
_ => false,
128-
}
129-
}
130-
131117
/// Whether this projection can be soundly normalized.
132118
///
133119
/// Wf predicates must not be normalized, as normalization

Diff for: compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs

+15
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,14 @@ where
262262
self.delegate.typing_mode()
263263
}
264264

265+
/// Computes the `PathKind` for the step from the current goal to the
266+
/// nested goal required due to `source`.
267+
///
268+
/// See #136824 for a more detailed reasoning for this behavior. We
269+
/// consider cycles to be coinductive if they 'step into' a where-clause
270+
/// of a coinductive trait. We will likely extend this function in the future
271+
/// and will need to clearly document it in the rustc-dev-guide before
272+
/// stabilization.
265273
pub(super) fn step_kind_for_source(&self, source: GoalSource) -> PathKind {
266274
match (self.current_goal_kind, source) {
267275
(_, GoalSource::NormalizeGoal(step_kind)) => step_kind,
@@ -1099,6 +1107,13 @@ where
10991107
///
11001108
/// This is a performance optimization to more eagerly detect cycles during trait
11011109
/// solving. See tests/ui/traits/next-solver/cycles/cycle-modulo-ambig-aliases.rs.
1110+
///
1111+
/// The emitted goals get evaluated in the context of the parent goal; by
1112+
/// replacing aliases in nested goals we essentially pull the normalization out of
1113+
/// the nested goal. We want to treat the goal as if the normalization still happens
1114+
/// inside of the nested goal by inheriting the `step_kind` of the nested goal and
1115+
/// storing it in the `GoalSource` of the emitted `AliasRelate` goals.
1116+
/// This is necessary for tests/ui/sized/coinductive-1.rs to compile.
11021117
struct ReplaceAliasWithInfer<'me, 'a, D, I>
11031118
where
11041119
D: SolverDelegate<Interner = I>,

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

+9-3
Original file line numberDiff line numberDiff line change
@@ -1225,15 +1225,21 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
12251225
/// that recursion is ok. This routine returns `true` if the top of the
12261226
/// stack (`cycle[0]`):
12271227
///
1228-
/// - is a defaulted trait,
1228+
/// - is a coinductive trait: an auto-trait or `Sized`,
12291229
/// - it also appears in the backtrace at some position `X`,
12301230
/// - all the predicates at positions `X..` between `X` and the top are
1231-
/// also defaulted traits.
1231+
/// also coinductive traits.
12321232
pub(crate) fn coinductive_match<I>(&mut self, mut cycle: I) -> bool
12331233
where
12341234
I: Iterator<Item = ty::Predicate<'tcx>>,
12351235
{
1236-
cycle.all(|predicate| predicate.is_coinductive(self.tcx()))
1236+
cycle.all(|p| match p.kind().skip_binder() {
1237+
ty::PredicateKind::Clause(ty::ClauseKind::Trait(data)) => {
1238+
self.infcx.tcx.trait_is_coinductive(data.def_id())
1239+
}
1240+
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(_)) => true,
1241+
_ => false,
1242+
})
12371243
}
12381244

12391245
/// Further evaluates `candidate` to decide whether all type parameters match and whether nested

Diff for: compiler/rustc_type_ir/src/solve/mod.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,8 @@ pub enum GoalSource {
8383
/// In case normalizing aliases in nested goals cycles, eagerly normalizing these
8484
/// aliases in the context of the parent may incorrectly change the cycle kind.
8585
/// Normalizing aliases in goals therefore tracks the original path kind for this
86-
/// nested goal.
87-
///
88-
/// This is necessary for tests/ui/sized/coinductive-1.rs to compile.
86+
/// nested goal. See the comment of the `ReplaceAliasWithInfer` visitor for more
87+
/// details.
8988
NormalizeGoal(PathKind),
9089
}
9190

Diff for: tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed.current.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error[E0275]: overflow evaluating the requirement `Foo<T>: SendIndir`
2-
--> $DIR/only-one-coinductive-step-needed.rs:9:15
2+
--> $DIR/only-one-coinductive-step-needed.rs:17:15
33
|
44
LL | struct Foo<T>(<Foo<T> as Trait>::Assoc);
55
| ^^^^^^^^^^^^^^^^^^^^^^^^
66
|
77
note: required for `Foo<T>` to implement `Trait`
8-
--> $DIR/only-one-coinductive-step-needed.rs:18:20
8+
--> $DIR/only-one-coinductive-step-needed.rs:26:20
99
|
1010
LL | impl<T: SendIndir> Trait for T {
1111
| --------- ^^^^^ ^

Diff for: tests/ui/traits/next-solver/cycles/coinduction/only-one-coinductive-step-needed.rs

+8
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@
55

66
// #136824 changed cycles to be coinductive if they have at least
77
// one productive step, causing this test to pass with the new solver.
8+
//
9+
// The cycle in the test is the following:
10+
// - `Foo<T>: Send`, builtin auto-trait impl requires
11+
// - `<Foo<T> as Trait>::Assoc: Send`, requires normalizing self type via impl, requires
12+
// - `Foo<T>: SendIndir`, via impl requires
13+
// - `Foo<T>: Send` cycle
14+
//
15+
// The old solver treats this cycle as inductive due to the `Foo<T>: SendIndir` step.
816

917
struct Foo<T>(<Foo<T> as Trait>::Assoc);
1018
//[current]~^ ERROR overflow evaluating the requirement `Foo<T>: SendIndir`

0 commit comments

Comments
 (0)