Description
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! ☺