Skip to content

Commit 41b6899

Browse files
committed
Remove rustc_feature::State.
`State` is used to distinguish active vs accepted vs removed features. However, these can also be distinguished by their location, in `ACTIVE_FEATURES`, `ACCEPTED_FEATURES`, and `REMOVED_FEATURES`. So this commit removes `State` and moves the internals of its variants next to the `Feature` in each element of `*_FEATURES`, introducing new types `ActiveFeature` and `RemovedFeature`. (There is no need for `AcceptedFeature` because `State::Accepted` had no fields.) This is a tighter type representation, avoids the need for some runtime checks, and makes the code a bit shorter.
1 parent 64368d0 commit 41b6899

File tree

5 files changed

+61
-97
lines changed

5 files changed

+61
-97
lines changed

compiler/rustc_expand/src/config.rs

+19-29
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@ use rustc_ast::{self as ast, AttrStyle, Attribute, HasAttrs, HasTokens, MetaItem
1414
use rustc_attr as attr;
1515
use rustc_data_structures::flat_map_in_place::FlatMapInPlace;
1616
use rustc_data_structures::fx::FxHashSet;
17-
use rustc_feature::{Feature, Features, State as FeatureState};
17+
use rustc_feature::Features;
1818
use rustc_feature::{ACCEPTED_FEATURES, ACTIVE_FEATURES, REMOVED_FEATURES};
1919
use rustc_parse::validate_attr;
2020
use rustc_session::parse::feature_err;
2121
use rustc_session::Session;
22-
use rustc_span::edition::{Edition, ALL_EDITIONS};
22+
use rustc_span::edition::ALL_EDITIONS;
2323
use rustc_span::symbol::{sym, Symbol};
2424
use rustc_span::Span;
2525
use thin_vec::ThinVec;
@@ -36,16 +36,6 @@ pub struct StripUnconfigured<'a> {
3636
}
3737

