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

ICE: rustc stack overflow error w/ recursive types #17882

Closed
carllerche opened this issue Oct 9, 2014 · 4 comments
Closed

ICE: rustc stack overflow error w/ recursive types #17882

carllerche opened this issue Oct 9, 2014 · 4 comments
Labels
I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️

Comments

@carllerche
Copy link
Member

Given the following code:

trait Stream<T, N: Stream<T>> {
}

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

Running rustc gives the following output:

task 'rustc' has overflowed its stack
[1]    47380 illegal hardware instruction  rustc types.rs
@nikomatsakis
Copy link
Contributor

cc me

@nikomatsakis
Copy link
Contributor

this is probably a dup of some other bug. The root cause is that we put need to convert the list of bounds at the same time as processing the trait definition. As part of my branch for generalized where clauses I've changed how this works, which ought to circumvent this error -- I'm not sure what's a shorter term fix.

@mbrubeck
Copy link
Contributor

Duplicate of #15477?

@huonw huonw added the I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ label Dec 28, 2014
@huonw
Copy link
Member

huonw commented Dec 28, 2014

Closing as a dupe of #15477. Thanks for filing!

@huonw huonw closed this as completed Dec 28, 2014
lnicola pushed a commit to lnicola/rust that referenced this issue Aug 29, 2024
fix: Panic while canonicalizing erroneous projection type

Fixes rust-lang#17866

The root cause of rust-lang#17866 is quite horrifyng 😨

```rust
trait T {
    type A;
}

type Foo = <S as T>::A; // note that S isn't defined

fn main() {
    Foo {}
}
```

While inferencing alias type `Foo = <S as T>::A`;

https://github.com/rust-lang/rust-analyzer/blob/78c2bdce860dbd996a8083224d01a96660dd6a15/crates/hir-ty/src/infer.rs#L1388-L1398

the error type `S` in it is substituted by inference var in L1396 above as below;

https://github.com/rust-lang/rust-analyzer/blob/78c2bdce860dbd996a8083224d01a96660dd6a15/crates/hir-ty/src/infer/unify.rs#L866-L869

This new inference var's index is `1`, as the type inferecing procedure here previously inserted another inference var into same `InferenceTable`.

But after that, the projection type made from the above then passed to the following function;

https://github.com/rust-lang/rust-analyzer/blob/78c2bdce860dbd996a8083224d01a96660dd6a15/crates/hir-ty/src/traits.rs#L88-L96

here, a whole new `InferenceTable` is made, without any inference var and in the L94, this table calls;

https://github.com/rust-lang/rust-analyzer/blob/78c2bdce860dbd996a8083224d01a96660dd6a15/crates/hir-ty/src/infer/unify.rs#L364-L370

And while registering `AliasEq` `obligation`, this obligation contains inference var `?1` made from the previous table, but this table has only one inference var `?0` made at L365.
So, the chalk panics when we try to canonicalize that obligation to register it, because the obligation contains an inference var `?1` that the canonicalizing table doesn't have.

Currently, we are calling `InferenceTable::new()` to do some normalizing, unifying or coercing things to some targets that might contain inference var that the new table doesn't have.
I think that this is quite dangerous footgun because the inference var is just an index that does not contain the information which table does it made from, so sometimes this "foreign" index might cause panic like this case, or point at the wrong variable.

This PR mitigates such behaviour simply by inserting sufficient number of inference vars to new table to avoid such problem.
This strategy doesn't harm current r-a's intention because the inference vars that passed into new tables are just "unresolved" variables in current r-a, so this is just making sure that such "unresolved" variables exist in the new table
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️
Projects
None yet
Development

No branches or pull requests

4 participants