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: src/librustc/middle/region.rs:1037: Encountered greater count 28 #69307

Closed
Kumassy opened this issue Feb 20, 2020 · 10 comments · Fixed by #70367
Closed

ICE: src/librustc/middle/region.rs:1037: Encountered greater count 28 #69307

Kumassy opened this issue Feb 20, 2020 · 10 comments · Fixed by #70367
Assignees
Labels
A-async-await Area: Async & Await AsyncAwait-Triaged Async-await issues that have been triaged during a working group meeting. C-bug Category: This is a bug. glacier ICE tracked in rust-lang/glacier. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ P-high High priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@Kumassy
Copy link

Kumassy commented Feb 20, 2020

Code

use tokio::prelude::*;
use tokio::runtime::Runtime;
use tokio::sync::mpsc;

fn main() {
    let mut rt = Runtime::new().unwrap();
    let mut sum = 0;
    sum += rt.block_on(async {
        let (tx, mut rx) = mpsc::unbounded_channel();
        tx.send(1).unwrap();

        while let Some(res) = rx.recv().await {
            println!("{:?}", res);
        }
        1
    });
}

Playground Link

Meta

rustc --version --verbose:

rustc 1.41.0 (5e1a79984 2020-01-27)
binary: rustc
commit-hash: 5e1a799842ba6ed4a57e91f7ab9435947482f7d8
commit-date: 2020-01-27
host: x86_64-unknown-linux-gnu
release: 1.41.0
LLVM version: 9.0

Same issue still exists in rustc +beta --version --verbose:

rustc 1.42.0-beta.3 (86f329b41 2020-02-07)
binary: rustc
commit-hash: 86f329b419dbac59da59e2ac7d6e21e5eb679ec7
commit-date: 2020-02-07
host: x86_64-unknown-linux-gnu
release: 1.42.0-beta.3
LLVM version: 9.0

and also in rustc +nightly --version --verbose:

rustc 1.43.0-nightly (7760cd0fb 2020-02-19)
binary: rustc
commit-hash: 7760cd0fbbbf2c59a625e075a5bdfa88b8e30f8a
commit-date: 2020-02-19
host: x86_64-unknown-linux-gnu
release: 1.43.0-nightly
LLVM version: 9.0

Error output

error: internal compiler error: src/librustc/middle/region.rs:1037: Encountered greater count 28 at span src/main.rs:13:31: 13:46 - expected no greater than 12

thread 'rustc' panicked at 'Box<Any>', src/librustc_errors/lib.rs:905:9
note: run with `RUST_BACKTRACE=1` environment variable to display a 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.41.0 (5e1a79984 2020-01-27) running on x86_64-unknown-linux-gnu

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

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

error: aborting due to previous error
Backtrace

error: internal compiler error: src/librustc/middle/region.rs:1037: Encountered greater count 28 at span src/main.rs:13:31: 13:46 - expected no greater than 12

