Skip to content

ICE: lifetime substitution in struct fields when struct implements Drop #14889

Closed
@pnkfelix

Description

@pnkfelix

This is an injection from sometime post 0.8 (probably very recent).

Some code:

#[deriving(Show)]
pub struct Context<'a> {
    field: Nested<'a>,
}

#[deriving(Show)]
pub struct Nested<'a>;

#[cfg(not(no_drop))]
impl<'a> Drop for Context<'a> {
    fn drop(&mut self) {
        println!("Dropping {}", *self);
    }
}

fn main() {
    let c = Context { field: Nested };
    println!("{}", c);
}

A transcript showing the ICE:

% rustc --version
rustc 0.11.0-pre (2c6caad 2014-06-14 04:46:46 +0000)
host: x86_64-apple-darwin
% rustc /tmp/foo.rs
error: internal compiler error: unexpected failure
note: the compiler hit an unexpected failure path. this is a bug.
note: we would appreciate a bug report: http://doc.rust-lang.org/complement-bugreport.html
note: run with `RUST_BACKTRACE=1` for a backtrace
task 'rustc' failed at 'index out of bounds: the len is 0 but the index is 0', /Users/pnkfelix/Dev/Mozilla/rust.git/src/librustc/lib.rs:1


% rustc --cfg no_drop /tmp/foo.rs
% 

The backtrace:

   1:        0x10be4c592 - rt::backtrace::imp::write::h4595e46a96942472aPp::v0.11.0.pre
   2:        0x10be5384a - failure::on_fail::h36bc5bc9e9066b83n5p::v0.11.0.pre
   3:        0x10c0dda29 - unwind::begin_unwind_inner::h7555e4d38a651235mOd::v0.11.0.pre
   4:        0x10c0dd5aa - unwind::begin_unwind_fmt::h0a25606ea9356b4ePLd::v0.11.0.pre
   5:        0x10c0dd341 - rust_begin_unwind
   6:        0x10c13717e - failure::begin_unwind::h2c605326302113e523v::v0.11.0.pre
   7:        0x10c13b709 - failure::fail_bounds_check::hce749997eee154e7e2v::v0.11.0.pre
   8:        0x108fbe691 - middle::subst::SubstFolder<'a>.TypeFolder::fold_region::h00e6419dabf970e3TqU::v0.11.0.pre
   9:        0x108fbe518 - middle::ty_fold::VecPerParamSpace<T>.TypeFoldable::fold_with::closure.62801
  10:        0x108fbd965 - middle::subst::VecPerParamSpace<T>::map::h10274010684604774229::v0.11.0.pre
  11:        0x108fbd70c - middle::ty_fold::TypeFolder::fold_substs::h9304712281823043231::v0.11.0.pre
  12:        0x108f673a4 - middle::subst::SubstFolder<'a>.TypeFolder::fold_ty::h462b8f3f57f4cc13srU::v0.11.0.pre
  13:        0x108f66b1e - middle::subst::T.Subst::subst_spanned::h15731439402557813363::v0.11.0.pre
  14:        0x1090d94f3 - middle::ty::lookup_field_type::h77f22892d9727d8a25R::v0.11.0.pre
  15:        0x108fa5856 - middle::ty::struct_fields::hea32f38181375c78jeS::v0.11.0.pre
  16:        0x109108152 - middle::ty::type_contents::tc_ty::he654f2f431a75d65OnP::v0.11.0.pre
  17:        0x1090a2191 - middle::ty::type_contents::h7ffc17733b627153KmP::v0.11.0.pre
  18:        0x109481b48 - middle::kind::check_item::h96b5a0fbc7aa7560tIV::v0.11.0.pre
  19:        0x109483eb1 - middle::kind::check_crate::h63e4bac94b391151SyV::v0.11.0.pre
  20:        0x10983ac1a - driver::driver::phase_3_run_analysis_passes::h4aab6aaf3689b4c1wfv::v0.11.0.pre
  21:        0x10983292a - driver::driver::compile_input::hdd225ecd32713dbbL3u::v0.11.0.pre
  22:        0x1098f455e - driver::run_compiler::hd1f9c8f1db63fe6djLx::v0.11.0.pre
  23:        0x1098f1ee6 - driver::main_args::closure.98487
  24:        0x10990c137 - driver::monitor::closure.99578
  25:        0x10990735b - task::TaskBuilder::try::closure.99341
  26:        0x108efabec - task::spawn_opts::closure.7249
  27:        0x10c0da5b8 - task::Task::run::closure.5244
  28:        0x10c150a0c - rust_try
  29:        0x10c0dceca - unwind::try::he15ed9069692b5dcLCd::v0.11.0.pre
  30:        0x10c0da485 - task::Task::run::hf8b632ad7174b7e9XSc::v0.11.0.pre
  31:        0x108efaa5b - task::spawn_opts::closure.7221
  32:        0x10c0dc509 - thread::thread_start::hc88622d48843830cmad::v0.11.0.pre
  33:     0x7fff8c110899 - _pthread_body
  34:     0x7fff8c11072a - _pthread_struct_init

Here is another version of the code that is closer to what originally led me to discover this ICE:

#[deriving(Show)]
pub struct Context<'a> {
    field: &'a (),
}

#[cfg(not(no_drop))]
impl<'a> Drop for Context<'a> {
    fn drop(&mut self) {
        println!("Dropping {}", *self);
    }
}

fn main() {
    let msg = ();
    let c = Context { field: &msg };
    println!("{}", c);
}

Note: Sometime between 0.8 and 0.10, we started requiring implementors of Drop to satisfy Send. So it is possible the latter code is just incorrect under the new rules.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-destructorsArea: Destructors (`Drop`, …)E-needs-testCall for participation: An issue has been fixed and does not reproduce, but no test has been added.I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions