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 cause by tokio::spawn a async function return future opaque type #68477

Closed
shisoft opened this issue Jan 23, 2020 · 3 comments · Fixed by #68505
Closed

ICE cause by tokio::spawn a async function return future opaque type #68477

shisoft opened this issue Jan 23, 2020 · 3 comments · Fixed by #68505

Comments

@shisoft
Copy link

@shisoft shisoft commented Jan 23, 2020

The ICE cause by cargo check, seems happened in multiple locations. One of the cause is when calling tokio::spawn function.

I don't know how to reproduce this problem in minimal example, but the faulty code in my project comes from here
https://github.com/ShisoftResearch/bifrost/blob/f67c57209dd15072a2868f46c1d26cd356caafae/src/raft/mod.rs#L631

Expecting the code to compile or providing reason for the failure. Instead, the compile just crashed.
This problem appears on both MacOS and Linux

Meta

rustc 1.42.0-nightly (5e8897b 2020-01-21)
binary: rustc
commit-hash: 5e8897b
commit-date: 2020-01-21
host: x86_64-unknown-linux-gnu
release: 1.42.0-nightly
LLVM version: 9.0

tokio 0.2.10

Backtrace:

error: internal compiler error: src/librustc/ich/impls_ty.rs:96: StableHasher: unexpected region RePlaceholder(Placeholder { universe: U596, name: BrAnon(3) })

