Skip to content

Commit fd2632d

Browse files
committed
Auto merge of #104087 - nbdd0121:const, r=scottmcm
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 #76001 (the tracking issue should *not* be closed as it needs to track inline const in pattern position). The initial implementation is done in #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. #89964). The inference is implemented in #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 #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: #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
2 parents 32f4e77 + 360117c commit fd2632d

14 files changed

+74
-79
lines changed

tests/ui-toml/suppress_lint_in_const/test.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
#![feature(inline_const)]
21
#![warn(clippy::indexing_slicing)]
32
// We also check the out_of_bounds_indexing lint here, because it lints similar things and
43
// we want to avoid false positives.

tests/ui-toml/suppress_lint_in_const/test.stderr

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: indexing may panic
2-
--> tests/ui-toml/suppress_lint_in_const/test.rs:27:5
2+
--> tests/ui-toml/suppress_lint_in_const/test.rs:26:5
33
|
44
LL | x[index];
55
| ^^^^^^^^
@@ -9,39 +9,39 @@ LL | x[index];
99
= help: to override `-D warnings` add `#[allow(clippy::indexing_slicing)]`
1010

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

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

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

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

4343
error: indexing may panic
44-
--> tests/ui-toml/suppress_lint_in_const/test.rs:51:5
44+
--> tests/ui-toml/suppress_lint_in_const/test.rs:50:5
4545
|
4646
LL | v[M];
4747
| ^^^^

tests/ui/arithmetic_side_effects.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
arithmetic_overflow,
1111
unconditional_panic
1212
)]
13-
#![feature(const_mut_refs, inline_const)]
13+
#![feature(const_mut_refs)]
1414
#![warn(clippy::arithmetic_side_effects)]
1515

1616
extern crate proc_macro_derive;

tests/ui/bool_to_int_with_if.fixed

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#![feature(let_chains, inline_const)]
1+
#![feature(let_chains)]
22
#![warn(clippy::bool_to_int_with_if)]
33
#![allow(unused, dead_code, clippy::unnecessary_operation, clippy::no_effect)]
44

tests/ui/bool_to_int_with_if.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#![feature(let_chains, inline_const)]
1+
#![feature(let_chains)]
22
#![warn(clippy::bool_to_int_with_if)]
33
#![allow(unused, dead_code, clippy::unnecessary_operation, clippy::no_effect)]
44

tests/ui/const_is_empty.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
#![feature(inline_const)]
21
#![warn(clippy::const_is_empty)]
32
#![allow(clippy::needless_late_init, unused_must_use)]
43

tests/ui/const_is_empty.stderr

+26-26
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: this expression always evaluates to true
2-
--> tests/ui/const_is_empty.rs:6:8
2+
--> tests/ui/const_is_empty.rs:5:8
33
|
44
LL | if "".is_empty() {
55
| ^^^^^^^^^^^^^
@@ -8,151 +8,151 @@ LL | if "".is_empty() {
88
= help: to override `-D warnings` add `#[allow(clippy::const_is_empty)]`
99

1010
error: this expression always evaluates to false
11-
--> tests/ui/const_is_empty.rs:9:8
11+
--> tests/ui/const_is_empty.rs:8:8
1212
|
1313
LL | if "foobar".is_empty() {
1414
| ^^^^^^^^^^^^^^^^^^^
1515

1616
error: this expression always evaluates to true
17-
--> tests/ui/const_is_empty.rs:15:8
17+
--> tests/ui/const_is_empty.rs:14:8
1818
|
1919
LL | if b"".is_empty() {
2020
| ^^^^^^^^^^^^^^
2121

2222
error: this expression always evaluates to false
23-
--> tests/ui/const_is_empty.rs:18:8
23+
--> tests/ui/const_is_empty.rs:17:8
2424
|
2525
LL | if b"foobar".is_empty() {
2626
| ^^^^^^^^^^^^^^^^^^^^
2727

2828
error: this expression always evaluates to true
29-
--> tests/ui/const_is_empty.rs:35:8
29+
--> tests/ui/const_is_empty.rs:34:8
3030
|
3131
LL | if empty2.is_empty() {
3232
| ^^^^^^^^^^^^^^^^^
3333

3434
error: this expression always evaluates to false
35-
--> tests/ui/const_is_empty.rs:38:8
35+
--> tests/ui/const_is_empty.rs:37:8
3636
|
3737
LL | if non_empty2.is_empty() {
3838
| ^^^^^^^^^^^^^^^^^^^^^
3939

4040
error: this expression always evaluates to true
41-
--> tests/ui/const_is_empty.rs:60:13
41+
--> tests/ui/const_is_empty.rs:59:13
4242
|
4343
LL | let _ = EMPTY_STR.is_empty();
4444
| ^^^^^^^^^^^^^^^^^^^^
4545

4646
error: this expression always evaluates to false
47-
--> tests/ui/const_is_empty.rs:62:13
47+
--> tests/ui/const_is_empty.rs:61:13
4848
|
4949
LL | let _ = NON_EMPTY_STR.is_empty();
5050
| ^^^^^^^^^^^^^^^^^^^^^^^^
5151

5252
error: this expression always evaluates to true
53-
--> tests/ui/const_is_empty.rs:64:13
53+
--> tests/ui/const_is_empty.rs:63:13
5454
|
5555
LL | let _ = EMPTY_BSTR.is_empty();
5656
| ^^^^^^^^^^^^^^^^^^^^^
5757

5858
error: this expression always evaluates to false
59-
--> tests/ui/const_is_empty.rs:66:13
59+
--> tests/ui/const_is_empty.rs:65:13
6060
|
6161
LL | let _ = NON_EMPTY_BSTR.is_empty();
6262
| ^^^^^^^^^^^^^^^^^^^^^^^^^
6363

6464
error: this expression always evaluates to true
65-
--> tests/ui/const_is_empty.rs:68:13
65+
--> tests/ui/const_is_empty.rs:67:13
6666
|
6767
LL | let _ = EMPTY_ARRAY.is_empty();
6868
| ^^^^^^^^^^^^^^^^^^^^^^
6969

7070
error: this expression always evaluates to true
71-
--> tests/ui/const_is_empty.rs:70:13
71+
--> tests/ui/const_is_empty.rs:69:13
7272
|
7373
LL | let _ = EMPTY_ARRAY_REPEAT.is_empty();
7474
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
7575

7676
error: this expression always evaluates to true
77-
--> tests/ui/const_is_empty.rs:72:13
77+
--> tests/ui/const_is_empty.rs:71:13
7878
|
7979
LL | let _ = EMPTY_U8_SLICE.is_empty();
8080
| ^^^^^^^^^^^^^^^^^^^^^^^^^
8181

8282
error: this expression always evaluates to false
83-
--> tests/ui/const_is_empty.rs:74:13
83+
--> tests/ui/const_is_empty.rs:73:13
8484
|
8585
LL | let _ = NON_EMPTY_U8_SLICE.is_empty();
8686
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
8787

8888
error: this expression always evaluates to false
89-
--> tests/ui/const_is_empty.rs:76:13
89+
--> tests/ui/const_is_empty.rs:75:13
9090
|
9191
LL | let _ = NON_EMPTY_ARRAY.is_empty();
9292
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
9393

9494
error: this expression always evaluates to false
95-
--> tests/ui/const_is_empty.rs:78:13
95+
--> tests/ui/const_is_empty.rs:77:13
9696
|
9797
LL | let _ = NON_EMPTY_ARRAY_REPEAT.is_empty();
9898
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
9999

100100
error: this expression always evaluates to true
101-
--> tests/ui/const_is_empty.rs:80:13
101+
--> tests/ui/const_is_empty.rs:79:13
102102
|
103103
LL | let _ = EMPTY_REF_ARRAY.is_empty();
104104
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
105105

106106
error: this expression always evaluates to false
107-
--> tests/ui/const_is_empty.rs:82:13
107+
--> tests/ui/const_is_empty.rs:81:13
108108
|
109109
LL | let _ = NON_EMPTY_REF_ARRAY.is_empty();
110110
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
111111

112112
error: this expression always evaluates to true
113-
--> tests/ui/const_is_empty.rs:84:13
113+
--> tests/ui/const_is_empty.rs:83:13
114114
|
115115
LL | let _ = EMPTY_SLICE.is_empty();
116116
| ^^^^^^^^^^^^^^^^^^^^^^
117117

118118
error: this expression always evaluates to false
119-
--> tests/ui/const_is_empty.rs:86:13
119+
--> tests/ui/const_is_empty.rs:85:13
120120
|
121121
LL | let _ = NON_EMPTY_SLICE.is_empty();
122122
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
123123

124124
error: this expression always evaluates to false
125-
--> tests/ui/const_is_empty.rs:88:13
125+
--> tests/ui/const_is_empty.rs:87:13
126126
|
127127
LL | let _ = NON_EMPTY_SLICE_REPEAT.is_empty();
128128
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
129129

130130
error: this expression always evaluates to false
131-
--> tests/ui/const_is_empty.rs:94:13
131+
--> tests/ui/const_is_empty.rs:93:13
132132
|
133133
LL | let _ = value.is_empty();
134134
| ^^^^^^^^^^^^^^^^
135135

136136
error: this expression always evaluates to false
137-
--> tests/ui/const_is_empty.rs:97:13
137+
--> tests/ui/const_is_empty.rs:96:13
138138
|
139139
LL | let _ = x.is_empty();
140140
| ^^^^^^^^^^^^
141141

142142
error: this expression always evaluates to true
143-
--> tests/ui/const_is_empty.rs:99:13
143+
--> tests/ui/const_is_empty.rs:98:13
144144
|
145145
LL | let _ = "".is_empty();
146146
| ^^^^^^^^^^^^^
147147

148148
error: this expression always evaluates to true
149-
--> tests/ui/const_is_empty.rs:101:13
149+
--> tests/ui/const_is_empty.rs:100:13
150150
|
151151
LL | let _ = b"".is_empty();
152152
| ^^^^^^^^^^^^^^
153153

154154
error: this expression always evaluates to true
155-
--> tests/ui/const_is_empty.rs:155:13
155+
--> tests/ui/const_is_empty.rs:154:13
156156
|
157157
LL | let _ = val.is_empty();
158158
| ^^^^^^^^^^^^^^

tests/ui/indexing_slicing_index.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
//@compile-flags: -Zdeduplicate-diagnostics=yes
22

3-
#![feature(inline_const)]
43
#![warn(clippy::indexing_slicing)]
54
// We also check the out_of_bounds_indexing lint here, because it lints similar things and
65
// we want to avoid false positives.

0 commit comments

Comments
 (0)