Skip to content

Commit

Permalink
Auto merge of #116550 - nnethercote:rustc-features-more, r=Nilstrieb
Browse files Browse the repository at this point in the history
Cleanup `rustc_features` some more

The sequel to #116437.

r? `@Nilstrieb`
  • Loading branch information
bors committed Oct 16, 2023
2 parents e7bdc5f + d284c8a commit 98c1e3d
Show file tree
Hide file tree
Showing 14 changed files with 254 additions and 292 deletions.
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

0 comments on commit 98c1e3d

Please sign in to comment.