diff options
| author | Michael Goulet <michael@errs.io> | 2023-03-27 19:41:15 +0000 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2023-03-29 16:13:05 +0000 |
| commit | d62238d6a8ed57fecddfa9b97fd79cb0ac814791 (patch) | |
| tree | 2e3ce08aadf17a0c89d4f574b5c7d07c2999b6db | |
| parent | cf32b9de1e8f66526c36ad2927458558d2e81093 (diff) | |
| download | rust-d62238d6a8ed57fecddfa9b97fd79cb0ac814791.tar.gz rust-d62238d6a8ed57fecddfa9b97fd79cb0ac814791.zip | |
Do not consider elaborated projection predicates for objects in new solver
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`. |
