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 #2000

Merged
merged 12 commits into from Sep 14, 2017

Conversation

@withoutboats
Contributor

withoutboats commented May 11, 2017

This is a new const generics RFC which addresses the issues around equality between const variables that were raised in this internals thread.

Rendered

[updated to link to final rendered version]

@withoutboats withoutboats self-assigned this May 11, 2017

@withoutboats withoutboats added the T-lang label May 11, 2017

@withoutboats

This comment has been minimized.

Show comment
Hide comment
@withoutboats

withoutboats May 11, 2017

Contributor

nits:

  1. I didn't actually talk about the compilation model in this RFC, should probably specify that these params are monomorphized.
  2. Consts as inputs to traits? Unclear to me what the compilation is for that. Monomorphize the traits into distinct traits?
Contributor

withoutboats commented May 11, 2017

nits:

  1. I didn't actually talk about the compilation model in this RFC, should probably specify that these params are monomorphized.
  2. Consts as inputs to traits? Unclear to me what the compilation is for that. Monomorphize the traits into distinct traits?
Show outdated Hide outdated text/0000-const-generics.md
Show outdated Hide outdated text/0000-const-generics.md
Show outdated Hide outdated text/0000-const-generics.md
Show outdated Hide outdated text/0000-const-generics.md
Show outdated Hide outdated text/0000-const-generics.md
@eddyb

This comment has been minimized.

Show comment
Hide comment
@eddyb

eddyb May 12, 2017

Member

Consts as inputs to traits? Unclear to me what the compilation is for that. Monomorphize the traits into distinct traits?

What does it mean to "monomorphize" a trait? If const parameters don't match the behavior of type parameters in some context then something has gone wrong with the semantics.

Member

eddyb commented May 12, 2017

Consts as inputs to traits? Unclear to me what the compilation is for that. Monomorphize the traits into distinct traits?

What does it mean to "monomorphize" a trait? If const parameters don't match the behavior of type parameters in some context then something has gone wrong with the semantics.

@withoutboats

This comment has been minimized.

Show comment
Hide comment
@withoutboats

withoutboats May 12, 2017

Contributor

I'm not sure what I was thinking, its the same as multiparameter traits - we just need to create a new instance during trans for every product of types and consts. That is <T as Foo<0>>::foo generates a different from from <T as Foo<1>>::foo, but this is no different from <T as Foo<Type0>>::foo and <T as Foo<Type1>>::foo.

Contributor

withoutboats commented May 12, 2017

I'm not sure what I was thinking, its the same as multiparameter traits - we just need to create a new instance during trans for every product of types and consts. That is <T as Foo<0>>::foo generates a different from from <T as Foo<1>>::foo, but this is no different from <T as Foo<Type0>>::foo and <T as Foo<Type1>>::foo.

Show outdated Hide outdated text/0000-const-generics.md
Show outdated Hide outdated text/0000-const-generics.md
@mark-i-m

This comment has been minimized.

Show comment
Hide comment
@mark-i-m

mark-i-m May 13, 2017

Contributor

Also, where does MIRI fit into this? Is it just that when MIRI comes around consts will suddenly gain a lot of functionality?

Contributor

mark-i-m commented May 13, 2017

Also, where does MIRI fit into this? Is it just that when MIRI comes around consts will suddenly gain a lot of functionality?

@withoutboats

This comment has been minimized.

Show comment
Hide comment
@withoutboats

withoutboats May 13, 2017

Contributor

Also, where does MIRI fit into this? Is it just that when MIRI comes around consts will suddenly gain a lot of functionality?

Yes, MIRI is orthogonal. The RFC has a comment in it which says that for the sake of this RFC we just assume integer arithmetic works; we're drawing a distinction between the range of expressions that can be evaluated at compile time (MIRI and const fn) and making types depend on constants (const generics).

Contributor

withoutboats commented May 13, 2017

Also, where does MIRI fit into this? Is it just that when MIRI comes around consts will suddenly gain a lot of functionality?

Yes, MIRI is orthogonal. The RFC has a comment in it which says that for the sake of this RFC we just assume integer arithmetic works; we're drawing a distinction between the range of expressions that can be evaluated at compile time (MIRI and const fn) and making types depend on constants (const generics).

@est31

This comment has been minimized.

Show comment
Hide comment
@est31

est31 May 13, 2017

Contributor

👍 🎉 Big support for this RFC and that it tries to not solve every issue related to const generics, but instead goes the slim but faster path, by avoiding to do anything about orthogonal issues.

