Description
I am writing my own little math library to learn rust. I was successful in implementing a mathematical vector type which uses a const generic parameter to specify its dimension/length and stores its values in an array of type [T; DIM]
under the hood. When trying to implement the same pattern for a matrix that uses a flat array to store its values, I encounter the following error:
#![feature(const_generics)]
pub type MatrixArray<T, const N : usize, const M : usize> = [T; N * M];
pub struct Matrix<T, const N : usize, const M : usize>
where T : Copy + Sized
{
store : MatrixArray<T, N, M>,
}
impl<T, const N : usize, const M : usize> Default for Matrix<T, N, M>
where T : Copy + Sized + Default
{
fn default() -> Self {
let zero_comps = unsafe {
let mut comps = std::mem::MaybeUninit::< MatrixArray<T, N, M> >::uninit().assume_init();
for comp in comps.iter_mut() {
*comp = T::default();
}
comps
};
Self {
store : zero_comps
}
}
}
fn main() {
println!("Does not compile!");
}
Errors:
Compiling playground v0.0.1 (/playground)
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
--> src/main.rs:1:12
|
1 | #![feature(const_generics)]
| ^^^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default
warning: field is never read: `store`
--> src/main.rs:8:5
|
8 | store : MatrixArray<T, N, M>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(dead_code)]` on by default
error: internal compiler error: constant in type had an ignored error: TooGeneric
--> src/main.rs:8:5
|
8 | store : MatrixArray<T, N, M>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: internal compiler error: constant in type had an ignored error: TooGeneric
--> src/main.rs:16:29
|
16 | let mut comps = std::mem::MaybeUninit::< MatrixArray<T, N, M> >::uninit().assume_init();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: internal compiler error: constant in type had an ignored error: TooGeneric
--> src/main.rs:16:29
|
16 | let mut comps = std::mem::MaybeUninit::< MatrixArray<T, N, M> >::uninit().assume_init();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: internal compiler error: broken MIR in DefId(0:17 ~ playground[a92e]::{{impl}}[0]::default[0]) (CanonicalUserTypeAnnotation { user_ty: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: TypeOf(DefId(2:1154 ~ core[77d3]::mem[0]::maybe_uninit[0]::{{impl}}[2]::uninit[0]), UserSubsts { substs: [^0], user_self_ty: Some(UserSelfTy { impl_def_id: DefId(2:1151 ~ core[77d3]::mem[0]::maybe_uninit[0]::{{impl}}[2]), self_ty: std::mem::MaybeUninit<[T; _]> }) }) }, span: src/main.rs:16:29: 16:84, inferred_ty: fn() -> std::mem::MaybeUninit<[T; _]> {std::mem::MaybeUninit::<[T; _]>::uninit} }): bad user type AscribeUserType(fn() -> std::mem::MaybeUninit<[T; _]> {std::mem::MaybeUninit::<[T; _]>::uninit}, DefId(2:1154 ~ core[77d3]::mem[0]::maybe_uninit[0]::{{impl}}[2]::uninit[0]) UserSubsts { substs: [_], user_self_ty: Some(UserSelfTy { impl_def_id: DefId(2:1151 ~ core[77d3]::mem[0]::maybe_uninit[0]::{{impl}}[2]), self_ty: std::mem::MaybeUninit<[T; _]> }) }): NoSolution
error: internal compiler error: broken MIR in DefId(0:17 ~ playground[a92e]::{{impl}}[0]::default[0]) (NoSolution): could not prove WellFormed(std::mem::MaybeUninit<[T; _]>)
--> src/main.rs:16:29
|
16 | let mut comps = std::mem::MaybeUninit::< MatrixArray<T, N, M> >::uninit().assume_init();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: internal compiler error: broken MIR in DefId(0:17 ~ playground[a92e]::{{impl}}[0]::default[0]) (NoSolution): could not prove WellFormed(std::mem::MaybeUninit<[T; _]>)
--> src/main.rs:14:5
|
14 | / fn default() -> Self {
15 | | let zero_comps = unsafe {
16 | | let mut comps = std::mem::MaybeUninit::< MatrixArray<T, N, M> >::uninit().assume_init();
17 | | for comp in comps.iter_mut() {
... |
24 | | }
25 | | }
| |_____^
error: internal compiler error: broken MIR in DefId(0:17 ~ playground[a92e]::{{impl}}[0]::default[0]) (NoSolution): could not prove WellFormed([T; _])
--> src/main.rs:14:5
|
14 | / fn default() -> Self {
15 | | let zero_comps = unsafe {
16 | | let mut comps = std::mem::MaybeUninit::< MatrixArray<T, N, M> >::uninit().assume_init();
17 | | for comp in comps.iter_mut() {
... |
24 | | }
25 | | }
| |_____^
thread 'rustc' panicked at 'no errors encountered even though `delay_span_bug` issued', src/librustc_errors/lib.rs:345:17
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
error: internal compiler error: unexpected panic
note: the compiler unexpectedly panicked. this is a bug.
note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports
note: rustc 1.42.0-nightly (da3629b05 2019-12-29) running on x86_64-unknown-linux-gnu
note: compiler flags: -C codegen-units=1 -C debuginfo=2 --crate-type bin
note: some of the compiler flags provided by cargo are hidden
error: could not compile `playground`.
To learn more, run the command again with --verbose.
Interestingly, I only get the MIR error message in my full project, but not the TooGeneric
error, which I put down to having more instances where the type is used therefore triggering monomorphization.
When I do not define the generic type but only use [T; N * M]
directly, I get normal error messages about non-matching types which I expect because of the treatment of this expression as a projection [T; _]
.
I suspect this to be another instance of #43408.