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

stabilize #![feature(min_const_generics)] in 1.51 #79135

Merged
merged 4 commits into from
Dec 27, 2020

Conversation

lcnr
Copy link
Contributor

@lcnr lcnr commented Nov 17, 2020

A new Kind
A Sort long Prophesized
Once Fragile, now Eternal

Stabilization report

This is the stabilization report for #![feature(min_const_generics)] (tracking issue #74878), a subset of #![feature(const_generics)] (tracking issue #44580), based on rust-lang/rfcs#2000.

The version target is 1.50 (2020-12-31 => beta, 2021-02-11 => stable) 1.51 (2021-02-11 => beta, 2021-03-25 => stable).

This report is a collaborative effort of @varkor, @shepmaster and @lcnr.

Summary

It is currently possible to parameterize functions, type aliases, types, traits and implementations by types and lifetimes.
With #![feature(min_const_generics)], it becomes possible, in addition, to parameterize these by constants.

This is done using the syntax const IDENT: Type in the parameter listing. Unlike full const generics, min_const_generics is limited to parameterization by integers, and constants of type char or bool.

We already use #![feature(min_const_generics)] on stable to implement many common traits for arrays. See the documentation for specific examples.

Generic const arguments, for now, are not permitted to involve computations depending on generic parameters. This means that const parameters may only be instantiated using either:

  1. const expressions that do not depend on any generic parameters, e.g. { foo() + 1 }, where foo is a const fn
  2. standalone const parameters, e.g. {N}

Example

#![feature(min_const_generics)]

trait Foo<const N: usize> {
    fn method<const M: usize>(&mut self, arr: [[u8; M]; N]);
}

struct Bar<T, const N: usize> {
    inner: [T; N],
}

impl<const N: usize> Foo<N> for Bar<u8, N> {
    fn method<const M: usize>(&mut self, arr: [[u8; M]; N]) {
        for (elem, s) in self.inner.iter_mut().zip(arr.iter()) {
            for &x in s {
                *elem &= x;
            }
        }
    }
}

fn function<const N: u16>() -> u16 {
    // Const parameters can be used freely inside of functions.
    (N + 1) / 2 * N
}

fn main() {
    let mut bar = Bar { inner: [0xff; 3] };
    // This infers the value of `M` from the type of the function argument.
    bar.method([[0b11_00, 0b01_00], [0b00_11, 0b00_01], [0b11_00, 0b00_11]]);
    assert_eq!(bar.inner, [0b01_00, 0b00_01, 0b00_00]);

    // You can also explicitly specify the value of `N`.
    assert_eq!(function::<17>(), 153);
}

Motivation

Rust has the built-in array type, which is parametric over a constant. Without const generics, this type can be quite cumbersome to use as it is not possible to generically implement a trait for arrays of different lengths. For example, this meant that, for a long time, the standard library only contained trait implementations for arrays up to a length of 32. This restriction has since been lifted through the use of const generics.

Const parameters allow users to naturally specify variants of a generic type which are more naturally parameterized by values, rather than by types. For example, using const generics, many of the uses of the crate typenum may now be replaced with const parameters, improving compilation time as well as code readability and diagnostics.

The subset described by min_const_generics is self-contained, but extensive enough to help with the most frequent issues: implementing traits for arrays and using arbitrarily-sized arrays inside of other types. Furthermore, it extends naturally to full const_generics once the remaining design and implementation questions have been resolved.

In-depth feature description

Declaring const parameters

Const parameters are allowed in all places where types and lifetimes are supported. They use the syntax const IDENT: Type. Currently, const parameters must be declared after lifetime and type parameters. Their scope is equal to the scope of other generic parameters. They live in the value namespace.

Type must be one of u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize, char and bool. This restriction is implemented in two places:

  1. during name resolution, where we forbid generic parameters
  2. during well-formedness checking, where we only allow the types listed above

The updated syntax of parameter listings is:

GenericParams:
    (OuterAttr* LifetimeParam),* (OuterAttr* TypeParam),* (OuterAttr* ConstParam),*

OuterAttr: '#[' ... ']'
LifetimeParam: ...
TypeParam: ...
ConstParam: 'const' IDENT ':' Type

Unlike type and lifetime parameters, const parameters of types can be used without being mentioned inside of a parameterized type because const parameters do not have issues concerning variance. This means that the following types are allowed:

struct Foo<const N: usize>;
enum Bar<const M: usize> { A, B }

Const arguments

Const parameters are instantiated using const arguments. Any concrete const expression or const parameter as a standalone argument can be used. When applying an expression as const parameter, most expressions must be contained within a block, with two exceptions:

  1. literals and single-segment path expressions
  2. array lengths