I too would like to see many of the proposed extensions happen (like unifying {1+N} with {N+1}), but if they were added with this RFC it would increase chance for this RFC to be merged at a later time, and the RFC to hang in unstable limbo for longer, because of some little edge case or because it would require MIRI. I rather have the main functionality merged now, and stabilized fast, and the orthogonal issues looked at separately. Therefore, I'm very glad of the direction this RFC is going!

❤️ Many thanks @withoutboats for championing this RFC!

Contributor

est31 commented May 13, 2017

👍 🎉 Big support for this RFC and that it tries to not solve every issue related to const generics, but instead goes the slim but faster path, by avoiding to do anything about orthogonal issues.

I too would like to see many of the proposed extensions happen (like unifying {1+N} with {N+1}), but if they were added with this RFC it would increase chance for this RFC to be merged at a later time, and the RFC to hang in unstable limbo for longer, because of some little edge case or because it would require MIRI. I rather have the main functionality merged now, and stabilized fast, and the orthogonal issues looked at separately. Therefore, I'm very glad of the direction this RFC is going!

❤️ Many thanks @withoutboats for championing this RFC!

@clarcharr

This comment has been minimized.

Show comment
Hide comment
@clarcharr

clarcharr May 13, 2017

Contributor

Question: does N - 1 unify with usize::MAX?

Contributor

clarcharr commented May 13, 2017

Question: does N - 1 unify with usize::MAX?

@mark-i-m

This comment has been minimized.

Show comment
Hide comment
@mark-i-m

mark-i-m May 13, 2017

Contributor

@clarcharr where do you see that?

Contributor

mark-i-m commented May 13, 2017

@clarcharr where do you see that?

@bstrie

This comment has been minimized.

Show comment
Hide comment
@bstrie

bstrie Sep 7, 2017

Contributor

Ordering and default parameters: Do all const parameters come last, or can they be mixed with types?

Given that we require all lifetime parameters to precede type parameters, it makes sense to me to require all const parameters to follow all type parameters, IOW to disallow mixing. This is a restriction that can always be lifted later.

Contributor

bstrie commented Sep 7, 2017

Ordering and default parameters: Do all const parameters come last, or can they be mixed with types?

Given that we require all lifetime parameters to precede type parameters, it makes sense to me to require all const parameters to follow all type parameters, IOW to disallow mixing. This is a restriction that can always be lifted later.

@eddyb

This comment has been minimized.

Show comment
Hide comment
@eddyb

eddyb Sep 7, 2017

Member

@bstrie The restriction doesn't make sense IMO. We use const before the name to avoid restrictions.

Member

eddyb commented Sep 7, 2017

@bstrie The restriction doesn't make sense IMO. We use const before the name to avoid restrictions.

@withoutboats

This comment has been minimized.

Show comment
Hide comment
@withoutboats

withoutboats Sep 7, 2017

Contributor

@bstrie you are missing this context #2000 (comment)

Contributor

withoutboats commented Sep 7, 2017

@bstrie you are missing this context #2000 (comment)

@rfcbot

This comment has been minimized.

Show comment
Hide comment
@rfcbot

rfcbot Sep 14, 2017

The final comment period is now complete.

rfcbot commented Sep 14, 2017

The final comment period is now complete.

@tomwhoiscontrary

This comment has been minimized.

Show comment
Hide comment
@tomwhoiscontrary

tomwhoiscontrary Sep 14, 2017

