diff options
| author | bors <bors@rust-lang.org> | 2017-09-16 17:02:17 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2017-09-16 17:02:17 +0000 |
| commit | ae8efdc87d5f4e22e05e1b60a72272cee87fa74c (patch) | |
| tree | fc7932f915f347bd68db4143b2e097e620faa538 /src/libsyntax | |
| parent | b965d55a3214b78ec9ffdd3017cb6aaa62c28059 (diff) | |
| parent | 332c38cd70e372f56356e02b18b88919fcb58a66 (diff) | |
| download | rust-ae8efdc87d5f4e22e05e1b60a72272cee87fa74c.tar.gz rust-ae8efdc87d5f4e22e05e1b60a72272cee87fa74c.zip | |
Auto merge of #43017 - durka:stabilize-const-invocation, r=eddyb
Individualize feature gates for const fn invocation
This PR changes the meaning of `#![feature(const_fn)]` so it is only required to declare a const fn but not to call one. Based on discussion at #24111. I was hoping we could have an FCP here in order to move that conversation forward.
This sets the stage for future stabilization of the constness of several functions in the standard library (listed below), so could someone please tag the lang team for review.
- `std::cell`
- `Cell::new`
- `RefCell::new`
- `UnsafeCell::new`
- `std::mem`
- `size_of`
- `align_of`
- `std::ptr`
- `null`
- `null_mut`
- `std::sync`
- `atomic`
- `Atomic{Bool,Ptr,Isize,Usize}::new`
- `once`
- `Once::new`
- primitives
- `{integer}::min_value`
- `{integer}::max_value`
Some other functions are const but they are also unstable or hidden, e.g. `Unique::new` so they don't have to be considered at this time.
After this stabilization, the following `*_INIT` constants in the standard library can be deprecated. I wasn't sure whether to include those deprecations in the current PR.
- `std::sync`
- `atomic`
- `ATOMIC_{BOOL,ISIZE,USIZE}_INIT`
- `once`
- `ONCE_INIT`
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/attr.rs | 79 | ||||
| -rw-r--r-- | src/libsyntax/diagnostic_list.rs | 3 | ||||
| -rw-r--r-- | src/libsyntax/feature_gate.rs | 6 |
3 files changed, 74 insertions, 14 deletions
diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index adbbc1b0ac5..03907eed900 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -637,12 +637,13 @@ pub fn eval_condition<F>(cfg: &ast::MetaItem, sess: &ParseSess, eval: &mut F) } } -/// Represents the #[stable], #[unstable] and #[rustc_deprecated] attributes. +/// Represents the #[stable], #[unstable], #[rustc_{deprecated,const_unstable}] attributes. #[derive(RustcEncodable, RustcDecodable, Clone, Debug, PartialEq, Eq, Hash)] pub struct Stability { pub level: StabilityLevel, pub feature: Symbol, pub rustc_depr: Option<RustcDeprecation>, + pub rustc_const_unstable: Option<RustcConstUnstable>, } /// The available stability levels. @@ -660,6 +661,11 @@ pub struct RustcDeprecation { } #[derive(RustcEncodable, RustcDecodable, PartialEq, PartialOrd, Clone, Debug, Eq, Hash)] +pub struct RustcConstUnstable { + pub feature: Symbol, +} + +#[derive(RustcEncodable, RustcDecodable, PartialEq, PartialOrd, Clone, Debug, Eq, Hash)] pub struct Deprecation { pub since: Option<Symbol>, pub note: Option<Symbol>, @@ -678,9 +684,15 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler, { let mut stab: Option<Stability> = None; let mut rustc_depr: Option<RustcDeprecation> = None; + let mut rustc_const_unstable: Option<RustcConstUnstable> = None; 'outer: for attr in attrs_iter { - if attr.path != "rustc_deprecated" && attr.path != "unstable" && attr.path != "stable" { + if ![ + "rustc_deprecated", + "rustc_const_unstable", + "unstable", + "stable", + ].iter().any(|&s| attr.path == s) { continue // not a stability level } @@ -703,21 +715,18 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler, } }; - match &*meta.name.as_str() { - "rustc_deprecated" => { - if rustc_depr.is_some() { - span_err!(diagnostic, item_sp, E0540, - "multiple rustc_deprecated attributes"); - break - } - - let mut since = None; - let mut reason = None; + macro_rules! get_meta { + ($($name:ident),+) => { + $( + let mut $name = None; + )+ for meta in metas { if let Some(mi) = meta.meta_item() { match &*mi.name().as_str() { - "since" => if !get(mi, &mut since) { continue 'outer }, - "reason" => if !get(mi, &mut reason) { continue 'outer }, + $( + stringify!($name) + => if !get(mi, &mut $name) { continue 'outer }, + )+ _ => { handle_errors(diagnostic, mi.span, AttrError::UnknownMetaItem(mi.name())); @@ -729,6 +738,18 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler, continue 'outer } } + } + } + + match &*meta.name.as_str() { + "rustc_deprecated" => { + if rustc_depr.is_some() { + span_err!(diagnostic, item_sp, E0540, + "multiple rustc_deprecated attributes"); + continue 'outer + } + + get_meta!(since, reason); match (since, reason) { (Some(since), Some(reason)) => { @@ -747,6 +768,23 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler, } } } + "rustc_const_unstable" => { + if rustc_const_unstable.is_some() { + span_err!(diagnostic, item_sp, E0553, + "multiple rustc_const_unstable attributes"); + continue 'outer + } + + get_meta!(feature); + if let Some(feature) = feature { + rustc_const_unstable = Some(RustcConstUnstable { + feature + }); + } else { + span_err!(diagnostic, attr.span(), E0629, "missing 'feature'"); + continue + } + } "unstable" => { if stab.is_some() { handle_errors(diagnostic, attr.span(), AttrError::MultipleStabilityLevels); @@ -791,6 +829,7 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler, }, feature, rustc_depr: None, + rustc_const_unstable: None, }) } (None, _, _) => { @@ -836,6 +875,7 @@ fn find_stability_generic<'a, I>(diagnostic: &Handler, }, feature, rustc_depr: None, + rustc_const_unstable: None, }) } (None, _) => { @@ -867,6 +907,17 @@ 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(ref mut stab) = stab { + stab.rustc_const_unstable = Some(rustc_const_unstable); + } else { + span_err!(diagnostic, item_sp, E0630, + "rustc_const_unstable attribute must be paired with \ + either stable or unstable attribute"); + } + } + stab } diff --git a/src/libsyntax/diagnostic_list.rs b/src/libsyntax/diagnostic_list.rs index 2ea3fe51d30..46dec73c962 100644 --- a/src/libsyntax/diagnostic_list.rs +++ b/src/libsyntax/diagnostic_list.rs @@ -357,8 +357,11 @@ register_diagnostics! { E0549, // rustc_deprecated attribute must be paired with either stable or unstable attribute E0550, // multiple deprecated attributes E0551, // incorrect meta item + E0553, // multiple rustc_const_unstable attributes E0555, // malformed feature attribute, expected #![feature(...)] E0556, // malformed feature, expected just one word E0584, // file for module `..` found at both .. and .. E0589, // invalid `repr(align)` attribute + E0629, // missing 'feature' (rustc_const_unstable) + E0630, // rustc_const_unstable attribute must be paired with stable/unstable attribute } diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 3d4ded2ae81..38e20b9fe40 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -137,6 +137,7 @@ declare_features! ( // rustc internal (active, rustc_diagnostic_macros, "1.0.0", None), + (active, rustc_const_unstable, "1.0.0", None), (active, advanced_slice_patterns, "1.0.0", Some(23121)), (active, box_syntax, "1.0.0", Some(27779)), (active, placement_in_syntax, "1.0.0", Some(27779)), @@ -622,6 +623,11 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG "the `#[rustc_on_unimplemented]` attribute \ is an experimental feature", cfg_fn!(on_unimplemented))), + ("rustc_const_unstable", Normal, Gated(Stability::Unstable, + "rustc_const_unstable", + "the `#[rustc_const_unstable]` attribute \ + is an internal feature", + cfg_fn!(rustc_const_unstable))), ("global_allocator", Normal, Gated(Stability::Unstable, "global_allocator", "the `#[global_allocator]` attribute is \ |
