Skip to content

Commit

Permalink
Auto merge of #53444 - varkor:lib_features-conditional, r=<try>
Browse files Browse the repository at this point in the history
[WIP] Only fetch lib_features when there are unknown feature attributes

An attempt to win back some of the performance lost in #52644 (comment).

cc @nnethercote
  • Loading branch information
bors committed Aug 17, 2018
2 parents 8b923a1 + dc30406 commit 2e13a6c
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 16 deletions.
26 changes: 21 additions & 5 deletions src/librustc/middle/lib_features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use ty::TyCtxt;
use syntax::symbol::Symbol;
use syntax::ast::{Attribute, MetaItem, MetaItemKind};
use syntax_pos::{Span, DUMMY_SP};
use hir::{Item, ItemKind};
use hir::intravisit::{self, NestedVisitorMap, Visitor};
use rustc_data_structures::fx::{FxHashSet, FxHashMap};
use errors::DiagnosticId;
Expand Down Expand Up @@ -143,6 +144,26 @@ impl<'a, 'tcx> Visitor<'tcx> for LibFeatureCollector<'a, 'tcx> {
NestedVisitorMap::All(&self.tcx.hir)
}

fn visit_item(&mut self, item: &'tcx Item) {
match item.node {
ItemKind::ExternCrate(_) => {
let def_id = self.tcx.hir.local_def_id(item.id);
let cnum = match self.tcx.extern_mod_stmt_cnum(def_id) {
Some(cnum) => cnum,
None => return,
};

for &(feature, since) in self.tcx.defined_lib_features(cnum).iter() {
self.collect_feature(feature, since, DUMMY_SP);
}
}

_ => {}
}

intravisit::walk_item(self, item);
}

fn visit_attribute(&mut self, attr: &'tcx Attribute) {
if let Some((feature, stable, span)) = self.extract(attr) {
self.collect_feature(feature, stable, span);
Expand All @@ -152,11 +173,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
}
20 changes: 11 additions & 9 deletions src/librustc/middle/stability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -846,18 +846,20 @@ 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);
if !remaining_lib_features.is_empty() {
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);
}
}
remaining_lib_features.remove(&feature);
}
remaining_lib_features.remove(&feature);
}

for (feature, span) in remaining_lib_features {
struct_span_err!(tcx.sess, span, E0635, "unknown feature `{}`", feature).emit();
for (feature, span) in remaining_lib_features {
struct_span_err!(tcx.sess, span, E0635, "unknown feature `{}`", feature).emit();
}
}

// FIXME(#44232): the `used_features` table no longer exists, so we
Expand Down
6 changes: 6 additions & 0 deletions src/test/ui/feature-gate/stability-attribute-consistency.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@
#![stable(feature = "stable_test_feature", since = "1.0.0")]

#![feature(staged_api)]
// Right now, stability attributes are only checked for consistency if we're
// collecting lib feature attributes, for performance. We collect lib
// feature attributes if there are non-lang feature attributes, or a crate
// that depends on the current one has non-lang feature attributes. Thus,
// we're enabling an arbitrary lib feature to force the check to kick in.
#![feature(rustc_private)]

#[stable(feature = "foo", since = "1.0.0")]
fn foo_stable_1_0_0() {}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
error[E0711]: feature `foo` is declared stable since 1.29.0, but was previously declared stable since 1.0.0
--> $DIR/stability-attribute-consistency.rs:18:1
--> $DIR/stability-attribute-consistency.rs:24:1
|
LL | #[stable(feature = "foo", since = "1.29.0")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0711]: feature `foo` is declared unstable, but was previously declared stable
--> $DIR/stability-attribute-consistency.rs:22:1
--> $DIR/stability-attribute-consistency.rs:28:1
|
LL | #[unstable(feature = "foo", issue = "0")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down

0 comments on commit 2e13a6c

Please sign in to comment.