use self::AttributeType::*;
use self::AttributeGate::*;
+use rustc_data_structures::fx::FxHashMap;
use rustc_target::spec::abi::Abi;
use ast::{self, NodeId, PatKind, RangeEnd};
use attr;
// Allows let bindings and destructuring in `const fn` functions and constants.
(active, const_let, "1.22.1", Some(48821), None),
+ // Allows accessing fields of unions inside const fn
+ (active, const_fn_union, "1.27.0", Some(51909), None),
+
+ // Allows casting raw pointers to `usize` during const eval
+ (active, const_raw_ptr_to_usize_cast, "1.27.0", Some(51910), None),
+
+ // Allows dereferencing raw pointers during const eval
+ (active, const_raw_ptr_deref, "1.27.0", Some(51911), None),
+
+ // Allows comparing raw pointers during const eval
+ (active, const_compare_raw_pointers, "1.27.0", Some(53020), None),
+
// Allows using #[prelude_import] on glob `use` items.
//
// rustc internal
// `extern "x86-interrupt" fn()`
(active, abi_x86_interrupt, "1.17.0", Some(40180), None),
-
// Allows the `catch {...}` expression
- (active, catch_expr, "1.17.0", Some(31436), Some(Edition::Edition2018)),
+ (active, catch_expr, "1.17.0", Some(31436), None),
// Used to preserve symbols (see llvm.used)
(active, used, "1.18.0", Some(40289), None),
(active, crate_in_paths, "1.23.0", Some(45477), Some(Edition::Edition2018)),
// In-band lifetime bindings (e.g. `fn foo(x: &'a u8) -> &'a u8`)
- (active, in_band_lifetimes, "1.23.0", Some(44524), Some(Edition::Edition2018)),
+ (active, in_band_lifetimes, "1.23.0", Some(44524), None),
// generic associated types (RFC 1598)
(active, generic_associated_types, "1.23.0", Some(44265), None),
(active, alloc_error_handler, "1.29.0", Some(51540), None),
(active, abi_amdgpu_kernel, "1.29.0", Some(51575), None),
+
+ // impl<I:Iterator> Iterator for &mut Iterator
+ // impl Debug for Foo<'_>
+ (active, impl_header_lifetime_elision, "1.30.0", Some(15872), Some(Edition::Edition2018)),
);
declare_features! (
let mut feature_checker = FeatureChecker::default();
- for &(.., f_edition, set) in ACTIVE_FEATURES.iter() {
+ let mut edition_enabled_features = FxHashMap();
+
+ for &(name, .., f_edition, set) in ACTIVE_FEATURES.iter() {
if let Some(f_edition) = f_edition {
if f_edition <= crate_edition {
set(&mut features, DUMMY_SP);
+ edition_enabled_features.insert(Symbol::intern(name), crate_edition);
}
}
}
continue
};
+ if let Some(edition) = ALL_EDITIONS.iter().find(|e| name == e.feature_name()) {
+ if *edition <= crate_edition {
+ continue
+ }
+
+ for &(name, .., f_edition, set) in ACTIVE_FEATURES.iter() {
+ if let Some(f_edition) = f_edition {
+ if f_edition <= *edition {
+ // FIXME(Manishearth) there is currently no way to set
+ // lib features by edition
+ set(&mut features, DUMMY_SP);
+ edition_enabled_features.insert(Symbol::intern(name), *edition);
+ }
+ }
+ }
+
+ continue
+ }
+
if let Some((.., set)) = ACTIVE_FEATURES.iter().find(|f| name == f.0) {
- set(&mut features, mi.span);
- feature_checker.collect(&features, mi.span);
- features.declared_lang_features.push((name, mi.span, None));
+ if let Some(edition) = edition_enabled_features.get(&name) {
+ struct_span_warn!(
+ span_handler,
+ mi.span,
+ E0705,
+ "the feature `{}` is included in the Rust {} edition",
+ name,
+ edition,
+ ).emit();
+ } else {
+ set(&mut features, mi.span);
+ feature_checker.collect(&features, mi.span);
+ features.declared_lang_features.push((name, mi.span, None));
+ }
continue
}
continue
}
- if let Some(edition) = ALL_EDITIONS.iter().find(|e| name == e.feature_name()) {
- if *edition <= crate_edition {
- continue
- }
-
- for &(.., f_edition, set) in ACTIVE_FEATURES.iter() {
- if let Some(f_edition) = f_edition {
- if *edition >= f_edition {
- // FIXME(Manishearth) there is currently no way to set
- // lib features by edition
- set(&mut features, DUMMY_SP);
- }
- }
- }
-
- continue
- }
-
features.declared_lib_features.push((name, mi.span));
}
}