Skip to content

"error: illegal recursive type" #19601

New issue

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

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

Already on GitHub? # to your account

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
# for free to join this conversation on GitHub. Already have an account? # 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