Description
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)