Generate the features structure and arrays with new macros.

This is more readable, safer, and allows for a much more efficient parsing.
This commit is contained in:
Leo Testard 2016-04-04 17:08:41 +02:00
parent 2f1dfe615d
commit ef1de519ff
2 changed files with 195 additions and 420 deletions

View File

@ -1345,14 +1345,14 @@ impl<'feat> ExpansionConfig<'feat> {
}
feature_tests! {
fn enable_quotes = allow_quote,
fn enable_asm = allow_asm,
fn enable_log_syntax = allow_log_syntax,
fn enable_concat_idents = allow_concat_idents,
fn enable_trace_macros = allow_trace_macros,
fn enable_quotes = quote,
fn enable_asm = asm,
fn enable_log_syntax = log_syntax,
fn enable_concat_idents = concat_idents,
fn enable_trace_macros = trace_macros,
fn enable_allow_internal_unstable = allow_internal_unstable,
fn enable_custom_derive = allow_custom_derive,
fn enable_pushpop_unsafe = allow_pushpop_unsafe,
fn enable_custom_derive = custom_derive,
fn enable_pushpop_unsafe = pushpop_unsafe,
}
}

View File

@ -22,7 +22,6 @@
//! gate usage is added, *do not remove it again* even once the feature
//! becomes stable.
use self::Status::*;
use self::AttributeType::*;
use self::AttributeGate::*;
@ -40,16 +39,57 @@ use parse::token::InternedString;
use std::ascii::AsciiExt;
use std::cmp;
enum Status {
/// Represents an active feature that is currently being implemented or
/// currently being considered for addition/removal.
Active,
macro_rules! setter {
($field: ident) => {{
fn f(features: &mut Features) -> &mut bool {
&mut features.$field
}
f as fn(&mut Features) -> &mut bool
}}
}
/// Represents a feature which has since been removed (it was once Active)
Removed,
macro_rules! declare_features {
($((active, $feature: ident, $ver: expr, $issue: expr)),+) => {
/// Represents active features that are currently being implemented or
/// currently being considered for addition/removal.
const ACTIVE_FEATURES: &'static [(&'static str, &'static str,
Option<u32>, fn(&mut Features) -> &mut bool)] = &[
$((stringify!($feature), $ver, $issue, setter!($feature))),+
];
/// This language feature has since been Accepted (it was once Active)
Accepted,
/// A set of features to be used by later passes.
pub struct Features {
/// spans of #![feature] attrs for stable language features. for error reporting
pub declared_stable_lang_features: Vec<Span>,
/// #![feature] attrs for non-language (library) features
pub declared_lib_features: Vec<(InternedString, Span)>,
$(pub $feature: bool),+
}
impl Features {
pub fn new() -> Features {
Features {
declared_stable_lang_features: Vec::new(),
declared_lib_features: Vec::new(),
$($feature: false),+
}
}
}
};
($((removed, $feature: ident, $ver: expr, $issue: expr)),+) => {
/// Represents features which has since been removed (it was once Active)
const REMOVED_FEATURES: &'static [(&'static str, &'static str, Option<u32>)] = &[
$((stringify!($feature), $ver, $issue)),+
];
};
($((accepted, $feature: ident, $ver: expr, $issue: expr)),+) => {
/// Those language feature has since been Accepted (it was once Active)
const ACCEPTED_FEATURES: &'static [(&'static str, &'static str, Option<u32>)] = &[
$((stringify!($feature), $ver, $issue)),+
];
}
}
// If you change this list without updating src/doc/reference.md, @cmr will be sad
@ -57,120 +97,88 @@ enum Status {
// The version numbers here correspond to the version in which the current status
// was set. This is most important for knowing when a particular feature became
// stable (active).
// NB: The tidy tool parses this information directly out of the source so take
// care when modifying it.
const KNOWN_FEATURES: &'static [(&'static str, &'static str, Option<u32>, Status)] = &[
("globs", "1.0.0", None, Accepted),
("macro_rules", "1.0.0", None, Accepted),
("struct_variant", "1.0.0", None, Accepted),
("asm", "1.0.0", Some(29722), Active),
("managed_boxes", "1.0.0", None, Removed),
("non_ascii_idents", "1.0.0", Some(28979), Active),
("thread_local", "1.0.0", Some(29594), Active),
("link_args", "1.0.0", Some(29596), Active),
("plugin_registrar", "1.0.0", Some(29597), Active),
("log_syntax", "1.0.0", Some(29598), Active),
("trace_macros", "1.0.0", Some(29598), Active),
("concat_idents", "1.0.0", Some(29599), Active),
// NB: The featureck.py script parses this information directly out of the source
// so take care when modifying it.
declare_features! (
(active, asm, "1.0.0", Some(29722)),
(active, concat_idents, "1.0.0", Some(29599)),
(active, link_args, "1.0.0", Some(29596)),
(active, log_syntax, "1.0.0", Some(29598)),
(active, non_ascii_idents, "1.0.0", Some(28979)),
(active, plugin_registrar, "1.0.0", Some(29597)),
(active, thread_local, "1.0.0", Some(29594)),
(active, trace_macros, "1.0.0", Some(29598)),
// rustc internal, for now:
("intrinsics", "1.0.0", None, Active),
("lang_items", "1.0.0", None, Active),
(active, intrinsics, "1.0.0", None),
(active, lang_items, "1.0.0", None),
("simd", "1.0.0", Some(27731), Active),
("default_type_params", "1.0.0", None, Accepted),
("quote", "1.0.0", Some(29601), Active),
("link_llvm_intrinsics", "1.0.0", Some(29602), Active),
("linkage", "1.0.0", Some(29603), Active),
("struct_inherit", "1.0.0", None, Removed),
(active, link_llvm_intrinsics, "1.0.0", Some(29602)),
(active, linkage, "1.0.0", Some(29603)),
(active, quote, "1.0.0", Some(29601)),
(active, simd, "1.0.0", Some(27731)),
("quad_precision_float", "1.0.0", None, Removed),
// rustc internal
("rustc_diagnostic_macros", "1.0.0", None, Active),
("unboxed_closures", "1.0.0", Some(29625), Active),
("reflect", "1.0.0", Some(27749), Active),
("import_shadowing", "1.0.0", None, Removed),
("advanced_slice_patterns", "1.0.0", Some(23121), Active),
("tuple_indexing", "1.0.0", None, Accepted),
("associated_types", "1.0.0", None, Accepted),
("visible_private_types", "1.0.0", None, Removed),
("slicing_syntax", "1.0.0", None, Accepted),
("box_syntax", "1.0.0", Some(27779), Active),
("placement_in_syntax", "1.0.0", Some(27779), Active),
(active, rustc_diagnostic_macros, "1.0.0", None),
(active, advanced_slice_patterns, "1.0.0", Some(23121)),
(active, box_syntax, "1.0.0", Some(27779)),
(active, placement_in_syntax, "1.0.0", Some(27779)),
(active, reflect, "1.0.0", Some(27749)),
(active, unboxed_closures, "1.0.0", Some(29625)),
// rustc internal.
("pushpop_unsafe", "1.2.0", None, Active),
(active, pushpop_unsafe, "1.2.0", None),
("on_unimplemented", "1.0.0", Some(29628), Active),
("simd_ffi", "1.0.0", Some(27731), Active),
("allocator", "1.0.0", Some(27389), Active),
("needs_allocator", "1.4.0", Some(27389), Active),
("linked_from", "1.3.0", Some(29629), Active),
("if_let", "1.0.0", None, Accepted),
("while_let", "1.0.0", None, Accepted),
("plugin", "1.0.0", Some(29597), Active),
("start", "1.0.0", Some(29633), Active),
("main", "1.0.0", Some(29634), Active),
("fundamental", "1.0.0", Some(29635), Active),
// A temporary feature gate used to enable parser extensions needed
// to bootstrap fix for #5723.
("issue_5723_bootstrap", "1.0.0", None, Accepted),
("structural_match", "1.8.0", Some(31434), Active),
// A way to temporarily opt out of opt in copy. This will *never* be accepted.
("opt_out_copy", "1.0.0", None, Removed),
(active, allocator, "1.0.0", Some(27389)),
(active, fundamental, "1.0.0", Some(29635)),
(active, linked_from, "1.3.0", Some(29629)),
(active, main, "1.0.0", Some(29634)),
(active, needs_allocator, "1.4.0", Some(27389)),
(active, on_unimplemented, "1.0.0", Some(29628)),
(active, plugin, "1.0.0", Some(29597)),
(active, simd_ffi, "1.0.0", Some(27731)),
(active, start, "1.0.0", Some(29633)),
(active, structural_match, "1.8.0", Some(31434)),
// OIBIT specific features
("optin_builtin_traits", "1.0.0", Some(13231), Active),
(active, optin_builtin_traits, "1.0.0", Some(13231)),
// macro reexport needs more discussion and stabilization
("macro_reexport", "1.0.0", Some(29638), Active),
// These are used to test this portion of the compiler, they don't actually
// mean anything
("test_accepted_feature", "1.0.0", None, Accepted),
("test_removed_feature", "1.0.0", None, Removed),
(active, macro_reexport, "1.0.0", Some(29638)),
// Allows use of #[staged_api]
// rustc internal
("staged_api", "1.0.0", None, Active),
(active, staged_api, "1.0.0", None),
// Allows using items which are missing stability attributes
// rustc internal
("unmarked_api", "1.0.0", None, Active),
// Allows using #![no_std]
("no_std", "1.0.0", None, Accepted),
(active, unmarked_api, "1.0.0", None),
// Allows using #![no_core]
("no_core", "1.3.0", Some(29639), Active),
(active, no_core, "1.3.0", Some(29639)),
// Allows using `box` in patterns; RFC 469
("box_patterns", "1.0.0", Some(29641), Active),
(active, box_patterns, "1.0.0", Some(29641)),
// Allows using the unsafe_no_drop_flag attribute (unlikely to
// switch to Accepted; see RFC 320)
("unsafe_no_drop_flag", "1.0.0", None, Active),
(active, unsafe_no_drop_flag, "1.0.0", None),
// Allows using the unsafe_destructor_blind_to_params attribute;
// RFC 1238
("dropck_parametricity", "1.3.0", Some(28498), Active),
(active, dropck_parametricity, "1.3.0", Some(28498)),
// Allows the use of custom attributes; RFC 572
("custom_attribute", "1.0.0", Some(29642), Active),
(active, custom_attribute, "1.0.0", Some(29642)),
// Allows the use of #[derive(Anything)] as sugar for
// #[derive_Anything].
("custom_derive", "1.0.0", Some(29644), Active),
(active, custom_derive, "1.0.0", Some(29644)),
// Allows the use of rustc_* attributes; RFC 572
("rustc_attrs", "1.0.0", Some(29642), Active),
(active, rustc_attrs, "1.0.0", Some(29642)),
// Allows the use of #[allow_internal_unstable]. This is an
// attribute on macro_rules! and can't use the attribute handling
@ -178,100 +186,128 @@ const KNOWN_FEATURES: &'static [(&'static str, &'static str, Option<u32>, Status
// macros disappear).
//
// rustc internal
("allow_internal_unstable", "1.0.0", None, Active),
(active, allow_internal_unstable, "1.0.0", None),
// #23121. Array patterns have some hazards yet.
("slice_patterns", "1.0.0", Some(23121), Active),
// Allows use of unary negate on unsigned integers, e.g. -e for e: u8
("negate_unsigned", "1.0.0", Some(29645), Removed),
(active, slice_patterns, "1.0.0", Some(23121)),
// Allows the definition of associated constants in `trait` or `impl`
// blocks.
("associated_consts", "1.0.0", Some(29646), Active),
(active, associated_consts, "1.0.0", Some(29646)),
// Allows the definition of `const fn` functions.
("const_fn", "1.2.0", Some(24111), Active),
(active, const_fn, "1.2.0", Some(24111)),
// Allows indexing into constant arrays.
("const_indexing", "1.4.0", Some(29947), Active),
(active, const_indexing, "1.4.0", Some(29947)),
// Allows using #[prelude_import] on glob `use` items.
//
// rustc internal
("prelude_import", "1.2.0", None, Active),
(active, prelude_import, "1.2.0", None),
// Allows the definition recursive static items.
("static_recursion", "1.3.0", Some(29719), Active),
(active, static_recursion, "1.3.0", Some(29719)),
// Allows default type parameters to influence type inference.
("default_type_parameter_fallback", "1.3.0", Some(27336), Active),
(active, default_type_parameter_fallback, "1.3.0", Some(27336)),
// Allows associated type defaults
("associated_type_defaults", "1.2.0", Some(29661), Active),
(active, associated_type_defaults, "1.2.0", Some(29661)),
// Allows macros to appear in the type position.
("type_macros", "1.3.0", Some(27245), Active),
(active, type_macros, "1.3.0", Some(27245)),
// allow `repr(simd)`, and importing the various simd intrinsics
("repr_simd", "1.4.0", Some(27731), Active),
(active, repr_simd, "1.4.0", Some(27731)),
// Allows cfg(target_feature = "...").
("cfg_target_feature", "1.4.0", Some(29717), Active),
(active, cfg_target_feature, "1.4.0", Some(29717)),
// allow `extern "platform-intrinsic" { ... }`
("platform_intrinsics", "1.4.0", Some(27731), Active),
(active, platform_intrinsics, "1.4.0", Some(27731)),
// allow `#[unwind]`
// rust runtime internal
("unwind_attributes", "1.4.0", None, Active),
(active, unwind_attributes, "1.4.0", None),
// allow the use of `#[naked]` on functions.
("naked_functions", "1.9.0", Some(32408), Active),
// allow empty structs and enum variants with braces
("braced_empty_structs", "1.8.0", Some(29720), Accepted),
// allow overloading augmented assignment operations like `a += b`
("augmented_assignments", "1.8.0", Some(28235), Accepted),
(active, naked_functions, "1.9.0", Some(32408)),
// allow `#[no_debug]`
("no_debug", "1.5.0", Some(29721), Active),
(active, no_debug, "1.5.0", Some(29721)),
// allow `#[omit_gdb_pretty_printer_section]`
// rustc internal.
("omit_gdb_pretty_printer_section", "1.5.0", None, Active),
(active, omit_gdb_pretty_printer_section, "1.5.0", None),
// Allows cfg(target_vendor = "...").
("cfg_target_vendor", "1.5.0", Some(29718), Active),
(active, cfg_target_vendor, "1.5.0", Some(29718)),
// Allow attributes on expressions and non-item statements
("stmt_expr_attributes", "1.6.0", Some(15701), Active),
// Allows `#[deprecated]` attribute
("deprecated", "1.9.0", Some(29935), Accepted),
(active, stmt_expr_attributes, "1.6.0", Some(15701)),
// allow using type ascription in expressions
("type_ascription", "1.6.0", Some(23416), Active),
(active, type_ascription, "1.6.0", Some(23416)),
// Allows cfg(target_thread_local)
("cfg_target_thread_local", "1.7.0", Some(29594), Active),
(active, cfg_target_thread_local, "1.7.0", Some(29594)),
// rustc internal
("abi_vectorcall", "1.7.0", None, Active),
(active, abi_vectorcall, "1.7.0", None),
// a...b and ...b
("inclusive_range_syntax", "1.7.0", Some(28237), Active),
(active, inclusive_range_syntax, "1.7.0", Some(28237)),
// `expr?`
("question_mark", "1.9.0", Some(31436), Active),
(active, question_mark, "1.9.0", Some(31436)),
// impl specialization (RFC 1210)
("specialization", "1.7.0", Some(31844), Active),
(active, specialization, "1.7.0", Some(31844)),
// pub(restricted) visibilities (RFC 1422)
("pub_restricted", "1.9.0", Some(32409), Active),
];
(active, pub_restricted, "1.9.0", Some(32409))
);
declare_features! (
(removed, import_shadowing, "1.0.0", None),
(removed, managed_boxes, "1.0.0", None),
// Allows use of unary negate on unsigned integers, e.g. -e for e: u8
(removed, negate_unsigned, "1.0.0", Some(29645)),
// A way to temporarily opt out of opt in copy. This will *never* be accepted.
(removed, opt_out_copy, "1.0.0", None),
(removed, quad_precision_float, "1.0.0", None),
(removed, struct_inherit, "1.0.0", None),
(removed, test_removed_feature, "1.0.0", None),
(removed, visible_private_types, "1.0.0", None)
);
declare_features! (
(accepted, associated_types, "1.0.0", None),
// allow overloading augmented assignment operations like `a += b`
(accepted, augmented_assignments, "1.8.0", Some(28235)),
// allow empty structs and enum variants with braces
(accepted, braced_empty_structs, "1.8.0", Some(29720)),
(accepted, default_type_params, "1.0.0", None),
(accepted, globs, "1.0.0", None),
(accepted, if_let, "1.0.0", None),
// A temporary feature gate used to enable parser extensions needed
// to bootstrap fix for #5723.
(accepted, issue_5723_bootstrap, "1.0.0", None),
(accepted, macro_rules, "1.0.0", None),
// Allows using #![no_std]
(accepted, no_std, "1.0.0", None),
(accepted, slicing_syntax, "1.0.0", None),
(accepted, struct_variant, "1.0.0", None),
// These are used to test this portion of the compiler, they don't actually
// mean anything
(accepted, test_accepted_feature, "1.0.0", None),
(accepted, tuple_indexing, "1.0.0", None),
(accepted, while_let, "1.0.0", None),
// Allows `#[deprecated]` attribute
(accepted, deprecated, "1.9.0", Some(29935))
);
// (changing above list without updating src/doc/reference.md makes @cmr sad)
#[derive(PartialEq, Copy, Clone, Debug)]
@ -471,7 +507,7 @@ pub const KNOWN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeGat
("naked", Whitelisted, Gated("naked_functions",
"the `#[naked]` attribute \
is an experimental feature",
cfg_fn!(naked))),
cfg_fn!(naked_functions))),
("export_name", Whitelisted, Ungated),
("inline", Whitelisted, Ungated),
("link", Whitelisted, Ungated),
@ -618,177 +654,6 @@ impl GatedCfg {
}
}
/// A set of features to be used by later passes.
pub struct Features {
pub unboxed_closures: bool,
pub rustc_diagnostic_macros: bool,
pub allow_quote: bool,
pub allow_asm: bool,
pub allow_log_syntax: bool,
pub allow_concat_idents: bool,
pub allow_trace_macros: bool,
pub allow_internal_unstable: bool,
pub allow_custom_derive: bool,
pub allow_placement_in: bool,
pub allow_box: bool,
pub allow_pushpop_unsafe: bool,
pub allow_inclusive_range: bool,
pub simd_ffi: bool,
pub unmarked_api: bool,
/// spans of #![feature] attrs for stable language features. for error reporting
pub declared_stable_lang_features: Vec<Span>,
/// #![feature] attrs for non-language (library) features
pub declared_lib_features: Vec<(InternedString, Span)>,
pub const_fn: bool,
pub const_indexing: bool,
pub static_recursion: bool,
pub default_type_parameter_fallback: bool,
pub rustc_attrs: bool,
pub type_macros: bool,
pub cfg_target_feature: bool,
pub cfg_target_vendor: bool,
pub cfg_target_thread_local: bool,
pub staged_api: bool,
pub stmt_expr_attributes: bool,
pub deprecated: bool,
pub question_mark: bool,
pub specialization: bool,
pub pub_restricted: bool,
pub structural_match: bool,
pub plugin: bool,
pub lang_items: bool,
pub linkage: bool,
pub thread_local: bool,
pub on_unimplemented: bool,
pub allocator: bool,
pub needs_allocator: bool,
pub fundamental: bool,
pub linked_from: bool,
pub naked: bool,
pub no_debug: bool,
pub omit_gdb_pretty_printer_section: bool,
pub dropck_parametricity: bool,
pub unwind_attributes: bool,
pub prelude_import: bool,
pub reflect: bool,
pub no_core: bool,
pub unsafe_no_drop_flag: bool,
pub custom_derive: bool,
pub custom_attribute: bool,
pub asm: bool,
pub log_syntax: bool,
pub trace_macros: bool,
pub concat_idents: bool,
pub box_syntax: bool,
pub placement_in_syntax: bool,
pub non_ascii_idents: bool,
pub macro_reexport: bool,
pub link_args: bool,
pub intrinsics: bool,
pub platform_intrinsics: bool,
pub abi_vectorcall: bool,
pub plugin_registrar: bool,
pub start: bool,
pub main: bool,
pub simd: bool,
pub repr_simd: bool,
pub optin_builtin_traits: bool,
pub link_llvm_intrinsics: bool,
pub type_ascription: bool,
pub inclusive_range_syntax: bool,
pub advanced_slice_patterns: bool,
pub slice_patterns: bool,
pub box_patterns: bool,
pub associated_consts: bool,
pub associated_type_defaults: bool
}
impl Features {
pub fn new() -> Features {
Features {
unboxed_closures: false,
rustc_diagnostic_macros: false,
allow_quote: false,
allow_asm: false,
allow_log_syntax: false,
allow_concat_idents: false,
allow_trace_macros: false,
allow_internal_unstable: false,
allow_custom_derive: false,
allow_placement_in: false,
allow_box: false,
allow_pushpop_unsafe: false,
allow_inclusive_range: false,
simd_ffi: false,
unmarked_api: false,
declared_stable_lang_features: Vec::new(),
declared_lib_features: Vec::new(),
const_fn: false,
const_indexing: false,
static_recursion: false,
default_type_parameter_fallback: false,
rustc_attrs: false,
type_macros: false,
cfg_target_feature: false,
cfg_target_vendor: false,
cfg_target_thread_local: false,
staged_api: false,
stmt_expr_attributes: false,
deprecated: false,
question_mark: false,
specialization: false,
pub_restricted: false,
structural_match: false,
plugin: false,
lang_items: false,
linkage: false,
thread_local: false,
on_unimplemented: false,
allocator: false,
needs_allocator: false,
fundamental: false,
linked_from: false,
naked: false,
no_debug: false,
omit_gdb_pretty_printer_section: false,
dropck_parametricity: false,
unwind_attributes: false,
prelude_import: false,
reflect: false,
no_core: false,
unsafe_no_drop_flag: false,
custom_derive: false,
custom_attribute: false,
asm: false,
log_syntax: false,
trace_macros: false,
concat_idents: false,
box_syntax: false,
placement_in_syntax: false,
non_ascii_idents: false,
macro_reexport: false,
link_args: false,
intrinsics: false,
platform_intrinsics: false,
abi_vectorcall: false,
plugin_registrar: false,
start: false,
main: false,
simd: false,
repr_simd: false,
optin_builtin_traits: false,
link_llvm_intrinsics: false,
type_ascription: false,
inclusive_range_syntax: false,
advanced_slice_patterns: false,
slice_patterns: false,
box_patterns: false,
associated_consts: false,
associated_type_defaults: false,
}
}
}
const EXPLAIN_BOX_SYNTAX: &'static str =
"box expression syntax is experimental; you can call `Box::new` instead.";
@ -802,21 +667,21 @@ const EXPLAIN_STMT_ATTR_SYNTAX: &'static str =
"attributes on non-item statements and expressions are experimental.";
pub fn check_for_box_syntax(f: Option<&Features>, diag: &Handler, span: Span) {
if let Some(&Features { allow_box: true, .. }) = f {
if let Some(&Features { box_syntax: true, .. }) = f {
return;
}
emit_feature_err(diag, "box_syntax", span, GateIssue::Language, EXPLAIN_BOX_SYNTAX);
}
pub fn check_for_placement_in(f: Option<&Features>, diag: &Handler, span: Span) {
if let Some(&Features { allow_placement_in: true, .. }) = f {
if let Some(&Features { placement_in_syntax: true, .. }) = f {
return;
}
emit_feature_err(diag, "placement_in_syntax", span, GateIssue::Language, EXPLAIN_PLACEMENT_IN);
}
pub fn check_for_pushpop_syntax(f: Option<&Features>, diag: &Handler, span: Span) {
if let Some(&Features { allow_pushpop_unsafe: true, .. }) = f {
if let Some(&Features { pushpop_unsafe: true, .. }) = f {
return;
}
emit_feature_err(diag, "pushpop_unsafe", span, GateIssue::Language, EXPLAIN_PUSHPOP_UNSAFE);
@ -895,15 +760,17 @@ impl<'a> Context<'a> {
}
fn find_lang_feature_issue(feature: &str) -> Option<u32> {
let info = KNOWN_FEATURES.iter()
.find(|t| t.0 == feature)
.unwrap();
let issue = info.2;
if let Active = info.3 {
if let Some(info) = ACTIVE_FEATURES.iter().find(|t| t.0 == feature) {
let issue = info.2;
// FIXME (#28244): enforce that active features have issue numbers
// assert!(issue.is_some())
issue
} else {
// search in Accepted or Removed features
ACCEPTED_FEATURES.iter().chain(REMOVED_FEATURES.iter())
.find(|t| t.0 == feature)
.unwrap().2
}
issue
}
pub enum GateIssue {
@ -1317,9 +1184,7 @@ fn check_crate_inner<F>(cm: &CodeMap, span_handler: &Handler,
-> Features
where F: FnOnce(&mut Context, &ast::Crate)
{
let mut accepted_features = Vec::new();
let mut unknown_features = Vec::new();
let mut enabled_features = Vec::new();
let mut features = Features::new();
for attr in &krate.attrs {
if !attr.check_name("feature") {
@ -1342,115 +1207,25 @@ fn check_crate_inner<F>(cm: &CodeMap, span_handler: &Handler,
continue
}
};
match KNOWN_FEATURES.iter()
.find(|& &(n, _, _, _)| name == n) {
Some(&(name, _, _, Active)) => {
enabled_features.push(name);
}
Some(&(_, _, _, Removed)) => {
span_handler.span_err(mi.span, "feature has been removed");
}
Some(&(_, _, _, Accepted)) => {
accepted_features.push(mi.span);
}
None => {
unknown_features.push((name, mi.span));
}
if let Some(&(_, _, _, setter)) = ACTIVE_FEATURES.iter()
.find(|& &(n, _, _, _)| name == n) {
*(setter(&mut features)) = true;
}
else if let Some(&(_, _, _)) = REMOVED_FEATURES.iter()
.find(|& &(n, _, _)| name == n) {
span_handler.span_err(mi.span, "feature has been removed");
}
else if let Some(&(_, _, _)) = ACCEPTED_FEATURES.iter()
.find(|& &(n, _, _)| name == n) {
features.declared_stable_lang_features.push(mi.span);
} else {
features.declared_lib_features.push((name, mi.span));
}
}
}
}
}
let has_feature = |feature: &str| -> bool {
enabled_features.iter().any(|&n| n == feature)
};
// FIXME (pnkfelix): Before adding the 99th entry below, change it
// to a single-pass (instead of N calls to `.has_feature`).
let features = Features {
unboxed_closures: has_feature("unboxed_closures"),
rustc_diagnostic_macros: has_feature("rustc_diagnostic_macros"),
allow_quote: has_feature("quote"),
allow_asm: has_feature("asm"),
allow_log_syntax: has_feature("log_syntax"),
allow_concat_idents: has_feature("concat_idents"),
allow_trace_macros: has_feature("trace_macros"),
allow_internal_unstable: has_feature("allow_internal_unstable"),
allow_custom_derive: has_feature("custom_derive"),
allow_placement_in: has_feature("placement_in_syntax"),
allow_box: has_feature("box_syntax"),
allow_pushpop_unsafe: has_feature("pushpop_unsafe"),
allow_inclusive_range: has_feature("inclusive_range_syntax"),
simd_ffi: has_feature("simd_ffi"),
unmarked_api: has_feature("unmarked_api"),
declared_stable_lang_features: accepted_features,
declared_lib_features: unknown_features,
const_fn: has_feature("const_fn"),
const_indexing: has_feature("const_indexing"),
static_recursion: has_feature("static_recursion"),
default_type_parameter_fallback: has_feature("default_type_parameter_fallback"),
rustc_attrs: has_feature("rustc_attrs"),
type_macros: has_feature("type_macros"),
cfg_target_feature: has_feature("cfg_target_feature"),
cfg_target_vendor: has_feature("cfg_target_vendor"),
cfg_target_thread_local: has_feature("cfg_target_thread_local"),
staged_api: has_feature("staged_api"),
stmt_expr_attributes: has_feature("stmt_expr_attributes"),
deprecated: has_feature("deprecated"),
question_mark: has_feature("question_mark"),
specialization: has_feature("specialization"),
pub_restricted: has_feature("pub_restricted"),
structural_match: has_feature("bool"),
plugin: has_feature("plugin"),
lang_items: has_feature("lang_items"),
linkage: has_feature("linkage"),
thread_local: has_feature("thread_local"),
on_unimplemented: has_feature("on_unimplemented"),
allocator: has_feature("allocator"),
needs_allocator: has_feature("needs_allocator"),
fundamental: has_feature("fundamental"),
linked_from: has_feature("linked_from"),
naked: has_feature("naked"),
no_debug: has_feature("no_debug"),
omit_gdb_pretty_printer_section: has_feature("omit_gdb_pretty_printer_section"),
dropck_parametricity: has_feature("dropck_parametricity"),
unwind_attributes: has_feature("unwind_attributes"),
prelude_import: has_feature("prelude_import"),
reflect: has_feature("reflect"),
no_core: has_feature("no_core"),
unsafe_no_drop_flag: has_feature("unsafe_no_drop_flag"),
custom_derive: has_feature("custom_derive"),
custom_attribute: has_feature("custom_attribute"),
asm: has_feature("asm"),
log_syntax: has_feature("log_syntax"),
trace_macros: has_feature("trace_macros"),
concat_idents: has_feature("concat_idents"),
box_syntax: has_feature("box_syntax"),
placement_in_syntax: has_feature("placement_in_syntax"),
non_ascii_idents: has_feature("non_ascii_idents"),
macro_reexport: has_feature("macro_reexport"),
link_args: has_feature("link_args"),
intrinsics: has_feature("intrinsics"),
platform_intrinsics: has_feature("platform_intrinsics"),
abi_vectorcall: has_feature("abi_vectorcall"),
plugin_registrar: has_feature("plugin_registrar"),
start: has_feature("start"),
main: has_feature("main"),
simd: has_feature("simd"),
repr_simd: has_feature("repr_simd"),
optin_builtin_traits: has_feature("optin_builtin_traits"),
link_llvm_intrinsics: has_feature("link_llvm_intrinsics"),
type_ascription: has_feature("type_ascription"),
inclusive_range_syntax: has_feature("inclusive_range_syntax"),
advanced_slice_patterns: has_feature("advanced_slice_patterns"),
slice_patterns: has_feature("slice_patterns"),
box_patterns: has_feature("box_patterns"),
associated_consts: has_feature("associated_consts"),
associated_type_defaults: has_feature("associated_type_defaults"),
};
let mut cx = Context {
features: features,
span_handler: span_handler,