diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs index 0b80969c307c8..d0e92a54cebbc 100644 --- a/compiler/rustc_trait_selection/src/solve/project_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs @@ -8,16 +8,28 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { &mut self, goal: Goal<'tcx, ProjectionPredicate<'tcx>>, ) -> QueryResult<'tcx> { - match goal.predicate.term.unpack() { - ty::TermKind::Ty(term) => { - let alias = goal.predicate.projection_ty.to_ty(self.tcx()); - self.eq(goal.param_env, alias, term)?; - self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) - } - // FIXME(associated_const_equality): actually do something here. - ty::TermKind::Const(_) => { - self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) - } - } + let tcx = self.tcx(); + let projection_term = match goal.predicate.term.unpack() { + ty::TermKind::Ty(_) => goal.predicate.projection_ty.to_ty(tcx).into(), + ty::TermKind::Const(_) => ty::Const::new_unevaluated( + tcx, + ty::UnevaluatedConst::new( + goal.predicate.projection_ty.def_id, + goal.predicate.projection_ty.args, + ), + tcx.type_of(goal.predicate.projection_ty.def_id) + .instantiate(tcx, goal.predicate.projection_ty.args), + ) + .into(), + }; + self.add_goal(goal.with( + tcx, + ty::PredicateKind::AliasRelate( + projection_term, + goal.predicate.term, + ty::AliasRelationDirection::Equate, + ), + )); + self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } } diff --git a/tests/ui/traits/new-solver/closure-signature-inference-2.rs b/tests/ui/traits/new-solver/closure-signature-inference-2.rs new file mode 100644 index 0000000000000..4481146e7e25e --- /dev/null +++ b/tests/ui/traits/new-solver/closure-signature-inference-2.rs @@ -0,0 +1,21 @@ +// compile-flags: -Ztrait-solver=next +// check-pass + +fn map U>(f: F) { + f(T::default()); +} + +fn main() { + map::(|x| x.to_string()); + // PREVIOUSLY when confirming the `map` call, we register: + // + // (1.) ?F: FnOnce<(i32,)> + // (2.) >::Output projects-to ?U + // + // While (1.) is ambiguous, (2.) immediately gets processed + // and we infer `?U := >::Output`. + // + // Thus, the only pending obligation that remains is (1.). + // Since it is a trait obligation, we don't use it to deduce + // the closure signature, and we fail! +} diff --git a/tests/ui/traits/new-solver/closure-signature-inference.rs b/tests/ui/traits/new-solver/closure-signature-inference.rs new file mode 100644 index 0000000000000..d739987880cd8 --- /dev/null +++ b/tests/ui/traits/new-solver/closure-signature-inference.rs @@ -0,0 +1,15 @@ +// compile-flags: -Ztrait-solver=next +// check-pass + +struct A; +impl A { + fn hi(self) {} +} + +fn hello() -> Result<(A,), ()> { + Err(()) +} + +fn main() { + let x = hello().map(|(x,)| x.hi()); +} diff --git a/tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-2.stderr b/tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-2.stderr index e4922b0c3e902..4548ab1e2972a 100644 --- a/tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-2.stderr +++ b/tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-2.stderr @@ -1,8 +1,18 @@ -error[E0284]: type annotations needed: cannot satisfy `<::Assoc as WithAssoc< as Id>::Assoc>>::Assoc normalizes-to <>::Assoc as Id>::Assoc` +error[E0284]: type annotations needed --> $DIR/generalize-proj-new-universe-index-2.rs:74:5 | LL | bound::<::Assoc, as Id>::Assoc, _>() - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot satisfy `<::Assoc as WithAssoc< as Id>::Assoc>>::Assoc normalizes-to <>::Assoc as Id>::Assoc` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `V` declared on the function `bound` + | + = note: cannot satisfy `<::Assoc as WithAssoc< as Id>::Assoc>>::Assoc == _` +note: required by a bound in `bound` + --> $DIR/generalize-proj-new-universe-index-2.rs:69:21 + | +LL | fn bound() + | ----- required by a bound in this function +LL | where +LL | T: WithAssoc, + | ^^^^^^^^^ required by this bound in `bound` error: aborting due to 1 previous error