thread 'rustc' panicked at 'Box<Any>', src/librustc_errors/lib.rs:905: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:84
   3: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
             at src/libstd/sys_common/backtrace.rs:61
   4: core::fmt::write
             at src/libcore/fmt/mod.rs:1025
   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:65
   7: std::sys_common::backtrace::print
             at src/libstd/sys_common/backtrace.rs:50
   8: std::panicking::default_hook::{{closure}}
             at src/libstd/panicking.rs:193
   9: std::panicking::default_hook
             at src/libstd/panicking.rs:210
  10: rustc_driver::report_ice
  11: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:475
  12: std::panicking::begin_panic
  13: rustc_errors::HandlerInner::bug
  14: rustc_errors::Handler::bug
  15: rustc::util::bug::opt_span_bug_fmt::{{closure}}
  16: rustc::ty::context::tls::with_opt::{{closure}}
  17: rustc::ty::context::tls::with_opt
  18: rustc::util::bug::opt_span_bug_fmt
  19: rustc::util::bug::bug_fmt
  20: rustc::middle::region::resolve_expr
  21: <rustc::middle::region::RegionResolutionVisitor as rustc::hir::intravisit::Visitor>::visit_stmt
  22: <rustc::middle::region::RegionResolutionVisitor as rustc::hir::intravisit::Visitor>::visit_block
  23: rustc::middle::region::resolve_expr
  24: <rustc::middle::region::RegionResolutionVisitor as rustc::hir::intravisit::Visitor>::visit_body
  25: rustc::middle::region::region_scope_tree
  26: rustc::ty::query::__query_compute::region_scope_tree
  27: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::region_scope_tree>::compute
  28: rustc::dep_graph::graph::DepGraph::with_task_impl
  29: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
  30: rustc_typeck::check::generator_interior::resolve_interior
  31: rustc_typeck::check::FnCtxt::resolve_generator_interiors
  32: rustc::ty::context::tls::with_context::{{closure}}
  33: rustc_typeck::check::typeck_tables_of
  34: rustc::ty::query::__query_compute::typeck_tables_of
  35: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::typeck_tables_of>::compute
  36: rustc::dep_graph::graph::DepGraph::with_task_impl
  37: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
  38: rustc::ty::query::__query_compute::typeck_tables_of
  39: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::typeck_tables_of>::compute
  40: rustc::dep_graph::graph::DepGraph::with_task_impl
  41: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
  42: rustc_typeck::collect::type_of
  43: rustc::ty::query::__query_compute::type_of
  44: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::type_of>::compute
  45: rustc::dep_graph::graph::DepGraph::with_task_impl
  46: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
  47: rustc::hir::intravisit::walk_expr
  48: rustc::hir::intravisit::walk_expr
  49: rustc::hir::intravisit::walk_expr
  50: rustc::hir::intravisit::walk_block
  51: rustc::hir::intravisit::Visitor::visit_fn
  52: rustc::hir::intravisit::walk_item
  53: <rustc_typeck::collect::CollectItemTypesVisitor as rustc::hir::intravisit::Visitor>::visit_item
  54: rustc::hir::map::Map::visit_item_likes_in_module
  55: rustc_typeck::collect::collect_mod_item_types
  56: rustc::ty::query::__query_compute::collect_mod_item_types
  57: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::collect_mod_item_types>::compute
  58: rustc::dep_graph::graph::DepGraph::with_task_impl
  59: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
  60: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::ensure_query
  61: rustc_typeck::check_crate::{{closure}}::{{closure}}
  62: rustc::util::common::time
  63: rustc_typeck::check_crate
  64: rustc_interface::passes::analysis
  65: rustc::ty::query::__query_compute::analysis
  66: rustc::dep_graph::graph::DepGraph::with_task_impl
  67: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
  68: rustc::ty::context::tls::enter_global
  69: rustc_interface::interface::run_compiler_in_existing_thread_pool
  70: std::thread::local::LocalKey<T>::with
  71: scoped_tls::ScopedKey<T>::set
  72: syntax::with_globals
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.41.0 (5e1a79984 2020-01-27) running on x86_64-unknown-linux-gnu

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

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

query stack during panic:
#0 [region_scope_tree] processing `main`
#1 [typeck_tables_of] processing `main`
#2 [typeck_tables_of] processing `main::{{closure}}#0`
#3 [type_of] processing `main::{{closure}}#0`
#4 [collect_mod_item_types] collecting item types in top-level module
#5 [analysis] running analysis passes on this crate
end of query stack
error: aborting due to previous error

@Kumassy Kumassy added 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. labels Feb 20, 2020
@pnkfelix
Copy link
Member

T-compiler triage: P-high. Leaving nomination label in place, since I don't want to disrupt WG-async-await workflow.

@pnkfelix pnkfelix added the P-high High priority label Feb 20, 2020
@LeSeulArtichaut
Copy link
Contributor

This does already ICE on 1.39.0

@Kumassy
Copy link
Author

Kumassy commented Feb 20, 2020

I could further simplify the code as:

use tokio::runtime::Runtime;

fn main() {
    let mut rt = Runtime::new().unwrap();
    let mut sum = 0;
    sum += rt.block_on(async {
        (async { }).await;
        1
    });
}

Playgrond Link

error: internal compiler error: src/librustc/middle/region.rs:1037: Encountered greater count 20 at span src/main.rs:7:9: 7:26 - expected no greater than 12

thread 'rustc' panicked at 'Box<Any>', src/librustc_errors/lib.rs:905:9
note: run with `RUST_BACKTRACE=1` environment variable to display a 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.41.0 (5e1a79984 2020-01-27) running on x86_64-unknown-linux-gnu

