Add feature gates for for
and ?
in consts
This commit is contained in:
parent
a985d8e6c7
commit
dbd126901a
@ -677,6 +677,12 @@ declare_features! (
|
|||||||
/// Allows `#[derive(Default)]` and `#[default]` on enums.
|
/// Allows `#[derive(Default)]` and `#[default]` on enums.
|
||||||
(active, derive_default_enum, "1.56.0", Some(86985), None),
|
(active, derive_default_enum, "1.56.0", Some(86985), None),
|
||||||
|
|
||||||
|
/// Allows `for _ in _` loops in const contexts.
|
||||||
|
(active, const_for, "1.55.0", None, None),
|
||||||
|
|
||||||
|
/// Allows the `?` operator in const contexts.
|
||||||
|
(active, const_try, "1.55.0", None, None),
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
// feature-group-end: actual feature gates
|
// feature-group-end: actual feature gates
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
|
@ -40,13 +40,14 @@ impl NonConstExpr {
|
|||||||
use hir::MatchSource::*;
|
use hir::MatchSource::*;
|
||||||
|
|
||||||
let gates: &[_] = match self {
|
let gates: &[_] = match self {
|
||||||
// A `for` loop's desugaring contains a call to `IntoIterator::into_iter`,
|
Self::Match(AwaitDesugar) => {
|
||||||
// so they are not yet allowed.
|
|
||||||
// Likewise, `?` desugars to a call to `Try::into_result`.
|
|
||||||
Self::Loop(ForLoop) | Self::Match(ForLoopDesugar | TryDesugar | AwaitDesugar) => {
|
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Self::Loop(ForLoop) | Self::Match(ForLoopDesugar) => &[sym::const_for],
|
||||||
|
|
||||||
|
Self::Match(TryDesugar) => &[sym::const_try],
|
||||||
|
|
||||||
Self::Match(IfLetGuardDesugar) => bug!("`if let` guard outside a `match` expression"),
|
Self::Match(IfLetGuardDesugar) => bug!("`if let` guard outside a `match` expression"),
|
||||||
|
|
||||||
// All other expressions are allowed.
|
// All other expressions are allowed.
|
||||||
|
@ -410,6 +410,7 @@ symbols! {
|
|||||||
const_fn_transmute,
|
const_fn_transmute,
|
||||||
const_fn_union,
|
const_fn_union,
|
||||||
const_fn_unsize,
|
const_fn_unsize,
|
||||||
|
const_for,
|
||||||
const_format_args,
|
const_format_args,
|
||||||
const_generic_defaults,
|
const_generic_defaults,
|
||||||
const_generics,
|
const_generics,
|
||||||
@ -432,6 +433,7 @@ symbols! {
|
|||||||
const_trait_bound_opt_out,
|
const_trait_bound_opt_out,
|
||||||
const_trait_impl,
|
const_trait_impl,
|
||||||
const_transmute,
|
const_transmute,
|
||||||
|
const_try,
|
||||||
constant,
|
constant,
|
||||||
constructor,
|
constructor,
|
||||||
contents,
|
contents,
|
||||||
|
8
src/test/ui/consts/const-for-feature-gate.rs
Normal file
8
src/test/ui/consts/const-for-feature-gate.rs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// gate-test-const_for
|
||||||
|
|
||||||
|
const _: () = {
|
||||||
|
for _ in 0..5 {}
|
||||||
|
//~^ error: `for` is not allowed in a `const`
|
||||||
|
};
|
||||||
|
|
||||||
|
fn main() {}
|
11
src/test/ui/consts/const-for-feature-gate.stderr
Normal file
11
src/test/ui/consts/const-for-feature-gate.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error[E0658]: `for` is not allowed in a `const`
|
||||||
|
--> $DIR/const-for-feature-gate.rs:4:5
|
||||||
|
|
|
||||||
|
LL | for _ in 0..5 {}
|
||||||
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: add `#![feature(const_for)]` to the crate attributes to enable
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0658`.
|
9
src/test/ui/consts/const-try-feature-gate.rs
Normal file
9
src/test/ui/consts/const-try-feature-gate.rs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
// gate-test-const_try
|
||||||
|
|
||||||
|
const fn t() -> Option<()> {
|
||||||
|
Some(())?;
|
||||||
|
//~^ error: `?` is not allowed in a `const fn`
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
11
src/test/ui/consts/const-try-feature-gate.stderr
Normal file
11
src/test/ui/consts/const-try-feature-gate.stderr
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
error[E0658]: `?` is not allowed in a `const fn`
|
||||||
|
--> $DIR/const-try-feature-gate.rs:4:5
|
||||||
|
|
|
||||||
|
LL | Some(())?;
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: add `#![feature(const_try)]` to the crate attributes to enable
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0658`.
|
39
src/test/ui/consts/const-try.rs
Normal file
39
src/test/ui/consts/const-try.rs
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
// check-pass
|
||||||
|
|
||||||
|
// Demonstrates what's needed to make use of `?` in const contexts.
|
||||||
|
|
||||||
|
#![crate_type = "lib"]
|
||||||
|
#![feature(try_trait_v2)]
|
||||||
|
#![feature(const_trait_impl)]
|
||||||
|
#![feature(const_try)]
|
||||||
|
|
||||||
|
use std::ops::{ControlFlow, FromResidual, Try};
|
||||||
|
|
||||||
|
struct TryMe;
|
||||||
|
struct Error;
|
||||||
|
|
||||||
|
impl const FromResidual<Error> for TryMe {
|
||||||
|
fn from_residual(residual: Error) -> Self {
|
||||||
|
TryMe
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl const Try for TryMe {
|
||||||
|
type Output = ();
|
||||||
|
type Residual = Error;
|
||||||
|
fn from_output(output: Self::Output) -> Self {
|
||||||
|
TryMe
|
||||||
|
}
|
||||||
|
fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {
|
||||||
|
ControlFlow::Break(Error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const fn t() -> TryMe {
|
||||||
|
TryMe?;
|
||||||
|
TryMe
|
||||||
|
}
|
||||||
|
|
||||||
|
const _: () = {
|
||||||
|
t();
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user