Skip to content

Commit fed7922

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 bf9a1c8 commit fed7922

File tree

5 files changed

+61
-97
lines changed

5 files changed

+61
-97
lines changed

compiler/rustc_expand/src/config.rs

Lines changed: 19 additions & 29 deletions
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) && let Some(list) = attr.meta_item_list() {
5141
list
@@ -79,11 +69,13 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute]) -> Features {
7969
// Enable edition-dependent features based on `features_edition`.
8070
// - E.g. enable `test_2018_feature` if `features_edition` is 2018 or higher
8171
let mut edition_enabled_features = FxHashSet::default();
82-
for feature in active_features_up_to(features_edition) {
83-
// FIXME(Manishearth) there is currently no way to set lib features by
84-
// edition.
85-
edition_enabled_features.insert(feature.name);
86-
feature.set(&mut features);
72+
for f in ACTIVE_FEATURES {
73+
if let Some(edition) = f.feature.edition && edition <= features_edition {
74+
// FIXME(Manishearth) there is currently no way to set lib features by
75+
// edition.
76+
edition_enabled_features.insert(f.feature.name);
77+
(f.set_enabled)(&mut features);
78+
}
8779
}
8880

8981
// Process all features declared in the code.
@@ -143,19 +135,17 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute]) -> Features {
143135
}
144136

145137
// If the declared feature has been removed, issue an error.
146-
if let Some(Feature { state, .. }) = REMOVED_FEATURES.iter().find(|f| name == f.name) {
147-
if let FeatureState::Removed { reason } = state {
148-
sess.emit_err(FeatureRemoved {
149-
span: mi.span(),
150-
reason: reason.map(|reason| FeatureRemovedReason { reason }),
151-
});
152-
continue;
153-
}
138+
if let Some(f) = REMOVED_FEATURES.iter().find(|f| name == f.feature.name) {
139+
sess.emit_err(FeatureRemoved {
140+
span: mi.span(),
141+
reason: f.reason.map(|reason| FeatureRemovedReason { reason }),
142+
});
143+
continue;
154144
}
155145

156146
// If the declared feature is stable, record it.
157-
if let Some(Feature { since, .. }) = ACCEPTED_FEATURES.iter().find(|f| name == f.name) {
158-
let since = Some(Symbol::intern(since));
147+
if let Some(f) = ACCEPTED_FEATURES.iter().find(|f| name == f.name) {
148+
let since = Some(Symbol::intern(f.since));
159149
features.set_declared_lang_feature(name, mi.span(), since);
160150
continue;
161151
}
@@ -171,8 +161,8 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute]) -> Features {
171161
}
172162

173163
// If the declared feature is unstable, record it.
174-
if let Some(f) = ACTIVE_FEATURES.iter().find(|f| name == f.name) {
175-
f.set(&mut features);
164+
if let Some(f) = ACTIVE_FEATURES.iter().find(|f| name == f.feature.name) {
165+
(f.set_enabled)(&mut features);
176166
features.set_declared_lang_feature(name, mi.span(), None);
177167
continue;
178168
}

compiler/rustc_feature/src/accepted.rs

Lines changed: 7 additions & 10 deletions
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

Lines changed: 14 additions & 22 deletions
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

Lines changed: 9 additions & 29 deletions
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

Lines changed: 12 additions & 7 deletions
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)