提交 532cd5f8 编写于 作者: H Huon Wilson

Separate most of rustc::lint::builtin into a separate crate.

This pulls out the implementations of most built-in lints into a
separate crate, to reduce edit-compile-test iteration times with
librustc_lint and increase parallelism. This should enable lints to be
refactored, added and deleted much more easily as it slashes the
edit-compile cycle to get a minimal working compiler to test with (`make
rustc-stage1`) from

    librustc -> librustc_typeck -> ... -> librustc_driver ->
        libcore -> ... -> libstd

to

    librustc_lint -> librustc_driver -> libcore -> ... libstd

which is significantly faster, mainly due to avoiding the librustc build
itself.

The intention would be to move as much as possible of the infrastructure
into the crate too, but the plumbing is deeply intertwined with librustc
itself at the moment. Also, there are lints for which diagnostics are
registered directly in the compiler code, not in their own crate
traversal, and their definitions have to remain in librustc.

This is a [breaking-change] for direct users of the compiler APIs:
callers of `rustc::session::build_session` or
`rustc::session::build_session_` need to manually call
`rustc_lint::register_builtins` on their return value.

This should make #22206 easier.
上级 e233987c
......@@ -54,7 +54,7 @@ TARGET_CRATES := libc std flate arena term \
log graphviz core rbml alloc \
unicode rustc_bitflags
RUSTC_CRATES := rustc rustc_typeck rustc_borrowck rustc_resolve rustc_driver \
rustc_trans rustc_back rustc_llvm rustc_privacy
rustc_trans rustc_back rustc_llvm rustc_privacy rustc_lint
HOST_CRATES := syntax $(RUSTC_CRATES) rustdoc fmt_macros
CRATES := $(TARGET_CRATES) $(HOST_CRATES)
TOOLS := compiletest rustdoc rustc rustbook
......@@ -70,7 +70,7 @@ DEPS_graphviz := std
DEPS_syntax := std term serialize log fmt_macros arena libc
DEPS_rustc_driver := arena flate getopts graphviz libc rustc rustc_back rustc_borrowck \
rustc_typeck rustc_resolve log syntax serialize rustc_llvm \
rustc_trans rustc_privacy
rustc_trans rustc_privacy rustc_lint
DEPS_rustc_trans := arena flate getopts graphviz libc rustc rustc_back \
log syntax serialize rustc_llvm
......@@ -78,12 +78,13 @@ DEPS_rustc_typeck := rustc syntax
DEPS_rustc_borrowck := rustc log graphviz syntax
DEPS_rustc_resolve := rustc log syntax
DEPS_rustc_privacy := rustc log syntax
DEPS_rustc_lint := rustc log syntax
DEPS_rustc := syntax flate arena serialize getopts rbml \
log graphviz rustc_llvm rustc_back
DEPS_rustc_llvm := native:rustllvm libc std
DEPS_rustc_back := std syntax rustc_llvm flate log libc
DEPS_rustdoc := rustc rustc_driver native:hoedown serialize getopts \
test
test rustc_lint
DEPS_rustc_bitflags := core
DEPS_flate := std native:miniz
DEPS_arena := std
......@@ -128,11 +129,13 @@ DOC_CRATES := $(filter-out rustc, \
$(filter-out rustc_resolve, \
$(filter-out rustc_driver, \
$(filter-out rustc_privacy, \
$(filter-out rustc_lint, \
$(filter-out log, \
$(filter-out getopts, \
$(filter-out syntax, $(CRATES)))))))))))
$(filter-out syntax, $(CRATES))))))))))))
COMPILER_DOC_CRATES := rustc rustc_trans rustc_borrowck rustc_resolve \
rustc_typeck rustc_driver syntax rustc_privacy
rustc_typeck rustc_driver syntax rustc_privacy \
rustc_lint
# This macro creates some simple definitions for each crate being built, just
# some munging of all of the parameters above.
......
......@@ -21,7 +21,7 @@ $(eval $(call RUST_CRATE,coretest))
TEST_TARGET_CRATES = $(filter-out core unicode,$(TARGET_CRATES)) coretest
TEST_DOC_CRATES = $(DOC_CRATES)
TEST_HOST_CRATES = $(filter-out rustc_typeck rustc_borrowck rustc_resolve rustc_trans,\
TEST_HOST_CRATES = $(filter-out rustc_typeck rustc_borrowck rustc_resolve rustc_trans rustc_lint,\
$(HOST_CRATES))
TEST_CRATES = $(TEST_TARGET_CRATES) $(TEST_HOST_CRATES)
......
......@@ -39,7 +39,6 @@
#![feature(unsafe_destructor)]
#![feature(staged_api)]
#![feature(std_misc)]
#![feature(unicode)]
#![feature(os)]
#![cfg_attr(test, feature(test))]
......
此差异已折叠。
......@@ -159,7 +159,7 @@ pub fn register_group(&mut self, sess: Option<&Session>,
}
}
fn register_renamed(&mut self, old_name: &str, new_name: &str) {
pub fn register_renamed(&mut self, old_name: &str, new_name: &str) {
let target = match self.by_name.get(new_name) {
Some(&Id(lint_id)) => lint_id.clone(),
_ => panic!("invalid lint renaming of {} to {}", old_name, new_name)
......@@ -167,80 +167,6 @@ fn register_renamed(&mut self, old_name: &str, new_name: &str) {
self.by_name.insert(old_name.to_string(), Renamed(new_name.to_string(), target));
}
pub fn register_builtin(&mut self, sess: Option<&Session>) {
macro_rules! add_builtin {
($sess:ident, $($name:ident),*,) => (
{$(
self.register_pass($sess, false, box builtin::$name as LintPassObject);
)*}
)
}
macro_rules! add_builtin_with_new {
($sess:ident, $($name:ident),*,) => (
{$(
self.register_pass($sess, false, box builtin::$name::new() as LintPassObject);
)*}
)
}
macro_rules! add_lint_group {
($sess:ident, $name:expr, $($lint:ident),*) => (
self.register_group($sess, false, $name, vec![$(LintId::of(builtin::$lint)),*]);
)
}
add_builtin!(sess,
HardwiredLints,
WhileTrue,
UnusedCasts,
ImproperCTypes,
BoxPointers,
UnusedAttributes,
PathStatements,
UnusedResults,
NonCamelCaseTypes,
NonSnakeCase,
NonUpperCaseGlobals,
UnusedParens,
UnusedImportBraces,
NonShorthandFieldPatterns,
UnusedUnsafe,
UnsafeCode,
UnusedMut,
UnusedAllocation,
MissingCopyImplementations,
UnstableFeatures,
Stability,
UnconditionalRecursion,
InvalidNoMangleItems,
PluginAsLibrary,
);
add_builtin_with_new!(sess,
TypeLimits,
RawPointerDerive,
MissingDoc,
MissingDebugImplementations,
);
add_lint_group!(sess, "bad_style",
NON_CAMEL_CASE_TYPES, NON_SNAKE_CASE, NON_UPPER_CASE_GLOBALS);
add_lint_group!(sess, "unused",
UNUSED_IMPORTS, UNUSED_VARIABLES, UNUSED_ASSIGNMENTS, DEAD_CODE,
UNUSED_MUT, UNREACHABLE_CODE, UNUSED_MUST_USE,
UNUSED_UNSAFE, PATH_STATEMENTS);
// We have one lint pass defined in this module.
self.register_pass(sess, false, box GatherNodeLevels as LintPassObject);
// Insert temporary renamings for a one-time deprecation
self.register_renamed("raw_pointer_deriving", "raw_pointer_derive");
self.register_renamed("unknown_features", "unused_features");
}
#[allow(unused_variables)]
fn find_lint(&self, lint_name: &str, sess: &Session, span: Option<Span>)
-> Option<LintId>
......@@ -741,7 +667,7 @@ fn visit_id(&mut self, id: ast::NodeId) {
// nodes, so that the variant size difference check in trans can call
// `raw_emit_lint`.
struct GatherNodeLevels;
pub struct GatherNodeLevels;
impl LintPass for GatherNodeLevels {
fn get_lints(&self) -> LintArray {
......
......@@ -37,7 +37,8 @@
use syntax::visit::FnKind;
use syntax::ast;
pub use lint::context::{Context, LintStore, raw_emit_lint, check_crate, gather_attrs};
pub use lint::context::{Context, LintStore, raw_emit_lint, check_crate, gather_attrs,
GatherNodeLevels};
/// Specification of a single lint.
#[derive(Copy, Debug)]
......
......@@ -8,7 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use lint;
use metadata::cstore::CStore;
use metadata::filesearch;
......@@ -389,7 +388,6 @@ pub fn build_session_(sopts: config::Options,
can_print_warnings: can_print_warnings
};
sess.lint_store.borrow_mut().register_builtin(Some(&sess));
sess
}
......
......@@ -47,6 +47,7 @@
extern crate rustc;
extern crate rustc_back;
extern crate rustc_borrowck;
extern crate rustc_lint;
extern crate rustc_privacy;
extern crate rustc_resolve;
extern crate rustc_trans;
......@@ -133,6 +134,7 @@ pub fn run_compiler<'a>(args: &[String],
};
let mut sess = build_session(sopts, input_file_path, descriptions);
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
if sess.unstable_options() {
sess.opts.show_span = matches.opt_str("show-span");
}
......@@ -299,11 +301,12 @@ fn no_input(&mut self,
0 => {
if sopts.describe_lints {
let mut ls = lint::LintStore::new();
ls.register_builtin(None);
rustc_lint::register_builtins(&mut ls, None);
describe_lints(&ls, false);
return None;
}
let sess = build_session(sopts.clone(), None, descriptions.clone());
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
let should_stop = RustcDefaultCalls::print_crate_info(&sess, None, odir, ofile);
if should_stop == Compilation::Stop {
return None;
......@@ -844,4 +847,3 @@ pub fn main() {
let result = run(env::args().collect());
std::env::set_exit_status(result as i32);
}
......@@ -13,6 +13,7 @@
use diagnostic;
use diagnostic::Emitter;
use driver;
use rustc_lint;
use rustc_resolve as resolve;
use rustc_typeck::middle::lang_items;
use rustc_typeck::middle::region::{self, CodeExtent, DestructionScopeData};
......@@ -108,6 +109,7 @@ fn test_env<F>(source_string: &str,
diagnostic::mk_span_handler(diagnostic_handler, codemap);
let sess = session::build_session_(options, None, span_diagnostic_handler);
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
let krate_config = Vec::new();
let input = config::Input::Str(source_string.to_string());
let krate = driver::phase_1_parse_input(&sess, krate_config, &input);
......
此差异已折叠。
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Many of the lints built into the Rust compiler.
//!
//! # Note
//!
//! This API is completely unstable and subject to change.
#![crate_name = "rustc_lint"]
#![unstable(feature = "rustc_private")]
#![staged_api]
#![crate_type = "dylib"]
#![crate_type = "rlib"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
html_root_url = "http://doc.rust-lang.org/nightly/")]
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(collections)]
#![feature(core)]
#![feature(int_uint)]
#![feature(quote)]
#![feature(rustc_diagnostic_macros)]
#![feature(rustc_private)]
#![feature(unsafe_destructor)]
#![feature(staged_api)]
#![feature(std_misc)]
#![feature(unicode)]
#![cfg_attr(test, feature(test))]
extern crate syntax;
#[macro_use]
extern crate rustc;
#[macro_use]
extern crate log;
pub use rustc::lint as lint;
pub use rustc::metadata as metadata;
pub use rustc::middle as middle;
pub use rustc::session as session;
pub use rustc::util as util;
use session::Session;
use lint::{LintPassObject, LintId};
mod builtin;
pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
macro_rules! add_builtin {
($sess:ident, $($name:ident),*,) => (
{$(
store.register_pass($sess, false, box builtin::$name as LintPassObject);
)*}
)
}
macro_rules! add_builtin_with_new {
($sess:ident, $($name:ident),*,) => (
{$(
store.register_pass($sess, false, box builtin::$name::new() as LintPassObject);
)*}
)
}
macro_rules! add_lint_group {
($sess:ident, $name:expr, $($lint:ident),*) => (
store.register_group($sess, false, $name, vec![$(LintId::of(builtin::$lint)),*]);
)
}
add_builtin!(sess,
HardwiredLints,
WhileTrue,
UnusedCasts,
ImproperCTypes,
BoxPointers,
UnusedAttributes,
PathStatements,
UnusedResults,
NonCamelCaseTypes,
NonSnakeCase,
NonUpperCaseGlobals,
UnusedParens,
UnusedImportBraces,
NonShorthandFieldPatterns,
UnusedUnsafe,
UnsafeCode,
UnusedMut,
UnusedAllocation,
MissingCopyImplementations,
UnstableFeatures,
Stability,
UnconditionalRecursion,
InvalidNoMangleItems,
PluginAsLibrary,
);
add_builtin_with_new!(sess,
TypeLimits,
RawPointerDerive,
MissingDoc,
MissingDebugImplementations,
);
add_lint_group!(sess, "bad_style",
NON_CAMEL_CASE_TYPES, NON_SNAKE_CASE, NON_UPPER_CASE_GLOBALS);
add_lint_group!(sess, "unused",
UNUSED_IMPORTS, UNUSED_VARIABLES, UNUSED_ASSIGNMENTS, DEAD_CODE,
UNUSED_MUT, UNREACHABLE_CODE, UNUSED_MUST_USE,
UNUSED_UNSAFE, PATH_STATEMENTS);
// We have one lint pass defined specially
store.register_pass(sess, false, box lint::GatherNodeLevels as LintPassObject);
// Insert temporary renamings for a one-time deprecation
store.register_renamed("raw_pointer_deriving", "raw_pointer_derive");
store.register_renamed("unknown_features", "unused_features");
}
......@@ -9,6 +9,7 @@
// except according to those terms.
pub use self::MaybeTyped::*;
use rustc_lint;
use rustc_driver::driver;
use rustc::session::{self, config};
use rustc::session::config::UnstableFeatures;
......@@ -114,6 +115,7 @@ pub fn run_core(search_paths: SearchPaths, cfgs: Vec<String>, externs: Externs,
let sess = session::build_session_(sessopts, cpath,
span_diagnostic_handler);
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
let cfg = config::build_configuration(&sess);
......
......@@ -42,6 +42,7 @@
extern crate rustc_trans;
extern crate rustc_driver;
extern crate rustc_resolve;
extern crate rustc_lint;
extern crate serialize;
extern crate syntax;
extern crate "test" as testing;
......
......@@ -20,6 +20,7 @@
use std::collections::{HashSet, HashMap};
use testing;
use rustc_lint;
use rustc::session::{self, config};
use rustc::session::config::get_unstable_features_setting;
use rustc::session::search_paths::{SearchPaths, PathKind};
......@@ -62,6 +63,7 @@ pub fn run(input: &str,
let sess = session::build_session_(sessopts,
Some(input_path.clone()),
span_diagnostic_handler);
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
let mut cfg = config::build_configuration(&sess);
cfg.extend(config::parse_cfgspecs(cfgs).into_iter());
......@@ -165,6 +167,7 @@ fn runtest(test: &str, cratename: &str, libs: SearchPaths,
let sess = session::build_session_(sessopts,
None,
span_diagnostic_handler);
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
let outdir = TempDir::new("rustdoctest").ok().expect("rustdoc needs a tempdir");
let out = Some(outdir.path().clone());
......
......@@ -10,6 +10,7 @@
extern crate rustc;
extern crate rustc_driver;
extern crate rustc_lint;
extern crate syntax;
use rustc::session::{build_session, Session};
......@@ -46,6 +47,7 @@ fn basic_sess(sysroot: Path) -> Session {
let descriptions = Registry::new(&rustc::diagnostics::DIAGNOSTICS);
let sess = build_session(opts, None, descriptions);
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
sess
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册