thread 'rustc' panicked at 'Box<Any>', src/librustc_errors/lib.rs:882:9
stack backtrace:
   0: backtrace::backtrace::libunwind::trace
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/libunwind.rs:88
   1: backtrace::backtrace::trace_unsynchronized
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/mod.rs:66
   2: std::sys_common::backtrace::_print_fmt
             at src/libstd/sys_common/backtrace.rs:77
   3: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
             at src/libstd/sys_common/backtrace.rs:59
   4: core::fmt::write
             at src/libcore/fmt/mod.rs:1052
   5: std::io::Write::write_fmt
             at src/libstd/io/mod.rs:1426
   6: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:62
   7: std::sys_common::backtrace::print
             at src/libstd/sys_common/backtrace.rs:49
   8: std::panicking::default_hook::{{closure}}
             at src/libstd/panicking.rs:204
   9: std::panicking::default_hook
             at src/libstd/panicking.rs:224
  10: rustc_driver::report_ice
  11: <alloc::boxed::Box<F> as core::ops::function::Fn<A>>::call
             at /rustc/5e8897b7b51636f157630e6639b711d698e1d101/src/liballoc/boxed.rs:1029
  12: proc_macro::bridge::client::<impl proc_macro::bridge::Bridge>::enter::{{closure}}::{{closure}}
             at /rustc/5e8897b7b51636f157630e6639b711d698e1d101/src/libproc_macro/bridge/client.rs:305
  13: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:476
  14: std::panicking::begin_panic
  15: rustc_errors::HandlerInner::bug
  16: rustc_errors::Handler::bug
  17: rustc::util::bug::opt_span_bug_fmt::{{closure}}
  18: rustc::ty::context::tls::with_opt::{{closure}}
  19: rustc::ty::context::tls::with_opt
  20: rustc::util::bug::opt_span_bug_fmt
  21: rustc::util::bug::bug_fmt
  22: rustc::ich::impls_ty::<impl rustc_data_structures::stable_hasher::HashStable<rustc::ich::hcx::StableHashingContext> for rustc::ty::sty::RegionKind>::hash_stable
  23: rustc::ty::sty::_DERIVE_rustc_data_structures_stable_hasher_HashStable_rustc_ich_StableHashingContext_ctx_FOR_TyKind::<impl rustc_data_structures::stable_hasher::HashStable<rustc::ich::hcx::StableHashingContext> for rustc::ty::sty::TyKind>::hash_stable
  24: std::thread::local::LocalKey<T>::with
  25: rustc::ty::sty::_DERIVE_rustc_data_structures_stable_hasher_HashStable_rustc_ich_StableHashingContext_ctx_FOR_TyKind::<impl rustc_data_structures::stable_hasher::HashStable<rustc::ich::hcx::StableHashingContext> for rustc::ty::sty::TyKind>::hash_stable
  26: std::thread::local::LocalKey<T>::with
  27: rustc::mir::interpret::_DERIVE_rustc_data_structures_stable_hasher_HashStable_rustc_ich_StableHashingContext_ctx_FOR_GlobalId::<impl rustc_data_structures::stable_hasher::HashStable<rustc::ich::hcx::StableHashingContext> for rustc::mir::interpret::GlobalId>::hash_stable
  28: <T as rustc::dep_graph::dep_node::DepNodeParams>::to_fingerprint
  29: rustc::dep_graph::dep_node::DepNode::new
  30: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
  31: rustc::mir::interpret::queries::<impl rustc::ty::context::TyCtxt>::const_eval_instance
  32: rustc::mir::interpret::queries::<impl rustc::ty::context::TyCtxt>::const_eval_resolve
  33: <rustc::traits::project::AssocTypeNormalizer as rustc::ty::fold::TypeFolder>::fold_const
  34: rustc::ty::structural_impls::<impl rustc::ty::fold::TypeFoldable for &rustc::ty::TyS>::super_fold_with
  35: <rustc::traits::project::AssocTypeNormalizer as rustc::ty::fold::TypeFolder>::fold_ty
  36: rustc::traits::project::normalize_with_depth
  37: rustc::infer::InferCtxt::commit_unconditionally
  38: <core::iter::adapters::flatten::FlatMap<I,U,F> as core::iter::traits::iterator::Iterator>::next
  39: <alloc::vec::Vec<T> as alloc::vec::SpecExtend<T,I>>::from_iter
  40: rustc::traits::select::SelectionContext::collect_predicates_for_types
  41: rustc::traits::select::SelectionContext::confirm_candidate
  42: rustc::traits::select::SelectionContext::select
  43: rustc_data_structures::obligation_forest::ObligationForest<O>::process_obligations
  44: <rustc::traits::fulfill::FulfillmentContext as rustc::traits::engine::TraitEngine>::select_where_possible
  45: rustc_typeck::check::FnCtxt::check_argument_types
  46: rustc_typeck::check::callee::<impl rustc_typeck::check::FnCtxt>::confirm_builtin_call
  47: rustc_typeck::check::callee::<impl rustc_typeck::check::FnCtxt>::check_call
  48: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_kind
  49: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_with_expectation_and_needs
  50: rustc_typeck::check::FnCtxt::check_decl_initializer
  51: rustc_typeck::check::FnCtxt::check_decl_local
  52: rustc_typeck::check::FnCtxt::check_stmt
  53: rustc_typeck::check::FnCtxt::check_block_with_expected
  54: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_kind
  55: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_with_expectation_and_needs
  56: rustc_typeck::check::FnCtxt::check_stmt
  57: rustc_typeck::check::FnCtxt::check_block_with_expected
  58: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_kind
  59: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_with_expectation_and_needs
  60: rustc_typeck::check::_match::<impl rustc_typeck::check::FnCtxt>::check_match
  61: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_kind
  62: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_with_expectation_and_needs
  63: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_kind
  64: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_with_expectation_and_needs
  65: rustc_typeck::check::FnCtxt::check_stmt
  66: rustc_typeck::check::FnCtxt::check_block_with_expected
  67: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_kind
  68: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_with_expectation_and_needs
  69: rustc_typeck::check::_match::<impl rustc_typeck::check::FnCtxt>::check_match
  70: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_kind
  71: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_with_expectation_and_needs
  72: rustc_typeck::check::FnCtxt::check_block_with_expected
  73: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_kind
  74: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_with_expectation_and_needs
  75: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_kind
  76: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_with_expectation_and_needs
  77: rustc_typeck::check::FnCtxt::check_block_with_expected
  78: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_kind
  79: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_with_expectation_and_needs
  80: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_return_expr
  81: rustc_typeck::check::check_fn
  82: rustc_typeck::check::closure::<impl rustc_typeck::check::FnCtxt>::check_expr_closure
  83: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_kind
  84: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_with_expectation_and_needs
  85: rustc_typeck::check::FnCtxt::check_argument_types
  86: rustc_typeck::check::callee::<impl rustc_typeck::check::FnCtxt>::confirm_builtin_call
  87: rustc_typeck::check::callee::<impl rustc_typeck::check::FnCtxt>::check_call
  88: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_kind
  89: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_expr_with_expectation_and_needs
  90: rustc_typeck::check::expr::<impl rustc_typeck::check::FnCtxt>::check_return_expr
  91: rustc_typeck::check::check_fn
  92: rustc::ty::context::tls::with_context::{{closure}}
  93: rustc_typeck::check::typeck_tables_of
  94: rustc::ty::query::__query_compute::typeck_tables_of
  95: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::typeck_tables_of>::compute
  96: rustc::dep_graph::graph::DepGraph::with_task_impl
  97: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
  98: rustc_typeck::collect::type_of
  99: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::type_of>::compute
 100: rustc::dep_graph::graph::DepGraph::with_task_impl
 101: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
 102: rustc::traits::select::SelectionContext::constituent_types_for_ty
 103: rustc::ty::sty::Binder<T>::map_bound
 104: rustc::traits::select::SelectionContext::confirm_candidate
 105: rustc::infer::InferCtxt::probe
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

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.42.0-nightly (5e8897b7b 2020-01-21) running on x86_64-unknown-linux-gnu

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

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

