diff --git a/src/librustc/middle/lib_features.rs b/src/librustc/middle/lib_features.rs index c21ac621803..ec618de6773 100644 --- a/src/librustc/middle/lib_features.rs +++ b/src/librustc/middle/lib_features.rs @@ -17,7 +17,7 @@ use ty::TyCtxt; use syntax::symbol::Symbol; use syntax::ast::{Attribute, MetaItem, MetaItemKind}; -use syntax_pos::{Span, DUMMY_SP}; +use syntax_pos::Span; use hir::intravisit::{self, NestedVisitorMap, Visitor}; use rustc_data_structures::fx::{FxHashSet, FxHashMap}; use errors::DiagnosticId; @@ -152,11 +152,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LibFeatureCollector<'a, 'tcx> { pub fn collect<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> LibFeatures { let mut collector = LibFeatureCollector::new(tcx); - for &cnum in tcx.crates().iter() { - for &(feature, since) in tcx.defined_lib_features(cnum).iter() { - collector.collect_feature(feature, since, DUMMY_SP); - } - } intravisit::walk_crate(&mut collector, tcx.hir.krate()); collector.lib_features } diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index efd568b03ab..85195b0f62e 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -846,14 +846,34 @@ pub fn check_unused_or_stable_features<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { remaining_lib_features.remove(&Symbol::intern("libc")); remaining_lib_features.remove(&Symbol::intern("test")); - for (feature, stable) in tcx.lib_features().to_vec() { - if let Some(since) = stable { - if let Some(span) = remaining_lib_features.get(&feature) { - // Warn if the user has enabled an already-stable lib feature. - unnecessary_stable_feature_lint(tcx, *span, feature, since); + let check_features = + |remaining_lib_features: &mut FxHashMap<_, _>, defined_features: &Vec<_>| { + for &(feature, since) in defined_features { + if let Some(since) = since { + if let Some(span) = remaining_lib_features.get(&feature) { + // Warn if the user has enabled an already-stable lib feature. + unnecessary_stable_feature_lint(tcx, *span, feature, since); + } + } + remaining_lib_features.remove(&feature); + if remaining_lib_features.is_empty() { + break; + } } + }; + + // We always collect the lib features declared in the current crate, even if there are + // no unknown features, because the collection also does feature attribute validation. + let local_defined_features = tcx.lib_features().to_vec(); + if !remaining_lib_features.is_empty() { + check_features(&mut remaining_lib_features, &local_defined_features); + + for &cnum in &*tcx.crates() { + if remaining_lib_features.is_empty() { + break; + } + check_features(&mut remaining_lib_features, &tcx.defined_lib_features(cnum)); } - remaining_lib_features.remove(&feature); } for (feature, span) in remaining_lib_features {