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

MIR generator compiler panic #52792

Closed
benbrittain opened this issue Jul 27, 2018 · 17 comments · Fixed by #52915
Closed

MIR generator compiler panic #52792

benbrittain opened this issue Jul 27, 2018 · 17 comments · Fixed by #52915
Labels
A-coroutines Area: Coroutines A-mir Area: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.html I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️

Comments

@benbrittain
Copy link

benbrittain commented Jul 27, 2018

error: internal compiler error: librustc_mir/transform/generator.rs:506: Broken MIR: generator contains type fidl_fuchsia_bluetooth::Status in MIR, but typeck only knows about for<'r, 's, 't0, 't1, 't2, 't3, 't4, 't5, 't6, 't7, 't8> {fidl_fuchsia_bluetooth_control::ControlRequestStream, std::sync::Arc<parking_lot::RwLock<control_service::ControlServiceState>>, futures::stream::Next<'r, fidl_fuchsia_bluetooth_control::ControlRequestStream>, std::mem::PinMut<'s, futures::stream::Next<'t0, fidl_fuchsia_bluetooth_control::ControlRequestStream>>, for<'t9, 't10> fn(&'t9 mut std::mem::PinMut<'t10, futures::stream::Next<'t1, fidl_fuchsia_bluetooth_control::ControlRequestStream>>) -> futures::Poll<<futures::stream::Next<'t1, fidl_fuchsia_bluetooth_control::ControlRequestStream> as futures::Future>::Output> {std::future::poll_in_task_cx::<futures::stream::Next<'t1, fidl_fuchsia_bluetooth_control::ControlRequestStream>>}, &'t2 mut std::mem::PinMut<'t3, futures::stream::Next<'t4, fidl_fuchsia_bluetooth_control::ControlRequestStream>>, futures::Poll<std::option::Option<std::result::Result<fidl_fuchsia_bluetooth_control::ControlRequest, fidl::Error>>>, (), std::option::Option<std::result::Result<fidl_fuchsia_bluetooth_control::ControlRequest, fidl::Error>>, std::result::Result<fidl_fuchsia_bluetooth_control::ControlRequest, fidl::Error>, fn(std::result::Result<fidl_fuchsia_bluetooth_control::ControlRequest, fidl::Error>) -> std::result::Result<<std::result::Result<fidl_fuchsia_bluetooth_control::ControlRequest, fidl::Error> as std::ops::Try>::Ok, <std::result::Result<fidl_fuchsia_bluetooth_control::ControlRequest, fidl::Error> as std::ops::Try>::Error> {<std::result::Result<fidl_fuchsia_bluetooth_control::ControlRequest, fidl::Error> as std::ops::Try>::into_result}, fidl_fuchsia_bluetooth_control::ControlRequest, std::string::String, fidl_fuchsia_bluetooth_control::ControlConnectResponder, fidl_fuchsia_bluetooth_control::ControlIsBluetoothAvailableResponder, std::option::Option<fidl::endpoints2::ClientEnd<fidl_fuchsia_bluetooth_control::PairingDelegateMarker>>, fidl_fuchsia_bluetooth_control::ControlSetPairingDelegateResponder, fidl_fuchsia_bluetooth_control::ControlGetAdaptersResponder, fidl_fuchsia_bluetooth_control::ControlSetActiveAdapterResponder, bool, fidl_fuchsia_bluetooth_control::ControlRequestDiscoveryResponder, fidl_fuchsia_bluetooth_control::ControlGetKnownRemoteDevicesResponder, fidl_fuchsia_bluetooth_control::ControlGetActiveAdapterInfoResponder, std::option::Option<std::string::String>, fidl_fuchsia_bluetooth_control::ControlSetNameResponder, parking_lot::RwLockWriteGuard<'t5, control_service::ControlServiceState>, fn(std::result::Result<fidl_fuchsia_bluetooth::Status, fidl::Error>) -> std::result::Result<<std::result::Result<fidl_fuchsia_bluetooth::Status, fidl::Error> as std::ops::Try>::Ok, <std::result::Result<fidl_fuchsia_bluetooth::Status, fidl::Error> as std::ops::Try>::Error> {<std::result::Result<fidl_fuchsia_bluetooth::Status, fidl::Error> as std::ops::Try>::into_result}, impl futures::Future, std::mem::PinMut<'t6, impl futures::Future>, for<'t9, 't10> fn(&'t9 mut std::mem::PinMut<'t10, impl futures::Future>) -> futures::Poll<<impl futures::Future as futures::Future>::Output> {std::future::poll_in_task_cx::<impl futures::Future>}, &'t7 mut std::mem::PinMut<'t8, impl futures::Future>, futures::Poll<std::result::Result<fidl_fuchsia_bluetooth::Status, fidl::Error>>}
   --> src/control_service.rs:27:112
    |
27  |   pub async fn make_control_service(hd: Arc<RwLock<HostDispatcher>>, chan: fasync::Channel) -> Result<(), Error> {
    |  ________________________________________________________________________________________________________________^
28  | |     let mut requests = ControlRequestStream::from_channel(chan);
29  | |
30  | |     let state = Arc::new(RwLock::new(ControlServiceState {
...   |
176 | |     //    .recover(|e| eprintln!("error running service: {:?}", e))
177 | | }
    | |_^

thread 'main' panicked at 'Box<Any>', librustc_errors/lib.rs:518:9
note: Run with `RUST_BACKTRACE=1` for a backtrace.
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.29.0-dev running on x86_64-unknown-linux-gnu

note: compiler flags: -C debuginfo=2 -C linker=/usr/local/google/home/bwb/fuchsia/buildtools/linux-x64/clang/bin/clang -C incremental -C link-arg=--target=x86_64-unknown-fuchsia -C link-arg=--sysroot=/usr/local/google/home/bwb/fuchsia/out/release-x64/sdks/zircon_sysroot/arch/x64/sysroot --crate-type bin

note: some of the compiler flags provided by cargo are hidden
@benbrittain
Copy link
Author

cc @cramertj

@cramertj
Copy link
Member

cc @Zoxc

@benbrittain
Copy link
Author

stack backtrace:
   0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
   1: std::sys_common::backtrace::print
   2: std::panicking::default_hook::{{closure}}
   3: std::panicking::default_hook
   4: rustc::util::common::panic_hook
   5: std::panicking::rust_panic_with_hook
   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: rustc::ty::context::tls::with_context_opt
  11: rustc::ty::context::tls::with_opt
  12: rustc::session::opt_span_bug_fmt
  13: rustc::session::span_bug_fmt
  14: <rustc_mir::transform::generator::StateTransform as rustc_mir::transform::MirPass>::run_pass
  15: rustc_mir::transform::optimized_mir::{{closure}}
  16: rustc_mir::transform::optimized_mir
  17: rustc::ty::query::__query_compute::optimized_mir
  18: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors<'tcx> for rustc::ty::query::queries::optimized_mir<'tcx>>::compute
  19: rustc::ty::context::tls::with_context
  20: rustc::dep_graph::graph::DepGraph::with_task_impl
  21: rustc::ty::context::tls::with_related_context
  22: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::force_query_with_job
  23: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::try_get_query
  24: rustc::ty::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::instance_mir
  25: rustc_mir::monomorphize::collector::collect_items_rec
  26: rustc_mir::monomorphize::collector::collect_items_rec
  27: rustc_mir::monomorphize::collector::collect_items_rec
  28: rustc_mir::monomorphize::collector::collect_items_rec
  29: rustc_mir::monomorphize::collector::collect_items_rec
  30: rustc_mir::monomorphize::collector::collect_items_rec
  31: rustc_mir::monomorphize::collector::collect_items_rec
  32: rustc_mir::monomorphize::collector::collect_items_rec
  33: rustc_mir::monomorphize::collector::collect_items_rec
  34: rustc_mir::monomorphize::collector::collect_items_rec
  35: rustc_mir::monomorphize::collector::collect_items_rec
  36: rustc_mir::monomorphize::collector::collect_items_rec
  37: rustc_mir::monomorphize::collector::collect_items_rec
  38: rustc_mir::monomorphize::collector::collect_items_rec
  39: rustc_mir::monomorphize::collector::collect_items_rec
  40: rustc_mir::monomorphize::collector::collect_crate_mono_items::{{closure}}
  41: rustc::util::common::time
  42: rustc_mir::monomorphize::collector::collect_crate_mono_items
  43: rustc::util::common::time
  44: rustc_codegen_llvm::base::collect_and_partition_mono_items
  45: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors<'tcx> for rustc::ty::query::queries::collect_and_partition_mono_items<'tcx>>::compute
  46: rustc::ty::context::tls::with_context
  47: rustc::dep_graph::graph::DepGraph::with_task_impl
  48: rustc::ty::context::tls::with_related_context
  49: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::force_query_with_job
  50: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::get_query
  51: <rustc_codegen_llvm::LlvmCodegenBackend as rustc_codegen_utils::codegen_backend::CodegenBackend>::codegen_crate
  52: rustc::util::common::time
  53: rustc_driver::driver::phase_4_codegen
  54: rustc_driver::driver::compile_input::{{closure}}
  55: rustc::ty::context::tls::enter_context
  56: <std::thread::local::LocalKey<T>>::with
  57: rustc::ty::context::TyCtxt::create_and_enter
  58: rustc_driver::driver::compile_input
  59: rustc_driver::run_compiler_with_pool
  60: <scoped_tls::ScopedKey<T>>::set
  61: <scoped_tls::ScopedKey<T>>::set
  62: syntax::with_globals
  63: <std::panic::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once
  64: __rust_maybe_catch_panic
  65: rustc_driver::run
  66: rustc_driver::main
  67: std::rt::lang_start::{{closure}}
  68: std::panicking::try::do_call
  69: __rust_maybe_catch_panic
  70: std::rt::lang_start_internal
  71: main
  72: __libc_start_main
  73: _start
query stack during panic:
#0 [optimized_mir] processing `control_service::make_control_service::{{closure}}`
#1 [collect_and_partition_mono_items] collect_and_partition_mono_items
end of query stack
error: aborting due to previous error

@Zoxc Zoxc added the A-coroutines Area: Coroutines label Jul 27, 2018
@cramertj cramertj added I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ A-mir Area: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.html labels Jul 27, 2018
@cramertj
Copy link
Member

@Zoxc I'm hitting this a lot at the moment-- any idea what the cause might be? I'd love to help get this resolved.

@cramertj
Copy link
Member

I'm sometimes able to fix it by moving conditions that await!() out of the body of an if let expression.

@cramertj
Copy link
Member

It also seems to have regressed between a1e6bc and 866a71-- updating the compiler caused this to happen in more places.

@cramertj
Copy link
Member

cramertj commented Jul 30, 2018

Possibly related to #52597 ? cc @oli-obk

@cramertj
Copy link
Member

Trying to fix in more places and it looks like it's always related to await! temporaries-- if I make let x = await!(...); it and then use x in the place I was using await!(...) it usually solves the issue.

@cramertj
Copy link
Member

Smaller example: (playground)

#![feature(async_await, await_macro, futures_api, arbitrary_self_types, pin)]

use std::sync::{Arc, atomic::{AtomicUsize, Ordering}};

struct Stream;
impl Stream {
    async fn next(&mut self) -> Option<()> {
        Some(())
    }
}

fn main() {
    let counter = Arc::new(AtomicUsize::new(0));
    let fut = async move {
        let mut stream = Stream;
        loop {
            let next = stream.next();
            let opt = await!(next);
            let is_some = opt.is_some();
            if is_some {
                counter.fetch_add(1, Ordering::SeqCst);
            } else {
                break;
            }
        }
    };
}

@aturon
Copy link
Member

aturon commented Jul 30, 2018

cc @rust-lang/compiler @alexcrichton this is blocking roll out of async/await in Fuchsia

@cramertj
Copy link
Member

@Zoxc Looked at this and pointed out that it looks like typechecking thinks that opt isn't live at the yield point (which is correct) but that MIR thinks it is live (which is incorrect). I tried searching through the diff to see if there were any related PRs, but so far the only thing I've found that touches MIR is #52597, which seems like it shouldn't be related.

@cramertj
Copy link
Member

@cavedweller Is working on bisecting this.

@Zoxc
Copy link
Contributor

Zoxc commented Jul 30, 2018

I think the problem is that opt is borrowed by is_some() and because of this the generator transformation
only uses StorageLive and StorageDead statements to calculate liveness. However we generate a StorageLive statement for opt before its initialiser which contains the yield statement. So opt appears live during the yield statement, even though its storage isn't used for anything.

@cramertj
Copy link
Member

cramertj commented Jul 31, 2018

Bisection pointed to #52681 as the PR that made this worse (more code ICEs now), although the minimal test case still fails before and after. cc @pnkfelix

@benbrittain
Copy link
Author

benbrittain commented Jul 31, 2018

@benbrittain
Copy link
Author

benbrittain commented Jul 31, 2018

using .unwrap() instead of ? makes the ICE "go away"

@eddyb
Copy link
Member

eddyb commented Jul 31, 2018

@Zoxc Ah you need at the very least to use StorageDead and initializations, not StorageLive.
AFAIK the type of a variable could be dead at a StorageLive (lifetimes not ready yet).
Arguably you could also have the time before moving out and a reinitialization also count as dead, e.g. x = {yield x.into_iter().count(); x = vec![]; } doesn't really need to keep x alive.

pietroalbini added a commit to pietroalbini/rust that referenced this issue Aug 1, 2018
…eddyb

Don't count MIR locals as borrowed after StorageDead when finding locals live across a yield terminator

This should fix rust-lang#52792.

r? @eddyb
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-coroutines Area: Coroutines A-mir Area: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.html I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️
Projects
None yet
5 participants