2019-11-30 05:43:32 +00:00
|
|
|
//! # Feature gates
|
2013-10-03 01:10:16 +00:00
|
|
|
//!
|
2019-11-30 05:43:32 +00:00
|
|
|
//! This crate declares the set of past and present unstable features in the compiler.
|
2021-04-07 19:47:01 +00:00
|
|
|
//! Feature gate checking itself is done in `rustc_ast_passes/src/feature_gate.rs`
|
2020-01-12 15:51:15 +00:00
|
|
|
//! at the moment.
|
2013-10-03 01:10:16 +00:00
|
|
|
//!
|
|
|
|
//! Features are enabled in programs via the crate-level attributes of
|
2014-06-22 17:29:42 +00:00
|
|
|
//! `#![feature(...)]` with a comma-separated list of features.
|
2015-01-15 03:27:45 +00:00
|
|
|
//!
|
2019-11-30 05:43:32 +00:00
|
|
|
//! For the purpose of future feature-tracking, once a feature gate is added,
|
|
|
|
//! even if it is stabilized or removed, *do not remove it*. Instead, move the
|
|
|
|
//! symbol to the `accepted` or `removed` modules respectively.
|
2015-02-03 22:31:06 +00:00
|
|
|
|
Use `tidy` to sort crate attributes for all compiler crates.
We already do this for a number of crates, e.g. `rustc_middle`,
`rustc_span`, `rustc_metadata`, `rustc_span`, `rustc_errors`.
For the ones we don't, in many cases the attributes are a mess.
- There is no consistency about order of attribute kinds (e.g.
`allow`/`deny`/`feature`).
- Within attribute kind groups (e.g. the `feature` attributes),
sometimes the order is alphabetical, and sometimes there is no
particular order.
- Sometimes the attributes of a particular kind aren't even grouped
all together, e.g. there might be a `feature`, then an `allow`, then
another `feature`.
This commit extends the existing sorting to all compiler crates,
increasing consistency. If any new attribute line is added there is now
only one place it can go -- no need for arbitrary decisions.
Exceptions:
- `rustc_log`, `rustc_next_trait_solver` and `rustc_type_ir_macros`,
because they have no crate attributes.
- `rustc_codegen_gcc`, because it's quasi-external to rustc (e.g. it's
ignored in `rustfmt.toml`).
2024-06-12 03:49:36 +00:00
|
|
|
// tidy-alphabetical-start
|
2023-11-13 12:39:17 +00:00
|
|
|
#![allow(internal_features)]
|
|
|
|
#![doc(rust_logo)]
|
Use `tidy` to sort crate attributes for all compiler crates.
We already do this for a number of crates, e.g. `rustc_middle`,
`rustc_span`, `rustc_metadata`, `rustc_span`, `rustc_errors`.
For the ones we don't, in many cases the attributes are a mess.
- There is no consistency about order of attribute kinds (e.g.
`allow`/`deny`/`feature`).
- Within attribute kind groups (e.g. the `feature` attributes),
sometimes the order is alphabetical, and sometimes there is no
particular order.
- Sometimes the attributes of a particular kind aren't even grouped
all together, e.g. there might be a `feature`, then an `allow`, then
another `feature`.
This commit extends the existing sorting to all compiler crates,
increasing consistency. If any new attribute line is added there is now
only one place it can go -- no need for arbitrary decisions.
Exceptions:
- `rustc_log`, `rustc_next_trait_solver` and `rustc_type_ir_macros`,
because they have no crate attributes.
- `rustc_codegen_gcc`, because it's quasi-external to rustc (e.g. it's
ignored in `rustfmt.toml`).
2024-06-12 03:49:36 +00:00
|
|
|
#![feature(rustdoc_internals)]
|
2024-08-27 02:55:54 +00:00
|
|
|
#![warn(unreachable_pub)]
|
Use `tidy` to sort crate attributes for all compiler crates.
We already do this for a number of crates, e.g. `rustc_middle`,
`rustc_span`, `rustc_metadata`, `rustc_span`, `rustc_errors`.
For the ones we don't, in many cases the attributes are a mess.
- There is no consistency about order of attribute kinds (e.g.
`allow`/`deny`/`feature`).
- Within attribute kind groups (e.g. the `feature` attributes),
sometimes the order is alphabetical, and sometimes there is no
particular order.
- Sometimes the attributes of a particular kind aren't even grouped
all together, e.g. there might be a `feature`, then an `allow`, then
another `feature`.
This commit extends the existing sorting to all compiler crates,
increasing consistency. If any new attribute line is added there is now
only one place it can go -- no need for arbitrary decisions.
Exceptions:
- `rustc_log`, `rustc_next_trait_solver` and `rustc_type_ir_macros`,
because they have no crate attributes.
- `rustc_codegen_gcc`, because it's quasi-external to rustc (e.g. it's
ignored in `rustfmt.toml`).
2024-06-12 03:49:36 +00:00
|
|
|
// tidy-alphabetical-end
|
2020-09-01 20:42:21 +00:00
|
|
|
|
2019-08-20 16:40:53 +00:00
|
|
|
mod accepted;
|
2019-11-30 01:34:18 +00:00
|
|
|
mod builtin_attrs;
|
2019-12-24 22:44:51 +00:00
|
|
|
mod removed;
|
2023-10-05 08:43:35 +00:00
|
|
|
mod unstable;
|
2019-08-22 21:48:08 +00:00
|
|
|
|
2020-12-12 16:18:44 +00:00
|
|
|
#[cfg(test)]
|
|
|
|
mod tests;
|
|
|
|
|
2024-01-29 22:59:09 +00:00
|
|
|
use std::num::NonZero;
|
2019-08-24 15:50:21 +00:00
|
|
|
|
2023-12-10 17:34:13 +00:00
|
|
|
use rustc_span::symbol::Symbol;
|
2024-07-28 22:13:50 +00:00
|
|
|
|
2019-08-24 15:50:21 +00:00
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
pub struct Feature {
|
2019-11-29 23:23:38 +00:00
|
|
|
pub name: Symbol,
|
2024-07-14 06:18:03 +00:00
|
|
|
/// For unstable features: the version the feature was added in.
|
|
|
|
/// For accepted features: the version the feature got stabilized in.
|
|
|
|
/// For removed features we are inconsistent; sometimes this is the
|
|
|
|
/// version it got added, sometimes the version it got removed.
|
2019-11-29 23:23:38 +00:00
|
|
|
pub since: &'static str,
|
2024-01-29 22:59:09 +00:00
|
|
|
issue: Option<NonZero<u32>>,
|
2019-08-24 15:50:21 +00:00
|
|
|
}
|
|
|
|
|
2019-11-29 23:39:51 +00:00
|
|
|
#[derive(Copy, Clone, Debug)]
|
|
|
|
pub enum Stability {
|
|
|
|
Unstable,
|
|
|
|
// First argument is tracking issue link; second argument is an optional
|
|
|
|
// help message, which defaults to "remove this attribute".
|
|
|
|
Deprecated(&'static str, Option<&'static str>),
|
|
|
|
}
|
|
|
|
|
2020-10-10 18:27:52 +00:00
|
|
|
#[derive(Clone, Copy, Debug, Hash)]
|
2019-11-30 01:50:47 +00:00
|
|
|
pub enum UnstableFeatures {
|
2023-10-05 08:43:35 +00:00
|
|
|
/// Disallow use of unstable features, as on beta/stable channels.
|
2019-11-30 01:50:47 +00:00
|
|
|
Disallow,
|
2023-10-05 08:43:35 +00:00
|
|
|
/// Allow use of unstable features, as on nightly.
|
2019-11-30 01:50:47 +00:00
|
|
|
Allow,
|
|
|
|
/// Errors are bypassed for bootstrapping. This is required any time
|
|
|
|
/// during the build that feature-related lints are set to warn or above
|
|
|
|
/// because the build turns on warnings-as-errors and uses lots of unstable
|
|
|
|
/// features. As a result, this is always required for building Rust itself.
|
2019-12-24 22:44:51 +00:00
|
|
|
Cheat,
|
2019-11-30 01:50:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl UnstableFeatures {
|
2020-10-10 18:27:52 +00:00
|
|
|
/// This takes into account `RUSTC_BOOTSTRAP`.
|
|
|
|
///
|
2023-10-04 03:54:12 +00:00
|
|
|
/// If `krate` is [`Some`], then setting `RUSTC_BOOTSTRAP=krate` will enable the nightly
|
|
|
|
/// features. Otherwise, only `RUSTC_BOOTSTRAP=1` will work.
|
2020-10-10 18:27:52 +00:00
|
|
|
pub fn from_environment(krate: Option<&str>) -> Self {
|
2019-11-30 01:50:47 +00:00
|
|
|
// `true` if this is a feature-staged build, i.e., on the beta or stable channel.
|
2023-01-12 10:36:04 +00:00
|
|
|
let disable_unstable_features =
|
2023-05-24 14:33:43 +00:00
|
|
|
option_env!("CFG_DISABLE_UNSTABLE_FEATURES").is_some_and(|s| s != "0");
|
2020-10-10 18:27:52 +00:00
|
|
|
// Returns whether `krate` should be counted as unstable
|
2023-05-24 14:19:22 +00:00
|
|
|
let is_unstable_crate =
|
|
|
|
|var: &str| krate.is_some_and(|name| var.split(',').any(|new_krate| new_krate == name));
|
2019-11-30 01:50:47 +00:00
|
|
|
// `true` if we should enable unstable features for bootstrapping.
|
2023-05-24 14:19:22 +00:00
|
|
|
let bootstrap =
|
|
|
|
std::env::var("RUSTC_BOOTSTRAP").is_ok_and(|var| var == "1" || is_unstable_crate(&var));
|
2019-11-30 01:50:47 +00:00
|
|
|
match (disable_unstable_features, bootstrap) {
|
|
|
|
(_, true) => UnstableFeatures::Cheat,
|
|
|
|
(true, _) => UnstableFeatures::Disallow,
|
2019-12-24 22:44:51 +00:00
|
|
|
(false, _) => UnstableFeatures::Allow,
|
2019-11-30 01:50:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn is_nightly_build(&self) -> bool {
|
|
|
|
match *self {
|
|
|
|
UnstableFeatures::Allow | UnstableFeatures::Cheat => true,
|
|
|
|
UnstableFeatures::Disallow => false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-01-29 22:59:09 +00:00
|
|
|
fn find_lang_feature_issue(feature: Symbol) -> Option<NonZero<u32>> {
|
2023-10-04 03:54:12 +00:00
|
|
|
// Search in all the feature lists.
|
2024-10-23 07:20:02 +00:00
|
|
|
if let Some(f) = UNSTABLE_LANG_FEATURES.iter().find(|f| f.name == feature) {
|
2024-10-23 07:18:19 +00:00
|
|
|
return f.issue;
|
2023-10-05 07:59:01 +00:00
|
|
|
}
|
2024-10-23 07:20:02 +00:00
|
|
|
if let Some(f) = ACCEPTED_LANG_FEATURES.iter().find(|f| f.name == feature) {
|
2023-10-05 07:59:01 +00:00
|
|
|
return f.issue;
|
|
|
|
}
|
2024-10-23 07:20:02 +00:00
|
|
|
if let Some(f) = REMOVED_LANG_FEATURES.iter().find(|f| f.feature.name == feature) {
|
2023-10-05 07:59:01 +00:00
|
|
|
return f.feature.issue;
|
2019-11-30 06:40:28 +00:00
|
|
|
}
|
2023-10-05 07:59:01 +00:00
|
|
|
panic!("feature `{feature}` is not declared anywhere");
|
2019-11-30 06:40:28 +00:00
|
|
|
}
|
|
|
|
|
2024-01-29 22:59:09 +00:00
|
|
|
const fn to_nonzero(n: Option<u32>) -> Option<NonZero<u32>> {
|
|
|
|
// Can be replaced with `n.and_then(NonZero::new)` if that is ever usable
|
2020-10-01 15:32:23 +00:00
|
|
|
// in const context. Requires https://github.com/rust-lang/rfcs/pull/2632.
|
2020-09-17 19:11:22 +00:00
|
|
|
match n {
|
|
|
|
None => None,
|
2024-02-08 22:03:25 +00:00
|
|
|
Some(n) => NonZero::new(n),
|
2020-09-17 19:11:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-30 06:40:28 +00:00
|
|
|
pub enum GateIssue {
|
|
|
|
Language,
|
2024-01-29 22:59:09 +00:00
|
|
|
Library(Option<NonZero<u32>>),
|
2019-11-30 06:40:28 +00:00
|
|
|
}
|
|
|
|
|
2024-01-29 22:59:09 +00:00
|
|
|
pub fn find_feature_issue(feature: Symbol, issue: GateIssue) -> Option<NonZero<u32>> {
|
2019-11-30 06:40:28 +00:00
|
|
|
match issue {
|
|
|
|
GateIssue::Language => find_lang_feature_issue(feature),
|
|
|
|
GateIssue::Library(lib) => lib,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-10-23 07:20:02 +00:00
|
|
|
pub use accepted::ACCEPTED_LANG_FEATURES;
|
2019-11-30 01:34:18 +00:00
|
|
|
pub use builtin_attrs::{
|
2024-09-06 16:47:22 +00:00
|
|
|
AttributeDuplicates, AttributeGate, AttributeSafety, AttributeTemplate, AttributeType,
|
|
|
|
BUILTIN_ATTRIBUTE_MAP, BUILTIN_ATTRIBUTES, BuiltinAttribute, GatedCfg, deprecated_attributes,
|
2024-03-18 16:05:18 +00:00
|
|
|
encode_cross_crate, find_gated_cfg, is_builtin_attr_name, is_stable_diagnostic_attribute,
|
2024-09-06 16:47:22 +00:00
|
|
|
is_valid_for_get_attr,
|
2019-11-30 01:34:18 +00:00
|
|
|
};
|
2024-10-23 07:20:02 +00:00
|
|
|
pub use removed::REMOVED_LANG_FEATURES;
|
|
|
|
pub use unstable::{Features, INCOMPATIBLE_FEATURES, UNSTABLE_LANG_FEATURES};
|