note: compiler flags: -C codegen-units=1 -C debuginfo=2 --crate-type bin

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

error: aborting due to previous error

@Kumassy
Copy link
Author

Kumassy commented Feb 20, 2020

However, this code does not cause ICE:

use tokio::runtime::Runtime;

fn main() {
    let mut rt = Runtime::new().unwrap();
    let mut sum = 0;
    sum = sum + rt.block_on(async {
        (async { }).await;
        1
    });
}

Playground Link

@Centril Centril added the E-needs-mcve Call for participation: This issue has a repro, but needs a Minimal Complete and Verifiable Example label Feb 21, 2020
@Centril
Copy link
Contributor

Centril commented Feb 21, 2020

If you can reproduce this without depending on tokio that would be great.

@Kumassy
Copy link
Author

Kumassy commented Feb 21, 2020

How abot this?

use futures::executor::block_on;

fn main() {
    let mut sum = 0;
    sum += block_on(async {
        (async { }).await;
        1
    });
}

Playground Link

error: internal compiler error: src/librustc/middle/region.rs:1037: Encountered greater count 20 at span src/main.rs:6:9: 6:26 - expected no greater than 8

thread 'rustc' panicked at 'Box<Any>', src/librustc_errors/lib.rs:905:9
note: run with `RUST_BACKTRACE=1` environment variable to display a 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.41.0 (5e1a79984 2020-01-27) running on x86_64-unknown-linux-gnu

note: compiler flags: -C codegen-units=1 -C debuginfo=2 --crate-type bin

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

error: aborting due to previous error

@Centril
Copy link
Contributor

Centril commented Feb 21, 2020

Minimized:

fn block_on<F>(_: F) -> usize {
    0
}

fn main() {
    let mut sum = 0;
    sum += block_on(async {
        (async {}).await;
        1
    });
}

@Centril Centril removed the E-needs-mcve Call for participation: This issue has a repro, but needs a Minimal Complete and Verifiable Example label Feb 21, 2020
@rust-lang-glacier-bot rust-lang-glacier-bot added the glacier ICE tracked in rust-lang/glacier. label Feb 21, 2020
@tmandry tmandry added AsyncAwait-OnDeck AsyncAwait-Triaged Async-await issues that have been triaged during a working group meeting. labels Feb 25, 2020
@pnkfelix
Copy link
Member

Discussed in T-compiler meeting. Keeping as P-high but removing nomination.

@nikomatsakis
Copy link
Contributor

OK so I've been investigating this a bit. I am not quite able to write-up mentoring instructions yet because I don't really understand what's going on, but I can leave a few notes.

First off, the ICE occurs in the code that is attempting to approximate what values may be live across an await. It occurs specifically when you have a foo += async { ... x.await ... } structure. The nested async blocks etc are not really needed. For example, this also fails in the same way;

fn block_on<F>(_: F) -> usize {
    0
}

fn main() {
    let mut sum = 0;
    sum += block_on(async {
        bar().await;
    });
}

async fn bar() { }

The ICE occurs in this match arm:

hir::ExprKind::AssignOp(_, ref left_expr, ref right_expr) => {

It appears to be related to some logic that is attempting to figure out a "worst case" execution order for += instructions:

// If the actual execution order turns out to be right-to-left,
// then we're fine. However, if the actual execution order is left-to-right,
// then we'll assign too low a count to any `yield` expressions
// we encounter in 'right_expression' - they should really occur after all of the
// expressions in 'left_expression'.

I confess I don't quite follow this logic anymore, but the problem has to do with entering a distinct async block. This code for example does not trigger the failure:

async fn bar() {
    let mut sum = 0;
    sum += block_on(async {
        baz().await;
    });
}

async fn baz() {
}

@nikomatsakis
Copy link
Contributor

nikomatsakis commented Mar 24, 2020

Ah, I think maybe I see the problem here actually -- I suspect the problem is that we need to clear (and then restore) the pessimistic_yield flag when we recurse into a closure body.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-async-await Area: Async & Await AsyncAwait-Triaged Async-await issues that have been triaged during a working group meeting. C-bug Category: This is a bug. glacier ICE tracked in rust-lang/glacier. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ P-high High priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

8 participants