@@ -271,12 +271,39 @@ 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 miscellaneous
276+ // nested goals will be converted to an inductive variant in the future.
277+ //
278+ // Having unknown cycles is always the safer option, as changing that to either
279+ // succeed or hard error is backwards compatible. If we incorrectly treat a cycle
280+ // as inductive even though it should not be, it may be unsound during coherence and
281+ // fixing it may cause inference breakage or introduce ambiguity.
282+ GoalSource :: Misc => PathKind :: Unknown ,
283+ GoalSource :: NormalizeGoal ( path_kind) => path_kind,
284+ GoalSource :: ImplWhereBound => {
285+ // We currently only consider a cycle coinductive if it steps
286+ // into a where-clause of a coinductive trait.
287+ //
288+ // We probably want to make all traits coinductive in the future,
289+ // so we treat cycles involving their where-clauses as ambiguous.
290+ if let CurrentGoalKind :: CoinductiveTrait = self . current_goal_kind {
291+ PathKind :: Coinductive
292+ } else {
293+ PathKind :: Unknown
294+ }
278295 }
279- _ => PathKind :: Inductive ,
296+ // Relating types is always unproductive. If we were to map proof trees to
297+ // corecursive functions as explained in #136824, relating types never
298+ // introduces a constructor which could cause the recursion to be guarded.
299+ GoalSource :: TypeRelating => PathKind :: Inductive ,
300+ // Instantiating a higher ranked goal can never cause the recursion to be
301+ // guarded and is therefore unproductive.
302+ GoalSource :: InstantiateHigherRanked => PathKind :: Inductive ,
303+ // These goal sources are likely unproductive and can be changed to
304+ // `PathKind::Inductive`. Keeping them as unknown until we're confident
305+ // about this and have an example where it is necessary.
306+ GoalSource :: AliasBoundConstCondition | GoalSource :: AliasWellFormed => PathKind :: Unknown ,
280307 }
281308 }
282309
@@ -606,7 +633,7 @@ where
606633
607634 let ( NestedNormalizationGoals ( nested_goals) , _, certainty) = self . evaluate_goal_raw (
608635 GoalEvaluationKind :: Nested ,
609- GoalSource :: Misc ,
636+ GoalSource :: TypeRelating ,
610637 unconstrained_goal,
611638 ) ?;
612639 // Add the nested goals from normalization to our own nested goals.
@@ -683,7 +710,7 @@ where
683710 pub ( super ) fn add_normalizes_to_goal ( & mut self , mut goal : Goal < I , ty:: NormalizesTo < I > > ) {
684711 goal. predicate = goal. predicate . fold_with ( & mut ReplaceAliasWithInfer :: new (
685712 self ,
686- GoalSource :: Misc ,
713+ GoalSource :: TypeRelating ,
687714 goal. param_env ,
688715 ) ) ;
689716 self . inspect . add_normalizes_to_goal ( self . delegate , self . max_input_universe , goal) ;
@@ -939,7 +966,15 @@ where
939966 rhs : T ,
940967 ) -> Result < ( ) , NoSolution > {
941968 let goals = self . delegate . relate ( param_env, lhs, variance, rhs, self . origin_span ) ?;
942- self . add_goals ( GoalSource :: Misc , goals) ;
969+ if cfg ! ( debug_assertions) {
970+ for g in goals. iter ( ) {
971+ match g. predicate . kind ( ) . skip_binder ( ) {
972+ ty:: PredicateKind :: Subtype { .. } | ty:: PredicateKind :: AliasRelate ( ..) => { }
973+ p => unreachable ! ( "unexpected nested goal in `relate`: {p:?}" ) ,
974+ }
975+ }
976+ }
977+ self . add_goals ( GoalSource :: TypeRelating , goals) ;
943978 Ok ( ( ) )
944979 }
945980
0 commit comments