3 //! This module implements the gating necessary for preventing certain compiler
4 //! features from being used by default. This module will crawl a pre-expanded
5 //! AST to ensure that there are no features which are used that are not
8 //! Features are enabled in programs via the crate-level attributes of
9 //! `#![feature(...)]` with a comma-separated list of features.
11 //! For the purpose of future feature-tracking, once code for detection of feature
12 //! gate usage is added, *do not remove it again* even once the feature
21 use std::num::NonZeroU32;
22 use syntax_pos::{Span, edition::Edition, symbol::Symbol};
24 #[derive(Clone, Copy)]
27 Active { set: fn(&mut Features, Span) },
28 Removed { reason: Option<&'static str> },
29 Stabilized { reason: Option<&'static str> },
32 impl fmt::Debug for State {
33 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
35 State::Accepted { .. } => write!(f, "accepted"),
36 State::Active { .. } => write!(f, "active"),
37 State::Removed { .. } => write!(f, "removed"),
38 State::Stabilized { .. } => write!(f, "stabilized"),
43 #[derive(Debug, Clone)]
47 pub since: &'static str,
48 issue: Option<u32>, // FIXME: once #58732 is done make this an Option<NonZeroU32>
49 pub edition: Option<Edition>,
50 description: &'static str,
54 // FIXME(Centril): privatize again.
55 pub fn issue(&self) -> Option<NonZeroU32> {
56 self.issue.and_then(|i| NonZeroU32::new(i))
60 #[derive(Copy, Clone, Debug)]
63 // First argument is tracking issue link; second argument is an optional
64 // help message, which defaults to "remove this attribute".
65 Deprecated(&'static str, Option<&'static str>),
68 #[derive(Clone, Copy, Hash)]
69 pub enum UnstableFeatures {
70 /// Hard errors for unstable features are active, as on beta/stable channels.
72 /// Allow features to be activated, as on nightly.
74 /// Errors are bypassed for bootstrapping. This is required any time
75 /// during the build that feature-related lints are set to warn or above
76 /// because the build turns on warnings-as-errors and uses lots of unstable
77 /// features. As a result, this is always required for building Rust itself.
81 impl UnstableFeatures {
82 pub fn from_environment() -> UnstableFeatures {
83 // `true` if this is a feature-staged build, i.e., on the beta or stable channel.
84 let disable_unstable_features = option_env!("CFG_DISABLE_UNSTABLE_FEATURES").is_some();
85 // `true` if we should enable unstable features for bootstrapping.
86 let bootstrap = std::env::var("RUSTC_BOOTSTRAP").is_ok();
87 match (disable_unstable_features, bootstrap) {
88 (_, true) => UnstableFeatures::Cheat,
89 (true, _) => UnstableFeatures::Disallow,
90 (false, _) => UnstableFeatures::Allow
94 pub fn is_nightly_build(&self) -> bool {
96 UnstableFeatures::Allow | UnstableFeatures::Cheat => true,
97 UnstableFeatures::Disallow => false,
102 pub use accepted::ACCEPTED_FEATURES;
103 pub use active::{ACTIVE_FEATURES, Features, INCOMPLETE_FEATURES};
104 pub use removed::{REMOVED_FEATURES, STABLE_REMOVED_FEATURES};
105 pub use builtin_attrs::{
106 AttributeGate, AttributeTemplate, AttributeType, find_gated_cfg, GatedCfg,
107 BuiltinAttribute, BUILTIN_ATTRIBUTES, BUILTIN_ATTRIBUTE_MAP,
108 deprecated_attributes, is_builtin_attr_name,