Skip to content

Transmutations between associated types on a trait with a non-'static lifetime parameter causes ICE #21174

Closed
@chris-morgan

Description

@chris-morgan

Minimised example:

trait Trait<'a> {
    type A;
    type B;
}

fn foo<'a, T: Trait<'a>>(value: T::A) {
    let new: T::B = unsafe { std::mem::transmute(value) };
    //let new: T::B = unsafe { std::mem::transmute_copy(&value) };
}

fn main() { }

Both the transmute and the transmute_copy fail in the same way, with an ICE:

ice.rs:7:30: 7:56 error: internal compiler error: Encountered early bound region when generalizing: ReEarlyBound(18, FnSpace, 0, 'a)
ice.rs:7     let new: T::B = unsafe { std::mem::transmute(value) };
                                      ^~~~~~~~~~~~~~~~~~~~~~~~~~
note: the compiler unexpectedly panicked. 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
thread 'rustc' panicked at 'Box<Any>', /home/chris/rust/src/libsyntax/diagnostic.rs:123

stack backtrace:
   1:     0x7ffc31fe8bf0 - sys::backtrace::write::h7b4652da93e0a6048Rt
   2:     0x7ffc3200a5d0 - failure::on_fail::h2a6984dfe8e1b221S5z
   3:     0x7ffc31f794d0 - rt::unwind::begin_unwind_inner::hbfa34a31f6bc957fKKz
   4:     0x7ffc2cf14780 - rt::unwind::begin_unwind::h11050972250347564622
   5:     0x7ffc2cf14710 - diagnostic::SpanHandler::span_bug::h772b340ea76d9a16uVF
   6:     0x7ffc303c2360 - middle::infer::combine::Generalizer<'cx, 'tcx>.ty_fold..TypeFolder<'tcx>::fold_region::hd76c2168a05cd0eeAYq
   7:     0x7ffc303c1e90 - middle::ty_fold::subst..Substs<'tcx>.TypeFoldable<'tcx>::fold_with::h17510703942836659071
   8:     0x7ffc303c26e0 - middle::ty_fold::super_fold_trait_ref::h17123474716300025693
   9:     0x7ffc303c1250 - middle::infer::combine::Generalizer<'cx, 'tcx>.ty_fold..TypeFolder<'tcx>::fold_ty::hf8dc4a34717656fdCXq
  10:     0x7ffc303bd210 - middle::infer::combine::CombineFields<'f, 'tcx>::instantiate::h838ff536ad48ff58tPq
  11:     0x7ffc303b6d90 - middle::infer::sub::Sub<'f, 'tcx>.Combine<'tcx>::tys::hb3084ddcbc6715f5Wvy
  12:     0x7ffc304348b0 - middle::infer::InferCtxt<'a, 'tcx>::sub_types::h1fa7aacfc8b9ab9930A
  13:     0x7ffc317aa910 - check::expected_types_for_fn_args::hb8f41846e0806e78Vvn
  14:     0x7ffc317a9bc0 - check::callee::confirm_builtin_call::hea6ce4b50a648ec6MFj
  15:     0x7ffc317a83c0 - check::callee::check_call::hde77aff579724b74lBj
  16:     0x7ffc317e6e70 - check::check_expr_with_unifier::h10444047677950281470
  17:     0x7ffc317ba6d0 - check::check_block_with_expected::h9f04f4b5abf44e4aGsp
  18:     0x7ffc317e6e70 - check::check_expr_with_unifier::h10444047677950281470
  19:     0x7ffc3180c250 - check::check_decl_local::h348a4ac1e0364dcfFmp
  20:     0x7ffc317ba6d0 - check::check_block_with_expected::h9f04f4b5abf44e4aGsp
  21:     0x7ffc317a6550 - check::check_fn::hdc4ea1d4d99eebd6Vek
  22:     0x7ffc317b7750 - check::check_bare_fn::hceca8b5a45d19c19g4j
  23:     0x7ffc317af4b0 - check::check_item::h97ffd72351ec0a713mk
  24:     0x7ffc3187b4f0 - check_crate::unboxed_closure.30734
  25:     0x7ffc318760b0 - check_crate::h401329d2b807aaabney
  26:     0x7ffc32542c20 - driver::phase_3_run_analysis_passes::ha0279b98663a6ec7EEa
  27:     0x7ffc32530a00 - driver::compile_input::habc7e9a404c53712Aba
  28:     0x7ffc325f2420 - run_compiler::h21eb51f8a0ee17ece5b
  29:     0x7ffc325f0b90 - thunk::F.Invoke<A, R>::invoke::h9539250436629313017
  30:     0x7ffc325efaf0 - rt::unwind::try::try_fn::h11124252207944909230
  31:     0x7ffc3207a2a0 - rust_try_inner
  32:     0x7ffc3207a290 - rust_try
  33:     0x7ffc325efda0 - thunk::F.Invoke<A, R>::invoke::h11373657575374727143
  34:     0x7ffc31ff8270 - sys::thread::thread_start::h4220cbfce5fdbe98VJw
  35:     0x7ffc2c732250 - start_thread
  36:     0x7ffc31c29219 - clone
  37:                0x0 - <unknown>

Adding 'static bounds to A and B on the trait or in the fn’s where clause doesn’t fix it, but changing <'a, T: Trait<'a>> to <T: Trait<'static>> does fix it. (In the particular case that I was dealing with, the lifetime could be changed to 'static where this was a problem, but it would only have taken a slight variation of it for me to be in a situation where I needed a non-'static implementation. There were, of course, other arguments which were using the 'a.)

The whole thing around there seems a bit fragile and I’m not quite sure what’s supposed to work and what’s not; if we just take an T::A and transmute it to (), for example, we get “error: cannot transmute to or from a type that contains type parameters in its interior [E0139]”. Anyway, an ICE is always a bug, so here’s the report! ☺

Metadata

Metadata

Assignees

No one assigned

    Labels

    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