Skip to content

Recursive type with infinite size leads to internal compiler error (try_mark_green() - Forcing the DepNode should have set its color) #57373

Closed
@BafDyce

Description

@BafDyce

A (rather complex) enum-based data structure (code below) lead to the following compiler panic:

$ RUST_BACKTRACE=1 cargo run
   Compiling nested-enums v0.1.0 (file:///home/programmer/programming/rustc-bugs/nested-enums)
error: internal compiler error: src/librustc/dep_graph/graph.rs:634: try_mark_green() - Forcing the DepNode should have set its color

thread 'rustc' panicked at 'Box<Any>', src/librustc_errors/lib.rs:590:9
stack backtrace:
   0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
             at src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:39
   1: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:70
   2: std::panicking::default_hook::{{closure}}
             at src/libstd/sys_common/backtrace.rs:58
             at src/libstd/panicking.rs:200
   3: std::panicking::default_hook
             at src/libstd/panicking.rs:215
   4: rustc::util::common::panic_hook
   5: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:482
   6: std::panicking::begin_panic
   7: rustc_errors::Handler::bug
   8: rustc::util::bug::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::util::bug::opt_span_bug_fmt
  13: rustc::util::bug::bug_fmt
  14: rustc::dep_graph::graph::DepGraph::try_mark_green
  15: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::try_mark_green_and_read
  16: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::try_get_with
  17: rustc::ty::AdtDef::sized_constraint
  18: rustc::ty::AdtDef::sized_constraint_for_ty
  19: rustc::ty::AdtDef::sized_constraint_for_ty
  20: <core::iter::FlatMap<I, U, F> as core::iter::iterator::Iterator>::next
  21: <smallvec::SmallVec<A> as core::iter::traits::FromIterator<<A as smallvec::Array>::Item>>::from_iter
  22: <T as rustc::ty::context::InternIteratorElement<T, R>>::intern_with
  23: rustc::ty::adt_sized_constraint
  24: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors<'tcx> for rustc::ty::query::queries::adt_sized_constraint<'tcx>>::compute
  25: rustc::dep_graph::graph::DepGraph::with_task_impl
  26: <rustc::ty::query::plumbing::JobOwner<'a, 'tcx, Q>>::start
  27: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::force_query_with_job
  28: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::force_query
  29: rustc::ty::query::plumbing::force_from_dep_node
  30: rustc::dep_graph::graph::DepGraph::try_mark_green
  31: rustc::dep_graph::graph::DepGraph::try_mark_green
  32: rustc::dep_graph::graph::DepGraph::try_mark_green
  33: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::try_mark_green_and_read
  34: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::try_get_with
  35: rustc::traits::query::evaluate_obligation::<impl rustc::infer::InferCtxt<'cx, 'gcx, 'tcx>>::evaluate_obligation
  36: rustc::traits::query::evaluate_obligation::<impl rustc::infer::InferCtxt<'cx, 'gcx, 'tcx>>::evaluate_obligation_no_overflow
  37: <rustc_data_structures::obligation_forest::ObligationForest<O>>::process_obligations
  38: <rustc::traits::fulfill::FulfillmentContext<'tcx> as rustc::traits::engine::TraitEngine<'tcx>>::select_where_possible
  39: <rustc::traits::fulfill::FulfillmentContext<'tcx> as rustc::traits::engine::TraitEngine<'tcx>>::select_all_or_error
  40: rustc_typeck::check::FnCtxt::select_all_obligations_or_error
  41: rustc::ty::context::GlobalCtxt::enter_local
  42: rustc_typeck::check::wfcheck::check_item_well_formed
  43: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors<'tcx> for rustc::ty::query::queries::check_item_well_formed<'tcx>>::compute
  44: rustc::dep_graph::graph::DepGraph::with_task_impl
  45: <rustc::ty::query::plumbing::JobOwner<'a, 'tcx, Q>>::start
  46: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::force_query_with_job
  47: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::try_get_with
  48: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::ensure_query
  49: <rustc_typeck::check::wfcheck::CheckTypeWellFormedVisitor<'a, 'tcx> as rustc::hir::intravisit::Visitor<'v>>::visit_item
  50: rustc::hir::Crate::visit_all_item_likes
  51: rustc::util::common::time
  52: rustc_typeck::check_crate
  53: <std::thread::local::LocalKey<T>>::with
  54: rustc::ty::context::TyCtxt::create_and_enter
  55: rustc_driver::driver::compile_input
  56: rustc_driver::run_compiler_with_pool
  57: <scoped_tls::ScopedKey<T>>::set
  58: rustc_driver::run_compiler
  59: <scoped_tls::ScopedKey<T>>::set
  60: syntax::with_globals
  61: __rust_maybe_catch_panic
             at src/libpanic_unwind/lib.rs:92
  62: <F as alloc::boxed::FnBox<A>>::call_box
  63: std::sys::unix::thread::Thread::new::thread_start
             at /rustc/b2b7a063af39455d7362524da3123c34c3f4842e/src/liballoc/boxed.rs:734
             at src/libstd/sys_common/thread.rs:14
             at src/libstd/sys/unix/thread.rs:81
  64: start_thread
  65: clone
query stack during panic:
#0 [adt_sized_constraint] processing `DieRollAction`
#1 [check_item_well_formed] processing `Action`
end of query stack
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.33.0-nightly (b2b7a063a 2019-01-01) 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: Could not compile `nested-enums`.

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

Instead, I would have expected the following error message:

error[E0072]: recursive type `Outer` has infinite size

This is the code:

#[derive(Debug)]
pub enum Action {
    Unknown(Option<Vec<String>>),
    AreaSelection(usize, Box<Action>),
    CardGive(usize, usize, Option<Vec<usize>>),
    CardPlayed(usize),
    CardSell(Option<Vec<usize>>, usize, usize, Option<usize>, usize),
    CardTake(usize, Option<Vec<usize>>),
    // THE BUG EXISTS IN THIS ENUM-VARIANT (see definition below)
    DieRoll(DieRollAction),
    HouseBuild(usize, Option<usize>),
    HouseDestruct,
    HouseReplace(usize),
    IgnoreRandomEvent(usize),
    IncreaseCardBudget(usize),
    Interrupt,
    InterruptSelf,
    InvestigatePersonalities(Option<Vec<usize>>),
    Kill(usize, bool, usize, bool),
    Loan(usize, usize),
    LoanPayback(usize),
    MinionMove(usize, usize, usize),
    MinionPlace(usize, bool),
    MinionSwap((usize, usize), (usize, usize)),
    MoneyGive(usize),
    MoneyTake(usize, usize),
    None,
    PersonalityExchange(Option<usize>, Option<usize>),
    RandomEvent,
    SwapHand((usize, Option<Vec<usize>>), (usize, Option<Vec<usize>>)),
    Text(Vec<Action>),
    TroublePlace(usize),
    TroubleRemove(usize),
    TurnStart(usize, bool),
    TurnEnd(usize, Vec<usize>),
}

#[derive(Debug)]
pub enum DieRollAction {
    DieRollRequest(u64, usize),
    DieRollResult(u64, Vec<usize>),
    Specification(usize, usize),
    // Here we create a recursive data structure without indirection
    DieRollExec(u64, (usize, Action)),
}

fn main() {
    let oo = Action::TurnStart(0, true);
    println!("{:#?}", oo);
}

Important Note: For submitting this bug report, I tried to sanitize the data structure (less variants, simplified names, etc.), however doing any changes (even if just renaming Action to something like Outer) removed the bug and resulted in the "infinite size" error, as expected.

Metadata

Metadata

Assignees

Labels

A-incr-compArea: Incremental compilationC-bugCategory: This is a bug.I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️P-mediumMedium priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions