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

Const generics expressions don't unify in type parameters #62058

Closed
vadixidav opened this issue Jun 22, 2019 · 3 comments
Closed

Const generics expressions don't unify in type parameters #62058

vadixidav opened this issue Jun 22, 2019 · 3 comments
Labels
A-const-generics Area: const generics (parameters and arguments) C-feature-request Category: A feature request, i.e: not implemented / a PR. const-generics-bad-diagnostics An error is correctly emitted, but is confusing, for `min_const_generics`. F-const_generics `#![feature(const_generics)]` requires-nightly This issue requires a nightly compiler in some way. T-lang Relevant to the language team, which will review and decide on the PR/issue.

Comments

@vadixidav
Copy link
Contributor

I know this has probably already been mentioned on the const generics tracking issue, but I wanted to make an issue specifically for this.

Example (working around some other bugs in const generics):

#![feature(const_generics)]

pub struct ConstBytes<const N: usize>([u8; N]);

/// A constant sized array of bits. `N` defines the number of bits in the array.
pub struct BitArray<const N: usize>(ConstBytes<{(N + 7) / 8}>);

impl<const N: usize> BitArray<{N}> {
    fn new(bytes: ConstBytes<{(N + 7) / 8}>) -> Self {
        Self(bytes)
    }
}

Output:

error[E0308]: mismatched types
  --> src\lib.rs:10:14
   |
10 |         Self(bytes)
   |              ^^^^^ expected `{(N + 7) / 8}`, found `{(N + 7) / 8}`
   |
   = note: expected type `ConstBytes<>`
              found type `ConstBytes<>`

I would expect it to be able to unify the const expression (N + 7) / 8 with itself. Technically, we can probably unify lots of things that are equal in value (N == M) if they are resolved at compile time, but if the expressions are exactly the same (same order and everything) I feel like it should be possible to do a simple equals comparison between the two expressions at compile time.

Rather than waiting for the more advanced "unify anything that resolves to the same value," perhaps we can just unify the exact same const expression without any canonicalization or anything just so I can do something basic like this. This would be useful for me to provide some initial abstraction over bit arrays despite some shortcomings from not being able to create the underlying storage internally.

Does this seem simple enough to support? Should there be an RFC for this basic kind of unification (unification of the exact same expression)? If so, I can make the RFC. I think this is a subset of the behavior we will eventually support, so it should be fine.

@jonas-schievink jonas-schievink added A-const-generics Area: const generics (parameters and arguments) T-lang Relevant to the language team, which will review and decide on the PR/issue. C-feature-request Category: A feature request, i.e: not implemented / a PR. labels Jul 28, 2019
@Centril Centril added F-const_generics `#![feature(const_generics)]` requires-nightly This issue requires a nightly compiler in some way. labels Aug 6, 2019
@varkor
Copy link
Member

varkor commented Apr 8, 2020

The error is now:

error[E0308]: mismatched types
  --> src/lib.rs:10:14
   |
10 |         Self(bytes)
   |              ^^^^^ expected `{(N + 7) / 8}`, found `{(N + 7) / 8}`
   |
   = note: expected struct `ConstBytes<{(N + 7) / 8}>`
              found struct `ConstBytes<{(N + 7) / 8}>`

which is expected, though the diagnostic could be better (i.e. can't unify complex expressions).

@varkor varkor added the const-generics-bad-diagnostics An error is correctly emitted, but is confusing, for `min_const_generics`. label Sep 13, 2020
@varkor
Copy link
Member

varkor commented Oct 1, 2020

The error is now:

error: constant expression depends on a generic parameter
 --> src/lib.rs:6:37
  |
6 | pub struct BitArray<const N: usize>(ConstBytes<{(N + 7) / 8}>);
  |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: this may fail depending on what value the parameter takes

error: constant expression depends on a generic parameter
 --> src/lib.rs:9:19
  |
9 |     fn new(bytes: ConstBytes<{(N + 7) / 8}>) -> Self {
  |                   ^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: this may fail depending on what value the parameter takes

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

I'm going to open a separate issue for this diagnostic, but this is much better than previously.

@varkor varkor closed this as completed Oct 1, 2020
@varkor
Copy link
Member

varkor commented Oct 1, 2020

Actually, the error message is better with min_const_generics, so this isn't an issue, as we have to explore unification in more detail for the full const_generics anyway.

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) C-feature-request Category: A feature request, i.e: not implemented / a PR. const-generics-bad-diagnostics An error is correctly emitted, but is confusing, for `min_const_generics`. F-const_generics `#![feature(const_generics)]` requires-nightly This issue requires a nightly compiler in some way. T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

4 participants