Skip to content

Commit

Permalink
Add a couple random projection tests
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Feb 10, 2023
1 parent d1ac43a commit 9790d6f
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// compile-flags: -Ztrait-solver=next
// check-pass

trait Foo {
type Assoc;
}

trait Bar {}

impl<T> Foo for T {
type Assoc = i32;
}

impl<T> Bar for T where T: Foo<Assoc = i32> {}

fn require_bar<T: Bar>() {}

fn foo<T: Foo>() {
// Unlike the classic solver, `<T as Foo>::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::<T>();
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// compile-flags: -Ztrait-solver=next

// When we're solving `<T as Foo>::Assoc = i32`, we actually first solve
// `<T as Foo>::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<T> Bar for T where T: Foo<Assoc = i32> {}

fn needs_bar<T: Bar>() {}

fn foo<T: Foo<Assoc = i32> + Foo<Assoc = u32>>() {
needs_bar::<T>();
//~^ ERROR type annotations needed: cannot satisfy `T: Bar`
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -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::<T>();
| ^^^^^^^^^^^^^^
|
= 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<T: Bar>() {}
| ^^^ required by this bound in `needs_bar`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0283`.

0 comments on commit 9790d6f

Please sign in to comment.