-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Segfault on cyclic trait type parameter bounds. #8762
Comments
I guess this is "just" infinite recursion overflowing the stack:
|
@huonw Should this be an error, or should it be allowed? |
No idea; but it certainly shouldn't be infinite recursion. |
Here's a use case that currently seg-faults: pub trait Matrix
<
S: Field,
RV: VectorSpace<S>,
CV: VectorSpace<S>,
MT: Matrix<S, CV, RV, Self>
>
: Ring
{
fn transpose(&self) -> MT;
} |
It should be an error, I think. |
Why? |
Well, hm. Maybe not an error, but how could it ever be implemented? |
As usual let's look at what Haskell does:
|
This is tied in with trait reform (#5527). I'm way behind in writing up my thoughts on this. In some cases, you can detect cyclic recursion, but in some cases you cannot -- you either have to impose arbitrary limits on the kinds of trait interactions that are permitted or you just have to check (and handle gracefully) the cycle. Haskell tends to take the "impose arbitrary limits" approach (see e.g. http://www.haskell.org/ghc/docs/7.0.1/html/users_guide/type-class-extensions.html#instance-rules), though users can opt to suspend those limits. |
Note: I did not intend that as a criticism of Haskell, despite using the word "arbitrary". I described the limits as "arbitrary" because I do not see a readily explainable and intuitive way to summarize them in plain English, so they feel quite arbitrary. |
Oh right, sorry. But then the Rust examples are invalid even before being cyclic:
For the Matrix example translated as:
it does complain about a cycle.
If you mean FlexibleContexts and UndecidableInstances, I suspect those might not be entirely the same issue. In particular class cycle checking seems to be independent of them (turning on UndecidableInstances makes no difference). |
I am referring to undecidable instances and the issue is not entirely independent. In this particular case, the cycle is readily detectable, but there are other ways to induce unbounded recursion that cannot be so easily detected (hence the paterson conditions etc). |
I just ran into this issue, with a use case like the following. The intent was to have two implementors. The first one would construct instances of the second one, and the second one would construct instances of itself. See below:
In context, I wasn't trying to do anything crazy, in my humble opinion, so I wasn't really expecting it to fail, although I guess it's not surprising in hindsight. If it's feasible, I think rustc should allow this kind of construct. The above example compiles if Edit: fixed syntax and formatting, and added concrete types to the example. |
This is the same as #15477, which is fixed. I've confirmed independently that this no longer reproduces. |
Replace `expr_visitor` with `for_each_expr` This is a minor change which uses `ControlFlow` rather than a boolean. This also runs the visitor rather than returning the visitor, which results in a small readability win as well. changelog: None
boom.
Edit: HAH!
The text was updated successfully, but these errors were encountered: