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

"error: illegal recursive type" #19601

Closed
anishathalye opened this issue Dec 6, 2014 · 7 comments
Closed

"error: illegal recursive type" #19601

anishathalye opened this issue Dec 6, 2014 · 7 comments
Labels
A-type-system Area: Type system E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added.

Comments

@anishathalye
Copy link

Is the restriction on recursive types really necessary?

It makes sense with structs, because recursive structs would mean infinite-sized structs. But with types, it seems unnecessary. After a brief discussion on the Rust IRC, someone told me that this is probably a bug.

Reduced Test Case

trait A<T> {}

trait DoesAforB<T> {}

// no way to express
// struct B<T> where B<T>: A<B<T>>;

struct B<T: DoesAforB<B<T>>>;

fn main() {}

Output

rec.rs:8:23: 8:27 error: illegal recursive type; insert an enum or struct in the cycle, if this is desired
rec.rs:8 struct B<T: DoesAforB<B<T>>>;
                               ^~~~

rustc version

rustc 0.13.0-nightly (336349c93 2014-11-17 20:37:19 +0000)

@eddyb
Copy link
Member

eddyb commented Dec 6, 2014

Even if we decide to not allow recursion, this is NOT recursion, it's referring to the same B<T>, not B<Foo<T>>.

@eddyb eddyb added the A-type-system Area: Type system label Dec 6, 2014
@anishathalye
Copy link
Author

The use case I had in mind for this would be having B<X> implementing A<B<X>> for each X, in the crate where X is defined. So it could be specific to Xs, and it would only be possible to instantiate a B<X> if A<B<X>> is implemented.

@nikomatsakis
Copy link
Contributor

This is more-or-less a dup of an existing issue I can't find right now. It's an artifact of how we translate bounds, which winds up forcing a DAG structure. It's in the process of being changed.

@milibopp
Copy link
Contributor

The following version of the code example in the OP works now:

trait A<T> {
    fn foo(&self) -> T;
}

struct B<T> where B<T>: A<B<T>> { t: T }

@mrhota
Copy link
Contributor

mrhota commented Aug 19, 2016

@anishathalye the reduced test case produces the following error message on stable:

error: parameter `T` is never used [--explain E0392]
 --> <anon>:9:10
  |>
9 |> struct B<T: DoesAforB<B<T>>>;
  |>          ^
help: consider removing `T` or using a marker such as `std::marker::PhantomData`

error: aborting due to previous error

If we change the test case so T is actually used, then the example compiles fine. Maybe this can be closed?

ping @nikomatsakis

@Mark-Simulacrum
Copy link
Member

Marking as E-neestest to permit closing this.

@Mark-Simulacrum Mark-Simulacrum added the E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. label May 11, 2017
@Mark-Simulacrum
Copy link
Member

Also going to unassign @nikomatsakis since I don't think they need to do actively do anything on this issue.

MaloJaffre added a commit to MaloJaffre/rust that referenced this issue Jun 18, 2017
Mark-Simulacrum added a commit to Mark-Simulacrum/rust that referenced this issue Jun 18, 2017
frewsxcv added a commit to frewsxcv/rust that referenced this issue Jun 18, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-type-system Area: Type system E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added.
Projects
None yet
Development

No branches or pull requests

6 participants