Introduce tidy lint to check for inconsistent tracking issues

This commit
    * Refactors the collect_lib_features function to work in a
      non-checking mode (no bad pointer needed, and list of
      lang features).
    * Introduces checking whether unstable/stable tags for a
      given feature have inconsistent tracking issues.
    * Fixes such inconsistencies throughout the codebase.
This commit is contained in:
est31 2017-06-16 19:58:37 +02:00
parent b40be00a0c
commit c6afde6c46
11 changed files with 78 additions and 43 deletions

View File

@ -428,7 +428,7 @@ impl Rc<str> {
#[doc(hidden)]
#[unstable(feature = "rustc_private",
reason = "for internal use in rustc",
issue = "0")]
issue = "27812")]
pub fn __from_str(value: &str) -> Rc<str> {
unsafe {
// Allocate enough space for `RcBox<str>`.
@ -453,7 +453,7 @@ impl<T> Rc<[T]> {
#[doc(hidden)]
#[unstable(feature = "rustc_private",
reason = "for internal use in rustc",
issue = "0")]
issue = "27812")]
pub fn __from_array(value: Box<[T]>) -> Rc<[T]> {
unsafe {
let ptr: *mut RcBox<[T]> =

View File

@ -99,7 +99,7 @@ use mem;
#[allow(deprecated)]
pub use self::sip::SipHasher;
#[unstable(feature = "sip_hash_13", issue = "29754")]
#[unstable(feature = "sip_hash_13", issue = "34767")]
#[allow(deprecated)]
pub use self::sip::{SipHasher13, SipHasher24};

View File

@ -2085,7 +2085,7 @@ pub trait StrExt {
fn is_char_boundary(&self, index: usize) -> bool;
#[stable(feature = "core", since = "1.6.0")]
fn as_bytes(&self) -> &[u8];
#[unstable(feature = "str_mut_extras", issue = "0")]
#[unstable(feature = "str_mut_extras", issue = "41119")]
unsafe fn as_bytes_mut(&mut self) -> &mut [u8];
#[stable(feature = "core", since = "1.6.0")]
fn find<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>;

View File

@ -26,7 +26,7 @@
#![deny(warnings)]
#![cfg_attr(stage0, feature(staged_api))]
#![feature(unicode)]
#![feature(rustc_private)]
pub use self::Piece::*;
pub use self::Position::*;

View File

@ -33,7 +33,6 @@
#![feature(quote)]
#![feature(rustc_diagnostic_macros)]
#![feature(slice_patterns)]
#![feature(unicode)]
#![feature(conservative_impl_trait)]
#![feature(command_envs)]

View File

@ -484,7 +484,7 @@ pub mod rt;
// but it may be stabilized long-term. As a result we're exposing a hidden,
// unstable module so we can get our build working.
#[doc(hidden)]
#[unstable(feature = "rand", issue = "0")]
#[unstable(feature = "rand", issue = "27703")]
pub mod __rand {
pub use rand::{thread_rng, ThreadRng, Rng};
}

View File

@ -56,7 +56,7 @@
//! between the two sources. (Also note that, on some systems e.g. FreeBSD, both `/dev/random`
//! and `/dev/urandom` may block once if the CSPRNG has not seeded yet.)
#![unstable(feature = "rand", issue = "0")]
#![unstable(feature = "rand", issue = "27703")]
use cell::RefCell;
use fmt;

View File

@ -599,9 +599,9 @@ impl char {
/// 'XID_Start' is a Unicode Derived Property specified in
/// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
/// mostly similar to `ID_Start` but modified for closure under `NFKx`.
#[unstable(feature = "unicode",
#[unstable(feature = "rustc_private",
reason = "mainly needed for compiler internals",
issue = "0")]
issue = "27812")]
#[inline]
pub fn is_xid_start(self) -> bool {
derived_property::XID_Start(self)
@ -613,9 +613,9 @@ impl char {
/// 'XID_Continue' is a Unicode Derived Property specified in
/// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
/// mostly similar to 'ID_Continue' but modified for closure under NFKx.
#[unstable(feature = "unicode",
#[unstable(feature = "rustc_private",
reason = "mainly needed for compiler internals",
issue = "0")]
issue = "27812")]
#[inline]
pub fn is_xid_continue(self) -> bool {
derived_property::XID_Continue(self)

View File

@ -56,7 +56,7 @@ pub fn check(path: &Path, bad: &mut bool, quiet: bool) {
let mut features = collect_lang_features(path);
assert!(!features.is_empty());
let lib_features = collect_lib_features(path, bad, &features);
let lib_features = get_and_check_lib_features(path, bad, &features);
assert!(!lib_features.is_empty());
let mut contents = String::new();
@ -217,10 +217,61 @@ pub fn collect_lang_features(base_src_path: &Path) -> Features {
.collect()
}
pub fn collect_lib_features(base_src_path: &Path,
bad: &mut bool,
features: &Features) -> Features {
pub fn collect_lib_features(base_src_path: &Path) -> Features {
let mut lib_features = Features::new();
map_lib_features(base_src_path,
&mut |res, _, _| {
match res {
Ok((name, feature)) => {
if lib_features.get(name).is_some() {
return;
}
lib_features.insert(name.to_owned(), feature);
},
Err(_) => (),
}
});
lib_features
}
fn get_and_check_lib_features(base_src_path: &Path,
bad: &mut bool,
lang_features: &Features) -> Features {
let mut lib_features = Features::new();
map_lib_features(base_src_path,
&mut |res, file, line| {
match res {
Ok((name, f)) => {
let mut err = |msg: &str| {
tidy_error!(bad, "{}:{}: {}", file.display(), line, msg);
};
if lang_features.contains_key(name) {
err("duplicating a lang feature");
}
if let Some(ref s) = lib_features.get(name) {
if s.level != f.level {
err("different stability level than before");
}
if s.since != f.since {
err("different `since` than before");
}
if s.tracking_issue != f.tracking_issue {
err("different `tracking_issue` than before");
}
}
lib_features.insert(name.to_owned(), f);
},
Err(msg) => {
tidy_error!(bad, "{}:{}: {}", file.display(), line, msg);
},
}
});
lib_features
}
fn map_lib_features(base_src_path: &Path,
mf: &mut FnMut(Result<(&str, Feature), &str>, &Path, usize)) {
let mut contents = String::new();
super::walk(base_src_path,
&mut |path| super::filter_dirs(path) || path.ends_with("src/test"),
@ -236,8 +287,11 @@ pub fn collect_lib_features(base_src_path: &Path,
let mut becoming_feature: Option<(String, Feature)> = None;
for (i, line) in contents.lines().enumerate() {
let mut err = |msg: &str| {
tidy_error!(bad, "{}:{}: {}", file.display(), i + 1, msg);
macro_rules! err {
($msg:expr) => {{
mf(Err($msg), file, i + 1);
continue;
}};
};
if let Some((ref name, ref mut f)) = becoming_feature {
if f.tracking_issue.is_none() {
@ -245,7 +299,7 @@ pub fn collect_lib_features(base_src_path: &Path,
.map(|s| s.parse().unwrap());
}
if line.ends_with("]") {
lib_features.insert(name.to_owned(), f.clone());
mf(Ok((name, f.clone())), file, i + 1);
} else if !line.ends_with(",") && !line.ends_with("\\") {
// We need to bail here because we might have missed the
// end of a stability attribute above because the "]"
@ -254,7 +308,7 @@ pub fn collect_lib_features(base_src_path: &Path,
// we continue parsing the file assuming the current stability
// attribute has not ended, and ignoring possible feature
// attributes in the process.
err("malformed stability attribute");
err!("malformed stability attribute");
} else {
continue;
}
@ -269,33 +323,17 @@ pub fn collect_lib_features(base_src_path: &Path,
};
let feature_name = match find_attr_val(line, "feature") {
Some(name) => name,
None => {
err("malformed stability attribute");
continue;
}
None => err!("malformed stability attribute"),
};
let since = match find_attr_val(line, "since") {
Some(name) => name,
None if level == Status::Stable => {
err("malformed stability attribute");
continue;
err!("malformed stability attribute");
}
None => "None",
};
let tracking_issue = find_attr_val(line, "issue").map(|s| s.parse().unwrap());
if features.contains_key(feature_name) {
err("duplicating a lang feature");
}
if let Some(ref s) = lib_features.get(feature_name) {
if s.level != level {
err("different stability level than before");
}
if s.since != since {
err("different `since` than before");
}
continue;
}
let feature = Feature {
level,
since: since.to_owned(),
@ -303,11 +341,10 @@ pub fn collect_lib_features(base_src_path: &Path,
tracking_issue,
};
if line.contains("]") {
lib_features.insert(feature_name.to_owned(), feature);
mf(Ok((feature_name, feature)), file, i + 1);
} else {
becoming_feature = Some((feature_name.to_owned(), feature));
}
}
});
lib_features
}

View File

@ -87,7 +87,7 @@ pub fn check(path: &path::Path, bad: &mut bool) {
// Library features
let lang_features = collect_lang_features(path);
let lib_features = collect_lib_features(path, bad, &lang_features);
let lib_features = collect_lib_features(path);
let unstable_lib_feature_names = collect_unstable_feature_names(&lib_features);
let unstable_book_lib_features_section_file_names =

View File

@ -129,8 +129,7 @@ fn main() {
let dest_path = Path::new(&dest_path_str).join("src");
let lang_features = collect_lang_features(src_path);
let mut bad = false;
let lib_features = collect_lib_features(src_path, &mut bad, &lang_features);
let lib_features = collect_lib_features(src_path);
let doc_src_path = src_path.join(PATH_STR);