Do not consider elaborated projection predicates for objects in new solver
This commit is contained in:
parent
cf32b9de1e
commit
d62238d6a8
4 changed files with 37 additions and 9 deletions
|
@ -6,6 +6,7 @@ use super::trait_goals::structural_traits::*;
|
||||||
use super::{EvalCtxt, SolverMode};
|
use super::{EvalCtxt, SolverMode};
|
||||||
use crate::traits::coherence;
|
use crate::traits::coherence;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
use rustc_data_structures::fx::FxIndexSet;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_infer::traits::query::NoSolution;
|
use rustc_infer::traits::query::NoSolution;
|
||||||
use rustc_infer::traits::util::elaborate_predicates;
|
use rustc_infer::traits::util::elaborate_predicates;
|
||||||
|
@ -489,9 +490,21 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
for assumption in
|
let own_bounds: FxIndexSet<_> =
|
||||||
elaborate_predicates(tcx, bounds.iter().map(|bound| bound.with_self_ty(tcx, self_ty)))
|
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) {
|
match G::consider_object_bound_candidate(self, goal, assumption) {
|
||||||
Ok(result) => {
|
Ok(result) => {
|
||||||
candidates.push(Candidate { source: CandidateSource::BuiltinImpl, result })
|
candidates.push(Candidate { source: CandidateSource::BuiltinImpl, result })
|
||||||
|
|
12
tests/ui/traits/new-solver/dont-elaborate-for-projections.rs
Normal file
12
tests/ui/traits/new-solver/dont-elaborate-for-projections.rs
Normal file
|
@ -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() {}
|
|
@ -10,7 +10,7 @@ trait Trait: SuperTrait<A = <Self as SuperTrait>::B> {}
|
||||||
|
|
||||||
fn transmute<A, B>(x: A) -> B {
|
fn transmute<A, B>(x: A) -> B {
|
||||||
foo::<A, B, dyn Trait<A = A, B = B>>(x)
|
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
|
fn foo<A, B, T: ?Sized>(x: T::A) -> B
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
error[E0283]: type annotations needed: cannot satisfy `dyn Trait<A = A, B = B>: Trait`
|
error[E0277]: the trait bound `dyn Trait<A = A, B = B>: Trait` is not satisfied
|
||||||
--> $DIR/more-object-bound.rs:12:5
|
--> $DIR/more-object-bound.rs:12:17
|
||||||
|
|
|
|
||||||
LL | foo::<A, B, dyn Trait<A = A, B = B>>(x)
|
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`
|
note: required by a bound in `foo`
|
||||||
--> $DIR/more-object-bound.rs:18:8
|
--> $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 | where
|
||||||
LL | T: Trait<B = B>,
|
LL | T: Trait<B = B>,
|
||||||
| ^^^^^^^^^^^^ required by this bound in `foo`
|
| ^^^^^^^^^^^^ 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
|
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`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue