rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
98.98k stars 12.79k forks source link

index out of bounds at middle::subst:405 #15557

Closed bgamari closed 10 years ago

bgamari commented 10 years ago

Compiling this program results in the following error with rustc 00cdd639a93ec1dcad85cebc52214eeba0441c93,

$ RUST_LOG=rustc::middle::kind,rustc::middle::typeck::astconv RUST_BACKTRACE=1 /opt/exp/rust/x86_64-unknown-linux-gnu/stage1/bin/rustc crash.rs
InterDEBUG:rustc::middle::typeck::astconv: ast_region_to_region(lifetime='a id=8) yields ReEarlyBound(12, TypeSpace, 0, 'a)
DEBUG:rustc::middle::typeck::astconv: opt_ast_region_to_region(opt_lifetime=Some('a)) yields ReEarlyBound(12, TypeSpace, 0, 'a)
DEBUG:rustc::middle::typeck::astconv: ty_rptr r=ReEarlyBound(12, TypeSpace, 0, 'a)
DEBUG:rustc::middle::typeck::astconv: mk_pointer(ptr_ty=RPtr(ReEarlyBound(12u32, TypeSpace, 0u, syntax::ast::Name(58u32))))
DEBUG:rustc::middle::typeck::astconv: ast_region_to_region(lifetime='a id=18) yields ReEarlyBound(14, TypeSpace, 0, 'a)
DEBUG:rustc::middle::typeck::astconv: ty_of_method_or_bare_fn
DEBUG:rustc::middle::typeck::astconv: opt_ast_region_to_region(opt_lifetime=None) yields ReLateBound(19, BrAnon(0))
DEBUG:rustc::middle::typeck::astconv: ty_of_method_or_bare_fn
DEBUG:rustc::middle::kind: checking impl with self type ty_struct(DefId { krate: 0, node: 5 }, Substs { types: VecPerParamSpace {TypeSpace: [], SelfSpace: [], FnSpace: [], }, regions: NonerasedRegions(VecPerParamSpace {TypeSpace: [ReEarlyBound(14, TypeSpace, 0, Name(58))], SelfSpace: [], FnSpace: [], }) })
crash.rs:1:1: 1:1 error: internal compiler error: Type parameter out of range when substituting in region 'a (root type='au32)
crash.rs:1 use std::ty::Unsafe;

task 'rustc' failed at 'Box<Any>', /opt/exp/rust/src/libsyntax/diagnostic.rs:107

stack backtrace:
   1:     0x7fc9e8922840 - rt::backtrace::imp::write::h0a20b0836877d9ac0Mp::v0.11.0
   2:     0x7fc9e89260a0 - failure::on_fail::h9368950ceb08d6a5f8p::v0.11.0
   3:     0x7fc9e90f7eb0 - unwind::begin_unwind_inner::h1ea00938b93c7417cZd::v0.11.0
   4:     0x7fc9e75bf9a0 - unwind::begin_unwind::h12621653176727986714::v0.11.0
   5:     0x7fc9e75bf8d0 - diagnostic::SpanHandler::span_bug::h4bae981243ffc58eMac::v0.11.0
   6:     0x7fc9e990c470 - driver::session::Session::span_bug::hc179e601dc679fecYos::v0.11.0
   7:     0x7fc9e991d800 - middle::subst::SubstFolder<'a>.TypeFolder::fold_region::he5ebd51cee9a84b33rV::v0.11.0
   8:     0x7fc9e98c4270 - middle::subst::SubstFolder<'a>.TypeFolder::fold_ty::h59e6cfaf115bff0ahuV::v0.11.0
   9:     0x7fc9e98c4180 - middle::subst::T.Subst::subst_spanned::h16361762956049246516::v0.11.0
  10:     0x7fc9e9a45830 - middle::ty::lookup_field_type::h3e7b27996e88cd1bHMS::v0.11.0
  11:     0x7fc9e9901c90 - middle::ty::struct_fields::h729f0dbbcf21bf37YUS::v0.11.0
  12:     0x7fc9e9a71fd0 - middle::ty::type_contents::tc_ty::h7d685e11e712e8a6V1P::v0.11.0
  13:     0x7fc9e9a0a250 - middle::ty::type_contents::h8e510766cec98181R0P::v0.11.0
  14:     0x7fc9e9dbefd0 - middle::kind::check_item::hfa5461b803c6c40dwpR::v0.11.0
  15:     0x7fc9e9dc1ed0 - middle::kind::check_crate::h70941b58fca9fc5bVfR::v0.11.0
  16:     0x7fc9ea0edfd0 - driver::driver::phase_3_run_analysis_passes::hd94ede6fcda9089cznr::v0.11.0
  17:     0x7fc9ea0e9750 - driver::driver::compile_input::h22443fcf4e1357eafar::v0.11.0
  18:     0x7fc9ea1a0140 - driver::run_compiler::hd0a576aeaeea68b3W0t::v0.11.0
  19:     0x7fc9ea1a0050 - driver::main_args::closure.127086
  20:     0x7fc9ea1b4560 - task::TaskBuilder<S>::try_future::closure.128230
  21:     0x7fc9ea1b4230 - task::TaskBuilder<S>::spawn_internal::closure.128207
  22:     0x7fc9ec193d00 - task::spawn_opts::closure.7759
  23:     0x7fc9e9252e60 - rust_try
  24:     0x7fc9e90f4490 - unwind::try::hb071379e55686597BNd::v0.11.0
  25:     0x7fc9e90f4190 - task::Task::run::ha6ba4f51b8a2758dXYc::v0.11.0
  26:     0x7fc9ec193ac0 - task::spawn_opts::closure.7705
  27:     0x7fc9e90f6ce0 - thread::thread_start::hc20479a5894ce695vld::v0.11.0
  28:     0x7fc9e83a40c0 - start_thread
  29:     0x7fc9e8dbb2d9 - __clone
  30:                0x0 - <unknown>
bgamari commented 10 years ago

I've tried looking at this unfortunately it appears to be a bit deep for the time I have available. I found this patch to be somewhat helpful for debugging. It produces,

test.rs:1:1: 1:1 error: internal compiler error: Type parameter out of range when substituting in region 'a (root type='aRegValue<u32,AReg1<'a>>)
test.rs:1 use std::ty::Unsafe;

Unfortunately I'm not familiar enough with the relevant code to know why this might be the case.

bgamari commented 10 years ago

Here is a more minimal test case,

use std::ty::Unsafe;

struct AReg1<'a>(&'a u32);

