Turn the duplicate feature lint into an error
This commit is contained in:
parent
c81b95f305
commit
47619c0dc7
6 changed files with 46 additions and 48 deletions
|
@ -1918,6 +1918,19 @@ fn foo<'a>(x: &'a i32, y: &i32) -> &'a i32 {
|
|||
```
|
||||
"##,
|
||||
|
||||
E0636: r##"
|
||||
A `#![feature]` attribute was declared multiple times.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0636
|
||||
#![allow(stable_features)]
|
||||
#![feature(rust1)]
|
||||
#![feature(rust1)] // error: the feature `rust1` has already been declared
|
||||
```
|
||||
|
||||
"##,
|
||||
|
||||
E0644: r##"
|
||||
A closure or generator was constructed that references its own type.
|
||||
|
||||
|
|
|
@ -111,12 +111,6 @@ declare_lint! {
|
|||
"unknown features found in crate-level #[feature] directives"
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
pub DUPLICATE_FEATURES,
|
||||
Deny,
|
||||
"duplicate features found in crate-level #[feature] directives"
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
pub STABLE_FEATURES,
|
||||
Warn,
|
||||
|
@ -375,7 +369,6 @@ impl LintPass for HardwiredLints {
|
|||
WARNINGS,
|
||||
UNUSED_FEATURES,
|
||||
UNKNOWN_FEATURES,
|
||||
DUPLICATE_FEATURES,
|
||||
STABLE_FEATURES,
|
||||
UNKNOWN_CRATE_TYPES,
|
||||
TRIVIAL_CASTS,
|
||||
|
|
|
@ -18,7 +18,7 @@ use hir::def::Def;
|
|||
use hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId, LOCAL_CRATE};
|
||||
use ty::{self, TyCtxt};
|
||||
use middle::privacy::AccessLevels;
|
||||
use session::DiagnosticMessageId;
|
||||
use session::{DiagnosticMessageId, Session};
|
||||
use syntax::symbol::Symbol;
|
||||
use syntax_pos::{Span, MultiSpan};
|
||||
use syntax::ast;
|
||||
|
@ -816,20 +816,14 @@ pub fn check_unused_or_stable_features<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
|
|||
|
||||
let declared_lang_features = &tcx.features().declared_lang_features;
|
||||
let mut lang_features = FxHashSet();
|
||||
for &(ref feature, span, since) in declared_lang_features {
|
||||
for &(feature, span, since) in declared_lang_features {
|
||||
if let Some(since) = since {
|
||||
// Warn if the user has enabled an already-stable lang feature.
|
||||
tcx.lint_node(lint::builtin::STABLE_FEATURES,
|
||||
ast::CRATE_NODE_ID,
|
||||
span,
|
||||
&format_stable_since_msg(*feature, since));
|
||||
unnecessary_stable_feature_lint(tcx, span, feature, since);
|
||||
}
|
||||
if lang_features.contains(&feature) {
|
||||
// Warn if the user enables a lang feature multiple times.
|
||||
tcx.lint_node(lint::builtin::DUPLICATE_FEATURES,
|
||||
ast::CRATE_NODE_ID,
|
||||
span,
|
||||
&format!("duplicate `{}` feature attribute", feature));
|
||||
duplicate_feature_err(tcx.sess, span, feature);
|
||||
}
|
||||
lang_features.insert(feature);
|
||||
}
|
||||
|
@ -837,12 +831,9 @@ pub fn check_unused_or_stable_features<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
|
|||
let declared_lib_features = &tcx.features().declared_lib_features;
|
||||
let mut remaining_lib_features = FxHashMap();
|
||||
for (feature, span) in declared_lib_features {
|
||||
// Warn if the user enables a lib feature multiple times.
|
||||
if remaining_lib_features.contains_key(&feature) {
|
||||
tcx.lint_node(lint::builtin::DUPLICATE_FEATURES,
|
||||
ast::CRATE_NODE_ID,
|
||||
*span,
|
||||
&format!("duplicate `{}` feature attribute", feature));
|
||||
// Warn if the user enables a lib feature multiple times.
|
||||
duplicate_feature_err(tcx.sess, *span, *feature);
|
||||
}
|
||||
remaining_lib_features.insert(feature, span.clone());
|
||||
}
|
||||
|
@ -851,16 +842,12 @@ pub fn check_unused_or_stable_features<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
|
|||
remaining_lib_features.remove(&Symbol::intern("libc"));
|
||||
|
||||
for (feature, stable) in tcx.lib_features().iter() {
|
||||
// Warn if the user has enabled an already-stable lib feature.
|
||||
if let Some(since) = stable {
|
||||
if let Some(span) = remaining_lib_features.get(&feature) {
|
||||
tcx.lint_node(lint::builtin::STABLE_FEATURES,
|
||||
ast::CRATE_NODE_ID,
|
||||
*span,
|
||||
&format_stable_since_msg(feature, since));
|
||||
// Warn if the user has enabled an already-stable lib feature.
|
||||
unnecessary_stable_feature_lint(tcx, *span, feature, since);
|
||||
}
|
||||
}
|
||||
|
||||
remaining_lib_features.remove(&feature);
|
||||
}
|
||||
|
||||
|
@ -875,8 +862,20 @@ pub fn check_unused_or_stable_features<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
|
|||
// don't lint about unused features. We should reenable this one day!
|
||||
}
|
||||
|
||||
fn format_stable_since_msg(feature: Symbol, since: Symbol) -> String {
|
||||
// "this feature has been stable since {}. Attribute no longer needed"
|
||||
format!("the feature `{}` has been stable since {} and no longer requires \
|
||||
an attribute to enable", feature, since)
|
||||
fn unnecessary_stable_feature_lint<'a, 'tcx>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
span: Span,
|
||||
feature: Symbol,
|
||||
since: Symbol
|
||||
) {
|
||||
tcx.lint_node(lint::builtin::STABLE_FEATURES,
|
||||
ast::CRATE_NODE_ID,
|
||||
span,
|
||||
&format!("the feature `{}` has been stable since {} and no longer requires \
|
||||
an attribute to enable", feature, since));
|
||||
}
|
||||
|
||||
fn duplicate_feature_err(sess: &Session, span: Span, feature: Symbol) {
|
||||
struct_span_err!(sess, span, E0636, "the feature `{}` has already been declared", feature)
|
||||
.emit();
|
||||
}
|
||||
|
|
|
@ -189,7 +189,6 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
|
|||
UNUSED_EXTERN_CRATES,
|
||||
UNUSED_FEATURES,
|
||||
UNKNOWN_FEATURES,
|
||||
DUPLICATE_FEATURES,
|
||||
UNUSED_LABELS,
|
||||
UNUSED_PARENS);
|
||||
|
||||
|
|
|
@ -9,12 +9,11 @@
|
|||
// except according to those terms.
|
||||
|
||||
#![allow(stable_features)]
|
||||
#![deny(duplicate_features)]
|
||||
|
||||
#![feature(rust1)]
|
||||
#![feature(rust1)] //~ ERROR duplicate `rust1` feature attribute
|
||||
#![feature(rust1)] //~ ERROR the feature `rust1` has already been declared
|
||||
|
||||
#![feature(if_let)]
|
||||
#![feature(if_let)] //~ ERROR duplicate `if_let` feature attribute
|
||||
#![feature(if_let)] //~ ERROR the feature `if_let` has already been declared
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,20 +1,15 @@
|
|||
error: duplicate `if_let` feature attribute
|
||||
--> $DIR/duplicate-features.rs:18:12
|
||||
error[E0636]: the feature `if_let` has already been declared
|
||||
--> $DIR/duplicate-features.rs:17:12
|
||||
|
|
||||
LL | #![feature(if_let)] //~ ERROR duplicate `if_let` feature attribute
|
||||
LL | #![feature(if_let)] //~ ERROR the feature `if_let` has already been declared
|
||||
| ^^^^^^
|
||||
|
|
||||
note: lint level defined here
|
||||
--> $DIR/duplicate-features.rs:12:9
|
||||
|
|
||||
LL | #![deny(duplicate_features)]
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: duplicate `rust1` feature attribute
|
||||
--> $DIR/duplicate-features.rs:15:12
|
||||
error[E0636]: the feature `rust1` has already been declared
|
||||
--> $DIR/duplicate-features.rs:14:12
|
||||
|
|
||||
LL | #![feature(rust1)] //~ ERROR duplicate `rust1` feature attribute
|
||||
LL | #![feature(rust1)] //~ ERROR the feature `rust1` has already been declared
|
||||
| ^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0636`.
|
||||
|
|
Loading…
Add table
Reference in a new issue