提交 31b7d64f 编写于 作者: A Aaron Turon

rustc: Add deprecation/renaming support for lints

Since a large number of lints are being renamed for RFC 344, this commit
adds some basic deprecation/renaming functionality to the pluggable lint
system. It allows a simple mapping of old to new names, and can warn
when old names are being used.

This change needs to be rolled out in stages. In this commit, the
deprecation warning is commented out, but the old name is forwarded to
the new one.

Once the commit lands and we have generated a new snapshot of the
compiler, we can add the deprecation warning and rename all uses of the
lints in the rust codebase.
上级 3c0d2a7c
...@@ -63,7 +63,7 @@ pub struct LintStore { ...@@ -63,7 +63,7 @@ pub struct LintStore {
passes: Option<Vec<LintPassObject>>, passes: Option<Vec<LintPassObject>>,
/// Lints indexed by name. /// Lints indexed by name.
by_name: HashMap<String, LintId>, by_name: HashMap<String, TargetLint>,
/// Current levels of each lint, and where they were set. /// Current levels of each lint, and where they were set.
levels: HashMap<LintId, LevelSource>, levels: HashMap<LintId, LevelSource>,
...@@ -73,6 +73,15 @@ pub struct LintStore { ...@@ -73,6 +73,15 @@ pub struct LintStore {
lint_groups: HashMap<&'static str, (Vec<LintId>, bool)>, lint_groups: HashMap<&'static str, (Vec<LintId>, bool)>,
} }
/// The targed of the `by_name` map, which accounts for renaming/deprecation.
enum TargetLint {
/// A direct lint target
Id(LintId),
/// Temporary renaming, used for easing migration pain; see #16545
Renamed(String, LintId),
}
impl LintStore { impl LintStore {
fn get_level_source(&self, lint: LintId) -> LevelSource { fn get_level_source(&self, lint: LintId) -> LevelSource {
match self.levels.find(&lint) { match self.levels.find(&lint) {
...@@ -115,7 +124,7 @@ pub fn register_pass(&mut self, sess: Option<&Session>, ...@@ -115,7 +124,7 @@ pub fn register_pass(&mut self, sess: Option<&Session>,
self.lints.push((*lint, from_plugin)); self.lints.push((*lint, from_plugin));
let id = LintId::of(*lint); let id = LintId::of(*lint);
if !self.by_name.insert(lint.name_lower(), id) { if !self.by_name.insert(lint.name_lower(), Id(id)) {
let msg = format!("duplicate specification of lint {}", lint.name_lower()); let msg = format!("duplicate specification of lint {}", lint.name_lower());
match (sess, from_plugin) { match (sess, from_plugin) {
// We load builtin lints first, so a duplicate is a compiler bug. // We load builtin lints first, so a duplicate is a compiler bug.
...@@ -154,6 +163,14 @@ pub fn register_group(&mut self, sess: Option<&Session>, ...@@ -154,6 +163,14 @@ pub fn register_group(&mut self, sess: Option<&Session>,
} }
} }
fn register_renamed(&mut self, old_name: &str, new_name: &str) {
let target = match self.by_name.find_equiv(&new_name) {
Some(&Id(lint_id)) => lint_id.clone(),
_ => fail!("invalid lint renaming of {} to {}", old_name, new_name)
};
self.by_name.insert(old_name.to_string(), Renamed(new_name.to_string(), target));
}
pub fn register_builtin(&mut self, sess: Option<&Session>) { pub fn register_builtin(&mut self, sess: Option<&Session>) {
macro_rules! add_builtin ( ( $sess:ident, $($name:ident),*, ) => ( macro_rules! add_builtin ( ( $sess:ident, $($name:ident),*, ) => (
{$( {$(
...@@ -208,12 +225,59 @@ pub fn register_builtin(&mut self, sess: Option<&Session>) { ...@@ -208,12 +225,59 @@ pub fn register_builtin(&mut self, sess: Option<&Session>) {
// We have one lint pass defined in this module. // We have one lint pass defined in this module.
self.register_pass(sess, false, box GatherNodeLevels as LintPassObject); self.register_pass(sess, false, box GatherNodeLevels as LintPassObject);
// Insert temporary renamings for a one-time deprecation (#16545)
self.register_renamed("unnecessary_typecast", "unused_typecasts");
self.register_renamed("unsigned_negate", "unsigned_negation");
self.register_renamed("type_limits", "unused_comparisons");
self.register_renamed("type_overflow", "overflowing_literals");
self.register_renamed("ctypes", "improper_ctypes");
self.register_renamed("owned_heap_memory", "box_pointers");
self.register_renamed("unused_attribute", "unused_attributes");
self.register_renamed("path_statement", "path_statements");
self.register_renamed("unused_result", "unused_results");
self.register_renamed("non_uppercase_statics", "non_upper_case_globals");
self.register_renamed("unnecessary_parens", "unused_parens");
self.register_renamed("unnecessary_import_braces", "unused_import_braces");
self.register_renamed("unsafe_block", "unsafe_blocks");
self.register_renamed("unnecessary_allocation", "unused_allocation");
self.register_renamed("missing_doc", "missing_docs");
self.register_renamed("unused_extern_crate", "unused_extern_crates");
self.register_renamed("unnecessary_qualification", "unused_qualifications");
self.register_renamed("unrecognized_lint", "unknown_lints");
self.register_renamed("unused_variable", "unused_variables");
self.register_renamed("dead_assignment", "unused_assignments");
self.register_renamed("unknown_crate_type", "unknown_crate_types");
self.register_renamed("variant_size_difference", "variant_size_differences");
self.register_renamed("transmute_fat_ptr", "fat_ptr_transmutes");
}
#[allow(unused_variable)]
fn find_lint(&self, lint_name: &str, sess: &Session, span: Option<Span>)
-> Option<LintId>
{
match self.by_name.find_equiv(&lint_name) {
Some(&Id(lint_id)) => Some(lint_id),
Some(&Renamed(ref new_name, lint_id)) => {
// NOTE(stage0): add the following code after the next snapshot
// let warning = format!("lint {} has been renamed to {}",
// lint_name, new_name);
// match span {
// Some(span) => sess.span_warn(span, warning.as_slice()),
// None => sess.warn(warning.as_slice()),
// };
Some(lint_id)
}
None => None
}
} }
pub fn process_command_line(&mut self, sess: &Session) { pub fn process_command_line(&mut self, sess: &Session) {
for &(ref lint_name, level) in sess.opts.lint_opts.iter() { for &(ref lint_name, level) in sess.opts.lint_opts.iter() {
match self.by_name.find_equiv(&lint_name.as_slice()) { match self.find_lint(lint_name.as_slice(), sess, None) {
Some(&lint_id) => self.set_level(lint_id, (level, CommandLine)), Some(lint_id) => self.set_level(lint_id, (level, CommandLine)),
None => { None => {
match self.lint_groups.iter().map(|(&x, pair)| (x, pair.ref0().clone())) match self.lint_groups.iter().map(|(&x, pair)| (x, pair.ref0().clone()))
.collect::<HashMap<&'static str, Vec<LintId>>>() .collect::<HashMap<&'static str, Vec<LintId>>>()
...@@ -421,8 +485,8 @@ fn with_lint_attrs(&mut self, ...@@ -421,8 +485,8 @@ fn with_lint_attrs(&mut self,
continue; continue;
} }
Ok((lint_name, level, span)) => { Ok((lint_name, level, span)) => {
match self.lints.by_name.find_equiv(&lint_name.get()) { match self.lints.find_lint(lint_name.get(), &self.tcx.sess, Some(span)) {
Some(&lint_id) => vec![(lint_id, level, span)], Some(lint_id) => vec![(lint_id, level, span)],
None => { None => {
match self.lints.lint_groups.find_equiv(&lint_name.get()) { match self.lints.lint_groups.find_equiv(&lint_name.get()) {
Some(&(ref v, _)) => v.iter() Some(&(ref v, _)) => v.iter()
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册