diff options
| author | Michael Goulet <michael@errs.io> | 2025-03-23 18:56:34 +0000 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2025-03-24 16:57:06 +0000 |
| commit | 251455bcc5b3652d2af2eed29a317d0afd907e48 (patch) | |
| tree | 66ef213d53af02aa78d4edae26ed2042a821bb88 | |
| parent | 90f5eab952728ac6edcf529a171f7de5c25e5d49 (diff) | |
| download | rust-251455bcc5b3652d2af2eed29a317d0afd907e48.tar.gz rust-251455bcc5b3652d2af2eed29a317d0afd907e48.zip | |
Allow WellFormed goals to be returned from relating in new solver
3 files changed, 57 insertions, 7 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 0322c9e4ab0..7ef36d0e9ae 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 @@ -971,15 +971,17 @@ where rhs: T, ) -> Result<(), NoSolution> { let goals = self.delegate.relate(param_env, lhs, variance, rhs, self.origin_span)?; - if cfg!(debug_assertions) { - for g in goals.iter() { - match g.predicate.kind().skip_binder() { - ty::PredicateKind::Subtype { .. } | ty::PredicateKind::AliasRelate(..) => {} - p => unreachable!("unexpected nested goal in `relate`: {p:?}"), + for &goal in goals.iter() { + let source = match goal.predicate.kind().skip_binder() { + ty::PredicateKind::Subtype { .. } | ty::PredicateKind::AliasRelate(..) => { + GoalSource::TypeRelating } - } + // FIXME(-Znext-solver=coinductive): should these WF goals also be unproductive? + ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(_)) => GoalSource::Misc, + p => unreachable!("unexpected nested goal in `relate`: {p:?}"), + }; + self.add_goal(source, goal); } - self.add_goals(GoalSource::TypeRelating, goals); Ok(()) } diff --git a/tests/ui/traits/next-solver/well-formed-in-relate.rs b/tests/ui/traits/next-solver/well-formed-in-relate.rs new file mode 100644 index 00000000000..eec1ddef228 --- /dev/null +++ b/tests/ui/traits/next-solver/well-formed-in-relate.rs @@ -0,0 +1,21 @@ +fn main() { + let x; + //~^ ERROR type annotations needed for `Map<_, _>` + higher_ranked(); + x = unconstrained_map(); +} + +fn higher_ranked() where for<'a> &'a (): Sized {} + +struct Map<T, U> where T: Fn() -> U { + t: T, +} + +trait Mirror { + type Assoc; +} +impl<T> Mirror for T { + type Assoc = T; +} + +fn unconstrained_map<T: Fn() -> U, U>() -> <Map<T, U> as Mirror>::Assoc { todo!() } diff --git a/tests/ui/traits/next-solver/well-formed-in-relate.stderr b/tests/ui/traits/next-solver/well-formed-in-relate.stderr new file mode 100644 index 00000000000..5294a072d31 --- /dev/null +++ b/tests/ui/traits/next-solver/well-formed-in-relate.stderr @@ -0,0 +1,27 @@ +error[E0283]: type annotations needed for `Map<_, _>` + --> $DIR/well-formed-in-relate.rs:2:9 + | +LL | let x; + | ^ +... +LL | x = unconstrained_map(); + | ------------------- type must be known at this point + | + = note: multiple `impl`s satisfying `_: Fn()` found in the following crates: `alloc`, `core`: + - impl<A, F> Fn<A> for &F + where A: Tuple, F: Fn<A>, F: ?Sized; + - impl<Args, F, A> Fn<Args> for Box<F, A> + where Args: Tuple, F: Fn<Args>, A: Allocator, F: ?Sized; +note: required by a bound in `unconstrained_map` + --> $DIR/well-formed-in-relate.rs:21:25 + | +LL | fn unconstrained_map<T: Fn() -> U, U>() -> <Map<T, U> as Mirror>::Assoc { todo!() } + | ^^^^^^^^^ required by this bound in `unconstrained_map` +help: consider giving `x` an explicit type, where the type for type parameter `T` is specified + | +LL | let x: Map<T, U>; + | +++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0283`. |
