Skip to content

struct in type of const param causes ICE #74199

Closed
@lcnr

Description

@lcnr
Contributor
// check-pass
#![feature(const_generics)]

struct Foo<const N: [u8; {
    struct Foo<const N: usize>;

    impl<const N: usize> Foo<N> {
        fn value() -> usize {
            N
        }
    }

    Foo::<17>::value()
}]>;

fn main() {}

causes an ICE with

warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes
 --> src/main.rs:2:12
  |
2 | #![feature(const_generics)]
  |            ^^^^^^^^^^^^^^
  |
  = note: `#[warn(incomplete_features)]` on by default
  = note: see issue #44580 <https://github.com/rust-lang/rust/issues/44580> for more information

error[E0391]: cycle detected when computing type of `Foo::N`
 --> src/main.rs:4:18
  |
4 | struct Foo<const N: [u8; {
  |                  ^
  |
  = note: ...which again requires computing type of `Foo::N`, completing the cycle
note: cycle used when computing type of `Foo`
 --> src/main.rs:4:1
  |
4 | struct Foo<const N: [u8; {
  | ^^^^^^^^^^^^^^^^^^^^^^^^

error[E0391]: cycle detected when computing type of `Foo`
  --> src/main.rs:4:1
   |
4  | struct Foo<const N: [u8; {
   | ^^^^^^^^^^^^^^^^^^^^^^^^
   |
note: ...which requires computing type of `Foo::N`...
  --> src/main.rs:4:18
   |
4  | struct Foo<const N: [u8; {
   |                  ^
note: ...which requires const-evaluating + checking `Foo::{{constant}}#0`...
  --> src/main.rs:4:26
   |
4  |   struct Foo<const N: [u8; {
   |  __________________________^
5  | |     struct Foo<const N: usize>;
6  | |
7  | |     impl<const N: usize> Foo<N> {
...  |
13 | |     Foo::<17>::value()
14 | | }]>;
   | |_^
note: ...which requires const-evaluating + checking `Foo::{{constant}}#0`...
  --> src/main.rs:4:26
   |
4  |   struct Foo<const N: [u8; {
   |  __________________________^
5  | |     struct Foo<const N: usize>;
6  | |
7  | |     impl<const N: usize> Foo<N> {
...  |
13 | |     Foo::<17>::value()
14 | | }]>;
   | |_^
note: ...which requires const-evaluating `Foo::{{constant}}#0`...
  --> src/main.rs:4:26
   |
4  |   struct Foo<const N: [u8; {
   |  __________________________^
5  | |     struct Foo<const N: usize>;
6  | |
7  | |     impl<const N: usize> Foo<N> {
...  |
13 | |     Foo::<17>::value()
14 | | }]>;
   | |_^
note: ...which requires type-checking `Foo::{{constant}}#0`...
  --> src/main.rs:4:26
   |
4  |   struct Foo<const N: [u8; {
   |  __________________________^
5  | |     struct Foo<const N: usize>;
6  | |
7  | |     impl<const N: usize> Foo<N> {
...  |
13 | |     Foo::<17>::value()
14 | | }]>;
   | |_^
note: ...which requires computing the variances of `Foo::{{constant}}#0::Foo`...
  --> src/main.rs:5:5
   |
5  |     struct Foo<const N: usize>;
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
   = note: ...which requires computing the variances for items in this crate...
   = note: ...which again requires computing type of `Foo`, completing the cycle
note: cycle used when collecting item types in top-level module
  --> src/main.rs:2:1
   |
2  | / #![feature(const_generics)]
3  | |
4  | | struct Foo<const N: [u8; {
5  | |     struct Foo<const N: usize>;
...  |
15 | |
16 | | fn main() {}
   | |____________^

error: internal compiler error: src/librustc_typeck/variance/constraints.rs:165:17: `build_constraints_for_item` unsupported for this item
  --> src/main.rs:4:1
   |
4  | / struct Foo<const N: [u8; {
5  | |     struct Foo<const N: usize>;
6  | |
7  | |     impl<const N: usize> Foo<N> {
...  |
13 | |     Foo::<17>::value()
14 | | }]>;
   | |____^

thread 'rustc' panicked at 'Box<Any>', /rustc/8aa18cbdc5d4bc33bd61e2d9a4b643d87f5d21de/src/libstd/macros.rs:13:23
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

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.46.0-nightly (8aa18cbdc 2020-07-08) running on x86_64-unknown-linux-gnu

note: compiler flags: -C embed-bitcode=no -C codegen-units=1 -C debuginfo=2 --crate-type bin

note: some of the compiler flags provided by cargo are hidden

error: aborting due to 3 previous errors; 1 warning emitted

Activity

added
I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️
T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
C-bugCategory: This is a bug.
A-const-genericsArea: const generics (parameters and arguments)
on Jul 9, 2020
ayushmishra2005

ayushmishra2005 commented on Jul 18, 2020

@ayushmishra2005
Contributor

@lcnr I would like to fix it. Can you please guide me?

lcnr

lcnr commented on Jul 18, 2020

@lcnr
ContributorAuthor

I am not completely sure what's going wrong here myself yet.

I will try to look into what we can do here soon. If you open a new topic on zulip we can discuss it there.

lcnr

lcnr commented on Jul 18, 2020

@lcnr
ContributorAuthor

Not completely sure why this ICEs after the cycle error, will have to ask about this myself.
edit: cycle errors don't actually cause a fatal error in some cases and return an error value instead, so the above now makes sense to me
We can fix the ice for now by ignoring ty::Error here

_ => {
span_bug!(
tcx.def_span(def_id),
"`build_constraints_for_item` unsupported for this item"
);
}

The cycle error itself seems like a quite difficult problem though x.x

#![feature(const_generics)]
struct Bar<T>(T);

impl<T> Bar<T> {
    const fn value() -> usize {
        42
    }
}

struct Foo<const N: [u8; Bar::<u32>::value()]>;

I don't have the time to think too much about this, but the short overview is the following:

  • we want to evaluate the type of N while we compute the type of Foo.
  • while doing so we actually eval Bar::<u32>::value() somewhat eagerly (for whatever reason), not sure about that one
  • evaluating Bar::<u32>::value() requires the variance of T in Bar<T>.
  • computing variance is a global computation, so getting the variance of Bar<T> computes the variance of Foo<N> at the same time.
  • we need the type of Foo for this, which causes an ICE

This luckily is outside of min_const_generics as proposed in rust-lang/lang-team#37 😅

added a commit that references this issue on Jul 31, 2020

Rollup merge of rust-lang#74991 - JulianKnodt:74199, r=lcnr

3ad6fed
added a commit that references this issue on Jul 31, 2020

Auto merge of rust-lang#74994 - JohnTitor:rollup-eknaekv, r=JohnTitor

Alexendoo

Alexendoo commented on Aug 2, 2020

@Alexendoo
Member

Fixed by #74991

lcnr

lcnr commented on Aug 2, 2020

@lcnr
ContributorAuthor

This shouldn't error, will open a new issue for that

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-const-genericsArea: const generics (parameters and arguments)C-bugCategory: This is a bug.F-const_generics`#![feature(const_generics)]`I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.glacierICE tracked in rust-lang/glacier.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @ayushmishra2005@Alexendoo@lcnr@rust-lang-glacier-bot

        Issue actions

          struct in type of const param causes ICE · Issue #74199 · rust-lang/rust