Skip to content

Commit d62238d

Browse files
Do not consider elaborated projection predicates for objects in new solver
1 parent cf32b9d commit d62238d

File tree

4 files changed

+37
-9
lines changed

4 files changed

+37
-9
lines changed

compiler/rustc_trait_selection/src/solve/assembly.rs

+16-3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use super::trait_goals::structural_traits::*;
66
use super::{EvalCtxt, SolverMode};
77
use crate::traits::coherence;
88
use itertools::Itertools;
9+
use rustc_data_structures::fx::FxIndexSet;
910
use rustc_hir::def_id::DefId;
1011
use rustc_infer::traits::query::NoSolution;
1112
use rustc_infer::traits::util::elaborate_predicates;
@@ -489,9 +490,21 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
489490
};
490491

491492
let tcx = self.tcx();
492-
for assumption in
493-
elaborate_predicates(tcx, bounds.iter().map(|bound| bound.with_self_ty(tcx, self_ty)))
494-
{
493+
let own_bounds: FxIndexSet<_> =
494+
bounds.iter().map(|bound| bound.with_self_ty(tcx, self_ty)).collect();
495+
for assumption in elaborate_predicates(tcx, own_bounds.iter().copied()) {
496+
// FIXME: Predicates are fully elaborated in the object type's existential bounds
497+
// list. We want to only consider these pre-elaborated projections, and not other
498+
// projection predicates that we reach by elaborating the principal trait ref,
499+
// since that'll cause ambiguity.
500+
//
501+
// We can remove this when we have implemented intersections in responses.
502+
if assumption.to_opt_poly_projection_pred().is_some()
503+
&& !own_bounds.contains(&assumption)
504+
{
505+
continue;
506+
}
507+
495508
match G::consider_object_bound_candidate(self, goal, assumption) {
496509
Ok(result) => {
497510
candidates.push(Candidate { source: CandidateSource::BuiltinImpl, result })
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// compile-flags: -Ztrait-solver=next
2+
// check-pass
3+
4+
trait Iter<'a, I: 'a>: Iterator<Item = &'a I> {}
5+
6+
fn needs_iter<'a, T: Iter<'a, I> + ?Sized, I: 'a>(_: &T) {}
7+
8+
fn test(x: &dyn Iter<'_, ()>) {
9+
needs_iter(x);
10+
}
11+
12+
fn main() {}

tests/ui/traits/new-solver/more-object-bound.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ trait Trait: SuperTrait<A = <Self as SuperTrait>::B> {}
1010

1111
fn transmute<A, B>(x: A) -> B {
1212
foo::<A, B, dyn Trait<A = A, B = B>>(x)
13-
//~^ ERROR type annotations needed: cannot satisfy `dyn Trait<A = A, B = B>: Trait`
13+
//~^ ERROR the trait bound `dyn Trait<A = A, B = B>: Trait` is not satisfied
1414
}
1515

1616
fn foo<A, B, T: ?Sized>(x: T::A) -> B
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
error[E0283]: type annotations needed: cannot satisfy `dyn Trait<A = A, B = B>: Trait`
2-
--> $DIR/more-object-bound.rs:12:5
1+
error[E0277]: the trait bound `dyn Trait<A = A, B = B>: Trait` is not satisfied
2+
--> $DIR/more-object-bound.rs:12:17
33
|
44
LL | foo::<A, B, dyn Trait<A = A, B = B>>(x)
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5+
| ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `dyn Trait<A = A, B = B>`
66
|
7-
= note: cannot satisfy `dyn Trait<A = A, B = B>: Trait`
87
note: required by a bound in `foo`
98
--> $DIR/more-object-bound.rs:18:8
109
|
@@ -13,7 +12,11 @@ LL | fn foo<A, B, T: ?Sized>(x: T::A) -> B
1312
LL | where
1413
LL | T: Trait<B = B>,
1514
| ^^^^^^^^^^^^ required by this bound in `foo`
15+
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
16+
|
17+
LL | fn transmute<A, B>(x: A) -> B where dyn Trait<A = A, B = B>: Trait {
18+
| ++++++++++++++++++++++++++++++++++++
1619

1720
error: aborting due to previous error
1821

19-
For more information about this error, try `rustc --explain E0283`.
22+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)