Skip to content

Commit 86319f7

Browse files
committed
Rollup merge of #33973 - zackmdavis:stable_features_warning_notes_version_stabilized, r=brson
stable features lint warning mentions version stabilized To accomplish this, we alter the checks in `rustc::middle::stability` to use the `StabilityLevel` defined in `syntax::attr` (which includes the version in which the feature was stabilized) rather than the local `StabilityLevel` in the same module, and make the `declared_stable_lang_features` field of `syntax::feature_gate::Features` hold a Vec of feature-name, span tuples (in analogy to the `declared_lib_features` field) rather than just spans. Fixes #33394. ![stable_features_version_lint_before_and_after](https://cloud.githubusercontent.com/assets/1076988/15659237/5d952a3a-267c-11e6-9181-c9e612eefd7d.png) r? @brson (tagging Brian because he [wrote](#21958) the lint)
2 parents e214c3e + 06c9e0f commit 86319f7

File tree

3 files changed

+26
-16
lines changed

3 files changed

+26
-16
lines changed

src/librustc/middle/stability.rs

+17-11
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use syntax::parse::token::InternedString;
2626
use syntax::codemap::{Span, DUMMY_SP};
2727
use syntax::ast;
2828
use syntax::ast::{NodeId, Attribute};
29-
use syntax::feature_gate::{GateIssue, emit_feature_err};
29+
use syntax::feature_gate::{GateIssue, emit_feature_err, find_lang_feature_accepted_version};
3030
use syntax::attr::{self, Stability, Deprecation, AttrMetaMethods};
3131
use util::nodemap::{DefIdMap, FnvHashSet, FnvHashMap};
3232

@@ -37,6 +37,7 @@ use hir::pat_util::EnumerateAndAdjustIterator;
3737

3838
use std::mem::replace;
3939
use std::cmp::Ordering;
40+
use std::ops::Deref;
4041

4142
#[derive(RustcEncodable, RustcDecodable, PartialEq, PartialOrd, Clone, Copy, Debug, Eq, Hash)]
4243
pub enum StabilityLevel {
@@ -322,7 +323,7 @@ impl<'a, 'tcx> Index<'tcx> {
322323
/// features and possibly prints errors. Returns a list of all
323324
/// features used.
324325
pub fn check_unstable_api_usage<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>)
325-
-> FnvHashMap<InternedString, StabilityLevel> {
326+
-> FnvHashMap<InternedString, attr::StabilityLevel> {
326327
let _task = tcx.dep_graph.in_task(DepNode::StabilityCheck);
327328
let ref active_lib_features = tcx.sess.features.borrow().declared_lib_features;
328329

@@ -343,7 +344,7 @@ pub fn check_unstable_api_usage<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>)
343344
struct Checker<'a, 'tcx: 'a> {
344345
tcx: TyCtxt<'a, 'tcx, 'tcx>,
345346
active_features: FnvHashSet<InternedString>,
346-
used_features: FnvHashMap<InternedString, StabilityLevel>,
347+
used_features: FnvHashMap<InternedString, attr::StabilityLevel>,
347348
// Within a block where feature gate checking can be skipped.
348349
in_skip_block: u32,
349350
}
@@ -367,7 +368,8 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
367368

