Description
The usage of const-generic types with specialization started to cause errors since nightly-2020-05-20 (rustc 2020-05-19).
All the following samples build successfully and work with nightly-2020-05-19 toolchain (rustc 2020-05-18) and earlier.
Code
#![feature(const_generics)]
#![feature(specialization)]
trait ValTypeSelect {
type ValTypeInner;
}
struct UseSmallInt<const N: bool>{}
impl<const N: bool> ValTypeSelect for UseSmallInt<N> {
default type ValTypeInner = i32;
}
impl ValTypeSelect for UseSmallInt<true> {
type ValTypeInner = i8;
}
struct MyStruct<const VAL: usize>
{
val: <UseSmallInt<{VAL!=0}> as ValTypeSelect>::ValTypeInner,
}
Gives the error:
error[E0284]: type annotations needed: cannot satisfy `<UseSmallInt<{VAL!=0}> as ValTypeSelect>::ValTypeInner == _`
--> src/main.rs:18:5
|
18 | val: <UseSmallInt<{VAL!=0}> as ValTypeSelect>::ValTypeInner,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot satisfy `<UseSmallInt<{VAL!=0}> as ValTypeSelect>::ValTypeInner == _`
To raise an error the const parameter (VAL
) may be used in const expression in any way except "path statement" like UseSmallInt<{VAL; true}>
. So this fails to compile too (playground):
struct MyStruct<const VAL: usize>
{
val: <UseSmallInt<{VAL+VAL; true}> as ValTypeSelect>::ValTypeInner,
}
ICE case
The ICE is encountered in a special case (playground):
#[derive(Clone)]
struct IntermediateStruct<const N: bool> {
field1: <UseSmallInt<N> as ValTypeSelect>::ValTypeInner,
field2: (),
}
struct MyStruct<const VAL: usize> {
intermed: IntermediateStruct<{VAL+VAL; true}>,
}
impl<const VAL: usize> MyStruct<VAL> {
fn consume_val(&self) {
let _x = self.intermed.clone();
}
}
Error:
error: internal compiler error: dtorck encountered internal error
--> src/lib.rs:27:13
|
27 | let _x = self.intermed.clone();
| ^^
error: internal compiler error: dtorck encountered internal error
--> src/lib.rs:27:18
|
27 | let _x = self.intermed.clone();
| ^^^^^^^^^^^^^^^^^^^^^
The ICE raises when the last field in IntermediateStruct
is not a const-generic-with-specialization member. If the field order is opposite, the general "type annotations needed" is reported (playground):
#[derive(Clone)]
struct IntermediateStruct<const N: bool> {
field2: (),
field1: <UseSmallInt<N> as ValTypeSelect>::ValTypeInner,
}
Meta
rustc --version --verbose
for nightly-2020-05-19:
rustc 1.45.0-nightly (d8878868c 2020-05-18)
binary: rustc
commit-hash: d8878868c8d7ef3779e7243953fc050cbb0e0565
commit-date: 2020-05-18
host: x86_64-unknown-linux-gnu
release: 1.45.0-nightly
LLVM version: 9.0
rustc --version --verbose
for nightly-2020-05-20:
rustc 1.45.0-nightly (3a7dfda40 2020-05-19)
binary: rustc
commit-hash: 3a7dfda40a3e798bf086bd58cc7e5e09deb808b5
commit-date: 2020-05-19
host: x86_64-unknown-linux-gnu
release: 1.45.0-nightly
LLVM version: 9.0