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: failed to get layout #43132

Closed
remram44 opened this Issue Jul 9, 2017 · 24 comments

Comments

Projects
None yet
9 participants
@remram44
Copy link
Contributor

remram44 commented Jul 9, 2017

   Compiling rs-web-tk v0.1.0 (file:///Users/remram/Documents/programming/rs-web-tk)
error: internal compiler error: src/librustc_trans/context.rs:739: failed to get layout for `&mut futures::future::join::MaybeDone<tk_listen::Listen<futures::stream::Map<tk_listen::SleepOnError<tokio_core::net::Incoming>, [closure@src/main.rs:85:14: 136:10 sender:&std::sync::Arc<futures_mpsc::Sender<std::string::String>>, outsockets:&std::sync::Arc<std::sync::Mutex<(std::collections::HashMap<i32, tk_bufstream::WriteFramed<tokio_core::net::TcpStream, tk_http::websocket::ServerCodec>>, i32)>>, cfg:&std::sync::Arc<tk_http::server::Config>, h1:&tokio_core::reactor::Handle]>>>`: the type `futures::future::join::MaybeDone<tk_listen::Listen<futures::stream::Map<tk_listen::SleepOnError<tokio_core::net::Incoming>, [closure@src/main.rs:85:14: 136:10 sender:&std::sync::Arc<futures_mpsc::Sender<std::string::String>>, outsockets:&std::sync::Arc<std::sync::Mutex<(std::collections::HashMap<i32, tk_bufstream::WriteFramed<tokio_core::net::TcpStream, tk_http::websocket::ServerCodec>>, i32)>>, cfg:&std::sync::Arc<tk_http::server::Config>, h1:&tokio_core::reactor::Handle]>>>` has an unknown layout

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.20.0-nightly (720c596ec 2017-07-08) running on x86_64-apple-darwin

note: run with `RUST_BACKTRACE=1` for a backtrace

thread 'rustc' panicked at 'Box<Any>', src/librustc_errors/lib.rs:489:8
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
stack backtrace:
   0: std::sys::imp::backtrace::tracing::imp::unwind_backtrace
   1: std::panicking::default_hook::{{closure}}
   2: std::panicking::default_hook
   3: std::panicking::rust_panic_with_hook
   4: std::panicking::begin_panic_new
   5: rustc_errors::Handler::bug
   6: rustc::session::opt_span_bug_fmt::{{closure}}
   7: rustc::session::opt_span_bug_fmt
   8: rustc::session::bug_fmt
   9: <&'a rustc_trans::context::SharedCrateContext<'a, 'tcx> as rustc::ty::layout::LayoutTyper<'tcx>>::layout_of
  10: rustc_trans::abi::FnType::unadjusted::{{closure}}
  11: rustc_trans::abi::FnType::unadjusted
  12: rustc_trans::declare::declare_fn
  13: rustc_trans::trans_item::TransItem::predefine
  14: rustc_trans::base::trans_crate
  15: rustc_driver::driver::phase_4_translate_to_llvm
  16: rustc_driver::driver::compile_input::{{closure}}
  17: rustc_driver::driver::phase_3_run_analysis_passes::{{closure}}
  18: rustc_driver::driver::phase_3_run_analysis_passes
  19: rustc_driver::driver::compile_input
  20: rustc_driver::run_compiler

error: Could not compile `rs-web-tk`.

Code: https://gitlab.com/remram44/rs-web/blob/bf5066037ffb627c98b4988ff7d46b054ce33e40/src/main.rs#L92

Using versions (similar crash; logs):
rustc 1.20.0-nightly (720c596 2017-07-08)
rustc 1.18.0 (03fc9d6 2017-06-06)

I don't know too much about the compiler internals, but a bug search for "layout_of" didn't bring up anything that seemed relevant. So here you go.

Seems similar to #37096 but I'm not using impl Trait?

@est31

This comment has been minimized.

Copy link
Contributor

est31 commented Jul 9, 2017

Minimized a bit (52 lines):

(expand)
extern crate futures;
extern crate futures_mpsc;
extern crate tk_http;
extern crate tk_listen;
extern crate tokio_core;

use std::sync::Arc;

use futures::{Future, Sink, Stream};
use futures::future::FutureResult;
use futures::stream::empty as empty_stream;
use tokio_core::reactor::Core;
use tk_http::server::buffered::{Request, BufferedDispatcher};
use tk_http::server::{Encoder, EncoderDone, Config, Proto, Error};
use tk_listen::ListenExt;

use tokio_core::net::TcpStream;
use std::net::SocketAddr;

fn http<S>(_: Request, _: Encoder<S>)
    -> FutureResult<EncoderDone<S>, Error>
{
    unimplemented!()
}

fn main() {
    let h = Core::new().unwrap().handle();

    let (sender, receiver) = futures_mpsc::channel::<()>(1);
    let sender = Arc::new(sender);

    let _ = empty_stream::<(TcpStream, SocketAddr), ()>()
        .map(|(socket, addr)| {
            let sender = sender.clone();
            Proto::new(socket, &Config::new().done(),
                BufferedDispatcher::new_with_websockets(addr, &h,
                    http,
                    move |_, _| {
                        let sender = (*sender).clone();
                        futures::future::ok(()).and_then(move |_| {
                            empty_stream::<(), String>().fold(sender, |sender, _| {
                                sender.send(()).map_err(|_| "")
                            })
                        })
                        .then(|_| Ok(()))
                    }),
                &h)
            .then(|_| Ok(()))
        })
        .listen(1000)
        .join(receiver.for_each(|_| Ok(())));
}
@alexcrichton

This comment has been minimized.

Copy link
Member

alexcrichton commented Jul 10, 2017

This showed up in the futures crate's test suite as well

@alexcrichton

This comment has been minimized.

Copy link
Member

alexcrichton commented Jul 10, 2017

A smaller version of what I believe is the same ICE:

extern crate futures;

use futures::{Future, Stream, Sink};
use futures::stream::iter;

fn foo<T>() -> T {
    loop {}
}

fn main() {
    iter(foo::<std::iter::Cloned<std::slice::Iter<i32>>>().map(Ok))
        .forward(
            foo::<Box<Sink<SinkItem = i32, SinkError = ()>>>()
        )
        .join(
            foo::<Box<Stream<Item = i32, Error = ()>>>()
                .for_each(|_| Ok(()))
        );
}
@est31

This comment has been minimized.

Copy link
Contributor

est31 commented Jul 10, 2017

@alexcrichton yeah now that I look at it is that on stable OP's example has a different ICE error than on nightly, very alike to #40274, while the one on nightly matches your example.

@alexcrichton alexcrichton added the I-ICE label Jul 10, 2017

@est31

This comment has been minimized.

Copy link
Contributor

est31 commented Jul 10, 2017

Bisected the nightly ICE using bisect-rust to #42840 (9b85e1c) -- cc @arielb1 @nikomatsakis

@arielb1 arielb1 self-assigned this Jul 12, 2017

@arielb1

This comment has been minimized.

Copy link
Contributor

arielb1 commented Jul 13, 2017

Looks like the projection cache is dropping normalization obligations on the floor at https://github.com/rust-lang/rust/blob/master/src/librustc/traits/project.rs#L1392:

fn opt_normalize_projection_type<'a, 'b, 'gcx, 'tcx>( //
// ...
            let result =             // ...
                Normalized {
                    value: normalized_ty,
                    obligations,
                } // ...
            infcx.projection_cache.borrow_mut()
                                  .complete(projection_ty, &result, cacheable);
            Some(result)
// ...
    fn complete(&mut self,
                key: ty::ProjectionTy<'tcx>,
                value: &NormalizedTy<'tcx>,
                cacheable: bool) {
        let fresh_key = if cacheable {
            debug!("ProjectionCacheEntry::complete: adding cache entry: key={:?}, value={:?}",
                   key, value);
            // <-- WHERE DID value.obligations JUST DISAPPEAR TO?
            self.map.insert(key, ProjectionCacheEntry::NormalizedTy(value.value))
        } else {
            debug!("ProjectionCacheEntry::complete: cannot cache: key={:?}, value={:?}",
                   key, value);
            !self.map.remove(key)
        };

        assert!(!fresh_key, "never started projecting `{:?}`", key);
    }

This causes problems with my new evaluation code because it causes an earlier call into evaluation, which allows the cache pollution to proceed (I think).

@arielb1

This comment has been minimized.

Copy link
Contributor

arielb1 commented Jul 13, 2017

Actually, the problem is that the projection cache is incompatible with 1-pass evaluation. Not sure how to solve this.

@alexcrichton

This comment has been minimized.

Copy link
Member

alexcrichton commented Jul 23, 2017

@arielb1 do you have further thoughts on this? The regression is now on beta :(

@aturon

This comment has been minimized.

Copy link
Member

aturon commented Jul 26, 2017

cc @eddyb

@eddyb

This comment has been minimized.

Copy link
Member

eddyb commented Jul 26, 2017

I don't have any specific knowledge of how the caches involved here interact. It seems like layout code triggers this but the problem could arise in a number of other ways.

@arielb1

This comment has been minimized.

Copy link
Contributor

arielb1 commented Jul 27, 2017

I have to talk to @nikomatsakis about this.

@nikomatsakis

This comment has been minimized.

Copy link
Contributor

nikomatsakis commented Jul 27, 2017

I can look into this, but not until Saturday.

@nikomatsakis

This comment has been minimized.

Copy link
Contributor

nikomatsakis commented Jul 27, 2017

triage: P-high

@rust-highfive rust-highfive added P-high and removed I-nominated labels Jul 27, 2017

@nikomatsakis nikomatsakis self-assigned this Jul 27, 2017

@nikomatsakis

This comment has been minimized.

Copy link
Contributor

nikomatsakis commented Jul 29, 2017

So I have a fix pending in this branch but I'm not sure what to use for a regression test, since I don't want to add a dependency on futures.

@alexcrichton

This comment has been minimized.

Copy link
Member

alexcrichton commented Jul 29, 2017

@nikomatsakis here's a "reasonably sized" test case which reproduces the error here.

@est31

This comment has been minimized.

Copy link
Contributor

est31 commented Jul 29, 2017

@nikomatsakis I've minimized @alexcrichton 's example to roughly the half here.

bors added a commit that referenced this issue Jul 31, 2017

Auto merge of #43546 - nikomatsakis:issue-43132, r=arielb1
save subobligations in the projection cache

The projection cache explicitly chose not to "preserve" subobligations for projections, since the fulfillment context ought to have been doing so. But for the trait evaluation scheme that causes problems. This PR reproduces subobligations. This has the potential to slow down compilation, but minimal investigation suggests it does not do so.

One hesitation about this PR: I could not find a way to make a standalone test case for #43132 (but admittedly I did not try very hard).

Fixes #43132.

r? @arielb1

@bors bors closed this in #43546 Jul 31, 2017

@remram44

This comment has been minimized.

Copy link
Contributor Author

remram44 commented Aug 1, 2017

The nightly is out and I no longer run into that ICE! On the other hand compiling this simple program now takes 8 minutes. The previous commit (before I introduced the ICE) is up from 6s to 1m51s.

@est31

This comment has been minimized.

Copy link
Contributor

est31 commented Aug 1, 2017

@remram44 I suggest you file a separate bug report for this.

@alexcrichton

This comment has been minimized.

Copy link
Member

alexcrichton commented Aug 1, 2017

@remram44 hm I can't seem to get the commit linked above to compile? What compiler are you using to compile it "pre ICE"?

@remram44

This comment has been minimized.

Copy link
Contributor Author

remram44 commented Aug 1, 2017

I'm compiling using stable and the nightly from the 28th from rustup... not sure why this would fail for you?

@alexcrichton

This comment has been minimized.

Copy link
Member

alexcrichton commented Aug 9, 2017

@remram44 sorry I still can't get the code to compile. Can you list the exact commands you're using, along with the exact toolchain in rustup-style syntax?

@remram44

This comment has been minimized.

Copy link
Contributor Author

remram44 commented Aug 9, 2017

The toolchains I tried are nightly-2017-08-01-x86_64-apple-darwin and nightly-2017-08-01-x86_64-unknown-linux-gnu.

Whatever your environment you can reproduce this from scratch in Docker with:

% docker run -ti --rm ubuntu:16.04
$ apt update && apt install curl gcc git
$ curl https://sh.rustup.rs -sSf | sh
$ . ~/.cargo/env
$ rustup toolchain install nightly-2017-07-28
$ rustup toolchain install nightly-2017-08-01
$ git clone https://gitlab.com/remram44/rs-web --single-branch --branch ICE
$ cd rs-web
$ cargo +nightly-2017-07-28 build
$ # Observe ICE
$ cargo +nightly-2017-08-01 build
$ # Observe no ICE, build time 8 minutes
$ git checkout 8fca3d957f91115349aaeb3ab58056b92d13b953
$ # Now on previous version, that always worked
$ cargo +nightly-2017-07-28 build
$ # Observe build time 6 seconds
$ cargo +nightly-2017-08-01 build
$ # Observe build time 1 minute 51 seconds
@alexcrichton

This comment has been minimized.

Copy link
Member

alexcrichton commented Aug 9, 2017

Ok thanks for the repro @remram44! Want to open a new issue with that so we can be sure to track it?

@remram44

This comment has been minimized.

Copy link
Contributor Author

remram44 commented Aug 9, 2017

Will do!

[edit: #43787]

bors added a commit that referenced this issue Aug 19, 2017

Auto merge of #43952 - arielb1:the-big-backout, r=nikomatsakis
[beta] back out #42480 and its dependents

#42480 makes the ICE in #43132 worse, and the "safe" fix to that causes the #43787 exponential worst-case.

Let's back everything out for beta to avoid regressions, and get the permafix in nightly.

bors added a commit that referenced this issue Aug 19, 2017

Auto merge of #43952 - arielb1:the-big-backout, r=nikomatsakis
[beta] back out #42480 and its dependents

#42480 makes the ICE in #43132 worse, and the "safe" fix to that causes the #43787 exponential worst-case.

Let's back everything out for beta to avoid regressions, and get the permafix in nightly.

@arielb1 arielb1 referenced this issue Oct 5, 2017

Merged

Beta 20170928 #44908

arielb1 added a commit to arielb1/rust that referenced this issue Oct 6, 2017

fix logic error in rust-lang#44269's `prune_cache_value_obligations`
We want to retain obligations that *contain* inference variables, not
obligations that *don't contain* them, in order to fix rust-lang#43132. Because
of surrounding changes to inference, the ICE doesn't occur in its
original case, but I believe it could still be made to occur on master.

Maybe I should try to write a new test case? Certainly not right now
(I'm mainly trying to get us a beta that we can ship) but maybe before
we land this PR on nightly?

This seems to cause a 10% performance regression in my imprecise
attempt to benchmark item-body checking for rust-lang#43613, but it's better to
be slow and right than fast and wrong. If we want to recover that, I
think we can change the constrained-type-parameter code to actually
give a list of projections that are important for resolving inference
variables and filter everything else out.

nikomatsakis added a commit to nikomatsakis/rust that referenced this issue Oct 6, 2017

fix logic error in rust-lang#44269's `prune_cache_value_obligations`
We want to retain obligations that *contain* inference variables, not
obligations that *don't contain* them, in order to fix rust-lang#43132. Because
of surrounding changes to inference, the ICE doesn't occur in its
original case, but I believe it could still be made to occur on master.

Maybe I should try to write a new test case? Certainly not right now
(I'm mainly trying to get us a beta that we can ship) but maybe before
we land this PR on nightly?

This seems to cause a 10% performance regression in my imprecise
attempt to benchmark item-body checking for rust-lang#43613, but it's better to
be slow and right than fast and wrong. If we want to recover that, I
think we can change the constrained-type-parameter code to actually
give a list of projections that are important for resolving inference
variables and filter everything else out.

bors added a commit that referenced this issue Oct 6, 2017

Auto merge of #45065 - arielb1:not-correct, r=nikomatsakis
fix logic error in #44269's `prune_cache_value_obligations`

We want to retain obligations that *contain* inference variables, not
obligations that *don't contain* them, in order to fix #43132. Because
of surrounding changes to inference, the ICE doesn't occur in its
original case, but I believe it could still be made to occur on master.

Maybe I should try to write a new test case? Certainly not right now
(I'm mainly trying to get us a beta that we can ship) but maybe before
we land this PR on nightly?

This seems to cause a 10% performance regression in my imprecise
attempt to benchmark item-body checking for #43613, but it's better to
be slow and right than fast and wrong. If we want to recover that, I
think we can change the constrained-type-parameter code to actually
give a list of projections that are important for resolving inference
variables and filter everything else out.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.