3838
pub fn features(sess: &Session, krate_attrs: &[Attribute]) -> Features {
39-
fn active_features_up_to(edition: Edition) -> impl Iterator<Item = &'static Feature> {
40-
ACTIVE_FEATURES.iter().filter(move |feature| {
41-
if let Some(feature_edition) = feature.edition {
42-
feature_edition <= edition
43-
} else {
44-
false
45-
}
46-
})
47-
}
48-
4939
fn feature_list(attr: &Attribute) -> ThinVec<ast::NestedMetaItem> {
5040
if attr.has_name(sym::feature)
5141
&& let Some(list) = attr.meta_item_list()
@@ -83,11 +73,13 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute]) -> Features {
8373
// Enable edition-dependent features based on `features_edition`.
8474
// - E.g. enable `test_2018_feature` if `features_edition` is 2018 or higher
8575
let mut edition_enabled_features = FxHashSet::default();
86-
for feature in active_features_up_to(features_edition) {
87-
// FIXME(Manishearth) there is currently no way to set lib features by
88-
// edition.
89-
edition_enabled_features.insert(feature.name);
90-
feature.set(&mut features);
76+
for f in ACTIVE_FEATURES {
77+
if let Some(edition) = f.feature.edition && edition <= features_edition {
78+
// FIXME(Manishearth) there is currently no way to set lib features by
79+
// edition.
80+
edition_enabled_features.insert(f.feature.name);
81+
(f.set_enabled)(&mut features);
82+
}
9183
}
9284

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

149141
// If the declared feature has been removed, issue an error.
150-
if let Some(Feature { state, .. }) = REMOVED_FEATURES.iter().find(|f| name == f.name) {
151-
if let FeatureState::Removed { reason } = state {
152-
sess.emit_err(FeatureRemoved {
153-
span: mi.span(),
154-
reason: reason.map(|reason| FeatureRemovedReason { reason }),
155-
});
156-
continue;
157-
}
142+
if let Some(f) = REMOVED_FEATURES.iter().find(|f| name == f.feature.name) {
143+
sess.emit_err(FeatureRemoved {
144+
span: mi.span(),
145+
reason: f.reason.map(|reason| FeatureRemovedReason { reason }),
146+
});
147+
continue;
158148
}
159149

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

177167
// If the declared feature is unstable, record it.
178-
if let Some(f) = ACTIVE_FEATURES.iter().find(|f| name == f.name) {
179-
f.set(&mut features);
168+
if let Some(f) = ACTIVE_FEATURES.iter().find(|f| name == f.feature.name) {
169+
(f.set_enabled)(&mut features);
180170
features.set_declared_lang_feature(name, mi.span(), None);
181171
continue;
182172
}

compiler/rustc_feature/src/accepted.rs

+7-10
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! List of the accepted feature gates.
22
3-
use super::{to_nonzero, Feature, State};
3+
use super::{to_nonzero, Feature};
44
use rustc_span::symbol::sym;
55

66
macro_rules! declare_features {
@@ -9,15 +9,12 @@ macro_rules! declare_features {
99
)+) => {
1010
/// Those language feature has since been Accepted (it was once Active)
1111
pub const ACCEPTED_FEATURES: &[Feature] = &[
12-
$(
13-
Feature {
14-
state: State::Accepted,
15-
name: sym::$feature,
16-
since: $ver,
17-
issue: to_nonzero($issue),
18-
edition: None,
19-
}
20-
),+
12+
$(Feature {
13+
name: sym::$feature,
14+
since: $ver,
15+
issue: to_nonzero($issue),
16+
edition: None,
17+
}),+
2118
];
2219
}
2320
}

compiler/rustc_feature/src/active.rs

+14-22
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
//! List of the active feature gates.
22
3-
use super::{to_nonzero, Feature, State};
3+
use super::{to_nonzero, Feature};
44

55
use rustc_data_structures::fx::FxHashSet;
66
use rustc_span::edition::Edition;
77
use rustc_span::symbol::{sym, Symbol};
88
use rustc_span::Span;
99

10+
pub struct ActiveFeature {
11+
pub feature: Feature,
12+
pub set_enabled: fn(&mut Features),
13+
}
14+
1015
#[derive(PartialEq)]
1116
enum FeatureStatus {
1217
Default,
@@ -32,21 +37,18 @@ macro_rules! declare_features {
3237
)+) => {
3338
/// Represents active features that are currently being implemented or
3439
/// currently being considered for addition/removal.
35-
pub const ACTIVE_FEATURES:
36-
&[Feature] =
37-
&[$(
38-
// (sym::$feature, $ver, $issue, $edition, set!($feature))
39-
Feature {
40-
state: State::Active {
41-
// Sets this feature's corresponding bool within `features`.
42-
set: |features| features.$feature = true,
43-
},
40+
pub const ACTIVE_FEATURES: &[ActiveFeature] = &[
41+
$(ActiveFeature {
42+
feature: Feature {
4443
name: sym::$feature,
4544
since: $ver,
4645
issue: to_nonzero($issue),
4746
edition: $edition,
48-
}
49-
),+];
47+
},
48+
// Sets this feature's corresponding bool within `features`.
49+
set_enabled: |features| features.$feature = true,
50+
}),+
51+
];
5052

5153
/// A set of features to be used by later passes.
5254
#[derive(Clone, Default, Debug)]
@@ -134,16 +136,6 @@ macro_rules! declare_features {
134136
};
135137
}
136138

137-
impl Feature {
138-
/// Sets this feature in `Features`. Panics if called on a non-active feature.
139-
pub fn set(&self, features: &mut Features) {
140-
match self.state {
141-
State::Active { set } => set(features),
142-
_ => panic!("called `set` on feature `{}` which is not `active`", self.name),
143-
}
144-
}
145-
}
146-
147139
// See https://rustc-dev-guide.rust-lang.org/feature-gates.html#feature-gates for more
148140
// documentation about handling feature gates.
149141
//

compiler/rustc_feature/src/lib.rs

+9-29
Original file line numberDiff line numberDiff line change
@@ -24,29 +24,10 @@ mod removed;
2424
mod tests;
2525

2626
use rustc_span::{edition::Edition, symbol::Symbol};
27-
use std::fmt;
2827
use std::num::NonZeroU32;
2928

30-
#[derive(Clone, Copy)]
31-
pub enum State {
32-
Accepted,
33-
Active { set: fn(&mut Features) },
34-
Removed { reason: Option<&'static str> },
35-
}
36-
37-
impl fmt::Debug for State {
38-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39-
match self {
40-
State::Accepted { .. } => write!(f, "accepted"),
41-
State::Active { .. } => write!(f, "active"),
42-
State::Removed { .. } => write!(f, "removed"),
43-
}
44-
}
45-
}
46-
4729
#[derive(Debug, Clone)]
4830
pub struct Feature {
49-
pub state: State,
5031
pub name: Symbol,
5132
pub since: &'static str,
5233
issue: Option<NonZeroU32>,
@@ -106,17 +87,16 @@ impl UnstableFeatures {
10687

10788
fn find_lang_feature_issue(feature: Symbol) -> Option<NonZeroU32> {
10889
// Search in all the feature lists.
109-
let found = []
110-
.iter()
111-
.chain(ACTIVE_FEATURES)
112-
.chain(ACCEPTED_FEATURES)
113-
.chain(REMOVED_FEATURES)
114-
.find(|t| t.name == feature);
115-
116-
match found {
117-
Some(found) => found.issue,
118-
None => panic!("feature `{feature}` is not declared anywhere"),
90+
if let Some(f) = ACTIVE_FEATURES.iter().find(|f| f.feature.name == feature) {
91+
return f.feature.issue;
92+
}
93+
if let Some(f) = ACCEPTED_FEATURES.iter().find(|f| f.name == feature) {
94+
return f.issue;
95+
}
96+
if let Some(f) = REMOVED_FEATURES.iter().find(|f| f.feature.name == feature) {
97+
return f.feature.issue;
11998
}
99+
panic!("feature `{feature}` is not declared anywhere");
120100
}
121101

122102
const fn to_nonzero(n: Option<u32>) -> Option<NonZeroU32> {

compiler/rustc_feature/src/removed.rs

+12-7
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,28 @@
11
//! List of the removed feature gates.
22
3-
use super::{to_nonzero, Feature, State};
3+
use super::{to_nonzero, Feature};
44
use rustc_span::symbol::sym;
55

6+
pub struct RemovedFeature {
7+
pub feature: Feature,
8+
pub reason: Option<&'static str>,
9+
}
10+
611
macro_rules! declare_features {
712
($(
813
$(#[doc = $doc:tt])* (removed, $feature:ident, $ver:expr, $issue:expr, None, $reason:expr),
914
)+) => {
1015
/// Represents unstable features which have since been removed (it was once Active)
11-
pub const REMOVED_FEATURES: &[Feature] = &[
12-
$(
13-
Feature {
14-
state: State::Removed { reason: $reason },
16+
pub const REMOVED_FEATURES: &[RemovedFeature] = &[
17+
$(RemovedFeature {
18+
feature: Feature {
1519
name: sym::$feature,
1620
since: $ver,
1721
issue: to_nonzero($issue),
1822
edition: None,
19-
}
20-
),+
23+
},
24+
reason: $reason
25+
}),+
2126
];
2227
};
2328
}

0 commit comments

Comments
 (0)