Skip to content

Commit

Permalink
Add feature gates for for and ? in consts
Browse files Browse the repository at this point in the history
  • Loading branch information
jonas-schievink committed Jul 29, 2021
1 parent a985d8e commit dbd1269
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 4 deletions.
6 changes: 6 additions & 0 deletions compiler/rustc_feature/src/active.rs
Expand Up @@ -677,6 +677,12 @@ declare_features! (
/// Allows `#[derive(Default)]` and `#[default]` on enums.
(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
// -------------------------------------------------------------------------
Expand Down
9 changes: 5 additions & 4 deletions compiler/rustc_passes/src/check_const.rs
Expand Up @@ -40,13 +40,14 @@ impl NonConstExpr {
use hir::MatchSource::*;

let gates: &[_] = match self {
// A `for` loop's desugaring contains a call to `IntoIterator::into_iter`,
// so they are not yet allowed.
// Likewise, `?` desugars to a call to `Try::into_result`.
Self::Loop(ForLoop) | Self::Match(ForLoopDesugar | TryDesugar | AwaitDesugar) => {
Self::Match(AwaitDesugar) => {
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"),

// All other expressions are allowed.
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_span/src/symbol.rs
Expand Up @@ -410,6 +410,7 @@ symbols! {
const_fn_transmute,
const_fn_union,
const_fn_unsize,
const_for,
const_format_args,
const_generic_defaults,
const_generics,
Expand All @@ -432,6 +433,7 @@ symbols! {
const_trait_bound_opt_out,
const_trait_impl,
const_transmute,
const_try,
constant,
constructor,
contents,
Expand Down
8 changes: 8 additions & 0 deletions src/test/ui/consts/const-for-feature-gate.rs
@@ -0,0 +1,8 @@
// gate-test-const_for

const _: () = {
for _ in 0..5 {}
//~^ error: `for` is not allowed in a `const`
};

fn main() {}
11 changes: 11 additions & 0 deletions src/test/ui/consts/const-for-feature-gate.stderr
@@ -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 changes: 9 additions & 0 deletions src/test/ui/consts/const-try-feature-gate.rs
@@ -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 changes: 11 additions & 0 deletions src/test/ui/consts/const-try-feature-gate.stderr
@@ -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 changes: 39 additions & 0 deletions src/test/ui/consts/const-try.rs
@@ -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();
};

0 comments on commit dbd1269

Please sign in to comment.