diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 2d3e5a4604e0..8acf8b1032fa 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -1734,9 +1734,9 @@ declare_lint! { } declare_lint! { - pub UNKNOWN_FEATURES, + pub UNUSED_FEATURES, Deny, - "unknown features found in crate-level #[feature] directives" + "unused or unknown features found in crate-level #[feature] directives" } declare_lint! { @@ -1780,7 +1780,7 @@ impl LintPass for HardwiredLints { DEAD_CODE, UNREACHABLE_CODE, WARNINGS, - UNKNOWN_FEATURES, + UNUSED_FEATURES, UNKNOWN_CRATE_TYPES, VARIANT_SIZE_DIFFERENCES, FAT_PTR_TRANSMUTES diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 1d27352a6e3b..2682df8b2ab5 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -257,6 +257,7 @@ impl LintStore { self.register_renamed("transmute_fat_ptr", "fat_ptr_transmutes"); self.register_renamed("raw_pointer_deriving", "raw_pointer_derive"); + self.register_renamed("unknown_features", "unused_features"); } #[allow(unused_variables)] @@ -829,6 +830,5 @@ pub fn check_crate(tcx: &ty::ctxt, } } - tcx.sess.abort_if_errors(); *tcx.node_lint_levels.borrow_mut() = cx.node_levels.into_inner(); } diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 0554533a4aaa..b1f6a19ea3ed 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -12,6 +12,7 @@ //! propagating default levels lexically from parent to children ast nodes. use session::Session; +use lint; use middle::ty; use metadata::csearch; use syntax::parse::token::InternedString; @@ -25,7 +26,7 @@ use syntax::ast_util::is_local; use syntax::attr::{Stability, AttrMetaMethods}; use syntax::visit::{FnKind, FkMethod, Visitor}; use syntax::feature_gate::emit_feature_warn; -use util::nodemap::{NodeMap, DefIdMap, FnvHashSet}; +use util::nodemap::{NodeMap, DefIdMap, FnvHashSet, FnvHashMap}; use util::ppaux::Repr; use std::mem::replace; @@ -418,13 +419,20 @@ pub fn lookup(tcx: &ty::ctxt, id: DefId) -> Option { /// Given the list of enabled features that were not language features (i.e. that /// were expected to be library features), and the list of features used from /// libraries, identify activated features that don't exist and error about them. -pub fn check_unknown_features(sess: &Session, - _used_lib_features: &FnvHashSet) { - let ref _lib_features = sess.features.borrow().lib_features; - // TODO +pub fn check_unused_features(sess: &Session, + used_lib_features: &FnvHashSet) { + let ref lib_features = sess.features.borrow().lib_features; + let mut active_lib_features: FnvHashMap + = lib_features.clone().into_iter().collect(); - //sess.add_lint(lint::builtin::UNKNOWN_FEATURES, - // ast::CRATE_NODE_ID, - // *uf, - // "unknown feature".to_string()); + for used_feature in used_lib_features.iter() { + active_lib_features.remove(used_feature); + } + + for (_, &span) in active_lib_features.iter() { + sess.add_lint(lint::builtin::UNUSED_FEATURES, + ast::CRATE_NODE_ID, + span, + "unused or unknown feature".to_string()); + } } diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 384f5af6819b..4626c5216bca 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -668,14 +668,14 @@ pub fn phase_3_run_analysis_passes<'tcx>(sess: Session, time(time_passes, "stability checking", (), |_| stability::check_unstable_api_usage(&ty_cx)); - time(time_passes, "unknown feature checking", (), |_| - stability::check_unknown_features( + time(time_passes, "unused feature checking", (), |_| + stability::check_unused_features( &ty_cx.sess, lib_features_used)); time(time_passes, "lint checking", (), |_| lint::check_crate(&ty_cx, &exported_items)); - // Some of the above passes generate errors + // The above three passes generate errors w/o aborting ty_cx.sess.abort_if_errors(); ty::CrateAnalysis {