This syntactic restriction is necessary to avoid ambiguity, or requiring infinite lookahead when parsing an expression as a generic argument.

In the cases where a generic argument could be resolved as either a type or const argument, we always interpret it as a type. This causes the following test to fail:

type N = u32;
struct Foo<const N: usize>;
fn foo<const N: usize>() -> Foo<N> { todo!() } // ERR

To circumvent this, the user may wrap the const parameter with braces, at which point it is unambiguously accepted.

type N = u32;
struct Foo<const N: usize>;
fn bar<const N: usize>() -> Foo<{ N }> { todo!() } // ok

Operations depending on generic parameters are not allowed, which is enforced during well-formedness checking. Allowing generic unevaluated constants would require a way to check if they would always evaluate successfully to prevent errors that are not caught at declaration time. This ability forms part of #![feature(const_evaluatable_checked)], which is not yet being stabilised.

Since we are not yet stabilizing #![feature(lazy_normalization_consts)], we must not supply the parent generics to anonymous constants except for repeat expressions. Doing so can cause cycle errors for arrays used in where-bounds. Not supplying the parent generics can however lead to ICEs occurring before well-formedness checking when trying to use a generic parameter. See #56445 for details.

Since we expect cases like this to occur more frequently once min_const_generics is stabilized, we have chosen to forbid generic parameters in anonymous constants during name resolution. While this changes the ICE in the situation above to an ordinary error, this is theoretically a breaking change, as early-bound lifetimes were previously permitted in repeat expressions but now are disallowed, causing the following snippet to break:

fn late_bound<'a>() {
    let _ = [0; {
        let _: &'a (); // ICE ==> ERR
        3
    }];
}

fn early_bound<'a>() where &'a (): Sized {
    let _ = [0; {
        let _: &'a (); // ok ==> ERR
        3
    }];
}

Using const parameters

Const parameters can be used almost everywhere ordinary constants are allowed, except that they may not be used in the construction of consts, statics, functions, or types inside a function body and are subject to the generic argument restrictions mentioned above.

Expressions containing const parameters are eligible for promotion:

fn test<const N: usize>() -> &'static usize {
    &(3 + N)
}

Symbol mangling

See the Rust symbol name mangling RFC for an overview. Generic const parameters take the form K[type][value] when the value is known, or Kp where the value is not known, where:

  • [type] is any integral type, bool, or char.
  • [value] is the unsigned hex value for integers, preceded by n when negative; is 0 or 1 for bool; is the hex value for char.

Exhaustiveness checking

We do not check the exhaustiveness of impls, meaning that the following example does not compile:

struct Foo<const B: bool>;
trait Bar {}
impl Bar for Foo<true> {}
impl Bar for Foo<false> {}

fn needs_bar(_: impl Bar) {}
fn generic<const B: bool>() {
    let v = Foo::<B>;
    needs_bar(v);
}

Type inference

