Skip to content

Commit 2e13a6c

Browse files
committed
Auto merge of #53444 - varkor:lib_features-conditional, r=<try>
[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
2 parents 8b923a1 + dc30406 commit 2e13a6c

File tree

4 files changed

+40
-16
lines changed

4 files changed

+40
-16
lines changed

src/librustc/middle/lib_features.rs

+21-5
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use ty::TyCtxt;
1818
use syntax::symbol::Symbol;
1919
use syntax::ast::{Attribute, MetaItem, MetaItemKind};
2020
use syntax_pos::{Span, DUMMY_SP};
21+
use hir::{Item, ItemKind};
2122
use hir::intravisit::{self, NestedVisitorMap, Visitor};
2223
use rustc_data_structures::fx::{FxHashSet, FxHashMap};
2324
use errors::DiagnosticId;
@@ -143,6 +144,26 @@ impl<'a, 'tcx> Visitor<'tcx> for LibFeatureCollector<'a, 'tcx> {
143144
NestedVisitorMap::All(&self.tcx.hir)
144145
}
145146

147+
fn visit_item(&mut self, item: &'tcx Item) {
148+
match item.node {
149+
ItemKind::ExternCrate(_) => {
150+
let def_id = self.tcx.hir.local_def_id(item.id);
151+
let cnum = match self.tcx.extern_mod_stmt_cnum(def_id) {
152+
Some(cnum) => cnum,
153+
None => return,
154+
};
155+
156+
for &(feature, since) in self.tcx.defined_lib_features(cnum).iter() {
157+
self.collect_feature(feature, since, DUMMY_SP);
158+
}
159+
}
160+
161+
_ => {}
162+
}
163+
164+
intravisit::walk_item(self, item);
165+
}
166+
146167
fn visit_attribute(&mut self, attr: &'tcx Attribute) {
147168
if let Some((feature, stable, span)) = self.extract(attr) {
148169
self.collect_feature(feature, stable, span);
@@ -152,11 +173,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LibFeatureCollector<'a, 'tcx> {
152173

153174
pub fn collect<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> LibFeatures {
154175
let mut collector = LibFeatureCollector::new(tcx);
155-
for &cnum in tcx.crates().iter() {
156-
for &(feature, since) in tcx.defined_lib_features(cnum).iter() {
157-
collector.collect_feature(feature, since, DUMMY_SP);
158-
}
159-
}
160176
intravisit::walk_crate(&mut collector, tcx.hir.krate());
161177
collector.lib_features
162178
}

src/librustc/middle/stability.rs

+11-9
Original file line numberDiff line numberDiff line change
@@ -846,18 +846,20 @@ pub fn check_unused_or_stable_features<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
846846
remaining_lib_features.remove(&Symbol::intern("libc"));
847847
remaining_lib_features.remove(&Symbol::intern("test"));
848848

849-
for (feature, stable) in tcx.lib_features().to_vec() {
850-
if let Some(since) = stable {
851-
if let Some(span) = remaining_lib_features.get(&feature) {
852-
// Warn if the user has enabled an already-stable lib feature.
853-
unnecessary_stable_feature_lint(tcx, *span, feature, since);
849+
if !remaining_lib_features.is_empty() {
850+
for (feature, stable) in tcx.lib_features().to_vec() {
851+
if let Some(since) = stable {
852+
if let Some(span) = remaining_lib_features.get(&feature) {
853+
// Warn if the user has enabled an already-stable lib feature.
854+
unnecessary_stable_feature_lint(tcx, *span, feature, since);
855+
}
854856
}
857+
remaining_lib_features.remove(&feature);
855858
}
856-
remaining_lib_features.remove(&feature);
857-
}
858859

859-
for (feature, span) in remaining_lib_features {
860-
struct_span_err!(tcx.sess, span, E0635, "unknown feature `{}`", feature).emit();
860+
for (feature, span) in remaining_lib_features {
861+
struct_span_err!(tcx.sess, span, E0635, "unknown feature `{}`", feature).emit();
862+
}
861863
}
862864

863865
// FIXME(#44232): the `used_features` table no longer exists, so we

src/test/ui/feature-gate/stability-attribute-consistency.rs

+6
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@
1111
#![stable(feature = "stable_test_feature", since = "1.0.0")]
1212

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

1521
#[stable(feature = "foo", since = "1.0.0")]
1622
fn foo_stable_1_0_0() {}

src/test/ui/feature-gate/stability-attribute-consistency.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error[E0711]: feature `foo` is declared stable since 1.29.0, but was previously declared stable since 1.0.0
2-
--> $DIR/stability-attribute-consistency.rs:18:1
2+
--> $DIR/stability-attribute-consistency.rs:24:1
33
|
44
LL | #[stable(feature = "foo", since = "1.29.0")]
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
66

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

0 commit comments

Comments
 (0)