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:
parent
b40be00a0c
commit
c6afde6c46
11 changed files with 78 additions and 43 deletions
|
@ -428,7 +428,7 @@ impl Rc<str> {
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[unstable(feature = "rustc_private",
|
#[unstable(feature = "rustc_private",
|
||||||
reason = "for internal use in rustc",
|
reason = "for internal use in rustc",
|
||||||
issue = "0")]
|
issue = "27812")]
|
||||||
pub fn __from_str(value: &str) -> Rc<str> {
|
pub fn __from_str(value: &str) -> Rc<str> {
|
||||||
unsafe {
|
unsafe {
|
||||||
// Allocate enough space for `RcBox<str>`.
|
// Allocate enough space for `RcBox<str>`.
|
||||||
|
@ -453,7 +453,7 @@ impl<T> Rc<[T]> {
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[unstable(feature = "rustc_private",
|
#[unstable(feature = "rustc_private",
|
||||||
reason = "for internal use in rustc",
|
reason = "for internal use in rustc",
|
||||||
issue = "0")]
|
issue = "27812")]
|
||||||
pub fn __from_array(value: Box<[T]>) -> Rc<[T]> {
|
pub fn __from_array(value: Box<[T]>) -> Rc<[T]> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let ptr: *mut RcBox<[T]> =
|
let ptr: *mut RcBox<[T]> =
|
||||||
|
|
|
@ -99,7 +99,7 @@ use mem;
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
pub use self::sip::SipHasher;
|
pub use self::sip::SipHasher;
|
||||||
|
|
||||||
#[unstable(feature = "sip_hash_13", issue = "29754")]
|
#[unstable(feature = "sip_hash_13", issue = "34767")]
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
pub use self::sip::{SipHasher13, SipHasher24};
|
pub use self::sip::{SipHasher13, SipHasher24};
|
||||||
|
|
||||||
|
|
|
@ -2085,7 +2085,7 @@ pub trait StrExt {
|
||||||
fn is_char_boundary(&self, index: usize) -> bool;
|
fn is_char_boundary(&self, index: usize) -> bool;
|
||||||
#[stable(feature = "core", since = "1.6.0")]
|
#[stable(feature = "core", since = "1.6.0")]
|
||||||
fn as_bytes(&self) -> &[u8];
|
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];
|
unsafe fn as_bytes_mut(&mut self) -> &mut [u8];
|
||||||
#[stable(feature = "core", since = "1.6.0")]
|
#[stable(feature = "core", since = "1.6.0")]
|
||||||
fn find<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>;
|
fn find<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>;
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
#![deny(warnings)]
|
#![deny(warnings)]
|
||||||
|
|
||||||
#![cfg_attr(stage0, feature(staged_api))]
|
#![cfg_attr(stage0, feature(staged_api))]
|
||||||
#![feature(unicode)]
|
#![feature(rustc_private)]
|
||||||
|
|
||||||
pub use self::Piece::*;
|
pub use self::Piece::*;
|
||||||
pub use self::Position::*;
|
pub use self::Position::*;
|
||||||
|
|
|
@ -33,7 +33,6 @@
|
||||||
#![feature(quote)]
|
#![feature(quote)]
|
||||||
#![feature(rustc_diagnostic_macros)]
|
#![feature(rustc_diagnostic_macros)]
|
||||||
#![feature(slice_patterns)]
|
#![feature(slice_patterns)]
|
||||||
#![feature(unicode)]
|
|
||||||
#![feature(conservative_impl_trait)]
|
#![feature(conservative_impl_trait)]
|
||||||
#![feature(command_envs)]
|
#![feature(command_envs)]
|
||||||
|
|
||||||
|
|
|
@ -484,7 +484,7 @@ pub mod rt;
|
||||||
// but it may be stabilized long-term. As a result we're exposing a hidden,
|
// but it may be stabilized long-term. As a result we're exposing a hidden,
|
||||||
// unstable module so we can get our build working.
|
// unstable module so we can get our build working.
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[unstable(feature = "rand", issue = "0")]
|
#[unstable(feature = "rand", issue = "27703")]
|
||||||
pub mod __rand {
|
pub mod __rand {
|
||||||
pub use rand::{thread_rng, ThreadRng, Rng};
|
pub use rand::{thread_rng, ThreadRng, Rng};
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,7 @@
|
||||||
//! between the two sources. (Also note that, on some systems e.g. FreeBSD, both `/dev/random`
|
//! 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.)
|
//! 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 cell::RefCell;
|
||||||
use fmt;
|
use fmt;
|
||||||
|
|
|
@ -599,9 +599,9 @@ impl char {
|
||||||
/// 'XID_Start' is a Unicode Derived Property specified in
|
/// 'XID_Start' is a Unicode Derived Property specified in
|
||||||
/// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
|
/// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
|
||||||
/// mostly similar to `ID_Start` but modified for closure under `NFKx`.
|
/// mostly similar to `ID_Start` but modified for closure under `NFKx`.
|
||||||
#[unstable(feature = "unicode",
|
#[unstable(feature = "rustc_private",
|
||||||
reason = "mainly needed for compiler internals",
|
reason = "mainly needed for compiler internals",
|
||||||
issue = "0")]
|
issue = "27812")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_xid_start(self) -> bool {
|
pub fn is_xid_start(self) -> bool {
|
||||||
derived_property::XID_Start(self)
|
derived_property::XID_Start(self)
|
||||||
|
@ -613,9 +613,9 @@ impl char {
|
||||||
/// 'XID_Continue' is a Unicode Derived Property specified in
|
/// 'XID_Continue' is a Unicode Derived Property specified in
|
||||||
/// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
|
/// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
|
||||||
/// mostly similar to 'ID_Continue' but modified for closure under NFKx.
|
/// mostly similar to 'ID_Continue' but modified for closure under NFKx.
|
||||||
#[unstable(feature = "unicode",
|
#[unstable(feature = "rustc_private",
|
||||||
reason = "mainly needed for compiler internals",
|
reason = "mainly needed for compiler internals",
|
||||||
issue = "0")]
|
issue = "27812")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_xid_continue(self) -> bool {
|
pub fn is_xid_continue(self) -> bool {
|
||||||
derived_property::XID_Continue(self)
|
derived_property::XID_Continue(self)
|
||||||
|
|
|
@ -56,7 +56,7 @@ pub fn check(path: &Path, bad: &mut bool, quiet: bool) {
|
||||||
let mut features = collect_lang_features(path);
|
let mut features = collect_lang_features(path);
|
||||||
assert!(!features.is_empty());
|
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());
|
assert!(!lib_features.is_empty());
|
||||||
|
|
||||||
let mut contents = String::new();
|
let mut contents = String::new();
|
||||||
|
@ -217,10 +217,61 @@ pub fn collect_lang_features(base_src_path: &Path) -> Features {
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn collect_lib_features(base_src_path: &Path,
|
pub fn collect_lib_features(base_src_path: &Path) -> Features {
|
||||||
bad: &mut bool,
|
|
||||||
features: &Features) -> Features {
|
|
||||||
let mut lib_features = Features::new();
|
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();
|
let mut contents = String::new();
|
||||||
super::walk(base_src_path,
|
super::walk(base_src_path,
|
||||||
&mut |path| super::filter_dirs(path) || path.ends_with("src/test"),
|
&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;
|
let mut becoming_feature: Option<(String, Feature)> = None;
|
||||||
for (i, line) in contents.lines().enumerate() {
|
for (i, line) in contents.lines().enumerate() {
|
||||||
let mut err = |msg: &str| {
|
macro_rules! err {
|
||||||
tidy_error!(bad, "{}:{}: {}", file.display(), i + 1, msg);
|
($msg:expr) => {{
|
||||||
|
mf(Err($msg), file, i + 1);
|
||||||
|
continue;
|
||||||
|
}};
|
||||||
};
|
};
|
||||||
if let Some((ref name, ref mut f)) = becoming_feature {
|
if let Some((ref name, ref mut f)) = becoming_feature {
|
||||||
if f.tracking_issue.is_none() {
|
if f.tracking_issue.is_none() {
|
||||||
|
@ -245,7 +299,7 @@ pub fn collect_lib_features(base_src_path: &Path,
|
||||||
.map(|s| s.parse().unwrap());
|
.map(|s| s.parse().unwrap());
|
||||||
}
|
}
|
||||||
if line.ends_with("]") {
|
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("\\") {
|
} else if !line.ends_with(",") && !line.ends_with("\\") {
|
||||||
// We need to bail here because we might have missed the
|
// We need to bail here because we might have missed the
|
||||||
// end of a stability attribute above because 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
|
// we continue parsing the file assuming the current stability
|
||||||
// attribute has not ended, and ignoring possible feature
|
// attribute has not ended, and ignoring possible feature
|
||||||
// attributes in the process.
|
// attributes in the process.
|
||||||
err("malformed stability attribute");
|
err!("malformed stability attribute");
|
||||||
} else {
|
} else {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -269,33 +323,17 @@ pub fn collect_lib_features(base_src_path: &Path,
|
||||||
};
|
};
|
||||||
let feature_name = match find_attr_val(line, "feature") {
|
let feature_name = match find_attr_val(line, "feature") {
|
||||||
Some(name) => name,
|
Some(name) => name,
|
||||||
None => {
|
None => err!("malformed stability attribute"),
|
||||||
err("malformed stability attribute");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
let since = match find_attr_val(line, "since") {
|
let since = match find_attr_val(line, "since") {
|
||||||
Some(name) => name,
|
Some(name) => name,
|
||||||
None if level == Status::Stable => {
|
None if level == Status::Stable => {
|
||||||
err("malformed stability attribute");
|
err!("malformed stability attribute");
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
None => "None",
|
None => "None",
|
||||||
};
|
};
|
||||||
let tracking_issue = find_attr_val(line, "issue").map(|s| s.parse().unwrap());
|
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 {
|
let feature = Feature {
|
||||||
level,
|
level,
|
||||||
since: since.to_owned(),
|
since: since.to_owned(),
|
||||||
|
@ -303,11 +341,10 @@ pub fn collect_lib_features(base_src_path: &Path,
|
||||||
tracking_issue,
|
tracking_issue,
|
||||||
};
|
};
|
||||||
if line.contains("]") {
|
if line.contains("]") {
|
||||||
lib_features.insert(feature_name.to_owned(), feature);
|
mf(Ok((feature_name, feature)), file, i + 1);
|
||||||
} else {
|
} else {
|
||||||
becoming_feature = Some((feature_name.to_owned(), feature));
|
becoming_feature = Some((feature_name.to_owned(), feature));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
lib_features
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,7 +87,7 @@ pub fn check(path: &path::Path, bad: &mut bool) {
|
||||||
// Library features
|
// Library features
|
||||||
|
|
||||||
let lang_features = collect_lang_features(path);
|
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_lib_feature_names = collect_unstable_feature_names(&lib_features);
|
||||||
let unstable_book_lib_features_section_file_names =
|
let unstable_book_lib_features_section_file_names =
|
||||||
|
|
|
@ -129,8 +129,7 @@ fn main() {
|
||||||
let dest_path = Path::new(&dest_path_str).join("src");
|
let dest_path = Path::new(&dest_path_str).join("src");
|
||||||
|
|
||||||
let lang_features = collect_lang_features(src_path);
|
let lang_features = collect_lang_features(src_path);
|
||||||
let mut bad = false;
|
let lib_features = collect_lib_features(src_path);
|
||||||
let lib_features = collect_lib_features(src_path, &mut bad, &lang_features);
|
|
||||||
|
|
||||||
let doc_src_path = src_path.join(PATH_STR);
|
let doc_src_path = src_path.join(PATH_STR);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue