Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recursive traits should be allowed when boxing #17893

Open
carllerche opened this issue Oct 9, 2014 · 5 comments
Open

Recursive traits should be allowed when boxing #17893

carllerche opened this issue Oct 9, 2014 · 5 comments
Labels
A-trait-system Area: Trait system A-type-system Area: Type system C-feature-request Category: A feature request, i.e: not implemented / a PR. T-lang Relevant to the language team, which will review and decide on the PR/issue.

Comments

@carllerche
Copy link
Member

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");
}
@aturon
Copy link
Member

aturon commented Oct 9, 2014

cc @nikomatsakis

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

@steveklabnik steveklabnik added A-type-system Area: Type system A-trait-system Area: Trait system labels Jan 27, 2015
@steveklabnik
Copy link
Member

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

@steveklabnik steveklabnik reopened this Feb 2, 2016
@Mark-Simulacrum Mark-Simulacrum added C-bug Category: This is a bug. T-lang Relevant to the language team, which will review and decide on the PR/issue. C-feature-request Category: A feature request, i.e: not implemented / a PR. and removed C-bug Category: This is a bug. labels Jul 22, 2017
@steveklabnik
Copy link
Member

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

@dimpolo
Copy link
Contributor

dimpolo commented Jan 26, 2022

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.

@dimpolo
Copy link
Contributor

dimpolo commented Sep 18, 2023

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> {}

lnicola pushed a commit to lnicola/rust that referenced this issue Aug 29, 2024
fix: Panic while hovering associated function with type annotation on generic param that not inherited from its container type

Fixes rust-lang#17871

We call `generic_args_sans_defaults` here;

https://github.com/rust-lang/rust-analyzer/blob/64a140527b383e3a2fe95908881624fc5374c60c/crates/hir-ty/src/display.rs#L1021-L1034

but the following substitution inside that function panic in rust-lang#17871;

https://github.com/rust-lang/rust-analyzer/blob/64a140527b383e3a2fe95908881624fc5374c60c/crates/hir-ty/src/display.rs#L1468

it's because the `Binders.binder` inside `default_parameters` has a same length with the generics of the function we are hovering on, but the generics of it is split into two, `fn_params` and `parent_params`.
Because of this, it may panic if the function has one or more default parameters and both `fn_params` and `parent_params` are non-empty, like the case in the title of this PR.

So, we must call `generic_args_sans_default` first and then split it into `fn_params` and `parent_params`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-trait-system Area: Trait system A-type-system Area: Type system C-feature-request Category: A feature request, i.e: not implemented / a PR. T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

5 participants