Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
disiamylborane opened this issue May 31, 2020 · 2 comments
Closed
Labels
A-const-generics Area: const generics (parameters and arguments) A-specialization Area: Trait impl specialization C-bug Category: This is a bug. F-generic_const_exprs `#![feature(generic_const_exprs)]` F-specialization `#![feature(specialization)]` requires-nightly This issue requires a nightly compiler in some way. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@disiamylborane
Copy link

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
@disiamylborane disiamylborane added the C-bug Category: This is a bug. label May 31, 2020
@jonas-schievink jonas-schievink added A-const-generics Area: const generics (parameters and arguments) F-const_generics `#![feature(const_generics)]` F-specialization `#![feature(specialization)]` requires-nightly This issue requires a nightly compiler in some way. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. A-specialization Area: Trait impl specialization labels May 31, 2020
@lcnr lcnr added F-generic_const_exprs `#![feature(generic_const_exprs)]` and removed F-const_generics `#![feature(const_generics)]` labels Jun 28, 2022
@lcnr
Copy link
Contributor

lcnr commented Jun 28, 2022

this seems to be fixed, even though it requires different feature gates and an explicit const evaluatable bound rn

#![feature(generic_const_exprs)]
#![feature(specialization)]

trait ValTypeSelect {
    type ValTypeInner: std::fmt::Display + From<i8>;
}

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>
where
    [(); (VAL != 0) as usize]:,
{
    val: <UseSmallInt<{ VAL != 0 }> as ValTypeSelect>::ValTypeInner,
}

fn main() {
    let x = MyStruct::<0> { val: 0.into() };
    println!("{}", x.val);
}

The other tests have overly complex constants for generic_const_exprs so they can't easily be converted. Marking as needs test.

@disiamylborane
Copy link
Author

Closing as fixed. The original code sample is now completely outdated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-const-generics Area: const generics (parameters and arguments) A-specialization Area: Trait impl specialization C-bug Category: This is a bug. F-generic_const_exprs `#![feature(generic_const_exprs)]` F-specialization `#![feature(specialization)]` requires-nightly This issue requires a nightly compiler in some way. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

3 participants