Add an error when declaring features that are stable in the current Rust edition
This commit is contained in:
parent
d19832105e
commit
60ad63640f
4 changed files with 79 additions and 22 deletions
|
@ -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! {
|
register_diagnostics! {
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
use self::AttributeType::*;
|
use self::AttributeType::*;
|
||||||
use self::AttributeGate::*;
|
use self::AttributeGate::*;
|
||||||
|
|
||||||
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_target::spec::abi::Abi;
|
use rustc_target::spec::abi::Abi;
|
||||||
use ast::{self, NodeId, PatKind, RangeEnd};
|
use ast::{self, NodeId, PatKind, RangeEnd};
|
||||||
use attr;
|
use attr;
|
||||||
|
@ -1900,10 +1901,13 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
|
||||||
|
|
||||||
let mut feature_checker = FeatureChecker::default();
|
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 let Some(f_edition) = f_edition {
|
||||||
if f_edition <= crate_edition {
|
if f_edition <= crate_edition {
|
||||||
set(&mut features, DUMMY_SP);
|
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
|
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) {
|
if let Some((.., set)) = ACTIVE_FEATURES.iter().find(|f| name == f.0) {
|
||||||
set(&mut features, mi.span);
|
if let Some(edition) = edition_enabled_features.get(&name) {
|
||||||
feature_checker.collect(&features, mi.span);
|
struct_span_err!(
|
||||||
features.declared_lang_features.push((name, mi.span, None));
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1951,24 +1985,6 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
|
||||||
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));
|
features.declared_lib_features.push((name, mi.span));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
18
src/test/ui/E0705.rs
Normal file
18
src/test/ui/E0705.rs
Normal file
|
@ -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 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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;
|
||||||
|
}
|
9
src/test/ui/E0705.stderr
Normal file
9
src/test/ui/E0705.stderr
Normal file
|
@ -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`.
|
Loading…
Add table
Add a link
Reference in a new issue