Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cleanup rustc_features some more #116550

Merged
merged 2 commits into from
Oct 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/rustc_ast_passes/src/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -658,7 +658,7 @@ fn check_incompatible_features(sess: &Session, features: &Features) {

for (f1, f2) in rustc_feature::INCOMPATIBLE_FEATURES
.iter()
.filter(|&&(f1, f2)| features.enabled(f1) && features.enabled(f2))
.filter(|&&(f1, f2)| features.active(f1) && features.active(f2))
{
if let Some((f1_name, f1_span)) = declared_features.clone().find(|(name, _)| name == f1) {
if let Some((f2_name, f2_span)) = declared_features.clone().find(|(name, _)| name == f2)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
let gate = match op.status_in_item(self.ccx) {
Status::Allowed => return,

Status::Unstable(gate) if self.tcx.features().enabled(gate) => {
Status::Unstable(gate) if self.tcx.features().active(gate) => {
let unstable_in_stable = self.ccx.is_const_stable_const_fn()
&& !super::rustc_allow_const_fn_unstable(self.tcx, self.def_id(), gate);
if unstable_in_stable {
Expand Down
50 changes: 20 additions & 30 deletions compiler/rustc_expand/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ use rustc_ast::{self as ast, AttrStyle, Attribute, HasAttrs, HasTokens, MetaItem
use rustc_attr as attr;
use rustc_data_structures::flat_map_in_place::FlatMapInPlace;
use rustc_data_structures::fx::FxHashSet;
use rustc_feature::{Feature, Features, State as FeatureState};
use rustc_feature::{ACCEPTED_FEATURES, ACTIVE_FEATURES, REMOVED_FEATURES};
use rustc_feature::Features;
use rustc_feature::{ACCEPTED_FEATURES, REMOVED_FEATURES, UNSTABLE_FEATURES};
use rustc_parse::validate_attr;
use rustc_session::parse::feature_err;
use rustc_session::Session;
use rustc_span::edition::{Edition, ALL_EDITIONS};
use rustc_span::edition::ALL_EDITIONS;
use rustc_span::symbol::{sym, Symbol};
use rustc_span::Span;
use thin_vec::ThinVec;
Expand All @@ -36,16 +36,6 @@ pub struct StripUnconfigured<'a> {
}

pub fn features(sess: &Session, krate_attrs: &[Attribute]) -> Features {
fn active_features_up_to(edition: Edition) -> impl Iterator<Item = &'static Feature> {
ACTIVE_FEATURES.iter().filter(move |feature| {
if let Some(feature_edition) = feature.edition {
feature_edition <= edition
} else {
false
}
})
}

fn feature_list(attr: &Attribute) -> ThinVec<ast::NestedMetaItem> {
if attr.has_name(sym::feature)
&& let Some(list) = attr.meta_item_list()
Expand Down Expand Up @@ -83,11 +73,13 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute]) -> Features {
// Enable edition-dependent features based on `features_edition`.
// - E.g. enable `test_2018_feature` if `features_edition` is 2018 or higher
let mut edition_enabled_features = FxHashSet::default();
for feature in active_features_up_to(features_edition) {
// FIXME(Manishearth) there is currently no way to set lib features by
// edition.
edition_enabled_features.insert(feature.name);
feature.set(&mut features);
for f in UNSTABLE_FEATURES {
if let Some(edition) = f.feature.edition && edition <= features_edition {
// FIXME(Manishearth) there is currently no way to set lib features by
// edition.
edition_enabled_features.insert(f.feature.name);
(f.set_enabled)(&mut features);
}
}

// Process all features declared in the code.
Expand Down Expand Up @@ -147,19 +139,17 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute]) -> Features {
}

// If the declared feature has been removed, issue an error.
if let Some(Feature { state, .. }) = REMOVED_FEATURES.iter().find(|f| name == f.name) {
if let FeatureState::Removed { reason } = state {
sess.emit_err(FeatureRemoved {
span: mi.span(),
reason: reason.map(|reason| FeatureRemovedReason { reason }),
});
continue;
}
if let Some(f) = REMOVED_FEATURES.iter().find(|f| name == f.feature.name) {
sess.emit_err(FeatureRemoved {
span: mi.span(),
reason: f.reason.map(|reason| FeatureRemovedReason { reason }),
});
continue;
}

// If the declared feature is stable, record it.
if let Some(Feature { since, .. }) = ACCEPTED_FEATURES.iter().find(|f| name == f.name) {
let since = Some(Symbol::intern(since));
if let Some(f) = ACCEPTED_FEATURES.iter().find(|f| name == f.name) {
let since = Some(Symbol::intern(f.since));
features.set_declared_lang_feature(name, mi.span(), since);
continue;
}
Expand All @@ -175,8 +165,8 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute]) -> Features {
}

// If the declared feature is unstable, record it.
if let Some(f) = ACTIVE_FEATURES.iter().find(|f| name == f.name) {
f.set(&mut features);
if let Some(f) = UNSTABLE_FEATURES.iter().find(|f| name == f.feature.name) {
(f.set_enabled)(&mut features);
features.set_declared_lang_feature(name, mi.span(), None);
continue;
}
Expand Down
19 changes: 8 additions & 11 deletions compiler/rustc_feature/src/accepted.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
//! List of the accepted feature gates.

use super::{to_nonzero, Feature, State};
use super::{to_nonzero, Feature};
use rustc_span::symbol::sym;

macro_rules! declare_features {
($(
$(#[doc = $doc:tt])* (accepted, $feature:ident, $ver:expr, $issue:expr, None),
)+) => {
/// Those language feature has since been Accepted (it was once Active)
/// Formerly unstable features that have now been accepted (stabilized).
pub const ACCEPTED_FEATURES: &[Feature] = &[
$(
Feature {
state: State::Accepted,
name: sym::$feature,
since: $ver,
issue: to_nonzero($issue),
edition: None,
}
),+
$(Feature {
name: sym::$feature,
since: $ver,
issue: to_nonzero($issue),
edition: None,
}),+
];
}
}
Expand Down
46 changes: 13 additions & 33 deletions compiler/rustc_feature/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,37 +16,18 @@
#![deny(rustc::diagnostic_outside_of_impl)]

mod accepted;
mod active;
mod builtin_attrs;
mod removed;
mod unstable;

#[cfg(test)]
mod tests;

use rustc_span::{edition::Edition, symbol::Symbol};
use std::fmt;
use std::num::NonZeroU32;

#[derive(Clone, Copy)]
pub enum State {
Accepted,
Active { set: fn(&mut Features) },
Removed { reason: Option<&'static str> },
}

impl fmt::Debug for State {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
State::Accepted { .. } => write!(f, "accepted"),
State::Active { .. } => write!(f, "active"),
State::Removed { .. } => write!(f, "removed"),
}
}
}

#[derive(Debug, Clone)]
pub struct Feature {
pub state: State,
pub name: Symbol,
pub since: &'static str,
issue: Option<NonZeroU32>,
Expand All @@ -63,9 +44,9 @@ pub enum Stability {

#[derive(Clone, Copy, Debug, Hash)]
pub enum UnstableFeatures {
/// Hard errors for unstable features are active, as on beta/stable channels.
/// Disallow use of unstable features, as on beta/stable channels.
Disallow,
/// Allow features to be activated, as on nightly.
/// Allow use of unstable features, as on nightly.
Allow,
/// Errors are bypassed for bootstrapping. This is required any time
/// during the build that feature-related lints are set to warn or above
Expand Down Expand Up @@ -106,17 +87,16 @@ impl UnstableFeatures {

fn find_lang_feature_issue(feature: Symbol) -> Option<NonZeroU32> {
// Search in all the feature lists.
let found = []
.iter()
.chain(ACTIVE_FEATURES)
.chain(ACCEPTED_FEATURES)
.chain(REMOVED_FEATURES)
.find(|t| t.name == feature);

match found {
Some(found) => found.issue,
None => panic!("feature `{feature}` is not declared anywhere"),
if let Some(f) = UNSTABLE_FEATURES.iter().find(|f| f.feature.name == feature) {
return f.feature.issue;
}
if let Some(f) = ACCEPTED_FEATURES.iter().find(|f| f.name == feature) {
return f.issue;
}
if let Some(f) = REMOVED_FEATURES.iter().find(|f| f.feature.name == feature) {
return f.feature.issue;
}
panic!("feature `{feature}` is not declared anywhere");
}

const fn to_nonzero(n: Option<u32>) -> Option<NonZeroU32> {
Expand All @@ -141,11 +121,11 @@ pub fn find_feature_issue(feature: Symbol, issue: GateIssue) -> Option<NonZeroU3
}

pub use accepted::ACCEPTED_FEATURES;
pub use active::{Features, ACTIVE_FEATURES, INCOMPATIBLE_FEATURES};
pub use builtin_attrs::AttributeDuplicates;
pub use builtin_attrs::{
deprecated_attributes, find_gated_cfg, is_builtin_attr_name, is_builtin_only_local,
is_valid_for_get_attr, AttributeGate, AttributeTemplate, AttributeType, BuiltinAttribute,
GatedCfg, BUILTIN_ATTRIBUTES, BUILTIN_ATTRIBUTE_MAP,
};
pub use removed::REMOVED_FEATURES;
pub use unstable::{Features, INCOMPATIBLE_FEATURES, UNSTABLE_FEATURES};
21 changes: 13 additions & 8 deletions compiler/rustc_feature/src/removed.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,28 @@
//! List of the removed feature gates.

use super::{to_nonzero, Feature, State};
use super::{to_nonzero, Feature};
use rustc_span::symbol::sym;

pub struct RemovedFeature {
pub feature: Feature,
pub reason: Option<&'static str>,
}

macro_rules! declare_features {
($(
$(#[doc = $doc:tt])* (removed, $feature:ident, $ver:expr, $issue:expr, None, $reason:expr),
)+) => {
/// Represents unstable features which have since been removed (it was once Active)
pub const REMOVED_FEATURES: &[Feature] = &[
$(
Feature {
state: State::Removed { reason: $reason },
/// Formerly unstable features that have now been removed.
pub const REMOVED_FEATURES: &[RemovedFeature] = &[
$(RemovedFeature {
feature: Feature {
name: sym::$feature,
since: $ver,
issue: to_nonzero($issue),
edition: None,
}
),+
},
reason: $reason
}),+
];
};
}
Expand Down
Loading
Loading