Skip to content

Extra RPIT bound leads to TAIT cycle error E0391 #108151

Closed as not planned
Closed as not planned
@QuineDot

Description

@QuineDot

I tried this code:

#![feature(type_alias_impl_trait)]

// Motivation for having a TAIT: Need to convey that the iterator's item type
// is the same as the other associated type in `-> impl SelfReferencingAssocs`
pub trait Trait {}
pub trait SelfReferencingAssocs {
    type NotAlwaysNameable: Trait;
    type Iter: Iterator<Item = Self::NotAlwaysNameable>;
}

pub type Alias = impl Trait;
impl Trait for () {}
impl SelfReferencingAssocs for () {
    type NotAlwaysNameable = Alias;
    type Iter = std::vec::IntoIter<Self::NotAlwaysNameable>;
}

fn _some_defining_use() -> Alias {}

pub fn f()
-> impl SelfReferencingAssocs<
    NotAlwaysNameable = Alias,
    Iter = impl Send + Iterator<Item = Alias>,
>
{
}

I expected to see this happen: compiles like it does if you remove Send:

 pub fn f()
 -> impl SelfReferencingAssocs<
     NotAlwaysNameable = Alias,
-    Iter = impl Send + Iterator<Item = Alias>,
+    Iter = impl Iterator<Item = Alias>,
 >

Instead, this happened:

error[[E0391]](https://doc.rust-lang.org/nightly/error_codes/E0391.html): cycle detected when computing type of `Alias::{opaque#0}`
  --> src/lib.rs:11:18
   |
11 | pub type Alias = impl Trait;
   |                  ^^^^^^^^^^
   |
note: ...which requires type-checking `f`...
  --> src/lib.rs:21:4
   |
21 |   -> impl SelfReferencingAssocs<
   |  ____^
22 | |     NotAlwaysNameable = Alias,
23 | |     Iter = impl Send + Iterator<Item = Alias>,
24 | | >
   | |_^
   = note: ...which requires evaluating trait selection obligation `<() as SelfReferencingAssocs>::Iter == f::{opaque#0}::{opaque#0}`...
   = note: ...which again requires computing type of `Alias::{opaque#0}`, completing the cycle
note: cycle used when checking item types in top-level module
  --> src/lib.rs:1:1
   |
1  | / #![feature(type_alias_impl_trait)]
2  | |
3  | | // Motivation for having a TAIT: Need to convey that the iterator's item type
4  | | // is the same as the other associated type in `-> impl SelfReferencingAssocs`
...  |
25 | | {
26 | | }
   | |_^

Additional notes

A workaround is to isolate the defining use. Perhaps this deserves a diagnostic issue to suggest such isolation in the face of cycle errors?

Motivated by this URLO thread. Note how not unifying the two associated types leads to an opaque_hidden_inferred_bound lint warning. (The lint is not necessarily satisfiable on stable and I've encouraged the poster to file a separate issue about that.)

Meta

Playground nightly 1.69.0-nightly (2023-02-15 2d14db321b043ffc579a)

@rustbot +labels A-impl-trait F-type_alias_impl-trait requires-nightly

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions