From 3ba825725390fe103a057e59100c7c8cafc22404 Mon Sep 17 00:00:00 2001 From: Ross MacArthur Date: Mon, 11 Nov 2019 19:33:30 +0200 Subject: support issue = "none" in unstable attributes - Use `Option` to represent issue numbers. --- src/libsyntax/attr/builtin.rs | 31 +++++++++++++++++++++---------- src/libsyntax/feature_gate/active.rs | 6 +++--- src/libsyntax/feature_gate/check.rs | 31 ++++++++++++++++--------------- src/libsyntax/feature_gate/mod.rs | 11 +++++++++-- 4 files changed, 49 insertions(+), 30 deletions(-) (limited to 'src/libsyntax') diff --git a/src/libsyntax/attr/builtin.rs b/src/libsyntax/attr/builtin.rs index d0a31b330ab..2b759c205f5 100644 --- a/src/libsyntax/attr/builtin.rs +++ b/src/libsyntax/attr/builtin.rs @@ -6,6 +6,7 @@ use crate::print::pprust; use crate::sess::ParseSess; use errors::{Applicability, Handler}; +use std::num::NonZeroU32; use syntax_pos::hygiene::Transparency; use syntax_pos::{symbol::Symbol, symbol::sym, Span}; @@ -157,7 +158,7 @@ pub struct Stability { #[derive(RustcEncodable, RustcDecodable, PartialEq, PartialOrd, Copy, Clone, Debug, Eq, Hash)] pub enum StabilityLevel { // Reason for the current stability level and the relevant rust-lang issue - Unstable { reason: Option, issue: u32, is_soft: bool }, + Unstable { reason: Option, issue: Option, is_soft: bool }, Stable { since: Symbol }, } @@ -394,18 +395,28 @@ fn find_stability_generic<'a, I>(sess: &ParseSess, match (feature, reason, issue) { (Some(feature), reason, Some(issue)) => { + let issue = match &*issue.as_str() { + // FIXME(rossmacarthur): remove "0" because "none" should be used + // See #41260 + "none" | "0" => None, + issue => { + if let Ok(num) = issue.parse() { + NonZeroU32::new(num) + } else { + span_err!( + diagnostic, + attr.span, + E0545, + "incorrect 'issue'" + ); + continue + } + } + }; stab = Some(Stability { level: Unstable { reason, - issue: { - if let Ok(issue) = issue.as_str().parse() { - issue - } else { - span_err!(diagnostic, attr.span, E0545, - "incorrect 'issue'"); - continue - } - }, + issue, is_soft, }, feature, diff --git a/src/libsyntax/feature_gate/active.rs b/src/libsyntax/feature_gate/active.rs index d59d0f0e28e..2819ee273d9 100644 --- a/src/libsyntax/feature_gate/active.rs +++ b/src/libsyntax/feature_gate/active.rs @@ -207,10 +207,10 @@ declare_features! ( /// Allows using `#![needs_allocator]`, an implementation detail of `#[global_allocator]`. (active, allocator_internals, "1.20.0", None, None), - // no-tracking-issue-end - /// Added for testing E0705; perma-unstable. - (active, test_2018_feature, "1.31.0", Some(0), Some(Edition::Edition2018)), + (active, test_2018_feature, "1.31.0", None, Some(Edition::Edition2018)), + + // no-tracking-issue-end // ------------------------------------------------------------------------- // feature-group-end: internal feature gates diff --git a/src/libsyntax/feature_gate/check.rs b/src/libsyntax/feature_gate/check.rs index 4742e01d7f4..3bf1e24bf12 100644 --- a/src/libsyntax/feature_gate/check.rs +++ b/src/libsyntax/feature_gate/check.rs @@ -18,6 +18,7 @@ use syntax_pos::{Span, DUMMY_SP, MultiSpan}; use log::debug; use std::env; +use std::num::NonZeroU32; #[derive(Copy, Clone, Debug)] pub enum Stability { @@ -55,25 +56,28 @@ pub fn check_attribute(attr: &ast::Attribute, parse_sess: &ParseSess, features: PostExpansionVisitor { parse_sess, features }.visit_attribute(attr) } -fn find_lang_feature_issue(feature: Symbol) -> Option { +fn find_lang_feature_issue(feature: Symbol) -> Option { if let Some(info) = ACTIVE_FEATURES.iter().find(|t| t.name == feature) { // FIXME (#28244): enforce that active features have issue numbers - // assert!(info.issue.is_some()) - info.issue + // assert!(info.issue().is_some()) + info.issue() } else { // search in Accepted, Removed, or Stable Removed features - let found = ACCEPTED_FEATURES.iter().chain(REMOVED_FEATURES).chain(STABLE_REMOVED_FEATURES) + let found = ACCEPTED_FEATURES + .iter() + .chain(REMOVED_FEATURES) + .chain(STABLE_REMOVED_FEATURES) .find(|t| t.name == feature); match found { - Some(&Feature { issue, .. }) => issue, - None => panic!("Feature `{}` is not declared anywhere", feature), + Some(found) => found.issue(), + None => panic!("feature `{}` is not declared anywhere", feature), } } } pub enum GateIssue { Language, - Library(Option) + Library(Option) } #[derive(Debug, Copy, Clone, PartialEq)] @@ -126,14 +130,11 @@ fn leveled_feature_err<'a, S: Into>( GateStrength::Soft => diag.struct_span_warn(span, explain), }; - match issue { - None | Some(0) => {} // We still accept `0` as a stand-in for backwards compatibility - Some(n) => { - err.note(&format!( - "for more information, see https://github.com/rust-lang/rust/issues/{}", - n, - )); - } + if let Some(n) = issue { + err.note(&format!( + "for more information, see https://github.com/rust-lang/rust/issues/{}", + n, + )); } // #23973: do not suggest `#![feature(...)]` if we are in beta/stable diff --git a/src/libsyntax/feature_gate/mod.rs b/src/libsyntax/feature_gate/mod.rs index ba970618c0e..c4418c0f0f6 100644 --- a/src/libsyntax/feature_gate/mod.rs +++ b/src/libsyntax/feature_gate/mod.rs @@ -18,8 +18,9 @@ mod active; mod builtin_attrs; mod check; -use std::fmt; use crate::{edition::Edition, symbol::Symbol}; +use std::fmt; +use std::num::NonZeroU32; use syntax_pos::Span; #[derive(Clone, Copy)] @@ -46,11 +47,17 @@ pub struct Feature { state: State, name: Symbol, since: &'static str, - issue: Option, + issue: Option, // FIXME: once #58732 is done make this an Option edition: Option, description: &'static str, } +impl Feature { + fn issue(&self) -> Option { + self.issue.and_then(|i| NonZeroU32::new(i)) + } +} + pub use active::{Features, INCOMPLETE_FEATURES}; pub use builtin_attrs::{ AttributeGate, AttributeType, GatedCfg, -- cgit 1.4.1-3-g733a5