From 9790d6fbdd07d1efbec8088c88dc2b0d1f9ba283 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 9 Feb 2023 18:57:02 +0000 Subject: [PATCH] Add a couple random projection tests --- .../param-candidate-doesnt-shadow-project.rs | 25 ++++++++++++++++ ...ojection-param-candidates-are-ambiguous.rs | 30 +++++++++++++++++++ ...tion-param-candidates-are-ambiguous.stderr | 16 ++++++++++ 3 files changed, 71 insertions(+) create mode 100644 tests/ui/traits/new-solver/param-candidate-doesnt-shadow-project.rs create mode 100644 tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.rs create mode 100644 tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.stderr diff --git a/tests/ui/traits/new-solver/param-candidate-doesnt-shadow-project.rs b/tests/ui/traits/new-solver/param-candidate-doesnt-shadow-project.rs new file mode 100644 index 00000000000..bdf999ec5dd --- /dev/null +++ b/tests/ui/traits/new-solver/param-candidate-doesnt-shadow-project.rs @@ -0,0 +1,25 @@ +// compile-flags: -Ztrait-solver=next +// check-pass + +trait Foo { + type Assoc; +} + +trait Bar {} + +impl Foo for T { + type Assoc = i32; +} + +impl Bar for T where T: Foo {} + +fn require_bar() {} + +fn foo() { + // Unlike the classic solver, `::Assoc = _` will still project + // down to `i32` even though there's a param-env candidate here, since we + // don't assemble any param-env projection candidates for `T: Foo` alone. + require_bar::(); +} + +fn main() {} diff --git a/tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.rs b/tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.rs new file mode 100644 index 00000000000..cde2059ca9b --- /dev/null +++ b/tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.rs @@ -0,0 +1,30 @@ +// compile-flags: -Ztrait-solver=next + +// When we're solving `::Assoc = i32`, we actually first solve +// `::Assoc = _#1t`, then unify `_#1t` with `i32`. That goal +// with the inference variable is ambiguous when there are >1 param-env +// candidates. + +// We don't unify the RHS of a projection goal eagerly when solving, both +// for caching reasons and partly to make sure that we don't make the new +// trait solver smarter than it should be. + +// This is (as far as I can tell) a forwards-compatible decision, but if you +// make this test go from fail to pass, be sure you understand the implications! + +trait Foo { + type Assoc; +} + +trait Bar {} + +impl Bar for T where T: Foo {} + +fn needs_bar() {} + +fn foo + Foo>() { + needs_bar::(); + //~^ ERROR type annotations needed: cannot satisfy `T: Bar` +} + +fn main() {} diff --git a/tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.stderr b/tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.stderr new file mode 100644 index 00000000000..fa5e780ee5e --- /dev/null +++ b/tests/ui/traits/new-solver/two-projection-param-candidates-are-ambiguous.stderr @@ -0,0 +1,16 @@ +error[E0283]: type annotations needed: cannot satisfy `T: Bar` + --> $DIR/two-projection-param-candidates-are-ambiguous.rs:26:5 + | +LL | needs_bar::(); + | ^^^^^^^^^^^^^^ + | + = note: cannot satisfy `T: Bar` +note: required by a bound in `needs_bar` + --> $DIR/two-projection-param-candidates-are-ambiguous.rs:23:17 + | +LL | fn needs_bar() {} + | ^^^ required by this bound in `needs_bar` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0283`.