query stack during panic:
#0 [typeck_tables_of] processing `raft::RaftService::send_followers_heartbeat`
#1 [type_of] processing `raft::RaftService::send_followers_heartbeat::{{opaque}}#0`
#2 [evaluate_obligation] evaluating trait selection obligation `for<'r, 's, 't0, 't1, 't2, 't3, 't4, 't5, 't6, 't7, 't8, 't9, 't10, 't11, 't12, 't13, 't14, 't15, 't16, 't17, 't18, 't19, 't20, 't21, 't22, 't23> {std::sync::Arc<raft::RaftService>, i64, i64, raft::RaftService, std::sync::Arc<raft::RaftService>, &'r utils::rwlock::RwLock<raft::RaftMeta>, utils::rwlock::RwLock<raft::RaftMeta>, utils::rwlock::RwLockWriteGuardFut<'s, raft::RaftMeta>, utils::rwlock::RwLockWriteGuardFut<'t0, raft::RaftMeta>, (), (), utils::rwlock::RwLockWriteGuard<'t1, raft::RaftMeta>, raft::CheckerAction, raft::CheckerAction, &'t2 raft::RaftService, std::sync::Arc<raft::RaftService>, utils::rwlock::RwLockWriteGuard<'t3, raft::RaftMeta>, &'t4 mut utils::rwlock::RwLockWriteGuard<'t5, raft::RaftMeta>, &'t6 mut utils::rwlock::RwLockWriteGuard<'t7, raft::RaftMeta>, std::option::Option<u64>, impl core::future::future::Future, impl core::future::future::Future, (), (), &'t14 raft::RaftService, std::sync::Arc<raft::RaftService>, utils::rwlock::RwLockWriteGuard<'t15, raft::RaftMeta>, &'t16 mut utils::rwlock::RwLockWriteGuard<'t17, raft::RaftMeta>, &'t18 mut utils::rwlock::RwLockWriteGuard<'t19, raft::RaftMeta>, impl core::future::future::Future, impl core::future::future::Future, (), (), i64, i64, bool, bool, i64, u64, std::time::Duration, tokio::time::delay::Delay, tokio::time::delay::Delay, (), ()}: std::marker::Send`
#3 [typeck_tables_of] processing `raft::RaftService::start`
#4 [typeck_tables_of] processing `raft::RaftService::start::{{closure}}#0`
#5 [type_of] processing `raft::RaftService::start::{{closure}}#0`
#6 [collect_mod_item_types] collecting item types in module `raft`
#7 [analysis] running analysis passes on this crate
end of query stack
error: aborting due to previous error

error: could not compile `bifrost`.

To learn more, run the command again with --verbose.
@Aaron1011

This comment has been minimized.

Copy link
Contributor

@Aaron1011 Aaron1011 commented Jan 23, 2020

Minimized (use rustc -C incremental=1 --edition=2018 to reproduce):

#![feature(const_generics)]

const FOO: usize = 1;

struct Container<T> {
    val: std::marker::PhantomData<T>,
    blah: [(); FOO]
}

async fn dummy() {}

async fn foo() {
    let a: Container<&'static ()>;
    dummy().await;
}

fn is_send<T: Send>(_: T) {}

fn main() {
    is_send(foo());
}

There's a lot going on here:

  1. We compute the witness type for foo, erasing &'static to a new ReLateBound
  2. We try to evaluate an auto-trait predicate for the opaque return value of foo. This requires us to evaluate Container<T>: Send, with the late-bound region type &_# () substituted in for T.
  3. Evaluation succeeds, giving us an auto-impl candidate.
  4. In SelectionContext::collect_predicates_for_types, we replace the late-bound region with a placeholder region, and try to normalize the auto-impl candidate.
  5. During normalization, we try to const-eval [(); FOO] (a constituent type of Container)
  6. Since #![feature(const_generics)] is enabled, we use the proper generic substs for the reference to FOO - namely, we provide T as a subst, since the unevaluated expression might use it.
  7. Since T is the placeholder-instantiated type &_# (), we try to const-eval an Instance with a placeholder region in its substs.
  8. Incremental compilation is enabled, so we ICE.

EDIT: I may be wrong about where exactly the placeholder region is getting created.

In the original ICE, the #![feature(const_generics)] came from liballoc, and the LeafNode struct takes the place of Container.

@Aaron1011

This comment has been minimized.

Copy link
Contributor

@Aaron1011 Aaron1011 commented Jan 23, 2020

This should be fixed by #67717, since canonicalized const-eval queries can handle placeholder regions.

@pnkfelix

This comment has been minimized.

Copy link
Member

@pnkfelix pnkfelix commented Jan 23, 2020

triage: P-high, removing nomination label. Assigning to @Aaron1011

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Linked pull requests

Successfully merging a pull request may close this issue.

6 participants
You can’t perform that action at this time.