-
Notifications
You must be signed in to change notification settings - Fork 13.3k
de-macro-ize feature gate checking #66945
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,34 +6,22 @@ use syntax_pos::edition::Edition; | |
use syntax_pos::Span; | ||
use syntax_pos::symbol::{Symbol, sym}; | ||
|
||
macro_rules! set { | ||
($field: ident) => {{ | ||
fn f(features: &mut Features, _: Span) { | ||
features.$field = true; | ||
} | ||
f as fn(&mut Features, Span) | ||
}} | ||
} | ||
|
||
macro_rules! declare_features { | ||
($( | ||
$(#[doc = $doc:tt])* (active, $feature:ident, $ver:expr, $issue:expr, $edition:expr), | ||
)+) => { | ||
/// Represents active features that are currently being implemented or | ||
/// currently being considered for addition/removal. | ||
pub const ACTIVE_FEATURES: | ||
&[Feature] = | ||
&[$( | ||
// (sym::$feature, $ver, $issue, $edition, set!($feature)) | ||
Feature { | ||
state: State::Active { set: set!($feature) }, | ||
name: sym::$feature, | ||
since: $ver, | ||
issue: $issue, | ||
edition: $edition, | ||
description: concat!($($doc,)*), | ||
} | ||
),+]; | ||
pub const ACTIVE_FEATURES: &[Feature] = &[$( | ||
Feature { | ||
state: State::Active, | ||
name: sym::$feature, | ||
since: $ver, | ||
issue: $issue, | ||
edition: $edition, | ||
description: concat!($($doc,)*), | ||
} | ||
),+]; | ||
|
||
/// A set of features to be used by later passes. | ||
#[derive(Clone, Default)] | ||
|
@@ -44,28 +32,43 @@ macro_rules! declare_features { | |
pub declared_lib_features: Vec<(Symbol, Span)>, | ||
$( | ||
$(#[doc = $doc])* | ||
pub $feature: bool | ||
$feature: bool | ||
),+ | ||
} | ||
|
||
impl Features { | ||
/// Is the given feature enabled? | ||
/// | ||
/// Panics if the symbol doesn't correspond to a declared feature. | ||
pub fn on(&self, name: Symbol) -> bool { | ||
match name { | ||
$(sym::$feature => self.$feature,)+ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wish we had field pointers (like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps the field approach can be kept with the use of macros being minimized rather than fully eliminated. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Initially I had a Otherwise, perhaps field accesses outside There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is unclear to me -- why is the macro itself bad? It looks like this is still using a macro. It looks also like we're still generating the fields, so we why can't expose those is not clear to me. |
||
_ => panic!("unknown feature `{}`", name), | ||
} | ||
} | ||
|
||
/// Enable the given `feature`. | ||
/// | ||
/// Panics if called on a non-active feature | ||
/// or a symbol not corresponding to a declared feature. | ||
pub fn enable(&mut self, feature: &Feature, _: Span) { | ||
let Feature { name, .. } = feature; | ||
match feature.state { | ||
State::Active => match *name { | ||
$(sym::$feature => self.$feature = true,)+ | ||
_ => panic!("unknown feature `{}`", name), | ||
}, | ||
_ => panic!("called `set` on feature `{}` which is not `active`", name), | ||
} | ||
} | ||
|
||
pub fn walk_feature_fields(&self, mut f: impl FnMut(&str, bool)) { | ||
$(f(stringify!($feature), self.$feature);)+ | ||
} | ||
} | ||
}; | ||
} | ||
|
||
impl Feature { | ||
/// Sets this feature in `Features`. Panics if called on a non-active feature. | ||
pub fn set(&self, features: &mut Features, span: Span) { | ||
match self.state { | ||
State::Active { set } => set(features, span), | ||
_ => panic!("called `set` on feature `{}` which is not `active`", self.name) | ||
} | ||
} | ||
} | ||
|
||
// If you change this, please modify `src/doc/unstable-book` as well. | ||
// | ||
// Don't ever remove anything from this list; move them to `removed.rs`. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the field approach is rejected after all in favor of a method, could it be named
enabled
instead ofon
?"
on
" looks like it's... an event handler of sorts?onKeyPress
anyone?The "on/off" association certainly didn't come immediately to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Heh; I went with
.active(..)
first, then changed to.enabled(..)
and finally to.on(..)
to make it shorter. 😂.enabled(..)
is fine by me.