368369
match *stab {
369370
Some(&Stability { level: attr::Unstable {ref reason, issue}, ref feature, .. }) => {
370-
self.used_features.insert(feature.clone(), Unstable);
371+
self.used_features.insert(feature.clone(),
372+
attr::Unstable { reason: reason.clone(), issue: issue });
371373

372374
if !self.active_features.contains(feature) {
373375
let msg = match *reason {
@@ -380,7 +382,7 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
380382
}
381383
}
382384
Some(&Stability { ref level, ref feature, .. }) => {
383-
self.used_features.insert(feature.clone(), StabilityLevel::from_attr_level(level));
385+
self.used_features.insert(feature.clone(), level.clone());
384386

385387
// Stable APIs are always ok to call and deprecated APIs are
386388
// handled by a lint.
@@ -716,28 +718,32 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
716718
/// libraries, identify activated features that don't exist and error about them.
717719
pub fn check_unused_or_stable_features(sess: &Session,
718720
lib_features_used: &FnvHashMap<InternedString,
719-
StabilityLevel>) {
721+
attr::StabilityLevel>) {
720722
let ref declared_lib_features = sess.features.borrow().declared_lib_features;
721723
let mut remaining_lib_features: FnvHashMap<InternedString, Span>
722724
= declared_lib_features.clone().into_iter().collect();
723725

724-
let stable_msg = "this feature is stable. attribute no longer needed";
726+
fn format_stable_since_msg(version: &str) -> String {
727+
format!("this feature has been stable since {}. Attribute no longer needed", version)
728+
}
725729

726-
for &span in &sess.features.borrow().declared_stable_lang_features {
730+
for &(ref stable_lang_feature, span) in &sess.features.borrow().declared_stable_lang_features {
731+
let version = find_lang_feature_accepted_version(stable_lang_feature.deref())
732+
.expect("unexpectedly couldn't find version feature was stabilized");
727733
sess.add_lint(lint::builtin::STABLE_FEATURES,
728734
ast::CRATE_NODE_ID,
729735
span,
730-
stable_msg.to_string());
736+
format_stable_since_msg(version));
731737
}
732738

733739
for (used_lib_feature, level) in lib_features_used {
734740
match remaining_lib_features.remove(used_lib_feature) {
735741
Some(span) => {
736-
if *level == Stable {
742+
if let &attr::StabilityLevel::Stable { since: ref version } = level {
737743
sess.add_lint(lint::builtin::STABLE_FEATURES,
738744
ast::CRATE_NODE_ID,
739745
span,
740-
stable_msg.to_string());
746+
format_stable_since_msg(version.deref()));
741747
}
742748
}
743749
None => ( /* used but undeclared, handled during the previous ast visit */ )

src/libsyntax/feature_gate.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ macro_rules! declare_features {
5959

6060
/// A set of features to be used by later passes.
6161
pub struct Features {
62-
/// spans of #![feature] attrs for stable language features. for error reporting
63-
pub declared_stable_lang_features: Vec<Span>,
62+
/// #![feature] attrs for stable language features, for error reporting
63+
pub declared_stable_lang_features: Vec<(InternedString, Span)>,
6464
/// #![feature] attrs for non-language (library) features
6565
pub declared_lib_features: Vec<(InternedString, Span)>,
6666
$(pub $feature: bool),+
@@ -753,6 +753,10 @@ pub fn check_attribute(attr: &ast::Attribute, handler: &Handler,
753753
cx.check_attribute(attr, true);
754754
}
755755

756+
pub fn find_lang_feature_accepted_version(feature: &str) -> Option<&'static str> {
757+
ACCEPTED_FEATURES.iter().find(|t| t.0 == feature).map(|t| t.1)
758+
}
759+
756760
fn find_lang_feature_issue(feature: &str) -> Option<u32> {
757761
if let Some(info) = ACTIVE_FEATURES.iter().find(|t| t.0 == feature) {
758762
let issue = info.2;
@@ -1191,7 +1195,7 @@ pub fn get_features(span_handler: &Handler, krate: &ast::Crate) -> Features {
11911195
}
11921196
else if let Some(&(_, _, _)) = ACCEPTED_FEATURES.iter()
11931197
.find(|& &(n, _, _)| name == n) {
1194-
features.declared_stable_lang_features.push(mi.span);
1198+
features.declared_stable_lang_features.push((name, mi.span));
11951199
} else {
11961200
features.declared_lib_features.push((name, mi.span));
11971201
}

src/test/compile-fail/stable-features.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
// language and lib features.
1313

1414
#![deny(stable_features)]
15-
#![feature(test_accepted_feature)] //~ ERROR this feature is stable
16-
#![feature(rust1)] //~ ERROR this feature is stable
15+
#![feature(test_accepted_feature)] //~ ERROR this feature has been stable since 1.0.0
16+
#![feature(rust1)] //~ ERROR this feature has been stable since 1.0.0
1717

1818
fn main() {
1919
let _foo: Vec<()> = Vec::new();

0 commit comments

Comments
 (0)