The value of const parameters can be inferred during typeck. One interesting case is the length of generic arrays, which can also be inferred from patterns (implemented in #70562). Practical usage of this can be seen in #76825.

Equality of constants

#![feature(min_const_generics)] only permits generic parameters to be used as standalone generic arguments. We compare two parameters to be equal if they are literally the same generic parameter.

Associated constants

Associated constants can use const parameters without restriction, see #79135 (comment) for more details.

Future work

As this is a limited subset of rust-lang/rfcs#2000, there are quite a few extensions we will be looking into next.

Lazy normalization of constants

Stabilizing #![feature(lazy_normalization_consts)] (tracking issue #72219) will remove some special cases that are currently necessary for min_const_generics, and unblocks operations on const parameters.

Relaxing ordering requirements between const and type parameters

We currently restrict the order of generic parameters so that types must come before consts. We could relax this, as is currently done with const_generics. Without this it is not possible to use both type defaults and const parameters at the same time.

Unrestricting the order will require us to improve some diagnostics that expect there to be a strict order between type and const parameters.

Allowing more parameter types

We would like to support const parameters of more types, especially&str and user-defined types. Both are blocked on valtrees. There are also open questions regarding the design of structural_match concerning the latter. Supporting generic const parameter types such as struct Foo<T, const N: T> will be a lot harder and is unlikely to be implemented in the near future.

Default values of const parameters

We do not yet support default values for const parameters. There is work in progress to enable this on nightly (see #75384).

Generic const operations

With #![feature(min_const_generics)], only concrete const expressions and parameters as standalone arguments are allowed in types and repeat expressions. However, supporting generic const operations, such as N + 1 or std::mem::size_of::<T>() is highly desirable. This feature is in early development under #![feature(const_evaluatable_checked)].

Implementation history

Many people have contributed to the design and implementation of const generics over the last three years. See #44580 (comment) for a summary. Once again thank you to everybody who helped out here!


r? @varkor

@lcnr lcnr added T-lang Relevant to the language team, which will review and decide on the PR/issue. relnotes Marks issues that should be documented in the release notes of the next release. F-min_const_generics labels Nov 17, 2020
@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Nov 17, 2020
@lcnr lcnr force-pushed the the-paleogenesis-of-generic-germination branch 2 times, most recently from 8f0d7b4 to 504ac2e Compare November 17, 2020 13:27
@Feilkin

This comment has been minimized.

@mark-i-m
Copy link
Member

I don't even have enough words to say thank you to everyone that worked on this...

@lcnr
Copy link
Contributor Author

lcnr commented Nov 17, 2020

@bors try

@bors
Copy link
Contributor

bors commented Nov 17, 2020

⌛ Trying commit 504ac2eda6435080272e911f9822198c9b915229 with merge 90c27759f26e0dee460c146b45d69b36d2943c22...

@bors
Copy link
Contributor

bors commented Nov 17, 2020

☀️ Try build successful - checks-actions
Build commit: 90c27759f26e0dee460c146b45d69b36d2943c22 (90c27759f26e0dee460c146b45d69b36d2943c22)

@lcnr
Copy link
Contributor Author

lcnr commented Nov 17, 2020

Let's start with the crater run.

@craterbot check

@craterbot
Copy link
Collaborator

👌 Experiment pr-79135 created and queued.
🤖 Automatically detected try build 90c27759f26e0dee460c146b45d69b36d2943c22
🔍 You can check out the queue and this experiment's details.

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot craterbot added S-waiting-on-crater Status: Waiting on a crater run to be completed. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Nov 17, 2020
Copy link
Member

@varkor varkor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implementation looks fine, so this can be merged after a FCP (which is blocked on a crater run).

@newpavlov
Copy link
Contributor

newpavlov commented Nov 18, 2020

It could be not a right place to ask this question, but I haven't seen it discussed in github issues.

As I understand from #68436, the team is currently leaning towards making well-formedness bounds mandatory, at least for initial versions of const generics. But the example provided in the OP contains the following code:

trait Foo<const N: usize> {
    fn method<const M: usize>(&mut self, arr: [[u8; M]; N]);
}

struct Bar<T, const N: usize> {
    inner: [T; N],
}

It is obvious that using N = M = usize::MAX will result in invalid types (in the sense as discussed in the linked issue). And the version of min_const_generics proposed for stabilization allows definition of such types. Trying to instantiate Bar<u8, {usize::MAX}> will result in a "the type is too big for the current architecture" compilation error. Is it not a clear violation of the mandatory bounds approach?

In the linked issue @oli-obk has wrote:

i do expect that you will have to write almost all the same bounds as those that you write with the typenum crate

But with generic-array + typenum we have to use bounds like this:

use generic_array::{GenericArray, ArrayLength};

pub struct Bar<N: ArrayLength<u8>> {
    inner: GenericArray<u8, N>,
}

Having exceptions for mandatory bounds looks like an incoherency to me. I think that either well-formedness bounds must be mandatory for all const expressions (including simple constants) used in type construction, or that they should not be mandatory in the first place as argued by me in the linked issue, since any CTFE panic (e.g. underflow and overflow errors) will result in a compilation error either way and the "too big" errors can appear in code which uses standalone const parameters.

@oli-obk
Copy link
Contributor

oli-obk commented Nov 18, 2020

You are right, that clashes with what is stated in #68436, but we have opted to make an exception for arrays that are too big for the platform long ago. As you can see in https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=3b64dfe7c917d8016e5ca089cb03ad37, which in some form compiles since 1.0 up to the point where it recognizes that the array size is too large and aborts compilation.

What we'll allow you to do at some point is to specify via a where bound (#76560), that you are expecting a specific array type to compile successfully. Once that is in place, we may decide to start emitting lints (or maybe just have clippy do it) to encourage you to add bounds for your arrays. But even with such analyses, constructs like https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=f6ab8b6261decf5f651b2869b431eff1 can still cause the same error and are essentially impossible to catch without a lot of work.

Also, note that [[u8; usize::MAX]; usize::MAX] is a well formed type as long as you don't try to use an instance of it.
See https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=c353a806e9965615ff00b3c1cddb1504 for an example. We do not believe that checking the size of values of types is a responsibility of the type system.

So, my summary is basically that this is nothing new and this PR does not make the situation worse, even if easier to trigger. I reopened #25116 to track the bad diagnostics of this situation.

@newpavlov
Copy link
Contributor

We do not believe that checking the size of values of types is a responsibility of the type system.

I agree with this position. I had a different impression because in the #68436 discussion I've assumed that mandatory bounds will catch the "too big" error as well and no one has corrected me.

To prevent adding noise to this PR, I will try to argue my position in #76560 a bit later.

bors-servo added a commit to servo/rust-smallvec that referenced this pull request Dec 28, 2020
Remove `min_const_generics` feature

Depends on rust-lang/rust#79135.

If #240 is already under development and will be available before the 1.50 release, then feel free to close this PR. Otherwise, the feature removal will benefit upstream projects in the meanwhile.
SimonSapin added a commit to SimonSapin/rust that referenced this pull request Dec 29, 2020
Tracking issue: rust-lang#65798

This is unblocked now that `min_const_generics` has been stabilized
in rust-lang#79135.

This PR does *not* include the corresponding `IntoIterator` impl,
which is rust-lang#65819.
Instead, an iterator can be constructed through the `new` method.

`new` would become unnecessary when `IntoIterator` is implemented
and might be deprecated then, although it will stay stable.
@spastorino spastorino removed the to-announce Announce this issue on triage meeting label Dec 31, 2020
bors bot added a commit to tock/tock that referenced this pull request Jan 11, 2021
2334: update rust january 7 2021 r=bradjc a=hudson-ayers

### Pull Request Overview

This pull request updates the rust nightly version to 2021-01-07. This was motivated by the stabilization of `min_const_generics` ( rust-lang/rust#79135 ) -- by using this nightly, we will be able to use const generics in Tock without adding an unstable feature.


### Testing Strategy

compiling

### TODO or Help Wanted

N/A

### Documentation Updated

- [x] Updated the relevant files in `/docs`.

### Formatting

- [x] Ran `make prepush`.


Co-authored-by: Hudson Ayers <hayers@stanford.edu>
bors added a commit to rust-lang/miri that referenced this pull request Jan 17, 2021
Remove `#![feature(const_generics)]` and `#![allow(incomplete_features)]`

`#![feature(min_const_generics)]` has been [stabilized](rust-lang/rust#79135), so I removed `#![feature(const_generics)]` and `#![allow(incomplete_features)]` (I assume Miri is not built by the beta bootstrap compiler so it's fine to just remove them).

The test [`tests/run-pass/specialization.rs` also has a `#![allow(incomplete_features)]` for `#![feature(specialization)]`](https://github.com/rust-lang/miri/blob/9949d9e4/tests/run-pass/specialization.rs#L1-L2). I think that can be removed and `#![feature(specialization)]` can be replaced with `#![feature(min_specialization)]`, but I'm not sure whether I should do that because it's a test. Feel free to ask me to remove it if it's fine to do so.
bors bot added a commit to Ogeon/palette that referenced this pull request Mar 30, 2021
205: Generalizing gradients and add constant gradients r=Ogeon a=NicolasKlenert

This pull request contains two commits:

### 1. Generalization of  `Gradient` 

This allows creation of gradients from arrays. The inner collection type only has to be `ArrayLike`. For backward compatibility the default is still vector. This allows constant gradients and should also allow gradients to be supported for the next `#[no-std]` build. Other options to enable `#[no-std]` for gradients were briefly disscused in #156.

### 2. Adding some constant gradients

This commit adds constant gradients. To be precise, it adds all 4 new matplotlib color gradients, which are perfectly perceptually-uniform, both in regular form and also when converted to black-and-white and therefore one of the most useful gradients. These are build the same way the named colors are built. A new feature-flag `named_gradients` is added to toggle said constants. This closes #62.

### Alterantives

- The generalization of gradients can be achieved in a multiple of ways. Using a trait is just one of them and may be the wrong way to go. 
   - However I think because this pull request doesn't have any breaking changes and gradients should be supporting arrays in future versions of the crate, it doesn't seem like this update of  `Gradient` will cause more breaking API changes in the future than otherwise. Also constant gradients may be the only interaction with gradients a user needs, such that introducing them could reduce the number of users which actually relies on the generation of `Gradient` itself.
- At the moment the 4 constant gradients are using linear interpolation but in nature these gradients are Spline-Interpolations of exaclty two points (and 2 controlpoints). If `Gradient` will support Spline-Inerpolation in the future and the exact controlpoints of these gradients can be found (I only found the colormaps), the gradients could be implemented more memory efficient.

### Remark

These commits depend on const generics, which is a feature in beta but is planned to be stable on 2021-03-25 onwords (see [#79135](rust-lang/rust#79135)).

Co-authored-by: Nicolas Klenert <klenert.nicolas@gmail.com>
Co-authored-by: NicolasKlenert <Nicolas_Klenert@web.de>
Co-authored-by: NicolasKlenert <klenert.nicolas@gmail.com>
wip-sync pushed a commit to NetBSD/pkgsrc-wip that referenced this pull request Apr 10, 2021
Pkgsrc changes:
 * Remove one SunOS patch, apparently no longer needed.
 * Adapt one patch for Darwin, adjust cargo checksum accordingly.
 * Adjust bootstraps to version 1.50.0.

Version 1.51.0 (2021-03-25)
============================

Language
--------
- [You can now parameterize items such as functions, traits, and
  `struct`s by constant values in addition to by types and
  lifetimes.][79135] Also known as "const generics" E.g. you can
  now write the following. Note:  Only values of primitive integers,
  `bool`, or `char` types are currently permitted.

  ```rust
  struct GenericArray<T, const LENGTH: usize> {
      inner: [T; LENGTH]
  }

  impl<T, const LENGTH: usize> GenericArray<T, LENGTH> {
      const fn last(&self) -> Option<&T> {
          if LENGTH == 0 {
              None
          } else {
              Some(&self.inner[LENGTH - 1])
          }
      }
  }
  ```

Compiler
--------

- [Added the `-Csplit-debuginfo` codegen option for macOS platforms.][79570]
  This option controls whether debug information is split across
  multiple files or packed into a single file. **Note** This option
  is unstable on other platforms.
- [Added tier 3\* support for `aarch64_be-unknown-linux-gnu`,
  `aarch64-unknown-linux-gnu_ilp32`, and
  `aarch64_be-unknown-linux-gnu_ilp32` targets.][81455]
- [Added tier 3 support for `i386-unknown-linux-gnu` and
  `i486-unknown-linux-gnu` targets.][80662]
- [The `target-cpu=native` option will now detect individual features
  of CPUs.][80749]
- [Rust now uses `inline-asm` for stack probes when used with LLVM
  11.0.1+][77885]

\* Refer to Rust's [platform support page][forge-platform-support]
for more information on Rust's tiered platform support.

Libraries
---------

- [`Box::downcast` is now also implemented for any `dyn Any + Send
  + Sync` object.][80945]
- [`str` now implements `AsMut<str>`.][80279]
- [`u64` and `u128` now implement `From<char>`.][79502]
- [`Error` is now implemented for `&T` where `T` implements `Error`.][75180]
- [`Poll::{map_ok, map_err}` are now implemented for `Poll<Option<Result<T,
  E>>>`.][80968]
- [`unsigned_abs` is now implemented for all signed integer types.][80959]
- [`io::Empty` now implements `io::Seek`.][78044]
- [`rc::Weak<T>` and `sync::Weak<T>`'s methods such as `as_ptr`
  are now implemented for `T: ?Sized` types.][80764]

Stabilized APIs
---------------

- [`Arc::decrement_strong_count`]
- [`Arc::increment_strong_count`]
- [`Once::call_once_force`]
- [`Peekable::next_if_eq`]
- [`Peekable::next_if`]
- [`Seek::stream_position`]
- [`array::IntoIter`]
- [`panic::panic_any`]
- [`ptr::addr_of!`]
- [`ptr::addr_of_mut!`]
- [`slice::fill_with`]
- [`slice::split_inclusive_mut`]
- [`slice::split_inclusive`]
- [`slice::strip_prefix`]
- [`slice::strip_suffix`]
- [`str::split_inclusive`]
- [`sync::OnceState`]
- [`task::Wake`]

Cargo
-----
- [Added the `split-debuginfo` profile option to control the -Csplit-debuginfo
  codegen option.][cargo/9112]
- [Added the `resolver` field to `Cargo.toml` to enable the new
  feature resolver and CLI option behavior.][cargo/8997] Version
  2 of the feature resolver will try to avoid unifying features of
  dependencies where that unification could be unwanted.  Such as
  using the same dependency with a `std` feature in a build scripts
  and proc-macros, while using the `no-std` feature in the final
  binary. See the [Cargo book documentation][feature-resolver@2.0]
  for more information on the feature.

Rustdoc
-------
- [Rustdoc will now include documentation for methods available
  from `Deref` traits.][80653]
- [You can now provide a `--default-theme` flag which sets the
  default theme to use for documentation.][79642]

Various improvements to intra-doc links:

- [You can link to non-path primitives such as `slice`.][80181]
- [You can link to associated items.][74489]
- [You can now include generic parameters when linking to items,
  like `Vec<T>`.][76934]

Misc
----
- [You can now pass `--include-ignored` to tests (e.g. with
  `cargo test -- --include-ignored`) to include testing tests marked
  `#[ignore]`.][80053]

Compatibility Notes
-------------------

- [WASI platforms no longer use the `wasm-bindgen` ABI, and instead
  use the wasm32 ABI.][79998]
- [`rustc` no longer promotes division, modulo and indexing operations
  to `const` that could fail.][80579]

- [The minimum version of glibc for the following platforms has
  been bumped to version 2.31 for the distributed artifacts.][81521]
    - `armv5te-unknown-linux-gnueabi`
    - `sparc64-unknown-linux-gnu`
    - `thumbv7neon-unknown-linux-gnueabihf`
    - `armv7-unknown-linux-gnueabi`
    - `x86_64-unknown-linux-gnux32`

Internal Only
-------------

- [Consistently avoid constructing optimized MIR when not doing codegen][80718]

[79135]: rust-lang/rust#79135
[74489]: rust-lang/rust#74489
[76934]: rust-lang/rust#76934
[79570]: rust-lang/rust#79570
[80181]: rust-lang/rust#80181
[79642]: rust-lang/rust#79642
[80945]: rust-lang/rust#80945
[80279]: rust-lang/rust#80279
[80053]: rust-lang/rust#80053
[79502]: rust-lang/rust#79502
[75180]: rust-lang/rust#75180
[79135]: rust-lang/rust#79135
[81521]: rust-lang/rust#81521
[80968]: rust-lang/rust#80968
[80959]: rust-lang/rust#80959
[80718]: rust-lang/rust#80718
[80653]: rust-lang/rust#80653
[80579]: rust-lang/rust#80579
[79998]: rust-lang/rust#79998
[78044]: rust-lang/rust#78044
[81455]: rust-lang/rust#81455
[80764]: rust-lang/rust#80764
[80749]: rust-lang/rust#80749
[80662]: rust-lang/rust#80662
[77885]: rust-lang/rust#77885
[cargo/8997]: rust-lang/cargo#8997
[cargo/9112]: rust-lang/cargo#9112
[feature-resolver@2.0]: https://doc.rust-lang.org/nightly/cargo/reference/features.html#feature-resolver-version-2
[`Once::call_once_force`]: https://doc.rust-lang.org/stable/std/sync/struct.Once.html#method.call_once_force
[`sync::OnceState`]: https://doc.rust-lang.org/stable/std/sync/struct.OnceState.html
[`panic::panic_any`]: https://doc.rust-lang.org/stable/std/panic/fn.panic_any.html
[`slice::strip_prefix`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.strip_prefix
[`slice::strip_suffix`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.strip_prefix
[`Arc::increment_strong_count`]: https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#method.increment_strong_count
[`Arc::decrement_strong_count`]: https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#method.decrement_strong_count
[`slice::fill_with`]: https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.fill_with
[`ptr::addr_of!`]: https://doc.rust-lang.org/nightly/std/ptr/macro.addr_of.html
[`ptr::addr_of_mut!`]: https://doc.rust-lang.org/nightly/std/ptr/macro.addr_of_mut.html
[`array::IntoIter`]: https://doc.rust-lang.org/nightly/std/array/struct.IntoIter.html
[`slice::split_inclusive`]: https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_inclusive
[`slice::split_inclusive_mut`]: https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_inclusive_mut
[`str::split_inclusive`]: https://doc.rust-lang.org/nightly/std/primitive.str.html#method.split_inclusive
[`task::Wake`]: https://doc.rust-lang.org/nightly/std/task/trait.Wake.html
[`Seek::stream_position`]: https://doc.rust-lang.org/nightly/std/io/trait.Seek.html#method.stream_position
[`Peekable::next_if`]: https://doc.rust-lang.org/nightly/std/iter/struct.Peekable.html#method.next_if
[`Peekable::next_if_eq`]: https://doc.rust-lang.org/nightly/std/iter/struct.Peekable.html#method.next_if_eq
netbsd-srcmastr pushed a commit to NetBSD/pkgsrc that referenced this pull request May 26, 2021
Pkgsrc changes:
 * Add support for the big-endian arm64 NetBSD target (aarch64_be).
 * On NetBSD/i386, use the i586 (pentium) bootstrap kit variant in
   preference to i686.
 * Adjust patches, re-compute line offsets, re-compute crate checksums.
 * Remove a patch which was either integrated upstream and/or no longer
   applies.
 * Bump bootstraps to 1.50.0.
 * Move conditionals until after bsd.prefs.mk so that they work...
 * Default to "dist" build target if cross-compiling, but allow
   also to override via rust.BUILD_TARGET.
 * Allow overriding MAKE_JOBS_SAFE via rust.MAKE_JOBS_SAFE if you
   want a different trade-off between occasional breakage and performance.
 * Adjust platform.mk according to work already done in wip/rust/
 * Add a patch to optimize the install.sh script used to install binary
   bootstraps to not do so many forks; use case/esac and parameter expansion
   instead of grep, sed and cut.
 * Drop building documentation for the binary bootstrap kits.  This will
   also impact the lang/rust-bin package.  For full documentation, build
   or install lang/rust as a package.

Upstream changes:

Version 1.51.0 (2021-03-25)
============================

Language
--------
- [You can now parameterize items such as functions, traits, and
  `struct`s by constant values in addition to by types and
  lifetimes.][79135] Also known as "const generics" E.g. you can
  now write the following. Note:  Only values of primitive integers,
  `bool`, or `char` types are currently permitted.
  ```rust
  struct GenericArray<T, const LENGTH: usize> {
      inner: [T; LENGTH]
  }

  impl<T, const LENGTH: usize> GenericArray<T, LENGTH> {
      const fn last(&self) -> Option<&T> {
          if LENGTH == 0 {
              None
          } else {
              Some(&self.inner[LENGTH - 1])
          }
      }
  }
  ```

Compiler
--------

- [Added the `-Csplit-debuginfo` codegen option for macOS platforms.][79570]
  This option controls whether debug information is split across
  multiple files or packed into a single file. **Note** This option
  is unstable on other platforms.
- [Added tier 3\* support for `aarch64_be-unknown-linux-gnu`,
  `aarch64-unknown-linux-gnu_ilp32`, and
  `aarch64_be-unknown-linux-gnu_ilp32` targets.][81455]

- [Added tier 3 support for `i386-unknown-linux-gnu` and
  `i486-unknown-linux-gnu` targets.][80662]

- [The `target-cpu=native` option will now detect individual features
  of CPUs.][80749]

\* Refer to Rust's [platform support page][platform-support-doc] for more
information on Rust's tiered platform support.

Libraries
---------

- [`Box::downcast` is now also implemented for any `dyn Any + Send
  + Sync` object.][80945]
- [`str` now implements `AsMut<str>`.][80279]
- [`u64` and `u128` now implement `From<char>`.][79502]
- [`Error` is now implemented for `&T` where `T` implements `Error`.][75180]
- [`Poll::{map_ok, map_err}` are now implemented for
  `Poll<Option<Result<T,E>>>`.][80968]
- [`unsigned_abs` is now implemented for all signed integer types.][80959]
- [`io::Empty` now implements `io::Seek`.][78044]
- [`rc::Weak<T>` and `sync::Weak<T>`'s methods such as `as_ptr`
  are now implemented for `T: ?Sized` types.][80764]
- [`Div` and `Rem` by their `NonZero` variant is now implemented
  for all unsigned integers.][79134]

Stabilized APIs
---------------

- [`Arc::decrement_strong_count`]
- [`Arc::increment_strong_count`]
- [`Once::call_once_force`]
- [`Peekable::next_if_eq`]
- [`Peekable::next_if`]
- [`Seek::stream_position`]
- [`array::IntoIter`]
- [`panic::panic_any`]
- [`ptr::addr_of!`]
- [`ptr::addr_of_mut!`]
- [`slice::fill_with`]
- [`slice::split_inclusive_mut`]
- [`slice::split_inclusive`]
- [`slice::strip_prefix`]
- [`slice::strip_suffix`]
- [`str::split_inclusive`]
- [`sync::OnceState`]
- [`task::Wake`]
- [`VecDeque::range`]
- [`VecDeque::range_mut`]

Cargo
-----
- [Added the `split-debuginfo` profile option to control the -Csplit-debuginfo
  codegen option.][cargo/9112]
- [Added the `resolver` field to `Cargo.toml` to enable the new
  feature resolver and CLI option behavior.][cargo/8997] Version
  2 of the feature resolver will try to avoid unifying features of
  dependencies where that unification could be unwanted.  Such as
  using the same dependency with a `std` feature in a build scripts
  and proc-macros, while using the `no-std` feature in the final
  binary. See the [Cargo book documentation][feature-resolver@2.0]
  for more information on the feature.

Rustdoc
-------

- [Rustdoc will now include documentation for methods available
  from _nested_ `Deref` traits.][80653]
- [You can now provide a `--default-theme` flag which sets the
  default theme to use for documentation.][79642]

Various improvements to intra-doc links:

- [You can link to non-path primitives such as `slice`.][80181]
- [You can link to associated items.][74489]
- [You can now include generic parameters when linking to items,
  like `Vec<T>`.][76934]

Misc
----
- [You can now pass `--include-ignored` to tests (e.g. with
  `cargo test -- --include-ignored`) to include testing tests marked
  `#[ignore]`.][80053]

Compatibility Notes
-------------------

- [WASI platforms no longer use the `wasm-bindgen` ABI, and instead
  use the wasm32 ABI.][79998]
- [`rustc` no longer promotes division, modulo and indexing operations
  to `const` that could fail.][80579]
- [The minimum version of glibc for the following platforms has
  been bumped to version 2.31 for the distributed artifacts.][81521]
    - `armv5te-unknown-linux-gnueabi`
    - `sparc64-unknown-linux-gnu`
    - `thumbv7neon-unknown-linux-gnueabihf`
    - `armv7-unknown-linux-gnueabi`
    - `x86_64-unknown-linux-gnux32`
- [`atomic::spin_loop_hint` has been deprecated.][80966] It's
  recommended to use `hint::spin_loop` instead.

Internal Only
-------------

- [Consistently avoid constructing optimized MIR when not doing codegen][80718]

[79135]: rust-lang/rust#79135
[74489]: rust-lang/rust#74489
[76934]: rust-lang/rust#76934
[79570]: rust-lang/rust#79570
[80181]: rust-lang/rust#80181
[79642]: rust-lang/rust#79642
[80945]: rust-lang/rust#80945
[80279]: rust-lang/rust#80279
[80053]: rust-lang/rust#80053
[79502]: rust-lang/rust#79502
[75180]: rust-lang/rust#75180
[79135]: rust-lang/rust#79135
[81521]: rust-lang/rust#81521
[80968]: rust-lang/rust#80968
[80959]: rust-lang/rust#80959
[80718]: rust-lang/rust#80718
[80653]: rust-lang/rust#80653
[80579]: rust-lang/rust#80579
[79998]: rust-lang/rust#79998
[78044]: rust-lang/rust#78044
[81455]: rust-lang/rust#81455
[80764]: rust-lang/rust#80764
[80749]: rust-lang/rust#80749
[80662]: rust-lang/rust#80662
[79134]: rust-lang/rust#79134
[80966]: rust-lang/rust#80966
[cargo/8997]: rust-lang/cargo#8997
[cargo/9112]: rust-lang/cargo#9112
[feature-resolver@2.0]: https://doc.rust-lang.org/nightly/cargo/reference/features.html#feature-resolver-version-2
[`Once::call_once_force`]: https://doc.rust-lang.org/stable/std/sync/struct.Once.html#method.call_once_force
[`sync::OnceState`]: https://doc.rust-lang.org/stable/std/sync/struct.OnceState.html
[`panic::panic_any`]: https://doc.rust-lang.org/stable/std/panic/fn.panic_any.html
[`slice::strip_prefix`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.strip_prefix
[`slice::strip_suffix`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.strip_prefix
[`Arc::increment_strong_count`]: https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#method.increment_strong_count
[`Arc::decrement_strong_count`]: https://doc.rust-lang.org/nightly/std/sync/struct.Arc.html#method.decrement_strong_count
[`slice::fill_with`]: https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.fill_with
[`ptr::addr_of!`]: https://doc.rust-lang.org/nightly/std/ptr/macro.addr_of.html
[`ptr::addr_of_mut!`]: https://doc.rust-lang.org/nightly/std/ptr/macro.addr_of_mut.html
[`array::IntoIter`]: https://doc.rust-lang.org/nightly/std/array/struct.IntoIter.html
[`slice::split_inclusive`]: https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_inclusive
[`slice::split_inclusive_mut`]: https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.split_inclusive_mut
[`str::split_inclusive`]: https://doc.rust-lang.org/nightly/std/primitive.str.html#method.split_inclusive
[`task::Wake`]: https://doc.rust-lang.org/nightly/std/task/trait.Wake.html
[`Seek::stream_position`]: https://doc.rust-lang.org/nightly/std/io/trait.Seek.html#method.stream_position
[`Peekable::next_if`]: https://doc.rust-lang.org/nightly/std/iter/struct.Peekable.html#method.next_if
[`Peekable::next_if_eq`]: https://doc.rust-lang.org/nightly/std/iter/struct.Peekable.html#method.next_if_eq
[`VecDeque::range`]: https://doc.rust-lang.org/nightly/std/collections/struct.VecDeque.html#method.range
[`VecDeque::range_mut`]: https://doc.rust-lang.org/nightly/std/collections/struct.VecDeque.html#method.range_mut
@lcnr lcnr added the A-const-generics Area: const generics (parameters and arguments) label Aug 26, 2021
gcapizzi added a commit to gcapizzi/expect that referenced this pull request Aug 13, 2022
This was possible thanks to the [stabilisation of minimal const generics
support](rust-lang/rust#79135) in Rust 1.51.
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) disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. finished-final-comment-period The final comment period is finished for this PR / Issue. merged-by-bors This PR was explicitly merged by bors. relnotes Marks issues that should be documented in the release notes of the next release. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet