1
Fork 0

Rollup merge of #91140 - nbdd0121:const_typeck, r=oli-obk

Split inline const to two feature gates and mark expression position inline const complete

This PR splits inline const in pattern position into its own `#![feature(inline_const_pat)]` feature gate, and make the usage in expression position complete.

I think I have resolved most outstanding issues related to `inline_const` with #89561 and other PRs. The only thing left that I am aware of is #90150 and the lack of lifetime checks when inline const is used in pattern position (FIXME in #89561). Implementation-wise when used in pattern position it has to be lowered during MIR building while in expression position it's evaluated only when monomorphizing (just like normal consts), so it makes some sense to separate it into two feature gates so one can progress without being blocked by another.

``@rustbot`` label: T-compiler F-inline_const
This commit is contained in:
Matthias Krüger 2021-11-23 19:28:10 +01:00 committed by GitHub
commit a26c2c7495
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
32 changed files with 72 additions and 43 deletions

View file

@ -719,6 +719,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) {
gate_all!(const_trait_impl, "const trait impls are experimental");
gate_all!(half_open_range_patterns, "half-open range patterns are unstable");
gate_all!(inline_const, "inline-const is experimental");
gate_all!(inline_const_pat, "inline-const in pattern position is experimental");
gate_all!(
const_generics_defaults,
"default values for const generic parameters are experimental"

View file

@ -409,7 +409,9 @@ declare_features! (
/// Allows associated types in inherent impls.
(incomplete, inherent_associated_types, "1.52.0", Some(8995), None),
/// Allow anonymous constants from an inline `const` block
(incomplete, inline_const, "1.49.0", Some(76001), None),
(active, inline_const, "1.49.0", Some(76001), None),
/// Allow anonymous constants from an inline `const` block in pattern position
(incomplete, inline_const_pat, "1.58.0", Some(76001), None),
/// Allows using `pointer` and `reference` in intra-doc links
(active, intra_doc_pointers, "1.51.0", Some(80896), None),
/// Allows `#[instruction_set(_)]` attribute

View file

@ -1243,7 +1243,7 @@ impl<'a> Parser<'a> {
} else if self.eat_keyword(kw::Unsafe) {
self.parse_block_expr(None, lo, BlockCheckMode::Unsafe(ast::UserProvided), attrs)
} else if self.check_inline_const(0) {
self.parse_const_block(lo.to(self.token.span))
self.parse_const_block(lo.to(self.token.span), false)
} else if self.is_do_catch_block() {
self.recover_do_catch(attrs)
} else if self.is_try_block() {

View file

@ -1095,8 +1095,12 @@ impl<'a> Parser<'a> {
}
/// Parses inline const expressions.
fn parse_const_block(&mut self, span: Span) -> PResult<'a, P<Expr>> {
fn parse_const_block(&mut self, span: Span, pat: bool) -> PResult<'a, P<Expr>> {
if pat {
self.sess.gated_spans.gate(sym::inline_const_pat, span);
} else {
self.sess.gated_spans.gate(sym::inline_const, span);
}
self.eat_keyword(kw::Const);
let blk = self.parse_block()?;
let anon_const = AnonConst {

View file

@ -437,7 +437,7 @@ impl<'a> Parser<'a> {
PatKind::Box(pat)
} else if self.check_inline_const(0) {
// Parse `const pat`
let const_expr = self.parse_const_block(lo.to(self.token.span))?;
let const_expr = self.parse_const_block(lo.to(self.token.span), true)?;
if let Some(re) = self.parse_range_end() {
self.parse_pat_range_begin_with(const_expr, re)?
@ -884,7 +884,7 @@ impl<'a> Parser<'a> {
fn parse_pat_range_end(&mut self) -> PResult<'a, P<Expr>> {
if self.check_inline_const(0) {
self.parse_const_block(self.token.span)
self.parse_const_block(self.token.span, true)
} else if self.check_path() {
let lo = self.token.span;
let (qself, path) = if self.eat_lt() {

View file

@ -732,6 +732,7 @@ symbols! {
inlateout,
inline,
inline_const,
inline_const_pat,
inout,
instruction_set,
intel,

View file

@ -0,0 +1,24 @@
# `inline_const_pat`
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:
```rust
#![feature(inline_const_pat)]
const fn one() -> i32 { 1 }
let some_int = 3;
match some_int {
const { 1 + 2 } => println!("Matched 1 + 2"),
const { one() } => println!("Matched const fn returning 1"),
_ => println!("Didn't match anything :("),
}
```
[#76001]: https://github.com/rust-lang/rust/issues/76001

View file

@ -2,6 +2,8 @@
The tracking issue for this feature is: [#76001]
See also [`inline_const_pat`](inline-const-pat.md)
------
This feature allows you to use inline constant expressions. For example, you can
@ -27,19 +29,4 @@ fn main() {
}
```
You can also use inline constant expressions in patterns:
```rust
#![feature(inline_const)]
const fn one() -> i32 { 1 }
let some_int = 3;
match some_int {
const { 1 + 2 } => println!("Matched 1 + 2"),
const { one() } => println!("Matched const fn returning 1"),
_ => println!("Didn't match anything :("),
}
```
[#76001]: https://github.com/rust-lang/rust/issues/76001

View file

@ -1,6 +1,5 @@
// Regression test for issue 90013.
// check-pass
#![allow(incomplete_features)]
#![feature(inline_const)]
fn main() {

View file

@ -1,7 +1,7 @@
// run-pass
#![feature(inline_const)]
#![allow(unused, incomplete_features)]
#![allow(unused)]
// Some type that is not copyable.
struct Bar;

View file

@ -0,0 +1,4 @@
fn main() {
let const { () } = ();
//~^ ERROR inline-const in pattern position is experimental [E0658]
}

View file

@ -0,0 +1,12 @@
error[E0658]: inline-const in pattern position is experimental
--> $DIR/feature-gate-inline_const_pat.rs:2:9
|
LL | let const { () } = ();
| ^^^^^
|
= note: see issue #76001 <https://github.com/rust-lang/rust/issues/76001> for more information
= help: add `#![feature(inline_const_pat)]` to the crate attributes to enable
error: aborting due to previous error
For more information about this error, try `rustc --explain E0658`.

View file

@ -2,7 +2,7 @@
#![allow(incomplete_features)]
#![feature(exclusive_range_pattern)]
#![feature(half_open_range_patterns)]
#![feature(inline_const)]
#![feature(inline_const_pat)]
fn main() {
let mut if_lettable = vec![];

View file

@ -12,7 +12,7 @@ fn main() {
y @ (0..5 | 6) => or_two.push(y),
//~^ exclusive range pattern syntax is experimental
y @ 0..const { 5 + 1 } => assert_eq!(y, 5),
//~^ inline-const is experimental
//~^ inline-const in pattern position is experimental
//~| exclusive range pattern syntax is experimental
y @ -5.. => range_from.push(y),
y @ ..-7 => assert_eq!(y, -8),

View file

@ -7,14 +7,14 @@ LL | y @ ..-7 => assert_eq!(y, -8),
= note: see issue #67264 <https://github.com/rust-lang/rust/issues/67264> for more information
= help: add `#![feature(half_open_range_patterns)]` to the crate attributes to enable
error[E0658]: inline-const is experimental
error[E0658]: inline-const in pattern position is experimental
--> $DIR/range_pat_interactions3.rs:14:20
|
LL | y @ 0..const { 5 + 1 } => assert_eq!(y, 5),
| ^^^^^
|
= note: see issue #76001 <https://github.com/rust-lang/rust/issues/76001> for more information
= help: add `#![feature(inline_const)]` to the crate attributes to enable
= help: add `#![feature(inline_const_pat)]` to the crate attributes to enable
error[E0658]: exclusive range pattern syntax is experimental
--> $DIR/range_pat_interactions3.rs:10:17

View file

@ -1,6 +1,5 @@
// build-pass
#![allow(incomplete_features)]
#![feature(inline_const)]
use std::cell::Cell;

View file

@ -1,7 +1,7 @@
// run-pass
#![allow(incomplete_features)]
#![feature(inline_const)]
fn foo() -> i32 {
const {
let x = 5 + 10;

View file

@ -1,7 +1,6 @@
// check-pass
#![feature(inline_const)]
#![allow(incomplete_features)]
pub fn todo<T>() -> T {
const { todo!() }

View file

@ -1,4 +1,3 @@
#![allow(incomplete_features)]
#![feature(const_mut_refs)]
#![feature(inline_const)]

View file

@ -1,5 +1,5 @@
error[E0597]: `y` does not live long enough
--> $DIR/const-expr-lifetime-err.rs:24:30
--> $DIR/const-expr-lifetime-err.rs:23:30
|
LL | fn foo<'a>() {
| -- lifetime `'a` defined here

View file

@ -1,6 +1,5 @@
// run-pass
#![allow(incomplete_features)]
#![feature(const_mut_refs)]
#![feature(inline_const)]

View file

@ -1,7 +1,7 @@
// run-pass
#![allow(incomplete_features)]
#![feature(inline_const)]
macro_rules! do_const_block{
($val:block) => { const $val }
}

View file

@ -1,6 +1,5 @@
// run-pass
#![allow(incomplete_features)]
#![feature(inline_const)]
const fn bar() -> i32 {

View file

@ -1,5 +1,5 @@
#![allow(incomplete_features)]
#![feature(inline_const)]
#![feature(inline_const_pat)]
// rust-lang/rust#82518: ICE with inline-const in match referencing const-generic parameter

View file

@ -1,6 +1,6 @@
// check-pass
#![feature(inline_const)]
#![feature(inline_const_pat)]
#![allow(incomplete_features)]
fn main() {

View file

@ -2,7 +2,7 @@
#![allow(incomplete_features)]
#![feature(const_mut_refs)]
#![feature(inline_const)]
#![feature(inline_const_pat)]
use std::marker::PhantomData;

View file

@ -3,6 +3,7 @@
#![allow(incomplete_features)]
#![feature(const_mut_refs)]
#![feature(inline_const)]
#![feature(inline_const_pat)]
use std::marker::PhantomData;

View file

@ -1,7 +1,7 @@
// build-pass
#![allow(incomplete_features)]
#![feature(inline_const, half_open_range_patterns, exclusive_range_pattern)]
#![feature(inline_const_pat, half_open_range_patterns, exclusive_range_pattern)]
fn main() {
const N: u32 = 10;
let x: u32 = 3;

View file

@ -1,7 +1,7 @@
// run-pass
#![allow(incomplete_features)]
#![feature(inline_const)]
#![feature(inline_const_pat)]
const MMIO_BIT1: u8 = 4;
const MMIO_BIT2: u8 = 5;

View file

@ -1,5 +1,5 @@
// check-pass
#![feature(inline_const)]
#![feature(inline_const_pat)]
#![allow(incomplete_features)]
#![deny(dead_code)]

View file

@ -2,7 +2,7 @@
#![allow(incomplete_features)]
#![allow(unreachable_code)]
#![feature(const_async_blocks)]
#![feature(inline_const)]
#![feature(inline_const_pat)]
fn main() {
match loop {} {

View file

@ -2,7 +2,6 @@
// ignore-emscripten FIXME(#45351) hits an LLVM assert
#![feature(repr_simd, platform_intrinsics)]
#![allow(incomplete_features)]
#![feature(inline_const)]
#[repr(simd)]