Skip to content

Commit

Permalink
Auto merge of rust-lang#104087 - nbdd0121:const, r=scottmcm
Browse files Browse the repository at this point in the history
Stabilise inline_const

# Stabilisation Report

## Summary

This PR will stabilise `inline_const` feature in expression position. `inline_const_pat` is still unstable and will *not* be stabilised.

The feature will allow code like this:
```rust
foo(const { 1 + 1 })
```
which is roughly desugared into
```rust
struct Foo;
impl Foo {
    const FOO: i32 = 1 + 1;
}
foo(Foo::FOO)
```

This feature is from rust-lang/rfcs#2920 and is tracked in rust-lang#76001 (the tracking issue should *not* be closed as it needs to track inline const in pattern position). The initial implementation is done in rust-lang#77124.

## Difference from RFC

There are two major differences (enhancements) as implemented from the RFC. First thing is that the RFC says that the type of an inline const block inferred from the content *within* it, but we currently can infer the type using the information from outside the const block as well. This is a frequently requested feature to the initial implementation (e.g. rust-lang#89964). The inference is implemented in rust-lang#89561 and is done by treating inline const similar to a closure and therefore share inference context with its parent body.

This allows code like:
```rust
let v: Vec<i32> = const { Vec::new() };
```

Another enhancement that differs from the RFC is that we currently allow inline consts to reference generic parameters. This is implemented in rust-lang#96557.

This allows code like:
```rust
fn create_none_array<T, const N: usize>() -> [Option<T>; N] {
    [const { None::<T> }; N]
}
```

This enhancement also makes inline const usable as static asserts:

```rust
fn require_zst<T>() {
    const { assert!(std::mem::size_of::<T>() == 0) }
}
```

## Documentation

Reference: rust-lang/reference#1295

## Unresolved issues

We still have a few issues that are not resolved, but I don't think it necessarily has to block stabilisation:
* expr fragment specifier issue: rust-lang#86730
* ~~`const {}` behaves similar to `async {}` but not to `{}` and `unsafe {}` (they are treated as `ExpressionWithoutBlock` rather than `ExpressionWithBlock`): https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/const.20blocks.20differ.20from.20normal.20and.20from.20unsafe.20blocks/near/290229453~~

## Tests

There are a few tests in https://github.com/rust-lang/rust/tree/master/src/test/ui/inline-const
  • Loading branch information
bors committed Apr 24, 2024
2 parents 5557f8c + 8169c4c commit 87a0479
Show file tree
Hide file tree
Showing 95 changed files with 206 additions and 319 deletions.
1 change: 0 additions & 1 deletion compiler/rustc_ast_passes/src/feature_gate.rs
Expand Up @@ -556,7 +556,6 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
half_open_range_patterns_in_slices,
"half-open range patterns in slices are unstable"
);
gate_all!(inline_const, "inline-const is experimental");
gate_all!(inline_const_pat, "inline-const in pattern position is experimental");
gate_all!(associated_const_equality, "associated const equality is incomplete");
gate_all!(yeet_expr, "`do yeet` expression is experimental");
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/accepted.rs
Expand Up @@ -211,6 +211,8 @@ declare_features! (
(accepted, inclusive_range_syntax, "1.26.0", Some(28237)),
/// Allows inferring outlives requirements (RFC 2093).
(accepted, infer_outlives_requirements, "1.30.0", Some(44493)),
/// Allow anonymous constants from an inline `const` block
(accepted, inline_const, "CURRENT_RUSTC_VERSION", Some(76001)),
/// Allows irrefutable patterns in `if let` and `while let` statements (RFC 2086).
(accepted, irrefutable_let_patterns, "1.33.0", Some(44495)),
/// Allows `#[instruction_set(_)]` attribute.
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_feature/src/unstable.rs
Expand Up @@ -501,8 +501,6 @@ declare_features! (
(unstable, impl_trait_in_fn_trait_return, "1.64.0", Some(99697)),
/// Allows associated types in inherent impls.
(incomplete, inherent_associated_types, "1.52.0", Some(8995)),
/// Allow anonymous constants from an inline `const` block
(unstable, inline_const, "1.49.0", Some(76001)),
/// Allow anonymous constants from an inline `const` block in pattern position
(unstable, inline_const_pat, "1.58.0", Some(76001)),
/// Allows using `pointer` and `reference` in intra-doc links
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/lib.rs
Expand Up @@ -37,7 +37,7 @@
#![feature(coroutines)]
#![feature(stmt_expr_attributes)]
#![feature(if_let_guard)]
#![feature(inline_const)]
#![cfg_attr(bootstrap, feature(inline_const))]
#![feature(iter_from_coroutine)]
#![feature(negative_impls)]
#![feature(never_type)]
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_transform/src/lib.rs
Expand Up @@ -4,7 +4,7 @@
#![feature(cow_is_borrowed)]
#![feature(decl_macro)]
#![feature(impl_trait_in_assoc_type)]
#![feature(inline_const)]
#![cfg_attr(bootstrap, feature(inline_const))]
#![feature(is_sorted)]
#![feature(let_chains)]
#![feature(map_try_insert)]
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_parse/src/parser/mod.rs
Expand Up @@ -1252,8 +1252,6 @@ impl<'a> Parser<'a> {
fn parse_const_block(&mut self, span: Span, pat: bool) -> PResult<'a, P<Expr>> {
if pat {
self.psess.gated_spans.gate(sym::inline_const_pat, span);
} else {
self.psess.gated_spans.gate(sym::inline_const, span);
}
self.eat_keyword(kw::Const);
let (attrs, blk) = self.parse_inner_attrs_and_block()?;
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_serialize/src/lib.rs
Expand Up @@ -11,7 +11,7 @@
#![cfg_attr(bootstrap, feature(associated_type_bounds))]
#![feature(const_option)]
#![feature(core_intrinsics)]
#![feature(inline_const)]
#![cfg_attr(bootstrap, feature(inline_const))]
#![feature(min_specialization)]
#![feature(never_type)]
#![feature(ptr_sub_ptr)]
Expand Down
2 changes: 1 addition & 1 deletion library/alloc/src/lib.rs
Expand Up @@ -128,7 +128,6 @@
#![feature(fn_traits)]
#![feature(hasher_prefixfree_extras)]
#![feature(hint_assert_unchecked)]
#![feature(inline_const)]
#![feature(inplace_iteration)]
#![feature(iter_advance_by)]
#![feature(iter_next_chunk)]
Expand Down Expand Up @@ -169,6 +168,7 @@
// Language features:
// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(associated_type_bounds))]
#![cfg_attr(bootstrap, feature(inline_const))]
#![cfg_attr(not(bootstrap), rustc_preserve_ub_checks)]
#![cfg_attr(not(test), feature(coroutine_trait))]
#![cfg_attr(test, feature(panic_update_hook))]
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/lib.rs
Expand Up @@ -201,6 +201,7 @@
//
// Language features:
// tidy-alphabetical-start
#![cfg_attr(bootstrap, feature(inline_const))]
#![feature(abi_unadjusted)]
#![feature(adt_const_params)]
#![feature(allow_internal_unsafe)]
Expand Down Expand Up @@ -231,7 +232,6 @@
#![feature(fundamental)]
#![feature(generic_arg_infer)]
#![feature(if_let_guard)]
#![feature(inline_const)]
#![feature(intra_doc_pointers)]
#![feature(intrinsics)]
#![feature(lang_items)]
Expand Down
9 changes: 6 additions & 3 deletions library/core/src/sync/atomic.rs
Expand Up @@ -511,7 +511,8 @@ impl AtomicBool {
/// # Examples
///
/// ```
/// #![feature(atomic_from_mut, inline_const)]
/// #![feature(atomic_from_mut)]
/// # #![cfg_attr(bootstrap, feature(inline_const))]
/// use std::sync::atomic::{AtomicBool, Ordering};
///
/// let mut some_bools = [const { AtomicBool::new(false) }; 10];
Expand Down Expand Up @@ -1313,7 +1314,8 @@ impl<T> AtomicPtr<T> {
/// # Examples
///
/// ```
/// #![feature(atomic_from_mut, inline_const)]
/// #![feature(atomic_from_mut)]
/// # #![cfg_attr(bootstrap, feature(inline_const))]
/// use std::ptr::null_mut;
/// use std::sync::atomic::{AtomicPtr, Ordering};
///
Expand Down Expand Up @@ -2303,7 +2305,8 @@ macro_rules! atomic_int {
/// # Examples
///
/// ```
/// #![feature(atomic_from_mut, inline_const)]
/// #![feature(atomic_from_mut)]
/// # #![cfg_attr(bootstrap, feature(inline_const))]
#[doc = concat!($extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};")]
///
#[doc = concat!("let mut some_ints = [const { ", stringify!($atomic_type), "::new(0) }; 10];")]
Expand Down
2 changes: 1 addition & 1 deletion library/core/tests/lib.rs
Expand Up @@ -46,7 +46,7 @@
#![feature(hasher_prefixfree_extras)]
#![feature(hashmap_internals)]
#![feature(try_find)]
#![feature(inline_const)]
#![cfg_attr(bootstrap, feature(inline_const))]
#![feature(is_sorted)]
#![feature(layout_for_ptr)]
#![feature(pattern)]
Expand Down
1 change: 0 additions & 1 deletion library/portable-simd/crates/core_simd/src/lib.rs
Expand Up @@ -7,7 +7,6 @@
convert_float_to_int,
core_intrinsics,
decl_macro,
inline_const,
intra_doc_pointers,
repr_simd,
simd_ffi,
Expand Down
Expand Up @@ -2,8 +2,6 @@

The tracking issue for this feature is: [#76001]

See also [`inline_const`](inline-const.md)

------

This feature allows you to use inline constant expressions in pattern position:
Expand Down
32 changes: 0 additions & 32 deletions src/doc/unstable-book/src/language-features/inline-const.md

This file was deleted.

@@ -1,4 +1,3 @@
#![feature(inline_const)]
#![warn(clippy::indexing_slicing)]
// We also check the out_of_bounds_indexing lint here, because it lints similar things and
// we want to avoid false positives.
Expand Down
@@ -1,5 +1,5 @@
error: indexing may panic
--> tests/ui-toml/suppress_lint_in_const/test.rs:27:5
--> tests/ui-toml/suppress_lint_in_const/test.rs:26:5
|
LL | x[index];
| ^^^^^^^^
Expand All @@ -9,39 +9,39 @@ LL | x[index];
= help: to override `-D warnings` add `#[allow(clippy::indexing_slicing)]`

error: indexing may panic
--> tests/ui-toml/suppress_lint_in_const/test.rs:42:5
--> tests/ui-toml/suppress_lint_in_const/test.rs:41:5
|
LL | v[0];
| ^^^^
|
= help: consider using `.get(n)` or `.get_mut(n)` instead

error: indexing may panic
--> tests/ui-toml/suppress_lint_in_const/test.rs:43:5
--> tests/ui-toml/suppress_lint_in_const/test.rs:42:5
|
LL | v[10];
| ^^^^^
|
= help: consider using `.get(n)` or `.get_mut(n)` instead

error: indexing may panic
--> tests/ui-toml/suppress_lint_in_const/test.rs:44:5
--> tests/ui-toml/suppress_lint_in_const/test.rs:43:5
|
LL | v[1 << 3];
| ^^^^^^^^^
|
= help: consider using `.get(n)` or `.get_mut(n)` instead

error: indexing may panic
--> tests/ui-toml/suppress_lint_in_const/test.rs:50:5
--> tests/ui-toml/suppress_lint_in_const/test.rs:49:5
|
LL | v[N];
| ^^^^
|
= help: consider using `.get(n)` or `.get_mut(n)` instead

error: indexing may panic
--> tests/ui-toml/suppress_lint_in_const/test.rs:51:5
--> tests/ui-toml/suppress_lint_in_const/test.rs:50:5
|
LL | v[M];
| ^^^^
Expand Down
2 changes: 1 addition & 1 deletion src/tools/clippy/tests/ui/arithmetic_side_effects.rs
Expand Up @@ -10,7 +10,7 @@
arithmetic_overflow,
unconditional_panic
)]
#![feature(const_mut_refs, inline_const)]
#![feature(const_mut_refs)]
#![warn(clippy::arithmetic_side_effects)]

extern crate proc_macro_derive;
Expand Down
2 changes: 1 addition & 1 deletion src/tools/clippy/tests/ui/bool_to_int_with_if.fixed
@@ -1,4 +1,4 @@
#![feature(let_chains, inline_const)]
#![feature(let_chains)]
#![warn(clippy::bool_to_int_with_if)]
#![allow(unused, dead_code, clippy::unnecessary_operation, clippy::no_effect)]

Expand Down
2 changes: 1 addition & 1 deletion src/tools/clippy/tests/ui/bool_to_int_with_if.rs
@@ -1,4 +1,4 @@
#![feature(let_chains, inline_const)]
#![feature(let_chains)]
#![warn(clippy::bool_to_int_with_if)]
#![allow(unused, dead_code, clippy::unnecessary_operation, clippy::no_effect)]

Expand Down
1 change: 0 additions & 1 deletion src/tools/clippy/tests/ui/const_is_empty.rs
@@ -1,4 +1,3 @@
#![feature(inline_const)]
#![warn(clippy::const_is_empty)]
#![allow(clippy::needless_late_init, unused_must_use)]

Expand Down

0 comments on commit 87a0479

Please sign in to comment.