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

Acknowledge that [CONST; N] is stable #79270

Merged
merged 3 commits into from Dec 21, 2020

Conversation

RalfJung
Copy link
Member

@RalfJung RalfJung commented Nov 21, 2020

When const_in_array_repeat_expressions (RFC 2203) got unstably implemented as part of #61749, accidentally, the special case of repeating a constant got stabilized immediately. That is why the following code works on stable:

const EMPTY: Vec<i32> = Vec::new();

pub const fn bar() -> [Vec<i32>; 2] {
    [EMPTY; 2]
}

fn main() {
    let x = bar();
}

In contrast, if we had written [expr; 2] for some expression that is not literally a constant but could be evaluated at compile-time (e.g. (EMPTY,).0), this would have failed.

We could take back this stabilization as it was clearly accidental. However, I propose we instead just officially accept this and stabilize a small subset of RFC 2203, while leaving the more complex case of general expressions that could be evaluated at compile-time unstable. Making that case work well is pretty much blocked on inline const expressions (to avoid relying too much on implicit promotion), so it could take a bit until it comes to full fruition. [CONST; N] is an uncontroversial subset of this feature that has no semantic ambiguities, does not rely on promotion, and basically provides the full expressive power of RFC 2203 but without the convenience (people have to define constants to repeat them, possibly using associated consts if generics are involved).

Well, I said "no semantic ambiguities", that is only almost true... the one point I am not sure about is [CONST; 0]. There are two possible behaviors here: either this is equivalent to let x = CONST; [x; 0], or it is a NOP (if we argue that the constant is never actually instantiated). The difference between the two is that if CONST has a destructor, it should run in the former case (but currently doesn't, due to #74836); but should not run if it is considered a NOP. For regular [x; 0] there seems to be consensus on running drop (there isn't really an alternative); any opinions for the CONST special case? Should this instantiate the const only to immediately run its destructors? That seems somewhat silly to me. After all, the let-expansion does not work in general, for N > 1.

Cc @rust-lang/lang @rust-lang/wg-const-eval
Cc #49147

@rust-highfive
Copy link
Collaborator

r? @matthewjasper

(rust_highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Nov 21, 2020
@RalfJung RalfJung added I-nominated T-lang Relevant to the language team, which will review and decide on the PR/issue. labels Nov 21, 2020
@matthewjasper matthewjasper added S-waiting-on-team Status: Awaiting decision from the relevant subteam (see the T-<team> label). and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Nov 28, 2020
@matthewjasper
Copy link
Contributor

r=me with lang team sign-off

@RalfJung
Copy link
Member Author

Regarding dropping, I now added a test to make sure that [CONST; 0] does not call the destructor. The reasoning is that [CONST; N] should instantiate the const and then later call the destructor exactly N times.

This is in contrast to [non_const_expr; N] which always evaluates the expression exactly once, and thus calls the destructor exactly once (with #74836 fixed). Note that there being a destructor implies !Copy and thus N <= 1.

@scottmcm
Copy link
Member

scottmcm commented Dec 1, 2020

We discussed this in the lang team meeting today and decided to go ahead and

@rfcbot fcp merge


I agree that we might as well just allow this to work for something that's just the ident (well, a path) of a const. As you mentioned, we'll want [const { EMPTY }; 2] to work at some point, and it seems fine for this specific case to allow it without the extra const{} -- it feels kinda weird to have to put it around something that's already a const anyway.

@rfcbot
Copy link

rfcbot commented Dec 1, 2020

Team member @scottmcm has proposed to merge this. The next step is review by the rest of the tagged team members:

No concerns currently listed.

Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

See this document for info about what commands tagged team members can give me.

@rfcbot rfcbot added proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. labels Dec 1, 2020
@RalfJung
Copy link
Member Author

RalfJung commented Dec 2, 2020

@scottmcm

We discussed this in the lang team meeting today and decided to go ahead and

Did you have a chance to talk about the issue with [expr; 0] that I described above?

bors bot added a commit to tock/tock that referenced this pull request Dec 2, 2020
2215: remove all uses of unstable const_in_array_repeat_expressions feature r=bradjc a=hudson-ayers

### Pull Request Overview

This pull request removes all uses of the unstable `const_in_array_repeat_expressions` feature. It was originally necessary in order to have ergonomic scheduler components, but a subset of the feature that is sufficient for our use was accidentally stabilized, and the Rust maintainers are moving to make that stabilization permanent (see rust-lang/rust#79270). So this is an easy way to get rid of an unstable feature.


### Testing Strategy

This pull request was tested by compiling and flashing several apps on an Imix.


### TODO or Help Wanted

N/A

### Documentation Updated

- [x] No updates are required.

### Formatting

- [x] Ran `make prepush`.


Co-authored-by: Hudson Ayers <hayers@stanford.edu>
@rfcbot rfcbot added final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. and removed proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. labels Dec 8, 2020
@rfcbot
Copy link

rfcbot commented Dec 8, 2020

🔔 This is now entering its final comment period, as per the review above. 🔔

@scottmcm
Copy link
Member

scottmcm commented Dec 8, 2020

@RalfJung we discussed this again today in the triage meeting, and agreed that [CONST; 0] not instantiating the const made sense, as consistent with other lengths as you described above.


Another piece of that which came to mind today is that since [CONST; 0] must be a const item, then if it panics in evaluation then it'll give a const_err warning on the item. AKA it'll be evaluated somewhere, even if not in that expression, so one still has help finding any problems that might exist in it.

@Mark-Simulacrum
Copy link
Member

(Dropping nomination - I don't think this needs further lang discussion right now)

@rfcbot rfcbot added finished-final-comment-period The final comment period is finished for this PR / Issue. to-announce Announce this issue on triage meeting and removed final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. labels Dec 18, 2020
@rfcbot
Copy link

rfcbot commented Dec 18, 2020

The final comment period, with a disposition to merge, as per the review above, is now complete.

As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed.

The RFC will be merged soon.

@bors bors added the S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. label Dec 20, 2020
@bors
Copy link
Contributor

bors commented Dec 20, 2020

Testing commit f2ced78 with merge 3e8060c...

bors added a commit to rust-lang-ci/rust that referenced this pull request Dec 20, 2020
Acknowledge that `[CONST; N]` is stable

When `const_in_array_repeat_expressions` (RFC 2203) got unstably implemented as part of rust-lang#61749, accidentally, the special case of repeating a *constant* got stabilized immediately. That is why the following code works on stable:

```rust
const EMPTY: Vec<i32> = Vec::new();

pub const fn bar() -> [Vec<i32>; 2] {
    [EMPTY; 2]
}

fn main() {
    let x = bar();
}
```

In contrast, if we had written `[expr; 2]` for some expression that is not *literally* a constant but could be evaluated at compile-time (e.g. `(EMPTY,).0`), this would have failed.

We could take back this stabilization as it was clearly accidental. However, I propose we instead just officially accept this and stabilize a small subset of RFC 2203, while leaving the more complex case of general expressions that could be evaluated at compile-time unstable. Making that case work well is pretty much blocked on inline `const` expressions (to avoid relying too much on [implicit promotion](https://github.com/rust-lang/const-eval/blob/master/promotion.md)), so it could take a bit until it comes to full fruition. `[CONST; N]` is an uncontroversial subset of this feature that has no semantic ambiguities, does not rely on promotion, and basically provides the full expressive power of RFC 2203 but without the convenience (people have to define constants to repeat them, possibly using associated consts if generics are involved).

Well, I said "no semantic ambiguities", that is only almost true... the one point I am not sure about is `[CONST; 0]`. There are two possible behaviors here: either this is equivalent to `let x = CONST; [x; 0]`, or it is a NOP (if we argue that the constant is never actually instantiated). The difference between the two is that if `CONST` has a destructor, it should run in the former case (but currently doesn't, due to rust-lang#74836); but should not run if it is considered a NOP. For regular `[x; 0]` there seems to be consensus on running drop (there isn't really an alternative); any opinions for the `CONST` special case? Should this instantiate the const only to immediately run its destructors? That seems somewhat silly to me. After all, the `let`-expansion does *not* work in general, for `N > 1`.

Cc `@rust-lang/lang` `@rust-lang/wg-const-eval`
Cc rust-lang#49147
@rust-log-analyzer
Copy link
Collaborator

The job x86_64-gnu-llvm-9 failed! Check out the build log: (web) (plain)

Click to see the possible cause of the failure (guessed by this bot)

@bors
Copy link
Contributor

bors commented Dec 20, 2020

💔 Test failed - checks-actions

@bors bors added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Dec 20, 2020
@RalfJung
Copy link
Member Author

Rebased... but then I realized this is a network problem:

Couldn't connect to server (Failed to connect to crates.io port 443: Network is unreachable)

@bors retry

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Dec 20, 2020
@RalfJung
Copy link
Member Author

@bors r=oli-obk

@bors
Copy link
Contributor

bors commented Dec 21, 2020

📌 Commit 7f3e18c has been approved by oli-obk

@bors
Copy link
Contributor

bors commented Dec 21, 2020

Testing commit 7f3e18c with merge 11c94a1...

@bors
Copy link
Contributor

bors commented Dec 21, 2020

☀️ Test successful - checks-actions
Approved by: oli-obk
Pushing 11c94a1 to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors label Dec 21, 2020
@bors bors merged commit 11c94a1 into rust-lang:master Dec 21, 2020
1 check passed
@rustbot rustbot added this to the 1.50.0 milestone Dec 21, 2020
@RalfJung RalfJung deleted the array-repeat-consts branch Dec 26, 2020
@spastorino spastorino removed the to-announce Announce this issue on triage meeting label Dec 31, 2020
@RalfJung RalfJung added the relnotes Marks issues that should be documented in the release notes of the next release. label Jan 1, 2021
netbsd-srcmastr pushed a commit to NetBSD/pkgsrc that referenced this pull request Apr 19, 2021
Pkgsrc changes:
 * Adjust patches, re-compute line offsets, fix capitalization.
 * Remove i686/FreeBSD support, no longer provided upstream.
 * Bump bootstraps to 1.49.0.
 * Change USE_TOOLS from bsdtar to gtar.
 * Reduce diffs to pkgsrc-wip package patches.
 * Allow rust.BUILD_TARGET to override automatic choice of target.
 * Add an i586/NetBSD (pentium) bootstrap variant (needs testing),
   not yet added as bootstrap since 1.49 doesn't have that variant.

Upstream changes:

Version 1.50.0 (2021-02-11)
============================

Language
-----------------------
- [You can now use `const` values for `x` in `[x; N]` array
  expressions.][79270] This has been technically possible since
  1.38.0, as it was unintentionally stabilized.
- [Assignments to `ManuallyDrop<T>` union fields are now considered
  safe.][78068]

Compiler
-----------------------
- [Added tier 3\* support for the `armv5te-unknown-linux-uclibceabi`
  target.][78142]
- [Added tier 3 support for the `aarch64-apple-ios-macabi` target.][77484]
- [The `x86_64-unknown-freebsd` is now built with the full toolset.][79484]

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

Libraries
-----------------------

- [`proc_macro::Punct` now implements `PartialEq<char>`.][78636]
- [`ops::{Index, IndexMut}` are now implemented for fixed sized
  arrays of any length.][74989]
- [On Unix platforms, the `std::fs::File` type now has a "niche"
  of `-1`.][74699] This value cannot be a valid file descriptor,
  and now means `Option<File>` takes up the same amount of space
  as `File`.

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

- [`bool::then`]
- [`btree_map::Entry::or_insert_with_key`]
- [`f32::clamp`]
- [`f64::clamp`]
- [`hash_map::Entry::or_insert_with_key`]
- [`Ord::clamp`]
- [`RefCell::take`]
- [`slice::fill`]
- [`UnsafeCell::get_mut`]

The following previously stable methods are now `const`.

- [`IpAddr::is_ipv4`]
- [`IpAddr::is_ipv6`]
- [`Layout::size`]
- [`Layout::align`]
- [`Layout::from_size_align`]
- `pow` for all integer types.
- `checked_pow` for all integer types.
- `saturating_pow` for all integer types.
- `wrapping_pow` for all integer types.
- `next_power_of_two` for all unsigned integer types.
- `checked_power_of_two` for all unsigned integer types.

Cargo
-----------------------

- [Added the `[build.rustc-workspace-wrapper]` option.][cargo/8976]
  This option sets a wrapper to execute instead of `rustc`, for
  workspace members only.
- [`cargo:rerun-if-changed` will now, if provided a directory, scan the entire
  contents of that directory for changes.][cargo/8973]
- [Added the `--workspace` flag to the `cargo update` command.][cargo/8725]

Misc
----

- [The search results tab and the help button are focusable with
  keyboard in rustdoc.][79896]
- [Running tests will now print the total time taken to execute.][75752]

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

- [The `compare_and_swap` method on atomics has been deprecated.][79261]
  It's recommended to use the `compare_exchange` and
  `compare_exchange_weak` methods instead.
- [Changes in how `TokenStream`s are checked have fixed some cases
  where you could write unhygenic `macro_rules!` macros.][79472]
- [`#![test]` as an inner attribute is now considered unstable like
  other inner macro attributes, and reports an error by default
  through the `soft_unstable` lint.][79003]
- [Overriding a `forbid` lint at the same level that it was set is
  now a hard error.][78864]
- [Dropped support for all cloudabi targets.][78439]
- [You can no longer intercept `panic!` calls by supplying your
  own macro.][78343] It's recommended to use the `#[panic_handler]`
  attribute to provide your own implementation.
- [Semi-colons after item statements (e.g. `struct Foo {};`) now
  produce a warning.][78296]

[74989]: rust-lang/rust#74989
[79261]: rust-lang/rust#79261
[79896]: rust-lang/rust#79896
[79484]: rust-lang/rust#79484
[79472]: rust-lang/rust#79472
[79270]: rust-lang/rust#79270
[79003]: rust-lang/rust#79003
[78864]: rust-lang/rust#78864
[78636]: rust-lang/rust#78636
[78439]: rust-lang/rust#78439
[78343]: rust-lang/rust#78343
[78296]: rust-lang/rust#78296
[78068]: rust-lang/rust#78068
[75752]: rust-lang/rust#75752
[74699]: rust-lang/rust#74699
[78142]: rust-lang/rust#78142
[77484]: rust-lang/rust#77484
[cargo/8976]: rust-lang/cargo#8976
[cargo/8973]: rust-lang/cargo#8973
[cargo/8725]: rust-lang/cargo#8725
[`IpAddr::is_ipv4`]: https://doc.rust-lang.org/stable/std/net/enum.IpAddr.html#method.is_ipv4
[`IpAddr::is_ipv6`]: https://doc.rust-lang.org/stable/std/net/enum.IpAddr.html#method.is_ipv6
[`Layout::align`]: https://doc.rust-lang.org/stable/std/alloc/struct.Layout.html#method.align
[`Layout::from_size_align`]: https://doc.rust-lang.org/stable/std/alloc/struct.Layout.html#method.from_size_align
[`Layout::size`]: https://doc.rust-lang.org/stable/std/alloc/struct.Layout.html#method.size
[`Ord::clamp`]: https://doc.rust-lang.org/stable/std/cmp/trait.Ord.html#method.clamp
[`RefCell::take`]: https://doc.rust-lang.org/stable/std/cell/struct.RefCell.html#method.take
[`UnsafeCell::get_mut`]: https://doc.rust-lang.org/stable/std/cell/struct.UnsafeCell.html#method.get_mut
[`bool::then`]: https://doc.rust-lang.org/stable/std/primitive.bool.html#method.then
[`btree_map::Entry::or_insert_with_key`]: https://doc.rust-lang.org/stable/std/collections/btree_map/enum.Entry.html#method.or_insert_with_key
[`f32::clamp`]: https://doc.rust-lang.org/stable/std/primitive.f32.html#method.clamp
[`f64::clamp`]: https://doc.rust-lang.org/stable/std/primitive.f64.html#method.clamp
[`hash_map::Entry::or_insert_with_key`]: https://doc.rust-lang.org/stable/std/collections/hash_map/enum.Entry.html#method.or_insert_with_key
[`slice::fill`]: https://doc.rust-lang.org/stable/std/primitive.slice.html#method.fill
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
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