diff --git a/src/libsyntax/diagnostic_list.rs b/src/libsyntax/diagnostic_list.rs index 8534969c623bc..bfbe9ef1fee46 100644 --- a/src/libsyntax/diagnostic_list.rs +++ b/src/libsyntax/diagnostic_list.rs @@ -374,6 +374,20 @@ and likely to change in the future. "##, +E0705: r##" +A `#![feature]` attribute was declared for a feature that is stable in +the current edition. + +Erroneous code example: + +```compile_fail,E0705 +#![allow(rust_2018_preview)] +#![feature(raw_identifiers)] // error: the feature `raw_identifiers` is + // included in the Rust 2018 edition +``` + +"##, + } register_diagnostics! { diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 833b6953dcd3c..0014fd5ae48b3 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -25,6 +25,7 @@ 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; @@ -1900,10 +1901,13 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], 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); } } } @@ -1931,10 +1935,40 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], 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_err!( + 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 } @@ -1951,24 +1985,6 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], 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)); } } diff --git a/src/test/ui/E0705.rs b/src/test/ui/E0705.rs new file mode 100644 index 0000000000000..743c108bb6854 --- /dev/null +++ b/src/test/ui/E0705.rs @@ -0,0 +1,18 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(rust_2018_preview)] +#![feature(raw_identifiers)] +//~^ ERROR the feature `raw_identifiers` is included in the Rust 2018 edition + +fn main() { + let foo = 0; + let bar = r#foo; +} diff --git a/src/test/ui/E0705.stderr b/src/test/ui/E0705.stderr new file mode 100644 index 0000000000000..cab443a213725 --- /dev/null +++ b/src/test/ui/E0705.stderr @@ -0,0 +1,9 @@ +error[E0705]: the feature `raw_identifiers` is included in the Rust 2018 edition + --> $DIR/E0705.rs:12:12 + | +LL | #![feature(raw_identifiers)] + | ^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0705`.