Skip to content

"Type annotations needed" and ICE with const generics and specialization #72821

Closed
@disiamylborane

Description

@disiamylborane

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

Complete on playground

#![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

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-const-genericsArea: const generics (parameters and arguments)A-specializationArea: Trait impl specializationC-bugCategory: This is a bug.F-generic_const_exprs`#![feature(generic_const_exprs)]`F-specialization`#![feature(specialization)]`T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.requires-nightlyThis issue requires a nightly compiler in some way.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions