diff options
| author | Yuki Okushi <huyuumi.dev@gmail.com> | 2019-11-12 16:36:16 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-11-12 16:36:16 +0900 |
| commit | 4134a4acf555bad45c83b0379df5fb86402499ec (patch) | |
| tree | a6e77a1a987f9cc3edb8edcdeead9ffb4e358876 /src/libsyntax | |
| parent | 6bdd1beca6d310f0baaffa0835a16a968061ccfb (diff) | |
| parent | 3ba825725390fe103a057e59100c7c8cafc22404 (diff) | |
| download | rust-4134a4acf555bad45c83b0379df5fb86402499ec.tar.gz rust-4134a4acf555bad45c83b0379df5fb86402499ec.zip | |
Rollup merge of #66299 - rossmacarthur:fix-41260-avoid-issue-0, r=varkor
support issue = "none" in unstable attributes
This works towards fixing #41260.
This PR allows the use of `issue = "none"` in unstable attributes and makes changes to internally store the issue number as an `Option<NonZeroU32>`. For example:
```rust
#[unstable(feature = "unstable_test_feature", issue = "none")]
fn unstable_issue_none() {}
```
It was not made optional because feedback seen here #60860 suggested that people might forget the issue field if it was optional.
I could not remove the current uses of `issue = "0"` (of which there are a lot) because the stage 0 compiler expects the old syntax. Once this is available in the stage 0 compiler we can replace all uses of `"0"` with `"none"` and no longer allow `"0"`. This is my first time contributing, so I'm not sure what the protocol is with two-part things like this, so some guidance would be appreciated.
r? @varkor
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/attr/builtin.rs | 31 | ||||
| -rw-r--r-- | src/libsyntax/feature_gate/active.rs | 6 | ||||
| -rw-r--r-- | src/libsyntax/feature_gate/check.rs | 31 | ||||
| -rw-r--r-- | src/libsyntax/feature_gate/mod.rs | 11 |
4 files changed, 49 insertions, 30 deletions
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<Symbol>, issue: u32, is_soft: bool }, + Unstable { reason: Option<Symbol>, issue: Option<NonZeroU32>, 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<u32> { +fn find_lang_feature_issue(feature: Symbol) -> Option<NonZeroU32> { 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<u32>) + Library(Option<NonZeroU32>) } #[derive(Debug, Copy, Clone, PartialEq)] @@ -126,14 +130,11 @@ fn leveled_feature_err<'a, S: Into<MultiSpan>>( 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<u32>, + issue: Option<u32>, // FIXME: once #58732 is done make this an Option<NonZeroU32> edition: Option<Edition>, description: &'static str, } +impl Feature { + fn issue(&self) -> Option<NonZeroU32> { + self.issue.and_then(|i| NonZeroU32::new(i)) + } +} + pub use active::{Features, INCOMPLETE_FEATURES}; pub use builtin_attrs::{ AttributeGate, AttributeType, GatedCfg, |
