about summary refs log tree commit diff
path: root/src/libsyntax/feature_gate
diff options
context:
space:
mode:
authorStefan Lankes <slankes@eonerc.rwth-aachen.de>2019-11-13 00:24:37 +0100
committerStefan Lankes <slankes@eonerc.rwth-aachen.de>2019-11-13 00:24:37 +0100
commit88717319142e162ae2f48124d94f33d2c21bc2ce (patch)
treee50a968f836c55007e9bc8f305d4f0f80aca042c /src/libsyntax/feature_gate
parent969b74144641bf1c8ae5aba0581f4b52a4c15bac (diff)
parent4f03f4a989d1c8346c19dfb417a77c09b34408b8 (diff)
Merge remote-tracking branch 'rust-lang/master' into hermit
Diffstat (limited to 'src/libsyntax/feature_gate')
-rw-r--r--src/libsyntax/feature_gate/accepted.rs3
-rw-r--r--src/libsyntax/feature_gate/active.rs22
-rw-r--r--src/libsyntax/feature_gate/builtin_attrs.rs23
-rw-r--r--src/libsyntax/feature_gate/check.rs130
-rw-r--r--src/libsyntax/feature_gate/mod.rs11
-rw-r--r--src/libsyntax/feature_gate/removed.rs6
6 files changed, 102 insertions, 93 deletions
diff --git a/src/libsyntax/feature_gate/accepted.rs b/src/libsyntax/feature_gate/accepted.rs
index a1cf2d42108..0107611460b 100644
--- a/src/libsyntax/feature_gate/accepted.rs
+++ b/src/libsyntax/feature_gate/accepted.rs
@@ -253,6 +253,9 @@ declare_features! (
     (accepted, const_constructor, "1.40.0", Some(61456), None),
     /// Allows the use of `#[cfg(doctest)]`, set when rustdoc is collecting doctests.
     (accepted, cfg_doctest, "1.40.0", Some(62210), None),
+    /// Allows relaxing the coherence rules such that
+    /// `impl<T> ForeignTrait<LocalType> for ForeignType<T>` is permitted.
+    (accepted, re_rebalance_coherence, "1.41.0", Some(55437), None),
 
     // -------------------------------------------------------------------------
     // feature-group-end: accepted features
diff --git a/src/libsyntax/feature_gate/active.rs b/src/libsyntax/feature_gate/active.rs
index 736a363bbfc..2819ee273d9 100644
--- a/src/libsyntax/feature_gate/active.rs
+++ b/src/libsyntax/feature_gate/active.rs
@@ -134,9 +134,6 @@ declare_features! (
     /// Allows using `rustc_*` attributes (RFC 572).
     (active, rustc_attrs, "1.0.0", Some(29642), None),
 
-    /// Allows using `#[on_unimplemented(..)]` on traits.
-    (active, on_unimplemented, "1.0.0", Some(29628), None),
-
     /// Allows using the `box $expr` syntax.
     (active, box_syntax, "1.0.0", Some(49733), None),
 
@@ -210,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
@@ -268,9 +265,6 @@ declare_features! (
     /// Allows the use of SIMD types in functions declared in `extern` blocks.
     (active, simd_ffi, "1.0.0", Some(27731), None),
 
-    /// Allows using custom attributes (RFC 572).
-    (active, custom_attribute, "1.0.0", Some(29642), None),
-
     /// Allows using non lexical lifetimes (RFC 2094).
     (active, nll, "1.0.0", Some(43234), None),
 
@@ -469,10 +463,6 @@ declare_features! (
     /// Allows exhaustive integer pattern matching on `usize` and `isize`.
     (active, precise_pointer_size_matching, "1.32.0", Some(56354), None),
 
-    /// Allows relaxing the coherence rules such that
-    /// `impl<T> ForeignTrait<LocalType> for ForeignType<T>` is permitted.
-    (active, re_rebalance_coherence, "1.32.0", Some(55437), None),
-
     /// Allows using `#[ffi_returns_twice]` on foreign functions.
     (active, ffi_returns_twice, "1.34.0", Some(58314), None),
 
@@ -533,6 +523,12 @@ declare_features! (
     /// Allows using the `efiapi` ABI.
     (active, abi_efiapi, "1.40.0", Some(65815), None),
 
+    /// Allows using the `#[register_attr]` attribute.
+    (active, register_attr, "1.41.0", Some(66080), None),
+
+    /// Allows using the `#[register_attr]` attribute.
+    (active, register_tool, "1.41.0", Some(66079), None),
+
     // -------------------------------------------------------------------------
     // feature-group-end: actual feature gates
     // -------------------------------------------------------------------------
diff --git a/src/libsyntax/feature_gate/builtin_attrs.rs b/src/libsyntax/feature_gate/builtin_attrs.rs
index eb811c3e0ff..608cc2a09cb 100644
--- a/src/libsyntax/feature_gate/builtin_attrs.rs
+++ b/src/libsyntax/feature_gate/builtin_attrs.rs
@@ -166,7 +166,7 @@ macro_rules! experimental {
 }
 
 const IMPL_DETAIL: &str = "internal implementation detail";
-const INTERAL_UNSTABLE: &str = "this is an internal attribute that will never be stable";
+const INTERNAL_UNSTABLE: &str = "this is an internal attribute that will never be stable";
 
 pub type BuiltinAttribute = (Symbol, AttributeType, AttributeTemplate, AttributeGate);
 
@@ -329,6 +329,14 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
 
     gated!(ffi_returns_twice, Whitelisted, template!(Word), experimental!(ffi_returns_twice)),
     gated!(track_caller, Whitelisted, template!(Word), experimental!(track_caller)),
+    gated!(
+        register_attr, CrateLevel, template!(List: "attr1, attr2, ..."),
+        experimental!(register_attr),
+    ),
+    gated!(
+        register_tool, CrateLevel, template!(List: "tool1, tool2, ..."),
+        experimental!(register_tool),
+    ),
 
     // ==========================================================================
     // Internal attributes: Stability, deprecation, and unsafe:
@@ -418,14 +426,14 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         linkage, Whitelisted, template!(NameValueStr: "external|internal|..."),
         "the `linkage` attribute is experimental and not portable across platforms",
     ),
-    rustc_attr!(rustc_std_internal_symbol, Whitelisted, template!(Word), INTERAL_UNSTABLE),
+    rustc_attr!(rustc_std_internal_symbol, Whitelisted, template!(Word), INTERNAL_UNSTABLE),
 
     // ==========================================================================
     // Internal attributes, Macro related:
     // ==========================================================================
 
     rustc_attr!(rustc_builtin_macro, Whitelisted, template!(Word), IMPL_DETAIL),
-    rustc_attr!(rustc_proc_macro_decls, Normal, template!(Word), INTERAL_UNSTABLE),
+    rustc_attr!(rustc_proc_macro_decls, Normal, template!(Word), INTERNAL_UNSTABLE),
     rustc_attr!(
         rustc_macro_transparency, Whitelisted,
         template!(NameValueStr: "transparent|semitransparent|opaque"),
@@ -436,17 +444,16 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     // Internal attributes, Diagnostics related:
     // ==========================================================================
 
-    gated!(
+    rustc_attr!(
         rustc_on_unimplemented, Whitelisted,
         template!(
             List: r#"/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...""#,
             NameValueStr: "message"
         ),
-        on_unimplemented,
-        experimental!(rustc_on_unimplemented),
+        INTERNAL_UNSTABLE
     ),
     // Whitelists "identity-like" conversion methods to suggest on type mismatch.
-    rustc_attr!(rustc_conversion_suggestion, Whitelisted, template!(Word), INTERAL_UNSTABLE),
+    rustc_attr!(rustc_conversion_suggestion, Whitelisted, template!(Word), INTERNAL_UNSTABLE),
 
     // ==========================================================================
     // Internal attributes, Const related:
@@ -454,7 +461,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
 
     rustc_attr!(rustc_promotable, Whitelisted, template!(Word), IMPL_DETAIL),
     rustc_attr!(rustc_allow_const_fn_ptr, Whitelisted, template!(Word), IMPL_DETAIL),
-    rustc_attr!(rustc_args_required_const, Whitelisted, template!(List: "N"), INTERAL_UNSTABLE),
+    rustc_attr!(rustc_args_required_const, Whitelisted, template!(List: "N"), INTERNAL_UNSTABLE),
 
     // ==========================================================================
     // Internal attributes, Layout related:
diff --git a/src/libsyntax/feature_gate/check.rs b/src/libsyntax/feature_gate/check.rs
index 13a24ca046d..3bf1e24bf12 100644
--- a/src/libsyntax/feature_gate/check.rs
+++ b/src/libsyntax/feature_gate/check.rs
@@ -3,26 +3,22 @@ use super::accepted::ACCEPTED_FEATURES;
 use super::removed::{REMOVED_FEATURES, STABLE_REMOVED_FEATURES};
 use super::builtin_attrs::{AttributeGate, BUILTIN_ATTRIBUTE_MAP};
 
-use crate::ast::{
-    self, AssocTyConstraint, AssocTyConstraintKind, NodeId, GenericParam, GenericParamKind,
-    PatKind, RangeEnd, VariantData,
-};
-use crate::attr::{self, check_builtin_attribute};
+use crate::ast::{self, AssocTyConstraint, AssocTyConstraintKind, NodeId};
+use crate::ast::{GenericParam, GenericParamKind, PatKind, RangeEnd, VariantData};
+use crate::attr;
 use crate::source_map::Spanned;
 use crate::edition::{ALL_EDITIONS, Edition};
 use crate::visit::{self, FnKind, Visitor};
-use crate::parse::token;
 use crate::sess::ParseSess;
 use crate::symbol::{Symbol, sym};
-use crate::tokenstream::TokenTree;
 
 use errors::{Applicability, DiagnosticBuilder, Handler};
 use rustc_data_structures::fx::FxHashMap;
-use rustc_target::spec::abi::Abi;
 use syntax_pos::{Span, DUMMY_SP, MultiSpan};
 use log::debug;
 
 use std::env;
+use std::num::NonZeroU32;
 
 #[derive(Copy, Clone, Debug)]
 pub enum Stability {
@@ -60,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)]
@@ -131,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
@@ -192,62 +188,70 @@ macro_rules! gate_feature_post {
 }
 
 impl<'a> PostExpansionVisitor<'a> {
-    fn check_abi(&self, abi: Abi, span: Span) {
-        match abi {
-            Abi::RustIntrinsic => {
+    fn check_abi(&self, abi: ast::Abi) {
+        let ast::Abi { symbol, span } = abi;
+
+        match &*symbol.as_str() {
+            // Stable
+            "Rust" |
+            "C" |
+            "cdecl" |
+            "stdcall" |
+            "fastcall" |
+            "aapcs" |
+            "win64" |
+            "sysv64" |
+            "system" => {}
+            "rust-intrinsic" => {
                 gate_feature_post!(&self, intrinsics, span,
                                    "intrinsics are subject to change");
             },
-            Abi::PlatformIntrinsic => {
+            "platform-intrinsic" => {
                 gate_feature_post!(&self, platform_intrinsics, span,
                                    "platform intrinsics are experimental and possibly buggy");
             },
-            Abi::Vectorcall => {
+            "vectorcall" => {
                 gate_feature_post!(&self, abi_vectorcall, span,
                                    "vectorcall is experimental and subject to change");
             },
-            Abi::Thiscall => {
+            "thiscall" => {
                 gate_feature_post!(&self, abi_thiscall, span,
                                    "thiscall is experimental and subject to change");
             },
-            Abi::RustCall => {
+            "rust-call" => {
                 gate_feature_post!(&self, unboxed_closures, span,
                                    "rust-call ABI is subject to change");
             },
-            Abi::PtxKernel => {
+            "ptx-kernel" => {
                 gate_feature_post!(&self, abi_ptx, span,
                                    "PTX ABIs are experimental and subject to change");
             },
-            Abi::Unadjusted => {
+            "unadjusted" => {
                 gate_feature_post!(&self, abi_unadjusted, span,
                                    "unadjusted ABI is an implementation detail and perma-unstable");
             },
-            Abi::Msp430Interrupt => {
+            "msp430-interrupt" => {
                 gate_feature_post!(&self, abi_msp430_interrupt, span,
                                    "msp430-interrupt ABI is experimental and subject to change");
             },
-            Abi::X86Interrupt => {
+            "x86-interrupt" => {
                 gate_feature_post!(&self, abi_x86_interrupt, span,
                                    "x86-interrupt ABI is experimental and subject to change");
             },
-            Abi::AmdGpuKernel => {
+            "amdgpu-kernel" => {
                 gate_feature_post!(&self, abi_amdgpu_kernel, span,
                                    "amdgpu-kernel ABI is experimental and subject to change");
             },
-            Abi::EfiApi => {
+            "efiapi" => {
                 gate_feature_post!(&self, abi_efiapi, span,
                                    "efiapi ABI is experimental and subject to change");
             },
-            // Stable
-            Abi::Cdecl |
-            Abi::Stdcall |
-            Abi::Fastcall |
-            Abi::Aapcs |
-            Abi::Win64 |
-            Abi::SysV64 |
-            Abi::Rust |
-            Abi::C |
-            Abi::System => {}
+            abi => {
+                self.parse_sess.span_diagnostic.delay_span_bug(
+                    span,
+                    &format!("unrecognized ABI not caught in lowering: {}", abi),
+                )
+            }
         }
     }
 
@@ -324,18 +328,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
         if let Some((.., AttributeGate::Gated(_, name, descr, has_feature))) = attr_info {
             gate_feature_fn!(self, has_feature, attr.span, name, descr, GateStrength::Hard);
         }
-        // Check input tokens for built-in and key-value attributes.
-        match attr_info {
-            // `rustc_dummy` doesn't have any restrictions specific to built-in attributes.
-            Some((name, _, template, _)) if name != sym::rustc_dummy =>
-                check_builtin_attribute(self.parse_sess, attr, name, template),
-            _ => if let Some(TokenTree::Token(token)) = attr.tokens.trees().next() {
-                if token == token::Eq {
-                    // All key-value attributes are restricted to meta-item syntax.
-                    attr.parse_meta(self.parse_sess).map_err(|mut err| err.emit()).ok();
-                }
-            }
-        }
         // Check unstable flavors of the `#[doc]` attribute.
         if attr.check_name(sym::doc) {
             for nested_meta in attr.meta_item_list().unwrap_or_default() {
@@ -372,7 +364,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
     fn visit_item(&mut self, i: &'a ast::Item) {
         match i.kind {
             ast::ItemKind::ForeignMod(ref foreign_module) => {
-                self.check_abi(foreign_module.abi, i.span);
+                self.check_abi(foreign_module.abi);
             }
 
             ast::ItemKind::Fn(..) => {
@@ -502,7 +494,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
     fn visit_ty(&mut self, ty: &'a ast::Ty) {
         match ty.kind {
             ast::TyKind::BareFn(ref bare_fn_ty) => {
-                self.check_abi(bare_fn_ty.abi, ty.span);
+                self.check_abi(bare_fn_ty.abi);
             }
             ast::TyKind::Never => {
                 gate_feature_post!(&self, never_type, ty.span,
@@ -596,7 +588,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
             // Stability of const fn methods are covered in
             // `visit_trait_item` and `visit_impl_item` below; this is
             // because default methods don't pass through this point.
-            self.check_abi(header.abi, span);
+            self.check_abi(header.abi);
         }
 
         if fn_decl.c_variadic() {
@@ -630,7 +622,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
         match ti.kind {
             ast::TraitItemKind::Method(ref sig, ref block) => {
                 if block.is_none() {
-                    self.check_abi(sig.header.abi, ti.span);
+                    self.check_abi(sig.header.abi);
                 }
                 if sig.decl.c_variadic() {
                     gate_feature_post!(&self, c_variadic, ti.span,
@@ -823,7 +815,7 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
             }
 
             if let Some(allowed) = allow_features.as_ref() {
-                if allowed.iter().find(|&f| f == &name.as_str() as &str).is_none() {
+                if allowed.iter().find(|&f| name.as_str() == *f).is_none() {
                     span_err!(span_handler, mi.span(), E0725,
                               "the feature `{}` is not in the list of allowed features",
                               name);
@@ -862,18 +854,17 @@ pub fn check_crate(krate: &ast::Crate,
     maybe_stage_features(&parse_sess.span_diagnostic, krate, unstable);
     let mut visitor = PostExpansionVisitor { parse_sess, features };
 
+    let spans = parse_sess.gated_spans.spans.borrow();
     macro_rules! gate_all {
-        ($gate:ident, $msg:literal) => { gate_all!($gate, $gate, $msg); };
-        ($spans:ident, $gate:ident, $msg:literal) => {
-            for span in &*parse_sess.gated_spans.$spans.borrow() {
+        ($gate:ident, $msg:literal) => {
+            for span in spans.get(&sym::$gate).unwrap_or(&vec![]) {
                 gate_feature!(&visitor, $gate, *span, $msg);
             }
         }
     }
-
     gate_all!(let_chains, "`let` expressions in this position are experimental");
     gate_all!(async_closure, "async closures are unstable");
-    gate_all!(yields, generators, "yield syntax is experimental");
+    gate_all!(generators, "yield syntax is experimental");
     gate_all!(or_patterns, "or-patterns syntax is experimental");
     gate_all!(const_extern_fn, "`const extern fn` definitions are unstable");
 
@@ -884,7 +875,7 @@ pub fn check_crate(krate: &ast::Crate,
             // FIXME(eddyb) do something more useful than always
             // disabling these uses of early feature-gatings.
             if false {
-                for span in &*parse_sess.gated_spans.$gate.borrow() {
+                for span in spans.get(&sym::$gate).unwrap_or(&vec![]) {
                     gate_feature!(&visitor, $gate, *span, $msg);
                 }
             }
@@ -901,7 +892,6 @@ pub fn check_crate(krate: &ast::Crate,
     gate_all!(try_blocks, "`try` blocks are unstable");
     gate_all!(label_break_value, "labels on blocks are unstable");
     gate_all!(box_syntax, "box expression syntax is experimental; you can call `Box::new` instead");
-
     // To avoid noise about type ascription in common syntax errors,
     // only emit if it is the *only* error. (Also check it last.)
     if parse_sess.span_diagnostic.err_count() == 0 {
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,
diff --git a/src/libsyntax/feature_gate/removed.rs b/src/libsyntax/feature_gate/removed.rs
index 2c29e1ebf14..f0aa74c65df 100644
--- a/src/libsyntax/feature_gate/removed.rs
+++ b/src/libsyntax/feature_gate/removed.rs
@@ -67,6 +67,9 @@ declare_features! (
      Some("merged into `#![feature(slice_patterns)]`")),
     (removed, macro_reexport, "1.0.0", Some(29638), None,
      Some("subsumed by `pub use`")),
+    /// Allows using custom attributes (RFC 572).
+    (removed, custom_attribute, "1.0.0", Some(29642), None,
+     Some("removed in favor of `#![register_tool]` and `#![register_attr]`")),
     (removed, pushpop_unsafe, "1.2.0", None, None, None),
     (removed, needs_allocator, "1.4.0", Some(27389), None,
      Some("subsumed by `#![feature(allocator_internals)]`")),
@@ -99,6 +102,9 @@ declare_features! (
     /// + `__register_diagnostic`
     /// +`__build_diagnostic_array`
     (removed, rustc_diagnostic_macros, "1.38.0", None, None, None),
+    /// Allows using `#[on_unimplemented(..)]` on traits.
+    /// (Moved to `rustc_attrs`.)
+    (removed, on_unimplemented, "1.40.0", None, None, None),
 
     // -------------------------------------------------------------------------
     // feature-group-end: removed features