(Apologies if this has already been addressed, i'm still working through the RFC and comments)

Const parameters always come after type parameters

Why? I can vaguely imagine cases where i might prefer otherwise, like:

struct ParallelStridedArrays<T, const T_STRIDE: usize, U, const U_STRIDE: usize> {
  // ...
}

It's not a deal-breaker, but it will be a mild annoyance for someone at some point.

tomwhoiscontrary commented Sep 14, 2017

(Apologies if this has already been addressed, i'm still working through the RFC and comments)

Const parameters always come after type parameters

Why? I can vaguely imagine cases where i might prefer otherwise, like:

struct ParallelStridedArrays<T, const T_STRIDE: usize, U, const U_STRIDE: usize> {
  // ...
}

It's not a deal-breaker, but it will be a mild annoyance for someone at some point.

@tomwhoiscontrary

This comment has been minimized.

Show comment
Hide comment
@tomwhoiscontrary

tomwhoiscontrary Sep 14, 2017

/me does the bikeshedding dance

When applying an expression as const parameter (except for arrays), which is not an identity expression, the expression must be contained within a block. This syntactic restriction is necessary to avoid requiring infinite lookahead when parsing an expression inside of a type.

A block rather than parentheses? I appreciate that they are pretty much equivalent in an expression-oriented language, but i would naturally reach for parens here myself.

tomwhoiscontrary commented Sep 14, 2017

/me does the bikeshedding dance

When applying an expression as const parameter (except for arrays), which is not an identity expression, the expression must be contained within a block. This syntactic restriction is necessary to avoid requiring infinite lookahead when parsing an expression inside of a type.

A block rather than parentheses? I appreciate that they are pretty much equivalent in an expression-oriented language, but i would naturally reach for parens here myself.

@thepowersgang

This comment has been minimized.

Show comment
Hide comment
@thepowersgang

thepowersgang Sep 14, 2017

Contributor

For the latter point, it's because () is already valid in types (for tuples or grouping trait objects), {} isn't so can be used to indicate to the parser that it's about to parse an expression.

Contributor

thepowersgang commented Sep 14, 2017

For the latter point, it's because () is already valid in types (for tuples or grouping trait objects), {} isn't so can be used to indicate to the parser that it's about to parse an expression.

@burdges

This comment has been minimized.

Show comment
Hide comment
@burdges

burdges Sep 14, 2017

I think conceptually const generic parameters coming after others makes sense because the compiler might eventually make some const generic parameters into arguments under the hood, depending upon how they were used, the state of alloca/VLA, etc. In principle, the compiler could do so with type parameters too, but the analysis sounds harder. And lifetimes first makes sense because they never exist at runtime time.

burdges commented Sep 14, 2017

I think conceptually const generic parameters coming after others makes sense because the compiler might eventually make some const generic parameters into arguments under the hood, depending upon how they were used, the state of alloca/VLA, etc. In principle, the compiler could do so with type parameters too, but the analysis sounds harder. And lifetimes first makes sense because they never exist at runtime time.

@withoutboats

This comment has been minimized.

Show comment
Hide comment
@withoutboats

withoutboats Sep 14, 2017

Contributor

Ordering of const arguments is supposed to be an unresolved question because of its interaction with default args, I'll remove that statement from the RFC.

Contributor

withoutboats commented Sep 14, 2017

Ordering of const arguments is supposed to be an unresolved question because of its interaction with default args, I'll remove that statement from the RFC.

@withoutboats withoutboats referenced this pull request Sep 14, 2017

Open

Tracking issue for const generics (RFC 2000) #44580

0 of 7 tasks complete

@withoutboats withoutboats merged commit 8ca6994 into rust-lang:master Sep 14, 2017

@withoutboats

This comment has been minimized.

Show comment
Hide comment
@withoutboats

withoutboats Sep 14, 2017

Contributor

Const generics is accepted & merged as RFC 2000. Tracking issue is rust-lang/rust#44580.

Contributor

withoutboats commented Sep 14, 2017

Const generics is accepted & merged as RFC 2000. Tracking issue is rust-lang/rust#44580.

@leonardo-m leonardo-m referenced this pull request Jul 30, 2018

Open

Integer generics #3345

mqudsi added a commit to mqudsi/rusqlite that referenced this pull request Sep 5, 2018

Add impls for i128 16-byte integer db conversions
rust nightly has i128/u128 as 16-byte integer types, expected to land
into stable at some point in the (near?) future. SQLite's maximum
variable-length integer size is 8-bytes, so this needs to be serialized
into a blob for storage in the database.

Obviously endianness is a concern here; I've opted to use the platform's
native endianness rather than a hard-coded BE/LE choice. This is
contracted out to i128's `from_bytes`/`to_bytes`, which will take care
of the platform-specific endianness for us.

The usage of `unsafe` in the call to i128::from_bytes is to avoid a
potentially expensive extra allocation and looping over the contents of
the vector to copy them to a `[u8; 16]` intermediate. Once [RFC #2000](rust-lang/rfcs#2000) lands in nightly (tracked in [#44580](rust-lang/rust#44580)), [const generics](https://internals.rust-lang.org/t/lang-team-minutes-const-generics/5090) should make it possible to convert the `Vec<u8>` to a fixed-length `[u8; 16]` array in a nicer fashion.

@Centril Centril referenced this pull request Sep 18, 2018

Open

RFC: Elide array size #2545

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