Skip to content

Commit c7af606

Browse files
author
Keegan McAllister
committed
Clean up and document the public lint API
Also change some code formatting. lint::builtin becomes a sibling of lint::context in order to ensure that lints implemented there use the same public API as lint plugins.
1 parent 819f76c commit c7af606

File tree

5 files changed

+767
-681
lines changed

5 files changed

+767
-681
lines changed

src/librustc/driver/driver.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ pub fn phase_3_run_analysis_passes(sess: Session,
384384
});
385385

386386
time(time_passes, "lint checking", (), |_|
387-
lint::check_crate(&ty_cx, &exported_items, krate));
387+
lint::check_crate(&ty_cx, krate, &exported_items));
388388

389389
CrateAnalysis {
390390
exp_map2: exp_map2,

src/librustc/lint/builtin.rs

Lines changed: 35 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,31 @@
99
// except according to those terms.
1010

1111
//! Lints built in to rustc.
12+
//!
13+
//! This is a sibling of `lint::context` in order to ensure that
14+
//! lints implemented here use the same public API as lint plugins.
15+
//!
16+
//! To add a new lint to rustc, declare it here using `declare_lint!()`.
17+
//! Then add code to emit the new lint in the appropriate circumstances.
18+
//! You can do that in an existing `LintPass` if it makes sense, or in
19+
//! a new `LintPass`, or using `Session::add_lint` elsewhere in the
20+
//! compiler. Only do the latter if the check can't be written cleanly
21+
//! as a `LintPass`.
22+
//!
23+
//! If you define a new `LintPass`, you will also need to add it to the
24+
//! `add_builtin_lints!()` invocation in `context.rs`. That macro
25+
//! requires a `Default` impl for your `LintPass` type.
1226
1327
use metadata::csearch;
1428
use middle::def::*;
1529
use middle::trans::adt; // for `adt::is_ffi_safe`
16-
use middle::typeck::astconv::{ast_ty_to_ty, AstConv};
30+
use middle::typeck::astconv::ast_ty_to_ty;
1731
use middle::typeck::infer;
1832
use middle::privacy::ExportedItems;
1933
use middle::{typeck, ty, def, pat_util};
2034
use util::ppaux::{ty_to_str};
2135
use util::nodemap::NodeSet;
2236
use lint::{Context, LintPass, LintArray};
23-
use lint;
2437

2538
use std::cmp;
2639
use std::collections::HashMap;
@@ -169,7 +182,7 @@ impl LintPass for TypeLimits {
169182
match ty::get(ty::expr_ty(cx.tcx, e)).sty {
170183
ty::ty_int(t) => {
171184
let int_type = if t == ast::TyI {
172-
cx.tcx.sess.targ_cfg.int_type
185+
cx.sess().targ_cfg.int_type
173186
} else { t };
174187
let (min, max) = int_ty_range(int_type);
175188
let mut lit_val: i64 = match lit.node {
@@ -188,7 +201,7 @@ impl LintPass for TypeLimits {
188201
},
189202
ty::ty_uint(t) => {
190203
let uint_type = if t == ast::TyU {
191-
cx.tcx.sess.targ_cfg.uint_type
204+
cx.sess().targ_cfg.uint_type
192205
} else { t };
193206
let (min, max) = uint_ty_range(uint_type);
194207
let lit_val: u64 = match lit.node {
@@ -430,9 +443,9 @@ impl LintPass for HeapMemory {
430443
ast::ItemFn(..) |
431444
ast::ItemTy(..) |
432445
ast::ItemEnum(..) |
433-
ast::ItemStruct(..) => self.check_heap_type(cx, it.span,
434-
ty::node_id_to_type(cx.tcx,
435-
it.id)),
446+
ast::ItemStruct(..)
447+
=> self.check_heap_type(cx, it.span,
448+
ty::node_id_to_type(cx.tcx, it.id)),
436449
_ => ()
437450
}
438451

@@ -441,8 +454,7 @@ impl LintPass for HeapMemory {
441454
ast::ItemStruct(struct_def, _) => {
442455
for struct_field in struct_def.fields.iter() {
443456
self.check_heap_type(cx, struct_field.span,
444-
ty::node_id_to_type(cx.tcx,
445-
struct_field.node.id));
457+
ty::node_id_to_type(cx.tcx, struct_field.node.id));
446458
}
447459
}
448460
_ => ()
@@ -677,7 +689,7 @@ impl LintPass for UnusedResult {
677689
_ => {}
678690
}
679691
} else {
680-
csearch::get_item_attrs(&cx.tcx.sess.cstore, did, |attrs| {
692+
csearch::get_item_attrs(&cx.sess().cstore, did, |attrs| {
681693
if attr::contains_name(attrs.as_slice(), "must_use") {
682694
cx.span_lint(unused_must_use, s.span,
683695
"unused result which must be used");
@@ -711,7 +723,7 @@ impl LintPass for DeprecatedOwnedVector {
711723
ty::ty_uniq(t) => match ty::get(t).sty {
712724
ty::ty_vec(_, None) => {
713725
cx.span_lint(deprecated_owned_vector, e.span,
714-
"use of deprecated `~[]` vector; replaced by `std::vec::Vec`")
726+
"use of deprecated `~[]` vector; replaced by `std::vec::Vec`")
715727
}
716728
_ => {}
717729
},
@@ -791,7 +803,7 @@ fn method_context(cx: &Context, m: &ast::Method) -> MethodContext {
791803
};
792804

793805
match cx.tcx.methods.borrow().find_copy(&did) {
794-
None => cx.tcx.sess.span_bug(m.span, "missing method descriptor?!"),
806+
None => cx.sess().span_bug(m.span, "missing method descriptor?!"),
795807
Some(md) => {
796808
match md.container {
797809
ty::TraitContainer(..) => TraitDefaultImpl,
@@ -1110,15 +1122,14 @@ impl UnusedMut {
11101122
match mode {
11111123
ast::BindByValue(ast::MutMutable) => {
11121124
if path.segments.len() != 1 {
1113-
cx.tcx.sess.span_bug(p.span,
1125+
cx.sess().span_bug(p.span,
11141126
"mutable binding that doesn't consist \
11151127
of exactly one segment");
11161128
}
11171129
let ident = path.segments.get(0).identifier;
11181130
if !token::get_ident(ident).get().starts_with("_") {
1119-
mutables.insert_or_update_with(ident.name as uint, vec!(id), |_, old| {
1120-
old.push(id);
1121-
});
1131+
mutables.insert_or_update_with(ident.name as uint,
1132+
vec!(id), |_, old| { old.push(id); });
11221133
}
11231134
}
11241135
_ => {
@@ -1279,7 +1290,7 @@ impl MissingDoc {
12791290
desc: &'static str) {
12801291
// If we're building a test harness, then warning about
12811292
// documentation is probably not really relevant right now.
1282-
if cx.tcx.sess.opts.test { return }
1293+
if cx.sess().opts.test { return }
12831294

12841295
// `#[doc(hidden)]` disables missing_doc check.
12851296
if self.doc_hidden() { return }
@@ -1358,7 +1369,8 @@ impl LintPass for MissingDoc {
13581369
}
13591370

13601371
fn check_fn(&mut self, cx: &Context,
1361-
fk: &visit::FnKind, _: &ast::FnDecl, _: &ast::Block, _: Span, _: ast::NodeId) {
1372+
fk: &visit::FnKind, _: &ast::FnDecl,
1373+
_: &ast::Block, _: Span, _: ast::NodeId) {
13621374
match *fk {
13631375
visit::FkMethod(_, _, m) => {
13641376
// If the method is an impl for a trait, don't doc.
@@ -1381,7 +1393,8 @@ impl LintPass for MissingDoc {
13811393
fn check_struct_field(&mut self, cx: &Context, sf: &ast::StructField) {
13821394
match sf.node.kind {
13831395
ast::NamedField(_, vis) if vis == ast::Public => {
1384-
let cur_struct_def = *self.struct_def_stack.last().expect("empty struct_def_stack");
1396+
let cur_struct_def = *self.struct_def_stack.last()
1397+
.expect("empty struct_def_stack");
13851398
self.check_missing_doc_attrs(cx, Some(cur_struct_def),
13861399
sf.node.attrs.as_slice(), sf.span, "a struct field")
13871400
}
@@ -1404,8 +1417,8 @@ declare_lint!(experimental, Warn,
14041417
declare_lint!(unstable, Allow,
14051418
"detects use of #[unstable] items (incl. items with no stability attribute)")
14061419

1407-
/// Checks for use of items with #[deprecated], #[experimental] and
1408-
/// #[unstable] (or none of them) attributes.
1420+
/// Checks for use of items with `#[deprecated]`, `#[experimental]` and
1421+
/// `#[unstable]` attributes, or no stability attribute.
14091422
#[deriving(Default)]
14101423
pub struct Stability;
14111424

@@ -1472,7 +1485,7 @@ impl LintPass for Stability {
14721485
let mut s = None;
14731486
// run through all the attributes and take the first
14741487
// stability one.
1475-
csearch::get_item_attrs(&cx.tcx.sess.cstore, id, |attrs| {
1488+
csearch::get_item_attrs(&cx.sess().cstore, id, |attrs| {
14761489
if s.is_none() {
14771490
s = attr::find_stability(attrs.as_slice())
14781491
}
@@ -1503,32 +1516,6 @@ impl LintPass for Stability {
15031516
}
15041517
}
15051518

1506-
/// Doesn't actually warn; just gathers information for use by
1507-
/// checks in trans.
1508-
#[deriving(Default)]
1509-
pub struct GatherNodeLevels;
1510-
1511-
impl LintPass for GatherNodeLevels {
1512-
fn get_lints(&self) -> LintArray {
1513-
lint_array!()
1514-
}
1515-
1516-
fn check_item(&mut self, cx: &Context, it: &ast::Item) {
1517-
match it.node {
1518-
ast::ItemEnum(..) => {
1519-
let lint_id = lint::LintId::of(variant_size_difference);
1520-
match cx.lints.get_level_source(lint_id) {
1521-
lvlsrc @ (lvl, _) if lvl != lint::Allow => {
1522-
cx.insert_node_level(it.id, lint_id, lvlsrc);
1523-
},
1524-
_ => { }
1525-
}
1526-
},
1527-
_ => { }
1528-
}
1529-
}
1530-
}
1531-
15321519
declare_lint!(pub unused_imports, Warn,
15331520
"imports that are never used")
15341521

0 commit comments

Comments
 (0)