diff options
| author | Michael Goulet <michael@errs.io> | 2024-12-23 20:17:53 +0000 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2025-01-06 17:58:42 +0000 |
| commit | ebdf19a8bbd1efb533bab35b0a2b327e4a33282f (patch) | |
| tree | 074293f94d79462076f8f2adaeaece3f5fed210c | |
| parent | 2be9ffc1afd0623ab0697cbaca5693b80c6d362c (diff) | |
| download | rust-ebdf19a8bbd1efb533bab35b0a2b327e4a33282f.tar.gz rust-ebdf19a8bbd1efb533bab35b0a2b327e4a33282f.zip | |
Recurse on GAT where clauses in fulfillment error proof tree visitor
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); }; |
