about summary refs log tree commit diff
path: root/compiler/rustc_next_trait_solver/src
diff options
context:
space:
mode:
authorlcnr <rust@lcnr.de>2025-04-16 10:19:14 +0200
committerlcnr <rust@lcnr.de>2025-04-16 10:35:09 +0200
commit48e119ef5a8b46ce8db8d362a6d94668c6deb541 (patch)
treedb83e257c71a6e33b595d53c9c2e00fbffbb065a /compiler/rustc_next_trait_solver/src
parentefb1e3d676e1549811da79ebd124b6fc4d856248 (diff)
downloadrust-48e119ef5a8b46ce8db8d362a6d94668c6deb541.tar.gz
rust-48e119ef5a8b46ce8db8d362a6d94668c6deb541.zip
stepping into impls for norm is unproductive
Diffstat (limited to 'compiler/rustc_next_trait_solver/src')
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs21
1 files changed, 13 insertions, 8 deletions
diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
index 148ba02252d..9994c85d0d0 100644
--- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
@@ -286,18 +286,23 @@ where
             // fixing it may cause inference breakage or introduce ambiguity.
             GoalSource::Misc => PathKind::Unknown,
             GoalSource::NormalizeGoal(path_kind) => path_kind,
-            GoalSource::ImplWhereBound => {
+            GoalSource::ImplWhereBound => match self.current_goal_kind {
                 // We currently only consider a cycle coinductive if it steps
                 // into a where-clause of a coinductive trait.
+                CurrentGoalKind::CoinductiveTrait => PathKind::Coinductive,
+                // While normalizing via an impl does step into a where-clause of
+                // an impl, accessing the associated item immediately steps out of
+                // it again. This means cycles/recursive calls are not guarded
+                // by impls used for normalization.
                 //
+                // See tests/ui/traits/next-solver/cycles/normalizes-to-is-not-productive.rs
+                // for how this can go wrong.
+                CurrentGoalKind::NormalizesTo => PathKind::Inductive,
                 // We probably want to make all traits coinductive in the future,
-                // so we treat cycles involving their where-clauses as ambiguous.
-                if let CurrentGoalKind::CoinductiveTrait = self.current_goal_kind {
-                    PathKind::Coinductive
-                } else {
-                    PathKind::Unknown
-                }
-            }
+                // so we treat cycles involving where-clauses of not-yet coinductive
+                // traits as ambiguous for now.
+                CurrentGoalKind::Misc => PathKind::Unknown,
+            },
             // Relating types is always unproductive. If we were to map proof trees to
             // corecursive functions as explained in #136824, relating types never
             // introduces a constructor which could cause the recursion to be guarded.