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: static generator (Broken MIR: generator contains type [...] in MIR, but typeck only knows about for) #49592

Closed
PaulGrandperrin opened this issue Apr 2, 2018 · 6 comments
Labels
A-coroutines Area: Coroutines C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@PaulGrandperrin
Copy link

Hi,
I was trying to do a "quick and dirty" port of future-await 0.1 to use immovable generators everywhere, using the new API from the recent nightlies (#49194).

It's really simple, you just have to enclose calls to resume() with unsafe blocks and add the static keyword to all generator declarations.
It worked well for the places where the macro code was in declarative style but when trying to add the static keyword to generator declared in procedure style macros, I get an ICE.

You can find the offending code in question here: PaulGrandperrin/futures-await@227bcc3#diff-aae145273a44b5b7d67eba92bc61af08R343

#[proc_macro]
pub fn async_block(input: TokenStream) -> TokenStream {
    let input = TokenStream::from(TokenTree {
        kind: TokenNode::Group(Delimiter::Brace, input),
        span: proc_macro::Span::def_site(),
    });
    let expr = syn::parse(input)
        .expect("failed to parse tokens as an expression");
    let expr = ExpandAsyncFor.fold_expr(expr);

    let mut tokens = quote_cs! {
        ::futures::__rt::gen
    };

    let span = Span::call_site();
    syn::token::Paren(span).surround(&mut tokens, |tokens| {
        syn::token::Unsafe(span).to_tokens(tokens);
        syn::token::Brace(span).surround(tokens, |tokens| {
            syn::token::Static(span).to_tokens(tokens); // if you comment this line => No ICE
            syn::token::Move(span).to_tokens(tokens);
            syn::token::OrOr([span, span]).to_tokens(tokens);
            syn::token::Brace(span).surround(tokens, |tokens| {
                (quote_cs! {
                    if false { yield ::futures::Async::NotReady }
                }).to_tokens(tokens);
                expr.to_tokens(tokens);
            });
        });


    });

    tokens.into()
}

To reproduce, clone the branch rustc-bug of https://github.com/PaulGrandperrin/futures-await.git
and use it in a project using async_block!.

Here is the crash

   Compiling reactfs v0.1.0 (file:///home/paulg/Projects/reactfs)
     Running `rustc --crate-name reactfs src/lib.rs --crate-type lib --emit=dep-info,link -C debuginfo=2 --cfg 'feature="default"' --cfg 'feature="instrumentation"' -C metadata=882e506be794ab99 -C extra-filename=-882e506be794ab99 --out-dir /home/paulg/Projects/reactfs/target/debug/deps -C incremental=/home/paulg/Projects/reactfs/target/debug/incremental -L dependency=/home/paulg/Projects/reactfs/target/debug/deps --extern byteorder=/home/paulg/Projects/reactfs/target/debug/deps/libbyteorder-f8246f5b53339753.rlib --extern itertools=/home/paulg/Projects/reactfs/target/debug/deps/libitertools-eb98fbccb4da1591.rlib --extern honggfuzz=/home/paulg/Projects/reactfs/target/debug/deps/libhonggfuzz-9f774f97be9121c6.rlib --extern bytes=/home/paulg/Projects/reactfs/target/debug/deps/libbytes-3be8cb5d0748d1dc.rlib --extern num_traits=/home/paulg/Projects/reactfs/target/debug/deps/libnum_traits-30c3c0056211cac7.rlib --extern futures_await=/home/paulg/Projects/reactfs/target/debug/deps/libfutures_await-637cade218d0db17.rlib --extern futures=/home/paulg/Projects/reactfs/target/debug/deps/libfutures-75d075e86bb0e45b.rlib --extern slab=/home/paulg/Projects/reactfs/target/debug/deps/libslab-158bd0e99f5d7cbe.rlib --extern failure=/home/paulg/Projects/reactfs/target/debug/deps/libfailure-6808a5ea78d81bc4.rlib --extern enum_primitive_derive=/home/paulg/Projects/reactfs/target/debug/deps/libenum_primitive_derive-7e3658016f2f1a8c.so --extern fuzztest=/home/paulg/Projects/reactfs/target/debug/deps/libfuzztest-c5ecfc509dc6c5c0.rlib -C target-cpu=native -L native=/home/paulg/Projects/reactfs/target/debug/build/backtrace-sys-f867eb04e6714ca4/out/.libs`
error: internal compiler error: librustc_mir/transform/generator.rs:495: Broken MIR: generator contains type (core::ObjectPointer, u64, std::option::Option<u64>) in MIR, but typeck only knows about for<'r, 's, 't0> {futures::Async<futures::__rt::Mu>, (), fn(std::result::Result<(), failure::Error>) -> std::result::Result<<std::result::Result<(), failure::Error> as std::ops::Try>::Ok, <std::result::Result<(), failure::Error> as std::ops::Try>::Error> {<std::result::Result<(), failure::Error> as std::ops::Try>::into_result}, impl futures::__rt::MyFuture<std::result::Result<(), failure::Error>>, fn(std::result::Result<core::Uberblock, failure::Error>) -> std::result::Result<<std::result::Result<core::Uberblock, failure::Error> as std::ops::Try>::Ok, <std::result::Result<core::Uberblock, failure::Error> as std::ops::Try>::Error> {<std::result::Result<core::Uberblock, failure::Error> as std::ops::Try>::into_result}, impl futures::__rt::MyFuture<std::result::Result<core::Uberblock, failure::Error>>, core::Uberblock, core::ObjectPointer, u64, fn(std::ops::Range<usize>) -> <std::ops::Range<usize> as std::iter::IntoIterator>::IntoIter {<std::ops::Range<usize> as std::iter::IntoIterator>::into_iter}, usize, &'r std::vec::Vec<(u64, u64)>, std::ops::Range<usize>, fn(std::result::Result<(core::ObjectPointer, u64, std::option::Option<u64>), failure::Error>) -> std::result::Result<<std::result::Result<(core::ObjectPointer, u64, std::option::Option<u64>), failure::Error> as std::ops::Try>::Ok, <std::result::Result<(core::ObjectPointer, u64, std::option::Option<u64>), failure::Error> as std::ops::Try>::Error> {<std::result::Result<(core::ObjectPointer, u64, std::option::Option<u64>), failure::Error> as std::ops::Try>::into_result}, std::boxed::Box<futures::Future<Error=failure::Error, Item=(core::ObjectPointer, u64, std::option::Option<u64>)> + 's>, std::boxed::Box<futures::Future<Error=failure::Error, Item=std::vec::Vec<core::NodeEntry<u64, u64>>> + 't0>}
   --> src/core/instrumentation.rs:113:5
    |
113 | /     async_block!{
114 | |         await!(format(handle.clone()))?;
115 | |         let uberblock = await!(find_latest_uberblock(handle.clone()))?;
116 | |         let (mut op, mut free_space_offset) = (uberblock.tree_root_pointer, uberblock.free_space_offset);
...   |
134 | |         await!(read_btree(handle.clone(), op.clone()))
135 | |     }
    | |_____^

thread 'rustc' panicked at 'Box<Any>', librustc_errors/lib.rs:488:9
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
stack backtrace:
   0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
             at libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
   1: std::sys_common::backtrace::print
             at libstd/sys_common/backtrace.rs:71
             at libstd/sys_common/backtrace.rs:59
   2: std::panicking::default_hook::{{closure}}
             at libstd/panicking.rs:207
   3: std::panicking::default_hook
             at libstd/panicking.rs:223
   4: core::ops::function::Fn::call
   5: std::panicking::rust_panic_with_hook
             at libstd/panicking.rs:403
   6: std::panicking::begin_panic
   7: rustc_errors::Handler::span_bug
   8: rustc::session::opt_span_bug_fmt::{{closure}}
   9: rustc::ty::context::tls::with_opt::{{closure}}
  10: <std::thread::local::LocalKey<T>>::try_with
  11: <std::thread::local::LocalKey<T>>::with
  12: rustc::ty::context::tls::with
  13: rustc::ty::context::tls::with_opt
  14: rustc::session::opt_span_bug_fmt
  15: rustc::session::span_bug_fmt
  16: <rustc_mir::transform::generator::StateTransform as rustc_mir::transform::MirPass>::run_pass
  17: rustc_mir::transform::optimized_mir::{{closure}}
  18: rustc_mir::transform::optimized_mir
  19: rustc::ty::maps::<impl rustc::ty::maps::queries::optimized_mir<'tcx>>::compute_result
  20: rustc::dep_graph::graph::DepGraph::with_task_impl
  21: rustc_errors::Handler::track_diagnostics
  22: rustc::ty::maps::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::cycle_check
  23: rustc::ty::maps::<impl rustc::ty::maps::queries::optimized_mir<'tcx>>::force
  24: rustc::ty::maps::<impl rustc::ty::maps::queries::optimized_mir<'tcx>>::try_get
  25: rustc::ty::maps::TyCtxtAt::optimized_mir
  26: rustc::ty::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::generator_layout
  27: rustc_metadata::encoder::<impl rustc_metadata::isolated_encoder::IsolatedEncoder<'a, 'b, 'tcx>>::encode_info_for_closure
  28: rustc::dep_graph::graph::DepGraph::with_ignore
  29: rustc_metadata::encoder::<impl rustc_metadata::index_builder::IndexBuilder<'a, 'b, 'tcx>>::encode_info_for_expr
  30: rustc::hir::intravisit::walk_expr
  31: rustc::hir::intravisit::walk_expr
  32: rustc::hir::intravisit::Visitor::visit_nested_body
  33: <rustc_metadata::encoder::EncodeVisitor<'a, 'b, 'tcx> as rustc::hir::intravisit::Visitor<'tcx>>::visit_item
  34: rustc::hir::Crate::visit_all_item_likes
  35: rustc_metadata::encoder::encode_metadata
  36: rustc_metadata::cstore_impl::<impl rustc::middle::cstore::CrateStore for rustc_metadata::cstore::CStore>::encode_metadata
  37: rustc::ty::context::TyCtxt::encode_metadata
  38: rustc_trans::base::write_metadata
  39: rustc::util::common::time
  40: rustc_trans::base::trans_crate
  41: <rustc_trans::LlvmTransCrate as rustc_trans_utils::trans_crate::TransCrate>::trans_crate
  42: rustc::util::common::time
  43: rustc_driver::driver::phase_4_translate_to_llvm
  44: rustc_driver::driver::compile_input::{{closure}}
  45: <std::thread::local::LocalKey<T>>::with
  46: <std::thread::local::LocalKey<T>>::with
  47: rustc::ty::context::TyCtxt::create_and_enter
  48: rustc_driver::driver::compile_input
  49: rustc_driver::run_compiler_impl
  50: syntax::with_globals
error: aborting due to previous error


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.26.0-nightly (ae544ee1c 2018-03-29) running on x86_64-unknown-linux-gnu

note: compiler flags: -C debuginfo=2 -C incremental -C target-cpu=native --crate-type lib

note: some of the compiler flags provided by cargo are hidden

error: Could not compile `reactfs`.

Caused by:
  process didn't exit successfully: `rustc --crate-name reactfs src/lib.rs --crate-type lib --emit=dep-info,link -C debuginfo=2 --cfg feature="default" --cfg feature="instrumentation" -C metadata=882e506be794ab99 -C extra-filename=-882e506be794ab99 --out-dir /home/paulg/Projects/reactfs/target/debug/deps -C incremental=/home/paulg/Projects/reactfs/target/debug/incremental -L dependency=/home/paulg/Projects/reactfs/target/debug/deps --extern byteorder=/home/paulg/Projects/reactfs/target/debug/deps/libbyteorder-f8246f5b53339753.rlib --extern itertools=/home/paulg/Projects/reactfs/target/debug/deps/libitertools-eb98fbccb4da1591.rlib --extern honggfuzz=/home/paulg/Projects/reactfs/target/debug/deps/libhonggfuzz-9f774f97be9121c6.rlib --extern bytes=/home/paulg/Projects/reactfs/target/debug/deps/libbytes-3be8cb5d0748d1dc.rlib --extern num_traits=/home/paulg/Projects/reactfs/target/debug/deps/libnum_traits-30c3c0056211cac7.rlib --extern futures_await=/home/paulg/Projects/reactfs/target/debug/deps/libfutures_await-637cade218d0db17.rlib --extern futures=/home/paulg/Projects/reactfs/target/debug/deps/libfutures-75d075e86bb0e45b.rlib --extern slab=/home/paulg/Projects/reactfs/target/debug/deps/libslab-158bd0e99f5d7cbe.rlib --extern failure=/home/paulg/Projects/reactfs/target/debug/deps/libfailure-6808a5ea78d81bc4.rlib --extern enum_primitive_derive=/home/paulg/Projects/reactfs/target/debug/deps/libenum_primitive_derive-7e3658016f2f1a8c.so --extern fuzztest=/home/paulg/Projects/reactfs/target/debug/deps/libfuzztest-c5ecfc509dc6c5c0.rlib -C target-cpu=native -L native=/home/paulg/Projects/reactfs/target/debug/build/backtrace-sys-f867eb04e6714ca4/out/.libs` (exit code: 101)
@PaulGrandperrin
Copy link
Author

PaulGrandperrin commented Apr 2, 2018

Oh, it's not related to the fact that it's a procedural macro..
I quickly rewrote this macro in declarative style and there is still the same ICE!
You can find this code in the rustc-bug2 branch if you which.

PaulGrandperrin/futures-await@3cb0834#diff-7cea22f34a23b3125ac94b700b8afa92R30

#[macro_export]
macro_rules! async_block {
    ($e:expr) => {
        ::futures::__rt::gen(unsafe {
                    static move || {
                        if false {
                            yield ::futures::Async::NotReady
                        }
                        {
                        $e
                        }
                    }
                }
                )
    }

}

@PaulGrandperrin PaulGrandperrin changed the title ICE: in proc_macro when creating static generator tokens ICE: in proc_macro when creating static generator tokens (Broken MIR: generator contains type [...] in MIR, but typeck only knows about for) Apr 2, 2018
@PaulGrandperrin
Copy link
Author

I guess @Zoxc

@Zoxc Zoxc added the A-coroutines Area: Coroutines label Apr 2, 2018
@PaulGrandperrin
Copy link
Author

Ok, so I've been wrestling with this issue quite a bit to reduce it down.

First, it's absolutely not related to macros.
Second it's not dependent on the code I shared on this thread but on the code that uses it.
Anyways, I've managed to reduce the use case enough to make it reproducible easily on the playground:

https://play.rust-lang.org/?gist=9f9e2687b234c1d8b4667ae148000249&version=nightly

I will continue to try to reduce it down tomorrow and post an update.

@PaulGrandperrin PaulGrandperrin changed the title ICE: in proc_macro when creating static generator tokens (Broken MIR: generator contains type [...] in MIR, but typeck only knows about for) ICE: static generator (Broken MIR: generator contains type [...] in MIR, but typeck only knows about for) Apr 4, 2018
@Zoxc
Copy link
Contributor

Zoxc commented Apr 5, 2018

This might be the same bug as #49232.

@XAMPPRocky XAMPPRocky added I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. C-bug Category: This is a bug. labels Jun 29, 2018
@Zoxc
Copy link
Contributor

Zoxc commented Aug 6, 2018

@PaulGrandperrin Your reduced case compiles on nightly now.

@PaulGrandperrin
Copy link
Author

The bug is indeed fixed, thanks!!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-coroutines Area: Coroutines C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

3 participants