about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-12-23 20:17:53 +0000
committerMichael Goulet <michael@errs.io>2025-01-06 17:58:42 +0000
commitebdf19a8bbd1efb533bab35b0a2b327e4a33282f (patch)
tree074293f94d79462076f8f2adaeaece3f5fed210c
parent2be9ffc1afd0623ab0697cbaca5693b80c6d362c (diff)
downloadrust-ebdf19a8bbd1efb533bab35b0a2b327e4a33282f.tar.gz
rust-ebdf19a8bbd1efb533bab35b0a2b327e4a33282f.zip
Recurse on GAT where clauses in fulfillment error proof tree visitor
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/effect_goals.rs4
-rw-r--r--compiler/rustc_trait_selection/src/solve/fulfill.rs14
-rw-r--r--compiler/rustc_type_ir/src/solve/mod.rs4
-rw-r--r--tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail-2.current.stderr2
-rw-r--r--tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail-2.next.stderr6
-rw-r--r--tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail-2.rs6
-rw-r--r--tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail.current.stderr2
-rw-r--r--tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail.next.stderr6
-rw-r--r--tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail.rs6
-rw-r--r--tests/ui/traits/const-traits/const-opaque.no.stderr2
-rw-r--r--tests/ui/traits/const-traits/const-opaque.rs2
11 files changed, 29 insertions, 25 deletions
diff --git a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
index 281796e84b1..7669a305d58 100644
--- a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
@@ -103,7 +103,7 @@ where
                 |ecx| {
                     // Const conditions must hold for the implied const bound to hold.
                     ecx.add_goals(
-                        GoalSource::Misc,
+                        GoalSource::AliasBoundConstCondition,
                         cx.const_conditions(alias_ty.def_id)
                             .iter_instantiated(cx, alias_ty.args)
                             .map(|trait_ref| {
@@ -353,7 +353,7 @@ where
 
         ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
             ecx.add_goals(
-                GoalSource::ImplWhereBound,
+                GoalSource::AliasBoundConstCondition,
                 const_conditions.into_iter().map(|trait_ref| {
                     goal.with(
                         cx,
diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs
index 7aa82c52c9f..986176aca77 100644
--- a/compiler/rustc_trait_selection/src/solve/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs
@@ -413,6 +413,7 @@ impl<'tcx> BestObligation<'tcx> {
                                     matches!(
                                         nested_goal.source(),
                                         GoalSource::ImplWhereBound
+                                            | GoalSource::AliasBoundConstCondition
                                             | GoalSource::InstantiateHigherRanked
                                             | GoalSource::AliasWellFormed
                                     ) && match self.consider_ambiguities {
@@ -495,7 +496,6 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
         };
 
         let mut impl_where_bound_count = 0;
-        let mut impl_const_condition_bound_count = 0;
         for nested_goal in candidate.instantiate_nested_goals(self.span()) {
             trace!(nested_goal = ?(nested_goal.goal(), nested_goal.source(), nested_goal.result()));
 
@@ -521,21 +521,25 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
                     ));
                     impl_where_bound_count += 1;
                 }
-                (ChildMode::Host(parent_host_pred), GoalSource::ImplWhereBound) => {
+                (
+                    ChildMode::Host(parent_host_pred),
+                    GoalSource::ImplWhereBound | GoalSource::AliasBoundConstCondition,
+                ) => {
                     obligation = make_obligation(derive_host_cause(
                         tcx,
                         candidate.kind(),
                         self.obligation.cause.clone(),
-                        impl_const_condition_bound_count,
+                        impl_where_bound_count,
                         parent_host_pred,
                     ));
-                    impl_const_condition_bound_count += 1;
+                    impl_where_bound_count += 1;
                 }
                 // Skip over a higher-ranked predicate.
                 (_, GoalSource::InstantiateHigherRanked) => {
                     obligation = self.obligation.clone();
                 }
-                (ChildMode::PassThrough, _) | (_, GoalSource::AliasWellFormed) => {
+                (ChildMode::PassThrough, _)
+                | (_, GoalSource::AliasWellFormed | GoalSource::AliasBoundConstCondition) => {
                     obligation = make_obligation(self.obligation.cause.clone());
                 }
             }
diff --git a/compiler/rustc_type_ir/src/solve/mod.rs b/compiler/rustc_type_ir/src/solve/mod.rs
index 8fe512026e5..1ae904d50e0 100644
--- a/compiler/rustc_type_ir/src/solve/mod.rs
+++ b/compiler/rustc_type_ir/src/solve/mod.rs
@@ -68,6 +68,10 @@ pub enum GoalSource {
     /// FIXME(-Znext-solver=coinductive): Explain how and why this
     /// changes whether cycles are coinductive.
     ImplWhereBound,
+    /// Const conditions that need to hold for `~const` alias bounds to hold.
+    ///
+    /// FIXME(-Znext-solver=coinductive): Are these even coinductive?
+    AliasBoundConstCondition,
     /// Instantiating a higher-ranked goal and re-proving it.
     InstantiateHigherRanked,
     /// Predicate required for an alias projection to be well-formed.
diff --git a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail-2.current.stderr b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail-2.current.stderr
index 03da9159bea..4cd87002e49 100644
--- a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail-2.current.stderr
+++ b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail-2.current.stderr
@@ -5,7 +5,7 @@ LL |     T::Assoc::<U>::func();
    |     ^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `U: ~const Other` is not satisfied
-  --> $DIR/assoc-type-const-bound-usage-fail-2.rs:27:5
+  --> $DIR/assoc-type-const-bound-usage-fail-2.rs:26:5
    |
 LL |     <T as Trait>::Assoc::<U>::func();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail-2.next.stderr b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail-2.next.stderr
index ce58b486a16..4cd87002e49 100644
--- a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail-2.next.stderr
+++ b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail-2.next.stderr
@@ -1,11 +1,11 @@
-error[E0277]: the trait bound `<T as Trait>::Assoc<U>: ~const Trait` is not satisfied
+error[E0277]: the trait bound `U: ~const Other` is not satisfied
   --> $DIR/assoc-type-const-bound-usage-fail-2.rs:24:5
    |
 LL |     T::Assoc::<U>::func();
    |     ^^^^^^^^^^^^^
 
-error[E0277]: the trait bound `<T as Trait>::Assoc<U>: ~const Trait` is not satisfied
-  --> $DIR/assoc-type-const-bound-usage-fail-2.rs:27:5
+error[E0277]: the trait bound `U: ~const Other` is not satisfied
+  --> $DIR/assoc-type-const-bound-usage-fail-2.rs:26:5
    |
 LL |     <T as Trait>::Assoc::<U>::func();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail-2.rs b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail-2.rs
index bdd98eaf541..e1c30b53611 100644
--- a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail-2.rs
+++ b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail-2.rs
@@ -22,11 +22,9 @@ trait Other {}
 
 const fn fails<T: ~const Trait, U: Other>() {
     T::Assoc::<U>::func();
-    //[current]~^ ERROR the trait bound `U: ~const Other` is not satisfied
-    //[next]~^^ ERROR the trait bound `<T as Trait>::Assoc<U>: ~const Trait` is not satisfied
+    //~^ ERROR the trait bound `U: ~const Other` is not satisfied
     <T as Trait>::Assoc::<U>::func();
-    //[current]~^ ERROR the trait bound `U: ~const Other` is not satisfied
-    //[next]~^^ ERROR the trait bound `<T as Trait>::Assoc<U>: ~const Trait` is not satisfied
+    //~^ ERROR the trait bound `U: ~const Other` is not satisfied
 }
 
 const fn works<T: ~const Trait, U: ~const Other>() {
diff --git a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail.current.stderr b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail.current.stderr
index ccd4af99cf4..9c29a894749 100644
--- a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail.current.stderr
+++ b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail.current.stderr
@@ -5,7 +5,7 @@ LL |     T::Assoc::func();
    |     ^^^^^^^^
 
 error[E0277]: the trait bound `T: ~const Trait` is not satisfied
-  --> $DIR/assoc-type-const-bound-usage-fail.rs:20:5
+  --> $DIR/assoc-type-const-bound-usage-fail.rs:19:5
    |
 LL |     <T as Trait>::Assoc::func();
    |     ^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail.next.stderr b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail.next.stderr
index ee1b663b999..9c29a894749 100644
--- a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail.next.stderr
+++ b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail.next.stderr
@@ -1,11 +1,11 @@
-error[E0277]: the trait bound `<T as Trait>::Assoc: ~const Trait` is not satisfied
+error[E0277]: the trait bound `T: ~const Trait` is not satisfied
   --> $DIR/assoc-type-const-bound-usage-fail.rs:17:5
    |
 LL |     T::Assoc::func();
    |     ^^^^^^^^
 
-error[E0277]: the trait bound `<T as Trait>::Assoc: ~const Trait` is not satisfied
-  --> $DIR/assoc-type-const-bound-usage-fail.rs:20:5
+error[E0277]: the trait bound `T: ~const Trait` is not satisfied
+  --> $DIR/assoc-type-const-bound-usage-fail.rs:19:5
    |
 LL |     <T as Trait>::Assoc::func();
    |     ^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail.rs b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail.rs
index 224ebb2daf1..3761fea1968 100644
--- a/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail.rs
+++ b/tests/ui/traits/const-traits/assoc-type-const-bound-usage-fail.rs
@@ -15,11 +15,9 @@ trait Trait {
 
 const fn unqualified<T: Trait>() {
     T::Assoc::func();
-    //[current]~^ ERROR the trait bound `T: ~const Trait` is not satisfied
-    //[next]~^^ ERROR the trait bound `<T as Trait>::Assoc: ~const Trait` is not satisfied
+    //~^ ERROR the trait bound `T: ~const Trait` is not satisfied
     <T as Trait>::Assoc::func();
-    //[current]~^ ERROR the trait bound `T: ~const Trait` is not satisfied
-    //[next]~^^ ERROR the trait bound `<T as Trait>::Assoc: ~const Trait` is not satisfied
+    //~^ ERROR the trait bound `T: ~const Trait` is not satisfied
 }
 
 const fn works<T: ~const Trait>() {
diff --git a/tests/ui/traits/const-traits/const-opaque.no.stderr b/tests/ui/traits/const-traits/const-opaque.no.stderr
index 33aa1065df3..1278e125746 100644
--- a/tests/ui/traits/const-traits/const-opaque.no.stderr
+++ b/tests/ui/traits/const-traits/const-opaque.no.stderr
@@ -12,7 +12,7 @@ note: required by a bound in `bar`
 LL | const fn bar<T: ~const Foo>(t: T) -> impl ~const Foo {
    |                 ^^^^^^ required by this bound in `bar`
 
-error[E0277]: the trait bound `impl Foo: const Foo` is not satisfied
+error[E0277]: the trait bound `(): const Foo` is not satisfied
   --> $DIR/const-opaque.rs:33:12
    |
 LL |     opaque.method();
diff --git a/tests/ui/traits/const-traits/const-opaque.rs b/tests/ui/traits/const-traits/const-opaque.rs
index bfcadd521a5..96cdd7d9f26 100644
--- a/tests/ui/traits/const-traits/const-opaque.rs
+++ b/tests/ui/traits/const-traits/const-opaque.rs
@@ -31,7 +31,7 @@ const _: () = {
     let opaque = bar(());
     //[no]~^ ERROR the trait bound `(): const Foo` is not satisfied
     opaque.method();
-    //[no]~^ ERROR the trait bound `impl Foo: const Foo` is not satisfied
+    //[no]~^ ERROR the trait bound `(): const Foo` is not satisfied
     std::mem::forget(opaque);
 };