impl<'a> Drop for AReg1<'a> {
  fn drop(&mut self) {}
}

If one comments out the impl Drop the crash does not occur.

bgamari commented 10 years ago

Here is a rough call graph that I've worked out

driver::driver::phase_3_run_analysis_passes
  middle::typeck::check_crate
    middle::typeck::collect::collect_item_types
      collect::convert
        ItemStruct generics has region
        collect::ty_of_item
          in ItemStruct case
          collect::ty_generics_for_type
            collect::ty_generics
          converts ItemStruct to PolyTy

        PolyTy generics still has region
        collect::convert_struct
          converts ast::StructDef to ty::t
          mk_item_substs
          ty::mk_struct

  Somewhere in here Subst on struct is dropped

  middle::kind::check_crate
    middle::kind::check_item
      middle::ty::type_contents
        match on `get(ty).sty`
        find `ty_struct(did, substs)`
        middle::ty::struct_fields
          middle::ty::lookup_field_type
            middle::subst::Subst::subst_spanned
              middle::subst::TypeFolder::fold_region(r: ty::Region)
                match on `r`
                find ty::ReEarlyBound(_, space, i, region_name)
                match on `substs.regions`
                find NonerasedRegions(regions)
                look for region index `i` in substitutions for space `space`
                fail
bgamari commented 10 years ago

The problem appears to be here where a new ty::t is created with an empty Substs. When the substitution engine then goes to perform a substitution for 'a, it finds none and crashes.

bgamari commented 10 years ago

Perhaps the check,

if !struct_tpt.generics.has_type_params(subst::TypeSpace) { ... }

is supposed to read,

if !struct_tpt.generics.has_type_params(subst::TypeSpace)
  && !struct_tpt.generics.has_region_params(subst::TypeSpace) { ... }
bgamari commented 10 years ago

Closing in favor of the pull request.