Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 1 addition & 9 deletions compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,18 +280,10 @@ where
// We currently only consider a cycle coinductive if it steps
// into a where-clause of a coinductive trait.
CurrentGoalKind::CoinductiveTrait => PathKind::Coinductive,
// While normalizing via an impl does step into a where-clause of
// an impl, accessing the associated item immediately steps out of
// it again. This means cycles/recursive calls are not guarded
// by impls used for normalization.
//
// See tests/ui/traits/next-solver/cycles/normalizes-to-is-not-productive.rs
// for how this can go wrong.
CurrentGoalKind::NormalizesTo => PathKind::Inductive,
// We probably want to make all traits coinductive in the future,
// so we treat cycles involving where-clauses of not-yet coinductive
// traits as ambiguous for now.
CurrentGoalKind::Misc => PathKind::Unknown,
CurrentGoalKind::Misc | CurrentGoalKind::NormalizesTo => PathKind::Unknown,
},
// Relating types is always unproductive. If we were to map proof trees to
// corecursive functions as explained in #136824, relating types never
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ trait Foo {
trait Baz {}

impl<'a, T> Foo for &'a T //~ ERROR not all trait items implemented, missing: `Item`
//~| ERROR the trait bound `&'a T: Foo` is not satisfied
//~| ERROR type annotations needed: cannot satisfy `&'a T: Foo`
where
Self::Item: 'a, //~ ERROR the trait bound `&'a T: Foo` is not satisfied
Self::Item: 'a,
{
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,37 +10,26 @@ LL | | where
LL | | Self::Item: 'a,
| |___________________^ missing `Item` in implementation

error[E0277]: the trait bound `&'a T: Foo` is not satisfied
error[E0283]: type annotations needed: cannot satisfy `&'a T: Foo`
--> $DIR/next-solver-region-resolution.rs:12:21
|
LL | impl<'a, T> Foo for &'a T
| ^^^^^ the trait `Foo` is not implemented for `&'a T`
| ^^^^^
|
help: the trait `Foo` is not implemented for `&'a _`
but it is implemented for `&_`
note: multiple `impl`s satisfying `&'a T: Foo` found
--> $DIR/next-solver-region-resolution.rs:12:1
|
LL | / impl<'a, T> Foo for &'a T
LL | |
LL | | where
LL | | Self::Item: 'a,
| |___________________^

error[E0277]: the trait bound `&'a T: Foo` is not satisfied
--> $DIR/next-solver-region-resolution.rs:15:17
|
LL | Self::Item: 'a,
| ^^ the trait `Foo` is not implemented for `&'a T`
|
help: the trait `Foo` is not implemented for `&'a _`
but it is implemented for `&_`
--> $DIR/next-solver-region-resolution.rs:12:1
|
LL | / impl<'a, T> Foo for &'a T
...
LL | / impl<'a, T> Foo for &T
LL | |
LL | | where
LL | | Self::Item: 'a,
| |___________________^
LL | | Self::Item: Baz,
| |____________________^

error[E0046]: not all trait items implemented, missing: `Item`
--> $DIR/next-solver-region-resolution.rs:19:1
Expand All @@ -63,7 +52,7 @@ LL | | where
LL | | Self::Item: Baz,
| |____________________^

error: aborting due to 5 previous errors
error: aborting due to 4 previous errors

Some errors have detailed explanations: E0046, E0277.
Some errors have detailed explanations: E0046, E0283.
For more information about an error, try `rustc --explain E0046`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
error[E0283]: type annotations needed: cannot satisfy `<Vec<T> as IntoIterator>::IntoIter: Iterator`
--> $DIR/normalizes-to-is-not-productive-2.rs:21:41
|
LL | <Vec<T> as IntoIterator>::IntoIter: Iterator,
| ^^^^^^^^
|
= note: cannot satisfy `<Vec<T> as IntoIterator>::IntoIter: Iterator`

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0283`.
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
//@ revisions: current next
//@ ignore-compare-mode-next-solver (explicit revisions)
//@[next] compile-flags: -Znext-solver
//@ check-pass
//@[current] check-pass

// Regression test for trait-system-refactor-initiative#176.
// Test from trait-system-refactor-initiative#176.
//
// Normalizing `<Vec<T> as IntoIterator>::IntoIter` has two candidates
// inside of the function:
Expand All @@ -13,11 +13,13 @@
// - where-clause requires `<Vec<T> as IntoIterator>::IntoIter eq Vec<T>`
// - normalize `<Vec<T> as IntoIterator>::IntoIter` again, cycle
//
// We need to treat this cycle as an error to be able to use the actual impl.
// The blanket impl is unfortunately also a productive cycle, so we have to
// break this code, see trait-system-refactor-initiative#273

fn test<T>()
where
<Vec<T> as IntoIterator>::IntoIter: Iterator,
//[next]~^ ERROR type annotations needed: cannot satisfy `<Vec<T> as IntoIterator>::IntoIter: Iterator`
{
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
//@ ignore-compare-mode-next-solver (explicit)
//@ compile-flags: -Znext-solver

// Make sure that stepping into impl where-clauses of `NormalizesTo`
// goals is unproductive. This must not compile, see the inline
// comments.
// A test for the cycle handling when stepping into where-clauses of `NormalizesTo`.
// Whether stepping into where-clauses is productive depends on how they are used.
//
// In this concrete test, the cycle must not be productive.

trait Bound {
fn method();
Expand All @@ -30,7 +31,7 @@ fn impls_bound<T: Bound>() {

// The where-clause requires `Foo: Trait<T>` to hold to be wf.
// If stepping into where-clauses during normalization is considered
// to be productive, this would be the case:
// to be productive here, this would be the case:
//
// - `Foo: Trait<T>`
// - via blanket impls, requires `Foo: Bound`
Expand All @@ -40,12 +41,13 @@ fn impls_bound<T: Bound>() {
fn generic<T>()
where
<Foo as Trait<T>>::Assoc: Bound,
//~^ ERROR the trait bound `Foo: Bound` is not satisfied
//~^ ERROR overflow evaluating the requirement `<Foo as Trait<T>>::Assoc: Bound`
//~| ERROR overflow evaluating whether `<Foo as Trait<T>>::Assoc` is well-formed
{
// Requires proving `Foo: Bound` by normalizing
// `<Foo as Trait<T>>::Assoc` to `Foo`.
impls_bound::<Foo>();
//~^ ERROR the trait bound `Foo: Bound` is not satisfied
//~^ ERROR overflow evaluating the requirement `Foo: Bound`
}
fn main() {
// Requires proving `<Foo as Trait<u32>>::Assoc: Bound`.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,56 +1,27 @@
error[E0277]: the trait bound `Foo: Bound` is not satisfied
--> $DIR/normalizes-to-is-not-productive.rs:42:31
error[E0275]: overflow evaluating the requirement `<Foo as Trait<T>>::Assoc: Bound`
--> $DIR/normalizes-to-is-not-productive.rs:43:31
|
LL | <Foo as Trait<T>>::Assoc: Bound,
| ^^^^^ unsatisfied trait bound
|
help: the trait `Bound` is not implemented for `Foo`
--> $DIR/normalizes-to-is-not-productive.rs:18:1
|
LL | struct Foo;
| ^^^^^^^^^^
help: the trait `Bound` is implemented for `u32`
--> $DIR/normalizes-to-is-not-productive.rs:11:1
|
LL | impl Bound for u32 {
| ^^^^^^^^^^^^^^^^^^
note: required for `Foo` to implement `Trait<T>`
--> $DIR/normalizes-to-is-not-productive.rs:23:19
|
LL | impl<T: Bound, U> Trait<U> for T {
| ----- ^^^^^^^^ ^
| |
| unsatisfied trait bound introduced here
note: required by a bound in `Bound`
--> $DIR/normalizes-to-is-not-productive.rs:8:1
| ^^^^^

error[E0275]: overflow evaluating whether `<Foo as Trait<T>>::Assoc` is well-formed
--> $DIR/normalizes-to-is-not-productive.rs:43:31
|
LL | / trait Bound {
LL | | fn method();
LL | | }
| |_^ required by this bound in `Bound`
LL | <Foo as Trait<T>>::Assoc: Bound,
| ^^^^^

error[E0277]: the trait bound `Foo: Bound` is not satisfied
--> $DIR/normalizes-to-is-not-productive.rs:47:19
error[E0275]: overflow evaluating the requirement `Foo: Bound`
--> $DIR/normalizes-to-is-not-productive.rs:49:19
|
LL | impls_bound::<Foo>();
| ^^^ unsatisfied trait bound
|
help: the trait `Bound` is not implemented for `Foo`
--> $DIR/normalizes-to-is-not-productive.rs:18:1
|
LL | struct Foo;
| ^^^^^^^^^^
help: the trait `Bound` is implemented for `u32`
--> $DIR/normalizes-to-is-not-productive.rs:11:1
| ^^^
|
LL | impl Bound for u32 {
| ^^^^^^^^^^^^^^^^^^
note: required by a bound in `impls_bound`
--> $DIR/normalizes-to-is-not-productive.rs:27:19
--> $DIR/normalizes-to-is-not-productive.rs:28:19
|
LL | fn impls_bound<T: Bound>() {
| ^^^^^ required by this bound in `impls_bound`

error: aborting due to 2 previous errors
error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0277`.
For more information about this error, try `rustc --explain E0275`.
Loading