From a12d0d4f6672a9621771433d2f05757f1f79130d Mon Sep 17 00:00:00 2001 From: Alex Burka Date: Fri, 8 Sep 2017 18:11:30 +0000 Subject: honor #[rustc_const_unstable] attributes --- src/libsyntax/attr.rs | 79 +++++++++++++++++++++++++++++++++------- src/libsyntax/diagnostic_list.rs | 3 ++ src/libsyntax/feature_gate.rs | 6 +++ 3 files changed, 74 insertions(+), 14 deletions(-) (limited to 'src/libsyntax') 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(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, + pub rustc_const_unstable: Option, } /// The available stability levels. @@ -659,6 +660,11 @@ pub struct RustcDeprecation { pub reason: Symbol, } +#[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, @@ -678,9 +684,15 @@ 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; '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 \ -- cgit 1.4.1-3-g733a5