Skip to content

Cycle error when combining RPITIT, generic bounds equality, and lifetimes #122019

Closed
@jhpratt

Description

@jhpratt

Minimal example (playground):

pub trait Foo<'a> {
    type Assoc;

    fn demo<T>(other: T) -> impl Foo<'a, Assoc = Self::Assoc>
    where
        T: Foo<'a, Assoc = core::convert::Infallible>;
}

outputs

error[E0391]: cycle detected when computing generics of `Foo::demo::{opaque#0}`
 --> src/lib.rs:4:29
  |
4 |     fn demo<T>(other: T) -> impl Foo<'a, Assoc = Self::Assoc>
  |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
note: ...which requires computing generics of `Foo::demo`...
 --> src/lib.rs:4:5
  |
4 | /     fn demo<T>(other: T) -> impl Foo<'a, Assoc = Self::Assoc>
5 | |     where
6 | |         T: Foo<'a, Assoc = core::convert::Infallible>;
  | |______________________________________________________^
note: ...which requires looking up a named region...
 --> src/lib.rs:4:5
  |
4 | /     fn demo<T>(other: T) -> impl Foo<'a, Assoc = Self::Assoc>
5 | |     where
6 | |         T: Foo<'a, Assoc = core::convert::Infallible>;
  | |______________________________________________________^
note: ...which requires resolving lifetimes...
 --> src/lib.rs:4:5
  |
4 | /     fn demo<T>(other: T) -> impl Foo<'a, Assoc = Self::Assoc>
5 | |     where
6 | |         T: Foo<'a, Assoc = core::convert::Infallible>;
  | |______________________________________________________^
note: ...which requires collecting associated items of `Foo`...
 --> src/lib.rs:1:1
  |
1 | pub trait Foo<'a> {
  | ^^^^^^^^^^^^^^^^^
note: ...which requires collecting associated items or fields of `Foo`...
 --> src/lib.rs:1:1
  |
1 | pub trait Foo<'a> {
  | ^^^^^^^^^^^^^^^^^
note: ...which requires creating associated items for impl trait in trait returned by `Foo::demo`...
 --> src/lib.rs:4:5
  |
4 | /     fn demo<T>(other: T) -> impl Foo<'a, Assoc = Self::Assoc>
5 | |     where
6 | |         T: Foo<'a, Assoc = core::convert::Infallible>;
  | |______________________________________________________^
note: ...which requires creates the associated item corresponding to the opaque type `Foo::demo::{opaque#0}`...
 --> src/lib.rs:4:29
  |
4 |     fn demo<T>(other: T) -> impl Foo<'a, Assoc = Self::Assoc>
  |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  = note: ...which again requires computing generics of `Foo::demo::{opaque#0}`, completing the cycle
note: cycle used when collecting item types in top-level module
 --> src/lib.rs:1:1
  |
1 | / pub trait Foo<'a> {
2 | |     type Assoc;
3 | |
4 | |     fn demo<T>(other: T) -> impl Foo<'a, Assoc = Self::Assoc>
5 | |     where
6 | |         T: Foo<'a, Assoc = core::convert::Infallible>;
7 | | }
  | |_^
  = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information

In the example, the implementation is irrelevant. The definition itself is the cause for error. Removing either the lifetime or the Assoc = Infallible results in successful compilation as expected.

I don't understand why it's causing a cycle error, but intuitively I don't see why it should be. Introducing an InfallibleFoo trait with a blanket implementation is a possible workaround and what I'll be doing while the issue exists.

Metadata

Metadata

Labels

C-bugCategory: This is a bug.F-return_position_impl_trait_in_trait`#![feature(return_position_impl_trait_in_trait)]`I-cycleIssue: A query cycle occurred while none was expectedT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions