Skip to content

Recursive traits should be allowed when boxing #17893

Open

Description

@carllerche

The following should work:

trait Future<T> {
    fn take(self) -> T;
}

trait Stream<T>: Future<Option<(T, Box<Stream<T>>)>> {
}

pub fn main() {
    println!("zomg");
}

Activity

  1. aturon commented on Oct 9, 2014

    @aturon
    Contributor

    cc @nikomatsakis

    Currently gets the error "error: illegal recursive type; insert an enum or struct in the cycle, if this is desired"

  2. steveklabnik commented on Feb 2, 2016

    @steveklabnik
    Contributor

    Triage: current error:

    hello.rs:5:40: 5:49 error: unsupported cyclic reference between types/traits detected [E0391]
    hello.rs:5 trait Stream<T>: Future<Option<(T, Box<Stream<T>>)>> {
                                                      ^~~~~~~~~
    hello.rs:5:40: 5:49 help: run `rustc --explain E0391` to see a detailed explanation
    note: the cycle begins when computing the supertraits of `Stream`...
    note: ...which then again requires computing the supertraits of `Stream`, completing the cycle.
    hello.rs:5:40: 5:49 error: unsupported cyclic reference between types/traits detected [E0391]
    hello.rs:5 trait Stream<T>: Future<Option<(T, Box<Stream<T>>)>> {
                                                      ^~~~~~~~~
    hello.rs:5:40: 5:49 help: run `rustc --explain E0391` to see a detailed explanation
    note: the cycle begins when computing the supertraits of `Stream`...
    note: ...which then again requires computing the supertraits of `Stream`, completing the cycle.
    error: aborting due to 2 previous errors
    
    
  3. added
    C-bugCategory: This is a bug.
    T-langRelevant to the language team
    C-feature-requestCategory: A feature request, i.e: not implemented / a PR.
    and removed
    C-bugCategory: This is a bug.
    on Jul 22, 2017
  4. steveklabnik commented on Sep 24, 2018

    @steveklabnik
    Contributor

    New error:

    error[E0391]: cycle detected when computing the supertraits of `Stream`
     --> src/main.rs:5:1
      |
    5 | trait Stream<T>: Future<Option<(T, Box<Stream<T>>)>> {
      | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      |
      = note: ...which again requires computing the supertraits of `Stream`, completing the cycle
    
    
  5. dimpolo commented on Jan 26, 2022

    @dimpolo
    Contributor

    I would also like to see this.
    My use case is a custom Rc implementation with cycle detection, specifically designed for trait objects.
    Code would look something like this:

    use core::marker::PhantomData;
    
    // API:
    
    pub struct Rc<Dyn: ?Sized + Trace<Dyn>>{
        ptr_and_stuff: PhantomData<Dyn>,
    }
    
    pub trait Trace<Dyn: Trace<Dyn> + ?Sized> {
        /// Give the tracer access to other Rc<Dyn> that we own.
        /// Their `Dyn` must be the same as ours. 
        fn trace(&self, tracer: fn(&Rc<Dyn>));
    }
    
    // user code:
    
    trait MyTrait: Trace<dyn MyTrait>{}
    
    struct MyStruct{
        field: Rc<dyn MyTrait>,
    }
    
    impl Trace<dyn MyTrait> for MyStruct {
        fn trace(&self, tracer: fn(&Rc<dyn MyTrait>)){
            tracer(&self.field);
        }
    }

    The hacky workarounds found on stackoverflow sadly don't work.

  6. dimpolo commented on Sep 18, 2023

    @dimpolo
    Contributor

    Could someone comment if this has a chance to get accepted in the future?
    Is the problem that dyn Trait doesn't always implement Trait #88904?
    Will #107374 -Ztrait-solver=next help?
    Does this require coinduction?

    MRE:

    trait Foo<T: ?Sized> {}
    trait Bar: Foo<dyn Bar> {}
  7. added a commit that references this issue on Aug 29, 2024
  8. added
    T-typesRelevant to the types team, which will review and decide on the PR/issue.
    on Dec 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-trait-systemArea: Trait systemA-type-systemArea: Type systemC-feature-requestCategory: A feature request, i.e: not implemented / a PR.T-langRelevant to the language teamT-typesRelevant to the types 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