Skip to content

Commit dc88ce2

Browse files
committed
change definitely non-productive cycles to error
1 parent c44ecdf commit dc88ce2

20 files changed

+232
-205
lines changed

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -740,7 +740,7 @@ where
740740
// We skip the goal itself as that one would cycle.
741741
let predicate: I::Predicate = trait_ref.upcast(cx);
742742
ecx.add_goals(
743-
GoalSource::Misc,
743+
GoalSource::CoherenceUnknowableSuper,
744744
elaborate::elaborate(cx, [predicate])
745745
.skip(1)
746746
.map(|predicate| goal.with(cx, predicate)),

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

+34-8
Original file line numberDiff line numberDiff line change
@@ -271,12 +271,38 @@ where
271271
/// and will need to clearly document it in the rustc-dev-guide before
272272
/// stabilization.
273273
pub(super) fn step_kind_for_source(&self, source: GoalSource) -> PathKind {
274-
match (self.current_goal_kind, source) {
275-
(_, GoalSource::NormalizeGoal(step_kind)) => step_kind,
276-
(CurrentGoalKind::CoinductiveTrait, GoalSource::ImplWhereBound) => {
277-
PathKind::Coinductive
274+
match source {
275+
// We treat these goals as unknown for now. It is likely that most, if not all
276+
// miscellaneous nested goals will be converted to `GoalSource::MiscKnownInductive`
277+
// over time.
278+
GoalSource::Misc => PathKind::Unknown,
279+
GoalSource::NormalizeGoal(path_kind) => path_kind,
280+
GoalSource::ImplWhereBound => {
281+
// We currently only consider a cycle coinductive if it steps
282+
// into a where-clause of a coinductive trait.
283+
//
284+
// We probably want to make all traits coinductive in the future,
285+
// so we treat cycles involving their where-clauses as ambiguous.
286+
if let CurrentGoalKind::CoinductiveTrait = self.current_goal_kind {
287+
PathKind::Coinductive
288+
} else {
289+
PathKind::Unknown
290+
}
278291
}
279-
_ => PathKind::Inductive,
292+
// We treat checking super trait bounds for unknowable candidates as
293+
// unknown. Treating them is inductive would cause be unsound as it causes
294+
// tests/ui/traits/next-solver/coherence/ambiguity-causes-visitor-hang.rs
295+
// to compile.
296+
GoalSource::CoherenceUnknowableSuper => PathKind::Unknown,
297+
// A step which is clearly unproductive. Cycles exclusively involving such steps
298+
// result in `Err(NoSolution)`.
299+
GoalSource::MiscKnownInductive | GoalSource::InstantiateHigherRanked => {
300+
PathKind::Inductive
301+
}
302+
// These goal sources are likely unproductive and can be changed to
303+
// `PathKind::Inductive`. Keeping them as unknown until we're confident
304+
// about this and have an example where it is necessary.
305+
GoalSource::AliasBoundConstCondition | GoalSource::AliasWellFormed => PathKind::Unknown,
280306
}
281307
}
282308

@@ -606,7 +632,7 @@ where
606632

607633
let (NestedNormalizationGoals(nested_goals), _, certainty) = self.evaluate_goal_raw(
608634
GoalEvaluationKind::Nested,
609-
GoalSource::Misc,
635+
GoalSource::normalizes_to(),
610636
unconstrained_goal,
611637
)?;
612638
// Add the nested goals from normalization to our own nested goals.
@@ -683,7 +709,7 @@ where
683709
pub(super) fn add_normalizes_to_goal(&mut self, mut goal: Goal<I, ty::NormalizesTo<I>>) {
684710
goal.predicate = goal.predicate.fold_with(&mut ReplaceAliasWithInfer::new(
685711
self,
686-
GoalSource::Misc,
712+
GoalSource::normalizes_to(),
687713
goal.param_env,
688714
));
689715
self.inspect.add_normalizes_to_goal(self.delegate, self.max_input_universe, goal);
@@ -939,7 +965,7 @@ where
939965
rhs: T,
940966
) -> Result<(), NoSolution> {
941967
let goals = self.delegate.relate(param_env, lhs, variance, rhs, self.origin_span)?;
942-
self.add_goals(GoalSource::Misc, goals);
968+
self.add_goals(GoalSource::MiscKnownInductive, goals);
943969
Ok(())
944970
}
945971

Diff for: compiler/rustc_next_trait_solver/src/solve/inspect/build.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,7 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> ProofTreeBuilder<D> {
421421
self.add_goal(
422422
delegate,
423423
max_input_universe,
424-
GoalSource::Misc,
424+
GoalSource::normalizes_to(),
425425
goal.with(delegate.cx(), goal.predicate),
426426
);
427427
}

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ where
313313
ty::AliasRelationDirection::Equate,
314314
),
315315
);
316-
self.add_goal(GoalSource::Misc, alias_relate_goal);
316+
self.add_goal(GoalSource::MiscKnownInductive, alias_relate_goal);
317317
self.try_evaluate_added_goals()?;
318318
Ok(self.resolve_vars_if_possible(normalized_term))
319319
} else {

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ where
2424
ty::AliasRelationDirection::Equate,
2525
),
2626
);
27-
self.add_goal(GoalSource::Misc, goal);
27+
self.add_goal(GoalSource::MiscKnownInductive, goal);
2828
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
2929
}
3030
}

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

+4-8
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::marker::PhantomData;
33

44
use rustc_type_ir::Interner;
55
use rustc_type_ir::search_graph::{self, PathKind};
6-
use rustc_type_ir::solve::{CanonicalInput, Certainty, QueryResult};
6+
use rustc_type_ir::solve::{CanonicalInput, Certainty, NoSolution, QueryResult};
77

88
use super::inspect::ProofTreeBuilder;
99
use super::{FIXPOINT_STEP_LIMIT, has_no_inference_or_external_constraints};
@@ -47,7 +47,8 @@ where
4747
) -> QueryResult<I> {
4848
match kind {
4949
PathKind::Coinductive => response_no_constraints(cx, input, Certainty::Yes),
50-
PathKind::Inductive => response_no_constraints(cx, input, Certainty::overflow(false)),
50+
PathKind::Unknown => response_no_constraints(cx, input, Certainty::overflow(false)),
51+
PathKind::Inductive => Err(NoSolution),
5152
}
5253
}
5354

@@ -57,12 +58,7 @@ where
5758
input: CanonicalInput<I>,
5859
result: QueryResult<I>,
5960
) -> bool {
60-
match kind {
61-
PathKind::Coinductive => response_no_constraints(cx, input, Certainty::Yes) == result,
62-
PathKind::Inductive => {
63-
response_no_constraints(cx, input, Certainty::overflow(false)) == result
64-
}
65-
}
61+
Self::initial_provisional_result(cx, kind, input) == result
6662
}
6763

6864
fn on_stack_overflow(

Diff for: compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -438,9 +438,15 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
438438

439439
let obligation;
440440
match (child_mode, nested_goal.source()) {
441+
// We shouldn't really care about coherence unknowable candidates
442+
// as we never report fulfillment errors involving them. However, this
443+
// is still reachable when building the fulfillment errors.
444+
(_, GoalSource::CoherenceUnknowableSuper) => continue,
441445
(
442446
ChildMode::Trait(_) | ChildMode::Host(_),
443-
GoalSource::Misc | GoalSource::NormalizeGoal(_),
447+
GoalSource::Misc
448+
| GoalSource::MiscKnownInductive
449+
| GoalSource::NormalizeGoal(_),
444450
) => {
445451
continue;
446452
}

0 commit comments

Comments
 (0)