about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2023-12-13 14:11:09 +0000
committerMichael Goulet <michael@errs.io>2023-12-14 18:41:23 +0000
commit929d632b541cb52c23e1b768bb8c3f88bf9b5955 (patch)
treeb625d6417e72dbc7e699f379fc2794a5dcbebe1e
parent2ecba0fa00b75e7291978c50bece407f17296f45 (diff)
downloadrust-929d632b541cb52c23e1b768bb8c3f88bf9b5955.tar.gz
rust-929d632b541cb52c23e1b768bb8c3f88bf9b5955.zip
Unconditionally register alias-relate in projection goal
-rw-r--r--compiler/rustc_trait_selection/src/solve/project_goals.rs34
-rw-r--r--tests/ui/traits/next-solver/closure-signature-inference-2.rs21
-rw-r--r--tests/ui/traits/next-solver/closure-signature-inference.rs15
-rw-r--r--tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-2.stderr14
-rw-r--r--tests/ui/traits/next-solver/projection/param-env-trait-candidate-1.rs (renamed from tests/ui/traits/new-solver/projection/param-env-trait-candidate-1.rs)0
-rw-r--r--tests/ui/traits/next-solver/projection/param-env-trait-candidate-2.rs (renamed from tests/ui/traits/new-solver/projection/param-env-trait-candidate-2.rs)0
6 files changed, 71 insertions, 13 deletions
diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs
index 0b80969c307..d0e92a54ceb 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/next-solver/closure-signature-inference-2.rs b/tests/ui/traits/next-solver/closure-signature-inference-2.rs
new file mode 100644
index 00000000000..8fece7ba91f
--- /dev/null
+++ b/tests/ui/traits/next-solver/closure-signature-inference-2.rs
@@ -0,0 +1,21 @@
+// compile-flags: -Znext-solver
+// check-pass
+
+fn map<T: Default, U, F: FnOnce(T) -> U>(f: F) {
+    f(T::default());
+}
+
+fn main() {
+    map::<i32, _ /* ?U */, _ /* ?F */>(|x| x.to_string());
+    // PREVIOUSLY when confirming the `map` call, we register:
+    //
+    // (1.) ?F: FnOnce<(i32,)>
+    // (2.) <?F as FnOnce<(i32,)>>::Output projects-to ?U
+    //
+    // While (1.) is ambiguous, (2.) immediately gets processed
+    // and we infer `?U := <?F as FnOnce<(i32,)>>::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/next-solver/closure-signature-inference.rs b/tests/ui/traits/next-solver/closure-signature-inference.rs
new file mode 100644
index 00000000000..355fc790229
--- /dev/null
+++ b/tests/ui/traits/next-solver/closure-signature-inference.rs
@@ -0,0 +1,15 @@
+// compile-flags: -Znext-solver
+// 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 e4922b0c3e9..4548ab1e297 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 `<<Rigid as IdHigherRankedBound>::Assoc as WithAssoc<<Wrapper<Leaf> as Id>::Assoc>>::Assoc normalizes-to <<Leaf as WithAssoc<_>>::Assoc as Id>::Assoc`
+error[E0284]: type annotations needed
   --> $DIR/generalize-proj-new-universe-index-2.rs:74:5
    |
 LL |     bound::<<Rigid as IdHigherRankedBound>::Assoc, <Wrapper<Leaf> as Id>::Assoc, _>()
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot satisfy `<<Rigid as IdHigherRankedBound>::Assoc as WithAssoc<<Wrapper<Leaf> as Id>::Assoc>>::Assoc normalizes-to <<Leaf as WithAssoc<_>>::Assoc as Id>::Assoc`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `V` declared on the function `bound`
+   |
+   = note: cannot satisfy `<<Rigid as IdHigherRankedBound>::Assoc as WithAssoc<<Wrapper<Leaf> as Id>::Assoc>>::Assoc == _`
+note: required by a bound in `bound`
+  --> $DIR/generalize-proj-new-universe-index-2.rs:69:21
+   |
+LL | fn bound<T: ?Sized, U: ?Sized, V: ?Sized>()
+   |    ----- required by a bound in this function
+LL | where
+LL |     T: WithAssoc<U, Assoc = V>,
+   |                     ^^^^^^^^^ required by this bound in `bound`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/traits/new-solver/projection/param-env-trait-candidate-1.rs b/tests/ui/traits/next-solver/projection/param-env-trait-candidate-1.rs
index b337c067374..b337c067374 100644
--- a/tests/ui/traits/new-solver/projection/param-env-trait-candidate-1.rs
+++ b/tests/ui/traits/next-solver/projection/param-env-trait-candidate-1.rs
diff --git a/tests/ui/traits/new-solver/projection/param-env-trait-candidate-2.rs b/tests/ui/traits/next-solver/projection/param-env-trait-candidate-2.rs
index db8dc1eb9be..db8dc1eb9be 100644
--- a/tests/ui/traits/new-solver/projection/param-env-trait-candidate-2.rs
+++ b/tests/ui/traits/next-solver/projection/param-env-trait-candidate-2.rs