Add lint groups; define built-in lint groups bad_style
and unused
This adds support for lint groups to the compiler. Lint groups are a way of grouping a number of lints together under one name. For example, this also defines a default lint for naming conventions, named `bad_style`. Writing `#[allow(bad_style)]` is equivalent to writing `#[allow(non_camel_case_types, non_snake_case, non_uppercase_statics)]`. These lint groups can also be defined as a compiler plugin using the new `Registry::register_lint_group` method. This also adds two built-in lint groups, `bad_style` and `unused`. The contents of these groups can be seen by running `rustc -W help`.
This commit is contained in:
parent
de7abd8824
commit
ed2aad8b43
src
libcollections/hash
libcore
librustc
driver
lint
middle/typeck/infer
plugin
librustrt
test
auxiliary
compile-fail-fulldeps
compile-fail
run-pass-fulldeps
@ -157,7 +157,6 @@ macro_rules! impl_hash_tuple(
|
||||
|
||||
( $($name:ident)+) => (
|
||||
impl<S: Writer, $($name: Hash<S>),*> Hash<S> for ($($name,)*) {
|
||||
#[allow(uppercase_variables)]
|
||||
#[inline]
|
||||
#[allow(non_snake_case)]
|
||||
fn hash(&self, state: &mut S) {
|
||||
|
@ -775,7 +775,7 @@ macro_rules! def_fn_mut(
|
||||
FnMut<($($args,)*),Result>
|
||||
for extern "Rust" fn($($args: $args,)*) -> Result {
|
||||
#[rust_call_abi_hack]
|
||||
#[allow(uppercase_variables)]
|
||||
#[allow(non_snake_case)]
|
||||
fn call_mut(&mut self, args: ($($args,)*)) -> Result {
|
||||
let ($($args,)*) = args;
|
||||
(*self)($($args,)*)
|
||||
|
@ -242,13 +242,17 @@ pub fn phase_2_configure_and_expand(sess: &Session,
|
||||
}
|
||||
});
|
||||
|
||||
let Registry { syntax_exts, lint_passes, .. } = registry;
|
||||
let Registry { syntax_exts, lint_passes, lint_groups, .. } = registry;
|
||||
|
||||
{
|
||||
let mut ls = sess.lint_store.borrow_mut();
|
||||
for pass in lint_passes.move_iter() {
|
||||
ls.register_pass(Some(sess), true, pass);
|
||||
}
|
||||
|
||||
for (name, to) in lint_groups.move_iter() {
|
||||
ls.register_group(Some(sess), true, name, to);
|
||||
}
|
||||
}
|
||||
|
||||
// Lint plugins are registered; now we can process command line flags.
|
||||
|
@ -180,14 +180,26 @@ Available lint options:
|
||||
lints
|
||||
}
|
||||
|
||||
fn sort_lint_groups(lints: Vec<(&'static str, Vec<lint::LintId>, bool)>)
|
||||
-> Vec<(&'static str, Vec<lint::LintId>)> {
|
||||
let mut lints: Vec<_> = lints.move_iter().map(|(x, y, _)| (x, y)).collect();
|
||||
lints.sort_by(|&(x, _): &(&'static str, Vec<lint::LintId>),
|
||||
&(y, _): &(&'static str, Vec<lint::LintId>)| {
|
||||
x.cmp(&y)
|
||||
});
|
||||
lints
|
||||
}
|
||||
|
||||
let (plugin, builtin) = lint_store.get_lints().partitioned(|&(_, p)| p);
|
||||
let plugin = sort_lints(plugin);
|
||||
let builtin = sort_lints(builtin);
|
||||
|
||||
// FIXME (#7043): We should use the width in character cells rather than
|
||||
// the number of codepoints.
|
||||
let (plugin_groups, builtin_groups) = lint_store.get_lint_groups().partitioned(|&(_, _, p)| p);
|
||||
let plugin_groups = sort_lint_groups(plugin_groups);
|
||||
let builtin_groups = sort_lint_groups(builtin_groups);
|
||||
|
||||
let max_name_len = plugin.iter().chain(builtin.iter())
|
||||
.map(|&s| s.name.char_len())
|
||||
.map(|&s| s.name.width(true))
|
||||
.max().unwrap_or(0);
|
||||
let padded = |x: &str| {
|
||||
" ".repeat(max_name_len - x.char_len()).append(x)
|
||||
@ -208,16 +220,48 @@ Available lint options:
|
||||
|
||||
print_lints(builtin);
|
||||
|
||||
match (loaded_plugins, plugin.len()) {
|
||||
(false, 0) => {
|
||||
println!("Compiler plugins can provide additional lints. To see a listing of these, \
|
||||
re-run `rustc -W help` with a crate filename.");
|
||||
|
||||
|
||||
let max_name_len = plugin_groups.iter().chain(builtin_groups.iter())
|
||||
.map(|&(s, _)| s.width(true))
|
||||
.max().unwrap_or(0);
|
||||
let padded = |x: &str| {
|
||||
" ".repeat(max_name_len - x.char_len()).append(x)
|
||||
};
|
||||
|
||||
println!("Lint groups provided by rustc:\n");
|
||||
println!(" {} {}", padded("name"), "sub-lints");
|
||||
println!(" {} {}", padded("----"), "---------");
|
||||
|
||||
let print_lint_groups = |lints: Vec<(&'static str, Vec<lint::LintId>)>| {
|
||||
for (name, to) in lints.move_iter() {
|
||||
let name = name.chars().map(|x| x.to_lowercase())
|
||||
.collect::<String>().replace("_", "-");
|
||||
let desc = to.move_iter().map(|x| x.as_str()).collect::<Vec<String>>().connect(", ");
|
||||
println!(" {} {}",
|
||||
padded(name.as_slice()), desc);
|
||||
}
|
||||
(false, _) => fail!("didn't load lint plugins but got them anyway!"),
|
||||
(true, 0) => println!("This crate does not load any lint plugins."),
|
||||
(true, _) => {
|
||||
println!("Lint checks provided by plugins loaded by this crate:\n");
|
||||
print_lints(plugin);
|
||||
println!("\n");
|
||||
};
|
||||
|
||||
print_lint_groups(builtin_groups);
|
||||
|
||||
match (loaded_plugins, plugin.len(), plugin_groups.len()) {
|
||||
(false, 0, _) | (false, _, 0) => {
|
||||
println!("Compiler plugins can provide additional lints and lint groups. To see a \
|
||||
listing of these, re-run `rustc -W help` with a crate filename.");
|
||||
}
|
||||
(false, _, _) => fail!("didn't load lint plugins but got them anyway!"),
|
||||
(true, 0, 0) => println!("This crate does not load any lint plugins or lint groups."),
|
||||
(true, l, g) => {
|
||||
if l > 0 {
|
||||
println!("Lint checks provided by plugins loaded by this crate:\n");
|
||||
print_lints(plugin);
|
||||
}
|
||||
if g > 0 {
|
||||
println!("Lint groups provided by plugins loaded by this crate:\n");
|
||||
print_lint_groups(plugin_groups);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -736,7 +736,7 @@ impl LintPass for UnusedResult {
|
||||
}
|
||||
}
|
||||
|
||||
declare_lint!(NON_CAMEL_CASE_TYPES, Warn,
|
||||
declare_lint!(pub NON_CAMEL_CASE_TYPES, Warn,
|
||||
"types, variants, traits and type parameters should have camel case names")
|
||||
|
||||
pub struct NonCamelCaseTypes;
|
||||
@ -844,7 +844,7 @@ fn method_context(cx: &Context, m: &ast::Method) -> MethodContext {
|
||||
}
|
||||
}
|
||||
|
||||
declare_lint!(NON_SNAKE_CASE, Warn,
|
||||
declare_lint!(pub NON_SNAKE_CASE, Warn,
|
||||
"methods, functions, lifetime parameters and modules should have snake case names")
|
||||
|
||||
pub struct NonSnakeCase;
|
||||
@ -930,8 +930,8 @@ impl LintPass for NonSnakeCase {
|
||||
self.check_snake_case(cx, "trait method", t.ident, t.span);
|
||||
}
|
||||
|
||||
fn check_lifetime_decl(&mut self, cx: &Context, t: &ast::Lifetime) {
|
||||
self.check_snake_case(cx, "lifetime", t.name.ident(), t.span);
|
||||
fn check_lifetime_decl(&mut self, cx: &Context, t: &ast::LifetimeDef) {
|
||||
self.check_snake_case(cx, "lifetime", t.lifetime.name.ident(), t.lifetime.span);
|
||||
}
|
||||
|
||||
fn check_pat(&mut self, cx: &Context, p: &ast::Pat) {
|
||||
@ -962,7 +962,7 @@ impl LintPass for NonSnakeCase {
|
||||
}
|
||||
}
|
||||
|
||||
declare_lint!(NON_UPPERCASE_STATICS, Allow,
|
||||
declare_lint!(pub NON_UPPERCASE_STATICS, Allow,
|
||||
"static constants should have uppercase identifiers")
|
||||
|
||||
pub struct NonUppercaseStatics;
|
||||
@ -1143,7 +1143,7 @@ impl LintPass for UnsafeBlock {
|
||||
}
|
||||
}
|
||||
|
||||
declare_lint!(UNUSED_MUT, Warn,
|
||||
declare_lint!(pub UNUSED_MUT, Warn,
|
||||
"detect mut variables which don't need to be mutable")
|
||||
|
||||
pub struct UnusedMut;
|
||||
|
@ -66,6 +66,10 @@ pub struct LintStore {
|
||||
|
||||
/// Current levels of each lint, and where they were set.
|
||||
levels: HashMap<LintId, LevelSource>,
|
||||
|
||||
/// Map of registered lint groups to what lints they expand to. The bool
|
||||
/// is true if the lint group was added by a plugin.
|
||||
lint_groups: HashMap<&'static str, (Vec<LintId>, bool)>,
|
||||
}
|
||||
|
||||
impl LintStore {
|
||||
@ -90,6 +94,7 @@ impl LintStore {
|
||||
passes: Some(vec!()),
|
||||
by_name: HashMap::new(),
|
||||
levels: HashMap::new(),
|
||||
lint_groups: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -97,6 +102,10 @@ impl LintStore {
|
||||
self.lints.as_slice()
|
||||
}
|
||||
|
||||
pub fn get_lint_groups<'t>(&'t self) -> Vec<(&'static str, Vec<LintId>, bool)> {
|
||||
self.lint_groups.iter().map(|(k, &(ref v, b))| (*k, v.clone(), b)).collect()
|
||||
}
|
||||
|
||||
pub fn register_pass(&mut self, sess: Option<&Session>,
|
||||
from_plugin: bool, pass: LintPassObject) {
|
||||
for &lint in pass.get_lints().iter() {
|
||||
@ -123,6 +132,25 @@ impl LintStore {
|
||||
self.passes.get_mut_ref().push(pass);
|
||||
}
|
||||
|
||||
pub fn register_group(&mut self, sess: Option<&Session>,
|
||||
from_plugin: bool, name: &'static str,
|
||||
to: Vec<LintId>) {
|
||||
let new = self.lint_groups.insert(name, (to, from_plugin));
|
||||
|
||||
if !new {
|
||||
let msg = format!("duplicate specification of lint group {}", name);
|
||||
match (sess, from_plugin) {
|
||||
// We load builtin lints first, so a duplicate is a compiler bug.
|
||||
// Use early_error when handling -W help with no crate.
|
||||
(None, _) => early_error(msg.as_slice()),
|
||||
(Some(sess), false) => sess.bug(msg.as_slice()),
|
||||
|
||||
// A duplicate name from a plugin is a user error.
|
||||
(Some(sess), true) => sess.err(msg.as_slice()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn register_builtin(&mut self, sess: Option<&Session>) {
|
||||
macro_rules! add_builtin ( ( $sess:ident, $($name:ident),*, ) => (
|
||||
{$(
|
||||
@ -136,6 +164,10 @@ impl LintStore {
|
||||
)*}
|
||||
))
|
||||
|
||||
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,
|
||||
@ -162,6 +194,13 @@ impl LintStore {
|
||||
MissingDoc,
|
||||
)
|
||||
|
||||
add_lint_group!(sess, "bad_style",
|
||||
NON_CAMEL_CASE_TYPES, NON_SNAKE_CASE, NON_UPPERCASE_STATICS)
|
||||
|
||||
add_lint_group!(sess, "unused",
|
||||
UNUSED_IMPORTS, UNUSED_VARIABLE, DEAD_ASSIGNMENT, DEAD_CODE,
|
||||
UNUSED_MUT, UNREACHABLE_CODE)
|
||||
|
||||
// We have one lint pass defined in this module.
|
||||
self.register_pass(sess, false, box GatherNodeLevels as LintPassObject);
|
||||
}
|
||||
@ -170,8 +209,20 @@ impl LintStore {
|
||||
for &(ref lint_name, level) in sess.opts.lint_opts.iter() {
|
||||
match self.by_name.find_equiv(&lint_name.as_slice()) {
|
||||
Some(&lint_id) => self.set_level(lint_id, (level, CommandLine)),
|
||||
None => sess.err(format!("unknown {} flag: {}",
|
||||
level.as_str(), lint_name).as_slice()),
|
||||
None => {
|
||||
match self.lint_groups.iter().map(|(&x, &(ref y, _))| (x, y.clone()))
|
||||
.collect::<HashMap<&'static str, Vec<LintId>>>()
|
||||
.find_equiv(&lint_name.as_slice()) {
|
||||
Some(v) => {
|
||||
v.iter()
|
||||
.map(|lint_id: &LintId|
|
||||
self.set_level(*lint_id, (level, CommandLine)))
|
||||
.collect::<Vec<()>>();
|
||||
}
|
||||
None => sess.err(format!("unknown {} flag: {}",
|
||||
level.as_str(), lint_name).as_slice()),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -305,7 +356,7 @@ impl<'a> Context<'a> {
|
||||
krate: krate,
|
||||
exported_items: exported_items,
|
||||
lints: lint_store,
|
||||
level_stack: vec!(),
|
||||
level_stack: vec![],
|
||||
node_levels: RefCell::new(HashMap::new()),
|
||||
}
|
||||
}
|
||||
@ -359,35 +410,46 @@ impl<'a> Context<'a> {
|
||||
let mut pushed = 0u;
|
||||
|
||||
for result in gather_attrs(attrs).move_iter() {
|
||||
let (lint_id, level, span) = match result {
|
||||
let v = match result {
|
||||
Err(span) => {
|
||||
self.tcx.sess.span_err(span, "malformed lint attribute");
|
||||
continue;
|
||||
}
|
||||
Ok((lint_name, level, span)) => {
|
||||
match self.lints.by_name.find_equiv(&lint_name.get()) {
|
||||
Some(&lint_id) => (lint_id, level, span),
|
||||
Some(&lint_id) => vec![(lint_id, level, span)],
|
||||
None => {
|
||||
self.span_lint(builtin::UNRECOGNIZED_LINT, span,
|
||||
format!("unknown `{}` attribute: `{}`",
|
||||
level.as_str(), lint_name).as_slice());
|
||||
continue;
|
||||
match self.lints.lint_groups.find_equiv(&lint_name.get()) {
|
||||
Some(&(ref v, _)) => v.iter()
|
||||
.map(|lint_id: &LintId|
|
||||
(*lint_id, level, span))
|
||||
.collect(),
|
||||
None => {
|
||||
self.span_lint(builtin::UNRECOGNIZED_LINT, span,
|
||||
format!("unknown `{}` attribute: `{}`",
|
||||
level.as_str(), lint_name).as_slice());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let now = self.lints.get_level_source(lint_id).val0();
|
||||
if now == Forbid && level != Forbid {
|
||||
let lint_name = lint_id.as_str();
|
||||
self.tcx.sess.span_err(span,
|
||||
format!("{}({}) overruled by outer forbid({})",
|
||||
level.as_str(), lint_name, lint_name).as_slice());
|
||||
} else if now != level {
|
||||
let src = self.lints.get_level_source(lint_id).val1();
|
||||
self.level_stack.push((lint_id, (now, src)));
|
||||
pushed += 1;
|
||||
self.lints.set_level(lint_id, (level, Node(span)));
|
||||
for (lint_id, level, span) in v.move_iter() {
|
||||
let now = self.lints.get_level_source(lint_id).val0();
|
||||
if now == Forbid && level != Forbid {
|
||||
let lint_name = lint_id.as_str();
|
||||
self.tcx.sess.span_err(span,
|
||||
format!("{}({}) overruled by outer forbid({})",
|
||||
level.as_str(), lint_name,
|
||||
lint_name).as_slice());
|
||||
} else if now != level {
|
||||
let src = self.lints.get_level_source(lint_id).val1();
|
||||
self.level_stack.push((lint_id, (now, src)));
|
||||
pushed += 1;
|
||||
self.lints.set_level(lint_id, (level, Node(span)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,7 @@ pub struct Equate<'f> {
|
||||
fields: CombineFields<'f>
|
||||
}
|
||||
|
||||
#[allow(non_snake_case_functions)]
|
||||
#[allow(non_snake_case)]
|
||||
pub fn Equate<'f>(cf: CombineFields<'f>) -> Equate<'f> {
|
||||
Equate { fields: cf }
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ pub struct Glb<'f> {
|
||||
fields: CombineFields<'f>
|
||||
}
|
||||
|
||||
#[allow(non_snake_case_functions)]
|
||||
#[allow(non_snake_case)]
|
||||
pub fn Glb<'f>(cf: CombineFields<'f>) -> Glb<'f> {
|
||||
Glb { fields: cf }
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ pub struct Lub<'f> {
|
||||
fields: CombineFields<'f>
|
||||
}
|
||||
|
||||
#[allow(non_snake_case_functions)]
|
||||
#[allow(non_snake_case)]
|
||||
pub fn Lub<'f>(cf: CombineFields<'f>) -> Lub<'f> {
|
||||
Lub { fields: cf }
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ pub struct Sub<'f> {
|
||||
fields: CombineFields<'f>
|
||||
}
|
||||
|
||||
#[allow(non_snake_case_functions)]
|
||||
#[allow(non_snake_case)]
|
||||
pub fn Sub<'f>(cf: CombineFields<'f>) -> Sub<'f> {
|
||||
Sub { fields: cf }
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
//! Used by plugin crates to tell `rustc` about the plugins they provide.
|
||||
|
||||
use lint::LintPassObject;
|
||||
use lint::{LintPassObject, LintId, Lint};
|
||||
|
||||
use syntax::ext::base::{SyntaxExtension, NamedSyntaxExtension, NormalTT};
|
||||
use syntax::ext::base::{IdentTT, LetSyntaxTT, ItemDecorator, ItemModifier, BasicMacroExpander};
|
||||
@ -19,6 +19,8 @@ use syntax::codemap::Span;
|
||||
use syntax::parse::token;
|
||||
use syntax::ast;
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
/// Structure used to register plugins.
|
||||
///
|
||||
/// A plugin registrar function takes an `&mut Registry` and should call
|
||||
@ -36,6 +38,9 @@ pub struct Registry {
|
||||
|
||||
#[doc(hidden)]
|
||||
pub lint_passes: Vec<LintPassObject>,
|
||||
|
||||
#[doc(hidden)]
|
||||
pub lint_groups: HashMap<&'static str, Vec<LintId>>,
|
||||
}
|
||||
|
||||
impl Registry {
|
||||
@ -45,6 +50,7 @@ impl Registry {
|
||||
krate_span: krate.span,
|
||||
syntax_exts: vec!(),
|
||||
lint_passes: vec!(),
|
||||
lint_groups: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -80,4 +86,9 @@ impl Registry {
|
||||
pub fn register_lint_pass(&mut self, lint_pass: LintPassObject) {
|
||||
self.lint_passes.push(lint_pass);
|
||||
}
|
||||
|
||||
/// Register a lint group.
|
||||
pub fn register_lint_group(&mut self, name: &'static str, to: Vec<&'static Lint>) {
|
||||
self.lint_groups.insert(name, to.move_iter().map(|x| LintId::of(x)).collect());
|
||||
}
|
||||
}
|
||||
|
@ -218,10 +218,10 @@ impl<T: 'static> KeyValue<T> {
|
||||
// Do nothing.
|
||||
None
|
||||
}
|
||||
(0, Some(newValue)) => {
|
||||
(0, Some(new_value)) => {
|
||||
// The current value is uninitialized and we're storing a new value.
|
||||
unsafe {
|
||||
ptr::write(&mut (*value_box).value, newValue);
|
||||
ptr::write(&mut (*value_box).value, new_value);
|
||||
*(*value_box).refcount.get() = 1;
|
||||
None
|
||||
}
|
||||
@ -234,10 +234,10 @@ impl<T: 'static> KeyValue<T> {
|
||||
Some(ret)
|
||||
}
|
||||
}
|
||||
(1, Some(newValue)) => {
|
||||
(1, Some(new_value)) => {
|
||||
// We have an initialized value and we're replacing it.
|
||||
let value_ref = unsafe { &mut (*value_box).value };
|
||||
let ret = mem::replace(value_ref, newValue);
|
||||
let ret = mem::replace(value_ref, new_value);
|
||||
// Refcount is already 1, leave it as that.
|
||||
Some(ret)
|
||||
}
|
||||
|
53
src/test/auxiliary/lint_group_plugin_test.rs
Normal file
53
src/test/auxiliary/lint_group_plugin_test.rs
Normal file
@ -0,0 +1,53 @@
|
||||
// Copyright 2014 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.
|
||||
|
||||
// force-host
|
||||
|
||||
#![feature(phase, plugin_registrar)]
|
||||
|
||||
extern crate syntax;
|
||||
|
||||
// Load rustc as a plugin to get macros
|
||||
#[phase(plugin, link)]
|
||||
extern crate rustc;
|
||||
|
||||
use syntax::ast;
|
||||
use syntax::parse::token;
|
||||
use rustc::lint::{Context, LintPass, LintPassObject, LintArray};
|
||||
use rustc::plugin::Registry;
|
||||
|
||||
declare_lint!(TEST_LINT, Warn,
|
||||
"Warn about items named 'lintme'")
|
||||
|
||||
declare_lint!(PLEASE_LINT, Warn,
|
||||
"Warn about items named 'pleaselintme'")
|
||||
|
||||
struct Pass;
|
||||
|
||||
impl LintPass for Pass {
|
||||
fn get_lints(&self) -> LintArray {
|
||||
lint_array!(TEST_LINT, PLEASE_LINT)
|
||||
}
|
||||
|
||||
fn check_item(&mut self, cx: &Context, it: &ast::Item) {
|
||||
let name = token::get_ident(it.ident);
|
||||
if name.get() == "lintme" {
|
||||
cx.span_lint(TEST_LINT, it.span, "item is named 'lintme'");
|
||||
} else if name.get() == "pleaselintme" {
|
||||
cx.span_lint(PLEASE_LINT, it.span, "item is named 'pleaselintme'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[plugin_registrar]
|
||||
pub fn plugin_registrar(reg: &mut Registry) {
|
||||
reg.register_lint_pass(box Pass as LintPassObject);
|
||||
reg.register_lint_group("lint_me", vec![TEST_LINT, PLEASE_LINT]);
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
// Copyright 2014 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.
|
||||
|
||||
// aux-build:lint_group_plugin_test.rs
|
||||
// ignore-stage1
|
||||
// compile-flags: -D lint-me
|
||||
|
||||
#![feature(phase)]
|
||||
|
||||
#[phase(plugin)]
|
||||
extern crate lint_group_plugin_test;
|
||||
|
||||
fn lintme() { } //~ ERROR item is named 'lintme'
|
||||
|
||||
fn pleaselintme() { } //~ ERROR item is named 'pleaselintme'
|
||||
|
||||
pub fn main() {
|
||||
lintme();
|
||||
pleaselintme();
|
||||
}
|
40
src/test/compile-fail/lint-group-style.rs
Normal file
40
src/test/compile-fail/lint-group-style.rs
Normal file
@ -0,0 +1,40 @@
|
||||
// Copyright 2014 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.
|
||||
|
||||
#![deny(bad_style)]
|
||||
//~^ NOTE lint level defined here
|
||||
#![allow(dead_code)]
|
||||
|
||||
fn CamelCase() {} //~ ERROR function `CamelCase` should have a snake case name
|
||||
|
||||
#[allow(bad_style)]
|
||||
mod test {
|
||||
fn CamelCase() {}
|
||||
|
||||
#[forbid(bad_style)]
|
||||
//~^ NOTE lint level defined here
|
||||
//~^^ NOTE lint level defined here
|
||||
mod bad {
|
||||
fn CamelCase() {} //~ ERROR function `CamelCase` should have a snake case name
|
||||
|
||||
static bad: int = 1; //~ ERROR static constant `bad` should have an uppercase name
|
||||
}
|
||||
|
||||
mod warn {
|
||||
#![warn(bad_style)]
|
||||
//~^ NOTE lint level defined here
|
||||
|
||||
fn CamelCase() {} //~ WARN function `CamelCase` should have a snake case name
|
||||
|
||||
struct snake_case; //~ WARN type `snake_case` should have a camel case name
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
28
src/test/run-pass-fulldeps/lint-group-plugin.rs
Normal file
28
src/test/run-pass-fulldeps/lint-group-plugin.rs
Normal file
@ -0,0 +1,28 @@
|
||||
// Copyright 2014 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.
|
||||
|
||||
// aux-build:lint_group_plugin_test.rs
|
||||
// ignore-stage1
|
||||
// ignore-pretty
|
||||
|
||||
#![feature(phase)]
|
||||
|
||||
#[phase(plugin)]
|
||||
extern crate lint_group_plugin_test;
|
||||
|
||||
fn lintme() { } //~ WARNING item is named 'lintme'
|
||||
fn pleaselintme() { } //~ WARNING item is named 'pleaselintme'
|
||||
|
||||
#[allow(lint_me)]
|
||||
pub fn main() {
|
||||
fn lintme() { }
|
||||
|
||||
fn pleaselintme() { }
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user