From 472ca7159812f8c360697f63454ee7bda1e02570 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Wed, 22 Aug 2018 15:56:37 +0200 Subject: Implement the `min_const_fn` feature gate --- src/libsyntax/attr/builtin.rs | 26 ++++++++++++-------------- src/libsyntax/attr/mod.rs | 2 +- src/libsyntax/feature_gate.rs | 29 +++++++++++++++++++++-------- 3 files changed, 34 insertions(+), 23 deletions(-) (limited to 'src/libsyntax') diff --git a/src/libsyntax/attr/builtin.rs b/src/libsyntax/attr/builtin.rs index ecd52a62eab..3eecdf14a4e 100644 --- a/src/libsyntax/attr/builtin.rs +++ b/src/libsyntax/attr/builtin.rs @@ -107,7 +107,11 @@ pub struct Stability { pub level: StabilityLevel, pub feature: Symbol, pub rustc_depr: Option, - pub rustc_const_unstable: Option, + /// `None` means the function is stable but needs to be allowed by the + /// `min_const_fn` feature + /// `Some` contains the feature gate required to be able to use the function + /// as const fn + pub const_stability: Option, } /// The available stability levels. @@ -141,11 +145,6 @@ pub struct RustcDeprecation { pub reason: Symbol, } -#[derive(RustcEncodable, RustcDecodable, PartialEq, PartialOrd, Clone, Debug, Eq, Hash)] -pub struct RustcConstUnstable { - pub feature: Symbol, -} - /// Check if `attrs` contains an attribute like `#![feature(feature_name)]`. /// This will not perform any "sanity checks" on the form of the attributes. pub fn contains_feature_attr(attrs: &[Attribute], feature_name: &str) -> bool { @@ -176,7 +175,7 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler, let mut stab: Option = None; let mut rustc_depr: Option = None; - let mut rustc_const_unstable: Option = None; + let mut rustc_const_unstable: Option = None; 'outer: for attr in attrs_iter { if ![ @@ -191,6 +190,7 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler, mark_used(attr); let meta = attr.meta(); + // attributes with data if let Some(MetaItem { node: MetaItemKind::List(ref metas), .. }) = meta { let meta = meta.as_ref().unwrap(); let get = |meta: &MetaItem, item: &mut Option| { @@ -272,9 +272,7 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler, get_meta!(feature); if let Some(feature) = feature { - rustc_const_unstable = Some(RustcConstUnstable { - feature - }); + rustc_const_unstable = Some(feature); } else { span_err!(diagnostic, attr.span(), E0629, "missing 'feature'"); continue @@ -330,7 +328,7 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler, }, feature, rustc_depr: None, - rustc_const_unstable: None, + const_stability: None, }) } (None, _, _) => { @@ -379,7 +377,7 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler, }, feature, rustc_depr: None, - rustc_const_unstable: None, + const_stability: None, }) } (None, _) => { @@ -412,9 +410,9 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler, } // Merge the const-unstable info into the stability info - if let Some(rustc_const_unstable) = rustc_const_unstable { + if let Some(feature) = rustc_const_unstable { if let Some(ref mut stab) = stab { - stab.rustc_const_unstable = Some(rustc_const_unstable); + stab.const_stability = Some(feature); } else { span_err!(diagnostic, item_sp, E0630, "rustc_const_unstable attribute must be paired with \ diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs index cd9d7682210..19bbbceff5f 100644 --- a/src/libsyntax/attr/mod.rs +++ b/src/libsyntax/attr/mod.rs @@ -15,7 +15,7 @@ mod builtin; pub use self::builtin::{ cfg_matches, contains_feature_attr, eval_condition, find_crate_name, find_deprecation, find_repr_attrs, find_stability, find_unwind_attr, Deprecation, InlineAttr, IntType, ReprAttr, - RustcConstUnstable, RustcDeprecation, Stability, StabilityLevel, UnwindAttr, + RustcDeprecation, Stability, StabilityLevel, UnwindAttr, }; pub use self::IntType::*; pub use self::ReprAttr::*; diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 080860f17f5..f226c9dd979 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -40,6 +40,16 @@ use symbol::{keywords, Symbol}; use std::{env, path}; macro_rules! set { + // The const_fn feature also enables the min_const_fn feature, because `min_const_fn` allows + // the declaration `const fn`, but the `const_fn` feature gate enables things inside those + // functions that we do not want to expose to the user for now. + (const_fn) => {{ + fn f(features: &mut Features, _: Span) { + features.const_fn = true; + features.min_const_fn = true; + } + f as fn(&mut Features, Span) + }}; ($field: ident) => {{ fn f(features: &mut Features, _: Span) { features.$field = true; @@ -206,25 +216,28 @@ declare_features! ( // #23121. Array patterns have some hazards yet. (active, slice_patterns, "1.0.0", Some(23121), None), - // Allows the definition of `const fn` functions. + // Allows the definition of `const fn` functions with some advanced features. (active, const_fn, "1.2.0", Some(24111), None), + // Allows the definition of `const fn` functions. + (active, min_const_fn, "1.30.0", Some(53555), None), + // Allows let bindings and destructuring in `const fn` functions and constants. (active, const_let, "1.22.1", Some(48821), None), - // Allows accessing fields of unions inside const fn + // Allows accessing fields of unions inside const fn. (active, const_fn_union, "1.27.0", Some(51909), None), - // Allows casting raw pointers to `usize` during const eval + // Allows casting raw pointers to `usize` during const eval. (active, const_raw_ptr_to_usize_cast, "1.27.0", Some(51910), None), - // Allows dereferencing raw pointers during const eval + // Allows dereferencing raw pointers during const eval. (active, const_raw_ptr_deref, "1.27.0", Some(51911), None), - // Allows reinterpretation of the bits of a value of one type as another type during const eval + // Allows reinterpretation of the bits of a value of one type as another type during const eval. (active, const_transmute, "1.29.0", Some(53605), None), - // Allows comparing raw pointers during const eval + // Allows comparing raw pointers during const eval. (active, const_compare_raw_pointers, "1.27.0", Some(53020), None), // Allows panicking during const eval (produces compile-time errors) @@ -1786,7 +1799,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { gate_feature_post!(&self, async_await, span, "async fn is unstable"); } if header.constness.node == ast::Constness::Const { - gate_feature_post!(&self, const_fn, span, "const fn is unstable"); + gate_feature_post!(&self, min_const_fn, span, "const fn is unstable"); } // stability of const fn methods are covered in // visit_trait_item and visit_impl_item below; this is @@ -1844,7 +1857,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { match ii.node { ast::ImplItemKind::Method(ref sig, _) => { if sig.header.constness.node == ast::Constness::Const { - gate_feature_post!(&self, const_fn, ii.span, "const fn is unstable"); + gate_feature_post!(&self, min_const_fn, ii.span, "const fn is unstable"); } } ast::ImplItemKind::Existential(..) => { -- cgit 1.4.1-3-g733a5