Skip to content

Commit 60ad636

Browse files
committed
Add an error when declaring features that are stable in the current Rust edition
1 parent d198321 commit 60ad636

File tree

4 files changed

+79
-22
lines changed

4 files changed

+79
-22
lines changed

src/libsyntax/diagnostic_list.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,20 @@ and likely to change in the future.
374374
375375
"##,
376376

377+
E0705: r##"
378+
A `#![feature]` attribute was declared for a feature that is stable in
379+
the current edition.
380+
381+
Erroneous code example:
382+
383+
```compile_fail,E0705
384+
#![allow(rust_2018_preview)]
385+
#![feature(raw_identifiers)] // error: the feature `raw_identifiers` is
386+
// included in the Rust 2018 edition
387+
```
388+
389+
"##,
390+
377391
}
378392

379393
register_diagnostics! {

src/libsyntax/feature_gate.rs

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
use self::AttributeType::*;
2626
use self::AttributeGate::*;
2727

28+
use rustc_data_structures::fx::FxHashMap;
2829
use rustc_target::spec::abi::Abi;
2930
use ast::{self, NodeId, PatKind, RangeEnd};
3031
use attr;
@@ -1900,10 +1901,13 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
19001901

19011902
let mut feature_checker = FeatureChecker::default();
19021903

1903-
for &(.., f_edition, set) in ACTIVE_FEATURES.iter() {
1904+
let mut edition_enabled_features = FxHashMap();
1905+
1906+
for &(name, .., f_edition, set) in ACTIVE_FEATURES.iter() {
19041907
if let Some(f_edition) = f_edition {
19051908
if f_edition <= crate_edition {
19061909
set(&mut features, DUMMY_SP);
1910+
edition_enabled_features.insert(Symbol::intern(name), crate_edition);
19071911
}
19081912
}
19091913
}
@@ -1931,10 +1935,40 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
19311935
continue
19321936
};
19331937

1938+
if let Some(edition) = ALL_EDITIONS.iter().find(|e| name == e.feature_name()) {
1939+
if *edition <= crate_edition {
1940+
continue
1941+
}
1942+
1943+
for &(name, .., f_edition, set) in ACTIVE_FEATURES.iter() {
1944+
if let Some(f_edition) = f_edition {
1945+
if f_edition <= *edition {
1946+
// FIXME(Manishearth) there is currently no way to set
1947+
// lib features by edition
1948+
set(&mut features, DUMMY_SP);
1949+
edition_enabled_features.insert(Symbol::intern(name), *edition);
1950+
}
1951+
}
1952+
}
1953+
1954+
continue
1955+
}
1956+
19341957
if let Some((.., set)) = ACTIVE_FEATURES.iter().find(|f| name == f.0) {
1935-
set(&mut features, mi.span);
1936-
feature_checker.collect(&features, mi.span);
1937-
features.declared_lang_features.push((name, mi.span, None));
1958+
if let Some(edition) = edition_enabled_features.get(&name) {
1959+
struct_span_err!(
1960+
span_handler,
1961+
mi.span,
1962+
E0705,
1963+
"the feature `{}` is included in the Rust {} edition",
1964+
name,
1965+
edition,
1966+
).emit();
1967+
} else {
1968+
set(&mut features, mi.span);
1969+
feature_checker.collect(&features, mi.span);
1970+
features.declared_lang_features.push((name, mi.span, None));
1971+
}
19381972
continue
19391973
}
19401974

@@ -1951,24 +1985,6 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
19511985
continue
19521986
}
19531987

1954-
if let Some(edition) = ALL_EDITIONS.iter().find(|e| name == e.feature_name()) {
1955-
if *edition <= crate_edition {
1956-
continue
1957-
}
1958-
1959-
for &(.., f_edition, set) in ACTIVE_FEATURES.iter() {
1960-
if let Some(f_edition) = f_edition {
1961-
if *edition >= f_edition {
1962-
// FIXME(Manishearth) there is currently no way to set
1963-
// lib features by edition
1964-
set(&mut features, DUMMY_SP);
1965-
}
1966-
}
1967-
}
1968-
1969-
continue
1970-
}
1971-
19721988
features.declared_lib_features.push((name, mi.span));
19731989
}
19741990
}

src/test/ui/E0705.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![feature(rust_2018_preview)]
12+
#![feature(raw_identifiers)]
13+
//~^ ERROR the feature `raw_identifiers` is included in the Rust 2018 edition
14+
15+
fn main() {
16+
let foo = 0;
17+
let bar = r#foo;
18+
}

src/test/ui/E0705.stderr

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0705]: the feature `raw_identifiers` is included in the Rust 2018 edition
2+
--> $DIR/E0705.rs:12:12
3+
|
4+
LL | #![feature(raw_identifiers)]
5+
| ^^^^^^^^^^^^^^^
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0705`.

0 commit comments

Comments
 (0)