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

Associated types, impl traits and closures; oh my, an ICE. #63154

Open
james-darkfox opened this issue Jul 31, 2019 · 6 comments

Comments

@james-darkfox
Copy link
Contributor

commented Jul 31, 2019

While experimenting with some code I hit this ICE. Interestingly, when running cargo test a second time, it magically works - skipping the error. Also, cargo miri test works fine too.

I'm on a slightly older nightly because some rustup components are missing on the latest. https://play.rust-lang.org confirms the ICE in both its stable and nightly.

#![allow(dead_code)]

trait HasAssocType {
    type Inner;
}

impl HasAssocType for () {
    type Inner = ();
}

trait Tr<I, T>: Fn(I) -> Option<T> {}
impl<I, T, Q: Fn(I) -> Option<T>> Tr<I, T> for Q {}

fn f<T: HasAssocType>() -> impl Tr<T, T::Inner> {
    |_| None
}

fn g<T, Y>(f: impl Tr<T, Y>) -> impl Tr<T, Y> {
    f
}

fn h() {
    g(f())(());
}
~ $ rustc --edition 2018 mir-ice.rs --test
error: internal compiler error: broken MIR in DefId(0:32 ~ mir_ice[317d]::h[0]) (Terminator { source_info: SourceInfo { span: mir-ice.rs:23:5: 23:11, scope: scope[0] }, kind: _3 = const g::<(), <() as HasAssocType>::Inner, impl Tr<(), <() as HasAssocType>::Inner>>(move _4) -> [return: bb3, unwind: bb4] }): call dest mismatch (impl Tr<(), <() as HasAssocType>::Inner> <- impl Tr<(), ()>): NoSolution
  --> mir-ice.rs:22:1
   |
22 | / fn h() {
23 | |     g(f())(());
24 | | }
   | |_^

error: internal compiler error: broken MIR in DefId(0:32 ~ mir_ice[317d]::h[0]) (_2 = &_3): bad assignment (&impl Tr<(), ()> = &impl Tr<(), <() as HasAssocType>::Inner>): NoSolution
  --> mir-ice.rs:23:5
   |
23 |     g(f())(());
   |     ^^^^^^

thread 'rustc' panicked at 'no errors encountered even though `delay_span_bug` issued', src/librustc_errors/lib.rs:362:17
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.

error: internal compiler error: unexpected panic

note: the compiler unexpectedly panicked. this is a bug.

note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports

note: rustc 1.37.0-nightly (1d9981f04 2019-06-20) running on x86_64-unknown-linux-gnu

@james-darkfox james-darkfox changed the title [MIR] [ICE] Associated types, traits, closures; oh my, an ICE. [MIR] [ICE] Associated types, impl traits and closures; oh my, an ICE. Jul 31, 2019

@Centril

This comment has been minimized.

Copy link
Member

commented Jul 31, 2019

Slight reduction:

#![allow(dead_code)]

trait HasAssocType {
    type Inner;
}

impl HasAssocType for () {
    type Inner = ();
}

trait Tr<I, T>
where
    Self: Fn(I),
{
}

impl<I, T, Q> Tr<I, T> for Q where Q: Fn(I) {}

fn f<T>() -> impl Tr<T, T::Inner>
where
    T: HasAssocType,
{
    |_| ()
}

fn g<T, Y, F>(f: F) -> impl Tr<T, Y>
where
    F: Tr<T, Y>,
{
    f
}

fn h() {
    g(f())(());
}

@nagisa nagisa added P-high and removed I-nominated labels Aug 1, 2019

@nagisa

This comment has been minimized.

Copy link
Contributor

commented Aug 1, 2019

Marking P-high. The fact that miri works and a regular compile does not suggests a missing call to normalize() somewhere, which would be fairly easy to fix once it is found.

@james-darkfox

This comment has been minimized.

Copy link
Contributor Author

commented Aug 1, 2019

@nagisa Not sure if it is related but I'm writing a parser combinator library (quite similar to nom 5.0), and when I'm not getting the error described above, I'm getting another with one of my test cases.

This requires me to boost the #![type_length_limit = "N"] to as suggested after a few iterations 12,792,521 and the builds are getting unusually slow. A common factor for these issues is that cargo miri test always works. Does the compiler not like combinators?

I'm not ready to release this code yet and I haven't reduced the second issue like the first.

Example depth of these combinators, can obviously get deeper. Along these lines. All functions but the second arguments to map return functions. (snippet of IRCv3 message-tags extension)

// snip
            opt(tuple!(
                tag("@"),
                map(
                    take_while1(none_of(" ".chars())),
                    delimited(
                        tag(";"),
                        tuple!(
                            opt(tag("+")),
                            opt(tuple(host, tag("/"))),
                            take_while(alt2!(letter, number, tag("-"))),
                            opt(tuple(
                                tag("="),
                                take_while(none_of("\0\0xa\0x0d; ".chars()))
                            ))
                        )
                    )
                ),
                space
            )),
// snip
error: reached the type-length limit while instantiating `alt::<&str, std::option::Option<...mnom/src/lib.rs:169:23: 169:40]>`
   --> omnom/src/lib.rs:122:1
    |
122 | / pub fn alt<I, T>(f: impl Omnom<I, T>, g: impl Omnom<I, T>) -> impl Omnom<I, T> {
123 | |     move |i| f(i).or_else(|(i, _)| g(i))
124 | | }
    | |_^
    |
    = note: consider adding a `#![type_length_limit="2683000"]` attribute to your crate

@james-darkfox james-darkfox changed the title [MIR] [ICE] Associated types, impl traits and closures; oh my, an ICE. Associated types, impl traits and closures; oh my, an ICE. Aug 1, 2019

@james-darkfox

This comment has been minimized.

Copy link
Contributor Author

commented Aug 3, 2019

HA. Okay this gets more weird. Moving fn h out to a test, everything else works except... Rust suddenly forgets how to make trivial equivalences.

src/lib.rs as above with h stripped into tests/test.rs. cargo test. Due to the requirement of a second compilation unit, I cannot reproduce this one on the playground.

Oh and this one doesn't get to "just work" with miri.

error[E0271]: type mismatch resolving `<() as weird_ice::HasAssocType>::Inner == <() as weird_ice::HasAssocType>::Inner`
 --> tests/test.rs:4:7
  |
4 |     g(f())(());
  |       ^^^ expected (), found associated type
  |
  = note: expected type `()`
             found type `<() as weird_ice::HasAssocType>::Inner`
@james-darkfox

This comment has been minimized.

Copy link
Contributor Author

commented Aug 3, 2019

Workaround. Passes the ICE and the type mismatch. Still requires #![type_length_limit="17557366"] in my real tests.

fn f<T: HasAssocType<Inner = Y>, Y>() -> impl Tr<T, Y> { /* .. */ }
@james-darkfox

This comment has been minimized.

Copy link
Contributor Author

commented Aug 6, 2019

@nagisa Using cargo rustc --test=irc -- -Zself-profile and summarize summarize irc-*.

Without the workaround. The IRC test builds in 8.54s on the first pass (ICE) (summary) plus 2.8s on the second (no ICE). (summary).

With the workaround. The test builds in 8.49s. (summary).

The first and third both spend 61% of the time (5 seconds) on normalize_ty_after_erasing_regions, followed by collect_and_partition_mono_items with 11-12% of the time (~980ms). The second pass to the first flips these but they're still at the top with 33% (920ms) and 31% (857ms) respectively.

All other tests (much simpler) compile immediately.

Edit: No idea why the first even built in the second pass as it should have failed with the type mismatch issue... shrugs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants
You can’t perform that action at this time.