I was playing around with the new associated constants trying to make type-level integers. Creating an array with a length defined by Five works, but creating one with the product of Multiply as a length causes the compiler to panic.
This is the code I tried to run:
use std::marker::PhantomData;
fn main() {
let _arr = [1; <Multiply<Five, Five>>::VAL]; // The compiler finds this scary for some reason.
}
trait TypeVal<T> {
const VAL: T;
}
struct Five;
impl TypeVal<usize> for Five {
const VAL: usize = 5;
}
struct Multiply<N, M> {
_n: PhantomData<N>,
_m: PhantomData<M>,
}
impl<N, M> TypeVal<usize> for Multiply<N, M>
where N: TypeVal<usize>,
M: TypeVal<usize>,
{
const VAL: usize = N::VAL * M::VAL;
}
rustc --version --verbose:
rustc 1.20.0 (f3d6973f4 2017-08-27)
binary: rustc
commit-hash: f3d6973f41a7d1fb83029c9c0ceaf0f5d4fd7208
commit-date: 2017-08-27
host: x86_64-unknown-linux-gnu
release: 1.20.0
LLVM version: 4.0
Backtrace:
thread 'rustc' panicked at 'internal error: entered unreachable code', /checkout/src/librustc_mir/hair/cx/mod.rs:140:8
stack backtrace:
0: 0x7f0518299d13 - std::sys::imp::backtrace::tracing::imp::unwind_backtrace::hcdf51e4c9dc54357
at /checkout/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
1: 0x7f0518294524 - std::sys_common::backtrace::_print::h9da91fd31a37d0f1
at /checkout/src/libstd/sys_common/backtrace.rs:71
2: 0x7f05182a7333 - std::panicking::default_hook::{{closure}}::h46820a72bf0cb624
at /checkout/src/libstd/sys_common/backtrace.rs:60
at /checkout/src/libstd/panicking.rs:380
3: 0x7f05182a703a - std::panicking::default_hook::h4c1ef1cc83189c8e
at /checkout/src/libstd/panicking.rs:390
4: 0x7f05182a77f7 - std::panicking::rust_panic_with_hook::h99016f44bdcb8544
at /checkout/src/libstd/panicking.rs:611
5: 0x7f05160699fa - std::panicking::begin_panic_new::h20bde0fa96b5baa3
6: 0x7f05160df42c - rustc_mir::hair::cx::Cx::fatal_const_eval_err::hf97cdba7fc5f66cd
7: 0x7f05160e3be8 - rustc_mir::hair::cx::expr::make_mirror_unadjusted::hbe391e56243cb2db
8: 0x7f05160dfda8 - rustc_mir::hair::cx::expr::<impl rustc_mir::hair::Mirror<'tcx> for &'tcx rustc::hir::Expr>::make_mirror::h4821ea617bc41d74
9: 0x7f05160c6b96 - <rustc_mir::hair::ExprRef<'tcx> as rustc_mir::build::into::EvalInto<'tcx>>::eval_into::h40e42cf42cf544dd
10: 0x7f05160cbed5 - rustc_mir::build::matches::<impl rustc_mir::build::Builder<'a, 'gcx, 'tcx>>::expr_into_pattern::h4a9bcd58a09e3d5d
11: 0x7f05160d1814 - rustc_mir::build::scope::<impl rustc_mir::build::Builder<'a, 'gcx, 'tcx>>::in_scope::h81e04d3bdbceb472
12: 0x7f05160b83d0 - rustc_mir::build::block::<impl rustc_mir::build::Builder<'a, 'gcx, 'tcx>>::ast_block_stmts::hafef382cef3e8204
13: 0x7f05160d1b99 - rustc_mir::build::scope::<impl rustc_mir::build::Builder<'a, 'gcx, 'tcx>>::in_scope::hc808f0a51c457ee5
14: 0x7f05160d170b - rustc_mir::build::scope::<impl rustc_mir::build::Builder<'a, 'gcx, 'tcx>>::in_opt_scope::hd179717c8f13dbe1
15: 0x7f05160c1796 - rustc_mir::build::expr::into::<impl rustc_mir::build::Builder<'a, 'gcx, 'tcx>>::into_expr::h111f38b2b7786042
16: 0x7f05160c6bbf - <rustc_mir::hair::ExprRef<'tcx> as rustc_mir::build::into::EvalInto<'tcx>>::eval_into::h40e42cf42cf544dd
17: 0x7f05160c11cd - rustc_mir::build::expr::into::<impl rustc_mir::build::Builder<'a, 'gcx, 'tcx>>::into_expr::h111f38b2b7786042
18: 0x7f05160c6bbf - <rustc_mir::hair::ExprRef<'tcx> as rustc_mir::build::into::EvalInto<'tcx>>::eval_into::h40e42cf42cf544dd
19: 0x7f05160c11cd - rustc_mir::build::expr::into::<impl rustc_mir::build::Builder<'a, 'gcx, 'tcx>>::into_expr::h111f38b2b7786042
20: 0x7f0516114bdc - rustc_mir::transform::mir_const::h44528d9ec6133f0c
21: 0x7f051534640f - rustc::ty::maps::<impl rustc::ty::maps::queries::mir_const<'tcx>>::try_get_with::{{closure}}::run_provider::hbd2ca39015d187b6
22: 0x7f051512f1da - rustc::dep_graph::graph::DepGraph::with_task::h296e6bba1fa15a03
23: 0x7f0515346940 - rustc::ty::maps::<impl rustc::ty::maps::queries::mir_const<'tcx>>::try_get::h11e76ae1dcdda37d
24: 0x7f05153805ba - rustc::ty::maps::TyCtxtAt::mir_const::hdaca076bb4373d8e
25: 0x7f051537d1c6 - rustc::ty::maps::<impl rustc::ty::context::TyCtxt<'a, 'tcx, 'lcx>>::mir_const::h12dfe73edca72c4f
26: 0x7f0516115aea - rustc_mir::transform::mir_validated::h4ab61ba27ff483ec
27: 0x7f051534773f - rustc::ty::maps::<impl rustc::ty::maps::queries::mir_validated<'tcx>>::try_get_with::{{closure}}::run_provider::h4e5b76b3ab5f815f
28: 0x7f051512f1da - rustc::dep_graph::graph::DepGraph::with_task::h296e6bba1fa15a03
29: 0x7f0515347c70 - rustc::ty::maps::<impl rustc::ty::maps::queries::mir_validated<'tcx>>::try_get::h89ca9fc9b1475a29
30: 0x7f05153806fa - rustc::ty::maps::TyCtxtAt::mir_validated::ha53b8d1b04be8f61
31: 0x7f051537d1f6 - rustc::ty::maps::<impl rustc::ty::context::TyCtxt<'a, 'tcx, 'lcx>>::mir_validated::hd499970927ef8808
32: 0x7f0517c304ca - rustc_borrowck::borrowck::borrowck::h0d64b1bfc871d914
33: 0x7f051512eeb4 - rustc::dep_graph::graph::DepGraph::with_task::h1ba8376c1cfaccee
34: 0x7f05153523df - rustc::ty::maps::<impl rustc::ty::maps::queries::borrowck<'tcx>>::try_get::hfdf892ac1155f936
35: 0x7f051537d532 - rustc::ty::maps::<impl rustc::ty::context::TyCtxt<'a, 'tcx, 'lcx>>::borrowck::h9e740c44bdab1305
36: 0x7f0517c30367 - rustc_borrowck::borrowck::check_crate::h0d548219b93e53b4
37: 0x7f051863b014 - rustc_driver::driver::phase_3_run_analysis_passes::{{closure}}::h5664029733f1f6d5
38: 0x7f051862efb0 - rustc_driver::driver::phase_3_run_analysis_passes::hf53b3e845cb6e837
39: 0x7f0518616d76 - rustc_driver::driver::compile_input::h26cfd26116d1d14c
40: 0x7f0518654ce1 - rustc_driver::run_compiler::h8741b5aff2ed69fc
41: 0x7f051857f21f - std::sys_common::backtrace::__rust_begin_short_backtrace::h4e951eb2de4f99f0
42: 0x7f05182d6d4c - __rust_maybe_catch_panic
at /checkout/src/libpanic_unwind/lib.rs:98
43: 0x7f05185b0900 - <F as alloc::boxed::FnBox<A>>::call_box::h140b04f7a2d92fc5
44: 0x7f05182a627b - std::sys::imp::thread::Thread::new::thread_start::h10fad04495d944f7
at /checkout/src/liballoc/boxed.rs:661
at /checkout/src/libstd/sys_common/thread.rs:21
at /checkout/src/libstd/sys/unix/thread.rs:84
45: 0x7f05135596b9 - start_thread
46: 0x7f0517f4f3dc - clone
47: 0x0 - <unknown>
I hope this is helpful.
Found something that might help:
use std::marker::PhantomData;
trait Val {
const VAL: usize;
}
struct Five;
impl Val for Five {
const VAL: usize = 5;
}
struct Multiply<T, U> {
_t: PhantomData<T>,
_u: PhantomData<U>,
}
impl<T: Val, U: Val> Val for Multiply<T, U> {
const VAL: usize = T::VAL * U::VAL;
}
fn main() {
let arr: [usize; 25] = [1; <Multiply<Five, Five>>::VAL];
println!("{:?}", arr);
}
<Multiply<Five, Five>>::VAL is 25usize, so there should be no type mismatch. However, I got this:
error[E0308]: mismatched types
--> src/main.rs:21:28
|
21 | let arr: [usize; 25] = [1; <Multiply<Five, Five>>::VAL];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an array with a fixed size of 25 elements, found one with 0 elements
|
= note: expected type `[usize; 25]`
found type `[usize; 0]`
I get the same backtrace when I annotate the type as [usize; 0].
The expression seems to evaulate properly to 25 in this context:
let num = <Multiply<Five, Five>>::VAL;
assert_eq!(num, 25);
Note that associated constants are not supported in array type [T; n] yet (#44168).
It seems like the compiler should say that, rather than crashing. This is the stable release, after all.
This no longer seems to ICE.
Most helpful comment
It seems like the compiler should say that, rather than crashing. This is the stable release, after all.