3 //! This crate declares the set of past and present unstable features in the compiler.
4 //! Feature gate checking itself is done in `rustc_ast_passes/src/feature_gate.rs`
7 //! Features are enabled in programs via the crate-level attributes of
8 //! `#![feature(...)]` with a comma-separated list of features.
10 //! For the purpose of future feature-tracking, once a feature gate is added,
11 //! even if it is stabilized or removed, *do not remove it*. Instead, move the
12 //! symbol to the `accepted` or `removed` modules respectively.
14 #![feature(once_cell)]
24 use rustc_span
::{edition::Edition, symbol::Symbol, Span}
;
26 use std
::num
::NonZeroU32
;
28 #[derive(Clone, Copy)]
31 Active { set: fn(&mut Features, Span) }
,
32 Removed { reason: Option<&'static str> }
,
33 Stabilized { reason: Option<&'static str> }
,
36 impl fmt
::Debug
for State
{
37 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
39 State
::Accepted { .. }
=> write
!(f
, "accepted"),
40 State
::Active { .. }
=> write
!(f
, "active"),
41 State
::Removed { .. }
=> write
!(f
, "removed"),
42 State
::Stabilized { .. }
=> write
!(f
, "stabilized"),
47 #[derive(Debug, Clone)]
51 pub since
: &'
static str,
52 issue
: Option
<NonZeroU32
>,
53 pub edition
: Option
<Edition
>,
54 description
: &'
static str,
57 #[derive(Copy, Clone, Debug)]
60 // First argument is tracking issue link; second argument is an optional
61 // help message, which defaults to "remove this attribute".
62 Deprecated(&'
static str, Option
<&'
static str>),
65 #[derive(Clone, Copy, Debug, Hash)]
66 pub enum UnstableFeatures
{
67 /// Hard errors for unstable features are active, as on beta/stable channels.
69 /// Allow features to be activated, as on nightly.
71 /// Errors are bypassed for bootstrapping. This is required any time
72 /// during the build that feature-related lints are set to warn or above
73 /// because the build turns on warnings-as-errors and uses lots of unstable
74 /// features. As a result, this is always required for building Rust itself.
78 impl UnstableFeatures
{
79 /// This takes into account `RUSTC_BOOTSTRAP`.
81 /// If `krate` is [`Some`], then setting `RUSTC_BOOTSTRAP=krate` will enable the nightly features.
82 /// Otherwise, only `RUSTC_BOOTSTRAP=1` will work.
83 pub fn from_environment(krate
: Option
<&str>) -> Self {
84 // `true` if this is a feature-staged build, i.e., on the beta or stable channel.
85 let disable_unstable_features
= option_env
!("CFG_DISABLE_UNSTABLE_FEATURES").is_some();
86 // Returns whether `krate` should be counted as unstable
87 let is_unstable_crate
= |var
: &str| {
88 krate
.map_or(false, |name
| var
.split('
,'
).any(|new_krate
| new_krate
== name
))
90 // `true` if we should enable unstable features for bootstrapping.
91 let bootstrap
= std
::env
::var("RUSTC_BOOTSTRAP")
92 .map_or(false, |var
| var
== "1" || is_unstable_crate(&var
));
93 match (disable_unstable_features
, bootstrap
) {
94 (_
, true) => UnstableFeatures
::Cheat
,
95 (true, _
) => UnstableFeatures
::Disallow
,
96 (false, _
) => UnstableFeatures
::Allow
,
100 pub fn is_nightly_build(&self) -> bool
{
102 UnstableFeatures
::Allow
| UnstableFeatures
::Cheat
=> true,
103 UnstableFeatures
::Disallow
=> false,
108 fn find_lang_feature_issue(feature
: Symbol
) -> Option
<NonZeroU32
> {
109 if let Some(info
) = ACTIVE_FEATURES
.iter().find(|t
| t
.name
== feature
) {
110 // FIXME (#28244): enforce that active features have issue numbers
111 // assert!(info.issue.is_some())
114 // search in Accepted, Removed, or Stable Removed features
115 let found
= ACCEPTED_FEATURES
117 .chain(REMOVED_FEATURES
)
118 .chain(STABLE_REMOVED_FEATURES
)
119 .find(|t
| t
.name
== feature
);
121 Some(found
) => found
.issue
,
122 None
=> panic
!("feature `{}` is not declared anywhere", feature
),
127 const fn to_nonzero(n
: Option
<u32>) -> Option
<NonZeroU32
> {
128 // Can be replaced with `n.and_then(NonZeroU32::new)` if that is ever usable
129 // in const context. Requires https://github.com/rust-lang/rfcs/pull/2632.
132 Some(n
) => NonZeroU32
::new(n
),
138 Library(Option
<NonZeroU32
>),
141 pub fn find_feature_issue(feature
: Symbol
, issue
: GateIssue
) -> Option
<NonZeroU32
> {
143 GateIssue
::Language
=> find_lang_feature_issue(feature
),
144 GateIssue
::Library(lib
) => lib
,
148 pub use accepted
::ACCEPTED_FEATURES
;
149 pub use active
::{Features, ACTIVE_FEATURES, INCOMPATIBLE_FEATURES}
;
150 pub use builtin_attrs
::{
151 deprecated_attributes
, find_gated_cfg
, is_builtin_attr_name
, AttributeGate
, AttributeTemplate
,
152 AttributeType
, BuiltinAttribute
, GatedCfg
, BUILTIN_ATTRIBUTES
, BUILTIN_ATTRIBUTE_MAP
,
154 pub use removed
::{REMOVED_FEATURES, STABLE_REMOVED_FEATURES}
;