about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2023-03-27 19:41:15 +0000
committerMichael Goulet <michael@errs.io>2023-03-29 16:13:05 +0000
commitd62238d6a8ed57fecddfa9b97fd79cb0ac814791 (patch)
tree2e3ce08aadf17a0c89d4f574b5c7d07c2999b6db
parentcf32b9de1e8f66526c36ad2927458558d2e81093 (diff)
downloadrust-d62238d6a8ed57fecddfa9b97fd79cb0ac814791.tar.gz
rust-d62238d6a8ed57fecddfa9b97fd79cb0ac814791.zip
Do not consider elaborated projection predicates for objects in new solver
-rw-r--r--compiler/rustc_trait_selection/src/solve/assembly.rs19
-rw-r--r--tests/ui/traits/new-solver/dont-elaborate-for-projections.rs12
-rw-r--r--tests/ui/traits/new-solver/more-object-bound.rs2
-rw-r--r--tests/ui/traits/new-solver/more-object-bound.stderr13
4 files changed, 37 insertions, 9 deletions
diff --git a/compiler/rustc_trait_selection/src/solve/assembly.rs b/compiler/rustc_trait_selection/src/solve/assembly.rs
index 0f7a0eb337b..856b1c08b72 100644
--- a/compiler/rustc_trait_selection/src/solve/assembly.rs
+++ b/compiler/rustc_trait_selection/src/solve/assembly.rs
@@ -6,6 +6,7 @@ use super::trait_goals::structural_traits::*;
 use super::{EvalCtxt, SolverMode};
 use crate::traits::coherence;
 use itertools::Itertools;
+use rustc_data_structures::fx::FxIndexSet;
 use rustc_hir::def_id::DefId;
 use rustc_infer::traits::query::NoSolution;
 use rustc_infer::traits::util::elaborate_predicates;
@@ -489,9 +490,21 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         };
 
         let tcx = self.tcx();
-        for assumption in
-            elaborate_predicates(tcx, bounds.iter().map(|bound| bound.with_self_ty(tcx, self_ty)))
-        {
+        let own_bounds: FxIndexSet<_> =
+            bounds.iter().map(|bound| bound.with_self_ty(tcx, self_ty)).collect();
+        for assumption in elaborate_predicates(tcx, own_bounds.iter().copied()) {
+            // FIXME: Predicates are fully elaborated in the object type's existential bounds
+            // list. We want to only consider these pre-elaborated projections, and not other
+            // projection predicates that we reach by elaborating the principal trait ref,
+            // since that'll cause ambiguity.
+            //
+            // We can remove this when we have implemented intersections in responses.
+            if assumption.to_opt_poly_projection_pred().is_some()
+                && !own_bounds.contains(&assumption)
+            {
+                continue;
+            }
+
             match G::consider_object_bound_candidate(self, goal, assumption) {
                 Ok(result) => {
                     candidates.push(Candidate { source: CandidateSource::BuiltinImpl, result })
diff --git a/tests/ui/traits/new-solver/dont-elaborate-for-projections.rs b/tests/ui/traits/new-solver/dont-elaborate-for-projections.rs
new file mode 100644
index 00000000000..e608250063c
--- /dev/null
+++ b/tests/ui/traits/new-solver/dont-elaborate-for-projections.rs
@@ -0,0 +1,12 @@
+// compile-flags: -Ztrait-solver=next
+// check-pass
+
+trait Iter<'a, I: 'a>: Iterator<Item = &'a I> {}
+
+fn needs_iter<'a, T: Iter<'a, I> + ?Sized, I: 'a>(_: &T) {}
+
+fn test(x: &dyn Iter<'_, ()>) {
+    needs_iter(x);
+}
+
+fn main() {}
diff --git a/tests/ui/traits/new-solver/more-object-bound.rs b/tests/ui/traits/new-solver/more-object-bound.rs
index 712759ef0e6..bb730b18ef7 100644
--- a/tests/ui/traits/new-solver/more-object-bound.rs
+++ b/tests/ui/traits/new-solver/more-object-bound.rs
@@ -10,7 +10,7 @@ trait Trait: SuperTrait<A = <Self as SuperTrait>::B> {}
 
 fn transmute<A, B>(x: A) -> B {
     foo::<A, B, dyn Trait<A = A, B = B>>(x)
-    //~^ ERROR type annotations needed: cannot satisfy `dyn Trait<A = A, B = B>: Trait`
+    //~^ ERROR the trait bound `dyn Trait<A = A, B = B>: Trait` is not satisfied
 }
 
 fn foo<A, B, T: ?Sized>(x: T::A) -> B
diff --git a/tests/ui/traits/new-solver/more-object-bound.stderr b/tests/ui/traits/new-solver/more-object-bound.stderr
index 208fdecb08f..4554b8c7473 100644
--- a/tests/ui/traits/new-solver/more-object-bound.stderr
+++ b/tests/ui/traits/new-solver/more-object-bound.stderr
@@ -1,10 +1,9 @@
-error[E0283]: type annotations needed: cannot satisfy `dyn Trait<A = A, B = B>: Trait`
-  --> $DIR/more-object-bound.rs:12:5
+error[E0277]: the trait bound `dyn Trait<A = A, B = B>: Trait` is not satisfied
+  --> $DIR/more-object-bound.rs:12:17
    |
 LL |     foo::<A, B, dyn Trait<A = A, B = B>>(x)
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `dyn Trait<A = A, B = B>`
    |
-   = note: cannot satisfy `dyn Trait<A = A, B = B>: Trait`
 note: required by a bound in `foo`
   --> $DIR/more-object-bound.rs:18:8
    |
@@ -13,7 +12,11 @@ LL | fn foo<A, B, T: ?Sized>(x: T::A) -> B
 LL | where
 LL |     T: Trait<B = B>,
    |        ^^^^^^^^^^^^ required by this bound in `foo`
+help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
+   |
+LL | fn transmute<A, B>(x: A) -> B where dyn Trait<A = A, B = B>: Trait {
+   |                               ++++++++++++++++++++++++++++++++++++
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0283`.
+For more information about this error, try `rustc --explain E0277`.